{"repo": "ccsert/opencode-review-gitea", "files": {"docker-compose.yaml": {"7451ddeb0afbfe9c168b0a2157b4cb9334c7efca": {"t": 1785745198.7066634, "n": 1504, "h": "41225f843054f569", "c": "# Docker Compose for local testing\n# Usage: docker compose run --rm review\n#\n# Before running, set environment variables:\n# export GITEA_TOKEN=your_token\n# export DEEPSEEK_API_KEY=your_api_key\n\nservices:\n review:\n build: .\n image: ghcr.io/ccsert/opencode-review:latest\n volumes:\n # Mount current directory as workspace\n - .:/workspace:ro\n # Optional: Mount custom config to override built-in\n # - ./.opencode-review:/app/.opencode-review:ro\n environment:\n # Required\n - GITEA_TOKEN=${GITEA_TOKEN}\n - GITEA_SERVER_URL=${GITEA_SERVER_URL:-https://gitea.com}\n \n # LLM API Keys (at least one required)\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-}\n - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}\n - OPENAI_API_KEY=${OPENAI_API_KEY:-}\n \n # Configuration\n - MODEL=${MODEL:-deepseek/deepseek-chat}\n - REVIEW_LANGUAGE=${REVIEW_LANGUAGE:-auto}\n - REVIEW_STYLE=${REVIEW_STYLE:-balanced}\n \n # PR Context (for testing)\n - PR_NUMBER=${PR_NUMBER:-1}\n - REPO_OWNER=${REPO_OWNER:-owner}\n - REPO_NAME=${REPO_NAME:-repo}\n working_dir: /workspace\n \n # Development mode with shell access\n dev:\n build: .\n volumes:\n - .:/workspace\n - ./.opencode-review:/app/.opencode-review\n environment:\n - GITEA_TOKEN=${GITEA_TOKEN}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-}\n - MODEL=${MODEL:-deepseek/deepseek-chat}\n entrypoint: /bin/bash\n stdin_open: true\n tty: true\n"}, "54baa5afdbaaca1626381effb5a85e045856f5c7": {"t": 1785748550.932019, "n": 1504, "h": "41225f843054f569", "c": "# Docker Compose for local testing\n# Usage: docker compose run --rm review\n#\n# Before running, set environment variables:\n# export GITEA_TOKEN=your_token\n# export DEEPSEEK_API_KEY=your_api_key\n\nservices:\n review:\n build: .\n image: ghcr.io/ccsert/opencode-review:latest\n volumes:\n # Mount current directory as workspace\n - .:/workspace:ro\n # Optional: Mount custom config to override built-in\n # - ./.opencode-review:/app/.opencode-review:ro\n environment:\n # Required\n - GITEA_TOKEN=${GITEA_TOKEN}\n - GITEA_SERVER_URL=${GITEA_SERVER_URL:-https://gitea.com}\n \n # LLM API Keys (at least one required)\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-}\n - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}\n - OPENAI_API_KEY=${OPENAI_API_KEY:-}\n \n # Configuration\n - MODEL=${MODEL:-deepseek/deepseek-chat}\n - REVIEW_LANGUAGE=${REVIEW_LANGUAGE:-auto}\n - REVIEW_STYLE=${REVIEW_STYLE:-balanced}\n \n # PR Context (for testing)\n - PR_NUMBER=${PR_NUMBER:-1}\n - REPO_OWNER=${REPO_OWNER:-owner}\n - REPO_NAME=${REPO_NAME:-repo}\n working_dir: /workspace\n \n # Development mode with shell access\n dev:\n build: .\n volumes:\n - .:/workspace\n - ./.opencode-review:/app/.opencode-review\n environment:\n - GITEA_TOKEN=${GITEA_TOKEN}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-}\n - MODEL=${MODEL:-deepseek/deepseek-chat}\n entrypoint: /bin/bash\n stdin_open: true\n tty: true\n"}, "e1a9786059c2ae7efe88d99f283279091bf3dc39": {"t": 1785748552.020564, "n": 1548, "h": "7aff91c8e1d34fe5", "c": "# Docker Compose for local testing\n# Usage: docker compose run --rm review\n#\n# Before running, set environment variables:\n# export GITEA_TOKEN=your_token\n# export DEEPSEEK_API_KEY=your_api_key\n\nservices:\n review:\n build: .\n image: ghcr.io/ccsert/opencode-review:latest\n volumes:\n # Mount current directory as workspace\n - .:/workspace:ro\n # Optional: Mount custom config to override built-in\n # - ./.opencode-review:/app/.opencode-review:ro\n environment:\n # Required\n - GITEA_TOKEN=${GITEA_TOKEN}\n - GITEA_SERVER_URL=${GITEA_SERVER_URL:-https://gitea.com}\n \n # LLM API Keys (at least one required)\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-}\n - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}\n - OPENAI_API_KEY=${OPENAI_API_KEY:-}\n \n # Configuration\n - MODEL=${MODEL:-deepseek/deepseek-chat}\n - REVIEW_LANGUAGE=${REVIEW_LANGUAGE:-auto}\n - REVIEW_STYLE=${REVIEW_STYLE:-balanced}\n - AUTO_APPROVE=${AUTO_APPROVE:-false}\n \n # PR Context (for testing)\n - PR_NUMBER=${PR_NUMBER:-1}\n - REPO_OWNER=${REPO_OWNER:-owner}\n - REPO_NAME=${REPO_NAME:-repo}\n working_dir: /workspace\n \n # Development mode with shell access\n dev:\n build: .\n volumes:\n - .:/workspace\n - ./.opencode-review:/app/.opencode-review\n environment:\n - GITEA_TOKEN=${GITEA_TOKEN}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-}\n - MODEL=${MODEL:-deepseek/deepseek-chat}\n entrypoint: /bin/bash\n stdin_open: true\n tty: true\n"}}, "templates/workflow-source.yaml": {"7451ddeb0afbfe9c168b0a2157b4cb9334c7efca": {"t": 1785745203.042128, "n": 3620, "h": "34131c06f46aa020", "c": "# OpenCode Review - Source Installation Workflow Template\n# \n# This workflow uses the source-based installation method.\n# Files required in your repository:\n# - .opencode-review/ (agents, tools, skills)\n# - .gitea/workflows/opencode-review.yaml (this file)\n#\n# Installation:\n# curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash -s -- --source\n\nname: OpenCode Review\n\non:\n issue_comment:\n types: [created]\n pull_request_review_comment:\n types: [created]\n pull_request:\n types: [opened, synchronize]\n\njobs:\n opencode-review:\n # Trigger on /oc or /opencode command, or on new/updated PR\n if: |\n github.event_name == 'pull_request' ||\n contains(github.event.comment.body, '/oc') ||\n contains(github.event.comment.body, '/opencode')\n runs-on: ubuntu-latest\n container: catthehacker/ubuntu:act-latest\n \n steps:\n - name: Checkout repository\n uses: actions/checkout@v4\n with:\n persist-credentials: false\n\n - name: Install Bun\n run: |\n curl -fsSL https://bun.sh/install | bash\n echo \"$HOME/.bun/bin\" >> $GITHUB_PATH\n\n - name: Install dependencies\n working-directory: .opencode-review\n run: ~/.bun/bin/bun install\n\n - name: Install OpenCode CLI\n run: ~/.bun/bin/bun add -g opencode-ai\n\n - name: Run code review\n env:\n # OpenCode configuration\n OPENCODE_CONFIG_DIR: ${{ github.workspace }}/.opencode-review\n \n # Model configuration (provider/model-id format)\n # Examples: deepseek/deepseek-chat, anthropic/claude-sonnet-4-5, openai/gpt-4o\n MODEL: deepseek/deepseek-chat\n \n # Gitea/Forgejo configuration\n GITEA_TOKEN: ${{ secrets.OPENCODE_GIT_TOKEN }}\n GITEA_SERVER_URL: ${{ gitea.server_url }}\n \n # Review configuration\n REVIEW_LANGUAGE: auto # auto | en | zh-CN\n # REVIEW_STYLE: balanced # concise | balanced | thorough | security\n # FILE_PATTERNS: \"\" # Glob patterns to filter files (e.g., \"*.ts,*.go,src/**\")\n \n # LLM API Keys (configure the one matching your MODEL)\n DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}\n ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}\n OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}\n \n # LLM Gateway (optional, for LiteLLM, OpenRouter, Together AI, etc.)\n # OPENAI_BASE_URL: \"\" # e.g., http://localhost:4000/v1\n \n # PR context\n PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }}\n REPO_OWNER: ${{ github.repository_owner }}\n REPO_NAME: ${{ github.event.repository.name }}\n \n # Logging\n OPENCODE_LOG_LEVEL: info\n run: |\n # Build language instruction\n LANG_INSTRUCTION=\"\"\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh) LANG_INSTRUCTION=\"请使用中文回复。\" ;;\n en) LANG_INSTRUCTION=\"Reply in English.\" ;;\n esac\n \n # Build file filter instruction\n FILE_INSTRUCTION=\"\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n FILE_INSTRUCTION=\"Only review files matching: $FILE_PATTERNS.\"\n fi\n \n opencode run --agent code-review \\\n \"Review PR #${PR_NUMBER} in ${REPO_OWNER}/${REPO_NAME}. \\\n Analyze code changes, identify issues, and submit review with inline comments. \\\n ${LANG_INSTRUCTION} ${FILE_INSTRUCTION}\"\n"}, "fe0b60167424520e4dc1fff4cb5f45a6e7c79638": {"t": 1785748551.1064763, "n": 3620, "h": "34131c06f46aa020", "c": "# OpenCode Review - Source Installation Workflow Template\n# \n# This workflow uses the source-based installation method.\n# Files required in your repository:\n# - .opencode-review/ (agents, tools, skills)\n# - .gitea/workflows/opencode-review.yaml (this file)\n#\n# Installation:\n# curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash -s -- --source\n\nname: OpenCode Review\n\non:\n issue_comment:\n types: [created]\n pull_request_review_comment:\n types: [created]\n pull_request:\n types: [opened, synchronize]\n\njobs:\n opencode-review:\n # Trigger on /oc or /opencode command, or on new/updated PR\n if: |\n github.event_name == 'pull_request' ||\n contains(github.event.comment.body, '/oc') ||\n contains(github.event.comment.body, '/opencode')\n runs-on: ubuntu-latest\n container: catthehacker/ubuntu:act-latest\n \n steps:\n - name: Checkout repository\n uses: actions/checkout@v4\n with:\n persist-credentials: false\n\n - name: Install Bun\n run: |\n curl -fsSL https://bun.sh/install | bash\n echo \"$HOME/.bun/bin\" >> $GITHUB_PATH\n\n - name: Install dependencies\n working-directory: .opencode-review\n run: ~/.bun/bin/bun install\n\n - name: Install OpenCode CLI\n run: ~/.bun/bin/bun add -g opencode-ai\n\n - name: Run code review\n env:\n # OpenCode configuration\n OPENCODE_CONFIG_DIR: ${{ github.workspace }}/.opencode-review\n \n # Model configuration (provider/model-id format)\n # Examples: deepseek/deepseek-chat, anthropic/claude-sonnet-4-5, openai/gpt-4o\n MODEL: deepseek/deepseek-chat\n \n # Gitea/Forgejo configuration\n GITEA_TOKEN: ${{ secrets.OPENCODE_GIT_TOKEN }}\n GITEA_SERVER_URL: ${{ gitea.server_url }}\n \n # Review configuration\n REVIEW_LANGUAGE: auto # auto | en | zh-CN\n # REVIEW_STYLE: balanced # concise | balanced | thorough | security\n # FILE_PATTERNS: \"\" # Glob patterns to filter files (e.g., \"*.ts,*.go,src/**\")\n \n # LLM API Keys (configure the one matching your MODEL)\n DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}\n ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}\n OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}\n \n # LLM Gateway (optional, for LiteLLM, OpenRouter, Together AI, etc.)\n # OPENAI_BASE_URL: \"\" # e.g., http://localhost:4000/v1\n \n # PR context\n PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }}\n REPO_OWNER: ${{ github.repository_owner }}\n REPO_NAME: ${{ github.event.repository.name }}\n \n # Logging\n OPENCODE_LOG_LEVEL: info\n run: |\n # Build language instruction\n LANG_INSTRUCTION=\"\"\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh) LANG_INSTRUCTION=\"请使用中文回复。\" ;;\n en) LANG_INSTRUCTION=\"Reply in English.\" ;;\n esac\n \n # Build file filter instruction\n FILE_INSTRUCTION=\"\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n FILE_INSTRUCTION=\"Only review files matching: $FILE_PATTERNS.\"\n fi\n \n opencode run --agent code-review \\\n \"Review PR #${PR_NUMBER} in ${REPO_OWNER}/${REPO_NAME}. \\\n Analyze code changes, identify issues, and submit review with inline comments. \\\n ${LANG_INSTRUCTION} ${FILE_INSTRUCTION}\"\n"}, "37ad4f81cd7aeb2d9401c2f3bbbab1fbc6d26057": {"t": 1785748552.7228134, "n": 3456, "h": "b48f561ff3cecfae", "c": "# OpenCode Review - Source Installation Workflow Template\n# \n# This workflow uses the source-based installation method.\n# Files required in your repository:\n# - .opencode-review/ (agents, tools, skills)\n# - .gitea/workflows/opencode-review.yaml (this file)\n#\n# Installation:\n# curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash -s -- --source\n\nname: OpenCode Review\n\non:\n issue_comment:\n types: [created]\n pull_request_review_comment:\n types: [created]\n pull_request:\n types: [opened, synchronize]\n\njobs:\n opencode-review:\n # Trigger on /oc or /opencode command, or on new/updated PR\n if: |\n github.event_name == 'pull_request' ||\n contains(github.event.comment.body, '/oc') ||\n contains(github.event.comment.body, '/opencode')\n runs-on: ubuntu-latest\n container: catthehacker/ubuntu:act-latest\n \n steps:\n - name: Checkout repository\n uses: actions/checkout@v4\n with:\n persist-credentials: false\n\n - name: Install Bun\n run: |\n curl -fsSL https://bun.sh/install | bash\n echo \"$HOME/.bun/bin\" >> $GITHUB_PATH\n\n - name: Install dependencies\n working-directory: .opencode-review\n run: ~/.bun/bin/bun install\n\n - name: Install OpenCode CLI\n run: ~/.bun/bin/bun add -g opencode-ai\n\n - name: Run code review\n env:\n # OpenCode configuration\n OPENCODE_CONFIG_DIR: ${{ github.workspace }}/.opencode-review\n \n # Model configuration (provider/model-id format)\n # Examples: deepseek/deepseek-chat, anthropic/claude-sonnet-4-5, openai/gpt-4o\n MODEL: deepseek/deepseek-chat\n \n # Gitea/Forgejo configuration\n GITEA_TOKEN: ${{ secrets.OPENCODE_GIT_TOKEN }}\n GITEA_SERVER_URL: ${{ gitea.server_url }}\n \n # Review configuration\n REVIEW_LANGUAGE: auto # auto | en | zh-CN\n # REVIEW_STYLE: balanced # concise | balanced | thorough | security\n # FILE_PATTERNS: \"\" # Glob patterns to filter files (e.g., \"*.ts,*.go,src/**\")\n \n # LLM API Keys (configure the one matching your MODEL)\n DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}\n ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}\n OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}\n \n # PR context\n PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }}\n REPO_OWNER: ${{ github.repository_owner }}\n REPO_NAME: ${{ github.event.repository.name }}\n \n # Logging\n OPENCODE_LOG_LEVEL: info\n run: |\n # Build language instruction\n LANG_INSTRUCTION=\"\"\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh) LANG_INSTRUCTION=\"请使用中文回复。\" ;;\n en) LANG_INSTRUCTION=\"Reply in English.\" ;;\n esac\n \n # Build file filter instruction\n FILE_INSTRUCTION=\"\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n FILE_INSTRUCTION=\"Only review files matching: $FILE_PATTERNS.\"\n fi\n \n opencode run --agent code-review \\\n \"Review PR #${PR_NUMBER} in ${REPO_OWNER}/${REPO_NAME}. \\\n Analyze code changes, identify issues, and submit review with inline comments. \\\n ${LANG_INSTRUCTION} ${FILE_INSTRUCTION}\"\n"}, "e1a9786059c2ae7efe88d99f283279091bf3dc39": {"t": 1785748553.8194814, "n": 2699, "h": "e7bc7d666ba7e442", "c": "# OpenCode Review - Source Installation Workflow Template\n# \n# This workflow uses the source-based installation method.\n# Files required in your repository:\n# - .opencode-review/ (agents, tools, skills)\n# - .gitea/workflows/opencode-review.yaml (this file)\n#\n# Installation:\n# curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash -s -- --source\n\nname: OpenCode Review\n\non:\n issue_comment:\n types: [created]\n pull_request_review_comment:\n types: [created]\n pull_request:\n types: [opened, synchronize]\n\njobs:\n opencode-review:\n # Trigger on /oc or /opencode command, or on new/updated PR\n if: |\n github.event_name == 'pull_request' ||\n contains(github.event.comment.body, '/oc') ||\n contains(github.event.comment.body, '/opencode')\n runs-on: ubuntu-latest\n container: catthehacker/ubuntu:act-latest\n \n steps:\n - name: Checkout repository\n uses: actions/checkout@v4\n with:\n persist-credentials: false\n\n - name: Install Bun\n run: |\n curl -fsSL https://bun.sh/install | bash\n echo \"$HOME/.bun/bin\" >> $GITHUB_PATH\n\n - name: Install dependencies\n working-directory: .opencode-review\n run: ~/.bun/bin/bun install\n\n - name: Install OpenCode CLI\n run: ~/.bun/bin/bun add -g opencode-ai\n\n - name: Run code review\n env:\n # OpenCode configuration\n OPENCODE_CONFIG_DIR: ${{ github.workspace }}/.opencode-review\n \n # Model configuration (provider/model-id format)\n # Examples: deepseek/deepseek-chat, anthropic/claude-sonnet-4-5, openai/gpt-4o\n MODEL: deepseek/deepseek-chat\n \n # Gitea/Forgejo configuration\n GITEA_TOKEN: ${{ secrets.OPENCODE_GIT_TOKEN }}\n GITEA_SERVER_URL: ${{ gitea.server_url }}\n \n # LLM API Keys (configure the one matching your MODEL)\n DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}\n ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}\n OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}\n \n # PR context\n PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }}\n REPO_OWNER: ${{ github.repository_owner }}\n REPO_NAME: ${{ github.event.repository.name }}\n \n # Logging\n OPENCODE_LOG_LEVEL: info\n run: |\n opencode run --agent code-review \\\n \"Please review PR #${PR_NUMBER} in ${REPO_OWNER}/${REPO_NAME}. \\\n Analyze the code changes, identify issues, suggest improvements, \\\n and submit a review with inline comments.\"\n"}}, "entrypoint.sh": {"7451ddeb0afbfe9c168b0a2157b4cb9334c7efca": {"t": 1785745938.1786647, "n": 10330, "h": "428b235887be8145", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n # Use subshell to avoid directory stack issues\n (\n cd /workspace/.opencode-review || exit 1\n bun install 2>/dev/null || echo \"[WARN] Failed to install custom dependencies\"\n )\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for server URL\n if [ -z \"$GITEA_SERVER_URL\" ] && [ -z \"$GITHUB_SERVER_URL\" ]; then\n missing+=(\"GITEA_SERVER_URL or GITHUB_SERVER_URL\")\n fi\n\n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n\n # Warn if no LLM API key is set (not fatal - some providers don't need one)\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && \\\n [ -z \"$OPENAI_API_KEY\" ] && [ -z \"$LLM_API_KEY\" ] && \\\n [ -z \"$OPENROUTER_API_KEY\" ] && [ -z \"$OPENAI_BASE_URL\" ]; then\n log_warn \"No LLM API key detected (DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, LLM_API_KEY, OPENROUTER_API_KEY)\"\n log_warn \"If you are using a local model or custom gateway, you can ignore this warning\"\n log_warn \"Set OPENAI_BASE_URL to use an OpenAI-compatible gateway (LiteLLM, OpenRouter, etc.)\"\n fi\n \n log_success \"Environment validated\"\n log_warn \"Note: GITEA_TOKEN must have 'write:repository' scope to submit reviews\"\n}\n\ninfer_gitea_server_url() {\n # Normalize: remove trailing slashes and /api/v1 suffix\n if [ -n \"$GITEA_SERVER_URL\" ]; then\n export GITEA_SERVER_URL=\"${GITEA_SERVER_URL%/}\"\n export GITEA_SERVER_URL=\"${GITEA_SERVER_URL%/api/v1}\"\n return 0\n fi\n\n if [ -n \"$GITHUB_SERVER_URL\" ]; then\n export GITEA_SERVER_URL=\"${GITHUB_SERVER_URL%/}\"\n export GITEA_SERVER_URL=\"${GITEA_SERVER_URL%/api/v1}\"\n return 0\n fi\n\n # Best-effort inference from git remote when running locally with -v $(pwd):/workspace\n if [ -d \"/workspace/.git\" ]; then\n local remote\n remote=$(git -C /workspace remote get-url origin 2>/dev/null || true)\n\n if [[ \"$remote\" =~ ^https?:// ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^(https?://[^/]+).*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n\n # SSH-style: git@host:owner/repo.git -> assume https://host\n if [[ \"$remote\" =~ ^git@[^:]+: ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^git@([^:]+):.*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"https://$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n fi\n}\n\nnormalize_repo_context() {\n # Accept REPO_NAME as either \"repo\" or \"owner/repo\".\n if [ -n \"$REPO_NAME\" ] && [[ \"$REPO_NAME\" == */* ]]; then\n local owner_part=\"${REPO_NAME%%/*}\"\n local repo_part=\"${REPO_NAME#*/}\"\n\n if [ -z \"$REPO_OWNER\" ]; then\n export REPO_OWNER=\"$owner_part\"\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n\n if [ \"$owner_part\" = \"$REPO_OWNER\" ]; then\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n fi\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n prompt=\"$prompt.\"\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt Focus only on critical issues, be concise.\"\n ;;\n thorough)\n prompt=\"$prompt Provide thorough analysis including best practices and improvements.\"\n ;;\n security)\n prompt=\"$prompt Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt Provide balanced feedback on bugs, security, and code quality.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt 请使用简体中文回复。\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n # Add file filter instructions\n if [ -n \"$FILE_PATTERNS\" ]; then\n prompt=\"$prompt Only review files matching: $FILE_PATTERNS.\"\n fi\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Server: ${GITEA_SERVER_URL:-${GITHUB_SERVER_URL:-}}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n echo \" Filter: $FILE_PATTERNS\"\n fi\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n if [ -n \"$REPO_OWNER\" ] && [ -n \"$REPO_NAME\" ]; then\n echo \" Repo: $REPO_OWNER/$REPO_NAME\"\n fi\n}\n\ncheck_architecture() {\n local arch\n arch=$(uname -m)\n if [ \"$arch\" != \"x86_64\" ] && [ \"$arch\" != \"amd64\" ]; then\n log_warn \"Detected architecture: $arch (opencode-ai binary may not be supported)\"\n log_warn \"If you encounter errors, please use the source installation method:\"\n log_warn \" https://github.com/ccsert/opencode-review-gitea#installation\"\n # Verify opencode binary actually works\n if ! opencode --version >/dev/null 2>&1; then\n log_error \"opencode binary is not compatible with $arch architecture\"\n log_error \"The pre-built Docker image only supports x86_64/amd64\"\n log_error \"Please use the source installation method instead (--source)\"\n exit 1\n fi\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n check_architecture\n setup_config\n infer_gitea_server_url\n normalize_repo_context\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" GITEA_SERVER_URL Base URL like https://gitea.example.com (required)\"\n echo \"\"\n echo \" LLM API Keys (at least one recommended):\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" LLM_API_KEY Generic API key for other providers\"\n echo \" OPENROUTER_API_KEY OpenRouter API key\"\n echo \"\"\n echo \" LLM Gateway (for LiteLLM, OpenRouter, Together AI, etc.):\"\n echo \" OPENAI_BASE_URL Custom API base URL (e.g., http://localhost:4000/v1)\"\n echo \"\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" FILE_PATTERNS Glob patterns to filter files (e.g., '*.ts,*.go')\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "97109259b67e3121a1a5b15214ecd60a561a43ea": {"t": 1785748552.7091858, "n": 10330, "h": "428b235887be8145", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n # Use subshell to avoid directory stack issues\n (\n cd /workspace/.opencode-review || exit 1\n bun install 2>/dev/null || echo \"[WARN] Failed to install custom dependencies\"\n )\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for server URL\n if [ -z \"$GITEA_SERVER_URL\" ] && [ -z \"$GITHUB_SERVER_URL\" ]; then\n missing+=(\"GITEA_SERVER_URL or GITHUB_SERVER_URL\")\n fi\n\n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n\n # Warn if no LLM API key is set (not fatal - some providers don't need one)\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && \\\n [ -z \"$OPENAI_API_KEY\" ] && [ -z \"$LLM_API_KEY\" ] && \\\n [ -z \"$OPENROUTER_API_KEY\" ] && [ -z \"$OPENAI_BASE_URL\" ]; then\n log_warn \"No LLM API key detected (DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, LLM_API_KEY, OPENROUTER_API_KEY)\"\n log_warn \"If you are using a local model or custom gateway, you can ignore this warning\"\n log_warn \"Set OPENAI_BASE_URL to use an OpenAI-compatible gateway (LiteLLM, OpenRouter, etc.)\"\n fi\n \n log_success \"Environment validated\"\n log_warn \"Note: GITEA_TOKEN must have 'write:repository' scope to submit reviews\"\n}\n\ninfer_gitea_server_url() {\n # Normalize: remove trailing slashes and /api/v1 suffix\n if [ -n \"$GITEA_SERVER_URL\" ]; then\n export GITEA_SERVER_URL=\"${GITEA_SERVER_URL%/}\"\n export GITEA_SERVER_URL=\"${GITEA_SERVER_URL%/api/v1}\"\n return 0\n fi\n\n if [ -n \"$GITHUB_SERVER_URL\" ]; then\n export GITEA_SERVER_URL=\"${GITHUB_SERVER_URL%/}\"\n export GITEA_SERVER_URL=\"${GITEA_SERVER_URL%/api/v1}\"\n return 0\n fi\n\n # Best-effort inference from git remote when running locally with -v $(pwd):/workspace\n if [ -d \"/workspace/.git\" ]; then\n local remote\n remote=$(git -C /workspace remote get-url origin 2>/dev/null || true)\n\n if [[ \"$remote\" =~ ^https?:// ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^(https?://[^/]+).*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n\n # SSH-style: git@host:owner/repo.git -> assume https://host\n if [[ \"$remote\" =~ ^git@[^:]+: ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^git@([^:]+):.*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"https://$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n fi\n}\n\nnormalize_repo_context() {\n # Accept REPO_NAME as either \"repo\" or \"owner/repo\".\n if [ -n \"$REPO_NAME\" ] && [[ \"$REPO_NAME\" == */* ]]; then\n local owner_part=\"${REPO_NAME%%/*}\"\n local repo_part=\"${REPO_NAME#*/}\"\n\n if [ -z \"$REPO_OWNER\" ]; then\n export REPO_OWNER=\"$owner_part\"\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n\n if [ \"$owner_part\" = \"$REPO_OWNER\" ]; then\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n fi\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n prompt=\"$prompt.\"\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt Focus only on critical issues, be concise.\"\n ;;\n thorough)\n prompt=\"$prompt Provide thorough analysis including best practices and improvements.\"\n ;;\n security)\n prompt=\"$prompt Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt Provide balanced feedback on bugs, security, and code quality.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt 请使用简体中文回复。\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n # Add file filter instructions\n if [ -n \"$FILE_PATTERNS\" ]; then\n prompt=\"$prompt Only review files matching: $FILE_PATTERNS.\"\n fi\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Server: ${GITEA_SERVER_URL:-${GITHUB_SERVER_URL:-}}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n echo \" Filter: $FILE_PATTERNS\"\n fi\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n if [ -n \"$REPO_OWNER\" ] && [ -n \"$REPO_NAME\" ]; then\n echo \" Repo: $REPO_OWNER/$REPO_NAME\"\n fi\n}\n\ncheck_architecture() {\n local arch\n arch=$(uname -m)\n if [ \"$arch\" != \"x86_64\" ] && [ \"$arch\" != \"amd64\" ]; then\n log_warn \"Detected architecture: $arch (opencode-ai binary may not be supported)\"\n log_warn \"If you encounter errors, please use the source installation method:\"\n log_warn \" https://github.com/ccsert/opencode-review-gitea#installation\"\n # Verify opencode binary actually works\n if ! opencode --version >/dev/null 2>&1; then\n log_error \"opencode binary is not compatible with $arch architecture\"\n log_error \"The pre-built Docker image only supports x86_64/amd64\"\n log_error \"Please use the source installation method instead (--source)\"\n exit 1\n fi\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n check_architecture\n setup_config\n infer_gitea_server_url\n normalize_repo_context\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" GITEA_SERVER_URL Base URL like https://gitea.example.com (required)\"\n echo \"\"\n echo \" LLM API Keys (at least one recommended):\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" LLM_API_KEY Generic API key for other providers\"\n echo \" OPENROUTER_API_KEY OpenRouter API key\"\n echo \"\"\n echo \" LLM Gateway (for LiteLLM, OpenRouter, Together AI, etc.):\"\n echo \" OPENAI_BASE_URL Custom API base URL (e.g., http://localhost:4000/v1)\"\n echo \"\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" FILE_PATTERNS Glob patterns to filter files (e.g., '*.ts,*.go')\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "fe0b60167424520e4dc1fff4cb5f45a6e7c79638": {"t": 1785748553.8022172, "n": 9287, "h": "666356c88107f0a2", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n # Use subshell to avoid directory stack issues\n (\n cd /workspace/.opencode-review || exit 1\n bun install 2>/dev/null || echo \"[WARN] Failed to install custom dependencies\"\n )\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for server URL\n if [ -z \"$GITEA_SERVER_URL\" ] && [ -z \"$GITHUB_SERVER_URL\" ]; then\n missing+=(\"GITEA_SERVER_URL or GITHUB_SERVER_URL\")\n fi\n\n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n\n # Warn if no LLM API key is set (not fatal - some providers don't need one)\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && \\\n [ -z \"$OPENAI_API_KEY\" ] && [ -z \"$LLM_API_KEY\" ] && \\\n [ -z \"$OPENROUTER_API_KEY\" ] && [ -z \"$OPENAI_BASE_URL\" ]; then\n log_warn \"No LLM API key detected (DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, LLM_API_KEY, OPENROUTER_API_KEY)\"\n log_warn \"If you are using a local model or custom gateway, you can ignore this warning\"\n log_warn \"Set OPENAI_BASE_URL to use an OpenAI-compatible gateway (LiteLLM, OpenRouter, etc.)\"\n fi\n \n log_success \"Environment validated\"\n log_warn \"Note: GITEA_TOKEN must have 'write:repository' scope to submit reviews\"\n}\n\ninfer_gitea_server_url() {\n if [ -n \"$GITEA_SERVER_URL\" ]; then\n return 0\n fi\n\n if [ -n \"$GITHUB_SERVER_URL\" ]; then\n export GITEA_SERVER_URL=\"$GITHUB_SERVER_URL\"\n return 0\n fi\n\n # Best-effort inference from git remote when running locally with -v $(pwd):/workspace\n if [ -d \"/workspace/.git\" ]; then\n local remote\n remote=$(git -C /workspace remote get-url origin 2>/dev/null || true)\n\n if [[ \"$remote\" =~ ^https?:// ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^(https?://[^/]+).*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n\n # SSH-style: git@host:owner/repo.git -> assume https://host\n if [[ \"$remote\" =~ ^git@[^:]+: ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^git@([^:]+):.*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"https://$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n fi\n}\n\nnormalize_repo_context() {\n # Accept REPO_NAME as either \"repo\" or \"owner/repo\".\n if [ -n \"$REPO_NAME\" ] && [[ \"$REPO_NAME\" == */* ]]; then\n local owner_part=\"${REPO_NAME%%/*}\"\n local repo_part=\"${REPO_NAME#*/}\"\n\n if [ -z \"$REPO_OWNER\" ]; then\n export REPO_OWNER=\"$owner_part\"\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n\n if [ \"$owner_part\" = \"$REPO_OWNER\" ]; then\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n fi\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n prompt=\"$prompt.\"\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt Focus only on critical issues, be concise.\"\n ;;\n thorough)\n prompt=\"$prompt Provide thorough analysis including best practices and improvements.\"\n ;;\n security)\n prompt=\"$prompt Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt Provide balanced feedback on bugs, security, and code quality.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt 请使用简体中文回复。\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n # Add file filter instructions\n if [ -n \"$FILE_PATTERNS\" ]; then\n prompt=\"$prompt Only review files matching: $FILE_PATTERNS.\"\n fi\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Server: ${GITEA_SERVER_URL:-${GITHUB_SERVER_URL:-}}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n echo \" Filter: $FILE_PATTERNS\"\n fi\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n if [ -n \"$REPO_OWNER\" ] && [ -n \"$REPO_NAME\" ]; then\n echo \" Repo: $REPO_OWNER/$REPO_NAME\"\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n setup_config\n infer_gitea_server_url\n normalize_repo_context\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" GITEA_SERVER_URL Base URL like https://gitea.example.com (required)\"\n echo \"\"\n echo \" LLM API Keys (at least one recommended):\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" LLM_API_KEY Generic API key for other providers\"\n echo \" OPENROUTER_API_KEY OpenRouter API key\"\n echo \"\"\n echo \" LLM Gateway (for LiteLLM, OpenRouter, Together AI, etc.):\"\n echo \" OPENAI_BASE_URL Custom API base URL (e.g., http://localhost:4000/v1)\"\n echo \"\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" FILE_PATTERNS Glob patterns to filter files (e.g., '*.ts,*.go')\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "b3c0e9dba4b88e287ccd796dfbcaac34ce024739": {"t": 1785748554.9049716, "n": 8465, "h": "f19efdc808d4a756", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n # Use subshell to avoid directory stack issues\n (\n cd /workspace/.opencode-review || exit 1\n bun install 2>/dev/null || echo \"[WARN] Failed to install custom dependencies\"\n )\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for server URL\n if [ -z \"$GITEA_SERVER_URL\" ] && [ -z \"$GITHUB_SERVER_URL\" ]; then\n missing+=(\"GITEA_SERVER_URL or GITHUB_SERVER_URL\")\n fi\n\n # Check for at least one LLM API key\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && [ -z \"$OPENAI_API_KEY\" ]; then\n missing+=(\"DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY\")\n fi\n \n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n \n log_success \"Environment validated\"\n log_warn \"Note: GITEA_TOKEN must have 'write:repository' scope to submit reviews\"\n}\n\ninfer_gitea_server_url() {\n if [ -n \"$GITEA_SERVER_URL\" ]; then\n return 0\n fi\n\n if [ -n \"$GITHUB_SERVER_URL\" ]; then\n export GITEA_SERVER_URL=\"$GITHUB_SERVER_URL\"\n return 0\n fi\n\n # Best-effort inference from git remote when running locally with -v $(pwd):/workspace\n if [ -d \"/workspace/.git\" ]; then\n local remote\n remote=$(git -C /workspace remote get-url origin 2>/dev/null || true)\n\n if [[ \"$remote\" =~ ^https?:// ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^(https?://[^/]+).*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n\n # SSH-style: git@host:owner/repo.git -> assume https://host\n if [[ \"$remote\" =~ ^git@[^:]+: ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^git@([^:]+):.*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"https://$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n fi\n}\n\nnormalize_repo_context() {\n # Accept REPO_NAME as either \"repo\" or \"owner/repo\".\n if [ -n \"$REPO_NAME\" ] && [[ \"$REPO_NAME\" == */* ]]; then\n local owner_part=\"${REPO_NAME%%/*}\"\n local repo_part=\"${REPO_NAME#*/}\"\n\n if [ -z \"$REPO_OWNER\" ]; then\n export REPO_OWNER=\"$owner_part\"\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n\n if [ \"$owner_part\" = \"$REPO_OWNER\" ]; then\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n fi\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n prompt=\"$prompt.\"\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt Focus only on critical issues, be concise.\"\n ;;\n thorough)\n prompt=\"$prompt Provide thorough analysis including best practices and improvements.\"\n ;;\n security)\n prompt=\"$prompt Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt Provide balanced feedback on bugs, security, and code quality.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt 请使用简体中文回复。\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n # Add file filter instructions\n if [ -n \"$FILE_PATTERNS\" ]; then\n prompt=\"$prompt Only review files matching: $FILE_PATTERNS.\"\n fi\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Server: ${GITEA_SERVER_URL:-${GITHUB_SERVER_URL:-}}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n echo \" Filter: $FILE_PATTERNS\"\n fi\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n if [ -n \"$REPO_OWNER\" ] && [ -n \"$REPO_NAME\" ]; then\n echo \" Repo: $REPO_OWNER/$REPO_NAME\"\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n setup_config\n infer_gitea_server_url\n normalize_repo_context\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" GITEA_SERVER_URL Base URL like https://gitea.example.com (required)\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" FILE_PATTERNS Glob patterns to filter files (e.g., '*.ts,*.go')\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "2ebf28ade3ffa4f543c0aeb3d9df39d8bc4a5d95": {"t": 1785748556.001247, "n": 8379, "h": "a06817806576459e", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n # Use subshell to avoid directory stack issues\n (\n cd /workspace/.opencode-review || exit 1\n bun install 2>/dev/null || echo \"[WARN] Failed to install custom dependencies\"\n )\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for server URL\n if [ -z \"$GITEA_SERVER_URL\" ] && [ -z \"$GITHUB_SERVER_URL\" ]; then\n missing+=(\"GITEA_SERVER_URL or GITHUB_SERVER_URL\")\n fi\n\n # Check for at least one LLM API key\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && [ -z \"$OPENAI_API_KEY\" ]; then\n missing+=(\"DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY\")\n fi\n \n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n \n log_success \"Environment validated\"\n}\n\ninfer_gitea_server_url() {\n if [ -n \"$GITEA_SERVER_URL\" ]; then\n return 0\n fi\n\n if [ -n \"$GITHUB_SERVER_URL\" ]; then\n export GITEA_SERVER_URL=\"$GITHUB_SERVER_URL\"\n return 0\n fi\n\n # Best-effort inference from git remote when running locally with -v $(pwd):/workspace\n if [ -d \"/workspace/.git\" ]; then\n local remote\n remote=$(git -C /workspace remote get-url origin 2>/dev/null || true)\n\n if [[ \"$remote\" =~ ^https?:// ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^(https?://[^/]+).*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n\n # SSH-style: git@host:owner/repo.git -> assume https://host\n if [[ \"$remote\" =~ ^git@[^:]+: ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^git@([^:]+):.*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"https://$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n fi\n}\n\nnormalize_repo_context() {\n # Accept REPO_NAME as either \"repo\" or \"owner/repo\".\n if [ -n \"$REPO_NAME\" ] && [[ \"$REPO_NAME\" == */* ]]; then\n local owner_part=\"${REPO_NAME%%/*}\"\n local repo_part=\"${REPO_NAME#*/}\"\n\n if [ -z \"$REPO_OWNER\" ]; then\n export REPO_OWNER=\"$owner_part\"\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n\n if [ \"$owner_part\" = \"$REPO_OWNER\" ]; then\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n fi\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n prompt=\"$prompt.\"\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt Focus only on critical issues, be concise.\"\n ;;\n thorough)\n prompt=\"$prompt Provide thorough analysis including best practices and improvements.\"\n ;;\n security)\n prompt=\"$prompt Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt Provide balanced feedback on bugs, security, and code quality.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt 请使用简体中文回复。\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n # Add file filter instructions\n if [ -n \"$FILE_PATTERNS\" ]; then\n prompt=\"$prompt Only review files matching: $FILE_PATTERNS.\"\n fi\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Server: ${GITEA_SERVER_URL:-${GITHUB_SERVER_URL:-}}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n echo \" Filter: $FILE_PATTERNS\"\n fi\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n if [ -n \"$REPO_OWNER\" ] && [ -n \"$REPO_NAME\" ]; then\n echo \" Repo: $REPO_OWNER/$REPO_NAME\"\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n setup_config\n infer_gitea_server_url\n normalize_repo_context\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" GITEA_SERVER_URL Base URL like https://gitea.example.com (required)\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" FILE_PATTERNS Glob patterns to filter files (e.g., '*.ts,*.go')\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "98be681d85d461eb10e30b9a7320d8ea9c7346d2": {"t": 1785748557.1265783, "n": 8529, "h": "dbbc3ac51a83a225", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n local orig_dir\n orig_dir=\"$(pwd)\"\n if cd /workspace/.opencode-review; then\n bun install 2>/dev/null || log_warn \"Failed to install custom dependencies\"\n cd \"$orig_dir\" || log_warn \"Failed to return to original directory\"\n else\n log_warn \"Failed to access /workspace/.opencode-review\"\n fi\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for server URL\n if [ -z \"$GITEA_SERVER_URL\" ] && [ -z \"$GITHUB_SERVER_URL\" ]; then\n missing+=(\"GITEA_SERVER_URL or GITHUB_SERVER_URL\")\n fi\n\n # Check for at least one LLM API key\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && [ -z \"$OPENAI_API_KEY\" ]; then\n missing+=(\"DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY\")\n fi\n \n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n \n log_success \"Environment validated\"\n}\n\ninfer_gitea_server_url() {\n if [ -n \"$GITEA_SERVER_URL\" ]; then\n return 0\n fi\n\n if [ -n \"$GITHUB_SERVER_URL\" ]; then\n export GITEA_SERVER_URL=\"$GITHUB_SERVER_URL\"\n return 0\n fi\n\n # Best-effort inference from git remote when running locally with -v $(pwd):/workspace\n if [ -d \"/workspace/.git\" ]; then\n local remote\n remote=$(git -C /workspace remote get-url origin 2>/dev/null || true)\n\n if [[ \"$remote\" =~ ^https?:// ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^(https?://[^/]+).*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n\n # SSH-style: git@host:owner/repo.git -> assume https://host\n if [[ \"$remote\" =~ ^git@[^:]+: ]]; then\n local host\n host=$(echo \"$remote\" | sed -E 's#^git@([^:]+):.*#\\1#')\n if [ -n \"$host\" ]; then\n export GITEA_SERVER_URL=\"https://$host\"\n log_info \"Inferred GITEA_SERVER_URL from git remote: $GITEA_SERVER_URL\"\n return 0\n fi\n fi\n fi\n}\n\nnormalize_repo_context() {\n # Accept REPO_NAME as either \"repo\" or \"owner/repo\".\n if [ -n \"$REPO_NAME\" ] && [[ \"$REPO_NAME\" == */* ]]; then\n local owner_part=\"${REPO_NAME%%/*}\"\n local repo_part=\"${REPO_NAME#*/}\"\n\n if [ -z \"$REPO_OWNER\" ]; then\n export REPO_OWNER=\"$owner_part\"\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n\n if [ \"$owner_part\" = \"$REPO_OWNER\" ]; then\n export REPO_NAME=\"$repo_part\"\n return 0\n fi\n fi\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n prompt=\"$prompt.\"\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt Focus only on critical issues, be concise.\"\n ;;\n thorough)\n prompt=\"$prompt Provide thorough analysis including best practices and improvements.\"\n ;;\n security)\n prompt=\"$prompt Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt Provide balanced feedback on bugs, security, and code quality.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt 请使用简体中文回复。\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n # Add file filter instructions\n if [ -n \"$FILE_PATTERNS\" ]; then\n prompt=\"$prompt Only review files matching: $FILE_PATTERNS.\"\n fi\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Server: ${GITEA_SERVER_URL:-${GITHUB_SERVER_URL:-}}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n echo \" Filter: $FILE_PATTERNS\"\n fi\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n if [ -n \"$REPO_OWNER\" ] && [ -n \"$REPO_NAME\" ]; then\n echo \" Repo: $REPO_OWNER/$REPO_NAME\"\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n setup_config\n infer_gitea_server_url\n normalize_repo_context\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" GITEA_SERVER_URL Base URL like https://gitea.example.com (required)\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" FILE_PATTERNS Glob patterns to filter files (e.g., '*.ts,*.go')\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "37ad4f81cd7aeb2d9401c2f3bbbab1fbc6d26057": {"t": 1785748558.1985633, "n": 6243, "h": "2aa1d0d9644892d2", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n local orig_dir\n orig_dir=\"$(pwd)\"\n if cd /workspace/.opencode-review; then\n bun install 2>/dev/null || log_warn \"Failed to install custom dependencies\"\n cd \"$orig_dir\" || log_warn \"Failed to return to original directory\"\n else\n log_warn \"Failed to access /workspace/.opencode-review\"\n fi\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for at least one LLM API key\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && [ -z \"$OPENAI_API_KEY\" ]; then\n missing+=(\"DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY\")\n fi\n \n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n \n log_success \"Environment validated\"\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n prompt=\"$prompt.\"\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt Focus only on critical issues, be concise.\"\n ;;\n thorough)\n prompt=\"$prompt Provide thorough analysis including best practices and improvements.\"\n ;;\n security)\n prompt=\"$prompt Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt Provide balanced feedback on bugs, security, and code quality.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt 请使用简体中文回复。\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n # Add file filter instructions\n if [ -n \"$FILE_PATTERNS\" ]; then\n prompt=\"$prompt Only review files matching: $FILE_PATTERNS.\"\n fi\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$FILE_PATTERNS\" ]; then\n echo \" Filter: $FILE_PATTERNS\"\n fi\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n setup_config\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" FILE_PATTERNS Glob patterns to filter files (e.g., '*.ts,*.go')\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "45c1de59f53f25e036ee2b43d8ebb8e6050713c1": {"t": 1785748559.3225095, "n": 5940, "h": "a4593321a7aa2c68", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n local orig_dir\n orig_dir=\"$(pwd)\"\n if cd /workspace/.opencode-review; then\n bun install 2>/dev/null || log_warn \"Failed to install custom dependencies\"\n cd \"$orig_dir\" || log_warn \"Failed to return to original directory\"\n else\n log_warn \"Failed to access /workspace/.opencode-review\"\n fi\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for at least one LLM API key\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && [ -z \"$OPENAI_API_KEY\" ]; then\n missing+=(\"DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY\")\n fi\n \n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n \n log_success \"Environment validated\"\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Please review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt. Be concise, focus only on critical issues.\"\n ;;\n thorough)\n prompt=\"$prompt. Provide thorough analysis including suggestions, best practices, and potential improvements.\"\n ;;\n security)\n prompt=\"$prompt. Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt. Provide balanced feedback on code quality, bugs, and improvements.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt Reply in Chinese (简体中文).\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n setup_config\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "7c701071931a021863045e191c34ca55132fe360": {"t": 1785748560.4050138, "n": 6242, "h": "0b8a296fd7063aaa", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n cd /workspace/.opencode-review\n if ! bun install; then\n log_error \"Failed to install custom dependencies in /workspace/.opencode-review. See bun output above for details.\"\n local orig_dir\n orig_dir=\"$(pwd)\"\n if cd /workspace/.opencode-review; then\n bun install 2>/dev/null || log_warn \"Failed to install custom dependencies\"\n if ! cd \"$orig_dir\"; then\n log_warn \"Failed to return to original directory: $orig_dir\"\n fi\n else\n log_warn \"Failed to access /workspace/.opencode-review; skipping dependency installation\"\n fi\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for at least one LLM API key\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && [ -z \"$OPENAI_API_KEY\" ]; then\n missing+=(\"DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY\")\n fi\n \n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n \n log_success \"Environment validated\"\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Please review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt. Be concise, focus only on critical issues.\"\n ;;\n thorough)\n prompt=\"$prompt. Provide thorough analysis including suggestions, best practices, and potential improvements.\"\n ;;\n security)\n prompt=\"$prompt. Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt. Provide balanced feedback on code quality, bugs, and improvements.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt Reply in Chinese (简体中文).\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n setup_config\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "42817f13494fc6408a66b368de86972784478a94": {"t": 1785748561.6625533, "n": 5825, "h": "14d1e206f6fb4c60", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n cd /workspace/.opencode-review\n if ! bun install; then\n log_error \"Failed to install custom dependencies in /workspace/.opencode-review. See bun output above for details.\"\n exit 1\n fi\n cd /workspace\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for at least one LLM API key\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && [ -z \"$OPENAI_API_KEY\" ]; then\n missing+=(\"DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY\")\n fi\n \n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n \n log_success \"Environment validated\"\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Please review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt. Be concise, focus only on critical issues.\"\n ;;\n thorough)\n prompt=\"$prompt. Provide thorough analysis including suggestions, best practices, and potential improvements.\"\n ;;\n security)\n prompt=\"$prompt. Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt. Provide balanced feedback on code quality, bugs, and improvements.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt Reply in Chinese (简体中文).\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n setup_config\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}, "e1a9786059c2ae7efe88d99f283279091bf3dc39": {"t": 1785748562.7350123, "n": 5708, "h": "f9824c360cd69db4", "c": "#!/bin/bash\n#\n# OpenCode Review Docker Entrypoint\n# Handles environment configuration and user config mounting\n#\n\nset -e\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\n# Check for user-mounted custom config\nsetup_config() {\n # If user mounted custom config at /workspace/.opencode-review, use it\n if [ -d \"/workspace/.opencode-review\" ]; then\n log_info \"Using custom config from /workspace/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/workspace/.opencode-review\"\n \n # Install dependencies if package.json exists\n if [ -f \"/workspace/.opencode-review/package.json\" ]; then\n log_info \"Installing custom tool dependencies...\"\n cd /workspace/.opencode-review\n bun install 2>/dev/null || log_warn \"Failed to install custom dependencies\"\n cd /workspace\n fi\n else\n log_info \"Using built-in config from /app/.opencode-review\"\n export OPENCODE_CONFIG_DIR=\"/app/.opencode-review\"\n fi\n}\n\n# Validate required environment variables\nvalidate_env() {\n local missing=()\n \n # Check for API token\n if [ -z \"$GITEA_TOKEN\" ] && [ -z \"$GITHUB_TOKEN\" ]; then\n missing+=(\"GITEA_TOKEN or GITHUB_TOKEN\")\n fi\n \n # Check for at least one LLM API key\n if [ -z \"$DEEPSEEK_API_KEY\" ] && [ -z \"$ANTHROPIC_API_KEY\" ] && [ -z \"$OPENAI_API_KEY\" ]; then\n missing+=(\"DEEPSEEK_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY\")\n fi\n \n if [ ${#missing[@]} -gt 0 ]; then\n log_error \"Missing required environment variables:\"\n for var in \"${missing[@]}\"; do\n echo \" - $var\"\n done\n exit 1\n fi\n \n log_success \"Environment validated\"\n}\n\n# Build the review prompt based on environment\nbuild_prompt() {\n local pr_num=\"${PR_NUMBER:-}\"\n local repo_owner=\"${REPO_OWNER:-}\"\n local repo_name=\"${REPO_NAME:-}\"\n \n local prompt=\"Please review\"\n \n if [ -n \"$pr_num\" ]; then\n prompt=\"$prompt PR #$pr_num\"\n fi\n \n if [ -n \"$repo_owner\" ] && [ -n \"$repo_name\" ]; then\n prompt=\"$prompt in $repo_owner/$repo_name\"\n fi\n \n # Add style instructions\n case \"${REVIEW_STYLE:-balanced}\" in\n concise)\n prompt=\"$prompt. Be concise, focus only on critical issues.\"\n ;;\n thorough)\n prompt=\"$prompt. Provide thorough analysis including suggestions, best practices, and potential improvements.\"\n ;;\n security)\n prompt=\"$prompt. Focus on security vulnerabilities and potential risks.\"\n ;;\n *)\n prompt=\"$prompt. Provide balanced feedback on code quality, bugs, and improvements.\"\n ;;\n esac\n \n # Add language preference\n case \"${REVIEW_LANGUAGE:-auto}\" in\n zh-CN|zh)\n prompt=\"$prompt Reply in Chinese (简体中文).\"\n ;;\n en)\n prompt=\"$prompt Reply in English.\"\n ;;\n # auto: let the model decide based on code content\n esac\n \n echo \"$prompt\"\n}\n\n# Print configuration summary\nprint_config() {\n log_info \"Configuration:\"\n echo \" Model: ${MODEL:-deepseek/deepseek-chat}\"\n echo \" Style: ${REVIEW_STYLE:-balanced}\"\n echo \" Language: ${REVIEW_LANGUAGE:-auto}\"\n echo \" Config: $OPENCODE_CONFIG_DIR\"\n if [ -n \"$PR_NUMBER\" ]; then\n echo \" PR: #$PR_NUMBER\"\n fi\n}\n\n# Main entrypoint\nmain() {\n local command=\"${1:-review}\"\n shift || true\n \n case \"$command\" in\n review)\n setup_config\n validate_env\n print_config\n \n local prompt\n if [ -n \"$1\" ]; then\n prompt=\"$*\"\n else\n prompt=$(build_prompt)\n fi\n \n log_info \"Running code review...\"\n exec opencode run --agent code-review \"$prompt\"\n ;;\n \n shell|bash|sh)\n log_info \"Starting interactive shell...\"\n exec /bin/bash\n ;;\n \n version|--version|-v)\n opencode --version\n ;;\n \n help|--help|-h)\n echo \"OpenCode Review for Gitea/Forgejo\"\n echo \"\"\n echo \"Usage: docker run ghcr.io/ccsert/opencode-review [command]\"\n echo \"\"\n echo \"Commands:\"\n echo \" review [prompt] Run code review (default)\"\n echo \" shell Start interactive shell\"\n echo \" version Show version\"\n echo \" help Show this help\"\n echo \"\"\n echo \"Environment Variables:\"\n echo \" GITEA_TOKEN Gitea API token (required)\"\n echo \" DEEPSEEK_API_KEY DeepSeek API key\"\n echo \" ANTHROPIC_API_KEY Anthropic API key\"\n echo \" OPENAI_API_KEY OpenAI API key\"\n echo \" MODEL AI model (default: deepseek/deepseek-chat)\"\n echo \" REVIEW_LANGUAGE auto|en|zh-CN (default: auto)\"\n echo \" REVIEW_STYLE concise|balanced|thorough|security (default: balanced)\"\n echo \" PR_NUMBER PR number to review\"\n echo \" REPO_OWNER Repository owner\"\n echo \" REPO_NAME Repository name\"\n ;;\n \n *)\n # Pass through to opencode\n exec opencode \"$command\" \"$@\"\n ;;\n esac\n}\n\nmain \"$@\"\n"}}, "install.sh": {"7451ddeb0afbfe9c168b0a2157b4cb9334c7efca": {"t": 1785745942.1864913, "n": 12615, "h": "d287782867707b84", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# Interactive: curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n# Docker only: curl ... | bash -s -- --docker\n# Source only: curl ... | bash -s -- --source\n# Offline: cd /your/project && /path/to/install.sh --offline --docker\n#\n# Options:\n# --docker Install Docker-based workflow only (recommended)\n# --source Install source-based workflow with .opencode-review/\n# --both Install both installation methods\n# --offline Enable offline mode (use script's directory as source)\n# --skip-deps Skip bun install (useful for offline/CI environments)\n# --help Show help message\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\nDOCKER_IMAGE=\"ghcr.io/ccsert/opencode-review\"\n\n# Installation mode\nINSTALL_MODE=\"\"\n\n# Offline mode settings\nOFFLINE_MODE=false\nSKIP_DEPS=false\n\n# Get the directory where this script is located\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\nparse_args() {\n while [[ $# -gt 0 ]]; do\n case $1 in\n --docker) INSTALL_MODE=\"docker\"; shift ;;\n --source) INSTALL_MODE=\"source\"; shift ;;\n --both) INSTALL_MODE=\"both\"; shift ;;\n --offline) OFFLINE_MODE=true; shift ;;\n --skip-deps) SKIP_DEPS=true; shift ;;\n --help|-h) show_help; exit 0 ;;\n *) log_error \"Unknown option: $1\"; show_help; exit 1 ;;\n esac\n done\n}\n\nshow_help() {\n echo \"\"\n echo \"OpenCode Gitea Review - Installation Script\"\n echo \"\"\n echo \"Usage:\"\n echo \" Online: curl -fsSL $REPO_URL/main/install.sh | bash [options]\"\n echo \" Offline: cd /your/project && /path/to/opencode-review-gitea/install.sh --offline [options]\"\n echo \"\"\n echo \"Options:\"\n echo \" --docker Install Docker-based workflow only (recommended)\"\n echo \" --source Install source-based workflow with .opencode-review/\"\n echo \" --both Install both installation methods\"\n echo \" --offline Enable offline mode (use script's directory as source)\"\n echo \" --skip-deps Skip 'bun install' (useful for offline/CI environments)\"\n echo \" --help Show this help message\"\n echo \"\"\n echo \"Offline Installation:\"\n echo \" 1. Clone repo: git clone $REPO_URL\"\n echo \" 2. In target project: cd /your/project\"\n echo \" 3. Run: /path/to/opencode-review-gitea/install.sh --offline --docker\"\n echo \"\"\n}\n\nprint_banner() {\n echo \"\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo -e \"${CYAN}|${NC} ${BOLD}OpenCode Gitea Review - AI-Powered Code Review${NC} ${CYAN}|${NC}\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo \"\"\n}\n\nselect_install_mode() {\n echo -e \"${BOLD}Select installation method:${NC}\"\n echo \"\"\n echo -e \" ${GREEN}1)${NC} ${BOLD}Docker${NC} (Recommended)\"\n echo \" - Zero files added to your repo (just 1 workflow file)\"\n echo \" - Faster CI (pre-built image, no dependency installation)\"\n echo \" - Automatic updates with :latest tag\"\n echo \"\"\n echo -e \" ${BLUE}2)${NC} ${BOLD}Source${NC}\"\n echo \" - Full control over agents, tools, and configuration\"\n echo \" - Can customize review behavior\"\n echo \" - Adds .opencode-review/ directory (~50KB)\"\n echo \"\"\n echo -e \" ${YELLOW}3)${NC} ${BOLD}Both${NC}\"\n echo \" - Install both methods (Docker workflow + source files)\"\n echo \" - Docker workflow can mount local config for customization\"\n echo \"\"\n \n # Read from /dev/tty to handle curl | bash execution\n while true; do\n read -p \"Enter choice [1-3]: \" choice < /dev/tty\n case $choice in\n 1) INSTALL_MODE=\"docker\"; break ;;\n 2) INSTALL_MODE=\"source\"; break ;;\n 3) INSTALL_MODE=\"both\"; break ;;\n *) echo \"Invalid choice. Please enter 1, 2, or 3.\" ;;\n esac\n done\n echo \"\"\n}\n\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\nget_project_root() { git rev-parse --show-toplevel; }\n\ncheck_source_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n if ! command -v bun &> /dev/null; then\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_warn \"bun not found. In offline mode, please install bun manually first.\"\n log_warn \"Or use --skip-deps to skip dependency installation.\"\n if [ \"$SKIP_DEPS\" = false ]; then\n exit 1\n fi\n else\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n fi\n}\n\nTMP_DIR=$(mktemp -d)\n\ndownload_repo() {\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_info \"Offline mode: using script directory as source\"\n log_info \"Source: $SCRIPT_DIR\"\n if [ ! -f \"$SCRIPT_DIR/templates/workflow-docker.yaml\" ] && [ ! -f \"$SCRIPT_DIR/templates/workflow-source.yaml\" ]; then\n log_error \"Invalid source: templates/ not found in $SCRIPT_DIR\"\n log_error \"Make sure you're running install.sh from the opencode-review-gitea repo\"\n exit 1\n fi\n # Copy to TMP_DIR for consistent handling\n cp -r \"$SCRIPT_DIR\" \"$TMP_DIR/repo\"\n log_success \"Using local repository\"\n else\n log_info \"Downloading opencode-review-gitea...\"\n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n fi\n}\n\ninstall_docker_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing Docker-based workflow...\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with Docker version? [y/N] \" -n 1 -r < /dev/tty\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-docker.yaml\" \"$workflow_target\"\n log_success \"Installed Docker workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_source_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing source files...\"\n local target_dir=\"$project_root/.opencode-review\"\n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r < /dev/tty\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Updated .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n}\n\ninstall_source_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with source version? [y/N] \" -n 1 -r < /dev/tty\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-source.yaml\" \"$workflow_target\"\n log_success \"Installed source workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_dependencies() {\n local project_root=\"$1\"\n if [ \"$SKIP_DEPS\" = true ]; then\n log_info \"Skipping dependency installation (--skip-deps)\"\n return\n fi\n if [ -d \"$project_root/.opencode-review\" ]; then\n log_info \"Installing npm dependencies...\"\n # Use subshell to avoid directory stack issues with zsh hooks\n (\n cd \"$project_root/.opencode-review\" || exit 1\n if [ -f \"$HOME/.bun/bin/bun\" ]; then\n \"$HOME/.bun/bin/bun\" install\n elif command -v bun &> /dev/null; then\n bun install\n else\n echo \"[WARN] bun not found, skipping dependency installation\"\n echo \"[WARN] Run 'cd .opencode-review && bun install' manually later\"\n exit 0\n fi\n )\n if [ $? -eq 0 ]; then\n log_success \"Dependencies installed\"\n fi\n fi\n}\n\ncleanup() { rm -rf \"$TMP_DIR\"; }\n\nprint_next_steps() {\n local mode=\"$1\"\n echo \"\"\n echo -e \"${GREEN}Installation complete!${NC}\"\n echo \"\"\n echo -e \"${BOLD}Next steps:${NC}\"\n echo \"\"\n echo \"1. Configure Gitea/Forgejo Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (default model)\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"both\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea .opencode-review\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker + Source)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"source\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Source)'\"\n echo \" git push\"\n fi\n echo \"\"\n echo \"3. Trigger review by commenting /oc or /opencode on a PR\"\n echo \"\"\n echo -e \"${BOLD}Documentation:${NC} $REPO_URL\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Docker image:${NC} $DOCKER_IMAGE:latest\"\n fi\n if [ \"$mode\" = \"source\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Isolation:${NC} Uses OPENCODE_CONFIG_DIR to load from .opencode-review/\"\n fi\n echo \"\"\n}\n\nmain() {\n parse_args \"$@\"\n print_banner\n check_git_repo\n local project_root=$(get_project_root)\n log_info \"Project root: $project_root\"\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"This tool uses isolated .opencode-review/ to avoid conflicts\"\n fi\n if [ -z \"$INSTALL_MODE\" ]; then\n select_install_mode\n fi\n log_info \"Installation mode: $INSTALL_MODE\"\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_info \"Offline mode: enabled\"\n fi\n if [ \"$SKIP_DEPS\" = true ]; then\n log_info \"Skip dependencies: enabled\"\n fi\n echo \"\"\n download_repo\n case \"$INSTALL_MODE\" in\n docker) install_docker_workflow \"$project_root\" ;;\n source)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_source_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n both)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_docker_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n esac\n cleanup\n print_next_steps \"$INSTALL_MODE\"\n}\n\ntrap cleanup EXIT\nmain \"$@\"\n"}, "1d82e5c41211a2ee730604bf263b0f4e72215e5f": {"t": 1785748548.8756201, "n": 12615, "h": "d287782867707b84", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# Interactive: curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n# Docker only: curl ... | bash -s -- --docker\n# Source only: curl ... | bash -s -- --source\n# Offline: cd /your/project && /path/to/install.sh --offline --docker\n#\n# Options:\n# --docker Install Docker-based workflow only (recommended)\n# --source Install source-based workflow with .opencode-review/\n# --both Install both installation methods\n# --offline Enable offline mode (use script's directory as source)\n# --skip-deps Skip bun install (useful for offline/CI environments)\n# --help Show help message\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\nDOCKER_IMAGE=\"ghcr.io/ccsert/opencode-review\"\n\n# Installation mode\nINSTALL_MODE=\"\"\n\n# Offline mode settings\nOFFLINE_MODE=false\nSKIP_DEPS=false\n\n# Get the directory where this script is located\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\nparse_args() {\n while [[ $# -gt 0 ]]; do\n case $1 in\n --docker) INSTALL_MODE=\"docker\"; shift ;;\n --source) INSTALL_MODE=\"source\"; shift ;;\n --both) INSTALL_MODE=\"both\"; shift ;;\n --offline) OFFLINE_MODE=true; shift ;;\n --skip-deps) SKIP_DEPS=true; shift ;;\n --help|-h) show_help; exit 0 ;;\n *) log_error \"Unknown option: $1\"; show_help; exit 1 ;;\n esac\n done\n}\n\nshow_help() {\n echo \"\"\n echo \"OpenCode Gitea Review - Installation Script\"\n echo \"\"\n echo \"Usage:\"\n echo \" Online: curl -fsSL $REPO_URL/main/install.sh | bash [options]\"\n echo \" Offline: cd /your/project && /path/to/opencode-review-gitea/install.sh --offline [options]\"\n echo \"\"\n echo \"Options:\"\n echo \" --docker Install Docker-based workflow only (recommended)\"\n echo \" --source Install source-based workflow with .opencode-review/\"\n echo \" --both Install both installation methods\"\n echo \" --offline Enable offline mode (use script's directory as source)\"\n echo \" --skip-deps Skip 'bun install' (useful for offline/CI environments)\"\n echo \" --help Show this help message\"\n echo \"\"\n echo \"Offline Installation:\"\n echo \" 1. Clone repo: git clone $REPO_URL\"\n echo \" 2. In target project: cd /your/project\"\n echo \" 3. Run: /path/to/opencode-review-gitea/install.sh --offline --docker\"\n echo \"\"\n}\n\nprint_banner() {\n echo \"\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo -e \"${CYAN}|${NC} ${BOLD}OpenCode Gitea Review - AI-Powered Code Review${NC} ${CYAN}|${NC}\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo \"\"\n}\n\nselect_install_mode() {\n echo -e \"${BOLD}Select installation method:${NC}\"\n echo \"\"\n echo -e \" ${GREEN}1)${NC} ${BOLD}Docker${NC} (Recommended)\"\n echo \" - Zero files added to your repo (just 1 workflow file)\"\n echo \" - Faster CI (pre-built image, no dependency installation)\"\n echo \" - Automatic updates with :latest tag\"\n echo \"\"\n echo -e \" ${BLUE}2)${NC} ${BOLD}Source${NC}\"\n echo \" - Full control over agents, tools, and configuration\"\n echo \" - Can customize review behavior\"\n echo \" - Adds .opencode-review/ directory (~50KB)\"\n echo \"\"\n echo -e \" ${YELLOW}3)${NC} ${BOLD}Both${NC}\"\n echo \" - Install both methods (Docker workflow + source files)\"\n echo \" - Docker workflow can mount local config for customization\"\n echo \"\"\n \n # Read from /dev/tty to handle curl | bash execution\n while true; do\n read -p \"Enter choice [1-3]: \" choice < /dev/tty\n case $choice in\n 1) INSTALL_MODE=\"docker\"; break ;;\n 2) INSTALL_MODE=\"source\"; break ;;\n 3) INSTALL_MODE=\"both\"; break ;;\n *) echo \"Invalid choice. Please enter 1, 2, or 3.\" ;;\n esac\n done\n echo \"\"\n}\n\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\nget_project_root() { git rev-parse --show-toplevel; }\n\ncheck_source_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n if ! command -v bun &> /dev/null; then\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_warn \"bun not found. In offline mode, please install bun manually first.\"\n log_warn \"Or use --skip-deps to skip dependency installation.\"\n if [ \"$SKIP_DEPS\" = false ]; then\n exit 1\n fi\n else\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n fi\n}\n\nTMP_DIR=$(mktemp -d)\n\ndownload_repo() {\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_info \"Offline mode: using script directory as source\"\n log_info \"Source: $SCRIPT_DIR\"\n if [ ! -f \"$SCRIPT_DIR/templates/workflow-docker.yaml\" ] && [ ! -f \"$SCRIPT_DIR/templates/workflow-source.yaml\" ]; then\n log_error \"Invalid source: templates/ not found in $SCRIPT_DIR\"\n log_error \"Make sure you're running install.sh from the opencode-review-gitea repo\"\n exit 1\n fi\n # Copy to TMP_DIR for consistent handling\n cp -r \"$SCRIPT_DIR\" \"$TMP_DIR/repo\"\n log_success \"Using local repository\"\n else\n log_info \"Downloading opencode-review-gitea...\"\n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n fi\n}\n\ninstall_docker_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing Docker-based workflow...\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with Docker version? [y/N] \" -n 1 -r < /dev/tty\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-docker.yaml\" \"$workflow_target\"\n log_success \"Installed Docker workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_source_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing source files...\"\n local target_dir=\"$project_root/.opencode-review\"\n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r < /dev/tty\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Updated .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n}\n\ninstall_source_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with source version? [y/N] \" -n 1 -r < /dev/tty\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-source.yaml\" \"$workflow_target\"\n log_success \"Installed source workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_dependencies() {\n local project_root=\"$1\"\n if [ \"$SKIP_DEPS\" = true ]; then\n log_info \"Skipping dependency installation (--skip-deps)\"\n return\n fi\n if [ -d \"$project_root/.opencode-review\" ]; then\n log_info \"Installing npm dependencies...\"\n # Use subshell to avoid directory stack issues with zsh hooks\n (\n cd \"$project_root/.opencode-review\" || exit 1\n if [ -f \"$HOME/.bun/bin/bun\" ]; then\n \"$HOME/.bun/bin/bun\" install\n elif command -v bun &> /dev/null; then\n bun install\n else\n echo \"[WARN] bun not found, skipping dependency installation\"\n echo \"[WARN] Run 'cd .opencode-review && bun install' manually later\"\n exit 0\n fi\n )\n if [ $? -eq 0 ]; then\n log_success \"Dependencies installed\"\n fi\n fi\n}\n\ncleanup() { rm -rf \"$TMP_DIR\"; }\n\nprint_next_steps() {\n local mode=\"$1\"\n echo \"\"\n echo -e \"${GREEN}Installation complete!${NC}\"\n echo \"\"\n echo -e \"${BOLD}Next steps:${NC}\"\n echo \"\"\n echo \"1. Configure Gitea/Forgejo Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (default model)\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"both\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea .opencode-review\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker + Source)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"source\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Source)'\"\n echo \" git push\"\n fi\n echo \"\"\n echo \"3. Trigger review by commenting /oc or /opencode on a PR\"\n echo \"\"\n echo -e \"${BOLD}Documentation:${NC} $REPO_URL\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Docker image:${NC} $DOCKER_IMAGE:latest\"\n fi\n if [ \"$mode\" = \"source\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Isolation:${NC} Uses OPENCODE_CONFIG_DIR to load from .opencode-review/\"\n fi\n echo \"\"\n}\n\nmain() {\n parse_args \"$@\"\n print_banner\n check_git_repo\n local project_root=$(get_project_root)\n log_info \"Project root: $project_root\"\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"This tool uses isolated .opencode-review/ to avoid conflicts\"\n fi\n if [ -z \"$INSTALL_MODE\" ]; then\n select_install_mode\n fi\n log_info \"Installation mode: $INSTALL_MODE\"\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_info \"Offline mode: enabled\"\n fi\n if [ \"$SKIP_DEPS\" = true ]; then\n log_info \"Skip dependencies: enabled\"\n fi\n echo \"\"\n download_repo\n case \"$INSTALL_MODE\" in\n docker) install_docker_workflow \"$project_root\" ;;\n source)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_source_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n both)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_docker_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n esac\n cleanup\n print_next_steps \"$INSTALL_MODE\"\n}\n\ntrap cleanup EXIT\nmain \"$@\"\n"}, "2ebf28ade3ffa4f543c0aeb3d9df39d8bc4a5d95": {"t": 1785748550.129519, "n": 12514, "h": "fe3301c065cb55d9", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# Interactive: curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n# Docker only: curl ... | bash -s -- --docker\n# Source only: curl ... | bash -s -- --source\n# Offline: cd /your/project && /path/to/install.sh --offline --docker\n#\n# Options:\n# --docker Install Docker-based workflow only (recommended)\n# --source Install source-based workflow with .opencode-review/\n# --both Install both installation methods\n# --offline Enable offline mode (use script's directory as source)\n# --skip-deps Skip bun install (useful for offline/CI environments)\n# --help Show help message\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\nDOCKER_IMAGE=\"ghcr.io/ccsert/opencode-review\"\n\n# Installation mode\nINSTALL_MODE=\"\"\n\n# Offline mode settings\nOFFLINE_MODE=false\nSKIP_DEPS=false\n\n# Get the directory where this script is located\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\nparse_args() {\n while [[ $# -gt 0 ]]; do\n case $1 in\n --docker) INSTALL_MODE=\"docker\"; shift ;;\n --source) INSTALL_MODE=\"source\"; shift ;;\n --both) INSTALL_MODE=\"both\"; shift ;;\n --offline) OFFLINE_MODE=true; shift ;;\n --skip-deps) SKIP_DEPS=true; shift ;;\n --help|-h) show_help; exit 0 ;;\n *) log_error \"Unknown option: $1\"; show_help; exit 1 ;;\n esac\n done\n}\n\nshow_help() {\n echo \"\"\n echo \"OpenCode Gitea Review - Installation Script\"\n echo \"\"\n echo \"Usage:\"\n echo \" Online: curl -fsSL $REPO_URL/main/install.sh | bash [options]\"\n echo \" Offline: cd /your/project && /path/to/opencode-review-gitea/install.sh --offline [options]\"\n echo \"\"\n echo \"Options:\"\n echo \" --docker Install Docker-based workflow only (recommended)\"\n echo \" --source Install source-based workflow with .opencode-review/\"\n echo \" --both Install both installation methods\"\n echo \" --offline Enable offline mode (use script's directory as source)\"\n echo \" --skip-deps Skip 'bun install' (useful for offline/CI environments)\"\n echo \" --help Show this help message\"\n echo \"\"\n echo \"Offline Installation:\"\n echo \" 1. Clone repo: git clone $REPO_URL\"\n echo \" 2. In target project: cd /your/project\"\n echo \" 3. Run: /path/to/opencode-review-gitea/install.sh --offline --docker\"\n echo \"\"\n}\n\nprint_banner() {\n echo \"\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo -e \"${CYAN}|${NC} ${BOLD}OpenCode Gitea Review - AI-Powered Code Review${NC} ${CYAN}|${NC}\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo \"\"\n}\n\nselect_install_mode() {\n echo -e \"${BOLD}Select installation method:${NC}\"\n echo \"\"\n echo -e \" ${GREEN}1)${NC} ${BOLD}Docker${NC} (Recommended)\"\n echo \" - Zero files added to your repo (just 1 workflow file)\"\n echo \" - Faster CI (pre-built image, no dependency installation)\"\n echo \" - Automatic updates with :latest tag\"\n echo \"\"\n echo -e \" ${BLUE}2)${NC} ${BOLD}Source${NC}\"\n echo \" - Full control over agents, tools, and configuration\"\n echo \" - Can customize review behavior\"\n echo \" - Adds .opencode-review/ directory (~50KB)\"\n echo \"\"\n echo -e \" ${YELLOW}3)${NC} ${BOLD}Both${NC}\"\n echo \" - Install both methods (Docker workflow + source files)\"\n echo \" - Docker workflow can mount local config for customization\"\n echo \"\"\n \n while true; do\n read -p \"Enter choice [1-3]: \" choice\n case $choice in\n 1) INSTALL_MODE=\"docker\"; break ;;\n 2) INSTALL_MODE=\"source\"; break ;;\n 3) INSTALL_MODE=\"both\"; break ;;\n *) echo \"Invalid choice. Please enter 1, 2, or 3.\" ;;\n esac\n done\n echo \"\"\n}\n\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\nget_project_root() { git rev-parse --show-toplevel; }\n\ncheck_source_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n if ! command -v bun &> /dev/null; then\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_warn \"bun not found. In offline mode, please install bun manually first.\"\n log_warn \"Or use --skip-deps to skip dependency installation.\"\n if [ \"$SKIP_DEPS\" = false ]; then\n exit 1\n fi\n else\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n fi\n}\n\nTMP_DIR=$(mktemp -d)\n\ndownload_repo() {\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_info \"Offline mode: using script directory as source\"\n log_info \"Source: $SCRIPT_DIR\"\n if [ ! -f \"$SCRIPT_DIR/templates/workflow-docker.yaml\" ] && [ ! -f \"$SCRIPT_DIR/templates/workflow-source.yaml\" ]; then\n log_error \"Invalid source: templates/ not found in $SCRIPT_DIR\"\n log_error \"Make sure you're running install.sh from the opencode-review-gitea repo\"\n exit 1\n fi\n # Copy to TMP_DIR for consistent handling\n cp -r \"$SCRIPT_DIR\" \"$TMP_DIR/repo\"\n log_success \"Using local repository\"\n else\n log_info \"Downloading opencode-review-gitea...\"\n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n fi\n}\n\ninstall_docker_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing Docker-based workflow...\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with Docker version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-docker.yaml\" \"$workflow_target\"\n log_success \"Installed Docker workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_source_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing source files...\"\n local target_dir=\"$project_root/.opencode-review\"\n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Updated .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n}\n\ninstall_source_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with source version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-source.yaml\" \"$workflow_target\"\n log_success \"Installed source workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_dependencies() {\n local project_root=\"$1\"\n if [ \"$SKIP_DEPS\" = true ]; then\n log_info \"Skipping dependency installation (--skip-deps)\"\n return\n fi\n if [ -d \"$project_root/.opencode-review\" ]; then\n log_info \"Installing npm dependencies...\"\n # Use subshell to avoid directory stack issues with zsh hooks\n (\n cd \"$project_root/.opencode-review\" || exit 1\n if [ -f \"$HOME/.bun/bin/bun\" ]; then\n \"$HOME/.bun/bin/bun\" install\n elif command -v bun &> /dev/null; then\n bun install\n else\n echo \"[WARN] bun not found, skipping dependency installation\"\n echo \"[WARN] Run 'cd .opencode-review && bun install' manually later\"\n exit 0\n fi\n )\n if [ $? -eq 0 ]; then\n log_success \"Dependencies installed\"\n fi\n fi\n}\n\ncleanup() { rm -rf \"$TMP_DIR\"; }\n\nprint_next_steps() {\n local mode=\"$1\"\n echo \"\"\n echo -e \"${GREEN}Installation complete!${NC}\"\n echo \"\"\n echo -e \"${BOLD}Next steps:${NC}\"\n echo \"\"\n echo \"1. Configure Gitea/Forgejo Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (default model)\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"both\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea .opencode-review\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker + Source)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"source\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Source)'\"\n echo \" git push\"\n fi\n echo \"\"\n echo \"3. Trigger review by commenting /oc or /opencode on a PR\"\n echo \"\"\n echo -e \"${BOLD}Documentation:${NC} $REPO_URL\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Docker image:${NC} $DOCKER_IMAGE:latest\"\n fi\n if [ \"$mode\" = \"source\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Isolation:${NC} Uses OPENCODE_CONFIG_DIR to load from .opencode-review/\"\n fi\n echo \"\"\n}\n\nmain() {\n parse_args \"$@\"\n print_banner\n check_git_repo\n local project_root=$(get_project_root)\n log_info \"Project root: $project_root\"\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"This tool uses isolated .opencode-review/ to avoid conflicts\"\n fi\n if [ -z \"$INSTALL_MODE\" ]; then\n select_install_mode\n fi\n log_info \"Installation mode: $INSTALL_MODE\"\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_info \"Offline mode: enabled\"\n fi\n if [ \"$SKIP_DEPS\" = true ]; then\n log_info \"Skip dependencies: enabled\"\n fi\n echo \"\"\n download_repo\n case \"$INSTALL_MODE\" in\n docker) install_docker_workflow \"$project_root\" ;;\n source)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_source_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n both)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_docker_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n esac\n cleanup\n print_next_steps \"$INSTALL_MODE\"\n}\n\ntrap cleanup EXIT\nmain \"$@\"\n"}, "72aac96e68e12491bf07241da8de56c973293fd8": {"t": 1785748551.7209563, "n": 12377, "h": "0320116bef754761", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# Interactive: curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n# Docker only: curl ... | bash -s -- --docker\n# Source only: curl ... | bash -s -- --source\n# Offline: cd /your/project && /path/to/install.sh --offline --docker\n#\n# Options:\n# --docker Install Docker-based workflow only (recommended)\n# --source Install source-based workflow with .opencode-review/\n# --both Install both installation methods\n# --offline Enable offline mode (use script's directory as source)\n# --skip-deps Skip bun install (useful for offline/CI environments)\n# --help Show help message\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\nDOCKER_IMAGE=\"ghcr.io/ccsert/opencode-review\"\n\n# Installation mode\nINSTALL_MODE=\"\"\n\n# Offline mode settings\nOFFLINE_MODE=false\nSKIP_DEPS=false\n\n# Get the directory where this script is located\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\nparse_args() {\n while [[ $# -gt 0 ]]; do\n case $1 in\n --docker) INSTALL_MODE=\"docker\"; shift ;;\n --source) INSTALL_MODE=\"source\"; shift ;;\n --both) INSTALL_MODE=\"both\"; shift ;;\n --offline) OFFLINE_MODE=true; shift ;;\n --skip-deps) SKIP_DEPS=true; shift ;;\n --help|-h) show_help; exit 0 ;;\n *) log_error \"Unknown option: $1\"; show_help; exit 1 ;;\n esac\n done\n}\n\nshow_help() {\n echo \"\"\n echo \"OpenCode Gitea Review - Installation Script\"\n echo \"\"\n echo \"Usage:\"\n echo \" Online: curl -fsSL $REPO_URL/main/install.sh | bash [options]\"\n echo \" Offline: cd /your/project && /path/to/opencode-review-gitea/install.sh --offline [options]\"\n echo \"\"\n echo \"Options:\"\n echo \" --docker Install Docker-based workflow only (recommended)\"\n echo \" --source Install source-based workflow with .opencode-review/\"\n echo \" --both Install both installation methods\"\n echo \" --offline Enable offline mode (use script's directory as source)\"\n echo \" --skip-deps Skip 'bun install' (useful for offline/CI environments)\"\n echo \" --help Show this help message\"\n echo \"\"\n echo \"Offline Installation:\"\n echo \" 1. Clone repo: git clone $REPO_URL\"\n echo \" 2. In target project: cd /your/project\"\n echo \" 3. Run: /path/to/opencode-review-gitea/install.sh --offline --docker\"\n echo \"\"\n}\n\nprint_banner() {\n echo \"\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo -e \"${CYAN}|${NC} ${BOLD}OpenCode Gitea Review - AI-Powered Code Review${NC} ${CYAN}|${NC}\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo \"\"\n}\n\nselect_install_mode() {\n echo -e \"${BOLD}Select installation method:${NC}\"\n echo \"\"\n echo -e \" ${GREEN}1)${NC} ${BOLD}Docker${NC} (Recommended)\"\n echo \" - Zero files added to your repo (just 1 workflow file)\"\n echo \" - Faster CI (pre-built image, no dependency installation)\"\n echo \" - Automatic updates with :latest tag\"\n echo \"\"\n echo -e \" ${BLUE}2)${NC} ${BOLD}Source${NC}\"\n echo \" - Full control over agents, tools, and configuration\"\n echo \" - Can customize review behavior\"\n echo \" - Adds .opencode-review/ directory (~50KB)\"\n echo \"\"\n echo -e \" ${YELLOW}3)${NC} ${BOLD}Both${NC}\"\n echo \" - Install both methods (Docker workflow + source files)\"\n echo \" - Docker workflow can mount local config for customization\"\n echo \"\"\n \n while true; do\n read -p \"Enter choice [1-3]: \" choice\n case $choice in\n 1) INSTALL_MODE=\"docker\"; break ;;\n 2) INSTALL_MODE=\"source\"; break ;;\n 3) INSTALL_MODE=\"both\"; break ;;\n *) echo \"Invalid choice. Please enter 1, 2, or 3.\" ;;\n esac\n done\n echo \"\"\n}\n\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\nget_project_root() { git rev-parse --show-toplevel; }\n\ncheck_source_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n if ! command -v bun &> /dev/null; then\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_warn \"bun not found. In offline mode, please install bun manually first.\"\n log_warn \"Or use --skip-deps to skip dependency installation.\"\n if [ \"$SKIP_DEPS\" = false ]; then\n exit 1\n fi\n else\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n fi\n}\n\nTMP_DIR=$(mktemp -d)\n\ndownload_repo() {\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_info \"Offline mode: using script directory as source\"\n log_info \"Source: $SCRIPT_DIR\"\n if [ ! -f \"$SCRIPT_DIR/templates/workflow-docker.yaml\" ] && [ ! -f \"$SCRIPT_DIR/templates/workflow-source.yaml\" ]; then\n log_error \"Invalid source: templates/ not found in $SCRIPT_DIR\"\n log_error \"Make sure you're running install.sh from the opencode-review-gitea repo\"\n exit 1\n fi\n # Copy to TMP_DIR for consistent handling\n cp -r \"$SCRIPT_DIR\" \"$TMP_DIR/repo\"\n log_success \"Using local repository\"\n else\n log_info \"Downloading opencode-review-gitea...\"\n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n fi\n}\n\ninstall_docker_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing Docker-based workflow...\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with Docker version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-docker.yaml\" \"$workflow_target\"\n log_success \"Installed Docker workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_source_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing source files...\"\n local target_dir=\"$project_root/.opencode-review\"\n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Updated .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n}\n\ninstall_source_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with source version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-source.yaml\" \"$workflow_target\"\n log_success \"Installed source workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_dependencies() {\n local project_root=\"$1\"\n if [ \"$SKIP_DEPS\" = true ]; then\n log_info \"Skipping dependency installation (--skip-deps)\"\n return\n fi\n if [ -d \"$project_root/.opencode-review\" ]; then\n log_info \"Installing npm dependencies...\"\n cd \"$project_root/.opencode-review\"\n if [ -f \"$HOME/.bun/bin/bun\" ]; then\n \"$HOME/.bun/bin/bun\" install\n elif command -v bun &> /dev/null; then\n bun install\n else\n log_warn \"bun not found, skipping dependency installation\"\n log_warn \"Run 'cd .opencode-review && bun install' manually later\"\n cd - > /dev/null\n return\n fi\n cd - > /dev/null\n log_success \"Dependencies installed\"\n fi\n}\n\ncleanup() { rm -rf \"$TMP_DIR\"; }\n\nprint_next_steps() {\n local mode=\"$1\"\n echo \"\"\n echo -e \"${GREEN}Installation complete!${NC}\"\n echo \"\"\n echo -e \"${BOLD}Next steps:${NC}\"\n echo \"\"\n echo \"1. Configure Gitea/Forgejo Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (default model)\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"both\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea .opencode-review\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker + Source)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"source\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Source)'\"\n echo \" git push\"\n fi\n echo \"\"\n echo \"3. Trigger review by commenting /oc or /opencode on a PR\"\n echo \"\"\n echo -e \"${BOLD}Documentation:${NC} $REPO_URL\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Docker image:${NC} $DOCKER_IMAGE:latest\"\n fi\n if [ \"$mode\" = \"source\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Isolation:${NC} Uses OPENCODE_CONFIG_DIR to load from .opencode-review/\"\n fi\n echo \"\"\n}\n\nmain() {\n parse_args \"$@\"\n print_banner\n check_git_repo\n local project_root=$(get_project_root)\n log_info \"Project root: $project_root\"\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"This tool uses isolated .opencode-review/ to avoid conflicts\"\n fi\n if [ -z \"$INSTALL_MODE\" ]; then\n select_install_mode\n fi\n log_info \"Installation mode: $INSTALL_MODE\"\n if [ \"$OFFLINE_MODE\" = true ]; then\n log_info \"Offline mode: enabled\"\n fi\n if [ \"$SKIP_DEPS\" = true ]; then\n log_info \"Skip dependencies: enabled\"\n fi\n echo \"\"\n download_repo\n case \"$INSTALL_MODE\" in\n docker) install_docker_workflow \"$project_root\" ;;\n source)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_source_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n both)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_docker_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n esac\n cleanup\n print_next_steps \"$INSTALL_MODE\"\n}\n\ntrap cleanup EXIT\nmain \"$@\"\n"}, "891de5c6a04051c6376394cfd7c10b9250a1811c": {"t": 1785748553.1668239, "n": 9651, "h": "83d788ad37de516b", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# Interactive: curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n# Docker only: curl ... | bash -s -- --docker\n# Source only: curl ... | bash -s -- --source\n#\n# Options:\n# --docker Install Docker-based workflow only (recommended)\n# --source Install source-based workflow with .opencode-review/\n# --both Install both installation methods\n# --help Show help message\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\nDOCKER_IMAGE=\"ghcr.io/ccsert/opencode-review\"\n\n# Installation mode\nINSTALL_MODE=\"\"\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\nparse_args() {\n while [[ $# -gt 0 ]]; do\n case $1 in\n --docker) INSTALL_MODE=\"docker\"; shift ;;\n --source) INSTALL_MODE=\"source\"; shift ;;\n --both) INSTALL_MODE=\"both\"; shift ;;\n --help|-h) show_help; exit 0 ;;\n *) log_error \"Unknown option: $1\"; show_help; exit 1 ;;\n esac\n done\n}\n\nshow_help() {\n echo \"\"\n echo \"OpenCode Gitea Review - Installation Script\"\n echo \"\"\n echo \"Usage:\"\n echo \" curl -fsSL $REPO_URL/main/install.sh | bash [options]\"\n echo \"\"\n echo \"Options:\"\n echo \" --docker Install Docker-based workflow only (recommended)\"\n echo \" --source Install source-based workflow with .opencode-review/\"\n echo \" --both Install both installation methods\"\n echo \" --help Show this help message\"\n echo \"\"\n}\n\nprint_banner() {\n echo \"\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo -e \"${CYAN}|${NC} ${BOLD}OpenCode Gitea Review - AI-Powered Code Review${NC} ${CYAN}|${NC}\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo \"\"\n}\n\nselect_install_mode() {\n echo -e \"${BOLD}Select installation method:${NC}\"\n echo \"\"\n echo -e \" ${GREEN}1)${NC} ${BOLD}Docker${NC} (Recommended)\"\n echo \" - Zero files added to your repo (just 1 workflow file)\"\n echo \" - Faster CI (pre-built image, no dependency installation)\"\n echo \" - Automatic updates with :latest tag\"\n echo \"\"\n echo -e \" ${BLUE}2)${NC} ${BOLD}Source${NC}\"\n echo \" - Full control over agents, tools, and configuration\"\n echo \" - Can customize review behavior\"\n echo \" - Adds .opencode-review/ directory (~50KB)\"\n echo \"\"\n echo -e \" ${YELLOW}3)${NC} ${BOLD}Both${NC}\"\n echo \" - Install both methods (Docker workflow + source files)\"\n echo \" - Docker workflow can mount local config for customization\"\n echo \"\"\n \n while true; do\n read -p \"Enter choice [1-3]: \" choice\n case $choice in\n 1) INSTALL_MODE=\"docker\"; break ;;\n 2) INSTALL_MODE=\"source\"; break ;;\n 3) INSTALL_MODE=\"both\"; break ;;\n *) echo \"Invalid choice. Please enter 1, 2, or 3.\" ;;\n esac\n done\n echo \"\"\n}\n\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\nget_project_root() { git rev-parse --show-toplevel; }\n\ncheck_source_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n if ! command -v bun &> /dev/null; then\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n}\n\nTMP_DIR=$(mktemp -d)\n\ndownload_repo() {\n log_info \"Downloading opencode-review-gitea...\"\n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n}\n\ninstall_docker_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing Docker-based workflow...\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with Docker version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-docker.yaml\" \"$workflow_target\"\n log_success \"Installed Docker workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_source_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing source files...\"\n local target_dir=\"$project_root/.opencode-review\"\n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Updated .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n}\n\ninstall_source_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with source version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-source.yaml\" \"$workflow_target\"\n log_success \"Installed source workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_dependencies() {\n local project_root=\"$1\"\n if [ -d \"$project_root/.opencode-review\" ]; then\n log_info \"Installing npm dependencies...\"\n cd \"$project_root/.opencode-review\"\n \"$HOME/.bun/bin/bun\" install\n cd - > /dev/null\n log_success \"Dependencies installed\"\n fi\n}\n\ncleanup() { rm -rf \"$TMP_DIR\"; }\n\nprint_next_steps() {\n local mode=\"$1\"\n echo \"\"\n echo -e \"${GREEN}Installation complete!${NC}\"\n echo \"\"\n echo -e \"${BOLD}Next steps:${NC}\"\n echo \"\"\n echo \"1. Configure Gitea/Forgejo Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (default model)\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"both\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea .opencode-review\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker + Source)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"source\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Source)'\"\n echo \" git push\"\n fi\n echo \"\"\n echo \"3. Trigger review by commenting /oc or /opencode on a PR\"\n echo \"\"\n echo -e \"${BOLD}Documentation:${NC} $REPO_URL\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo -e \"${BLUE}Docker image:${NC} $DOCKER_IMAGE:latest\"\n fi\n if [ \"$mode\" = \"source\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Isolation:${NC} Uses OPENCODE_CONFIG_DIR to load from .opencode-review/\"\n fi\n echo \"\"\n}\n\nmain() {\n parse_args \"$@\"\n print_banner\n check_git_repo\n local project_root=$(get_project_root)\n log_info \"Project root: $project_root\"\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"This tool uses isolated .opencode-review/ to avoid conflicts\"\n fi\n if [ -z \"$INSTALL_MODE\" ]; then\n select_install_mode\n fi\n log_info \"Installation mode: $INSTALL_MODE\"\n echo \"\"\n download_repo\n case \"$INSTALL_MODE\" in\n docker) install_docker_workflow \"$project_root\" ;;\n source)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_source_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n both)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_docker_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n esac\n cleanup\n print_next_steps \"$INSTALL_MODE\"\n}\n\ntrap cleanup EXIT\nmain \"$@\"\n"}, "681c3642775fea55fb3646d5f002fb32d615820f": {"t": 1785748555.4010522, "n": 9650, "h": "0d38c9aa643be3a1", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# Interactive: curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n# Docker only: curl ... | bash -s -- --docker\n# Source only: curl ... | bash -s -- --source\n#\n# Options:\n# --docker Install Docker-based workflow only (recommended)\n# --source Install source-based workflow with .opencode-review/\n# --both Install both installation methods\n# --help Show help message\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\nDOCKER_IMAGE=\"ghcr.io/ccsert/opencode-review\"\n\n# Installation mode\nINSTALL_MODE=\"\"\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\nparse_args() {\n while [[ $# -gt 0 ]]; do\n case $1 in\n --docker) INSTALL_MODE=\"docker\"; shift ;;\n --source) INSTALL_MODE=\"source\"; shift ;;\n --both) INSTALL_MODE=\"both\"; shift ;;\n --help|-h) show_help; exit 0 ;;\n *) log_error \"Unknown option: $1\"; show_help; exit 1 ;;\n esac\n done\n}\n\nshow_help() {\n echo \"\"\n echo \"OpenCode Gitea Review - Installation Script\"\n echo \"\"\n echo \"Usage:\"\n echo \" curl -fsSL $REPO_URL/main/install.sh | bash [options]\"\n echo \"\"\n echo \"Options:\"\n echo \" --docker Install Docker-based workflow only (recommended)\"\n echo \" --source Install source-based workflow with .opencode-review/\"\n echo \" --both Install both installation methods\"\n echo \" --help Show this help message\"\n echo \"\"\n}\n\nprint_banner() {\n echo \"\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo -e \"${CYAN}|${NC} ${BOLD}OpenCode Gitea Review - AI-Powered Code Review${NC} ${CYAN}|${NC}\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo \"\"\n}\n\nselect_install_mode() {\n echo -e \"${BOLD}Select installation method:${NC}\"\n echo \"\"\n echo -e \" ${GREEN}1)${NC} ${BOLD}Docker${NC} (Recommended)\"\n echo \" - Zero files added to your repo (just 1 workflow file)\"\n echo \" - Faster CI (pre-built image, no dependency installation)\"\n echo \" - Automatic updates with :latest tag\"\n echo \"\"\n echo -e \" ${BLUE}2)${NC} ${BOLD}Source${NC}\"\n echo \" - Full control over agents, tools, and configuration\"\n echo \" - Can customize review behavior\"\n echo \" - Adds .opencode-review/ directory (~50KB)\"\n echo \"\"\n echo -e \" ${YELLOW}3)${NC} ${BOLD}Both${NC}\"\n echo \" - Install both methods (Docker workflow + source files)\"\n echo \" - Docker workflow can mount local config for customization\"\n echo \"\"\n \n while true; do\n read -p \"Enter choice [1-3]: \" choice\n case $choice in\n 1) INSTALL_MODE=\"docker\"; break ;;\n 2) INSTALL_MODE=\"source\"; break ;;\n 3) INSTALL_MODE=\"both\"; break ;;\n *) echo \"Invalid choice. Please enter 1, 2, or 3.\" ;;\n esac\n done\n echo \"\"\n}\n\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\nget_project_root() { git rev-parse --show-toplevel; }\n\ncheck_source_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n if ! command -v bun &> /dev/null; then\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n}\n\nTMP_DIR=$(mktemp -d)\n\ndownload_repo() {\n log_info \"Downloading opencode-review-gitea...\"\n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n}\n\ninstall_docker_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing Docker-based workflow...\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with Docker version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-docker.yaml\" \"$workflow_target\"\n log_success \"Installed Docker workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_source_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing source files...\"\n local target_dir=\"$project_root/.opencode-review\"\n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Updated .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n}\n\ninstall_source_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with source version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-source.yaml\" \"$workflow_target\"\n log_success \"Installed source workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_dependencies() {\n local project_root=\"$1\"\n if [ -d \"$project_root/.opencode-review\" ]; then\n log_info \"Installing npm dependencies...\"\n cd \"$project_root/.opencode-review\"\n \"$HOME/.bun/bin/bun\" install\n cd - > /dev/null\n log_success \"Dependencies installed\"\n fi\n}\n\ncleanup() { rm -rf \"$TMP_DIR\"; }\n\nprint_next_steps() {\n local mode=\"$1\"\n echo \"\"\n echo -e \"${GREEN}Installation complete!${NC}\"\n echo \"\"\n echo -e \"${BOLD}Next steps:${NC}\"\n echo \"\"\n echo \"1. Configure Gitea/Forgejo Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (default model)\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"both\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea .opencode-review\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker + Source)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"source\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Source)'\"\n echo \" git push\"\n fi\n echo \"\"\n echo \"3. Trigger review by commenting /oc or /opencode on a PR\"\n echo \"\"\n echo -e \"${BOLD}Documentation:${NC} $REPO_URL\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo -e \"${BLUE}Docker image:${NC} $DOCKER_IMAGE:latest\"\n fi\n if [ \"$mode\" = \"source\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Isolation:${NC} Uses OPENCODE_CONFIG_DIR to load from .opencode-review/\"\n fi\n echo \"\"\n}\n\nmain() {\n parse_args \"$@\"\n print_banner\n check_git_repo\n local project_root=$(get_project_root)\n log_info \"Project root: $project_root\"\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"This tool uses isolated .opencode-review/ to avoid conflicts\"\n fi\n if [ -z \"$INSTALL_MODE\" ]; then\n select_install_mode\n fi\n log_info \"Installation mode: $INSTALL_MODE\"\n echo \"\"\n download_repo\n case \"$INSTALL_MODE\" in\n docker) install_docker_workflow \"$project_root\" ;;\n source)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_source_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n both)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_docker_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n esac\n cleanup\n print_next_steps \"$INSTALL_MODE\"\n}\n\ntrap cleanup EXIT\nmain \"$@\"\n"}, "f5548f5fff3e98bd87c6c256826f161979ba30af": {"t": 1785748556.527622, "n": 9430, "h": "464663c70206c52c", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# Interactive: curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n# Docker only: curl ... | bash -s -- --docker\n# Source only: curl ... | bash -s -- --source\n#\n# Options:\n# --docker Install Docker-based workflow only (recommended)\n# --source Install source-based workflow with .opencode-review/\n# --both Install both installation methods\n# --help Show help message\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\nDOCKER_IMAGE=\"ghcr.io/ccsert/opencode-review\"\n\n# Installation mode\nINSTALL_MODE=\"\"\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\nparse_args() {\n while [[ $# -gt 0 ]]; do\n case $1 in\n --docker) INSTALL_MODE=\"docker\"; shift ;;\n --source) INSTALL_MODE=\"source\"; shift ;;\n --both) INSTALL_MODE=\"both\"; shift ;;\n --help|-h) show_help; exit 0 ;;\n *) log_error \"Unknown option: $1\"; show_help; exit 1 ;;\n esac\n done\n}\n\nshow_help() {\n echo \"\"\n echo \"OpenCode Gitea Review - Installation Script\"\n echo \"\"\n echo \"Usage:\"\n echo \" curl -fsSL $REPO_URL/main/install.sh | bash [options]\"\n echo \"\"\n echo \"Options:\"\n echo \" --docker Install Docker-based workflow only (recommended)\"\n echo \" --source Install source-based workflow with .opencode-review/\"\n echo \" --both Install both installation methods\"\n echo \" --help Show this help message\"\n echo \"\"\n}\n\nprint_banner() {\n echo \"\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo -e \"${CYAN}|${NC} ${BOLD}OpenCode Gitea Review - AI-Powered Code Review${NC} ${CYAN}|${NC}\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo \"\"\n}\n\nselect_install_mode() {\n echo -e \"${BOLD}Select installation method:${NC}\"\n echo \"\"\n echo -e \" ${GREEN}1)${NC} ${BOLD}Docker${NC} (Recommended)\"\n echo \" - Zero files added to your repo (just 1 workflow file)\"\n echo \" - Faster CI (pre-built image, no dependency installation)\"\n echo \" - Automatic updates with :latest tag\"\n echo \"\"\n echo -e \" ${BLUE}2)${NC} ${BOLD}Source${NC}\"\n echo \" - Full control over agents, tools, and configuration\"\n echo \" - Can customize review behavior\"\n echo \" - Adds .opencode-review/ directory (~50KB)\"\n echo \"\"\n echo -e \" ${YELLOW}3)${NC} ${BOLD}Both${NC}\"\n echo \" - Install both methods (Docker workflow + source files)\"\n echo \" - Docker workflow can mount local config for customization\"\n echo \"\"\n \n while true; do\n read -p \"Enter choice [1-3]: \" choice\n case $choice in\n 1) INSTALL_MODE=\"docker\"; break ;;\n 2) INSTALL_MODE=\"source\"; break ;;\n 3) INSTALL_MODE=\"both\"; break ;;\n *) echo \"Invalid choice. Please enter 1, 2, or 3.\" ;;\n esac\n done\n echo \"\"\n}\n\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\nget_project_root() { git rev-parse --show-toplevel; }\n\ncheck_source_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n if ! command -v bun &> /dev/null; then\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n}\n\nTMP_DIR=$(mktemp -d)\n\ndownload_repo() {\n log_info \"Downloading opencode-review-gitea...\"\n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n}\n\ninstall_docker_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing Docker-based workflow...\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with Docker version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-docker.yaml\" \"$workflow_target\"\n log_success \"Installed Docker workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_source_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing source files...\"\n local target_dir=\"$project_root/.opencode-review\"\n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Updated .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n}\n\ninstall_source_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with source version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-source.yaml\" \"$workflow_target\"\n log_success \"Installed source workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_dependencies() {\n local project_root=\"$1\"\n if [ -d \"$project_root/.opencode-review\" ]; then\n log_info \"Installing npm dependencies...\"\n cd \"$project_root/.opencode-review\"\n bun install\n cd - > /dev/null\n log_success \"Dependencies installed\"\n fi\n}\n\ncleanup() { rm -rf \"$TMP_DIR\"; }\n\nprint_next_steps() {\n local mode=\"$1\"\n echo \"\"\n echo -e \"${GREEN}Installation complete!${NC}\"\n echo \"\"\n echo -e \"${BOLD}Next steps:${NC}\"\n echo \"\"\n echo \"1. Configure Gitea/Forgejo Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (default model)\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ] || [ \"$mode\" = \"both\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"source\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Source)'\"\n echo \" git push\"\n fi\n echo \"\"\n echo \"3. Trigger review by commenting /oc or /opencode on a PR\"\n echo \"\"\n echo -e \"${BOLD}Documentation:${NC} $REPO_URL\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo -e \"${BLUE}Docker image:${NC} $DOCKER_IMAGE:latest\"\n fi\n if [ \"$mode\" = \"source\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Isolation:${NC} Uses OPENCODE_CONFIG_DIR to load from .opencode-review/\"\n fi\n echo \"\"\n}\n\nmain() {\n parse_args \"$@\"\n print_banner\n check_git_repo\n local project_root=$(get_project_root)\n log_info \"Project root: $project_root\"\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"This tool uses isolated .opencode-review/ to avoid conflicts\"\n fi\n if [ -z \"$INSTALL_MODE\" ]; then\n select_install_mode\n fi\n log_info \"Installation mode: $INSTALL_MODE\"\n echo \"\"\n download_repo\n case \"$INSTALL_MODE\" in\n docker) install_docker_workflow \"$project_root\" ;;\n source)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_source_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n both)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_docker_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n esac\n cleanup\n print_next_steps \"$INSTALL_MODE\"\n}\n\ntrap cleanup EXIT\nmain \"$@\"\n"}, "d33b398c93fe0265fbe767b10e31c7fd3186de75": {"t": 1785748558.6173337, "n": 9633, "h": "06504f466af4a9a0", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# Interactive: curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n# Docker only: curl ... | bash -s -- --docker\n# Source only: curl ... | bash -s -- --source\n#\n# Options:\n# --docker Install Docker-based workflow only (recommended)\n# --source Install source-based workflow with .opencode-review/\n# --both Install both installation methods\n# --help Show help message\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\nDOCKER_IMAGE=\"ghcr.io/ccsert/opencode-review\"\n\n# Installation mode\nINSTALL_MODE=\"\"\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\nparse_args() {\n while [[ $# -gt 0 ]]; do\n case $1 in\n --docker) INSTALL_MODE=\"docker\"; shift ;;\n --source) INSTALL_MODE=\"source\"; shift ;;\n --both) INSTALL_MODE=\"both\"; shift ;;\n --help|-h) show_help; exit 0 ;;\n *) log_error \"Unknown option: $1\"; show_help; exit 1 ;;\n esac\n done\n}\n\nshow_help() {\n echo \"\"\n echo \"OpenCode Gitea Review - Installation Script\"\n echo \"\"\n echo \"Usage:\"\n echo \" curl -fsSL $REPO_URL/main/install.sh | bash [options]\"\n echo \"\"\n echo \"Options:\"\n echo \" --docker Install Docker-based workflow only (recommended)\"\n echo \" --source Install source-based workflow with .opencode-review/\"\n echo \" --both Install both installation methods\"\n echo \" --help Show this help message\"\n echo \"\"\n}\n\nprint_banner() {\n echo \"\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo -e \"${CYAN}|${NC} ${BOLD}OpenCode Gitea Review - AI-Powered Code Review${NC} ${CYAN}|${NC}\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo \"\"\n}\n\nselect_install_mode() {\n echo -e \"${BOLD}Select installation method:${NC}\"\n echo \"\"\n echo -e \" ${GREEN}1)${NC} ${BOLD}Docker${NC} (Recommended)\"\n echo \" - Zero files added to your repo (just 1 workflow file)\"\n echo \" - Faster CI (pre-built image, no dependency installation)\"\n echo \" - Automatic updates with :latest tag\"\n echo \"\"\n echo -e \" ${BLUE}2)${NC} ${BOLD}Source${NC}\"\n echo \" - Full control over agents, tools, and configuration\"\n echo \" - Can customize review behavior\"\n echo \" - Adds .opencode-review/ directory (~50KB)\"\n echo \"\"\n echo -e \" ${YELLOW}3)${NC} ${BOLD}Both${NC}\"\n echo \" - Install both methods (Docker workflow + source files)\"\n echo \" - Docker workflow can mount local config for customization\"\n echo \"\"\n \n while true; do\n read -p \"Enter choice [1-3]: \" choice\n case $choice in\n 1) INSTALL_MODE=\"docker\"; break ;;\n 2) INSTALL_MODE=\"source\"; break ;;\n 3) INSTALL_MODE=\"both\"; break ;;\n *) echo \"Invalid choice. Please enter 1, 2, or 3.\" ;;\n esac\n done\n echo \"\"\n}\n\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\nget_project_root() { git rev-parse --show-toplevel; }\n\ncheck_source_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n if ! command -v bun &> /dev/null; then\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n}\n\nTMP_DIR=$(mktemp -d)\n\ndownload_repo() {\n log_info \"Downloading opencode-review-gitea...\"\n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n}\n\ninstall_docker_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing Docker-based workflow...\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with Docker version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-docker.yaml\" \"$workflow_target\"\n log_success \"Installed Docker workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_source_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing source files...\"\n local target_dir=\"$project_root/.opencode-review\"\n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Updated .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n}\n\ninstall_source_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with source version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-source.yaml\" \"$workflow_target\"\n log_success \"Installed source workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_dependencies() {\n local project_root=\"$1\"\n if [ -d \"$project_root/.opencode-review\" ]; then\n log_info \"Installing npm dependencies...\"\n cd \"$project_root/.opencode-review\"\n bun install\n cd - > /dev/null\n log_success \"Dependencies installed\"\n fi\n}\n\ncleanup() { rm -rf \"$TMP_DIR\"; }\n\nprint_next_steps() {\n local mode=\"$1\"\n echo \"\"\n echo -e \"${GREEN}Installation complete!${NC}\"\n echo \"\"\n echo -e \"${BOLD}Next steps:${NC}\"\n echo \"\"\n echo \"1. Configure Gitea/Forgejo Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (default model)\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"both\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea .opencode-review\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker + Source)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"source\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Source)'\"\n echo \" git push\"\n fi\n echo \"\"\n echo \"3. Trigger review by commenting /oc or /opencode on a PR\"\n echo \"\"\n echo -e \"${BOLD}Documentation:${NC} $REPO_URL\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo -e \"${BLUE}Docker image:${NC} $DOCKER_IMAGE:latest\"\n fi\n if [ \"$mode\" = \"source\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Isolation:${NC} Uses OPENCODE_CONFIG_DIR to load from .opencode-review/\"\n fi\n echo \"\"\n}\n\nmain() {\n parse_args \"$@\"\n print_banner\n check_git_repo\n local project_root=$(get_project_root)\n log_info \"Project root: $project_root\"\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"This tool uses isolated .opencode-review/ to avoid conflicts\"\n fi\n if [ -z \"$INSTALL_MODE\" ]; then\n select_install_mode\n fi\n log_info \"Installation mode: $INSTALL_MODE\"\n echo \"\"\n download_repo\n case \"$INSTALL_MODE\" in\n docker) install_docker_workflow \"$project_root\" ;;\n source)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_source_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n both)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_docker_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n esac\n cleanup\n print_next_steps \"$INSTALL_MODE\"\n}\n\ntrap cleanup EXIT\nmain \"$@\"\n"}, "e1a9786059c2ae7efe88d99f283279091bf3dc39": {"t": 1785748559.7323806, "n": 9429, "h": "5467a83b9277e865", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# Interactive: curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n# Docker only: curl ... | bash -s -- --docker\n# Source only: curl ... | bash -s -- --source\n#\n# Options:\n# --docker Install Docker-based workflow only (recommended)\n# --source Install source-based workflow with .opencode-review/\n# --both Install both installation methods\n# --help Show help message\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\nDOCKER_IMAGE=\"ghcr.io/ccsert/opencode-review\"\n\n# Installation mode\nINSTALL_MODE=\"\"\n\nlog_info() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nlog_success() { echo -e \"${GREEN}[OK]${NC} $1\"; }\nlog_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nlog_error() { echo -e \"${RED}[ERROR]${NC} $1\"; }\n\nparse_args() {\n while [[ $# -gt 0 ]]; do\n case $1 in\n --docker) INSTALL_MODE=\"docker\"; shift ;;\n --source) INSTALL_MODE=\"source\"; shift ;;\n --both) INSTALL_MODE=\"both\"; shift ;;\n --help|-h) show_help; exit 0 ;;\n *) log_error \"Unknown option: $1\"; show_help; exit 1 ;;\n esac\n done\n}\n\nshow_help() {\n echo \"\"\n echo \"OpenCode Gitea Review - Installation Script\"\n echo \"\"\n echo \"Usage:\"\n echo \" curl -fsSL $REPO_URL/main/install.sh | bash [options]\"\n echo \"\"\n echo \"Options:\"\n echo \" --docker Install Docker-based workflow only (recommended)\"\n echo \" --source Install source-based workflow with .opencode-review/\"\n echo \" --both Install both installation methods\"\n echo \" --help Show this help message\"\n echo \"\"\n}\n\nprint_banner() {\n echo \"\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo -e \"${CYAN}|${NC} ${BOLD}OpenCode Gitea Review - AI-Powered Code Review${NC} ${CYAN}|${NC}\"\n echo -e \"${CYAN}+--------------------------------------------------------------+${NC}\"\n echo \"\"\n}\n\nselect_install_mode() {\n echo -e \"${BOLD}Select installation method:${NC}\"\n echo \"\"\n echo -e \" ${GREEN}1)${NC} ${BOLD}Docker${NC} (Recommended)\"\n echo \" - Zero files added to your repo (just 1 workflow file)\"\n echo \" - Faster CI (pre-built image, no dependency installation)\"\n echo \" - Automatic updates with :latest tag\"\n echo \"\"\n echo -e \" ${BLUE}2)${NC} ${BOLD}Source${NC}\"\n echo \" - Full control over agents, tools, and configuration\"\n echo \" - Can customize review behavior\"\n echo \" - Adds .opencode-review/ directory (~50KB)\"\n echo \"\"\n echo -e \" ${YELLOW}3)${NC} ${BOLD}Both${NC}\"\n echo \" - Install both methods (Docker workflow + source files)\"\n echo \" - Docker workflow can mount local config for customization\"\n echo \"\"\n \n while true; do\n read -p \"Enter choice [1-3]: \" choice\n case $choice in\n 1) INSTALL_MODE=\"docker\"; break ;;\n 2) INSTALL_MODE=\"source\"; break ;;\n 3) INSTALL_MODE=\"both\"; break ;;\n *) echo \"Invalid choice. Please enter 1, 2, or 3.\" ;;\n esac\n done\n echo \"\"\n}\n\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\nget_project_root() { git rev-parse --show-toplevel; }\n\ncheck_source_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n if ! command -v bun &> /dev/null; then\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n}\n\nTMP_DIR=$(mktemp -d)\n\ndownload_repo() {\n log_info \"Downloading opencode-review-gitea...\"\n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n}\n\ninstall_docker_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing Docker-based workflow...\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with Docker version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-docker.yaml\" \"$workflow_target\"\n log_success \"Installed Docker workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_source_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n log_info \"Installing source files...\"\n local target_dir=\"$project_root/.opencode-review\"\n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Updated .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n}\n\ninstall_source_workflow() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists\"\n read -p \"Overwrite with source version? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping workflow installation\"\n return\n fi\n fi\n cp \"$source_dir/templates/workflow-source.yaml\" \"$workflow_target\"\n log_success \"Installed source workflow: .gitea/workflows/opencode-review.yaml\"\n}\n\ninstall_dependencies() {\n local project_root=\"$1\"\n if [ -d \"$project_root/.opencode-review\" ]; then\n log_info \"Installing npm dependencies...\"\n cd \"$project_root/.opencode-review\"\n bun install\n cd - > /dev/null\n log_success \"Dependencies installed\"\n fi\n}\n\ncleanup() { rm -rf \"$TMP_DIR\"; }\n\nprint_next_steps() {\n local mode=\"$1\"\n echo \"\"\n echo -e \"${GREEN}Installation complete!${NC}\"\n echo \"\"\n echo -e \"${BOLD}Next steps:${NC}\"\n echo \"\"\n echo \"1. Configure Gitea/Forgejo Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (default model)\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ] || [ \"$mode\" = \"both\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Docker)'\"\n echo \" git push\"\n fi\n if [ \"$mode\" = \"source\" ]; then\n echo \"2. Commit and push:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode AI Review (Source)'\"\n echo \" git push\"\n fi\n echo \"\"\n echo \"3. Trigger review by commenting /oc or /opencode on a PR\"\n echo \"\"\n echo -e \"${BOLD}Documentation:${NC} $REPO_URL\"\n echo \"\"\n if [ \"$mode\" = \"docker\" ]; then\n echo -e \"${BLUE}Docker image:${NC} $DOCKER_IMAGE:latest\"\n fi\n if [ \"$mode\" = \"source\" ] || [ \"$mode\" = \"both\" ]; then\n echo -e \"${BLUE}Isolation:${NC} Uses OPENCODE_CONFIG_DIR to load from .opencode-review/\"\n fi\n echo \"\"\n}\n\nmain() {\n parse_args \"$@\"\n print_banner\n check_git_repo\n local project_root=$(get_project_root)\n log_info \"Project root: $project_root\"\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"This tool uses isolated .opencode-review/ to avoid conflicts\"\n fi\n if [ -z \"$INSTALL_MODE\" ]; then\n select_install_mode\n fi\n log_info \"Installation mode: $INSTALL_MODE\"\n echo \"\"\n download_repo\n case \"$INSTALL_MODE\" in\n docker) install_docker_workflow \"$project_root\" ;;\n source)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_source_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n both)\n check_source_dependencies\n install_source_files \"$project_root\"\n install_docker_workflow \"$project_root\"\n install_dependencies \"$project_root\"\n ;;\n esac\n cleanup\n print_next_steps \"$INSTALL_MODE\"\n}\n\ntrap cleanup EXIT\nmain \"$@\"\n"}, "88e370f448bcd78a93c2686fe168155cc2149b60": {"t": 1785748560.8268347, "n": 5666, "h": "beef463cc38ec69c", "c": "#!/bin/bash\n#\n# OpenCode Gitea Review - Installation Script\n# Installs the Gitea/Forgejo PR code review tool to your project\n#\n# Usage:\n# curl -fsSL https://raw.githubusercontent.com/ccsert/opencode-review-gitea/main/install.sh | bash\n#\n# This script installs to .opencode-review/ directory (NOT .opencode/)\n# to avoid conflicts with your existing OpenCode configuration.\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m'\n\n# Repository URL\nREPO_URL=\"https://github.com/ccsert/opencode-review-gitea\"\n\nlog_info() {\n echo -e \"${BLUE}[INFO]${NC} $1\"\n}\n\nlog_success() {\n echo -e \"${GREEN}[SUCCESS]${NC} $1\"\n}\n\nlog_warn() {\n echo -e \"${YELLOW}[WARN]${NC} $1\"\n}\n\nlog_error() {\n echo -e \"${RED}[ERROR]${NC} $1\"\n}\n\n# Check if in a git repository\ncheck_git_repo() {\n if ! git rev-parse --git-dir > /dev/null 2>&1; then\n log_error \"Current directory is not a git repository\"\n echo \"Please run this script in your project root directory\"\n exit 1\n fi\n}\n\n# Get project root\nget_project_root() {\n git rev-parse --show-toplevel\n}\n\n# Check dependencies\ncheck_dependencies() {\n if ! command -v git &> /dev/null; then\n log_error \"git is required but not installed\"\n exit 1\n fi\n \n if ! command -v bun &> /dev/null; then\n log_warn \"bun not found, attempting to install...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"$HOME/.bun/bin:$PATH\"\n fi\n}\n\n# Temporary directory\nTMP_DIR=$(mktemp -d)\n\n# Download repository\ndownload_repo() {\n log_info \"Downloading opencode-review-gitea...\"\n \n if command -v git &> /dev/null; then\n git clone --depth 1 \"$REPO_URL.git\" \"$TMP_DIR/repo\" 2>/dev/null || {\n log_warn \"Git clone failed, trying tarball...\"\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n }\n else\n curl -fsSL \"$REPO_URL/archive/main.tar.gz\" | tar -xz -C \"$TMP_DIR\"\n mv \"$TMP_DIR/opencode-review-gitea-main\" \"$TMP_DIR/repo\"\n fi\n}\n\n# Install files\ninstall_files() {\n local project_root=\"$1\"\n local source_dir=\"$TMP_DIR/repo\"\n \n log_info \"Installing to $project_root...\"\n \n # Install .opencode-review directory (isolated from user's .opencode)\n local target_dir=\"$project_root/.opencode-review\"\n \n if [ -d \"$target_dir\" ]; then\n log_warn \".opencode-review already exists\"\n read -p \"Overwrite? [y/N] \" -n 1 -r\n echo\n if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n log_info \"Skipping .opencode-review installation\"\n else\n rm -rf \"$target_dir\"\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n else\n cp -r \"$source_dir/.opencode-review\" \"$target_dir\"\n log_success \"Installed .opencode-review/\"\n fi\n \n # Install Gitea Actions workflow\n mkdir -p \"$project_root/.gitea/workflows\"\n local workflow_target=\"$project_root/.gitea/workflows/opencode-review.yaml\"\n \n if [ -f \"$workflow_target\" ]; then\n log_warn \"Workflow already exists: .gitea/workflows/opencode-review.yaml\"\n read -p \"Overwrite? [y/N] \" -n 1 -r\n echo\n if [[ $REPLY =~ ^[Yy]$ ]]; then\n cp \"$source_dir/.gitea/workflows/opencode-review.yaml\" \"$workflow_target\"\n log_success \"Updated workflow: .gitea/workflows/opencode-review.yaml\"\n fi\n else\n cp \"$source_dir/.gitea/workflows/opencode-review.yaml\" \"$workflow_target\"\n log_success \"Installed workflow: .gitea/workflows/opencode-review.yaml\"\n fi\n}\n\n# Install npm dependencies\ninstall_dependencies() {\n local project_root=\"$1\"\n \n log_info \"Installing npm dependencies...\"\n cd \"$project_root/.opencode-review\"\n bun install\n cd - > /dev/null\n}\n\n# Cleanup\ncleanup() {\n rm -rf \"$TMP_DIR\"\n}\n\n# Print next steps\nprint_next_steps() {\n echo \"\"\n echo -e \"${GREEN}✅ Installation complete!${NC}\"\n echo \"\"\n echo \"📋 Next steps:\"\n echo \"\"\n echo \"1. Configure Gitea Secrets:\"\n echo \" - OPENCODE_GIT_TOKEN: Your Gitea API Token\"\n echo \" - DEEPSEEK_API_KEY: Your LLM API Key (or other provider)\"\n echo \"\"\n echo \"2. Commit changes:\"\n echo \" git add .opencode-review .gitea\"\n echo \" git commit -m 'Add OpenCode Gitea Review'\"\n echo \" git push\"\n echo \"\"\n echo \"3. Use /oc or /opencode in PR comments to trigger review\"\n echo \"\"\n echo \"📚 Docs: https://github.com/ccsert/opencode-review-gitea\"\n echo \"\"\n echo -e \"${BLUE}ℹ️ Isolation:${NC} Uses OPENCODE_CONFIG_DIR environment variable\"\n echo \" to load from .opencode-review/ (won't affect your .opencode/)\"\n echo \" See: https://opencode.ai/docs/config/#custom-directory\"\n echo \"\"\n}\n\n# Main function\nmain() {\n echo \"\"\n echo \"╔══════════════════════════════════════════════════╗\"\n echo \"║ OpenCode Gitea Review - Installation Script ║\"\n echo \"╚══════════════════════════════════════════════════╝\"\n echo \"\"\n \n check_git_repo\n local project_root=$(get_project_root)\n \n log_info \"Project root: $project_root\"\n \n # Check if .opencode exists\n if [ -d \"$project_root/.opencode\" ]; then\n log_info \"Detected existing .opencode/ directory\"\n log_info \"Installing to separate .opencode-review/ directory to avoid conflicts\"\n fi\n \n check_dependencies\n download_repo\n install_files \"$project_root\"\n install_dependencies \"$project_root\"\n cleanup\n print_next_steps\n}\n\n# Error handling\ntrap cleanup EXIT\n\nmain \"$@\"\n"}}}}