Browse Source

fix(ci): keep the triage prompt under the 21000-char expression cap

The previous commit pushed handle-issue's prompt to 21587 characters and
GitHub stopped parsing the file: "(Line: 39, Col: 19): Exceeded max
expression length 21000". Because the prompt interpolates ${{ }}, GitHub
treats the whole block scalar as a single expression, and the cap applies
per expression. The failure mode is quiet and total - no job fails,
the workflow itself disappears, its registered name reverts from "Claude
Bot" to the file path, and the only signal is a run attributed to the
push with no jobs in it.

Drop the hand-written stack description, repository map and runtime-fact
list from that prompt and point at CLAUDE.md and docs/architecture.md
instead. Both are maintained, both are already in the checkout, and the
copy in the prompt had drifted from them anyway - it still described the
mtg worker, omitted internal/tunnelmonitor/ and memory.high, and filed
internal/web/runtime/ under "wiring". Only the support-facing facts that
live in neither file are kept: the install one-liner, the random initial
credentials, the distro-dependent env file, the Docker image and the
capabilities fail2ban needs.

handle-issue is now 15069 characters, and a header comment records the
limit so the next edit does not rediscover it in production.
Sanaei 12 hours ago
parent
commit
35cf6be6f9
1 changed files with 47 additions and 153 deletions
  1. 47 153
      .github/workflows/claude-bot.yml

+ 47 - 153
.github/workflows/claude-bot.yml

@@ -1,5 +1,12 @@
 name: Claude Bot
 
+# Each prompt: / claude_args: value below interpolates ${{ }}, so GitHub parses
+# the whole block scalar as ONE expression and caps it at 21000 characters.
+# Going over does not fail a job - the entire workflow stops parsing and
+# vanishes from Actions, with the run reported only as a workflow file issue.
+# Keep every prompt well under the cap; put shared context in CLAUDE.md and
+# docs/architecture.md, which are in the checkout, instead of pasting it here.
+
 on:
   issues:
     types: [opened]
@@ -48,165 +55,52 @@ jobs:
             open a pull request.
 
             REPOSITORY CONTEXT
-            The repo source is in the working directory. READ IT with
-            Read/Glob/Grep instead of assuming.
-
-            Stack:
-            - Backend: Go 1.26 (module github.com/mhsanaei/3x-ui/v3), Gin,
-              GORM. The panel runs Xray-core as a separately managed child
-              process (internal/xray/process.go) and also imports
-              github.com/xtls/xray-core as a library for config types and its
-              gRPC stats/handler API.
-            - Storage: SQLite by default (file at /etc/x-ui/x-ui.db);
-              PostgreSQL optional. Backend chosen at runtime via env vars.
-            - Frontend: React 19 + Ant Design 6 + Vite 8 + TypeScript in
-              frontend/, built into internal/web/dist/, which the Go server
-              embeds and serves. The old Go HTML templates and web/assets/
-              tree no longer exist.
-
-            Repository map:
-            - main.go                  entry point + the `x-ui` management CLI
-                                       (subcommands: run, migrate, migrate-db,
-                                       setting, cert, ...)
-            - internal/config/         embedded name/version, env parsing
-                                       (XUI_DEBUG, XUI_LOG_LEVEL, XUI_LOG_FOLDER,
-                                       XUI_BIN_FOLDER, XUI_SKIP_HSTS, XUI_DB_*)
-            - internal/database/       GORM init, migrations, SQLite->PostgreSQL
-                                       data migration
-              - internal/database/model/  models: Inbound, Client, Setting,
-                                       User, ... and the inbound Protocol enum
-                                       (model.go)
-            - internal/mtproto/        MTProto (Telegram) proxy inbounds: manages
-                                       one bundled `mtg-multi` child per inbound
-                                       (a multi-secret fork), serving each
-                                       client's FakeTLS secret, ad-tag and
-                                       quota/expiry; edits are hot-applied over
-                                       its management API
-            - internal/sub/            subscription server (client subscription
-                                       output, custom templates)
-            - internal/xray/           Xray-core child-process lifecycle, config
-                                       generation, gRPC API (stats, online
-                                       clients)
-            - internal/eventbus/       in-process pub/sub event bus (events.go
-                                       defines outbound up/down, xray.crash,
-                                       node up/down, cpu.high, memory.high,
-                                       login.attempt); tgbot and jobs
-                                       publish/subscribe
-            - internal/tunnelmonitor/  tunnel health watchdog (XUI_TUNNEL_HEALTH_*)
-            - internal/logger/, internal/util/   logging + shared helpers
-            - internal/web/            Gin HTTP/HTTPS server (web.go embeds
-                                       dist/ and translation/)
-              - internal/web/controller/   route handlers: panel pages AND the
-                                       JSON/REST API; OpenAPI spec served at
-                                       /panel/api/openapi.json
-              - internal/web/service/  business logic (InboundService,
-                                       SettingService, XrayService, node sync,
-                                       ...); subpackages: tgbot/ (Telegram bot),
-                                       email/ (SMTP notifications), outbound/,
-                                       panel/, integration/
-              - internal/web/job/      cron jobs (traffic accounting, IP-limit /
-                                       fail2ban, node heartbeat + traffic sync,
-                                       LDAP sync, MTProto, stats notify, ...)
-              - internal/web/middleware/   Gin middleware (auth, redirect,
-                                       domain checks)
-              - internal/web/entity/   request/response structs for the web layer
-              - internal/web/global/   cross-package access to web/sub servers
-              - internal/web/session/  cookie sessions + CSRF protection
-              - internal/web/locale/   i18n engine (go-i18n);
-                internal/web/translation/  the 13 embedded locale JSON files
-              - internal/web/runtime/   master/sub-node dispatch over mTLS
-                                       (runtime.go interface, local.go,
-                                       remote.go, manager.go, tls_client.go).
-                                       EVERY state-changing inbound/client
-                                       operation goes through it; bypassing it
-                                       silently breaks multi-node deployments
-              - internal/web/network/, internal/web/websocket/   net helpers,
-                                       live push
-              - internal/web/dist/     embedded Vite build of the React frontend
-                                       + generated openapi.json
-            - frontend/                React + TypeScript source (src/pages,
-                                       src/components, src/api, src/i18n, ...)
-            - tools/openapigen/        Go generator for the OpenAPI spec and
-                                       frontend API types
-            - docs/architecture.md     THE maintained code map: request
-                                       lifecycle, cron-job table, data model,
-                                       layering rules, and a "Symptom -> File"
-                                       index. Read it before grepping.
-            - docs/content/docs/{en,ru,fa,zh}/   the official documentation site
-                                       (guide/installation, guide/first-login,
-                                       help/faq, help/troubleshooting,
-                                       help/migration, operations/multi-node,
-                                       operations/backup-restore, config/,
-                                       reference/). Link the relevant page when
-                                       a question is already answered there.
-            - CLAUDE.md                the project's own rules for agents
-            - install.sh, update.sh, x-ui.sh, x-ui.service.*  install/upgrade
-              + systemd units
-            - Dockerfile, docker-compose.yml, DockerEntrypoint.sh, DockerInit.sh
-            - windows_files/, x-ui.rc  Windows support files. (A top-level
-              x-ui/ folder, if present, is gitignored local runtime data, not
-              source.)
-
-            Runtime facts (accurate as written; use them directly, no need to
-            re-derive them from source):
+            The full repo is checked out in the working directory. Two files in
+            it are maintained and authoritative - read them rather than relying
+            on any map reproduced in this prompt:
+            - CLAUDE.md             stack, repo layout, hard rules, conventions.
+            - docs/architecture.md  request lifecycle, cron-job table, data
+                                    model, layering rules, and a "Symptom ->
+                                    File" index. For "which file handles X" it
+                                    answers in one hop; grepping blind wastes
+                                    turns.
+            User-facing docs live in docs/content/docs/{en,ru,fa,zh}/
+            (guide/installation, guide/first-login, help/faq,
+            help/troubleshooting, help/migration, operations/multi-node,
+            operations/backup-restore, config/, reference/). If a question is
+            already answered there, link that page.
+
+            Support facts that are NOT in those files:
             - Linux install: bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
-            - Windows is also a supported platform (see README "Supported
-              Platforms" and windows_files/).
-            - Management menu: run `x-ui` on the server.
-            - Install generates a RANDOM username, password and web base path
-              (NOT admin/admin); `x-ui` can show/reset them.
-            - SQLite DB on Linux: /etc/x-ui/x-ui.db (folder overridable via
-              XUI_DB_FOLDER). On Windows the DB lives in the executable's
-              directory, not /etc - never quote the Linux path to a Windows user.
-            - Installer env/config file is DISTRO-DEPENDENT: /etc/default/x-ui
+            - Windows is supported (README "Supported Platforms",
+              windows_files/). On Windows the DB sits next to the executable,
+              not in /etc - never quote the Linux path to a Windows user.
+            - Management menu: run `x-ui` on the server. Install generates a
+              RANDOM username, password and web base path (NOT admin/admin);
+              `x-ui` can show or reset them.
+            - The installer env file is DISTRO-DEPENDENT: /etc/default/x-ui
               (Debian/Ubuntu), /etc/conf.d/x-ui (Arch), /etc/sysconfig/x-ui
-              (RHEL/Fedora/Alma/Rocky). Ask which distro, or say "the service
-              environment file for your distro" - naming the wrong one means the
-              user's edit is silently never read by systemd.
-            - Env vars: the list below is the common subset, NOT the complete
-              set. The panel also parses XUI_PORT, XUI_MAIN_FOLDER, XUI_GOGC,
-              XUI_MEMORY_LIMIT, XUI_PPROF, XUI_NONINTERACTIVE and the
-              XUI_TUNNEL_HEALTH_* family (monitor, url, interval, timeout,
-              failures, cooldown - the answer to "the panel restarts Xray every
-              few minutes"). NEVER tell a user a XUI_* variable does not exist
-              without grepping internal/config/ and internal/tunnelmonitor/ first.
-              Common subset: XUI_DB_TYPE (sqlite|postgres, default sqlite),
-              XUI_DB_DSN, XUI_DB_FOLDER (default /etc/x-ui),
-              XUI_DB_MAX_OPEN_CONNS, XUI_DB_MAX_IDLE_CONNS,
-              XUI_INIT_WEB_BASE_PATH (default /), XUI_ENABLE_FAIL2BAN (default
-              true), XUI_LOG_LEVEL (default info), XUI_LOG_FOLDER,
-              XUI_BIN_FOLDER, XUI_SKIP_HSTS, XUI_DEBUG.
-            - SQLite -> PostgreSQL: `x-ui migrate-db --dsn "postgres://..."`, then
-              set XUI_DB_TYPE/XUI_DB_DSN in the service environment file for the
-              user's distro and `systemctl restart x-ui`. The source SQLite file
-              is left in place.
+              (RHEL/Fedora). Ask which distro, or say "the service environment
+              file for your distro" - naming the wrong one means the user's
+              edit is silently never read by systemd.
+            - SQLite -> PostgreSQL: `x-ui migrate-db --dsn "postgres://..."`,
+              then set XUI_DB_TYPE/XUI_DB_DSN in that file and
+              `systemctl restart x-ui`. The source SQLite file is left in place.
             - Docker image: ghcr.io/mhsanaei/3x-ui. PostgreSQL profile:
               `docker compose --profile postgres up -d`. Fail2ban IP-limit
-              enforcement needs NET_ADMIN + NET_RAW (compose grants them via
-              cap_add; a bare `docker run` must add
-              `--cap-add=NET_ADMIN --cap-add=NET_RAW`).
-            - Protocols (inbound Protocol enum in internal/database/model/model.go):
-              VLESS, VMess, Trojan, Shadowsocks, WireGuard, Hysteria2 (stored
-              as protocol "hysteria" with stream version 2), HTTP, SOCKS
-              ("mixed"), Dokodemo-door ("tunnel"), MTProto (runs via the
-              bundled mtg-multi binary, internal/mtproto/). TUN is also
-              supported via Xray inbound settings in the UI.
-            - Transports: TCP (Raw), mKCP, WebSocket, gRPC, HTTPUpgrade, XHTTP.
-              Security options the panel offers per inbound: none, tls, reality.
-              XTLS is a VLESS *flow* (xtls-rprx-vision), not a security setting -
-              do not tell a user to select XTLS in the security dropdown.
-              Fallbacks supported.
-            - REST API: OpenAPI 3 spec generated at frontend build time and
-              served at /panel/api/openapi.json; in-panel API docs page
-              (Swagger UI). Telegram bot (internal/web/service/tgbot/) for
-              remote management. Multi-node support (node controller/services
-              + heartbeat and traffic-sync jobs). LDAP integration (go-ldap +
-              ldap_sync_job.go). 13 UI languages.
+              enforcement needs NET_ADMIN + NET_RAW (compose grants them; a bare
+              `docker run` must add --cap-add=NET_ADMIN --cap-add=NET_RAW).
+            - NEVER tell a user a XUI_* variable does not exist without grepping
+              internal/config/ and internal/tunnelmonitor/ first. The
+              XUI_TUNNEL_HEALTH_* family is the answer to "the panel restarts
+              Xray every few minutes".
+            - Security per inbound is none / tls / reality. XTLS is a VLESS
+              *flow* (xtls-rprx-vision), not a security setting - never tell
+              anyone to pick XTLS in the security dropdown.
             - DO NOT hardcode a version. For version or "is this already fixed"
-              questions, check the latest release and recent history with gh
-              (e.g. `gh release list -L 5`,
+              questions use `gh release list -L 5`,
               `gh search commits --repo ${{ github.repository }} "<keywords>"`,
-              and `gh search issues --repo ${{ github.repository }} "<keywords>" --state closed`).
+              and `gh search issues --repo ${{ github.repository }} "<keywords>" --state closed`.
 
             COMMENT STYLE (applies to EVERY comment you post in any step):
             - Professional, courteous, and matter-of-fact. No emoji, no