Skip to content

Conversation

@justin808
Copy link
Member

@justin808 justin808 commented Jan 15, 2026

Summary

  • Detect and support multiple version managers: mise, asdf, or direct PATH (rbenv/nvm/nodenv)
  • Add bin/conductor-exec wrapper that uses mise exec when available, falls back to direct execution otherwise
  • Update conductor.json scripts to use the wrapper for consistent tool execution
  • Add test and lint scripts to conductor.json for convenience

How it works

The setup script now:

  1. Checks for mise first → uses bin/conductor-exec wrapper for all commands
  2. Falls back to asdf → sources asdf.sh to configure PATH
  3. Falls back to direct commands → assumes rbenv/nvm/nodenv or system tools are in PATH

Related

Ported from react_on_rails PR #2302.

Test plan

  • Rubocop passes
  • Yarn lint passes
  • Test workspace setup in Conductor with mise (requires manual testing)
  • Test workspace setup in Conductor with asdf (requires manual testing)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Broader support for multiple version managers (mise, asdf, PATH-based) in the development setup
    • Added a lightweight command wrapper to ensure correct tool versions in non-interactive shells
    • New convenience test and lint scripts that run via the wrapper
  • Documentation

    • Added a "Conductor Environment" guide describing version manager detection and wrapper usage
  • Chores

    • Updated linting configuration to skip shell scripts

✏️ Tip: You can customize this high-level summary in your review settings.

- Detect and support mise, asdf, or direct PATH (rbenv/nvm/nodenv)
- Add bin/conductor-exec wrapper for consistent tool execution
- Use bin/conductor-exec in conductor.json scripts
- Fall back to direct commands for non-mise users
- Add test and lint scripts to conductor.json

For mise users in Conductor's non-interactive shell, the setup
script automatically uses bin/conductor-exec. The CLAUDE.md
documentation covers manual usage when needed.

Ported from react_on_rails PR #2302.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Jan 15, 2026

Warning

Rate limit exceeded

@justin808 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 14 minutes and 58 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 454e037 and 13c606f.

📒 Files selected for processing (1)
  • conductor-setup.sh

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a version-manager-aware execution wrapper (bin/conductor-exec), updates conductor-setup.sh to detect/use mise|asdf|PATH and route commands via run_cmd, updates conductor.json scripts to use the wrapper, and documents behavior in CLAUDE.md.

Changes

Cohort / File(s) Summary
Config & Linting
\.rubocop\.yml
Exclude bin/conductor-exec from RuboCop linting (it's a shell script).
Docs
CLAUDE\.md
Adds "Conductor Environment" section describing version manager detection (mise/asdf/PATH), bin/conductor-exec usage, examples, and notes on conductor.json scripts.
Execution wrapper
bin/conductor-exec
New executable shell script that delegates to mise exec -- "$@" when mise is present, otherwise execs the command directly.
Setup script
conductor-setup\.sh
Introduces VERSION_MANAGER detection (mise/asdf/PATH/none), run_cmd wrapper to route commands through manager, enforces Ruby >= 2.7.0 and Node >= 14.0.0, copies .env files from CONDUCTOR_ROOT_PATH, and uses run_cmd for installs and Husky/lint-staged setup.
Project scripts
conductor\.json
Wraps run with bin/conductor-exec, adds test (bin/conductor-exec bundle exec rspec) and lint (bin/conductor-exec bundle exec rubocop && bin/conductor-exec yarn lint).

Sequence Diagram

sequenceDiagram
    autonumber
    participant User
    participant Setup as conductor-setup.sh
    participant Exec as bin/conductor-exec
    participant VM as VersionManager (mise/asdf/PATH)
    participant Ruby
    participant Node

    User->>Setup: run setup
    Setup->>VM: detect manager (mise/asdf/PATH/none)
    VM-->>Setup: manager type

    Setup->>VM: run_cmd -> check Ruby version
    VM->>Ruby: ruby -v (via manager)
    Ruby-->>VM: version
    VM-->>Setup: ruby OK/fail

    Setup->>VM: run_cmd -> check Node version
    VM->>Node: node -v (via manager)
    Node-->>VM: version
    VM-->>Setup: node OK/fail

    Setup->>VM: run_cmd -> bundle/yarn install, husky setup
    VM->>Ruby: bundle install (if needed)
    Ruby-->>VM: success
    VM->>Node: yarn install (if needed)
    Node-->>VM: success

    User->>Exec: run tests/lint (e.g., `bin/conductor-exec bundle exec rspec`)
    Exec->>VM: delegate to mise exec or direct exec
    VM->>Ruby: execute command
    Ruby-->>VM: result
    VM-->>Exec: result
    Exec-->>User: output
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Judahmeek

Poem

🐰 I hop through scripts with a jaunty peep,
Mise, asdf, or PATH—I'll softly keep,
Wrapping commands so versions align,
Bundles and yarns now run on time,
A tiny rabbit cheering setup complete! ✨

🚥 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 'Update Conductor config to support multiple version managers' accurately reflects the main objective of the PR: enabling support for mise, asdf, or direct PATH usage as version managers.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% 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 unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jg/npm-auth-precheck

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.

@claude
Copy link

claude bot commented Jan 15, 2026

Code Review

I've reviewed this PR and found it to be well-structured with good improvements to version manager support. Here's my detailed feedback:

✅ Strengths

  1. Good abstraction: The bin/conductor-exec wrapper provides a clean abstraction for handling different version managers
  2. Documentation: Excellent inline comments and updated CLAUDE.md with clear usage instructions
  3. Backward compatibility: Falls back gracefully for users without mise/asdf
  4. User experience: Enhanced error messages with helpful guidance and version checking
  5. Proper exclusion: Added bin/conductor-exec to RuboCop exclusions since it's a shell script

🔍 Code Quality Issues

Portability Concerns

  1. Hardcoded zsh shebang: Both scripts use #!/bin/zsh or #!/usr/bin/env zsh

    • conductor-setup.sh:1 changed from #!/usr/bin/env bash to #!/bin/zsh
    • This assumes zsh is available, which may not be true on all systems
    • Question: Is this intentional? Bash would be more portable.
  2. Missing error handling flags:

    • The old script used bash with set -euo pipefail
    • The new script uses zsh with only set -e
    • Missing: set -u (error on undefined variables) and set -o pipefail (fail on pipe errors)

    Recommendation: Add set -uo pipefail for better error handling

Version Comparison Logic

Location: conductor-setup.sh:51, 61

The version comparison using sort -V has limitations:

  • sort -V may not be available on all systems
  • The echo -e flag behavior differs between shells
  • Could fail if version contains unexpected format

Suggestion: Add validation or use a more robust version comparison method

🐛 Potential Bugs

  1. Ruby version extraction (conductor-setup.sh:49): Assumes ruby -v outputs "ruby X.Y.Z ..." - could fail with custom builds
  2. Node version extraction (conductor-setup.sh:59): Assumes format "vX.Y.Z" - should handle cases without 'v' prefix
  3. Missing error handling on mise install (conductor-setup.sh:17): If mise install fails, should this be fatal?

🔒 Security Considerations

No major security issues found

  • Scripts properly use exec to avoid leaving processes around
  • File permissions correctly set
  • Environment variables used safely with proper quoting

🧪 Test Coverage

Missing: No automated tests for the shell scripts. Consider:

  1. Adding shellcheck validation to CI
  2. Testing in different environments (mise, asdf, no version manager)
  3. Testing edge cases (missing tools, wrong versions, etc.)

🎯 Recommendations Summary

High Priority:

  1. Clarify why zsh is required vs bash (or switch back to bash for portability)
  2. Re-add set -u and set -o pipefail for better error handling
  3. Handle edge cases in version extraction and comparison

Medium Priority:

  1. Add shellcheck to CI
  2. Consider making mise install failure explicit/fatal
  3. Document minimum shell version requirements

✅ Approval Recommendation

This PR is nearly ready to merge after addressing the shell portability question. The code quality is good, the approach is sound, and the UX improvements are valuable.

Suggested next steps:

  1. Clarify bash vs zsh decision
  2. Consider re-adding stricter error handling flags
  3. Run shellcheck on both scripts

Great work on improving the developer experience! 🎉

@greptile-apps
Copy link

greptile-apps bot commented Jan 15, 2026

Greptile Summary

This PR enhances Conductor workspace setup to support multiple version managers (mise, asdf, rbenv/nvm/nodenv), replacing the previous asdf-only approach. It introduces a new bin/conductor-exec wrapper that automatically uses mise exec when available or falls back to direct execution for other version managers.

Key changes:

  • Detects and configures mise (preferred), asdf, or direct PATH-based version managers
  • New bin/conductor-exec wrapper handles tool version execution consistently across environments
  • Updated conductor.json to use the wrapper for all commands
  • Added convenience test and lint scripts to conductor.json
  • Enhanced error checking with explicit Ruby/Node version validation
  • Improved setup output with better messaging

Considerations:

  • Changed from bash to zsh with less strict error handling (set -e vs set -euo pipefail)
  • Removed automatic .tool-versions file generation that asdf relied on - users now need pre-existing version configuration
  • The mise trust command on line 16 of conductor-setup.sh grants trust to the current directory's mise config, which could be a security consideration in untrusted repos
  • Minor shebang inconsistency between bin/conductor-exec and conductor-setup.sh

Confidence Score: 4/5

  • This PR is generally safe to merge with minor considerations around version manager configuration requirements
  • The implementation is well-structured and provides better multi-version-manager support. However, the score is 4/5 due to: (1) removal of automatic .tool-versions file creation which changes behavior for asdf users who relied on it, (2) change from bash to zsh with weaker error handling that removes set -u and set -o pipefail safeguards, and (3) the mise trust command which has security implications in untrusted environments. These aren't critical issues but warrant attention during testing.
  • Pay close attention to conductor-setup.sh - verify it works correctly with asdf/mise when no .tool-versions file exists, and test the weaker error handling doesn't mask issues

Important Files Changed

Filename Overview
bin/conductor-exec New wrapper script that uses mise exec when available, with shebang inconsistency (uses #!/usr/bin/env zsh vs #!/bin/zsh in conductor-setup.sh)
conductor-setup.sh Rewritten to detect multiple version managers (mise/asdf/PATH), changed from bash to zsh with weaker error handling, removed .tool-versions file generation, and relies on pre-existing version manager config
conductor.json Updated to use bin/conductor-exec wrapper for all commands and added convenience test and lint scripts

Sequence Diagram

sequenceDiagram
    participant User
    participant Conductor
    participant conductor-setup.sh
    participant bin/conductor-exec
    participant mise/asdf/PATH

    User->>Conductor: Run setup script
    Conductor->>conductor-setup.sh: Execute
    conductor-setup.sh->>conductor-setup.sh: Detect version manager
    alt mise detected
        conductor-setup.sh->>mise/asdf/PATH: mise trust
        conductor-setup.sh->>mise/asdf/PATH: mise install
    else asdf detected
        conductor-setup.sh->>mise/asdf/PATH: source asdf.sh
    else no version manager
        conductor-setup.sh->>conductor-setup.sh: Use system PATH
    end
    
    conductor-setup.sh->>bin/conductor-exec: run_cmd ruby --version
    bin/conductor-exec->>bin/conductor-exec: Check if mise available
    alt mise available
        bin/conductor-exec->>mise/asdf/PATH: mise exec -- ruby --version
    else fallback
        bin/conductor-exec->>mise/asdf/PATH: ruby --version
    end
    mise/asdf/PATH-->>conductor-setup.sh: Version info
    
    conductor-setup.sh->>bin/conductor-exec: run_cmd bundle install
    bin/conductor-exec->>mise/asdf/PATH: Execute with correct Ruby
    
    conductor-setup.sh->>bin/conductor-exec: run_cmd yarn install
    bin/conductor-exec->>mise/asdf/PATH: Execute with correct Node
    
    conductor-setup.sh-->>Conductor: Setup complete
    
    User->>Conductor: Run test/lint script
    Conductor->>bin/conductor-exec: bin/conductor-exec bundle exec rspec
    bin/conductor-exec->>mise/asdf/PATH: Execute with correct versions
    mise/asdf/PATH-->>User: Test results
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

5 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

@@ -0,0 +1,24 @@
#!/usr/bin/env zsh
Copy link

Choose a reason for hiding this comment

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

style: Shebang inconsistency: this uses #!/usr/bin/env zsh while conductor-setup.sh:1 uses #!/bin/zsh. Should use the same approach for consistency.

Suggested change
#!/usr/bin/env zsh
#!/bin/zsh

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: bin/conductor-exec
Line: 1:1

Comment:
**style:** Shebang inconsistency: this uses `#!/usr/bin/env zsh` while `conductor-setup.sh:1` uses `#!/bin/zsh`. Should use the same approach for consistency.

```suggestion
#!/bin/zsh
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 1 to 2
#!/bin/zsh
set -e
Copy link

Choose a reason for hiding this comment

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

style: Changed from bash to zsh and removed stricter error handling. The old script used set -euo pipefail (fails on undefined variables and pipe failures), but this now only uses set -e. This could allow errors to slip through if undefined variables or failing pipe commands are used.

Prompt To Fix With AI
This is a comment left during a code review.
Path: conductor-setup.sh
Line: 1:2

Comment:
**style:** Changed from bash to zsh and removed stricter error handling. The old script used `set -euo pipefail` (fails on undefined variables and pipe failures), but this now only uses `set -e`. This could allow errors to slip through if undefined variables or failing pipe commands are used.

How can I resolve this? If you propose a fix, please make it concise.

VERSION_MANAGER="mise"
echo "✅ Found mise"
# Trust mise config for current directory only and install tools
mise trust 2>/dev/null || true
Copy link

Choose a reason for hiding this comment

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

style: The mise trust command trusts the mise configuration in the current directory. This is necessary for mise to work, but could be a security concern if running in untrusted repositories. The old script didn't require this trust step.

Prompt To Fix With AI
This is a comment left during a code review.
Path: conductor-setup.sh
Line: 16:16

Comment:
**style:** The `mise trust` command trusts the mise configuration in the current directory. This is necessary for mise to work, but could be a security concern if running in untrusted repositories. The old script didn't require this trust step.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 12 to 32
if command -v mise &> /dev/null; then
VERSION_MANAGER="mise"
echo "✅ Found mise"
# Trust mise config for current directory only and install tools
mise trust 2>/dev/null || true
mise install
elif [[ -f ~/.asdf/asdf.sh ]]; then
VERSION_MANAGER="asdf"
source ~/.asdf/asdf.sh
echo "✅ Found asdf (from ~/.asdf/asdf.sh)"
elif command -v asdf &> /dev/null; then
VERSION_MANAGER="asdf"
# For homebrew-installed asdf
if [[ -f /opt/homebrew/opt/asdf/libexec/asdf.sh ]]; then
source /opt/homebrew/opt/asdf/libexec/asdf.sh
fi
echo "✅ Found asdf"
else
BUNDLE_CMD="bundle"
echo "ℹ️ No version manager detected, using system PATH"
echo " (Assuming rbenv/nvm/nodenv or system tools are already configured)"
fi
Copy link

Choose a reason for hiding this comment

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

style: The old script created .tool-versions file with echo "ruby 3.3.4" > .tool-versions to ensure asdf users had a Ruby version specified. The new script removes this, so asdf/mise users must have a pre-existing .tool-versions or .mise.toml file in the repository or their home directory. Check that all supported version managers will have access to appropriate version configuration.

Prompt To Fix With AI
This is a comment left during a code review.
Path: conductor-setup.sh
Line: 12:32

Comment:
**style:** The old script created `.tool-versions` file with `echo "ruby 3.3.4" > .tool-versions` to ensure asdf users had a Ruby version specified. The new script removes this, so asdf/mise users must have a pre-existing `.tool-versions` or `.mise.toml` file in the repository or their home directory. Check that all supported version managers will have access to appropriate version configuration.

How can I resolve this? If you propose a fix, please make it concise.

Copy link

@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: 1

🤖 Fix all issues with AI agents
In `@conductor-setup.sh`:
- Around line 101-104: The echo message "✅ Running initial linting checks..." is
misleading because the script only runs `run_cmd bundle exec rubocop --version`;
either update the message to something like "✅ Verifying linting tools..." to
reflect that it checks installation, or actually run the lint by replacing the
`--version` invocation with `run_cmd bundle exec rubocop` (or add a separate
lint run) so the message matches the action; update the line near the `run_cmd
bundle exec rubocop --version` call accordingly.
🧹 Nitpick comments (2)
bin/conductor-exec (1)

1-1: Consider using /usr/bin/env sh for broader portability.

The script only uses POSIX-compatible constructs (command -v, if/else/fi, exec "$@"), so it could work with /bin/sh. However, if the project intentionally standardizes on zsh (matching conductor-setup.sh), this is acceptable.

conductor-setup.sh (1)

22-28: Missing Intel Mac homebrew path for asdf.

The script only checks the Apple Silicon homebrew path (/opt/homebrew/opt/asdf/...). Intel Macs use /usr/local/opt/asdf/libexec/asdf.sh.

♻️ Proposed fix
 elif command -v asdf &> /dev/null; then
     VERSION_MANAGER="asdf"
     # For homebrew-installed asdf
     if [[ -f /opt/homebrew/opt/asdf/libexec/asdf.sh ]]; then
         source /opt/homebrew/opt/asdf/libexec/asdf.sh
+    elif [[ -f /usr/local/opt/asdf/libexec/asdf.sh ]]; then
+        source /usr/local/opt/asdf/libexec/asdf.sh
     fi
     echo "✅ Found asdf"
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c57cddd and 0fe455f.

📒 Files selected for processing (5)
  • .rubocop.yml
  • CLAUDE.md
  • bin/conductor-exec
  • conductor-setup.sh
  • conductor.json
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: shakacode/shakapacker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T04:44:25.430Z
Learning: This gem supports both webpack and rspack configurations - test changes with both bundlers when modifying core functionality
📚 Learning: 2025-12-22T04:44:25.430Z
Learnt from: CR
Repo: shakacode/shakapacker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T04:44:25.430Z
Learning: ALWAYS use `bundle exec` prefix when running Ruby commands (rubocop, rspec, rake, etc.)

Applied to files:

  • bin/conductor-exec
  • .rubocop.yml
  • conductor-setup.sh
  • conductor.json
  • CLAUDE.md
📚 Learning: 2025-12-22T04:44:25.430Z
Learnt from: CR
Repo: shakacode/shakapacker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T04:44:25.430Z
Learning: ALWAYS run `bundle exec rubocop` before committing Ruby changes

Applied to files:

  • .rubocop.yml
  • conductor-setup.sh
  • conductor.json
📚 Learning: 2024-10-09T10:46:03.499Z
Learnt from: marvinthepa
Repo: shakacode/shakapacker PR: 520
File: lib/shakapacker/utils/manager.rb:19-19
Timestamp: 2024-10-09T10:46:03.499Z
Learning: In `lib/install/template.rb` of the Shakapacker project, calls to `PackageJson.read` are wrapped inside `Dir.chdir(Rails.root)`, ensuring that `package.json` is read from the Rails root directory.

Applied to files:

  • conductor-setup.sh
📚 Learning: 2025-12-22T04:44:25.430Z
Learnt from: CR
Repo: shakacode/shakapacker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T04:44:25.430Z
Learning: ALWAYS run `yarn lint` before committing JavaScript changes

Applied to files:

  • conductor-setup.sh
📚 Learning: 2025-12-22T04:44:25.430Z
Learnt from: CR
Repo: shakacode/shakapacker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T04:44:25.430Z
Learning: Run the full test suite with `bundle exec rspec` before pushing

Applied to files:

  • conductor.json
📚 Learning: 2025-12-22T04:44:25.430Z
Learnt from: CR
Repo: shakacode/shakapacker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T04:44:25.430Z
Learning: This gem supports both webpack and rspack configurations - test changes with both bundlers when modifying core functionality

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-22T04:44:25.430Z
Learnt from: CR
Repo: shakacode/shakapacker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T04:44:25.430Z
Learning: Be aware of the dual package.json/Gemfile dependency management

Applied to files:

  • CLAUDE.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: Greptile Review
  • GitHub Check: Testing (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Testing (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Testing (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.0.x)
  • GitHub Check: Testing (ubuntu-latest, 3.4, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Testing (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Testing (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Testing (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Testing (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Testing (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Testing (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Testing (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Testing (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Testing (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Testing (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Testing (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Testing (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.6.0.x)
  • GitHub Check: Testing (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Testing (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: claude-review
🔇 Additional comments (8)
.rubocop.yml (1)

13-13: LGTM!

Correctly excludes the shell script from Ruby linting with a clear explanatory comment.

bin/conductor-exec (1)

19-24: LGTM!

Clean and correct implementation. Proper use of exec to replace the shell process and "$@" for correct argument handling.

conductor.json (1)

4-6: LGTM!

Scripts correctly use the bin/conductor-exec wrapper and follow project conventions with bundle exec prefix. The lint script properly combines both Ruby (rubocop) and JavaScript (yarn lint) checks. Based on learnings, this aligns with the project's requirements.

conductor-setup.sh (4)

34-41: LGTM!

The helper correctly delegates to bin/conductor-exec only for mise users (since mise requires mise exec for tool resolution), while asdf users benefit from the PATH modifications done by sourcing asdf.sh earlier.


48-66: LGTM!

Version extraction and comparison logic is correct. Using sort -V for semantic version comparison is a robust approach.


68-79: LGTM!

Safe handling of the optional CONDUCTOR_ROOT_PATH variable with proper fallback syntax.


81-99: LGTM!

Correct use of --frozen-lockfile for reproducible installs and proper Husky setup with lint-staged integration.

CLAUDE.md (1)

48-55: LGTM!

Clear and helpful documentation of the Conductor environment setup and wrapper usage. Good note about conductor.json scripts already using the wrapper.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

justin808 and others added 2 commits January 20, 2026 18:45
If a version manager is detected but no .tool-versions or .mise.toml
exists, create a default .tool-versions with Ruby 3.3.4 and Node 20.18.0.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use #!/bin/zsh consistently in both scripts
- Restore set -euo pipefail for better error handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Jan 21, 2026

Code Review - PR #867

Overall Assessment

This is a well-structured PR that improves Conductor setup by supporting multiple version managers (mise, asdf, PATH). The implementation is clean with good documentation. However, there are some issues to address.

Strengths

  1. Clear version manager detection hierarchy
  2. Good error messages with actionable guidance
  3. Helpful CLAUDE.md documentation
  4. Backward compatibility maintained

Potential Bugs & Issues

1. CRITICAL: Inconsistent shebang usage

  • conductor-setup.sh uses #!/bin/zsh (fixed path)
  • bin/conductor-exec uses #!/usr/bin/env zsh (portable)
  • Recommendation: Use #!/usr/bin/env zsh in conductor-setup.sh:1 for portability

2. Logic inconsistency in run_cmd function (lines 44-50)

  • Only uses bin/conductor-exec wrapper for mise users
  • Falls back to direct execution for asdf
  • Question: Why not always use the wrapper if it exists?

3. Race condition: bin/conductor-exec might not exist

  • run_cmd assumes wrapper exists before repo is fully checked out
  • Could fail silently for mise users
  • Recommendation: Add existence check

4. Missing version validation

  • Default versions (ruby 3.3.4, nodejs 20.18.0) might not be installable
  • Could fail with cryptic errors
  • Recommendation: Document requirements or add validation

Security Considerations

1. mise trust without confirmation (line 16)

  • Silently trusts directory configuration
  • Recommendation: Add comment explaining safety or add prompt

2. Command injection: Properly handled

  • Correct use of "$@" preserves argument boundaries

Test Coverage

  • Manual testing still needed for mise and asdf
  • Consider adding automated shell script tests
  • ShellCheck validation recommended

Code Quality

✅ Good:

  • Correct version comparison using sort -V
  • Clear documentation and comments
  • Follows project conventions

⚠️ Consider:

  • Use stderr for error messages
  • Run shellcheck on scripts
  • More consistent error handling

Summary

Recommendation: Approve with minor fixes

Must fix before merge:

  1. Change shebang to #!/usr/bin/env zsh in conductor-setup.sh:1
  2. Clarify run_cmd logic or document reasoning

Nice to have:

  1. Add shellcheck validation
  2. Document default version requirements
  3. Add security comment for mise trust
  4. Consider automated tests

Overall: Solid improvement to developer experience. Issues are minor and easily addressable.

🤖 Review generated with Claude Code

The message said "Running initial linting checks" but only verified
rubocop was installed. Changed to "Verifying linting tools".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Jan 21, 2026

Code Review: Update Conductor config to support multiple version managers

Overview

This PR adds support for multiple version managers (mise, asdf, and PATH-based tools). Overall, this is a well-thought-out improvement that addresses real developer experience issues.

✅ Strengths

  1. Clear documentation in CLAUDE.md with helpful examples
  2. Graceful fallback strategy: mise → asdf → PATH
  3. Informative output about which version manager is detected
  4. Simple, well-documented wrapper design

🔍 High Priority Issues

1. Shell compatibility (conductor-setup.sh:1)

The script uses #!/bin/zsh but the previous version used #!/usr/bin/env bash. Many CI/production environments use bash by default. This could cause failures on systems without zsh.

Recommendation: Revert to bash or add a check to verify zsh is available.

2. Version comparison portability (conductor-setup.sh:60, 69)

The sort -V flag is GNU-specific and may not work on macOS/BSD systems without GNU coreutils.

Recommendation: Test on macOS or use a more portable version comparison function.

3. Tool installation inconsistency

The script calls mise install for mise users but doesn't call asdf install for asdf users.

Recommendation: Add asdf tool installation for consistency.

🔧 Medium Priority Issues

  1. Missing executable bit verification - bin/conductor-exec might not be executable after git clone
  2. Environment file handling order - .env files copied late, but might be needed during bundle install
  3. Husky setup - Potentially overwrites custom pre-commit hooks without checking

🧪 Testing Needed

Before merging, test:

  • macOS (for sort -V compatibility)
  • PATH-based tools (rbenv/nvm)
  • When zsh is not available
  • When environment files don't exist

📝 Minor Suggestions

  1. Ensure trailing newline in conductor-setup.sh (per CLAUDE.md)
  2. Use consistent quoting for all variable expansions
  3. Include command names in error messages for easier debugging

Summary

Recommendation: Request changes to address the high-priority portability issues (shell compatibility, version comparison, asdf install), then merge after testing on both macOS and Linux with different version managers.

This is a valuable improvement - just needs some portability fixes before merging.

@claude
Copy link

claude bot commented Jan 21, 2026

PR Review: Update Conductor config to support multiple version managers

Summary

This PR adds multi-version-manager support (mise, asdf, PATH-based) to the Conductor setup script. Overall, this is a well-structured and thoughtful enhancement that improves the developer experience for Conductor users.

✅ Strengths

Code Quality

  • Clean architecture: The version manager detection cascade (mise → asdf → PATH) is logical and well-organized
  • Good abstraction: The run_cmd helper function nicely centralizes version manager logic
  • Error handling: Proper use of set -euo pipefail and clear error messages with exit codes
  • Self-documenting: Excellent inline comments and helpful user-facing output messages
  • Consistent style: Follows shell scripting best practices

Documentation

  • Excellent CLAUDE.md updates: Clear guidance on when/how to use bin/conductor-exec
  • Inline documentation: The wrapper script has thorough usage examples
  • User-friendly output: Clear emoji-prefixed messages guide users through setup

Design Decisions

  • Graceful degradation: Falls back appropriately when version managers are not present
  • Non-invasive: Only creates .tool-versions when needed for mise/asdf users
  • Backward compatible: Works with existing setups (asdf, rbenv, nvm, system tools)

🔍 Issues & Recommendations

1. Critical: Missing Trailing Newlines ⚠️

Per CLAUDE.md requirements, all files must end with a trailing newline. The following files are missing them:

  • bin/conductor-exec (line 24 should be followed by newline)
  • conductor.json (line 9 should be followed by newline)

Fix: Add a newline character at the end of both files.

2. Potential Bug: Version Comparison Edge Cases

# Line 60 & 70 - version comparison
if [[ $(echo -e "$MIN_RUBY_VERSION\n$RUBY_VERSION" | sort -V | head -n1) \!= "$MIN_RUBY_VERSION" ]]; then

Issues:

  • sort -V may not be available on all systems (not POSIX)
  • Version parsing with awk '{print $2}' could fail if Ruby outputs in a different format
  • For Node, cut -d'v' -f2 assumes version starts with 'v' (usually safe but not guaranteed)

Recommendation: Consider adding a fallback or using a more portable version comparison method. Alternatively, document the minimum system requirements.

3. Security: Trust Command Without User Confirmation

# Line 16
mise trust 2>/dev/null || true

Concern: Automatically trusting mise config could be a security risk if the repository contains malicious config.

Recommendation:

  • Add a comment explaining this is safe for trusted repositories
  • Consider logging that trust was granted
  • Or rely on users to manually trust before running setup

4. Redundant Version Manager Check in run_cmd

# Line 45
if [[ "$VERSION_MANAGER" == "mise" ]] && [[ -x "bin/conductor-exec" ]]; then

Question: Why check if bin/conductor-exec is executable? This script is creating it (or it is in the PR), so it should always exist and be executable.

Recommendation: Either remove the executability check or add a comment explaining the scenario where it might not exist.

5. Potential Timing Issue: run_cmd Before conductor-exec Exists

The setup script uses run_cmd starting at line 54, but bin/conductor-exec may not exist yet (it is added in this PR). For users upgrading, the first run might fail.

Recommendation: Consider adding a check or initialization of bin/conductor-exec earlier in the script, or handling the case where it does not exist yet.

6. Minor: Inconsistent asdf Detection

# Lines 18-28: Three different ways to detect asdf
elif [[ -f ~/.asdf/asdf.sh ]]; then
elif command -v asdf &> /dev/null; then
    if [[ -f /opt/homebrew/opt/asdf/libexec/asdf.sh ]]; then

Observation: The logic checks for ~/.asdf/asdf.sh first, then Homebrew location if asdf command exists. This means if both exist, Homebrew location is sourced after the standard location.

Question: Is this the intended priority? Consider reordering or documenting the precedence.

7. Enhancement: Node Version Extraction

# Line 68
NODE_VERSION=$(run_cmd node -v | cut -d'v' -f2)

Suggestion: Use parameter expansion for safer parsing:

NODE_VERSION=$(run_cmd node -v)
NODE_VERSION=${NODE_VERSION#v}  # Remove leading 'v' if present

8. Testing Gap

The PR description mentions manual testing is needed but has not been completed:

  • Test workspace setup in Conductor with mise
  • Test workspace setup in Conductor with asdf

Recommendation: Complete manual testing before merging, especially for edge cases like:

  • Upgrading from old setup without bin/conductor-exec
  • Systems without version managers
  • Systems with multiple version managers installed

🎯 Performance Considerations

  • Good: Version detection happens once at the start
  • Good: Using exec in wrapper script avoids unnecessary process spawning
  • Minor: Multiple run_cmd invocations for version checks could be optimized, but this is negligible for a setup script

🔒 Security Considerations

  • ✅ No obvious injection vulnerabilities
  • ⚠️ Automatic mise trust (see issue NO Merge - Relax ActiveSupport and Rails restrictions #3 above)
  • ✅ Using --frozen-lockfile for yarn install prevents unexpected dependency changes
  • ✅ Proper quoting throughout prevents word splitting issues

📋 Test Coverage

Missing: No automated tests for the shell scripts. Consider adding:

  • Unit tests using a shell testing framework (e.g., bats-core)
  • Integration tests in CI that run the setup script in different environments
  • Tests for the conductor-exec wrapper behavior

Note: The PR checklist shows linting passes but manual testing is incomplete.

🎨 Code Style

  • ✅ Consistent use of zsh shebang
  • ✅ Good emoji usage for visual clarity
  • ✅ Proper indentation (2 spaces)
  • ✅ Clear variable naming
  • ⚠️ Missing trailing newlines (violates CLAUDE.md requirement)

📝 Changelog

Not Required: This is an infrastructure/development environment change, not a user-facing feature. Per CLAUDE.md, no changelog entry is needed. ✅

🎓 Overall Assessment

Rating: 8.5/10

This is a solid PR that meaningfully improves the developer experience. The code is well-written, documented, and follows best practices. The main issues are:

  1. Must fix: Missing trailing newlines (linting requirement)
  2. Should fix: Complete manual testing
  3. Consider: Version comparison portability and security implications of auto-trust

✅ Recommendations Before Merge

Critical:

  1. ✅ Add trailing newlines to bin/conductor-exec and conductor.json
  2. ✅ Complete manual testing in Conductor with mise and asdf

Recommended:
3. Add comment explaining mise trust security implications
4. Clarify or remove the executability check in run_cmd
5. Test upgrade path for existing users without bin/conductor-exec

Optional:
6. Add shell script tests
7. Improve version comparison portability
8. Document asdf detection precedence

Great work overall! The multi-version-manager support will be valuable for teams using Conductor. 🚀

Copy link

@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: 1

🤖 Fix all issues with AI agents
In `@conductor-setup.sh`:
- Around line 12-41: When mise is detected, the script currently runs "mise
install" before creating .tool-versions, so on a clean repo mise has nothing to
install; remove or defer the "mise install" call from the initial mise detection
block (leave mise trust there if desired) and invoke "mise install" after the
block that creates the .tool-versions file (i.e., add a conditional that runs
mise install only when VERSION_MANAGER == "mise" right after the section that
writes .tool-versions), ensuring the VERSION_MANAGER variable and existence
checks (.tool-versions/.mise.toml) are used to decide whether to call mise
install.
♻️ Duplicate comments (1)
conductor-setup.sh (1)

110-113: Message/action mismatch already noted in prior review.

On a clean repo, mise install was running before .tool-versions existed,
so it had nothing to install. Now:
1. Detect mise and run mise trust
2. Create .tool-versions if missing
3. Run mise install (now has versions to install)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When creating .tool-versions for asdf/mise users, now reads from:
- .ruby-version (if exists) for Ruby version
- .node-version (if exists) for Node version

Falls back to sensible defaults (Ruby 3.3.4, Node 20.18.0) only
when these files don't exist.

This prevents version drift between project version files and
the generated .tool-versions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@justin808 justin808 merged commit ab57060 into main Jan 21, 2026
28 checks passed
@justin808 justin808 deleted the jg/npm-auth-precheck branch January 21, 2026 05:01
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.

2 participants