mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-06 05:35:46 +02:00
a4dd5b0c2e
Stateless CLI (design/dist/design) wrapping OpenAI Responses API for UI mockup generation. Three working commands: - generate: brief -> PNG mockup via gpt-4o + image_generation tool - check: vision-based quality gate via GPT-4o (text readability, layout completeness, visual coherence) - compare: generates self-contained HTML comparison board with star ratings, radio Pick, per-variant feedback, regenerate controls, and Submit button that writes structured JSON for agent polling Auth reads from ~/.gstack/openai.json (0600), falls back to OPENAI_API_KEY env var. Compiled separately from browse binary (openai added to devDependencies, not runtime deps). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
/**
|
|
* Auth resolution for OpenAI API access.
|
|
*
|
|
* Resolution order:
|
|
* 1. ~/.gstack/openai.json → { "api_key": "sk-..." }
|
|
* 2. OPENAI_API_KEY environment variable
|
|
* 3. null (caller handles guided setup or fallback)
|
|
*/
|
|
|
|
import fs from "fs";
|
|
import path from "path";
|
|
|
|
const CONFIG_PATH = path.join(process.env.HOME || "~", ".gstack", "openai.json");
|
|
|
|
export function resolveApiKey(): string | null {
|
|
// 1. Check ~/.gstack/openai.json
|
|
try {
|
|
if (fs.existsSync(CONFIG_PATH)) {
|
|
const content = fs.readFileSync(CONFIG_PATH, "utf-8");
|
|
const config = JSON.parse(content);
|
|
if (config.api_key && typeof config.api_key === "string") {
|
|
return config.api_key;
|
|
}
|
|
}
|
|
} catch {
|
|
// Fall through to env var
|
|
}
|
|
|
|
// 2. Check environment variable
|
|
if (process.env.OPENAI_API_KEY) {
|
|
return process.env.OPENAI_API_KEY;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Save an API key to ~/.gstack/openai.json with 0600 permissions.
|
|
*/
|
|
export function saveApiKey(key: string): void {
|
|
const dir = path.dirname(CONFIG_PATH);
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
fs.writeFileSync(CONFIG_PATH, JSON.stringify({ api_key: key }, null, 2));
|
|
fs.chmodSync(CONFIG_PATH, 0o600);
|
|
}
|
|
|
|
/**
|
|
* Get API key or exit with setup instructions.
|
|
*/
|
|
export function requireApiKey(): string {
|
|
const key = resolveApiKey();
|
|
if (!key) {
|
|
console.error("No OpenAI API key found.");
|
|
console.error("");
|
|
console.error("Run: $D setup");
|
|
console.error(" or save to ~/.gstack/openai.json: { \"api_key\": \"sk-...\" }");
|
|
console.error(" or set OPENAI_API_KEY environment variable");
|
|
console.error("");
|
|
console.error("Get a key at: https://platform.openai.com/api-keys");
|
|
process.exit(1);
|
|
}
|
|
return key;
|
|
}
|