refactor(installer): align with current pai-opencode structure#93
refactor(installer): align with current pai-opencode structure#93Steffen025 merged 3 commits intomainfrom
Conversation
- resolve install root from the repo layout instead of process.cwd() - write shell launcher to .opencode/PAI/Tools/pai.ts instead of stale .opencode/tools/pai.ts - validate PAI core via PAI/SKILL.md and detect shell functions, not just alias syntax - switch prerequisite detection/install from claude-code to opencode - update fallback config contextFiles to current PAI/ and PAI/USER paths - remove stale anthropic-max CLI help and outdated wrapper next-step instructions - recalculate installer counts using current skills/ and PAI/USER structure - keep GUI reconnect completion behavior intact while preserving current PR fixes
📝 WalkthroughWalkthroughThis PR migrates tool detection and validation infrastructure from Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@PAI-Install/cli/quick-install.ts`:
- Around line 173-176: The current check if (!values["api-key"]) enforces an API
key for every provider including "zen", which conflicts with the documented
headless example; change the validation in quick-install.ts to skip the API-key
requirement when provider === "zen" (i.e., only require values["api-key"] for
providers that need it such as "openai", "anthropic", "openrouter"), and add a
fallback to read sensitive keys from environment variables (e.g.,
process.env.ZEN_API_KEY or process.env.API_KEY) before failing; update the
validation logic around values["api-key"] and provider to prefer env vars and
only exit when no key exists for providers that actually require one.
In `@PAI-Install/engine/actions.ts`:
- Around line 336-351: The current install block uses an invalid package name
with tryExec("bun install -g `@opencode-ai/opencode`", ...), which will fail;
update the logic in the OpenCode install branch (the if on
det.tools.opencode.installed and the tryExec call) to either (a) attempt the
correct package if one exists (e.g., tryExec("bun install -g `@opencode-ai/sdk`",
...) after verifying availability) or (preferred) perform the documented
build-from-source sequence: clone the anomalyco/opencode repo, run the build
script via bun (e.g., git clone ... && cd opencode && bun install && bun run
./packages/opencode/script/build.ts --single), and then set
det.tools.opencode.installed accordingly; ensure you keep the same emit(...)
messages and fallback message updated to instruct manual build steps if
cloning/build fails, referencing the tryExec usage and
det.tools.opencode.installed check so reviewers can find the change.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: abbbff63-6cb7-41db-b37e-99b5f4b70bc6
📒 Files selected for processing (8)
PAI-Install/cli/quick-install.tsPAI-Install/engine/actions.tsPAI-Install/engine/config-gen.tsPAI-Install/engine/detect.tsPAI-Install/engine/steps-fresh.tsPAI-Install/engine/types.tsPAI-Install/engine/validate.tsPAI-Install/public/app.js
PAI-Install/cli/quick-install.ts
Outdated
| if (!values["api-key"]) { | ||
| console.error(`❌ --api-key is required for provider "${provider}"`); | ||
| console.error(' (Only --preset anthropic-max works without an API key)'); | ||
| process.exit(1); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if zen provider requires API key by examining provider-models.ts
rg -n "zen" PAI-Install/engine/provider-models.ts -A5 -B2Repository: Steffen025/pai-opencode
Length of output: 1060
🏁 Script executed:
# Get full context of the quick-install.ts around the API key validation
sed -n '160,185p' PAI-Install/cli/quick-install.tsRepository: Steffen025/pai-opencode
Length of output: 666
🏁 Script executed:
# Search for how zen provider is authenticated or used
rg -n "zen" PAI-Install -t ts -t tsx --max-count=20Repository: Steffen025/pai-opencode
Length of output: 94
🏁 Script executed:
# Look for zen provider client or API key handling
rg -n "api-key|apiKey|API_KEY" PAI-Install/cli/quick-install.ts -B3 -A3Repository: Steffen025/pai-opencode
Length of output: 1514
🏁 Script executed:
# Check if there's any environment variable handling for providers
rg -n "process.env" PAI-Install/cli/quick-install.tsRepository: Steffen025/pai-opencode
Length of output: 125
🏁 Script executed:
# Find and examine stepProviderConfig function
rg -n "stepProviderConfig" PAI-Install -A 30Repository: Steffen025/pai-opencode
Length of output: 8884
🏁 Script executed:
# Check provider client code for zen to see if API key is required
rg -n "zen" PAI-Install/engine -i -B2 -A5Repository: Steffen025/pai-opencode
Length of output: 6251
🏁 Script executed:
# Look for any zen-specific API key handling or provider client
fd -e ts -e js PAI-Install/engine | xargs grep -l "zen" -iRepository: Steffen025/pai-opencode
Length of output: 446
🏁 Script executed:
# Look for zen provider client or implementation
rg -n "zen" PAI-Install/engine --max-count=30Repository: Steffen025/pai-opencode
Length of output: 1482
🏁 Script executed:
# Search for any environment variable setup or provider client initialization
rg -n "ZEN_API_KEY\|opencode.ai\|zen.*api" PAI-Install -iRepository: Steffen025/pai-opencode
Length of output: 49
🏁 Script executed:
# Check if there's documentation about zen provider requirements
fd . PAI-Install -name "*.md" -o -name "*.txt" | head -20Repository: Steffen025/pai-opencode
Length of output: 297
Inconsistency: Zen API key requirement breaks documented headless workflow.
The help text example at line 99 shows zen can be installed without --api-key:
bun cli/quick-install.ts --preset zen --name "Steffen" --ai-name "Jeremy"
However, lines 173-176 enforce --api-key for all providers including zen. The zen provider is documented as "Free tier available," but the code treats it identically to paid providers (Anthropic, OpenRouter, OpenAI), requiring authentication upfront.
Either zen should skip API key validation, or the help text example needs updating. Additionally, consider using environment variables (e.g., process.env.ZEN_API_KEY) for sensitive configuration instead of CLI arguments, per the coding guidelines.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@PAI-Install/cli/quick-install.ts` around lines 173 - 176, The current check
if (!values["api-key"]) enforces an API key for every provider including "zen",
which conflicts with the documented headless example; change the validation in
quick-install.ts to skip the API-key requirement when provider === "zen" (i.e.,
only require values["api-key"] for providers that need it such as "openai",
"anthropic", "openrouter"), and add a fallback to read sensitive keys from
environment variables (e.g., process.env.ZEN_API_KEY or process.env.API_KEY)
before failing; update the validation logic around values["api-key"] and
provider to prefer env vars and only exit when no key exists for providers that
actually require one.
| if (!det.tools.opencode.installed) { | ||
| await emit({ event: "progress", step: "prerequisites", percent: 70, detail: "Installing OpenCode..." }); | ||
|
|
||
| // Use bun only (per PAI stack preferences) | ||
| const result = await tryExec("bun install -g @anthropic-ai/claude-code", 120000); | ||
| const result = await tryExec("bun install -g @opencode-ai/opencode", 120000); | ||
| if (result !== null) { | ||
| await emit({ event: "message", content: "OpenCode installed via bun." }); | ||
| } else { | ||
| await emit({ | ||
| event: "message", | ||
| content: "Could not install OpenCode automatically. Please install manually: bun install -g @anthropic-ai/claude-code", | ||
| content: "Could not install OpenCode automatically. Please install manually: bun install -g @opencode-ai/opencode", | ||
| }); | ||
| } | ||
| } else { | ||
| await emit({ event: "progress", step: "prerequisites", percent: 80, detail: `OpenCode found: v${det.tools.claude.version}` }); | ||
| await emit({ event: "progress", step: "prerequisites", percent: 80, detail: `OpenCode found: v${det.tools.opencode.version}` }); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if the OpenCode package exists
curl -s "https://registry.npmjs.org/@opencode-ai/opencode" | jq '.name, .["dist-tags"].latest'Repository: Steffen025/pai-opencode
Length of output: 76
🏁 Script executed:
#!/bin/bash
# Get full JSON response from npm registry to see what's returned
curl -s "https://registry.npmjs.org/@opencode-ai/opencode" | head -100Repository: Steffen025/pai-opencode
Length of output: 88
🏁 Script executed:
#!/bin/bash
# Search for OpenCode-related packages on npm
curl -s "https://registry.npmjs.org/-/v1/search?text=opencode&size=20" | jq '.objects[].package | {name, version, description}' | head -50Repository: Steffen025/pai-opencode
Length of output: 1720
🏁 Script executed:
#!/bin/bash
# Check the codebase for any references to the package name or installation instructions
rg "@opencode-ai/opencode|opencode.*install|bun install.*opencode" -A 2 -B 2Repository: Steffen025/pai-opencode
Length of output: 5181
Package @opencode-ai/opencode does not exist on npm — installation will fail.
The package name used in the installation command (bun install -g @opencode-ai/opencode``) returned a "Not found" error from the npm registry. The CHANGELOG indicates OpenCode should be built from source (cloning anomalyco/opencode.git and running `bun run ./packages/opencode/script/build.ts --single`), not installed via npm.
Either:
- Use the correct npm package name if available (search shows
@opencode-ai/sdkexists but not@opencode-ai/opencode) - Implement the build-from-source approach as documented in CHANGELOG
- Clarify the intended installation method and update the code accordingly
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@PAI-Install/engine/actions.ts` around lines 336 - 351, The current install
block uses an invalid package name with tryExec("bun install -g
`@opencode-ai/opencode`", ...), which will fail; update the logic in the OpenCode
install branch (the if on det.tools.opencode.installed and the tryExec call) to
either (a) attempt the correct package if one exists (e.g., tryExec("bun install
-g `@opencode-ai/sdk`", ...) after verifying availability) or (preferred) perform
the documented build-from-source sequence: clone the anomalyco/opencode repo,
run the build script via bun (e.g., git clone ... && cd opencode && bun install
&& bun run ./packages/opencode/script/build.ts --single), and then set
det.tools.opencode.installed accordingly; ensure you keep the same emit(...)
messages and fallback message updated to instruct manual build steps if
cloning/build fails, referencing the tryExec usage and
det.tools.opencode.installed check so reviewers can find the change.
Summary
Key fixes
Verification
Summary by CodeRabbit
New Features
Bug Fixes
Changes