-
Notifications
You must be signed in to change notification settings - Fork 32
Feature/cross platform installation scripts #351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Feature/cross platform installation scripts #351
Conversation
- Add install_pieces_cli.sh for macOS/Linux with shell auto-detection - Add install_pieces_cli.ps1 for Windows/PowerShell with cross-platform support - Both scripts create isolated virtual environments in ~/.pieces-cli - Include wrapper scripts for seamless CLI execution - Support shell completion setup for bash, zsh, fish, and PowerShell - Provide interactive configuration during installation
- Add ManageUpdateCommand for updating CLI across installation methods - Add ManageStatusCommand for checking version and update status - Add ManageUninstallCommand for clean removal including configs - Auto-detect installation method (pip, homebrew, installer script) - Support forced updates and configuration cleanup - Include proper error handling and user confirmations
- Register manage command in app.py command list - Add ManageCommandGroup import in command_interface/__init__.py - Add manage command URL constants in urls.py - Enable manage command without requiring PiecesOS login
- Add installer script instructions with curl/irm commands - Reorganize installation section with recommended installer scripts - Update shell completion setup with better formatting - Change uninstall instruction to use 'pieces manage uninstall' - Fix minor formatting issues in shell completion examples
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements cross-platform installation scripts for the Pieces CLI and adds a new “manage” command group to handle self-updates, status checks, and uninstalls, as well as a CLI-based PiecesOS updater with progress UI.
- Add
install_pieces_cli.shandinstall_pieces_cli.ps1for shell and PowerShell installers - Introduce
managesubcommands (update,status,uninstall) and wire them into the CLI - Provide a
PiecesUpdaterclass to perform PiecesOS updates in the CLI with rich progress indicators
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pieces/urls.py | Added placeholder URLs for manage commands |
| src/pieces/core/update_pieces_os.py | New module to update PiecesOS via CLI with progress spinners/bars |
| src/pieces/command_interface/manage_commands.py | New manage subcommands (update, status, uninstall) |
| src/pieces/command_interface/init.py | Registered ManageCommandGroup |
| src/pieces/app.py | Integrated “manage” into the main CLI routing |
| install_pieces_cli.sh | Bash installer script for macOS/Linux |
| install_pieces_cli.ps1 | PowerShell installer script for Windows and cross-platform use |
| README.md | Documented the new installer scripts and updated uninstall instructions |
Comments suppressed due to low confidence (2)
src/pieces/urls.py:80
- The documentation URL for
CLI_MANAGE_DOCSis currently empty. Populate this constant with the correct link to the manage command group documentation.
CLI_MANAGE_DOCS = ""
install_pieces_cli.sh:40
- The comment says Python 3.8+ but the version check enforces 3.11+. Update the comment to reflect the actual minimum supported version (3.11+).
# Check if a Python version meets minimum requirements (3.8+)
fa4b1db to
a28ac84
Compare
a28ac84 to
edc982f
Compare
Screen.Recording.2025-07-14.at.6.06.49.PM.mov@robert-at-pieces here is how the script looks |
README.md
Outdated
| ```bash | ||
| # macOS/Linux | ||
| curl -fsSL https://raw.githubusercontent.com/pieces-app/cli-agent/main/install_pieces_cli.sh | sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tsavo-at-pieces @mack-at-pieces Do we want to give it another url something like https://pieces.app/cli/install?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we do it through the builds server. Have you gotten with @nathan-courtney-pieces on this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tsavo-at-pieces if you want to test it
curl -fsSL https://raw.githubusercontent.com/pieces-app/cli-agent/feature/cross-platform-installation-scripts/install_pieces_cli.sh | sh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tsavo-at-pieces You want to host it in GCP then have the builds server create a link to it?
We can get that in but note that the Attribution tracking stuff is currently on staging
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DETAILED SOLUTION:
Current Code (Line 39):
curl -fsSL https://raw.githubusercontent.com/pieces-app/cli-agent/main/install_pieces_cli.sh | shChange To:
# Secure Installation with Verification
# Option 1: Full verification process
VERSION="1.2.3" # Pin to specific version
BASE_URL="https://github.com/pieces-app/cli-agent/releases/download/v${VERSION}"
# Download files
curl -fsSL "${BASE_URL}/install_pieces_cli.sh" -o install_pieces_cli.sh
curl -fsSL "${BASE_URL}/install_pieces_cli.sh.sha256" -o install_pieces_cli.sh.sha256
# Verify checksum
sha256sum -c install_pieces_cli.sh.sha256 || exit 1
# Execute after verification
sh install_pieces_cli.sh
# Cleanup
rm -f install_pieces_cli.sh install_pieces_cli.sh.sha256Option 2: For README simplicity, provide a secure wrapper:
# This would call a script that does verification internally
curl -fsSL https://pieces.app/install.sh | sh -s -- --verifyRequired Infrastructure Changes:
- Create checksums for each release:
sha256sum install_pieces_cli.sh > install_pieces_cli.sh.sha256 - Upload both files to GitHub releases
- Consider GPG signing for additional security
- Create secure wrapper script at pieces.app domain with built-in verification
tsavo-at-pieces
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting detailed code review. I'll be adding inline comments for each file with specific issues and solutions.
tsavo-at-pieces
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting detailed code review for README.md
tsavo-at-pieces
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting review of PowerShell installer script
220c7a5 to
8e7d159
Compare
tsavo-at-pieces
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting review of manage_commands.py
tsavo-at-pieces
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Detailed Code Review Complete
I've added inline comments on every file with specific issues and solutions. Here's the summary:
🔴 CRITICAL Security Issues (Must Fix Before Merge)
-
Remote Code Execution Vulnerabilities
- Installation scripts execute remote code without verification (README.md:39, manage_commands.py:249)
- No checksum/signature verification anywhere
- Scripts could be compromised at source or via MITM
-
Unsafe Package Installation
- pip install without hash verification (both installer scripts)
- No version pinning
- No SSL certificate validation
-
Path Injection Risks
- PATH manipulation without validation (PowerShell:164, Shell scripts)
- Could corrupt system PATH or inject malicious directories
🟡 Major Code Quality Issues
-
Error Handling
- Generic exception catching loses debugging context
- No rollback mechanisms on failure
- Incomplete cleanup in error paths
-
Code Duplication
- ~40% logic duplicated between PS1 and SH installers
- Should use templating or shared configuration
-
Function Complexity
- Multiple functions exceed 50 lines
- Poor separation of concerns
- Difficult to test and maintain
-
Missing Tests
- No test coverage for new functionality
- Installation scripts untestable in current form
🟢 Positive Aspects
- Good user experience with colored output and prompts
- Comprehensive platform support
- Clean integration with existing CLI structure
- Proper virtual environment isolation
Required Actions
-
Security (Blocking)
- Add checksum verification for all downloads
- Pin package versions with hash verification
- Never pipe remote content directly to shell
- Validate all paths before modification
-
Code Quality (Strongly Recommended)
- Add comprehensive error handling
- Implement rollback mechanisms
- Reduce function complexity
- Add test coverage
-
Documentation
- Fill in missing URL constants
- Document security considerations
- Add troubleshooting guide
Please address at least the critical security issues before this can be merged. The remote code execution vulnerabilities pose a significant risk to all users.
- Split monolithic manage_commands.py into focused modules: - manage_group.py: Command group structure - status_command.py: Status checking functionality - update_command.py: Update operations - uninstall_command.py: Uninstall operations - utils.py: Shared utility functions - Create corresponding test modules for each component - Improve code organization and maintainability - Enable targeted testing of individual command components
- Add check to skip onboarding when command is 'completion' - Prevents unnecessary onboarding flow during shell completion - Improves completion command performance and user experience
|
@tsavo-at-pieces |
🔐 Comprehensive Security Enhancement PlanAfter conducting extensive research on the security concerns raised in this PR, I've created a comprehensive implementation plan to address all vulnerabilities while maintaining user convenience. 📊 Security Research SummaryMy research revealed alarming statistics about supply chain security in 2024-2025:
🎯 Proposed SolutionI've created Issue #361 to track the implementation of a comprehensive security enhancement plan: #361 The plan includes: Phase 1: Immediate Security (Week 1-2)
Phase 2: Enhanced Infrastructure (Month 1-2)
Phase 3: Industry-Leading Security (Month 3-6)
📁 Implementation Files CreatedI've prepared ready-to-use implementation files:
🔍 Key Security Improvements
✅ Backward CompatibilityAll security enhancements maintain backward compatibility:
📈 Next Steps
The security landscape demands we take these threats seriously, but we can implement these improvements without disrupting the user experience. The phased approach allows us to make immediate improvements while building toward industry-leading security practices. I'll now add specific implementation details as individual comments on the relevant files. |
|
This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation. |
| name: Security Scan | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout Code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Run Trivy Security Scan | ||
| uses: aquasecurity/trivy-action@master | ||
| with: | ||
| scan-type: 'fs' | ||
| scan-ref: '.' | ||
| format: 'sarif' | ||
| output: 'trivy-results.sarif' | ||
|
|
||
| - name: Upload Trivy Results | ||
| uses: github/codeql-action/upload-sarif@v2 | ||
| if: always() | ||
| with: | ||
| sarif_file: 'trivy-results.sarif' | ||
|
|
||
| - name: Run Bandit Security Scan | ||
| run: | | ||
| pip install bandit | ||
| bandit -r src/ -f json -o bandit-report.json || true | ||
| # Create summary | ||
| if [ -f bandit-report.json ]; then | ||
| echo "## Bandit Security Scan Results" >> $GITHUB_STEP_SUMMARY | ||
| echo "Issues found: $(jq '.metrics."_totals"."SEVERITY.HIGH"' bandit-report.json)" >> $GITHUB_STEP_SUMMARY | ||
| fi No newline at end of file |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the problem, we need to add a permissions block to the security-scan job in .github/workflows/release-security.yml. This block should explicitly restrict the permissions of the GITHUB_TOKEN to the minimum necessary for the job—most likely contents: read, which allows the job to clone the repository but not modify it. The block should be added directly under runs-on: ubuntu-latest in the security-scan job definition, without modifying the rest of the workflow. No additional dependencies or imports are required for this change.
-
Copy modified lines R170-R171
| @@ -167,6 +167,8 @@ | ||
| security-scan: | ||
| name: Security Scan | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Checkout Code | ||
| uses: actions/checkout@v4 |
| name: Build Distribution | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout Code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Python | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: '3.11' | ||
|
|
||
| - name: Install Build Dependencies | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install build twine | ||
| - name: Build Package | ||
| run: python -m build | ||
|
|
||
| - name: Check Distribution | ||
| run: twine check dist/* | ||
|
|
||
| - name: Generate SBOM | ||
| uses: anchore/sbom-action@v0 | ||
| with: | ||
| artifact-name: pieces-cli-sbom.spdx.json | ||
| output-file: dist/pieces-cli-sbom.spdx.json | ||
|
|
||
| - name: Upload Build Artifacts | ||
| uses: actions/upload-artifact@v3 | ||
| with: | ||
| name: dist | ||
| path: dist/ | ||
|
|
||
| publish-testpypi: |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix this issue, add an explicit permissions block to the build job in .github/workflows/trusted-publisher.yml, specifying the minimal required permissions. According to GitHub's recommendations and the nature of the build job, the safest starting point is contents: read, as the job only needs to read code from the repository (via checkout) and does not push any changes or create issues/pull requests. The permissions block should be added directly under the build job definition (after runs-on: ubuntu-latest), matching the pattern used in the other jobs. No further changes or imports are required.
-
Copy modified lines R21-R22
| @@ -18,6 +18,8 @@ | ||
| build: | ||
| name: Build Distribution | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Checkout Code | ||
| uses: actions/checkout@v4 |
| name: Verify Publication | ||
| needs: [publish-pypi] | ||
| if: always() && needs.publish-pypi.result == 'success' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Wait for Package Availability | ||
| run: sleep 60 | ||
|
|
||
| - name: Setup Python | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: '3.11' | ||
|
|
||
| - name: Create Test Environment | ||
| run: python -m venv test-env | ||
|
|
||
| - name: Install Published Package | ||
| run: | | ||
| source test-env/bin/activate | ||
| pip install pieces-cli | ||
| - name: Verify Installation | ||
| run: | | ||
| source test-env/bin/activate | ||
| pieces --version | ||
| - name: Run Basic Tests | ||
| run: | | ||
| source test-env/bin/activate | ||
| pieces help | ||
| - name: Create Summary | ||
| run: | | ||
| echo "## Publication Verification" >> $GITHUB_STEP_SUMMARY | ||
| echo "✅ Package successfully published to PyPI" >> $GITHUB_STEP_SUMMARY | ||
| echo "✅ Installation verification passed" >> $GITHUB_STEP_SUMMARY | ||
| echo "✅ Basic functionality confirmed" >> $GITHUB_STEP_SUMMARY No newline at end of file |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix this problem, add an explicit permissions block to the verify-publication job in .github/workflows/trusted-publisher.yml. The block should contain the minimal permissions required for this job to run, which in this case is typically just contents: read. Place the permissions: block directly under the job definition (verify-publication:), and above the steps: key. No other changes or imports are necessary.
-
Copy modified lines R120-R121
| @@ -117,6 +117,8 @@ | ||
| needs: [publish-pypi] | ||
| if: always() && needs.publish-pypi.result == 'success' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Wait for Package Availability | ||
| run: sleep 60 |
tsavo-at-pieces
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔍 Comprehensive Code Review for PR #351: Cross-Platform Installation Scripts & Manage Commands
I've conducted a thorough review of this PR in the context of its dependency relationship with PR #360. This PR is critical for #360 as it implements the pieces manage update command that #360 references in its error messages.
📊 Review Summary
- Files Reviewed: 27 files
- Lines Added: 7,254
- Critical Issues: 3
- Security Concerns: 2 (already being addressed)
- Code Quality Issues: 5
- Test Coverage: Good (2,605 lines of tests)
🎯 Dependency on PR #360
This PR MUST be merged before PR #360 because:
- PR #360's error messages direct users to run
pieces manage update - Without this PR, users following those instructions will encounter command not found errors
- This creates a poor user experience and confusion
✅ Positive Aspects
-
Comprehensive Implementation
- Well-structured manage command group (update, status, uninstall)
- Cross-platform support (Windows, macOS, Linux)
- Multiple installation method detection (pip, homebrew, chocolatey, winget, installer)
-
Excellent Test Coverage
- 2,605 lines of test code
- Tests for all major functionality
- Mock-based testing for external dependencies
-
Good User Experience
- Colored output for better readability
- Progress indicators for long operations
- Clear error messages with recovery instructions
-
Security Improvements in Progress
- Installation scripts are commented out pending security review
- Comprehensive security plan created (Issue #361)
- Security documentation added (SECURITY.md)
🚨 Critical Issues That Need Attention
1. Empty URL Constants (BLOCKING)
- Files:
src/pieces/urls.py:80-85 - Issue: All manage command documentation URLs are empty strings
- Impact: Help commands will have broken links
- Fix Required: Populate with actual documentation URLs or remove if not needed
2. Inconsistent Error Handling
- Files: Multiple locations in manage_commands/
- Issue: Some operations use bare
except:clauses - Impact: Could hide critical errors from users
- Fix Required: Use specific exception types
3. Windows PATH Manipulation
- File:
install_pieces_cli.ps1:164 - Issue: PATH manipulation without proper validation
- Impact: Could corrupt system PATH on Windows
- Fix Required: Add validation and length checks
🔧 Code Quality Issues
-
Function Complexity
- Several functions exceed 50 lines (e.g.,
_detect_installation_source) - Should be refactored into smaller, testable units
- Several functions exceed 50 lines (e.g.,
-
Missing Type Hints
- Some utility functions lack proper type annotations
- Makes code harder to maintain and debug
-
Duplicate Logic
- Installation detection logic repeated across files
- Should be consolidated into shared utilities
🔒 Security Status
The security concerns raised by @tsavo-at-pieces are being addressed:
- ✅ Curl piping commands are commented out
- ✅ Security documentation added
- ⏳ Checksum verification planned (Issue #361)
- ⏳ Signed releases planned
📋 Required Actions Before Merge
- Fill in documentation URLs in
urls.pyor remove empty constants - Fix broad exception handling to use specific exceptions
- Add Windows PATH validation to prevent corruption
- Address remaining inline comments from previous reviews
🎯 Recommendation
STATUS: APPROVE WITH CONDITIONS ✅
This PR should be merged as soon as the blocking issues are fixed because:
- It unblocks PR #360 which has critical error handling improvements
- The security concerns are being addressed separately and shouldn't block functionality
- The code quality is generally good with comprehensive tests
- The manage commands provide essential functionality for CLI maintenance
🔄 Merge Order
- Fix the blocking issues in this PR (especially empty URLs)
- Merge this PR (#351)
- Then merge PR #360 which depends on it
- Continue security enhancements per Issue #361
The implementation is solid, well-tested, and provides critical functionality. Once the documentation URLs are populated and basic error handling is improved, this will be ready to merge.
🔍 Specific Issues Found During Review1. Empty Documentation URLs (src/pieces/urls.py:80-85)All manage command documentation URLs are empty: CLI_UPDATE_DOCS = ""
CLI_COMPLETION_DOCS = ""
CLI_MANAGE_DOCS = ""
CLI_MANAGE_UPDATE_DOCS = ""
CLI_MANAGE_STATUS_DOCS = ""
CLI_MANAGE_UNINSTALL_DOCS = ""Fix Required: Either:
2. Broad Exception HandlingMultiple locations use bare src/pieces/command_interface/manage_commands/utils.py:26 except (subprocess.CalledProcessError, FileNotFoundError, OSError):
return NoneThis is good! But other places need similar specific exception handling. src/pieces/command_interface/manage_commands/update_command.py:239 except Exception as e:
Settings.logger.error(f"Update failed: {e}")
return FalseShould catch specific exceptions like 3. Windows PATH Security Issue (install_pieces_cli.ps1:164)The PATH manipulation lacks validation: $newPath = "$InstallDir;$currentPath"
[Environment]::SetEnvironmentVariable("Path", $newPath, [EnvironmentVariableTarget]::User)Issues:
Fix Required: # Validate install directory exists
if (-not (Test-Path $InstallDir)) {
Write-Error "Installation directory does not exist: $InstallDir"
return
}
# Check PATH length
if (($newPath.Length) -gt 2000) {
Write-Warning "PATH would exceed safe length. Please manually add: $InstallDir"
return
}
# Check for duplicates
if ($currentPath -notlike "*$InstallDir*") {
[Environment]::SetEnvironmentVariable("Path", $newPath, [EnvironmentVariableTarget]::User)
}4. Function ComplexityThe
5. Missing Error ContextWhen operations fail, we often don't provide enough context: src/pieces/command_interface/manage_commands/update_command.py:203 Settings.logger.error(f"Failed to update pieces-cli")Should include:
6. Test Improvements NeededWhile test coverage is good, some edge cases are missing:
Priority Order for Fixes
Once these are addressed, this PR will be ready to merge and unblock PR #360. |
✅ Verification of Implementation StatusI've verified the current state of the PR and can confirm: Security Measures ✓
Code Implementation ✓
Minor Issues Remaining
Integration with PR #360 ✓The Recommendation: This PR is ready to merge with the understanding that:
|
0927a8f to
ae513cd
Compare
ae513cd to
9f0c329
Compare
Fixed two test failures in TestExecutableLocation: - test_finds_pieces_in_installer_structure - test_finds_pieces_relative_to_python The issue was that these tests were trying to patch the 'exists' method directly on Path objects using patch.object(), but Path.exists is read-only. Changed approach to patch pathlib.Path.exists globally with custom mock functions that return True only for the specific paths being tested. Also fixed the __file__ patching in test_finds_pieces_in_installer_structure to properly patch the module-level __file__ attribute instead of trying to patch pathlib.Path.__file__ which doesn't exist. All TestExecutableLocation tests now pass successfully.
Screen.Recording.2025-07-09.at.4.30.13.PM.mov