Supercode cli#209
Conversation
…functionality: - Bumped version in package.json to 0.1.68. - Added connection type to AI provider interface to distinguish between direct and proxy connections. - Updated various AI provider implementations to include connection type handling. - Enhanced chat and status row components to display connection type in the UI. - Improved model selection process to support new providers and models.
…functionality: - Bumped version in package.json to 0.1.69. - Added "supercode" as a new model provider in the AI provider interface. - Updated default provider in chat and agent chat functions to "supercode". - Refactored model selection to distinguish between cloud and BYOK models. - Enhanced error handling for API key configuration in the createProvider function.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
WalkthroughThe CLI now defaults to Supercode Cloud, supports Cloud and BYOK model selection, propagates direct/proxy connection metadata through chat UI, reads provider environment settings dynamically, and updates package metadata. ChangesSupercode provider integration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant ModelPicker
participant Chat
participant Provider
participant ServerProxyService
participant StatusBar
User->>ModelPicker: Select provider and model
ModelPicker-->>Chat: Return provider and model
Chat->>Provider: Create selected provider
Provider->>ServerProxyService: Send proxy request for Supercode
ServerProxyService-->>Chat: Return AI response
Chat->>StatusBar: Set connection type
StatusBar-->>User: Render cloud or key indicator
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 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 `@apps/supercode-cli/server/package.json.bak2`:
- Around line 1-84: Delete the committed backup artifact package.json.bak2. In
the active package.json, update the build:cli script to use a Linux-compatible
shebang replacement instead of macOS-only sed -i '', and remove dotenv from
devDependencies while leaving the remaining manifest entries unchanged.
In `@apps/supercode-cli/server/src/cli/ai/chat/chat.ts`:
- Around line 1914-1924: Update the /connect switching logic around
createProvider so modelToUse falls back to the previous provider.modelName only
when result.provider matches the current provider; otherwise use the newly
created provider.modelName. Ensure saveCliConfig persists the resolved new
provider model rather than carrying the previous provider’s model across
providers.
In `@apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts`:
- Around line 73-77: Update the hint mapping in the modelsForProvider display
flow to use each model’s existing cost value without appending an additional “x”
suffix. Preserve the empty hint for free models.
- Around line 12-18: Update the PROVIDERS list used by the /connect command to
include a MiniMax entry with value "minimax", an appropriate label and hint, and
the MiniMax API-key URL, matching the existing provider entry shape.
In `@apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts`:
- Around line 399-444: Preserve cancellation through both prompt flows: in
apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts lines 399-444,
return the current provider/model or an explicit canceled result when the
API-key or custom-model prompt is canceled instead of returning a newly selected
provider; in apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts
lines 81-111, detect cancellation from either model prompt and abort the connect
result rather than treating it as a successful provider change.
- Around line 124-153: Initialize ModelPicker.selected to the index of the first
non-section entry in MODELS, rather than 0, so the initial Enter action selects
an actual model. Use the existing isSection logic or equivalent normalization
while preserving the current section filtering and rendering behavior in render.
- Around line 225-226: Update the hasNext display in the model listing logic to
report the actual number of models remaining after the current window, rather
than the current window size represented by endIdx - startIdx. Use the available
collection length and endIdx to calculate the remaining count while preserving
the existing formatting and conditional behavior.
In `@apps/supercode-cli/server/src/cli/utils/tui.ts`:
- Line 788: Initialize the footer connection indicator during the initial chat
setup by calling setConnectionType with provider.connectionType alongside the
existing setModel call, before mounting the footer. Apply the same
initialization in the additional setup path identified by the comment, while
preserving the existing model and context-window initialization.
🪄 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: d11f4e53-f4ba-48be-97a9-91c1caa2c7d1
📒 Files selected for processing (16)
apps/supercode-cli/server/package.jsonapps/supercode-cli/server/package.json.bak2apps/supercode-cli/server/src/cli/ai/chat/chat.tsapps/supercode-cli/server/src/cli/ai/chat/chatAgent.tsapps/supercode-cli/server/src/cli/ai/chat/step-status-row.tsapps/supercode-cli/server/src/cli/ai/provider.tsapps/supercode-cli/server/src/cli/commands/slashCommands/connect.tsapps/supercode-cli/server/src/cli/commands/slashCommands/help.tsapps/supercode-cli/server/src/cli/commands/slashCommands/model.tsapps/supercode-cli/server/src/cli/utils/tui.tsapps/supercode-cli/server/src/config/google.config.tsapps/supercode-cli/server/src/config/mergedev.config.tsapps/supercode-cli/server/src/config/minimax.config.tsapps/supercode-cli/server/src/config/nvidia.config.tsapps/supercode-cli/server/src/config/openrouter.config.tsapps/supercode-cli/server/src/lib/cli-config.ts
| { | ||
| "name": "supercode-cli", | ||
| "version": "0.1.58", | ||
| "description": "AI-powered coding agent CLI", | ||
| "main": "dist/main.js", | ||
| "bin": { | ||
| "supercode": "dist/main.js" | ||
| }, | ||
| "scripts": { | ||
| "dev": "bun src/index.ts", | ||
| "dev:cli": "bun src/cli/main.ts", | ||
| "start": "bun src/index.ts", | ||
| "build": "bun run build:cli", | ||
| "build:cli": "bun build --target node --packages bundle --outdir dist --entry ./src/cli/main.ts --external @modelcontextprotocol/sdk && sed -i '' 's|#!/usr/bin/env bun|#!/usr/bin/env node|' dist/main.js", | ||
| "test": "bun test", | ||
| "typecheck": "tsc --noEmit", | ||
| "db:generate": "prisma generate", | ||
| "prepublishOnly": "bun run build:cli" | ||
| }, | ||
| "type": "module", | ||
| "files": [ | ||
| "dist/main.js", | ||
| "README.md" | ||
| ], | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/yashdev9274/supercli.git" | ||
| }, | ||
| "keywords": [ | ||
| "ai", | ||
| "cli", | ||
| "coding-agent", | ||
| "terminal" | ||
| ], | ||
| "author": "Yash Dewasthale", | ||
| "license": "MIT", | ||
| "engines": { | ||
| "node": ">=18" | ||
| }, | ||
| "dependencies": { | ||
| "@ai-sdk/google": "^3.0.80", | ||
| "@ai-sdk/openai-compatible": "^2.0.48", | ||
| "@modelcontextprotocol/sdk": "^1.9.0", | ||
| "@prisma/adapter-pg": "^7.8.0", | ||
| "@prisma/client": "^7.8.0", | ||
| "@prisma/client-runtime-utils": "^7.8.0", | ||
| "@prisma/driver-adapter-utils": "^7.8.0", | ||
| "@vercel/connect": "^0.3.2", | ||
| "ai": "^6.0.195", | ||
| "better-auth": "^1.5.5", | ||
| "boxen": "^8.0.1", | ||
| "chalk": "^5.6.2", | ||
| "commander": "^15.0.0", | ||
| "cors": "^2.8.5", | ||
| "eve": "^0.22.5", | ||
| "express": "^5.1.0", | ||
| "marked": "^18.0.4", | ||
| "marked-terminal": "^7.3.0", | ||
| "open": "^11.0.0", | ||
| "vercel-minimax-ai-provider": "^0.0.2", | ||
| "yocto-spinner": "^1.2.0", | ||
| "zod": "^3.25.2", | ||
| "zod-to-json-schema": "^3.25.2" | ||
| }, | ||
| "devDependencies": { | ||
| "@clack/prompts": "^1.5.0", | ||
| "@openrouter/ai-sdk-provider": "^2.9.0", | ||
| "@openrouter/sdk": "^0.12.79", | ||
| "@super/db-terminal": "workspace:*", | ||
| "@types/bun": "^1.3.14", | ||
| "@types/cors": "^2.8.17", | ||
| "@types/express": "^5.0.0", | ||
| "@types/node": "^22.0.0", | ||
| "@types/pg": "^8.18.0", | ||
| "api": "^6.1.3", | ||
| "dotenv": "^17.3.1", | ||
| "oas": "^34.0.1", | ||
| "prisma": "^7.4.2", | ||
| "typescript": "^5.7.0" | ||
| } | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Check if the active package.json contains the macOS-specific sed command or the dotenv dependency.
echo "Checking for macOS-specific sed:"
grep "sed -i ''" apps/supercode-cli/server/package.json || echo "None found."
echo "Checking for dotenv:"
grep "\"dotenv\"" apps/supercode-cli/server/package.json || echo "None found."Repository: yashdev9274/supercli
Length of output: 448
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Tracked files:"
git ls-files 'apps/supercode-cli/server/package.json*' || true
echo
echo "File stats:"
wc -l apps/supercode-cli/server/package.json apps/supercode-cli/server/package.json.bak2 2>/dev/null || true
echo
echo "Top-level comparison:"
python3 - <<'PY'
import json, pathlib, sys
for path in ["apps/supercode-cli/server/package.json", "apps/supercode-cli/server/package.json.bak2"]:
p = pathlib.Path(path)
print(f"\n== {path} ==")
data = json.loads(p.read_text())
print("name:", data.get("name"))
print("version:", data.get("version"))
print("has sed -i '' in build:cli:", "sed -i ''" in data.get("scripts", {}).get("build:cli", ""))
print("has dotenv:", any("dotenv" in k or "dotenv" in str(v) for k, v in data.get("dependencies", {}).items()) or any("dotenv" in k or "dotenv" in str(v) for k, v in data.get("devDependencies", {}).items()))
PYRepository: yashdev9274/supercli
Length of output: 665
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Tracked files:"
git ls-files 'apps/supercode-cli/server/package.json*' || true
echo
echo "File stats:"
wc -l apps/supercode-cli/server/package.json apps/supercode-cli/server/package.json.bak2 2>/dev/null || true
echo
echo "Top-level comparison:"
python3 - <<'PY'
import json, pathlib
for path in ["apps/supercode-cli/server/package.json", "apps/supercode-cli/server/package.json.bak2"]:
p = pathlib.Path(path)
print(f"\n== {path} ==")
data = json.loads(p.read_text())
print("name:", data.get("name"))
print("version:", data.get("version"))
print("has sed -i '' in build:cli:", "sed -i ''" in data.get("scripts", {}).get("build:cli", ""))
print("has dotenv:", any("dotenv" in k or "dotenv" in str(v) for k, v in data.get("dependencies", {}).items()) or any("dotenv" in k or "dotenv" in str(v) for k, v in data.get("devDependencies", {}).items()))
PYRepository: yashdev9274/supercli
Length of output: 665
Delete the committed backup file and clean up the active manifest
apps/supercode-cli/server/package.json.bak2is a backup artifact and should be removed.apps/supercode-cli/server/package.jsonstill usessed -i ''inbuild:cli, which breaks on Linux.dotenvis still listed indevDependencies; Bun already loads.envfiles without it.
🤖 Prompt for 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.
In `@apps/supercode-cli/server/package.json.bak2` around lines 1 - 84, Delete the
committed backup artifact package.json.bak2. In the active package.json, update
the build:cli script to use a Linux-compatible shebang replacement instead of
macOS-only sed -i '', and remove dotenv from devDependencies while leaving the
remaining manifest entries unchanged.
Source: Path instructions
| const modelToUse = result.model || provider.modelName | ||
| const newProvider = createProvider(result.provider, modelToUse) | ||
| if (newProvider) { | ||
| provider = newProvider | ||
| contextWindow = getContextWindow(provider.modelName) | ||
| footer.setModel(provider.modelName) | ||
| footer.setConnectionType(provider.connectionType) | ||
| footer.setContextWindow(contextWindow) | ||
| const label = `${provider.name} · ${provider.modelName}` | ||
| process.stdout.write(`\r\n ${chalk.hex(theme.green)("◆")} switched to ${chalk.hex(theme.green)(label)}\r\n`) | ||
| saveCliConfig({ provider: result.provider!, model: modelToUse, mode: conversation.mode as "chat" | "agent" }) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Prevent cross-provider model leakage.
When switching to a new provider via /connect, falling back to provider.modelName (the previous provider's model) will cause API errors if the user cancels or doesn't explicitly select a new model. The previous model name (e.g., deepseek-v4-flash) will be incorrectly passed to the new provider (e.g., google) and saved in the persistent config.
Instead, conditionally fall back to the existing model only if the provider remains the same, and use the newly resolved provider.modelName for saving the configuration.
🛠️ Proposed fix
- const modelToUse = result.model || provider.modelName
- const newProvider = createProvider(result.provider, modelToUse)
+ const modelToUse = result.model || (result.provider === provider.name ? provider.modelName : undefined)
+ const newProvider = createProvider(result.provider, modelToUse)
if (newProvider) {
provider = newProvider
contextWindow = getContextWindow(provider.modelName)
footer.setModel(provider.modelName)
footer.setConnectionType(provider.connectionType)
footer.setContextWindow(contextWindow)
const label = `${provider.name} · ${provider.modelName}`
process.stdout.write(`\r\n ${chalk.hex(theme.green)("◆")} switched to ${chalk.hex(theme.green)(label)}\r\n`)
- saveCliConfig({ provider: result.provider!, model: modelToUse, mode: conversation.mode as "chat" | "agent" })
+ saveCliConfig({ provider: result.provider!, model: provider.modelName, mode: conversation.mode as "chat" | "agent" })📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const modelToUse = result.model || provider.modelName | |
| const newProvider = createProvider(result.provider, modelToUse) | |
| if (newProvider) { | |
| provider = newProvider | |
| contextWindow = getContextWindow(provider.modelName) | |
| footer.setModel(provider.modelName) | |
| footer.setConnectionType(provider.connectionType) | |
| footer.setContextWindow(contextWindow) | |
| const label = `${provider.name} · ${provider.modelName}` | |
| process.stdout.write(`\r\n ${chalk.hex(theme.green)("◆")} switched to ${chalk.hex(theme.green)(label)}\r\n`) | |
| saveCliConfig({ provider: result.provider!, model: modelToUse, mode: conversation.mode as "chat" | "agent" }) | |
| const modelToUse = result.model || (result.provider === provider.name ? provider.modelName : undefined) | |
| const newProvider = createProvider(result.provider, modelToUse) | |
| if (newProvider) { | |
| provider = newProvider | |
| contextWindow = getContextWindow(provider.modelName) | |
| footer.setModel(provider.modelName) | |
| footer.setConnectionType(provider.connectionType) | |
| footer.setContextWindow(contextWindow) | |
| const label = `${provider.name} · ${provider.modelName}` | |
| process.stdout.write(`\r\n ${chalk.hex(theme.green)("◆")} switched to ${chalk.hex(theme.green)(label)}\r\n`) | |
| saveCliConfig({ provider: result.provider!, model: provider.modelName, mode: conversation.mode as "chat" | "agent" }) |
🤖 Prompt for 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.
In `@apps/supercode-cli/server/src/cli/ai/chat/chat.ts` around lines 1914 - 1924,
Update the /connect switching logic around createProvider so modelToUse falls
back to the previous provider.modelName only when result.provider matches the
current provider; otherwise use the newly created provider.modelName. Ensure
saveCliConfig persists the resolved new provider model rather than carrying the
previous provider’s model across providers.
| const PROVIDERS: Array<{ value: ModelProvider; label: string; hint: string; link: string }> = [ | ||
| { value: "google", label: "Google Gemini", hint: "gemini-2.5 models", link: "https://aistudio.google.com/apikey" }, | ||
| { value: "openrouter", label: "OpenRouter", hint: "multi-provider access", link: "https://openrouter.ai/keys" }, | ||
| { value: "nvidia", label: "NVIDIA NIM", hint: "free NVIDIA hosted models", link: "https://build.nvidia.com/explore/discover" }, | ||
| { value: "concentrateai", label: "ConcentrateAI", hint: "deepseek-v4 & glm models", link: "https://concentrate.ai" }, | ||
| { value: "mergedev", label: "Merge Dev Gateway", hint: "unified API gateway", link: "https://app.merge.dev" }, | ||
| ] |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Include MiniMax in the connect provider list.
ModelProvider and BYOK_MODELS support "minimax", but /connect provides no way to select it.
{ value: "nvidia", label: "NVIDIA NIM", hint: "free NVIDIA hosted models", link: "https://build.nvidia.com/explore/discover" },
+ { value: "minimax", label: "MiniMax", hint: "MiniMax hosted models", link: "" },📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const PROVIDERS: Array<{ value: ModelProvider; label: string; hint: string; link: string }> = [ | |
| { value: "google", label: "Google Gemini", hint: "gemini-2.5 models", link: "https://aistudio.google.com/apikey" }, | |
| { value: "openrouter", label: "OpenRouter", hint: "multi-provider access", link: "https://openrouter.ai/keys" }, | |
| { value: "nvidia", label: "NVIDIA NIM", hint: "free NVIDIA hosted models", link: "https://build.nvidia.com/explore/discover" }, | |
| { value: "concentrateai", label: "ConcentrateAI", hint: "deepseek-v4 & glm models", link: "https://concentrate.ai" }, | |
| { value: "mergedev", label: "Merge Dev Gateway", hint: "unified API gateway", link: "https://app.merge.dev" }, | |
| ] | |
| const PROVIDERS: Array<{ value: ModelProvider; label: string; hint: string; link: string }> = [ | |
| { value: "google", label: "Google Gemini", hint: "gemini-2.5 models", link: "https://aistudio.google.com/apikey" }, | |
| { value: "openrouter", label: "OpenRouter", hint: "multi-provider access", link: "https://openrouter.ai/keys" }, | |
| { value: "nvidia", label: "NVIDIA NIM", hint: "free NVIDIA hosted models", link: "https://build.nvidia.com/explore/discover" }, | |
| { value: "minimax", label: "MiniMax", hint: "MiniMax hosted models", link: "" }, | |
| { value: "concentrateai", label: "ConcentrateAI", hint: "deepseek-v4 & glm models", link: "https://concentrate.ai" }, | |
| { value: "mergedev", label: "Merge Dev Gateway", hint: "unified API gateway", link: "https://app.merge.dev" }, | |
| ] |
🤖 Prompt for 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.
In `@apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts` around
lines 12 - 18, Update the PROVIDERS list used by the /connect command to include
a MiniMax entry with value "minimax", an appropriate label and hint, and the
MiniMax API-key URL, matching the existing provider entry shape.
| ...modelsForProvider.map((m) => ({ | ||
| value: m.value, | ||
| label: `${m.label} ${chalk.hex(theme.muted)(m.desc)}`, | ||
| hint: m.cost ? `${m.cost}x` : "", | ||
| })), |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Do not append a second cost suffix.
Every non-free BYOK cost already contains x, so this renders hints such as 12xx.
- hint: m.cost ? `${m.cost}x` : "",
+ hint: m.cost,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ...modelsForProvider.map((m) => ({ | |
| value: m.value, | |
| label: `${m.label} ${chalk.hex(theme.muted)(m.desc)}`, | |
| hint: m.cost ? `${m.cost}x` : "", | |
| })), | |
| ...modelsForProvider.map((m) => ({ | |
| value: m.value, | |
| label: `${m.label} ${chalk.hex(theme.muted)(m.desc)}`, | |
| hint: m.cost, | |
| })), |
🤖 Prompt for 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.
In `@apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts` around
lines 73 - 77, Update the hint mapping in the modelsForProvider display flow to
use each model’s existing cost value without appending an additional “x” suffix.
Preserve the empty hint for free models.
| export const MODELS: ModelEntry[] = [ | ||
| { value: SECTION_CLOUD, label: "Supercode Cloud", provider: "supercode", cost: "", desc: "" }, | ||
| ...CLOUD_MODELS, | ||
| { value: SECTION_BYOK, label: "Bring Your Own Key", provider: "supercode", cost: "", desc: "" }, | ||
| ...BYOK_MODELS, | ||
| ] | ||
|
|
||
| export class ModelPicker { | ||
| items: ModelEntry[] = MODELS | ||
| selected = 0 | ||
| overlayLines = 0 | ||
|
|
||
| private isSection(item: ModelEntry): boolean { | ||
| return item.value === SECTION_CLOUD || item.value === SECTION_BYOK | ||
| } | ||
|
|
||
| render( | ||
| width: number, | ||
| currentProvider: string, | ||
| currentModel: string, | ||
| ): string[] { | ||
| const lines: string[] = [] | ||
| const total = this.items.length | ||
| if (total === 0) return lines | ||
| const visible = this.items.filter((m) => !this.isSection(m)) | ||
| const totalVisible = visible.length | ||
| if (totalVisible === 0) return lines | ||
|
|
||
| const maxVisible = 10 | ||
| const half = Math.floor(maxVisible / 2) | ||
|
|
||
| let start = Math.max(0, this.selected - half) | ||
| let end = Math.min(total, start + maxVisible) | ||
| if (end - start < maxVisible && start > 0) { | ||
| start = Math.max(0, end - maxVisible) | ||
| const visibleIdx = visible.indexOf(this.items[this.selected]!) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Start selection on the first actual model.
Index 0 is now SECTION_CLOUD, so pressing Enter without navigating returns "__section_cloud__" as the model. Initialize selected to the first non-section entry or normalize it before rendering.
Proposed fix
export class ModelPicker {
items: ModelEntry[] = MODELS
- selected = 0
+ selected = MODELS.findIndex(
+ (item) => item.value !== SECTION_CLOUD && item.value !== SECTION_BYOK,
+ )📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const MODELS: ModelEntry[] = [ | |
| { value: SECTION_CLOUD, label: "Supercode Cloud", provider: "supercode", cost: "", desc: "" }, | |
| ...CLOUD_MODELS, | |
| { value: SECTION_BYOK, label: "Bring Your Own Key", provider: "supercode", cost: "", desc: "" }, | |
| ...BYOK_MODELS, | |
| ] | |
| export class ModelPicker { | |
| items: ModelEntry[] = MODELS | |
| selected = 0 | |
| overlayLines = 0 | |
| private isSection(item: ModelEntry): boolean { | |
| return item.value === SECTION_CLOUD || item.value === SECTION_BYOK | |
| } | |
| render( | |
| width: number, | |
| currentProvider: string, | |
| currentModel: string, | |
| ): string[] { | |
| const lines: string[] = [] | |
| const total = this.items.length | |
| if (total === 0) return lines | |
| const visible = this.items.filter((m) => !this.isSection(m)) | |
| const totalVisible = visible.length | |
| if (totalVisible === 0) return lines | |
| const maxVisible = 10 | |
| const half = Math.floor(maxVisible / 2) | |
| let start = Math.max(0, this.selected - half) | |
| let end = Math.min(total, start + maxVisible) | |
| if (end - start < maxVisible && start > 0) { | |
| start = Math.max(0, end - maxVisible) | |
| const visibleIdx = visible.indexOf(this.items[this.selected]!) | |
| export class ModelPicker { | |
| items: ModelEntry[] = MODELS | |
| selected = MODELS.findIndex( | |
| (item) => item.value !== SECTION_CLOUD && item.value !== SECTION_BYOK, | |
| ) | |
| overlayLines = 0 |
🤖 Prompt for 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.
In `@apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts` around
lines 124 - 153, Initialize ModelPicker.selected to the index of the first
non-section entry in MODELS, rather than 0, so the initial Enter action selects
an actual model. Use the existing isSection logic or equivalent normalization
while preserving the current section filtering and rendering behavior in render.
| if (hasNext) { | ||
| lines.push(` ${chalk.hex(theme.greenDim)(`▼ ${total - end} more`)}`) | ||
| lines.push(` ${chalk.hex(theme.greenDim)(`▼ ${endIdx - startIdx} more`)}`) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Report the number of models remaining below.
endIdx - startIdx is the current window size, so this normally displays “10 more” regardless of how many entries remain.
- lines.push(` ${chalk.hex(theme.greenDim)(`▼ ${endIdx - startIdx} more`)}`)
+ lines.push(` ${chalk.hex(theme.greenDim)(`▼ ${totalVisible - endIdx} more`)}`)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (hasNext) { | |
| lines.push(` ${chalk.hex(theme.greenDim)(`▼ ${total - end} more`)}`) | |
| lines.push(` ${chalk.hex(theme.greenDim)(`▼ ${endIdx - startIdx} more`)}`) | |
| if (hasNext) { | |
| lines.push(` ${chalk.hex(theme.greenDim)(`▼ ${totalVisible - endIdx} more`)}`) |
🤖 Prompt for 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.
In `@apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts` around
lines 225 - 226, Update the hasNext display in the model listing logic to report
the actual number of models remaining after the current window, rather than the
current window size represented by endIdx - startIdx. Use the available
collection length and endIdx to calculate the remaining count while preserving
the existing formatting and conditional behavior.
| // For BYOK providers, check if an API key is configured | ||
| if (selected.provider !== "supercode") { | ||
| const config = await getCliConfig() | ||
| const envKeys = getProviderApiKeys() | ||
| const existingKey = config?.apiKeys?.[selected.provider] || envKeys[selected.provider] | ||
| if (!existingKey) { | ||
| process.stdout.write("\n") | ||
| const meta = providerMeta[selected.provider] | ||
| process.stdout.write( | ||
| ` ${chalk.hex(theme.amber)("◆")} ${chalk.hex(theme.green).bold(`${meta.label} needs an API key`)} | ||
|
|
||
| ${chalk.hex(theme.muted)(meta.link ? `Get your key at: ${meta.link}` : "")} | ||
|
|
||
| ` | ||
| ) | ||
| const apiKey = await password({ | ||
| message: chalk.hex(theme.green)(`paste your ${meta.label} API key`), | ||
| validate: (val: string | undefined) => { | ||
| if (!val || val.trim().length < 8) return "Key looks too short — please check and try again" | ||
| }, | ||
| }) | ||
| if (isCancel(apiKey)) { | ||
| return { provider: selected.provider, model: undefined } | ||
| } | ||
| await saveProviderApiKey(selected.provider, apiKey as string) | ||
| process.stdout.write( | ||
| ` ${chalk.hex(theme.green)("✓")} ${meta.label} API key saved — requests will go direct (🔑)\n\n`, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| // Handle custom model selection | ||
| if (selected.value === "__custom__") { | ||
| process.stdout.write(`\n`) | ||
| const customName = await text({ | ||
| message: chalk.hex(theme.green)(`enter model name for ${selected.provider}`), | ||
| placeholder: "e.g. my-custom-model-v1", | ||
| }) | ||
| if (isCancel(customName) || !(customName as string).trim()) { | ||
| return { provider: selected.provider, model: undefined } | ||
| } | ||
| const trimmed = (customName as string).trim() | ||
| process.stdout.write( | ||
| ` ${chalk.hex(theme.green)("✓")} model set to ${chalk.hex(theme.greenGlow)(trimmed)}\n\n`, | ||
| ) | ||
| return { provider: selected.provider, model: trimmed } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Preserve cancellation across model and connect flows.
Both functions return a newly selected provider after a nested prompt is canceled, so chat treats cancellation as a successful provider change.
apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts#L399-L444: return the current provider/model or an explicit canceled result.apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts#L81-L111: abort the connect result when either model prompt is canceled.
📍 Affects 2 files
apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts#L399-L444(this comment)apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts#L81-L111
🤖 Prompt for 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.
In `@apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts` around
lines 399 - 444, Preserve cancellation through both prompt flows: in
apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts lines 399-444,
return the current provider/model or an explicit canceled result when the
API-key or custom-model prompt is canceled instead of returning a newly selected
provider; in apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts
lines 81-111, detect cancellation from either model prompt and abort the connect
result rather than treating it as a successful provider change.
| private state = { | ||
| mode: "chat", | ||
| model: "", | ||
| connectionType: "", |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Initialize the connection indicator before mounting the footer.
The initial chat setup never calls footer.setConnectionType(provider.connectionType), so the new icon is absent until a model/connect command changes providers. Set it alongside the initial model.
footer.setModel(provider.modelName)
footer.setConnectionType(provider.connectionType)
footer.setContextWindow(contextWindow)Also applies to: 892-954
🤖 Prompt for 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.
In `@apps/supercode-cli/server/src/cli/utils/tui.ts` at line 788, Initialize the
footer connection indicator during the initial chat setup by calling
setConnectionType with provider.connectionType alongside the existing setModel
call, before mounting the footer. Apply the same initialization in the
additional setup path identified by the comment, while preserving the existing
model and context-window initialization.
Description
feat: update supercode-cli version to 0.1.69 and enhance AI provider functionality:
Type of change
How Has This Been Tested?
Please describe the tests that you ran to verify your changes.
bun testpassesbun run typecheckpassesbun run lintpasses (if applicable)Checklist:
Summary by CodeRabbit