Add ai setup command to configure openrouter key#126
Conversation
WalkthroughAdds ChangesAI Setup Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/api/ai.ts`:
- Around line 13-21: Trim the incoming API key before validating and returning
it: in the API parsing logic for data.apiKey (and similarly for data.maskedKey
if you want consistency), call .trim() on the string, then check typeof ===
'string' and trimmed.length > 0; if invalid, throw the existing CLIError,
otherwise return the trimmed apiKey (and trimmed maskedKey when present) in the
returned object so whitespace-only or whitespace-padded keys are rejected and
stored normalized.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3f66d55e-cd19-4770-b3f2-527d59835588
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (7)
README.mdsrc/commands/ai/index.tssrc/commands/ai/setup.test.tssrc/commands/ai/setup.tssrc/index.tssrc/lib/api/ai.test.tssrc/lib/api/ai.ts
jwfing
left a comment
There was a problem hiding this comment.
Code Review — ai setup command
Summary: Adds npx @insforge/cli ai setup to fetch the linked project's OpenRouter key and write it to a local env file. The implementation is well-scoped, follows project conventions, handles the security-sensitive raw-key exposure correctly, and ships with meaningful test coverage.
Requirements context: No /docs/superpowers/ directory found in this repo — review is assessed against the PR description alone.
Findings
Critical
(none)
Suggestion
[Software Engineering] Missing test for the skipped case in runAiSetup
src/commands/ai/setup.test.ts
There is no test covering the path where OPENROUTER_API_KEY already exists in the env file with the same value (the skipped case). The upsertEnvFile logic itself is tested in env-writer.test.ts, but runAiSetup's behavior when the result has skipped: ['OPENROUTER_API_KEY'] (including the log output in non-JSON mode and the returned skipped array) is unverified. Low blast radius, but the existing key match is a common real-world scenario worth covering.
[Software Engineering] No loading indicator during the API fetch in interactive mode
src/commands/ai/setup.ts:51
const key = await getOpenRouterApiKey();When !opts.json, the command shows clack.intro then immediately awaits the API call with no spinner. If the backend is slow, users see nothing for several seconds. The posthog setup command uses a clack.spinner() around its polling loop. A spinner around getOpenRouterApiKey() would give consistent UX and avoid the "is it frozen?" feeling.
[Functionality] No friendly 404 error message for the AI endpoint
src/lib/api/oss.ts / src/lib/api/ai.ts
ossFetch has custom 404 handling for /api/compute, /api/payments, and /api/database/migrations. The /api/ai/openrouter/api-key path is absent from that list. If a self-hosted instance doesn't have Model Gateway enabled, users get the generic "OSS request failed: 404". A specific message in getOpenRouterApiKey() (or an extra branch in ossFetch) — e.g. "AI gateway is not configured on this backend. See the InsForge dashboard AI page to enable Model Gateway." — would match the pattern used elsewhere and reduce friction for self-hosters.
Information
[Software Engineering] Duplicate description call for the ai command
src/commands/ai/index.ts:4 and src/index.ts:212
// src/index.ts
const aiCmd = program.command('ai').description('Manage AI model gateway setup');
// src/commands/ai/index.ts
aiCmd.description('Manage AI model gateway setup');The description is set twice with the same string. The second call (in registerAiCommands) silently overwrites the first. Harmless, but one of them is redundant — the registration function already sets it, so the call-site in src/index.ts can drop .description(...).
[Security] Positive note — raw key never leaks into result or analytics
AiSetupResult only exposes maskedKey; the raw apiKey is never serialised into the command output, JSON result, or analytics event. The explicit test 'does not return the raw key in the setup result' (setup.test.ts:44–47) correctly guards this. The README and CLI output warnings about NEXT_PUBLIC_ / VITE_ / PUBLIC_ prefixes are a nice touch.
Verdict
approved (informational — explicit GitHub approval is a separate human action)
Zero critical findings. The PR is clean, well-tested for the key paths, follows the existing command/test conventions closely, and handles the security-sensitive key exposure correctly. The suggestions above are worth a follow-up but are not blocking.
Greptile SummaryAdds a new
Confidence Score: 5/5Safe to merge — the new command writes a local env file and updates gitignore; no existing behavior is modified. The change is self-contained: a new CLI subcommand backed by a new API helper and a small additive patch to the 404 handler in ossFetch. The raw key never surfaces in JSON output or analytics events. The gitignore-update logic is correct and fully covered by tests, including the edge case of non-default local env file names. No existing command paths are touched. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
actor User
participant CLI as npx @insforge/cli
participant Config as getProjectConfig
participant Backend as InsForge Backend
participant FS as File System
User->>CLI: ai setup [--env-file .env.local] [--json]
CLI->>Config: getProjectConfig()
Config-->>CLI: "{ project_id, api_key, oss_host, ... }"
CLI->>Backend: GET /api/ai/openrouter/api-key
alt Backend lacks Model Gateway
Backend-->>CLI: 404 NOT_FOUND
CLI-->>User: CLIError: Upgrade InsForge project
else Key missing or whitespace
Backend-->>CLI: "200 { apiKey: "" }"
CLI-->>User: CLIError: AI gateway returned no key
else Success
Backend-->>CLI: "200 { apiKey, maskedKey }"
end
CLI->>FS: "upsertEnvFile(envPath, { OPENROUTER_API_KEY: apiKey })"
FS-->>CLI: "{ added, skipped, mismatched }"
CLI->>FS: ensureLocalEnvIgnored(cwd, envFile)
FS-->>CLI: gitignoreUpdated (bool)
CLI->>CLI: captureEvent(analytics)
alt --json flag
CLI-->>User: "{ success, envFile, added, skipped, mismatched, maskedKey }"
else interactive
CLI-->>User: clack output (Wrote .env.local, gitignore updated, ...)
end
Reviews (2): Last reviewed commit: "bump CLI version" | Re-trigger Greptile |
There was a problem hiding this comment.
No issues found across 8 files
Tip: cubic could auto-approve low-risk PRs like this, if it thinks it's safe to merge. Learn more
Summary by cubic
Adds
ai setupto@insforge/clito configure the InsForge Model Gateway by fetching the project’s OpenRouter key and writingOPENROUTER_API_KEYto an env file with safe defaults. Bumps the CLI to0.1.78.New Features
npx @insforge/cli ai setupwritesOPENROUTER_API_KEY(defaults to.env.local).--env-file <path>and--json..env*.localto.gitignoreonly for local env files inside the project.maskedKey; the raw key is never returned.Bug Fixes
Written for commit 922d7ef. Summary will update on new commits.
Summary by CodeRabbit
New Features
aicommand withsetupsubcommand to fetch and store an OpenRouter API key (supports custom env file and JSON output)Documentation
Behavior
Tests
Chores
Note
Add
ai setupcommand to fetch and write OpenRouter API key to an env fileai setupCLI subcommand that fetches the project'sOPENROUTER_API_KEYfrom the backend viagetOpenRouterApiKeyand writes it to an env file (default.env.local) usingupsertEnvFile..env*.localto.gitignorewhen the target file is a local env file inside the project and no equivalent ignore rule exists.--env-fileto target a custom env file and--jsonfor machine-readable output; the JSON result includes amaskedKeybut never the raw key.Changes since #126 opened
ai setupcommand to configureopenrouterAPI key [922d7ef].gitignoreupdate logic for non-default local environment files [e3e580e]Macroscope summarized 3c0fa38.