UNPKG

@nanocollective/nanocoder

Version:

A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter

81 lines 2.78 kB
/** * User-level storage for GitHub Copilot credentials. * The stored token is the GitHub OAuth access token from the device flow * (used to obtain short-lived Copilot API tokens). Stored under config path * (e.g. ~/.config/nanocoder/) so they are not in project config. */ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync, } from 'fs'; import { join } from 'path'; import { clearCopilotTokenCache } from '../auth/github-copilot.js'; import { getConfigPath } from '../config/paths.js'; const FILENAME = 'copilot-credentials.json'; /** Shared message when no Copilot credential is found (used by provider-factory and client-factory). */ export function getCopilotNoCredentialsMessage(providerName) { return `No Copilot credentials for "${providerName}". Type /copilot-login in the chat to log in, or run: nanocoder copilot login (from project: node dist/cli.js copilot login)`; } function getCredentialsPath() { return join(getConfigPath(), FILENAME); } function loadStore() { const path = getCredentialsPath(); if (!existsSync(path)) { return {}; } try { const raw = readFileSync(path, 'utf-8'); const data = JSON.parse(raw); if (data !== null && typeof data === 'object' && !Array.isArray(data)) { return data; } } catch { // Invalid or unreadable } return {}; } function writeStore(store) { const dir = getConfigPath(); if (!existsSync(dir)) { mkdirSync(dir, { recursive: true }); } const filePath = getCredentialsPath(); writeFileSync(filePath, JSON.stringify(store, null, 2), { encoding: 'utf-8', mode: 0o600, }); chmodSync(filePath, 0o600); } /** * Get stored Copilot credential for a provider name (e.g. "GitHub Copilot"). */ export function loadCopilotCredential(providerName) { const store = loadStore(); const entry = store[providerName]; if (!entry || typeof entry.oauthToken !== 'string') { return null; } return { oauthToken: entry.oauthToken, enterpriseUrl: typeof entry.enterpriseUrl === 'string' ? entry.enterpriseUrl : undefined, }; } /** * Save GitHub OAuth token (from device flow) for a provider name. */ export function saveCopilotCredential(providerName, oauthToken, enterpriseUrl) { const store = loadStore(); store[providerName] = { oauthToken, enterpriseUrl }; writeStore(store); } /** * Remove stored credential for a provider name. */ export function removeCopilotCredential(providerName) { const store = loadStore(); if (providerName in store) { delete store[providerName]; writeStore(store); clearCopilotTokenCache(); } } //# sourceMappingURL=copilot-credentials.js.map