()
| 80 | } |
| 81 | |
| 82 | async function runSetup(): Promise<void> { |
| 83 | const existing = resolveApiKey(); |
| 84 | if (existing) { |
| 85 | console.log("Existing API key found. Running smoke test..."); |
| 86 | } else { |
| 87 | console.log("No API key found. Please enter your OpenAI API key."); |
| 88 | console.log("Get one at: https://platform.openai.com/api-keys"); |
| 89 | console.log("(Needs image generation permissions)\n"); |
| 90 | |
| 91 | // Read from stdin |
| 92 | process.stdout.write("API key: "); |
| 93 | const reader = Bun.stdin.stream().getReader(); |
| 94 | const { value } = await reader.read(); |
| 95 | reader.releaseLock(); |
| 96 | const key = new TextDecoder().decode(value).trim(); |
| 97 | |
| 98 | if (!key || !key.startsWith("sk-")) { |
| 99 | console.error("Invalid key. Must start with 'sk-'."); |
| 100 | process.exit(1); |
| 101 | } |
| 102 | |
| 103 | saveApiKey(key); |
| 104 | console.log("Key saved to ~/.gstack/openai.json (0600 permissions)."); |
| 105 | } |
| 106 | |
| 107 | // Smoke test |
| 108 | console.log("\nRunning smoke test (generating a simple image)..."); |
| 109 | try { |
| 110 | await generate({ |
| 111 | brief: "A simple blue square centered on a white background. Minimal, geometric, clean.", |
| 112 | output: "/tmp/gstack-design-smoke-test.png", |
| 113 | size: "1024x1024", |
| 114 | quality: "low", |
| 115 | }); |
| 116 | console.log("\nSmoke test PASSED. Design generation is working."); |
| 117 | } catch (err: any) { |
| 118 | console.error(`\nSmoke test FAILED: ${err.message}`); |
| 119 | console.error("Check your API key and organization verification status."); |
| 120 | process.exit(1); |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | async function main(): Promise<void> { |
| 125 | const { command, flags, positionals } = parseArgs(process.argv); |
no test coverage detected