# yaml-language-server: $schema=https://schema.zeabur.app/template.json
apiVersion: zeabur.com/v1
kind: Template
metadata:
    name: OpenAB Antigravity
spec:
    description: |
        Deploy OpenAB with Google Antigravity CLI (agy) as a Discord bot. Uses the agy-acp Rust adapter for reliable ACP stdio communication. Supports multi-turn conversations via --continue session continuity.
    coverImage: https://raw.githubusercontent.com/openabdev/openab/main/images/banner.jpg
    icon: https://avatars.githubusercontent.com/u/274127192?v=4
    variables:
        - key: DISCORD_BOT_TOKEN
          type: STRING
          name: Discord Bot Token (optional)
          description: Optional. Token from https://discord.com/developers/applications. Leave empty if using Slack only.
        - key: OPENAB_ALLOWED_CHANNELS
          type: STRING
          name: Discord Channel IDs (optional)
          description: Optional. Comma-separated Discord channel IDs where the bot listens. Leave empty to allow all channels.
        - key: OPENAB_ALLOWED_USERS
          type: STRING
          name: Discord User IDs (optional)
          description: Optional. Comma-separated Discord user IDs allowed to interact with the bot. Leave empty to allow everyone.
        - key: SLACK_BOT_TOKEN
          type: STRING
          name: Slack Bot Token (optional)
          description: Optional. Bot User OAuth Token (xoxb-...) from Slack App settings. Leave empty to disable Slack.
        - key: SLACK_APP_TOKEN
          type: STRING
          name: Slack App Token (optional)
          description: Optional. App-Level Token (xapp-...) for Socket Mode. Required when Slack Bot Token is set.
        - key: OPENAB_ALLOW_BOT_MESSAGES
          type: STRING
          name: Allow Bot Messages (optional)
          description: Optional. Set to 'on' or 'mentions' to allow messages from bots/webhooks. Leave empty to disable.
        - key: OPENAB_TRUSTED_BOT_IDS
          type: STRING
          name: Trusted Bot IDs (optional)
          description: Optional. Comma-separated Discord bot IDs trusted to send messages. Leave empty to trust all bots.
        - key: OPENAB_MAX_SESSIONS
          type: STRING
          name: Max Concurrent Sessions (optional)
          description: 'Optional. Maximum number of concurrent agent sessions (default: 5).'
        - key: OPENAB_AGENT_COMMAND
          type: STRING
          name: Agent Command (optional)
          description: 'Optional. Override the agent CLI command (default: agy-acp). Only change if you know what you''re doing.'
        - key: OPENAB_CONFIG_URL
          type: STRING
          name: Config URL (optional)
          description: Optional. URL to a remote config.toml (https://). When set, the local config file is ignored and this URL is used instead.
    tags:
        - AI
        - Discord Bot
        - Developer Tools
    readme: |
        # OpenAB Antigravity

        One-click deployment of [OpenAB](https://github.com/openabdev/openab) with Google Antigravity CLI as the AI agent backend. This template uses the `agy-acp` Rust adapter for stable stdin/stdout pipe communication.

        ## Important Notes

        - **Image tag:** This template tracks the `beta` tag. To pin a specific version, change the image tag in Zeabur Dashboard → Service → Settings.
        - **Persistent storage:** `/home/agent` is mounted as a persistent volume. Config, auth tokens, and session data survive restarts.
        - **Config location:** `config.toml` is generated at `/home/agent/.config/openab/config.toml` on first boot. Edit it directly after that — env vars are only used for initial setup.

        ## Features

        - Lightweight Rust ACP adapter (`agy-acp`) bridges OpenAB to Google Antigravity CLI
        - Multi-turn conversations via `--continue` session continuity
        - ~5 second response time per prompt
        - Discord bot with emoji reaction status feedback
        - Slack support via Socket Mode

        ## Setup

        ### 1. Create a Discord Bot

        1. Go to [Discord Developer Portal](https://discord.com/developers/applications)
        2. Create a new application and add a Bot
        3. Enable **Message Content Intent** under Privileged Gateway Intents
        4. Copy the bot token and paste it as `DISCORD_BOT_TOKEN`
        5. Go to **OAuth2 → URL Generator** → check scope `bot` → check permissions: Send Messages, Send Messages in Threads, Create Public Threads, Read Message History, Add Reactions, Manage Messages
        6. Invite the bot to your server with the generated URL

        ### 2. Authenticate Antigravity CLI

        After deployment, open the **Exec** tab in Zeabur Dashboard and run:

        ```bash
        agy auth
        ```

        Complete the device flow in your browser. Auth tokens persist in the volume at `~/.gemini/`.

        ### 3. Configure Channels (Optional)

        Set `OPENAB_ALLOWED_CHANNELS` to restrict which channels the bot responds in. Leave empty to allow all channels.

        ## Slack Setup (Optional)

        1. Go to https://api.slack.com/apps → Create New App → From scratch
        2. Enable Socket Mode → generate App-Level Token with scope `connections:write`
        3. Enable Event Subscriptions → add bot events: `app_mention`, `message.channels`, `message.groups`
        4. OAuth & Permissions → add scopes: `app_mentions:read`, `chat:write`, `channels:history`, `groups:history`, `channels:read`, `groups:read`, `reactions:write`, `files:read`, `users:read`
        5. Install App → copy `xoxb-...` token and `xapp-...` token

        ## Customization

        | File | Description |
        |------|-------------|
        | `/home/agent/.config/openab/config.toml` | OpenAB config (sessions, reactions, etc.) |

        To reset config to defaults: `rm /home/agent/.config/openab/config.toml` and restart.

        ## Limitations

        - No streaming — `agy -p` returns the full response at once
        - Cancel is a no-op — `agy -p` runs to completion
        - Session continuity uses `--continue` (resumes most recent conversation per container)

        ## Links

        - [OpenAB GitHub](https://github.com/openabdev/openab)
        - [Agent Client Protocol](https://github.com/anthropics/agent-protocol)
    services:
        - name: openab-antigravity
          icon: https://avatars.githubusercontent.com/u/274127192?v=4
          template: PREBUILT_V2
          spec:
            id: openab-antigravity
            source:
                image: ghcr.io/openabdev/openab:beta-antigravity
                command:
                    - /bin/sh
                    - -c
                    - /opt/start-openab.sh
                runAsUserID: 1000
            volumes:
                - id: agent-home
                  dir: /home/agent
            env:
                DISCORD_BOT_TOKEN:
                    default: ${DISCORD_BOT_TOKEN}
                GATEWAY_PLATFORM:
                    default: ""
                GATEWAY_URL:
                    default: ""
                OPENAB_AGENT_COMMAND:
                    default: agy-acp
                OPENAB_ALLOW_BOT_MESSAGES:
                    default: ""
                OPENAB_ALLOWED_CHANNELS:
                    default: ""
                OPENAB_ALLOWED_USERS:
                    default: ""
                OPENAB_CONFIG_URL:
                    default: ""
                OPENAB_MAX_SESSIONS:
                    default: ""
                OPENAB_TRUSTED_BOT_IDS:
                    default: ""
                SLACK_APP_TOKEN:
                    default: ""
                SLACK_BOT_TOKEN:
                    default: ""
            configs:
                - path: /opt/start-openab.sh
                  template: |
                    #!/bin/sh
                    set -e

                    if [ -z "$DISCORD_BOT_TOKEN" ] && [ -z "$SLACK_BOT_TOKEN" ] && [ -z "$GATEWAY_URL" ]; then
                      echo "openab: no adapter configured (set DISCORD_BOT_TOKEN, SLACK_BOT_TOKEN, or GATEWAY_URL) — sleeping"
                      exec sleep infinity
                    fi

                    CONFIG_DIR=/home/agent/.config/openab
                    CONFIG_FILE=$CONFIG_DIR/config.toml
                    mkdir -p "$CONFIG_DIR"

                    if [ ! -f "$CONFIG_FILE" ]; then
                      cp /opt/config.toml.template "$CONFIG_FILE"

                      if [ -n "$DISCORD_BOT_TOKEN" ]; then
                        printf '\n[discord]\nbot_token = "%s"\n' "$DISCORD_BOT_TOKEN" >> "$CONFIG_FILE"
                        if [ -n "$OPENAB_ALLOW_BOT_MESSAGES" ]; then
                          printf 'allow_bot_messages = "%s"\n' "$OPENAB_ALLOW_BOT_MESSAGES" >> "$CONFIG_FILE"
                        fi
                        if [ -n "$OPENAB_TRUSTED_BOT_IDS" ]; then
                          IFS=','; bots=""; for id in $OPENAB_TRUSTED_BOT_IDS; do id=$(echo "$id" | tr -d ' '); [ -n "$id" ] && bots="${bots}\"${id}\","; done; unset IFS
                          printf 'trusted_bot_ids = [%s]\n' "$(echo "$bots" | sed 's/,$//')" >> "$CONFIG_FILE"
                        fi
                        if [ -n "$OPENAB_ALLOWED_CHANNELS" ]; then
                          IFS=','; channels=""; for id in $OPENAB_ALLOWED_CHANNELS; do id=$(echo "$id" | tr -d ' '); [ -n "$id" ] && channels="${channels}\"${id}\","; done; unset IFS
                          printf 'allowed_channels = [%s]\n' "$(echo "$channels" | sed 's/,$//')" >> "$CONFIG_FILE"
                        fi
                        if [ -n "$OPENAB_ALLOWED_USERS" ]; then
                          IFS=','; users=""; for id in $OPENAB_ALLOWED_USERS; do id=$(echo "$id" | tr -d ' '); [ -n "$id" ] && users="${users}\"${id}\","; done; unset IFS
                          printf 'allowed_users = [%s]\n' "$(echo "$users" | sed 's/,$//')" >> "$CONFIG_FILE"
                        fi
                      fi

                      if [ -n "$SLACK_BOT_TOKEN" ] && [ -n "$SLACK_APP_TOKEN" ]; then
                        printf '\n[slack]\nbot_token = "%s"\napp_token = "%s"\n' "$SLACK_BOT_TOKEN" "$SLACK_APP_TOKEN" >> "$CONFIG_FILE"
                      fi

                      if [ -n "$GATEWAY_URL" ]; then
                        printf '\n[gateway]\nurl = "%s"\nplatform = "%s"\nallow_all_channels = true\nallow_all_users = true\n' "$GATEWAY_URL" "${GATEWAY_PLATFORM:-telegram}" >> "$CONFIG_FILE"
                      fi

                      if [ -n "$OPENAB_MAX_SESSIONS" ]; then
                        printf '\n[pool]\nmax_sessions = %s\n' "$OPENAB_MAX_SESSIONS" >> "$CONFIG_FILE"
                      fi

                      echo "openab: config.toml generated at $CONFIG_FILE"
                    else
                      echo "openab: using existing config.toml (delete to regenerate)"
                    fi

                    exec openab run --config "${OPENAB_CONFIG_URL:-$CONFIG_FILE}"
                  permission: 493
                  envsubst: null
                - path: /opt/config.toml.template
                  template: |
                    [agent]
                    env = { AGY_WORKING_DIR = "/home/agent" }

                    [reactions]
                    enabled = true
                  permission: null
                  envsubst: null
localization:
    es-ES:
        description: |
            Despliega OpenAB con Google Antigravity CLI (agy) como bot de Discord. Usa el adaptador Rust agy-acp para comunicación ACP stdio estable.
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Token del Bot de Discord (opcional)
              description: Opcional. Token desde Discord Developer Portal. Dejar vacío si solo usa Slack.
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: IDs de Canales (opcional)
              description: Opcional. IDs de canales separados por comas. Dejar vacío para permitir todos.
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: IDs de Usuarios (opcional)
              description: Opcional. IDs de usuarios separados por comas. Dejar vacío para permitir todos.
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Token de Bot de Slack (opcional)
              description: Opcional. Bot User OAuth Token (xoxb-...). Dejar vacío para deshabilitar Slack.
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Token de App de Slack (opcional)
              description: Opcional. App-Level Token (xapp-...) para Socket Mode. Requerido con Slack Bot Token.
            - key: OPENAB_ALLOW_BOT_MESSAGES
              type: STRING
              name: Permitir Mensajes de Bot (opcional)
              description: Opcional. Establecer 'on' o 'mentions' para permitir mensajes de bots. Dejar vacío para deshabilitar.
            - key: OPENAB_TRUSTED_BOT_IDS
              type: STRING
              name: IDs de Bots Confiables (opcional)
              description: Opcional. IDs de bots confiables separados por comas. Dejar vacío para confiar en todos.
            - key: OPENAB_MAX_SESSIONS
              type: STRING
              name: Sesiones Concurrentes Máximas (opcional)
              description: 'Opcional. Número máximo de sesiones concurrentes (por defecto: 5).'
        readme: |
            # OpenAB Antigravity

            Despliegue con un clic de OpenAB con Google Antigravity CLI.

            ## Configuración

            1. Crear bot en Discord Developer Portal
            2. Habilitar **Message Content Intent**
            3. Después del despliegue, ejecutar `agy auth` en la pestaña Exec

            ## Limitaciones

            - Sin streaming
            - Cancelar es no-op
            - Continuidad de sesión usa `--continue`
    id-ID:
        description: |
            Deploy OpenAB dengan Google Antigravity CLI (agy) sebagai bot Discord. Menggunakan adapter Rust agy-acp untuk komunikasi ACP stdio yang stabil.
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Token Bot Discord (opsional)
              description: Opsional. Token dari Discord Developer Portal. Kosongkan jika hanya menggunakan Slack.
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: ID Channel (opsional)
              description: Opsional. ID channel dipisah koma. Kosongkan untuk mengizinkan semua.
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: ID Pengguna (opsional)
              description: Opsional. ID pengguna dipisah koma. Kosongkan untuk mengizinkan semua.
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Token Bot Slack (opsional)
              description: Opsional. Bot User OAuth Token (xoxb-...). Kosongkan untuk menonaktifkan Slack.
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Token App Slack (opsional)
              description: Opsional. App-Level Token (xapp-...) untuk Socket Mode. Diperlukan saat Slack Bot Token diatur.
            - key: OPENAB_ALLOW_BOT_MESSAGES
              type: STRING
              name: Izinkan Pesan Bot (opsional)
              description: Opsional. Atur 'on' atau 'mentions' untuk mengizinkan pesan bot. Kosongkan untuk menonaktifkan.
            - key: OPENAB_TRUSTED_BOT_IDS
              type: STRING
              name: ID Bot Terpercaya (opsional)
              description: Opsional. ID bot terpercaya dipisah koma. Kosongkan untuk mempercayai semua bot.
            - key: OPENAB_MAX_SESSIONS
              type: STRING
              name: Sesi Bersamaan Maksimum (opsional)
              description: 'Opsional. Jumlah maksimum sesi agen bersamaan (default: 5).'
        readme: |
            # OpenAB Antigravity

            Deploy satu klik OpenAB dengan Google Antigravity CLI.

            ## Pengaturan

            1. Buat bot di Discord Developer Portal
            2. Aktifkan **Message Content Intent**
            3. Setelah deploy, jalankan `agy auth` di tab Exec

            ## Keterbatasan

            - Tidak ada streaming
            - Batalkan adalah no-op
            - Kontinuitas sesi menggunakan `--continue`
    ja-JP:
        description: |
            OpenAB と Google Antigravity CLI (agy) を Discord ボットとしてデプロイします。agy-acp Rust アダプターによる安定した ACP stdio 通信をサポートします。
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Discord ボットトークン（オプション）
              description: オプション。Discord Developer Portal から取得したトークン。Slack のみ使用する場合は空欄でも可。
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: Discord チャンネル ID（オプション）
              description: オプション。Bot が監視する Discord チャンネル ID（カンマ区切り）。空の場合、全チャンネルで応答。
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: Discord ユーザー ID（オプション）
              description: オプション。Bot と対話できるユーザー ID（カンマ区切り）。空の場合、全員が利用可能。
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Slack Bot トークン（オプション）
              description: オプション。Bot User OAuth Token（xoxb-...）。空の場合、Slack は無効。
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Slack App トークン（オプション）
              description: オプション。Socket Mode 用の App-Level Token（xapp-...）。Slack Bot Token 設定時は必須。
            - key: OPENAB_ALLOW_BOT_MESSAGES
              type: STRING
              name: Bot メッセージ許可（オプション）
              description: オプション。'on' または 'mentions' に設定して bot メッセージを許可。空の場合は無効。
            - key: OPENAB_TRUSTED_BOT_IDS
              type: STRING
              name: 信頼する Bot ID（オプション）
              description: オプション。信頼する Bot ID（カンマ区切り）。空の場合は全 bot を信頼。
            - key: OPENAB_MAX_SESSIONS
              type: STRING
              name: 最大同時セッション数（オプション）
              description: オプション。最大同時 agent セッション数（デフォルト：5）。
        readme: |
            # OpenAB Antigravity

            [OpenAB](https://github.com/openabdev/openab) と Google Antigravity CLI をワンクリックデプロイ。

            ## セットアップ

            1. [Discord Developer Portal](https://discord.com/developers/applications) で Bot を作成
            2. **Message Content Intent** を有効化
            3. デプロイ後、**Exec** タブで `agy auth` を実行

            ## 制限事項

            - ストリーミング非対応
            - キャンセルは無効
            - セッション継続は `--continue` を使用
    zh-CN:
        description: |
            部署 OpenAB 搭配 Google Antigravity CLI (agy) 作为 Discord 机器人。使用 agy-acp Rust 适配器进行稳定的 ACP stdio 通信，支持通过 --continue 延续多轮对话。
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Discord 机器人 Token（选填）
              description: 选填。从 Discord Developer Portal 获取的 Token。仅使用 Slack 时可留空。
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: Discord 频道 ID（选填）
              description: 选填。Bot 监听的 Discord 频道 ID，以逗号分隔。留空则允许所有频道。
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: Discord 用户 ID（选填）
              description: 选填。以逗号分隔的 Discord 用户 ID。留空则允许所有人。
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Slack Bot Token（选填）
              description: 选填。Slack App 的 Bot User OAuth Token（xoxb-...）。留空则禁用 Slack。
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Slack App Token（选填）
              description: 选填。Socket Mode 用的 App-Level Token（xapp-...）。设置 Slack Bot Token 时必填。
            - key: OPENAB_ALLOW_BOT_MESSAGES
              type: STRING
              name: 允许 Bot 消息（选填）
              description: 选填。设为 'on' 或 'mentions' 以允许 bot 消息触发。留空则禁用。
            - key: OPENAB_TRUSTED_BOT_IDS
              type: STRING
              name: 信任的 Bot ID（选填）
              description: 选填。以逗号分隔的信任 Bot ID。留空则信任所有 bot。
            - key: OPENAB_MAX_SESSIONS
              type: STRING
              name: 最大并行 Session 数（选填）
              description: 选填。最大并行 agent session 数量（默认：5）。
        readme: |
            # OpenAB Antigravity

            一键部署 [OpenAB](https://github.com/openabdev/openab) 搭配 Google Antigravity CLI 作为 AI 代理后端。

            ## 注意事项

            - **持久化存储：** `/home/agent` 挂载为持久化磁盘。Config 和认证 Token 会在重启后保留。
            - **Config 位置：** 首次启动时生成于 `/home/agent/.config/openab/config.toml`。之后直接编辑即可。

            ## 设置

            1. 前往 [Discord Developer Portal](https://discord.com/developers/applications) 创建 Bot
            2. 启用 **Message Content Intent**
            3. 部署后在 **Exec** 分页执行 `agy auth`

            ## 限制

            - 不支持流式传输 — `agy -p` 一次返回完整响应
            - 取消为空操作 — `agy -p` 会执行到完成
            - 对话延续使用 `--continue`
    zh-TW:
        description: |
            部署 OpenAB 搭配 Google Antigravity CLI (agy) 作為 Discord 機器人。使用 agy-acp Rust 適配器進行穩定的 ACP stdio 通訊，支援透過 --continue 延續多輪對話。
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Discord 機器人 Token（選填）
              description: 選填。從 Discord Developer Portal 取得的 Token。僅使用 Slack 時可留空。
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: Discord 頻道 ID（選填）
              description: 選填。Bot 監聽的 Discord 頻道 ID，以逗號分隔。留空則允許所有頻道。
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: Discord 用戶 ID（選填）
              description: 選填。以逗號分隔的 Discord 用戶 ID。留空則允許所有人。
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Slack Bot Token（選填）
              description: 選填。Slack App 的 Bot User OAuth Token（xoxb-...）。留空則停用 Slack。
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Slack App Token（選填）
              description: 選填。Socket Mode 用的 App-Level Token（xapp-...）。設定 Slack Bot Token 時必填。
            - key: OPENAB_ALLOW_BOT_MESSAGES
              type: STRING
              name: 允許 Bot 訊息（選填）
              description: 選填。設為 'on' 或 'mentions' 以允許 bot 訊息觸發。留空則停用。
            - key: OPENAB_TRUSTED_BOT_IDS
              type: STRING
              name: 信任的 Bot ID（選填）
              description: 選填。以逗號分隔的信任 Bot ID。留空則信任所有 bot。
            - key: OPENAB_MAX_SESSIONS
              type: STRING
              name: 最大並行 Session 數（選填）
              description: 選填。最大並行 agent session 數量（預設：5）。
        readme: |
            # OpenAB Antigravity

            一鍵部署 [OpenAB](https://github.com/openabdev/openab) 搭配 Google Antigravity CLI 作為 AI 代理後端。

            ## 注意事項

            - **持久化儲存：** `/home/agent` 掛載為持久化磁碟。Config 和認證 Token 會在重啟後保留。
            - **Config 位置：** 首次啟動時生成於 `/home/agent/.config/openab/config.toml`。之後直接編輯即可。

            ## 設定

            1. 前往 [Discord Developer Portal](https://discord.com/developers/applications) 建立 Bot
            2. 啟用 **Message Content Intent**
            3. 部署後在 **Exec** 分頁執行 `agy auth`

            ## 限制

            - 不支援串流 — `agy -p` 一次回傳完整回應
            - 取消為空操作 — `agy -p` 會執行到完成
            - 對話延續使用 `--continue`
