#!/usr/bin/env bash set -euo pipefail OPENCODE_DIR="${HOME}/.config/opencode" CI_DIR="$(cd "$(dirname "$0")/.." && pwd)/opencode" UNINSTALL=false FORCE=false for arg in "$@"; do case "$arg" in --uninstall) UNINSTALL=true ;; --force) FORCE=true ;; --help|-h) echo "Usage: $(basename "$0") [--uninstall] [--force]" echo "" echo "Install CI opencode integration files to ~/.config/opencode/" echo "" echo " --uninstall Remove CI integration files" echo " --force Overwrite existing files without prompting" echo " --help Show this help" exit 0 ;; esac done if [ "$UNINSTALL" = true ]; then echo "Uninstalling CI opencode integration..." rm -f "${OPENCODE_DIR}/agents/ci-"*.md 2>/dev/null || true rm -f "${OPENCODE_DIR}/command/ci-"*.md 2>/dev/null || true rm -rf "${OPENCODE_DIR}/ci/" 2>/dev/null || true echo "CI integration files removed." echo "Note: opencode.json permissions entry preserved (edit manually if needed)." exit 0 fi if [ ! -d "$CI_DIR" ]; then echo "Error: opencode/ directory not found at ${CI_DIR}" echo "Ensure you're running from the CI repository root." exit 1 fi echo "Installing CI opencode integration..." echo " Source: ${CI_DIR}" echo " Target: ${OPENCODE_DIR}" echo "" mkdir -p "${OPENCODE_DIR}/agents" mkdir -p "${OPENCODE_DIR}/command" mkdir -p "${OPENCODE_DIR}/ci/contexts" mkdir -p "${OPENCODE_DIR}/ci/references" mkdir -p "${OPENCODE_DIR}/ci/workflows" COPIED=0 SKIPPED=0 copy_file() { local src="$1" local dest="$2" if [ -f "$dest" ] && [ "$FORCE" = false ]; then if cmp -s "$src" "$dest" 2>/dev/null; then SKIPPED=$((SKIPPED + 1)) return fi echo " Conflict: $(basename "$src") already exists. Use --force to overwrite." SKIPPED=$((SKIPPED + 1)) return fi cp "$src" "$dest" COPIED=$((COPIED + 1)) } echo "Installing agents..." for f in "${CI_DIR}/agents/ci-"*.md; do [ -f "$f" ] && copy_file "$f" "${OPENCODE_DIR}/agents/$(basename "$f")" done echo "Installing commands..." for f in "${CI_DIR}/command/ci-"*.md; do [ -f "$f" ] && copy_file "$f" "${OPENCODE_DIR}/command/$(basename "$f")" done echo "Installing contexts..." for f in "${CI_DIR}/ci/contexts/"*.md; do [ -f "$f" ] && copy_file "$f" "${OPENCODE_DIR}/ci/contexts/$(basename "$f")" done echo "Installing references..." for f in "${CI_DIR}/ci/references/"*.md; do [ -f "$f" ] && copy_file "$f" "${OPENCODE_DIR}/ci/references/$(basename "$f")" done echo "Installing workflows..." for f in "${CI_DIR}/ci/workflows/"*.md; do [ -f "$f" ] && copy_file "$f" "${OPENCODE_DIR}/ci/workflows/$(basename "$f")" done echo "Installing VERSION..." [ -f "${CI_DIR}/ci/VERSION" ] && copy_file "${CI_DIR}/ci/VERSION" "${OPENCODE_DIR}/ci/VERSION" echo "" echo "Merging opencode.json permissions..." OPENCODE_JSON="${OPENCODE_DIR}/opencode.json" CI_JSON="${CI_DIR}/opencode.json" if [ -f "$CI_JSON" ]; then if [ ! -f "$OPENCODE_JSON" ]; then cp "$CI_JSON" "$OPENCODE_JSON" echo " Created opencode.json" else if command -v node &>/dev/null; then node -e " const fs = require('fs'); const existing = JSON.parse(fs.readFileSync('${OPENCODE_JSON}', 'utf8')); const ci = JSON.parse(fs.readFileSync('${CI_JSON}', 'utf8')); const merged = { ...existing }; merged.permission = merged.permission || {}; merged.permission.read = merged.permission.read || {}; merged.permission.external_directory = merged.permission.external_directory || {}; for (const [k, v] of Object.entries(ci.permission?.read || {})) { if (!merged.permission.read[k]) merged.permission.read[k] = v; } for (const [k, v] of Object.entries(ci.permission?.external_directory || {})) { if (!merged.permission.external_directory[k]) merged.permission.external_directory[k] = v; } fs.writeFileSync('${OPENCODE_JSON}', JSON.stringify(merged, null, 2)); console.log(' Merged permissions (preserved existing entries)'); " else echo " Warning: node not found. Manually merge opencode.json permissions." echo " Add to opencode.json:" echo ' "~/.config/opencode/ci/*": "allow" (in permission.read and permission.external_directory)' fi fi fi echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo " CI ► INSTALL COMPLETE" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" echo " Copied: ${COPIED} files" echo " Skipped: ${SKIPPED} files" echo "" echo " Commands available: ci-init, ci-run, ci-quick, ci-status," echo " ci-audit, ci-verify, ci-debug, ci-review, ci-ship," echo " ci-rollback, ci-clarify" echo "" echo " Run --uninstall to remove." echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"