|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Inkbox for opencode — one-line installer. |
| 3 | +# |
| 4 | +# curl -fsSL https://raw.githubusercontent.com/inkbox-ai/opencode-plugin/main/install.sh | bash |
| 5 | +# |
| 6 | +# Clones (or updates) the plugin into ~/.inkbox-opencode/app, builds it, |
| 7 | +# installs it into your global opencode config (~/.config/opencode) with a |
| 8 | +# plugin wrapper, and puts an `inkbox-opencode` launcher on your PATH. |
| 9 | +# From a local checkout, run ./install.sh — it uses the checkout in place. |
| 10 | +# Re-running is safe: it updates the clone and reinstalls. |
| 11 | +set -euo pipefail |
| 12 | + |
| 13 | +REPO_SLUG="${INKBOX_OPENCODE_REPO:-inkbox-ai/opencode-plugin}" |
| 14 | +REPO_BRANCH="${INKBOX_OPENCODE_BRANCH:-main}" |
| 15 | +APP_DIR="${INKBOX_OPENCODE_APP_DIR:-$HOME/.inkbox-opencode/app}" |
| 16 | +BIN_DIR="${INKBOX_OPENCODE_BIN_DIR:-$HOME/.local/bin}" |
| 17 | +OPENCODE_CONFIG_DIR="${INKBOX_OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}" |
| 18 | + |
| 19 | +say() { printf '\033[1;36m==>\033[0m %s\n' "$*"; } |
| 20 | +warn() { printf '\033[1;33mwarning:\033[0m %s\n' "$*"; } |
| 21 | +die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; } |
| 22 | + |
| 23 | +# --- 1. prerequisites ------------------------------------------------------- |
| 24 | +command -v git >/dev/null 2>&1 || die "git is required." |
| 25 | +command -v npm >/dev/null 2>&1 || die "npm is required (comes with Node)." |
| 26 | +command -v node >/dev/null 2>&1 || die "Node.js 20+ is required." |
| 27 | +node -e 'process.exit(Number(process.versions.node.split(".")[0]) >= 20 ? 0 : 1)' || |
| 28 | + die "Node.js 20+ is required (found $(node --version))." |
| 29 | +command -v opencode >/dev/null 2>&1 || |
| 30 | + warn "the opencode CLI is not on PATH — install it (npm install -g opencode-ai); the gateway launches \`opencode serve\` and the plugin loads into opencode sessions." |
| 31 | + |
| 32 | +# --- 2. source: local checkout, or clone/update the app dir ----------------- |
| 33 | +SOURCE_DIR="" |
| 34 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" 2>/dev/null && pwd || true)" |
| 35 | +if [ -n "$SCRIPT_DIR" ] && [ -f "$SCRIPT_DIR/package.json" ] && |
| 36 | + grep -q '"name": "@inkbox/opencode-plugin"' "$SCRIPT_DIR/package.json" 2>/dev/null; then |
| 37 | + SOURCE_DIR="$SCRIPT_DIR" # running from inside a checkout (not curl | bash) |
| 38 | + say "Using the local checkout at $SOURCE_DIR" |
| 39 | +else |
| 40 | + if [ -d "$APP_DIR/.git" ]; then |
| 41 | + say "Updating $APP_DIR" |
| 42 | + git -C "$APP_DIR" fetch --quiet origin "$REPO_BRANCH" |
| 43 | + git -C "$APP_DIR" checkout --quiet "$REPO_BRANCH" |
| 44 | + git -C "$APP_DIR" reset --quiet --hard "origin/$REPO_BRANCH" |
| 45 | + else |
| 46 | + say "Cloning https://github.com/$REPO_SLUG into $APP_DIR" |
| 47 | + mkdir -p "$(dirname "$APP_DIR")" |
| 48 | + git clone --quiet --branch "$REPO_BRANCH" "https://github.com/$REPO_SLUG.git" "$APP_DIR" |
| 49 | + fi |
| 50 | + SOURCE_DIR="$APP_DIR" |
| 51 | +fi |
| 52 | + |
| 53 | +# --- 3. build + pack --------------------------------------------------------- |
| 54 | +say "Installing dependencies and building" |
| 55 | +(cd "$SOURCE_DIR" && npm install --silent --no-audit --no-fund && npm run -s build) |
| 56 | +TARBALL="$SOURCE_DIR/$(cd "$SOURCE_DIR" && npm pack --silent | tail -1)" |
| 57 | +[ -f "$TARBALL" ] || die "npm pack did not produce a tarball." |
| 58 | + |
| 59 | +# --- 4. wire the plugin into the global opencode config ---------------------- |
| 60 | +say "Installing the plugin into $OPENCODE_CONFIG_DIR" |
| 61 | +mkdir -p "$OPENCODE_CONFIG_DIR/plugins" |
| 62 | +(cd "$OPENCODE_CONFIG_DIR" && |
| 63 | + { [ -f package.json ] || npm init -y >/dev/null 2>&1; } && |
| 64 | + npm install --silent --no-audit --no-fund --save "$TARBALL") |
| 65 | + |
| 66 | +WRAPPER="$OPENCODE_CONFIG_DIR/plugins/inkbox.ts" |
| 67 | +if [ -f "$WRAPPER" ]; then |
| 68 | + say "Keeping your existing plugin wrapper at $WRAPPER" |
| 69 | +else |
| 70 | + cat > "$WRAPPER" <<'EOF' |
| 71 | +// Inkbox plugin wrapper — written by install.sh; edit freely (never overwritten). |
| 72 | +// Credentials resolve from env vars or ~/.inkbox/config; options: see README. |
| 73 | +import InkboxPlugin from "@inkbox/opencode-plugin"; |
| 74 | +
|
| 75 | +export default async (input: any) => InkboxPlugin(input, {}); |
| 76 | +EOF |
| 77 | + say "Wrote plugin wrapper $WRAPPER" |
| 78 | +fi |
| 79 | + |
| 80 | +# --- 5. launcher on PATH ------------------------------------------------------ |
| 81 | +mkdir -p "$BIN_DIR" |
| 82 | +chmod +x "$SOURCE_DIR/bin/inkbox-opencode.js" |
| 83 | +ln -sf "$SOURCE_DIR/bin/inkbox-opencode.js" "$BIN_DIR/inkbox-opencode" |
| 84 | +say "Launcher: $BIN_DIR/inkbox-opencode" |
| 85 | +case ":$PATH:" in |
| 86 | + *":$BIN_DIR:"*) ;; |
| 87 | + *) warn "$BIN_DIR is not on your PATH — add: export PATH=\"$BIN_DIR:\$PATH\"" ;; |
| 88 | +esac |
| 89 | + |
| 90 | +# --- 6. next steps ------------------------------------------------------------ |
| 91 | +cat <<EOF |
| 92 | +
|
| 93 | +Installed. Next: |
| 94 | +
|
| 95 | + 1. Credentials (or use ~/.inkbox/config): |
| 96 | + export INKBOX_API_KEY=... INKBOX_IDENTITY=... INKBOX_SIGNING_KEY=... |
| 97 | + 2. Check the wiring: |
| 98 | + inkbox-opencode doctor |
| 99 | + 3. Restart opencode — the Inkbox tools load in every session. |
| 100 | + 4. Optional always-on inbound gateway (replies to email/SMS/calls): |
| 101 | + inkbox-opencode autostart install # boot service; 'status' / 'uninstall' to manage |
| 102 | +
|
| 103 | +Docs: https://github.com/$REPO_SLUG#readme |
| 104 | +EOF |
0 commit comments