Skip to content

refactor(installer): align with current pai-opencode structure#93

Merged
Steffen025 merged 3 commits intomainfrom
fix/installer-validation-failures
Mar 27, 2026
Merged

refactor(installer): align with current pai-opencode structure#93
Steffen025 merged 3 commits intomainfrom
fix/installer-validation-failures

Conversation

@Steffen025
Copy link
Copy Markdown
Owner

@Steffen025 Steffen025 commented Mar 27, 2026

Summary

  • align fresh install with the actual repo .opencode tree instead of process.cwd()
  • fix stale validation paths and shell-function detection
  • switch prerequisite detection/install from Claude Code to OpenCode
  • update fallback config generation and CLI help to current repo structure
  • remove stale installer assumptions introduced before the v3 refactor

Key fixes

  • use repo root for install output so Electron no longer writes into PAI-Install/.opencode
  • validate PAI/SKILL.md instead of removed skills/PAI/SKILL.md
  • accept shell functions in validation, not just alias syntax
  • launch pai via .opencode/PAI/Tools/pai.ts
  • remove stale anthropic-max and old claude-code installer references

Verification

  • build checks passed for all changed installer files

Summary by CodeRabbit

  • New Features

    • Added support for OpenCode tool detection and installation.
  • Bug Fixes

    • Corrected configuration file paths for skills and context references.
    • Fixed API key requirement validation for all selected providers.
    • Resolved installation directory path resolution.
  • Changes

    • Removed special-case provider handling.
    • Simplified post-installation guidance to "Launch with: pai".

- 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
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

📝 Walkthrough

Walkthrough

This PR migrates tool detection and validation infrastructure from claude to opencode, restructures PAI-related configuration paths from skills/PAI/ to PAI/, removes special-case handling for the anthropic-max provider preset, and refines file-counting logic for skills inventory. Changes span CLI, detection, validation, and configuration generation layers.

Changes

Cohort / File(s) Summary
Tool Detection & Type Definitions
PAI-Install/engine/detect.ts, PAI-Install/engine/types.ts, PAI-Install/public/app.js
Replaces claude tool detection with opencode detection; updates DetectionResult.tools interface and UI rendering to reference opencode instead of claude.
Prerequisite & Configuration Actions
PAI-Install/engine/actions.ts, PAI-Install/engine/config-gen.ts
Updates OpenCode prerequisite check from claude.installed to opencode.installed and bun package reference; changes skill inventory from directory-based to file-based counting; shifts contextFiles paths from skills/PAI/ to PAI/ directories and adds voiceId to daidentity config.
Validation & Path Resolution
PAI-Install/engine/validate.ts
Updates PAI core presence check from skills/PAI/SKILL.md to PAI/SKILL.md; extends shell alias detection to support POSIX function syntax and fish function declarations.
Installer Flow & CLI
PAI-Install/cli/quick-install.ts, PAI-Install/engine/steps-fresh.ts
Removes anthropic-max preset special-case handling and API-key exemption; generalizes API-key requirement; updates fresh-install base directory to repository root, adds .opencode existence check, and changes shell alias script path from tools/pai.ts to PAI/Tools/pai.ts; simplifies "Next steps" output.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PR #84: Reverses the anthropic-max special-case handling by directly modifying quick-install.ts and provider preset logic.
  • PR #47: Large-scale PAI-Install port/migration work with overlapping changes to detection, validation, types, and installer files.
  • PR #91: Modifies fresh-install flow in steps-fresh.ts with related changes to shell alias handling, .opencode paths, and settings/daidentity configuration.

Poem

🐰 Claude waves goodbye, OpenCode takes the stage,
Skills find their new home under PAI/'s page,
Paths resolve true, aliases dance with grace,
The installer bounds forward at a brisker pace! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: aligning the installer with the current pai-opencode directory structure and removing outdated references.
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/installer-validation-failures

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4dadb14 and 9abfea9.

📒 Files selected for processing (8)
  • PAI-Install/cli/quick-install.ts
  • PAI-Install/engine/actions.ts
  • PAI-Install/engine/config-gen.ts
  • PAI-Install/engine/detect.ts
  • PAI-Install/engine/steps-fresh.ts
  • PAI-Install/engine/types.ts
  • PAI-Install/engine/validate.ts
  • PAI-Install/public/app.js

Comment on lines 173 to 176
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);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 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 -B2

Repository: 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.ts

Repository: 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=20

Repository: 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 -A3

Repository: 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.ts

Repository: Steffen025/pai-opencode

Length of output: 125


🏁 Script executed:

# Find and examine stepProviderConfig function
rg -n "stepProviderConfig" PAI-Install -A 30

Repository: 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 -A5

Repository: 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" -i

Repository: Steffen025/pai-opencode

Length of output: 446


🏁 Script executed:

# Look for zen provider client or implementation
rg -n "zen" PAI-Install/engine --max-count=30

Repository: 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 -i

Repository: 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 -20

Repository: 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.

Comment on lines +336 to 351
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}` });
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 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 -100

Repository: 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 -50

Repository: 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 2

Repository: 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:

  1. Use the correct npm package name if available (search shows @opencode-ai/sdk exists but not @opencode-ai/opencode)
  2. Implement the build-from-source approach as documented in CHANGELOG
  3. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant