From fce57302de1f1dd15a79e68152dca6b1114d64a7 Mon Sep 17 00:00:00 2001 From: zumayaaustin-creator Date: Tue, 23 Jun 2026 08:50:04 -0700 Subject: [PATCH 1/3] Add cross-platform launcher scripts --- README.md | 14 ++++++++- install.ps1 | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++ install.sh | 15 ++++++---- start.ps1 | 46 +++++++++++++++++++++++++++++ start.sh | 19 ++++++++---- 5 files changed, 165 insertions(+), 13 deletions(-) create mode 100644 install.ps1 create mode 100644 start.ps1 diff --git a/README.md b/README.md index cc209ea..6421144 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ chmod +x install.sh && ./install.sh | Tool | Required? | Install | |------|-----------|---------| -| Python 3.10+ | ✅ Required | `sudo apt install python3 python3-pip` | +| Python 3.10+ | ✅ Required | Linux/macOS: install from your package manager or `python.org`. Windows: install from `python.org` and select **Add Python to PATH**. Verify with `python --version` or `py -3 --version`. | | Node.js 18+ | ⚠ For opencode | `curl -fsSL https://deb.nodesource.com/setup_20.x \| sudo bash - && sudo apt install -y nodejs` | | opencode | ⚠ For code tasks | `npm install -g @opencode/cli` | | Hermes Agent | ⚠ For memory/scheduling | `curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh \| bash` | @@ -113,6 +113,18 @@ chmod +x install.sh && ./install.sh > ⚠ = Optional — the dashboard works with any subset of installed agents. +### Windows Quick Start + +```powershell +git clone https://github.com/modimihir07/agentic-os.git +cd agentic-os +.\install.ps1 +.\start.ps1 +# Open http://127.0.0.1:8080 +``` + +The PowerShell launchers resolve Python in this order: `py -3.10`, `py -3`, then `python`. For manual commands, prefer `python -m pip install -r requirements.txt` and `python server.py --port 8080` so the same interpreter runs both dependency installation and the server. + --- ## 🔧 Configuration diff --git a/install.ps1 b/install.ps1 new file mode 100644 index 0000000..75e4eec --- /dev/null +++ b/install.ps1 @@ -0,0 +1,84 @@ +$ErrorActionPreference = "Stop" + +Write-Host "=== Agentic OS Installer ===" +Write-Host "" + +function Resolve-Python { + $candidates = @( + @{ Command = "py"; Args = @("-3.10") }, + @{ Command = "py"; Args = @("-3") }, + @{ Command = "python"; Args = @() } + ) + + foreach ($candidate in $candidates) { + $cmd = Get-Command $candidate.Command -ErrorAction SilentlyContinue + if (-not $cmd) { continue } + + try { + & $candidate.Command @($candidate.Args) --version *> $null + return $candidate + } catch { + continue + } + } + + throw "Python 3.10+ is required. Install it from https://www.python.org/downloads/ and check 'Add Python to PATH'." +} + +$python = Resolve-Python +$pythonCommand = $python.Command +$pythonArgs = @($python.Args) +$pythonVersion = & $pythonCommand @pythonArgs --version +Write-Host "Python: $pythonVersion" + +Write-Host "Installing Python dependencies..." +& $pythonCommand @pythonArgs -m pip install -r requirements.txt --quiet + +# Check Node.js (for opencode) +if (Get-Command node -ErrorAction SilentlyContinue) { + Write-Host "Node.js: $(node --version)" +} else { + Write-Warning "Node.js not found. opencode requires Node 18+. Install from https://nodejs.org/." +} + +# Check opencode +if (Get-Command opencode -ErrorAction SilentlyContinue) { + $opencodeVersion = try { opencode --version } catch { "installed" } + Write-Host "opencode: $opencodeVersion" +} else { + Write-Warning "opencode not found. Install via: npm install -g @opencode/cli" +} + +# Check Hermes +if (Get-Command hermes -ErrorAction SilentlyContinue) { + Write-Host "Hermes: found" +} else { + Write-Warning "Hermes Agent not found. See the Hermes Agent documentation for Windows installation guidance." +} + +# Check Gemini CLI +if (Get-Command gemini -ErrorAction SilentlyContinue) { + Write-Host "Gemini CLI: found" +} else { + Write-Warning "Gemini CLI not found. Install via: npm install -g @google/gemini-cli" +} + +New-Item -ItemType Directory -Force -Path backups, audit | Out-Null + +if (-not (Test-Path .git)) { + Write-Host "Initializing git repository..." + git init + foreach ($entry in @("audit/*", "backups/*.tar.gz", "data/settings.json")) { + if (-not (Test-Path .gitignore) -or -not (Select-String -Path .gitignore -Pattern ([regex]::Escape($entry)) -Quiet)) { + Add-Content -Path .gitignore -Value $entry + } + } +} + +Write-Host "" +Write-Host "=== Installation complete! ===" +Write-Host "" +Write-Host "Next steps:" +Write-Host " 1. Edit data/settings.json with your API keys" +Write-Host " 2. Run .\start.ps1 to launch the dashboard" +Write-Host " 3. Open http://127.0.0.1:8080 in your browser" diff --git a/install.sh b/install.sh index de32e91..56ef94a 100755 --- a/install.sh +++ b/install.sh @@ -14,22 +14,25 @@ esac echo "Detected OS: $OS" # Check Python -if command -v python3 &>/dev/null; then - echo "Python: $(python3 --version)" +if command -v python &>/dev/null; then + PYTHON="python" +elif command -v python3 &>/dev/null; then + PYTHON="python3" else - echo "ERROR: Python 3.10+ required. Install via: sudo apt install python3 python3-pip" + echo "ERROR: Python 3.10+ required. Install from https://www.python.org/downloads/ or your OS package manager." exit 1 fi +echo "Python: $($PYTHON --version)" # Check pip -if ! command -v pip3 &>/dev/null; then +if ! $PYTHON -m pip --version &>/dev/null; then echo "Installing pip..." - python3 -m ensurepip --upgrade + $PYTHON -m ensurepip --upgrade fi # Install Python deps echo "Installing Python dependencies..." -pip3 install -r requirements.txt --quiet +$PYTHON -m pip install -r requirements.txt --quiet # Check Node.js (for opencode) if command -v node &>/dev/null; then diff --git a/start.ps1 b/start.ps1 new file mode 100644 index 0000000..700f52d --- /dev/null +++ b/start.ps1 @@ -0,0 +1,46 @@ +$ErrorActionPreference = "Stop" + +Write-Host "Starting Agentic OS Dashboard..." +Write-Host "" + +if (-not (Test-Path server.py)) { + Write-Error "server.py not found. Are you in the right directory?" + exit 1 +} + +function Resolve-Python { + $candidates = @( + @{ Command = "py"; Args = @("-3.10") }, + @{ Command = "py"; Args = @("-3") }, + @{ Command = "python"; Args = @() } + ) + + foreach ($candidate in $candidates) { + $cmd = Get-Command $candidate.Command -ErrorAction SilentlyContinue + if (-not $cmd) { continue } + + try { + & $candidate.Command @($candidate.Args) --version *> $null + return $candidate + } catch { + continue + } + } + + throw "Python 3.10+ is required. Install it from https://www.python.org/downloads/ and check 'Add Python to PATH'." +} + +$python = Resolve-Python +$pythonCommand = $python.Command +$pythonArgs = @($python.Args) + +& $pythonCommand @pythonArgs -m pip install -r requirements.txt --quiet + +$port = & $pythonCommand @pythonArgs -c "import json; f=open('data/settings.json'); d=json.load(f); print(d.get('dashboard',{}).get('port',8080)); f.close()" 2>$null +if (-not $port) { $port = "8080" } + +Write-Host "Dashboard: http://127.0.0.1:$port" +Write-Host "Press Ctrl+C to stop" +Write-Host "" + +& $pythonCommand @pythonArgs server.py --port $port diff --git a/start.sh b/start.sh index 8dea07b..f165161 100755 --- a/start.sh +++ b/start.sh @@ -10,18 +10,25 @@ if [ ! -f server.py ]; then exit 1 fi +# Resolve Python +if command -v python &>/dev/null; then + PYTHON="python" +elif command -v python3 &>/dev/null; then + PYTHON="python3" +else + echo "ERROR: Python 3.10+ required. Install from https://www.python.org/downloads/ or your OS package manager." + exit 1 +fi + # Check dependencies -pip3 install -r requirements.txt --quiet 2>/dev/null +$PYTHON -m pip install -r requirements.txt --quiet 2>/dev/null # Get port from settings or default -PORT=8080 -if command -v python3 &>/dev/null; then - PORT=$(python3 -c "import json; f=open('data/settings.json'); d=json.load(f); print(d.get('dashboard',{}).get('port',8080)); f.close()" 2>/dev/null || echo "8080") -fi +PORT=$($PYTHON -c "import json; f=open('data/settings.json'); d=json.load(f); print(d.get('dashboard',{}).get('port',8080)); f.close()" 2>/dev/null || echo "8080") echo "Dashboard: http://127.0.0.1:${PORT}" echo "Press Ctrl+C to stop" echo "" # Start server -python3 server.py --port "${PORT}" +$PYTHON server.py --port "${PORT}" From d5584a04b461509a142d6543b21ebe431b18b700 Mon Sep 17 00:00:00 2001 From: zumayaaustin-creator Date: Tue, 23 Jun 2026 08:59:27 -0700 Subject: [PATCH 2/3] docs: add Windows prerequisites --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index cc209ea..a720645 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,8 @@ chmod +x install.sh && ./install.sh ## 📋 Prerequisites +### Linux/macOS + | Tool | Required? | Install | |------|-----------|---------| | Python 3.10+ | ✅ Required | `sudo apt install python3 python3-pip` | @@ -111,8 +113,20 @@ chmod +x install.sh && ./install.sh | Hermes Agent | ⚠ For memory/scheduling | `curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh \| bash` | | Gemini CLI | ⚠ For Google AI | `npm install -g @google/gemini-cli` | +### Windows + +| Tool | Required? | Install | Verify / Next Step | +|------|-----------|---------|--------------------| +| Python 3.10+ | ✅ Required | Install from [python.org/downloads/windows](https://www.python.org/downloads/windows/) and enable **“Add python.exe to PATH”** during setup. | `python --version` | +| Node.js 18+ | ⚠ For opencode and Gemini CLI | Install from [nodejs.org](https://nodejs.org/). | `node --version` and `npm --version` | +| opencode | ⚠ For code tasks | `npm install -g @opencode/cli` | Confirm the CLI is available in a new terminal session. | +| Gemini CLI | ⚠ For Google AI | `npm install -g @google/gemini-cli` | Run `gemini auth login` and complete OAuth in the browser. | +| Hermes Agent | ⚠ For memory/scheduling | Windows support must be verified separately if the upstream installer remains Bash-only. | Check the upstream Hermes Agent install docs before relying on native Windows support. | + > ⚠ = Optional — the dashboard works with any subset of installed agents. +> **PowerShell execution policy:** if you use PowerShell scripts, allow local scripts for your user with `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`, or run a single installer invocation with `powershell -ExecutionPolicy Bypass -File .\install.ps1`. + --- ## 🔧 Configuration From b3f2ee5a0616c5759a6a805c25a0730677efebf4 Mon Sep 17 00:00:00 2001 From: zumayaaustin-creator Date: Tue, 23 Jun 2026 08:59:48 -0700 Subject: [PATCH 3/3] Configure CORS origins from dashboard settings --- server.py | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/server.py b/server.py index ca97124..839da22 100644 --- a/server.py +++ b/server.py @@ -21,6 +21,8 @@ from fastapi.responses import HTMLResponse, JSONResponse, Response from fastapi.staticfiles import StaticFiles from pydantic import BaseModel +BASE_DIR = Path(__file__).parent.resolve() + app = FastAPI(title="Agentic OS", version="1.1.0") # Load OpenRouter API key from Hermes .env @@ -33,16 +35,44 @@ if HERMES_ENV.exists(): if k == "OPENROUTER_API_KEY": os.environ[k] = v # last value wins (matches shell sourcing) +def get_cors_origins() -> list[str]: + """Return local dashboard origins allowed to call the API.""" + port = 8080 + settings_file = BASE_DIR / "data" / "settings.json" + + if settings_file.exists(): + try: + settings = json.loads(settings_file.read_text(encoding="utf-8")) + port = int(settings.get("dashboard", {}).get("port", port)) + except (json.JSONDecodeError, OSError, TypeError, ValueError): + port = 8080 + + origins = { + "http://127.0.0.1:8080", + "http://localhost:8080", + f"http://127.0.0.1:{port}", + f"http://localhost:{port}", + } + + extra_origins = os.environ.get("AGENTIC_OS_CORS_ORIGINS", "") + origins.update( + origin.strip() + for origin in extra_origins.split(",") + if origin.strip() + ) + + return sorted(origins) + + # CORS for local dev app.add_middleware( CORSMiddleware, - allow_origins=["http://127.0.0.1:8080", "http://localhost:8080"], + allow_origins=get_cors_origins(), allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) -BASE_DIR = Path(__file__).parent.resolve() # ─── Models ───────────────────────────────────────────────────────