@mdrv/opencode-quota 262.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.
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/bin/copilot-quota.ts +374 -0
- package/bin/glm-quota.ts +467 -0
- package/bin/install.js +439 -0
- package/bin/kimi-quota.ts +314 -0
- package/dist/bin/copilot-quota.d.ts +8 -0
- package/dist/bin/copilot-quota.d.ts.map +1 -0
- package/dist/bin/copilot-quota.js +298 -0
- package/dist/bin/copilot-quota.js.map +1 -0
- package/dist/bin/glm-quota.d.ts +8 -0
- package/dist/bin/glm-quota.d.ts.map +1 -0
- package/dist/bin/glm-quota.js +367 -0
- package/dist/bin/glm-quota.js.map +1 -0
- package/dist/bin/kimi-quota.d.ts +3 -0
- package/dist/bin/kimi-quota.d.ts.map +1 -0
- package/dist/bin/kimi-quota.js +241 -0
- package/dist/bin/kimi-quota.js.map +1 -0
- package/dist/src/api/client.d.ts +76 -0
- package/dist/src/api/client.d.ts.map +1 -0
- package/dist/src/api/client.js +203 -0
- package/dist/src/api/client.js.map +1 -0
- package/dist/src/api/endpoints.d.ts +22 -0
- package/dist/src/api/endpoints.d.ts.map +1 -0
- package/dist/src/api/endpoints.js +41 -0
- package/dist/src/api/endpoints.js.map +1 -0
- package/dist/src/api/platforms.d.ts +20 -0
- package/dist/src/api/platforms.d.ts.map +1 -0
- package/dist/src/api/platforms.js +38 -0
- package/dist/src/api/platforms.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +723 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/shared/logging.d.ts +7 -0
- package/dist/src/shared/logging.d.ts.map +1 -0
- package/dist/src/shared/logging.js +29 -0
- package/dist/src/shared/logging.js.map +1 -0
- package/dist/src/utils/box-constants.d.ts +43 -0
- package/dist/src/utils/box-constants.d.ts.map +1 -0
- package/dist/src/utils/box-constants.js +43 -0
- package/dist/src/utils/box-constants.js.map +1 -0
- package/dist/src/utils/date-formatter.d.ts +17 -0
- package/dist/src/utils/date-formatter.d.ts.map +1 -0
- package/dist/src/utils/date-formatter.js +33 -0
- package/dist/src/utils/date-formatter.js.map +1 -0
- package/dist/src/utils/error-formatter.d.ts +17 -0
- package/dist/src/utils/error-formatter.d.ts.map +1 -0
- package/dist/src/utils/error-formatter.js +60 -0
- package/dist/src/utils/error-formatter.js.map +1 -0
- package/dist/src/utils/progress-bar.d.ts +35 -0
- package/dist/src/utils/progress-bar.d.ts.map +1 -0
- package/dist/src/utils/progress-bar.js +43 -0
- package/dist/src/utils/progress-bar.js.map +1 -0
- package/dist/src/utils/reset-timer.d.ts +11 -0
- package/dist/src/utils/reset-timer.d.ts.map +1 -0
- package/dist/src/utils/reset-timer.js +32 -0
- package/dist/src/utils/reset-timer.js.map +1 -0
- package/dist/src/utils/time-window.d.ts +30 -0
- package/dist/src/utils/time-window.d.ts.map +1 -0
- package/dist/src/utils/time-window.js +34 -0
- package/dist/src/utils/time-window.js.map +1 -0
- package/dist/tests/error-handling/api-errors.test.d.ts +7 -0
- package/dist/tests/error-handling/api-errors.test.d.ts.map +1 -0
- package/dist/tests/error-handling/api-errors.test.js +110 -0
- package/dist/tests/error-handling/api-errors.test.js.map +1 -0
- package/dist/tests/error-handling/auth-errors.test.d.ts +7 -0
- package/dist/tests/error-handling/auth-errors.test.d.ts.map +1 -0
- package/dist/tests/error-handling/auth-errors.test.js +110 -0
- package/dist/tests/error-handling/auth-errors.test.js.map +1 -0
- package/dist/tests/error-handling/network-errors.test.d.ts +7 -0
- package/dist/tests/error-handling/network-errors.test.d.ts.map +1 -0
- package/dist/tests/error-handling/network-errors.test.js +94 -0
- package/dist/tests/error-handling/network-errors.test.js.map +1 -0
- package/dist/tests/error-handling/parse-errors.test.d.ts +7 -0
- package/dist/tests/error-handling/parse-errors.test.d.ts.map +1 -0
- package/dist/tests/error-handling/parse-errors.test.js +87 -0
- package/dist/tests/error-handling/parse-errors.test.js.map +1 -0
- package/dist/tests/error-handling/token-sanitization.test.d.ts +2 -0
- package/dist/tests/error-handling/token-sanitization.test.d.ts.map +1 -0
- package/dist/tests/error-handling/token-sanitization.test.js +59 -0
- package/dist/tests/error-handling/token-sanitization.test.js.map +1 -0
- package/dist/tests/functional/date-formatter.test.d.ts +5 -0
- package/dist/tests/functional/date-formatter.test.d.ts.map +1 -0
- package/dist/tests/functional/date-formatter.test.js +46 -0
- package/dist/tests/functional/date-formatter.test.js.map +1 -0
- package/dist/tests/functional/progress-bar.test.d.ts +5 -0
- package/dist/tests/functional/progress-bar.test.d.ts.map +1 -0
- package/dist/tests/functional/progress-bar.test.js +82 -0
- package/dist/tests/functional/progress-bar.test.js.map +1 -0
- package/dist/tests/functional/reset-timer.test.d.ts +6 -0
- package/dist/tests/functional/reset-timer.test.d.ts.map +1 -0
- package/dist/tests/functional/reset-timer.test.js +67 -0
- package/dist/tests/functional/reset-timer.test.js.map +1 -0
- package/dist/tests/functional/time-window.test.d.ts +5 -0
- package/dist/tests/functional/time-window.test.d.ts.map +1 -0
- package/dist/tests/functional/time-window.test.js +46 -0
- package/dist/tests/functional/time-window.test.js.map +1 -0
- package/dist/tests/integration/box-alignment.test.d.ts +8 -0
- package/dist/tests/integration/box-alignment.test.d.ts.map +1 -0
- package/dist/tests/integration/box-alignment.test.js +238 -0
- package/dist/tests/integration/box-alignment.test.js.map +1 -0
- package/dist/tests/integration/error-handling.test.d.ts +2 -0
- package/dist/tests/integration/error-handling.test.d.ts.map +1 -0
- package/dist/tests/integration/error-handling.test.js +36 -0
- package/dist/tests/integration/error-handling.test.js.map +1 -0
- package/dist/tests/integration/installer-config.test.d.ts +2 -0
- package/dist/tests/integration/installer-config.test.d.ts.map +1 -0
- package/dist/tests/integration/installer-config.test.js +65 -0
- package/dist/tests/integration/installer-config.test.js.map +1 -0
- package/dist/tests/integration/plugin-catch-block.test.d.ts +2 -0
- package/dist/tests/integration/plugin-catch-block.test.d.ts.map +1 -0
- package/dist/tests/integration/plugin-catch-block.test.js +134 -0
- package/dist/tests/integration/plugin-catch-block.test.js.map +1 -0
- package/dist/tests/integration/reset-time-display.test.d.ts +6 -0
- package/dist/tests/integration/reset-time-display.test.d.ts.map +1 -0
- package/dist/tests/integration/reset-time-display.test.js +138 -0
- package/dist/tests/integration/reset-time-display.test.js.map +1 -0
- package/dist/tests/module/http-client.test.d.ts +2 -0
- package/dist/tests/module/http-client.test.d.ts.map +1 -0
- package/dist/tests/module/http-client.test.js +49 -0
- package/dist/tests/module/http-client.test.js.map +1 -0
- package/dist/tests/module/platform-detection.test.d.ts +5 -0
- package/dist/tests/module/platform-detection.test.d.ts.map +1 -0
- package/dist/tests/module/platform-detection.test.js +48 -0
- package/dist/tests/module/platform-detection.test.js.map +1 -0
- package/integration/agents/copilot-quota-exec.md +20 -0
- package/integration/agents/glm-quota-exec.md +20 -0
- package/integration/command/copilot_quota.md +6 -0
- package/integration/command/glm_quota.md +6 -0
- package/integration/skills/copilot-quota/SKILL.md +11 -0
- package/integration/skills/glm-quota/SKILL.md +11 -0
- package/package.json +69 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { configureLogging, getLogger } from '../src/shared/logging.js'
|
|
3
|
+
|
|
4
|
+
const logger = getLogger('opencode-quota.cli.kimi')
|
|
5
|
+
const AUTH_JSON_PATH = `${process.env.HOME}/.local/share/opencode/auth.json`
|
|
6
|
+
|
|
7
|
+
interface ApiResponse<T> {
|
|
8
|
+
code?: number
|
|
9
|
+
msg?: string
|
|
10
|
+
data?: T
|
|
11
|
+
success?: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface LimitDetail {
|
|
15
|
+
limit?: number | null
|
|
16
|
+
used?: number | null
|
|
17
|
+
remaining?: number | null
|
|
18
|
+
reset_at?: string | null
|
|
19
|
+
resetTime?: string | null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface LimitWindow {
|
|
23
|
+
duration?: number | null
|
|
24
|
+
timeUnit?: string | null
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface LimitItem {
|
|
28
|
+
name?: string | null
|
|
29
|
+
title?: string | null
|
|
30
|
+
scope?: string | null
|
|
31
|
+
window?: LimitWindow | null
|
|
32
|
+
detail?: LimitDetail | null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface UsageData {
|
|
36
|
+
limit?: number | null
|
|
37
|
+
used?: number | null
|
|
38
|
+
remaining?: number | null
|
|
39
|
+
reset_at?: string | null
|
|
40
|
+
resetTime?: string | null
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface BalanceResponse {
|
|
44
|
+
usage?: UsageData | null
|
|
45
|
+
limits?: LimitItem[] | null
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function getCredentials(): Promise<string | null> {
|
|
49
|
+
try {
|
|
50
|
+
const authResp = await fetch(`file://${AUTH_JSON_PATH}`)
|
|
51
|
+
if (!authResp.ok) {
|
|
52
|
+
throw new Error('Failed to read auth.json')
|
|
53
|
+
}
|
|
54
|
+
const auth = await authResp.text()
|
|
55
|
+
const authJson = JSON.parse(auth)
|
|
56
|
+
const kimiData = authJson['kimi-for-coding'] || authJson.kimi || authJson.moonshot
|
|
57
|
+
if (!kimiData) {
|
|
58
|
+
logger.error('opencode-kimi-quota: Not configured. Run: opencode connect kimi-for-coding')
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
61
|
+
const kimiKey = typeof kimiData === 'string' ? kimiData : kimiData.key || kimiData.token
|
|
62
|
+
if (!kimiKey) {
|
|
63
|
+
logger.error('opencode-kimi-quota: Not configured. Run: opencode connect kimi-for-coding')
|
|
64
|
+
return null
|
|
65
|
+
}
|
|
66
|
+
return kimiKey
|
|
67
|
+
} catch {
|
|
68
|
+
logger.error('opencode-kimi-quota: Not configured. Run: opencode connect kimi')
|
|
69
|
+
return null
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function queryBalance(apiKey: string): Promise<BalanceResponse> {
|
|
74
|
+
const url = 'https://api.kimi.com/coding/v1/usages'
|
|
75
|
+
logger.debug(`Making request to: ${url}`)
|
|
76
|
+
logger.debug(`Method: GET`)
|
|
77
|
+
logger.debug(`Authorization: ${apiKey.substring(0, 20)}***`)
|
|
78
|
+
|
|
79
|
+
const response = await fetch(url, {
|
|
80
|
+
method: 'GET',
|
|
81
|
+
headers: {
|
|
82
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
83
|
+
'Accept': 'application/json',
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const statusCode = response.status
|
|
88
|
+
const body = await response.text()
|
|
89
|
+
|
|
90
|
+
logger.debug(`← Response: ${statusCode}, body: ${body.length} bytes`)
|
|
91
|
+
|
|
92
|
+
if (statusCode === 200) {
|
|
93
|
+
try {
|
|
94
|
+
const result = JSON.parse(body)
|
|
95
|
+
return {
|
|
96
|
+
usage: result.usage || null,
|
|
97
|
+
limits: result.limits || [],
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
logger.debug(`Failed to parse response: ${error}`)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (statusCode !== 200 && statusCode !== 401 && statusCode !== 403 && statusCode !== 404) {
|
|
105
|
+
throw new Error(`HTTP ${statusCode}: ${body.substring(0, 200)}`)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
usage: null,
|
|
110
|
+
limits: [],
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function formatDurationCompact(ms: number | string | undefined): string {
|
|
115
|
+
if (!ms) return ''
|
|
116
|
+
|
|
117
|
+
let timestamp: number
|
|
118
|
+
if (typeof ms === 'string') {
|
|
119
|
+
timestamp = new Date(ms).getTime()
|
|
120
|
+
} else {
|
|
121
|
+
timestamp = ms
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const now = Date.now()
|
|
125
|
+
const diffMs = timestamp - now
|
|
126
|
+
|
|
127
|
+
if (diffMs < 0) {
|
|
128
|
+
return 'now'
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const days = Math.floor(diffMs / (1000 * 60 * 60 * 24))
|
|
132
|
+
const hours = Math.floor((diffMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
|
|
133
|
+
const minutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60))
|
|
134
|
+
const seconds = Math.floor((diffMs % (1000 * 60)) / 1000)
|
|
135
|
+
|
|
136
|
+
const parts = []
|
|
137
|
+
if (days > 0) parts.push(`${days}d`)
|
|
138
|
+
if (hours > 0) parts.push(`${hours}h`)
|
|
139
|
+
if (minutes > 0) parts.push(`${minutes}m`)
|
|
140
|
+
if (seconds > 0 || parts.length === 0) parts.push(`${seconds}s`)
|
|
141
|
+
|
|
142
|
+
return parts.join(' ')
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function formatLimitLabel(item: LimitItem): string {
|
|
146
|
+
const window = item.window || {}
|
|
147
|
+
const duration = window.duration
|
|
148
|
+
let timeUnit = window.timeUnit
|
|
149
|
+
|
|
150
|
+
// Handle "TIME_UNIT_" prefix
|
|
151
|
+
if (timeUnit && timeUnit.startsWith('TIME_UNIT_')) {
|
|
152
|
+
timeUnit = timeUnit.replace('TIME_UNIT_', '')
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (duration == null) {
|
|
156
|
+
return item.name || item.title || item.scope || 'Unknown'
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (timeUnit === 'MINUTE') {
|
|
160
|
+
if (duration >= 60 && duration % 60 === 0) {
|
|
161
|
+
return `${duration / 60}h limit`
|
|
162
|
+
}
|
|
163
|
+
return `${duration}m limit`
|
|
164
|
+
}
|
|
165
|
+
if (timeUnit === 'HOUR') {
|
|
166
|
+
return `${duration}h limit`
|
|
167
|
+
}
|
|
168
|
+
if (timeUnit === 'DAY') {
|
|
169
|
+
return `${duration}d limit`
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return `${duration} ${timeUnit} limit`
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function formatUsage(balance: BalanceResponse): void {
|
|
176
|
+
console.log('')
|
|
177
|
+
console.log('Kimi Coding Plan Usage Statistics')
|
|
178
|
+
console.log('')
|
|
179
|
+
|
|
180
|
+
if (!balance.usage && (!balance.limits || balance.limits.length === 0)) {
|
|
181
|
+
console.log('No usage data available.')
|
|
182
|
+
console.log('')
|
|
183
|
+
console.log('Possible reasons:')
|
|
184
|
+
console.log(' - Not configured: Run `opencode connect kimi-for-coding`')
|
|
185
|
+
console.log(' - API key format mismatch')
|
|
186
|
+
console.log(' - No quota usage data available yet')
|
|
187
|
+
console.log('')
|
|
188
|
+
console.log('Please check your usage at:')
|
|
189
|
+
console.log(' https://platform.moonshot.ai/console')
|
|
190
|
+
console.log(' https://kimi-ai.chat/code/console')
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Display main usage summary
|
|
195
|
+
if (balance.usage) {
|
|
196
|
+
const { limit, used, remaining, reset_at, resetTime } = balance.usage
|
|
197
|
+
if (limit != null && used != null) {
|
|
198
|
+
const percentage = (used / limit) * 100
|
|
199
|
+
console.log(`Total Usage: ${used} / ${limit} (${percentage.toFixed(1)}% used)`)
|
|
200
|
+
console.log(`Remaining: ${remaining ?? (limit - used).toFixed(0)}`)
|
|
201
|
+
const resetTimeField = reset_at || resetTime
|
|
202
|
+
if (resetTimeField) {
|
|
203
|
+
const resetDate = new Date(resetTimeField)
|
|
204
|
+
console.log(`Next Reset: ${resetDate.toLocaleString()} (${formatDurationCompact(resetTimeField)})`)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
console.log('')
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Display detailed limits
|
|
211
|
+
if (balance.limits && balance.limits.length > 0) {
|
|
212
|
+
console.log('Usage Details:')
|
|
213
|
+
console.log('')
|
|
214
|
+
|
|
215
|
+
for (const item of balance.limits) {
|
|
216
|
+
const detail = (item.detail || item) as LimitItem & LimitDetail
|
|
217
|
+
const limit = detail.limit
|
|
218
|
+
const used = detail.used
|
|
219
|
+
const remaining = detail.remaining
|
|
220
|
+
const resetAt = detail.reset_at || detail.resetTime
|
|
221
|
+
|
|
222
|
+
if (limit != null) {
|
|
223
|
+
const label = formatLimitLabel(item)
|
|
224
|
+
console.log(` ${label}:`)
|
|
225
|
+
|
|
226
|
+
// Calculate used if not provided
|
|
227
|
+
const usedValue = used != null ? used : (remaining != null && limit != null ? limit - remaining : null)
|
|
228
|
+
|
|
229
|
+
if (usedValue != null) {
|
|
230
|
+
const percentage = (usedValue / limit) * 100
|
|
231
|
+
console.log(` Used: ${usedValue} / ${limit} (${percentage.toFixed(1)}% used)`)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (remaining != null) {
|
|
235
|
+
console.log(` Remaining: ${remaining}`)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (resetAt) {
|
|
239
|
+
const resetDate = new Date(resetAt)
|
|
240
|
+
console.log(` Next Reset: ${resetDate.toLocaleString()} (${formatDurationCompact(resetAt)})`)
|
|
241
|
+
}
|
|
242
|
+
console.log('')
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function showHelp(): void {
|
|
249
|
+
console.log('opencode-kimi-quota: Check Kimi Coding Plan quota from terminal')
|
|
250
|
+
console.log('')
|
|
251
|
+
console.log('Usage:')
|
|
252
|
+
console.log(' bun run bin/kimi-quota.ts [--debug|--raw]')
|
|
253
|
+
console.log('')
|
|
254
|
+
console.log('Options:')
|
|
255
|
+
console.log(' --debug, -d Enable debug logging')
|
|
256
|
+
console.log(' --raw Output raw JSON (default: formatted text)')
|
|
257
|
+
console.log('')
|
|
258
|
+
console.log('Environment:')
|
|
259
|
+
console.log(' LOG_LEVEL=debug Enable debug logging')
|
|
260
|
+
console.log('')
|
|
261
|
+
console.log('Authentication:')
|
|
262
|
+
console.log(' Reads from ~/.local/share/opencode/auth.json (kimi-for-coding, kimi, or moonshot provider)')
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
async function main(): Promise<void> {
|
|
266
|
+
const args = process.argv.slice(2)
|
|
267
|
+
const debugIndex = args.findIndex(a => a === '--debug' || a === '-d')
|
|
268
|
+
const rawIndex = args.findIndex(a => a === '--raw')
|
|
269
|
+
const helpIndex = args.findIndex(a => a === '--help' || a === '-h')
|
|
270
|
+
|
|
271
|
+
if (helpIndex !== -1) {
|
|
272
|
+
showHelp()
|
|
273
|
+
process.exit(0)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const rawOutput = rawIndex !== -1
|
|
277
|
+
|
|
278
|
+
if (debugIndex !== -1) {
|
|
279
|
+
configureLogging('debug')
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
logger.info('Starting opencode-kimi-quota CLI')
|
|
283
|
+
logger.debug(`Arguments: ${JSON.stringify({ debug: debugIndex !== -1, rawOutput, _: args })}`)
|
|
284
|
+
|
|
285
|
+
const apiKey = await getCredentials()
|
|
286
|
+
if (!apiKey) {
|
|
287
|
+
process.exit(1)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
const balance = await queryBalance(apiKey)
|
|
292
|
+
|
|
293
|
+
if (rawOutput) {
|
|
294
|
+
console.log(JSON.stringify(balance, null, 2))
|
|
295
|
+
process.exit(0)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
formatUsage(balance)
|
|
299
|
+
} catch (error) {
|
|
300
|
+
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
301
|
+
logger.error(`Error: ${errorMessage}`)
|
|
302
|
+
if (error instanceof Error && error.stack) {
|
|
303
|
+
logger.debug(`Stack: ${error.stack}`)
|
|
304
|
+
}
|
|
305
|
+
if (!rawOutput) {
|
|
306
|
+
console.log('')
|
|
307
|
+
console.log('Kimi Usage Check Failed')
|
|
308
|
+
console.log(`Error: ${errorMessage}`)
|
|
309
|
+
}
|
|
310
|
+
process.exit(1)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-quota.d.ts","sourceRoot":"","sources":["../../bin/copilot-quota.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
#!/usr/bin/env -S bun
|
|
2
|
+
/**
|
|
3
|
+
* GitHub Copilot quota CLI tool
|
|
4
|
+
* Fetches and displays GitHub Copilot usage statistics from command line
|
|
5
|
+
* Credentials are fetched from OpenCode's auth.json
|
|
6
|
+
*/
|
|
7
|
+
import * as https from 'https';
|
|
8
|
+
import * as os from 'os';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import { configureLogging, getLogger } from '../src/shared/logging.js';
|
|
11
|
+
const COMMAND_NAME = 'opencode-copilot-quota';
|
|
12
|
+
const AUTH_JSON_PATH = path.join(os.homedir(), '.local', 'share', 'opencode', 'auth.json');
|
|
13
|
+
// Global logger, assigned after configureLogging()
|
|
14
|
+
let logger;
|
|
15
|
+
/**
|
|
16
|
+
* Calculate duration until reset date
|
|
17
|
+
* @param resetDate - Reset date string (ISO 8601)
|
|
18
|
+
* @returns Human-readable duration (e.g., "7d 4h 32m 15s", "2h 57m 31s", "5m")
|
|
19
|
+
*/
|
|
20
|
+
function calculateDurationToReset(resetDate) {
|
|
21
|
+
const now = new Date();
|
|
22
|
+
const reset = new Date(resetDate);
|
|
23
|
+
const diffMs = reset.getTime() - now.getTime();
|
|
24
|
+
// If reset date is in the past, show "0d 0h 0m 0s"
|
|
25
|
+
if (diffMs <= 0) {
|
|
26
|
+
return '0d 0h 0m 0s';
|
|
27
|
+
}
|
|
28
|
+
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
29
|
+
const diffHours = Math.floor((diffMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
|
30
|
+
const diffMinutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60));
|
|
31
|
+
const diffSeconds = Math.floor((diffMs % (1000 * 60)) / 1000);
|
|
32
|
+
// Build duration string, hiding zero values
|
|
33
|
+
const parts = [];
|
|
34
|
+
if (diffDays > 0)
|
|
35
|
+
parts.push(`${diffDays}d`);
|
|
36
|
+
if (diffHours > 0)
|
|
37
|
+
parts.push(`${diffHours}h`);
|
|
38
|
+
if (diffMinutes > 0)
|
|
39
|
+
parts.push(`${diffMinutes}m`);
|
|
40
|
+
if (diffSeconds > 0)
|
|
41
|
+
parts.push(`${diffSeconds}s`);
|
|
42
|
+
return parts.length > 0 ? parts.join(' ') : '0s';
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse Copilot response and format output
|
|
46
|
+
* @param response - Raw JSON response string
|
|
47
|
+
* @returns Formatted output string
|
|
48
|
+
*/
|
|
49
|
+
function parseCopilotResponse(response) {
|
|
50
|
+
const data = JSON.parse(response);
|
|
51
|
+
const { login, copilot_plan, quota_reset_date_utc, quota_snapshots } = data;
|
|
52
|
+
// Format reset date and duration
|
|
53
|
+
const resetDate = new Date(quota_reset_date_utc)
|
|
54
|
+
.toLocaleDateString('en-US', {
|
|
55
|
+
year: 'numeric',
|
|
56
|
+
month: '2-digit',
|
|
57
|
+
day: '2-digit',
|
|
58
|
+
});
|
|
59
|
+
const duration = calculateDurationToReset(quota_reset_date_utc);
|
|
60
|
+
// Build formatted output (plain text, no boxes)
|
|
61
|
+
let output = '';
|
|
62
|
+
output += `GitHub Copilot Usage Statistics\n`;
|
|
63
|
+
output += `\n`;
|
|
64
|
+
output += `User: ${login}\n`;
|
|
65
|
+
output += `Plan: ${copilot_plan}\n`;
|
|
66
|
+
output += `Reset: ${resetDate} (${duration})\n`;
|
|
67
|
+
output += `\n`;
|
|
68
|
+
output += `QUOTA USAGE\n`;
|
|
69
|
+
output += `\n`;
|
|
70
|
+
// Chat
|
|
71
|
+
if (quota_snapshots.chat.unlimited) {
|
|
72
|
+
output += `Chat: Unlimited\n`;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const remaining = quota_snapshots.chat.percent_remaining ?? 0;
|
|
76
|
+
const used = 100 - remaining;
|
|
77
|
+
output += `Chat: ${used}% used\n`;
|
|
78
|
+
}
|
|
79
|
+
// Completions
|
|
80
|
+
if (quota_snapshots.completions.unlimited) {
|
|
81
|
+
output += `Completions: Unlimited\n`;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
const remaining = quota_snapshots.completions.percent_remaining ?? 0;
|
|
85
|
+
const used = 100 - remaining;
|
|
86
|
+
output += `Completions: ${used}% used\n`;
|
|
87
|
+
}
|
|
88
|
+
// Premium
|
|
89
|
+
const premium = quota_snapshots.premium_interactions;
|
|
90
|
+
if (premium.unlimited) {
|
|
91
|
+
output += `Premium: Unlimited\n`;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
const remaining = premium.quota_remaining ?? 0;
|
|
95
|
+
const entitlement = premium.entitlement ?? 0;
|
|
96
|
+
const used = entitlement - remaining;
|
|
97
|
+
const percentUsed = entitlement > 0 ? ((used / entitlement) * 100).toFixed(1) : '0.0';
|
|
98
|
+
output += `Premium: ${used.toFixed(2)} / ${entitlement} (${percentUsed}% used)\n`;
|
|
99
|
+
}
|
|
100
|
+
return output;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Make HTTPS request with timeout
|
|
104
|
+
*/
|
|
105
|
+
function makeRequest(url, token, headers = {}) {
|
|
106
|
+
logger.debug(`Making request to ${url}`);
|
|
107
|
+
logger.debug(`Using token: ${token.slice(0, 8)}...${token.slice(-4)}`);
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
const timeout = 10000; // 10 seconds
|
|
110
|
+
const timer = setTimeout(() => {
|
|
111
|
+
req.destroy();
|
|
112
|
+
logger.error(`Request timeout for ${url}`);
|
|
113
|
+
reject(new Error('Request timeout'));
|
|
114
|
+
}, timeout);
|
|
115
|
+
const urlObj = new URL(url);
|
|
116
|
+
const options = {
|
|
117
|
+
hostname: urlObj.hostname,
|
|
118
|
+
port: urlObj.port || 443,
|
|
119
|
+
path: urlObj.pathname + urlObj.search,
|
|
120
|
+
method: 'GET',
|
|
121
|
+
headers: {
|
|
122
|
+
'Authorization': `token ${token}`,
|
|
123
|
+
'Accept': 'application/json',
|
|
124
|
+
'Content-Type': 'application/json',
|
|
125
|
+
...headers,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
logger.debug(`Request options: ${JSON.stringify({
|
|
129
|
+
hostname: options.hostname,
|
|
130
|
+
path: options.path,
|
|
131
|
+
method: options.method,
|
|
132
|
+
headers: Object.fromEntries(Object.entries(options.headers).map(([k, v]) => [
|
|
133
|
+
k,
|
|
134
|
+
k === 'Authorization' ? `${v.slice(0, 13)}...${v.slice(-4)}` : v,
|
|
135
|
+
])),
|
|
136
|
+
})}`);
|
|
137
|
+
const req = https.request(options, (res) => {
|
|
138
|
+
let data = '';
|
|
139
|
+
logger.debug(`Response status: ${res.statusCode} ${res.statusMessage}`);
|
|
140
|
+
res.on('data', chunk => {
|
|
141
|
+
data += chunk;
|
|
142
|
+
});
|
|
143
|
+
res.on('end', () => {
|
|
144
|
+
clearTimeout(timer);
|
|
145
|
+
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
146
|
+
logger.debug(`Response received: ${data.slice(0, 100)}... (${data.length} bytes)`);
|
|
147
|
+
resolve(data);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
logger.error(`HTTP error: ${res.statusCode} ${res.statusMessage}`);
|
|
151
|
+
logger.debug(`Error response: ${data}`);
|
|
152
|
+
reject(new Error(`HTTP ${res.statusCode}: ${res.statusMessage}`));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
req.on('error', (err) => {
|
|
157
|
+
clearTimeout(timer);
|
|
158
|
+
logger.error(`Request error: ${err.message}`);
|
|
159
|
+
reject(err);
|
|
160
|
+
});
|
|
161
|
+
req.end();
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get credentials from OpenCode auth.json
|
|
166
|
+
*/
|
|
167
|
+
function getCredentials() {
|
|
168
|
+
logger.debug(`Looking for credentials at ${AUTH_JSON_PATH}`);
|
|
169
|
+
try {
|
|
170
|
+
const fs = require('fs');
|
|
171
|
+
if (!fs.existsSync(AUTH_JSON_PATH)) {
|
|
172
|
+
logger.debug('auth.json does not exist');
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
const content = fs.readFileSync(AUTH_JSON_PATH, 'utf-8');
|
|
176
|
+
const auth = JSON.parse(content);
|
|
177
|
+
logger.debug(`auth.json loaded with ${Object.keys(auth).length} providers`);
|
|
178
|
+
const copilotToken = auth['github-copilot']?.access ?? auth['github-copilot']?.refresh;
|
|
179
|
+
if (copilotToken) {
|
|
180
|
+
logger.info('Found credentials for provider: github-copilot');
|
|
181
|
+
return { token: copilotToken };
|
|
182
|
+
}
|
|
183
|
+
logger.debug('No credentials found for github-copilot provider');
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
logger.error(`Error reading auth.json: ${error}`);
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Display help message
|
|
193
|
+
*/
|
|
194
|
+
function showHelp() {
|
|
195
|
+
console.log(`
|
|
196
|
+
${COMMAND_NAME} - Check GitHub Copilot quota from terminal
|
|
197
|
+
|
|
198
|
+
USAGE:
|
|
199
|
+
bun run bin/copilot-quota.ts [--raw] [--debug]
|
|
200
|
+
|
|
201
|
+
OPTIONS:
|
|
202
|
+
--raw Output raw JSON (default: formatted output)
|
|
203
|
+
--debug, -d Enable debug logging (logs hidden by default)
|
|
204
|
+
--help, -h Display this help message
|
|
205
|
+
|
|
206
|
+
AUTHENTICATION:
|
|
207
|
+
Reads credentials from ~/.local/share/opencode/auth.json
|
|
208
|
+
Provider: github-copilot
|
|
209
|
+
|
|
210
|
+
EXAMPLES:
|
|
211
|
+
bun run bin/copilot-quota.ts
|
|
212
|
+
bun run bin/copilot-quota.ts --debug
|
|
213
|
+
bun run bin/copilot-quota.ts --raw
|
|
214
|
+
`);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Main CLI entry point
|
|
218
|
+
*/
|
|
219
|
+
async function main() {
|
|
220
|
+
const args = process.argv.slice(2);
|
|
221
|
+
// Check for help flag first (before logging config)
|
|
222
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
223
|
+
showHelp();
|
|
224
|
+
process.exit(0);
|
|
225
|
+
}
|
|
226
|
+
// Check for debug flag before configuring logging
|
|
227
|
+
const debugMode = args.includes('--debug') || args.includes('-d');
|
|
228
|
+
// Only configure logging when --debug is present
|
|
229
|
+
if (debugMode) {
|
|
230
|
+
await configureLogging('debug');
|
|
231
|
+
}
|
|
232
|
+
// Create logger after configureLogging (or with no-op if not configured)
|
|
233
|
+
if (debugMode) {
|
|
234
|
+
logger = getLogger(['opencode-quota', 'cli', 'copilot']);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
// No-op logger when debug mode is off
|
|
238
|
+
logger = {
|
|
239
|
+
debug: () => { },
|
|
240
|
+
info: () => { },
|
|
241
|
+
warn: () => { },
|
|
242
|
+
error: () => { },
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
logger.info(`${COMMAND_NAME} starting...`);
|
|
246
|
+
const rawOutput = args.includes('--raw');
|
|
247
|
+
logger.debug(`Arguments: ${args.join(' ')}`);
|
|
248
|
+
logger.debug(`Raw output: ${rawOutput}`);
|
|
249
|
+
try {
|
|
250
|
+
// Get credentials from OpenCode auth.json
|
|
251
|
+
const credentials = getCredentials();
|
|
252
|
+
if (!credentials) {
|
|
253
|
+
logger.error('No credentials found');
|
|
254
|
+
console.error(`\n${COMMAND_NAME}: Not configured.\nPlease connect to GitHub Copilot in OpenCode first.\n`);
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
// Query GitHub Copilot internal API
|
|
258
|
+
const customHeaders = {
|
|
259
|
+
'X-GitHub-Api-Version': '2025-04-01',
|
|
260
|
+
'User-Agent': 'GitHubCopilotChat/0.26.7',
|
|
261
|
+
'Editor-Version': 'vscode/1.96.2',
|
|
262
|
+
};
|
|
263
|
+
logger.info('Querying GitHub Copilot internal API...');
|
|
264
|
+
const response = await makeRequest('https://api.github.com/copilot_internal/user', credentials.token, customHeaders);
|
|
265
|
+
logger.info('Received response from GitHub API');
|
|
266
|
+
if (!rawOutput) {
|
|
267
|
+
// Parse and display formatted output
|
|
268
|
+
try {
|
|
269
|
+
const formatted = parseCopilotResponse(response);
|
|
270
|
+
console.log(formatted);
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
logger.error(`Failed to parse Copilot response: ${error}`);
|
|
274
|
+
logger.debug(`Invalid response: ${response}`);
|
|
275
|
+
throw new Error(`Parse error: ${error instanceof Error ? error.message : String(error)}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
// Print raw response
|
|
280
|
+
console.log(response);
|
|
281
|
+
}
|
|
282
|
+
logger.info('Completed successfully');
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
if (error instanceof Error) {
|
|
286
|
+
logger.error(`${error.name}: ${error.message}`);
|
|
287
|
+
console.error(`\n${COMMAND_NAME}: ${error.message}\n`);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
logger.error(`Unknown error: ${String(error)}`);
|
|
291
|
+
console.error(`\n${COMMAND_NAME}: Unknown error occurred\n`);
|
|
292
|
+
}
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// Run CLI
|
|
297
|
+
main();
|
|
298
|
+
//# sourceMappingURL=copilot-quota.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-quota.js","sourceRoot":"","sources":["../../bin/copilot-quota.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glm-quota.d.ts","sourceRoot":"","sources":["../../bin/glm-quota.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
|