From fb40bcdbbfd184a52de3c81f41e4e80ec0b63e86 Mon Sep 17 00:00:00 2001 From: Vagner Rodrigues Date: Mon, 25 May 2026 18:57:04 -0300 Subject: [PATCH] =?UTF-8?q?docs(readme):=20reflect=20v0.6.x=20=E2=80=94=20?= =?UTF-8?q?OpenCode=20CLI,=20plugins,=20Obsidian,=20headless=20browser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrites root README to match the state of main as of v0.6.1. Profile matrix - cli-bundle now lists 5 CLIs (added OpenCode). - 'plus on every profile' adds headless browser line. - 'cli-bundle additionally bundles' lists MCP servers, plugins, Obsidian vault, Dream mode — each as its own item with cross-link. Repo layout - lib/ shows obsidian.sh and plugins.sh. - cli-bundle script order updated: 05b-opencode, 08-obsidian, 09-plugins. New sections - Plugins: coverage matrix (GSD/gstack/superpowers per-CLI) + OpenSpec (universal) + official Anthropic marketplace (10 toggles). - Obsidian vault: layout, env knobs, -X ours conflict strategy. - Headless browser: chromium-browser apt path, fallback note, contrast vs Playwright bundled Chromium. - Tests + CI: install commands (apt/brew), CI + release workflow links. Maintenance - New npm-global update commands (openspec, openclaw). - Obsidian manual-sync command (obsidian-vault-sync wrapper). - Backup tar widened to cover all CLI config dirs + vault. Troubleshooting - New rows: Obsidian sync failure, plugin install hang, missing chromium. Status - 5-CLI bundle reflected. - Pointer to latest release tag (v0.6.1). - Removed shellcheck stub command; included real flags used by tests/lint.sh. Badges - Added CI + Release workflow status badges. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 211 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 166 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 52ba3af..48d28c5 100644 --- a/README.md +++ b/README.md @@ -2,31 +2,42 @@ > Idempotent shell-script installers that bootstrap a fresh Ubuntu 22.04 VPS > for one of four AI-agent stacks, with a one-profile-per-host mutex, -> shared base tooling, and DB clients baked in. +> shared base tooling, DB clients, headless browser, MCP servers, plugins, +> and an Obsidian-vault workspace shared across every CLI agent. [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE.md) ![Shell: bash](https://img.shields.io/badge/shell-bash-4EAA25) ![Target: Ubuntu 22.04](https://img.shields.io/badge/target-Ubuntu%2022.04-E95420) +![CI](https://github.com/govtech42/harness/actions/workflows/ci.yml/badge.svg) +![Release](https://github.com/govtech42/harness/actions/workflows/release.yml/badge.svg) ## What is this You rent a Lightsail/Hetzner/DO box. You want **one** of these stacks on it, fully configured, in a single command: -| Profile | What you get | -|--------------|-------------------------------------------------------------------------------------------| -| `cli-bundle` | Claude Code + OpenAI Codex + Google Antigravity + Cursor CLIs (any combination) | -| `openclaw` | [OpenClaw](https://github.com/openclaw/openclaw) — local agent gateway on port `18789` | -| `hermes` | [Hermes Agent](https://github.com/NousResearch/hermes-agent) (Nous Research, Python+uv) | -| `paperclip` | [Paperclip](https://github.com/paperclipai/paperclip) — Node API + embedded Postgres :3100 | +| Profile | What you get | +|--------------|-------------------------------------------------------------------------------------------------------| +| `cli-bundle` | Claude Code + OpenAI Codex + Google Antigravity + Cursor + **OpenCode** CLIs (any combination) | +| `openclaw` | [OpenClaw](https://github.com/openclaw/openclaw) — local agent gateway on port `18789` | +| `hermes` | [Hermes Agent](https://github.com/NousResearch/hermes-agent) (Nous Research, Python+uv) | +| `paperclip` | [Paperclip](https://github.com/paperclipai/paperclip) — Node API + embedded Postgres :3100 | Plus, on every profile: - Common Linux toolkit (`tmux`, `git`, `vim`, `jq`, `ripgrep`, `fd`, `fzf`, `htop`, …) - `psql` (PostgreSQL client) and `clickhouse-client` from the official ClickHouse deb repo +- **Headless browser** (`chromium` via apt — falls back to Playwright's bundled Chromium) - Timezone, swap file, npm user-global prefix, `~/.bashrc` PATH - A mutex marker so you don't accidentally stack two agent runtimes on one host +`cli-bundle` additionally bundles: + +- **MCP servers** for Claude (Context7, Linear, Slack, GitHub, Supabase, Sentry, Notion, Playwright, Filesystem, Obsidian) +- **Plugins** — GSD, gstack, superpowers, OpenSpec, plus the official Anthropic marketplace (Linear/Slack/GitHub/Notion/Atlassian/Asana/Figma/Sentry/Supabase/Vercel) +- **Obsidian vault** — shared workspace at `$OBSIDIAN_VAULT_DIR`, all CLIs read/write, optional git auto-sync +- **Dream mode** — cron-driven memory consolidation for Claude + ## Repo layout ``` @@ -34,11 +45,17 @@ harness/ ├── install.sh # top-level launcher (menu, arg, --status, --force) ├── lib/ │ ├── common.sh # mutex_check, mutex_set, load_env, banner -│ └── base-packages.sh # install_base_packages, install_db_clients, -│ # install_node, install_pnpm, install_uv +│ ├── base-packages.sh # install_base_packages, install_db_clients, +│ │ # install_headless_browser, install_node, +│ │ # install_pnpm, install_bun, install_uv +│ ├── obsidian.sh # setup_vault, sync_vault_now/install/uninstall +│ └── plugins.sh # claude_headless, install_official_claude_plugin, +│ # install_claude_plugin, install_openspec, +│ # install_gstack_for, print_manual_install_hint └── profiles/ ├── cli-bundle/ # 01-system → 02-claude → 03-codex → 04-antigravity - │ # → 05-cursor → 06-mcp → 07-dream + │ # → 05-cursor → 05b-opencode → 08-obsidian + │ # → 06-mcp → 07-dream → 09-plugins ├── openclaw/ # 01-system → 02-openclaw ├── hermes/ # 01-system → 02-hermes └── paperclip/ # 01-system → 02-paperclip @@ -47,7 +64,8 @@ harness/ Per-profile docs live in each `profiles//README.md`. Architecture + rationale in [`.claude/PLAN.md`](.claude/PLAN.md). Decision log in [`.claude/CHANGELOG.md`](.claude/CHANGELOG.md). Open design decisions in -[`.claude/RECOMMENDATIONS.md`](.claude/RECOMMENDATIONS.md). +[`.claude/RECOMMENDATIONS.md`](.claude/RECOMMENDATIONS.md). Open work items +in [`.claude/TODO.md`](.claude/TODO.md). ## Quick start @@ -103,37 +121,45 @@ Why: these stacks compete for PATH entries, ports, systemd unit names, and memory on small VPSes. Coexistence isn't supported. If you *really* know better, `--force` bypasses the check. -The `cli-bundle` profile is the one exception: it intentionally stacks four -**thin** CLI clients (Claude, Codex, Antigravity, Cursor) which have disjoint -config dirs and no port binds. +The `cli-bundle` profile is the exception: it intentionally stacks **five** +thin CLI clients (Claude, Codex, Antigravity, Cursor, OpenCode) which have +disjoint config dirs and no port binds. ## Pre-requisites -| Requirement | Detail | -|-----------------|---------------------------------------------------------------------| -| OS | Ubuntu 22.04 LTS (other Debian-likes may work but are untested) | -| RAM | 2 GB minimum; 4 GB recommended for `cli-bundle` with MCPs enabled | -| Disk | 10 GB free | -| Network | Outbound HTTPS to npm, GitHub, ClickHouse repo, each agent provider | -| Inbound | Static IP / SSH on `:22`; OAuth callbacks for some agents | -| User | `ubuntu` (or any user with `sudo` and a writable `$HOME`) | +| Requirement | Detail | +|-----------------|-----------------------------------------------------------------------| +| OS | Ubuntu 22.04 LTS (other Debian-likes may work but are untested) | +| RAM | 2 GB minimum; 4 GB recommended for `cli-bundle` with MCPs + plugins | +| Disk | 10 GB free | +| Network | Outbound HTTPS to npm, GitHub, ClickHouse repo, each agent provider | +| Inbound | Static IP / SSH on `:22`; OAuth callbacks for some agents | +| User | `ubuntu` (or any user with `sudo` and a writable `$HOME`) | ## What each profile installs ### `cli-bundle` -Per-CLI toggles in `.env` (`INSTALL_CLAUDE`, `INSTALL_CODEX`, -`INSTALL_ANTIGRAVITY`, `INSTALL_CURSOR`). Each defaults `true` for Claude, -`false` for the others — flip to opt in. - -- **Claude Code** — `npm i -g @anthropic-ai/claude-code` -- **Codex** — `npm i -g @openai/codex` -- **Antigravity** — upstream installer (`curl … | bash`) -- **Cursor** — upstream installer (`curl … | bash`) -- **MCP servers** — registered for Claude only (Context7, Linear, Slack, - GitHub, Supabase, Sentry, Notion, Playwright, Filesystem) -- **Dream mode** — cron-driven `claude -p` invocation of the - `anthropic-skills:consolidate-memory` skill at `03:00`. Log auto-rotates at - 5 MiB. See [profiles/cli-bundle/README.md](profiles/cli-bundle/README.md). + +Five CLIs — toggle each in `.env`. Defaults: Claude `true`, others `false`. + +| Toggle | CLI | Install path | +|------------------------|----------------------|-------------------------------------------------------| +| `INSTALL_CLAUDE` | Claude Code | `npm i -g @anthropic-ai/claude-code` | +| `INSTALL_CODEX` | OpenAI Codex | `npm i -g @openai/codex` | +| `INSTALL_ANTIGRAVITY` | Google Antigravity | upstream installer (`curl … \| bash`) | +| `INSTALL_CURSOR` | Cursor agent | upstream installer (`curl … \| bash`) | +| `INSTALL_OPENCODE` | OpenCode | upstream installer (`curl -fsSL https://opencode.ai/install \| bash`) | + +Plus: + +- **MCP servers** registered for Claude (`06-mcp.sh`) — Context7, Linear, + Slack, GitHub, Supabase, Sentry, Notion, Playwright, Filesystem, Obsidian. +- **Plugins** (`09-plugins.sh`) — see [Plugins](#plugins) below. +- **Obsidian vault** (`08-obsidian.sh`) — shared workspace for every CLI. +- **Dream mode** (`07-dream.sh`) — cron-driven `claude -p` invocation of + `anthropic-skills:consolidate-memory` at `03:00`; log auto-rotates at 5 MiB. + +Full docs: [profiles/cli-bundle/README.md](profiles/cli-bundle/README.md). ### `openclaw` Installs `openclaw` from npm globally. Seeds `~/.openclaw/openclaw.json` with @@ -150,6 +176,59 @@ puts `hermes` on PATH. Dev path (`false`) does git clone + `setup-hermes.sh`. the app on first run; no external DB needed. Optional systemd unit for the API server on port `3100`. +## Plugins + +Available in `cli-bundle` via `09-plugins.sh`. Headless install where the CLI +supports it; printed manual hint otherwise. + +| Plugin | Claude | Codex | Antigravity | Cursor | OpenCode | +|------------------|----------|-------------------|----------------------------|----------------------|----------------------| +| GSD | headless | — | — | — | — | +| gstack | headless | — | — | — | headless | +| superpowers | headless | manual `/plugins` | manual (not documented) | manual `/add-plugin` | manual fetch URL | +| **OpenSpec** | universal (npm global, `/opsx:*` slash commands from any CLI) — invoked via `openspec init` per project | + +Plus the **official Anthropic marketplace** (Claude-only, bundles pre-configured MCP + skills + slash commands): + +`INSTALL_LINEAR_PLUGIN`, `INSTALL_SLACK_PLUGIN`, `INSTALL_GITHUB_PLUGIN`, +`INSTALL_NOTION_PLUGIN`, `INSTALL_ATLASSIAN_PLUGIN`, `INSTALL_ASANA_PLUGIN`, +`INSTALL_FIGMA_PLUGIN`, `INSTALL_SENTRY_PLUGIN`, `INSTALL_SUPABASE_PLUGIN`, +`INSTALL_VERCEL_PLUGIN`. + +These coexist with the raw MCP toggles in `06-mcp.sh` (e.g. `INSTALL_LINEAR=true` +registers the bare MCP endpoint); the official plugin is the richer path. + +## Obsidian vault (cli-bundle) + +Opt-in shared workspace every CLI reads and writes. Headless on VPS (no +Obsidian app required); same files render in the desktop app on a workstation +that pulls the git remote. + +```env +INSTALL_OBSIDIAN=true +OBSIDIAN_VAULT_DIR=/home/ubuntu/vault +OBSIDIAN_VAULT_REPO=git@github.com:you/your-vault.git # optional +OBSIDIAN_AUTOSYNC=true # opt-in +OBSIDIAN_AUTOSYNC_SCHEDULE=*/15 * * * * +``` + +Layout: + +``` +$OBSIDIAN_VAULT_DIR/ +├── .claude/log.md # Claude Code writes here +├── .codex/log.md # Codex +├── .antigravity/log.md # Antigravity +├── .cursor/log.md # Cursor +├── inbox.md # any agent appends +├── notes/ # main markdown +├── .obsidian/app.json # config seed (versioned if git) +└── .gitignore # excludes workspace.json, cache, .trash/ +``` + +Git auto-sync uses `-X ours` — local edits always win on conflict +(trade-off documented in `.claude/RECOMMENDATIONS.md` and `.claude/CHANGELOG.md`). + ## Database clients Every profile's `01-system.sh` installs: @@ -161,6 +240,16 @@ Every profile's `01-system.sh` installs: Toggle off with `INSTALL_DB_CLIENTS=false` in the profile's `.env`. Granular control: `INSTALL_POSTGRES_CLIENT`, `INSTALL_CLICKHOUSE_CLIENT`. +## Headless browser + +`install_headless_browser()` in `lib/base-packages.sh` tries `chromium-browser` +then `chromium` via apt; warns (does not fail) if no apt package resolves. +Used for general agent shell work. Default `INSTALL_HEADLESS_BROWSER=true`. + +Playwright is a separate concern: `INSTALL_PLAYWRIGHT=true` in `06-mcp.sh` +does its own `playwright install-deps` + bundled-Chromium download + +`@playwright/mcp@latest` MCP registration. + ## Secrets - Each profile's `.env` (copied from `.env.example`) holds provider keys and @@ -171,7 +260,8 @@ control: `INSTALL_POSTGRES_CLIENT`, `INSTALL_CLICKHOUSE_CLIENT`. - Tokens (OAuth, etc.) live under `~/.claude/`, `~/.openclaw/`, etc. — back these up before destroying the VPS: ```bash - tar czf harness-backup.tgz ~/.claude ~/.openclaw ~/.harness-profile + tar czf harness-backup.tgz ~/.claude ~/.openclaw ~/.opencode \ + ~/.codex ~/.cursor ~/.antigravity ~/vault ~/.harness-profile ``` ## Maintenance @@ -186,12 +276,38 @@ control: `INSTALL_POSTGRES_CLIENT`, `INSTALL_CLICKHOUSE_CLIENT`. # wipe the marker if you intend a clean swap (combine with --force) rm ~/.harness-profile && ./install.sh -# update a CLI in cli-bundle +# update an npm-global CLI npm update -g @anthropic-ai/claude-code npm update -g @openai/codex -npm update -g openclaw # for the openclaw profile +npm update -g openclaw # for the openclaw profile +npm update -g @fission-ai/openspec # if INSTALL_OPENSPEC=true + +# manual Obsidian sync (if INSTALL_OBSIDIAN + git repo configured) +source ~/.bashrc && obsidian-vault-sync ``` +## Tests + CI + +Local test harness in `tests/`: + +```bash +# install deps (Ubuntu/Debian) +sudo apt-get install -y shellcheck bats +# install deps (macOS) +brew install shellcheck bats-core + +bash tests/lint.sh +bash tests/check_env_completeness.sh +bats tests/ +``` + +GitHub Actions: + +- [`ci.yml`](.github/workflows/ci.yml) — runs `lint`, `env-completeness`, and + `bats` jobs in parallel on every push and PR. +- [`release.yml`](.github/workflows/release.yml) — on `v*` tag, reruns CI then + publishes a GitHub release with notes extracted from `.claude/CHANGELOG.md`. + ## Troubleshooting | Symptom | Fix | @@ -203,6 +319,9 @@ npm update -g openclaw # for the openclaw profile | Out of RAM mid-install | Bump `SWAP_SIZE_GB` in `.env`, re-run | | ClickHouse repo signature error | Delete `/etc/apt/keyrings/clickhouse-keyring.gpg` and re-run | | Cron Dream job logs nothing | `crontab -l \| grep claude-dream` to confirm registered | +| Obsidian auto-sync fails | `tail ~/vault/.claude/sync.log`; verify `OBSIDIAN_VAULT_REPO` push access | +| Plugin install hangs in `claude -p` | Check `~/.claude/logs/` and retry with `--dangerously-skip-permissions` | +| `chromium` package missing | Rely on Playwright's bundled Chromium (set `INSTALL_PLAYWRIGHT=true`) | ## Development @@ -211,7 +330,7 @@ npm update -g openclaw # for the openclaw profile find . -name '*.sh' -exec bash -n {} \; -print # shellcheck (optional) -find . -name '*.sh' -exec shellcheck {} \; +find . -name '*.sh' -exec shellcheck -x -S warning -e SC1090,SC1091 {} \; ``` Conventions baked into every script: @@ -224,12 +343,14 @@ Conventions baked into every script: ## Status & roadmap -| Profile | Install path | Real-VPS verified | -|--------------|---------------------------------------|-------------------| -| cli-bundle | npm global + upstream installers | ✅ (partial) | -| openclaw | `npm i -g openclaw` | ⚠️ pending | -| hermes | upstream `curl \| bash` | ⚠️ pending | -| paperclip | `git clone + pnpm build` | ⚠️ pending | +| Profile | Install path | Real-VPS verified | +|--------------|-----------------------------------------------------|-------------------| +| cli-bundle | npm global + upstream installers (5 CLIs + plugins) | ✅ (partial) | +| openclaw | `npm i -g openclaw` | ⚠️ pending | +| hermes | upstream `curl \| bash` | ⚠️ pending | +| paperclip | `git clone + pnpm build` | ⚠️ pending | + +Releases: [v0.6.1](https://github.com/govtech42/harness/releases/tag/v0.6.1) (latest) — see [`.claude/CHANGELOG.md`](.claude/CHANGELOG.md) for the full reverse-chrono history. Open design decisions awaiting review: [`.claude/RECOMMENDATIONS.md`](.claude/RECOMMENDATIONS.md). Open work items: [`.claude/TODO.md`](.claude/TODO.md).