Ctrl K
ComunidadGuías…

install.ps1

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# OpenCompany Installer for Windows
# Usage: iwr -useb https://raw.githubusercontent.com/zeenie-ai/OpenCompany/main/install.ps1 | iex
#
# This script installs OpenCompany and its dependencies:
# - bun (the JavaScript runtime and package manager; no Node.js, no npm)
# - Python 3.12+ (via winget/choco)
# - uv (Python package manager)
#
# Prefer the desktop app if you just want to use OpenCompany on a laptop; this
# path is for terminal use.

$ErrorActionPreference = "Stop"

$MIN_PYTHON_VERSION = "3.12"
$PKG_NAME = "@zeenie-ai/opencompany"

# Colors
function Write-Color {
    param([string]$Text, [string]$Color = "White")
    Write-Host $Text -ForegroundColor $Color
}

function Info { Write-Color "[INFO] $args" "Cyan" }
function Success { Write-Color "[OK] $args" "Green" }
function Warn { Write-Color "[WARN] $args" "Yellow" }
function Error-Exit { Write-Color "[ERROR] $args" "Red"; exit 1 }

# Banner
Write-Host ""
Write-Color "  OpenCompany" "Cyan"
Write-Host ""
Write-Host "Self-improving AI employees, running on your own computer"
Write-Host ""

# Check if command exists
function Has-Command {
    param([string]$Command)
    $null -ne (Get-Command $Command -ErrorAction SilentlyContinue)
}

# Get package manager
function Get-PackageManager {
    if (Has-Command "winget") { return "winget" }
    if (Has-Command "choco") { return "choco" }
    return $null
}

# Refresh PATH from registry
function Refresh-Path {
    $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
}

# bun installs to $env:BUN_INSTALL (default ~\.bun) and puts global bin shims
# in its bin dir. Where it stores the global package itself varies, so nothing
# below depends on that: the `company` shim knows its own package root and
# `company provision` does the rest.
$BUN_HOME = if ($env:BUN_INSTALL) { $env:BUN_INSTALL } else { Join-Path $env:USERPROFILE ".bun" }
$BUN_BIN_DIR = Join-Path $BUN_HOME "bin"

# =============================================================================
# Dependency Checks and Installation
# =============================================================================

function Check-Bun {
    if (Has-Command "bun") {
        Success "bun $(bun --version)"
        return $true
    }
    return $false
}

function Install-Bun {
    Info "Installing bun (JavaScript runtime and package manager)..."
    Invoke-RestMethod https://bun.sh/install.ps1 | Invoke-Expression
    $env:Path = "$BUN_BIN_DIR;$env:Path"
    Refresh-Path
    $env:Path = "$BUN_BIN_DIR;$env:Path"
    if (-not (Check-Bun)) {
        Error-Exit "Failed to install bun. Install it manually from https://bun.sh and restart PowerShell."
    }
}

function Check-Python {
    foreach ($cmd in @("python", "python3")) {
        if (Has-Command $cmd) {
            $versionOutput = & $cmd --version 2>&1
            if ($versionOutput -match "Python (\d+)\.(\d+)") {
                $major = [int]$Matches[1]
                $minor = [int]$Matches[2]
                if ($major -ge 3 -and $minor -ge 12) {
                    Success "Python $major.$minor ($cmd)"
                    $script:PYTHON_CMD = $cmd
                    return $true
                }
            }
        }
    }
    Warn "Python $MIN_PYTHON_VERSION+ not found"
    return $false
}

function Install-Python {
    Info "Installing Python $MIN_PYTHON_VERSION..."
    $pm = Get-PackageManager

    switch ($pm) {
        "winget" {
            winget install Python.Python.3.12 --accept-package-agreements --accept-source-agreements
        }
        "choco" {
            choco install python312 -y
        }
        default {
            Error-Exit "Please install winget or chocolatey, or install Python manually from https://python.org/"
        }
    }

    Refresh-Path

    if (-not (Check-Python)) {
        Error-Exit "Failed to install Python. Please install manually and restart PowerShell."
    }
}

function Check-Uv {
    if (Has-Command "uv") {
        $version = (uv --version) -replace "uv ", ""
        Success "uv $version"
        return $true
    }
    return $false
}

function Install-Uv {
    Info "Installing uv (Python package manager)..."

    # Try pip first
    if ($script:PYTHON_CMD) {
        try {
            & $script:PYTHON_CMD -m pip install uv 2>&1 | Out-Null
            Refresh-Path
            if (Check-Uv) { return }
        } catch {}
    }

    # Fallback to official installer
    Invoke-RestMethod https://astral.sh/uv/install.ps1 | Invoke-Expression
    $env:Path = "$env:USERPROFILE\.local\bin;$env:Path"

    if (-not (Check-Uv)) {
        Error-Exit "Failed to install uv"
    }
}

# A previous npm-based install (or the pre-rebrand `machinaos` package) leaves
# a `company` / `machina` shim on PATH that would shadow the bun one. Remove it
# when npm happens to be around; skip silently otherwise.
function Remove-LegacyNpmInstalls {
    if (-not (Has-Command "npm")) { return }
    foreach ($pkg in @($PKG_NAME, "machinaos")) {
        npm list -g --depth=0 $pkg *> $null
        if ($LASTEXITCODE -eq 0) {
            Info "Removing legacy npm install of $pkg..."
            npm uninstall -g $pkg *> $null
            if ($LASTEXITCODE -ne 0) { Warn "Could not remove $pkg; run: npm uninstall -g $pkg" }
        }
    }
}

# =============================================================================
# Main Installation Flow
# =============================================================================

function Main {
    Write-Host ""
    Info "Checking dependencies..."
    Write-Host ""

    # Check and install dependencies
    if (-not (Check-Bun)) { Install-Bun }
    if (-not (Check-Python)) { Install-Python }
    if (-not (Check-Uv)) { Install-Uv }

    Remove-LegacyNpmInstalls

    Write-Host ""
    Info "Installing OpenCompany..."
    Write-Host ""

    # bun finds its global "project" by walking up from $BUN_INSTALL\install\global
    # until it meets a package.json. A stray package.json or package-lock.json in
    # the user profile (an old npm mishap) therefore hijacks global installs and
    # `bun add -g` fails with "InvalidNPMLockfile" (docs-internal/errors.md #23).
    # Giving the global dir its own manifest stops the walk-up.
    $globalDir = Join-Path $BUN_HOME "install\global"
    New-Item -ItemType Directory -Force -Path $globalDir | Out-Null
    $globalManifest = Join-Path $globalDir "package.json"
    if (-not (Test-Path $globalManifest)) {
        Set-Content -Path $globalManifest -Value '{ "private": true }' -Encoding utf8
    }

    # Global install as the current user (bun's global root is user-owned).
    bun add -g $PKG_NAME
    if ($LASTEXITCODE -ne 0) {
        Error-Exit "bun add -g $PKG_NAME failed."
    }

    # bun runs no lifecycle scripts for a global package, so provision the
    # Python side now rather than on the first `company` command. The shim is
    # addressed through bun's own answer for the global bin dir.
    $company = Join-Path (bun pm bin -g) "company.exe"
    Info "Provisioning the Python environment..."
    & $company provision
    if ($LASTEXITCODE -ne 0) {
        Error-Exit "Provisioning failed. Re-run with: company provision"
    }

    Write-Host ""
    Write-Color "============================================" "Green"
    Write-Color "  OpenCompany installed successfully!" "Green"
    Write-Color "============================================" "Green"
    Write-Host ""
    Write-Host "  Start OpenCompany:"
    Write-Host "    company start"
    Write-Host ""
    Write-Host "  Run diagnostics:"
    Write-Host "    company doctor"
    Write-Host ""
    Write-Host "  If 'company' is not found, open a new PowerShell window (bun's bin dir"
    Write-Host "  was added to your PATH)."
    Write-Host ""
}

# Run main
Main