Download packages/ai/src/cli.ts from SaylorTwift/pi: direct link, hf CLI and curl.
- Browser
- Download file 4.3 kB
-
https://huggingface.co/SaylorTwift/pi/resolve/main/packages/ai/src/cli.ts
- Command line
-
hf download hf://SaylorTwift/pi/packages/ai/src/cli.ts
-
curl -L -o cli.ts https://huggingface.co/SaylorTwift/pi/resolve/main/packages/ai/src/cli.ts
4.3 kB
| import { existsSync, readFileSync, writeFileSync } from "node:fs"; | |
| import { createInterface } from "node:readline"; | |
| import type { AuthPrompt, OAuthCredential, Provider } from "./index.ts"; | |
| import { builtinProviders } from "./providers/all.ts"; | |
| const AUTH_FILE = "auth.json"; | |
| const PROVIDERS = builtinProviders().filter( | |
| (provider): provider is Provider & { auth: { oauth: NonNullable<Provider["auth"]["oauth"]> } } => | |
| provider.auth.oauth !== undefined, | |
| ); | |
| function prompt(rl: ReturnType<typeof createInterface>, question: string): Promise<string> { | |
| return new Promise((resolve) => rl.question(question, resolve)); | |
| } | |
| function loadAuth(): Record<string, OAuthCredential> { | |
| if (!existsSync(AUTH_FILE)) return {}; | |
| try { | |
| return JSON.parse(readFileSync(AUTH_FILE, "utf-8")) as Record<string, OAuthCredential>; | |
| } catch { | |
| return {}; | |
| } | |
| } | |
| function saveAuth(auth: Record<string, OAuthCredential>): void { | |
| writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), "utf-8"); | |
| } | |
| async function answerPrompt(rl: ReturnType<typeof createInterface>, authPrompt: AuthPrompt): Promise<string> { | |
| if (authPrompt.type === "select") { | |
| console.log(`\n${authPrompt.message}`); | |
| for (let index = 0; index < authPrompt.options.length; index++) { | |
| console.log(` ${index + 1}. ${authPrompt.options[index].label}`); | |
| } | |
| const choice = Number.parseInt(await prompt(rl, `Enter number (1-${authPrompt.options.length}): `), 10) - 1; | |
| const selected = authPrompt.options[choice]; | |
| if (!selected) throw new Error("Invalid selection"); | |
| return selected.id; | |
| } | |
| return prompt(rl, `${authPrompt.message}${authPrompt.placeholder ? ` (${authPrompt.placeholder})` : ""}: `); | |
| } | |
| async function login(providerId: string): Promise<void> { | |
| const provider = PROVIDERS.find((entry) => entry.id === providerId); | |
| if (!provider) throw new Error(`Unknown provider: ${providerId}`); | |
| const rl = createInterface({ input: process.stdin, output: process.stdout }); | |
| try { | |
| const credential = await provider.auth.oauth.login({ | |
| signal: new AbortController().signal, | |
| prompt: (authPrompt) => answerPrompt(rl, authPrompt), | |
| notify: (event) => { | |
| switch (event.type) { | |
| case "auth_url": | |
| console.log(`\nOpen this URL in your browser:\n${event.url}`); | |
| if (event.instructions) console.log(event.instructions); | |
| break; | |
| case "device_code": | |
| console.log(`\nOpen this URL in your browser:\n${event.verificationUri}`); | |
| console.log(`Enter code: ${event.userCode}`); | |
| break; | |
| case "info": | |
| case "progress": | |
| console.log(event.message); | |
| break; | |
| } | |
| }, | |
| }); | |
| const auth = loadAuth(); | |
| auth[providerId] = credential; | |
| saveAuth(auth); | |
| console.log(`\nCredentials saved to ${AUTH_FILE}`); | |
| } finally { | |
| rl.close(); | |
| } | |
| } | |
| async function main(): Promise<void> { | |
| const args = process.argv.slice(2); | |
| const command = args[0]; | |
| if (!command || command === "help" || command === "--help" || command === "-h") { | |
| const providerList = PROVIDERS.map((provider) => ` ${provider.id.padEnd(20)} ${provider.name}`).join("\n"); | |
| console.log( | |
| `Usage: npx @earendil-works/pi-ai <command> [provider]\n\nCommands:\n login [provider] Login to an OAuth provider\n list List available providers\n\nProviders:\n${providerList}`, | |
| ); | |
| return; | |
| } | |
| if (command === "list") { | |
| for (const provider of PROVIDERS) console.log(`${provider.id.padEnd(20)} ${provider.name}`); | |
| return; | |
| } | |
| if (command === "login") { | |
| let providerId = args[1]; | |
| if (!providerId) { | |
| const rl = createInterface({ input: process.stdin, output: process.stdout }); | |
| try { | |
| for (let index = 0; index < PROVIDERS.length; index++) { | |
| console.log(` ${index + 1}. ${PROVIDERS[index].name}`); | |
| } | |
| const index = Number.parseInt(await prompt(rl, `Enter number (1-${PROVIDERS.length}): `), 10) - 1; | |
| providerId = PROVIDERS[index]?.id; | |
| } finally { | |
| rl.close(); | |
| } | |
| } | |
| if (!providerId || !PROVIDERS.some((provider) => provider.id === providerId)) { | |
| throw new Error(`Unknown provider: ${providerId ?? ""}`); | |
| } | |
| await login(providerId); | |
| return; | |
| } | |
| throw new Error(`Unknown command: ${command}`); | |
| } | |
| main().catch((error: unknown) => { | |
| console.error("Error:", error instanceof Error ? error.message : String(error)); | |
| process.exit(1); | |
| }); | |