import { readAuthFile } from '../../opencode/auth.js'; import { getAuthEntry, normalizeAuthEntry, buildResult, toUsageWindow, toNumber, toTimestamp } from '../utils/index.js'; const buildCopilotWindows = (payload) => { const quota = payload?.quota_snapshots ?? {}; const resetAt = toTimestamp(payload?.quota_reset_date); const windows = {}; const addWindow = (label, snapshot) => { if (!snapshot) return; const entitlement = toNumber(snapshot.entitlement); const remaining = toNumber(snapshot.remaining); const usedPercent = entitlement && remaining !== null ? Math.max(0, Math.min(100, 100 - (remaining / entitlement) * 100)) : null; const valueLabel = entitlement !== null && remaining !== null ? `${remaining.toFixed(0)} / ${entitlement.toFixed(0)} left` : null; windows[label] = toUsageWindow({ usedPercent, windowSeconds: null, resetAt, valueLabel }); }; addWindow('chat', quota.chat); addWindow('completions', quota.completions); addWindow('premium', quota.premium_interactions); return windows; }; export const providerId = 'github-copilot'; export const providerName = 'GitHub Copilot'; export const aliases = ['github-copilot', 'copilot']; export const isConfigured = () => { const auth = readAuthFile(); const entry = normalizeAuthEntry(getAuthEntry(auth, aliases)); return Boolean(entry?.access || entry?.token); }; export const fetchQuota = async () => { const auth = readAuthFile(); const entry = normalizeAuthEntry(getAuthEntry(auth, aliases)); const accessToken = entry?.access ?? entry?.token; if (!accessToken) { return buildResult({ providerId, providerName, ok: false, configured: false, error: 'Not configured' }); } try { const response = await fetch('https://api.github.com/copilot_internal/user', { method: 'GET', headers: { Authorization: `token ${accessToken}`, Accept: 'application/json', 'Editor-Version': 'vscode/1.96.2', 'X-Github-Api-Version': '2025-04-01' } }); if (!response.ok) { return buildResult({ providerId, providerName, ok: false, configured: true, error: `API error: ${response.status}` }); } const payload = await response.json(); return buildResult({ providerId, providerName, ok: true, configured: true, usage: { windows: buildCopilotWindows(payload) } }); } catch (error) { return buildResult({ providerId, providerName, ok: false, configured: true, error: error instanceof Error ? error.message : 'Request failed' }); } }; export const providerIdAddon = 'github-copilot-addon'; export const providerNameAddon = 'GitHub Copilot Add-on'; export const fetchQuotaAddon = async () => { const auth = readAuthFile(); const entry = normalizeAuthEntry(getAuthEntry(auth, aliases)); const accessToken = entry?.access ?? entry?.token; if (!accessToken) { return buildResult({ providerId: providerIdAddon, providerName: providerNameAddon, ok: false, configured: false, error: 'Not configured' }); } try { const response = await fetch('https://api.github.com/copilot_internal/user', { method: 'GET', headers: { Authorization: `token ${accessToken}`, Accept: 'application/json', 'Editor-Version': 'vscode/1.96.2', 'X-Github-Api-Version': '2025-04-01' } }); if (!response.ok) { return buildResult({ providerId: providerIdAddon, providerName: providerNameAddon, ok: false, configured: true, error: `API error: ${response.status}` }); } const payload = await response.json(); const windows = buildCopilotWindows(payload); const premium = windows.premium ? { premium: windows.premium } : windows; return buildResult({ providerId: providerIdAddon, providerName: providerNameAddon, ok: true, configured: true, usage: { windows: premium } }); } catch (error) { return buildResult({ providerId: providerIdAddon, providerName: providerNameAddon, ok: false, configured: true, error: error instanceof Error ? error.message : 'Request failed' }); } };