diff --git a/README.md b/README.md index b9c1a75..e543f11 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,8 @@ env.example template for the optional .env (Telegram/Gemini integrations) This repository is **private**, so the installer needs access to it. The simplest path is to clone it once and run the installer from the clone — your existing git credentials are used, no token to paste. +The installer is **all-in-one**: if OpenCode isn't already installed, it bootstraps the runtime first (from the official installer at [`opencode.ai/v2/install`](https://opencode.ai/v2/install)), then installs the fork. + ### Recommended — clone, then install ```bash @@ -165,6 +167,10 @@ The installer offers **Local** (`.opencode/` in the current project), **Global** | `--install-dir PATH` | install into an exact path | | `--source DIR` | install from a local clone instead of downloading | | `--branch REF` | branch/tag to install from (default `main`) | +| `--with-opencode` | install/update OpenCode even if it is already present | +| `--no-opencode` | skip the OpenCode runtime install | +| `--opencode-version V` | install a specific OpenCode version | +| `--opencode-no-path` | don't let the OpenCode installer edit your shell PATH | | `--yes` / `-y` | non-interactive; skip existing files | | `--force` | non-interactive; overwrite existing files | | `--dry-run` | show what would happen, change nothing | @@ -180,6 +186,12 @@ cp -R /tmp/oac/agent /tmp/oac/command /tmp/oac/context \ /tmp/oac/package.json .opencode/ ``` +This copies the **fork only** — install the OpenCode **runtime** first if it's missing: + +```bash +curl -fsSL https://opencode.ai/v2/install | bash +``` + Then start OpenCode and pick your agent: ```bash diff --git a/install.sh b/install.sh index 818caa8..6cba254 100755 --- a/install.sh +++ b/install.sh @@ -2,8 +2,9 @@ # # OpenAgents Control — Architect Fork · installer # ============================================================================ -# Installs the OAC Architect Fork — the agents, subagents, commands, context, -# skills and tools — into a project's .opencode/ directory or the global +# All-in-one bootstrap: installs OpenCode (the runtime) when it is missing, then +# the OAC Architect Fork — the agents, subagents, commands, context, skills and +# tools — into a project's .opencode/ directory or the global # ~/.config/opencode/ directory. # # Adapted from Darren Hinde's OpenAgents Control installer (MIT). @@ -22,6 +23,7 @@ # ./install.sh --source DIR # install from a local clone # ./install.sh --global --yes # non-interactive, skip existing files # ./install.sh --global --force # non-interactive, overwrite existing +# ./install.sh --no-opencode # install the fork only (skip OpenCode) # ./install.sh --dry-run # show the plan, change nothing # # Environment: @@ -46,6 +48,10 @@ TOKEN="${OAC_TOKEN:-}" PAYLOAD_DIRS="agent command context skills tool" PAYLOAD_FILES="env.example package.json" +# OpenCode runtime — the official installer places the binary in $HOME/.opencode/bin +OPENCODE_INSTALLER_URL="${OPENCODE_INSTALLER_URL:-https://opencode.ai/v2/install}" +OPENCODE_BIN_DIR="${HOME}/.opencode/bin" + # --------------------------------------------------------------------------- # Colours (only when writing to a terminal) # --------------------------------------------------------------------------- @@ -81,7 +87,8 @@ usage() { cat </dev/null 2>&1 || die "curl is required when using --token" fi +# --------------------------------------------------------------------------- +# OpenCode runtime (all-in-one bootstrap) +# --------------------------------------------------------------------------- +have_opencode() { + command -v opencode >/dev/null 2>&1 && return 0 + [ -x "${OPENCODE_BIN_DIR}/opencode" ] && return 0 + return 1 +} + +opencode_path() { + if command -v opencode >/dev/null 2>&1; then + command -v opencode + else + printf '%s' "${OPENCODE_BIN_DIR}/opencode" + fi +} + +ensure_opencode() { + if [ "$DRY_RUN" = 1 ]; then + if have_opencode; then + info "[dry-run] OpenCode already present — $(opencode_path)" + elif [ "$OPENCODE_MODE" = "no" ]; then + info "[dry-run] would skip OpenCode (--no-opencode)" + else + info "[dry-run] would install OpenCode from ${OPENCODE_INSTALLER_URL}" + fi + return 0 + fi + + if have_opencode && [ "$OPENCODE_MODE" != "yes" ]; then + success "OpenCode is already installed — $(opencode_path)" + return 0 + fi + + if [ "$OPENCODE_MODE" = "no" ]; then + info "Skipping the OpenCode install (--no-opencode)" + return 0 + fi + + if [ "$OPENCODE_MODE" = "auto" ] && ! have_opencode && [ -t 0 ] && [ -t 1 ]; then + printf "${BOLD}OpenCode is not installed. Install it now?${NC} [Y/n]: " + ans="" + read -r ans || true + case "$ans" in + [Nn]*) info "Skipping OpenCode."; return 0 ;; + esac + fi + + command -v curl >/dev/null 2>&1 || die "curl is required to install OpenCode" + + step "Installing OpenCode…" + local tmp + tmp="$(mktemp 2>/dev/null || mktemp -t oac)" + if ! curl -fsSL "$OPENCODE_INSTALLER_URL" -o "$tmp"; then + rm -f "$tmp" + die "Could not download the OpenCode installer (${OPENCODE_INSTALLER_URL})" + fi + + local ok=0 + if [ -n "$OPENCODE_VERSION" ] && [ "$OPENCODE_NO_PATH" = 1 ]; then + bash "$tmp" --no-modify-path --version "$OPENCODE_VERSION" && ok=1 + elif [ -n "$OPENCODE_VERSION" ]; then + bash "$tmp" --version "$OPENCODE_VERSION" && ok=1 + elif [ "$OPENCODE_NO_PATH" = 1 ]; then + bash "$tmp" --no-modify-path && ok=1 + else + bash "$tmp" && ok=1 + fi + rm -f "$tmp" + [ "$ok" = 1 ] || die "OpenCode installation failed" + + if have_opencode; then + success "OpenCode installed — $(opencode_path)" + case ":$PATH:" in + *":${OPENCODE_BIN_DIR}:"*) : ;; + *) warn "Add OpenCode to your PATH: export PATH=\"${OPENCODE_BIN_DIR}:\$PATH\"" ;; + esac + else + warn "The OpenCode installer finished, but 'opencode' is not on PATH yet. Re-open your shell and try again." + fi +} + # --------------------------------------------------------------------------- # Resolve the source payload # --------------------------------------------------------------------------- @@ -377,8 +480,13 @@ show_post_install() { if [ -f "$INSTALL_DIR/env.example" ]; then echo "2. (Optional) configure integrations: ${CYAN}cp ${INSTALL_DIR}/env.example .env${NC}" fi - echo "3. Start OpenCode and pick an agent:" - echo -e " ${CYAN}opencode${NC} → choose ${BOLD}OpenArchitect${NC} to spec/verify, ${BOLD}OpenAgent${NC} to build" + if have_opencode; then + echo "3. Start OpenCode and pick an agent:" + echo -e " ${CYAN}opencode${NC} → choose ${BOLD}OpenArchitect${NC} to spec/verify, ${BOLD}OpenAgent${NC} to build" + else + echo "3. Install OpenCode, then pick an agent:" + echo -e " ${CYAN}curl -fsSL ${OPENCODE_INSTALLER_URL} | bash${NC}" + fi echo info "Docs: ${REPO_URL}" } @@ -388,6 +496,7 @@ show_post_install() { # --------------------------------------------------------------------------- main() { print_header + ensure_opencode resolve_source resolve_install_dir