RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/CLAUDE.md/MHSanaei/3x-ui

CLAUDE.md

CLAUDE.md
CLAUDE.mdroot

Quality

82/100

Scores the file, not the repository.

Length

1,450 words

8 headings · 0 code blocks

Repository

44k

— · pushed 1 days ago

Last changed

2 days ago

First indexed 3 days ago.
MHSanaei/3x-ui/CLAUDE.mdRawGitHub
1# CLAUDE.md
2 
3Operational guide for AI agents working in this repo. Long-form human docs:
4`CONTRIBUTING.md` (setup, testing philosophy) and `frontend/README.md`.
5Read those before large changes. This file is the short, must-follow version.
6For a deep navigation map (request lifecycle, cron-job table, symptom → file
7index, layering rules), read `docs/architecture.md` on demand — do not guess
8file locations when it can answer in one hop.
9 
10## Stack
11- Backend: Go 1.26 (`module github.com/mhsanaei/3x-ui/v3`), Gin, GORM.
12 Runs Xray-core as a managed child process (`internal/xray/process.go`) and
13 imports `github.com/xtls/xray-core` for config types + gRPC stats/handler/router
14 API. MTProto inbounds run a second managed child — the `mtg-multi` binary
15 (a multi-secret mtg fork — NOT a Go dependency; its prebuilt release binary is
16 fetched at image/release build time by `DockerInit.sh` + `release.yml`,
17 panel-side code in `internal/mtproto/`) — outside Xray, one process per inbound
18 serving each
19 client's FakeTLS secret via the fork's `[secrets]` section (plus per-client
20 ad-tags via `[secret-ad-tags]` and per-client data quota / expiry via
21 `[secret-limits]`, mapped from the client's `totalGB`/`expiryTime`). Client,
22 ad-tag and quota/expiry edits are hot-applied through the fork's management API
23 (`PUT /secrets`, bearer-token guarded) so connections survive; the manager
24 falls back to a process restart on older binaries. A client's panel-side
25 traffic reset also calls `POST /secrets/{name}/reset-quota` so a renewed client
26 is not re-blocked by the sidecar's quota counter.
27- Storage: SQLite by default (`/etc/x-ui/x-ui.db` on Linux; the executable dir on
28 Windows), PostgreSQL optional (`XUI_DB_TYPE` / `XUI_DB_DSN`). The CGo SQLite
29 driver (`mattn/go-sqlite3`) needs a C compiler — `CGO_ENABLED=0` builds fail.
30- Frontend: React 19 + Ant Design 6 + Vite 8 + TypeScript in `frontend/`,
31 built into `internal/web/dist/` (gitignored) and embedded via `embed.FS`.
32 
33## Repo map
34- `main.go` — entry point + `x-ui` CLI (run, migrate, migrate-db, setting, cert).
35- `internal/config/` — env parsing (XUI_DEBUG, XUI_LOG_LEVEL, XUI_LOG_FOLDER,
36 XUI_BIN_FOLDER, XUI_SKIP_HSTS, XUI_PORT, XUI_DB_*).
37- `internal/database/` + `internal/database/model/` — GORM schema (~24 models;
38 Inbound, Client, Setting, User are the core), inbound Protocol enum,
39 AutoMigrate + hand-written migrations in `db.go`.
40- `internal/xray/` — Xray child-process lifecycle, config generation, gRPC API.
41- `internal/mtproto/` — MTProto inbounds via the bundled `mtg-multi` binary.
42- `internal/sub/` — subscription server (raw / JSON / Clash).
43- `internal/eventbus/` — in-process pub/sub (outbound/node health, xray.crash,
44 cpu.high, memory.high, login.attempt).
45- `internal/logger/`, `internal/util/` (link, crypto, sys, ldap, …),
46 `internal/tunnelmonitor/` — shared infrastructure.
47- `internal/web/` — Gin server (embeds `dist/` + `translation/`).
48 - `controller/` — panel + REST API handlers; OpenAPI at /panel/api/openapi.json.
49 - `service/` — business logic (InboundService, SettingService, XrayService,
50 node sync); subpackages tgbot/, email/, outbound/, panel/, integration/.
51 - `job/` — 17 cron jobs (traffic, fail2ban IP-limit, node heartbeat/sync, LDAP,
52 CPU/memory watchdogs, …); full table in `docs/architecture.md` §5.4.
53 - `middleware/`, `entity/`, `global/`, `session/` (CSRF), `network/`,
54 `runtime/` (master/sub-node over mTLS), `websocket/`.
55 - `locale/` + `translation/` — i18n, 13 embedded locale JSON files.
56- `frontend/` — React + TS source (see `frontend/CLAUDE.md`).
57- `tools/openapigen/` — Go generator that emits frontend types + Zod/JSON schemas
58 into `frontend/src/generated/` from Go structs. The OpenAPI doc itself
59 (`frontend/public/openapi.json`) is assembled from those + `endpoints.ts` by
60 `frontend/scripts/build-openapi.mjs`. (`tools/seedperf/` is a separate seeding
61 /load helper.)
62- `docs/` — separate Next.js/Fumadocs site (pnpm, own CI in `docs-ci.yml`,
63 outside `make verify`). Holds a THIRD independent implementation of
64 link/subscription generation in `docs/lib/xray/` — check it whenever
65 share-link or install-command output changes.
66 
67## Hard rules (non-negotiable)
68- Fix size must match bug size. Find the root cause, then make the SMALLEST
69 change that removes it — a one-line guard beats a new subsystem. A small bug
70 does not earn new columns, jobs, abstractions, config knobs or helper layers.
71 If a fix genuinely needs new architecture, say so and get agreement first;
72 never ship it unasked next to the fix.
73- Comments in committed Go/TS: 2 lines MAX per comment block. Make the name
74 carry the meaning first and rename rather than annotate; spend the 2 lines on
75 the *why* a name cannot hold — an invariant, an issue number, a non-obvious
76 constraint. Exempt: `//go:build`, `//go:generate`, and other directives.
77 HTML `<!-- -->` is fine. (A linter cannot enforce this — you must.)
78- New `g.POST`/`g.GET` in `internal/web/controller/` REQUIRES a matching entry
79 in `frontend/src/pages/api-docs/endpoints.ts`, then `make gen` (or
80 `cd frontend && npm run gen`). Hand-maintained but pinned both ways by
81 `TestRouteRegistryContract` (`internal/web/routes_contract_test.go`): a missing
82 OR stale entry fails `make test-go`. Scope: `/panel/api/*` + a few session
83 routes; sub-server routes are exempt.
84- Response examples come from Go struct `example:` tags via `tools/openapigen` —
85 never hand-write them. A new struct must be added to openapigen's `StructAllow`
86 allowlist (`tools/openapigen/main.go`) or it is silently omitted from
87 schemas/examples (and `build-openapi.mjs` then fails on the missing schema).
88- A new or renamed endpoint has a FOURTH step nothing checks: copy
89 `frontend/public/openapi.json` → `docs/public/openapi.json`, then
90 `cd docs && pnpm gen:api` to refresh the MDX under
91 `docs/content/docs/en/reference/api/`. `docs-ci.yml` fires only on `docs/**`.
92- A new English i18n key goes in EVERY locale JSON in `internal/web/translation/`
93 (13 files) AND must be referenced from `frontend/src` or Go in the SAME commit —
94 `frontend/src/test/i18n-dead-keys.test.ts` fails both ways. It is a frontend
95 test, so run `npm test`, not just `make test-go`. At runtime the frontend falls
96 back to en-US; Go (`internal/web/locale/`) returns "" for an unknown key.
97- DB / model changes require a migration in `internal/database/db.go`.
98- Every state-changing inbound/client op dispatches through `runtime.Runtime`
99 (`internal/web/runtime/`) — never straight to `internal/xray/api.go`, never from
100 a controller or cron job. A direct call passes every local test and silently
101 breaks every multi-node deployment. Other layering rules: `docs/architecture.md` §8.
102- Conventional commits: `type(area): short imperative summary`, then a body
103 explaining the why. Types in use: `fix`, `feat`, `chore`, `refactor`, `perf`,
104 `docs`, `style`.
105 
106## Go conventions
107- Stdlib `testing` only (no testify). Table-driven, `t.Run` subtests,
108 `t.Helper()` on helpers. Assert the exact value / typed error / emitted
109 string, never just `err != nil`. Prefer real deps over mocks: throwaway DB via
110 `database.InitDB(filepath.Join(t.TempDir(), "x-ui.db"))` +
111 `t.Cleanup(func() { _ = database.CloseDB() })`; `httptest` for HTTP.
112 `internal/sub`'s `initSubDB(t)` is the template.
113- A test must fail without its fix. Write it, revert the fix, watch it go red,
114 restore. A test that passes either way is worse than no test: it certifies
115 nothing and then gets cited as proof the fix works.
116- Test what can actually break. No test for a getter, a constant, a rename, a
117 pure map lookup, or inputs the function can never receive. One real test that
118 drives the bug through the actual code path beats five that restate the code.
119- Code must pass `golangci-lint run` (gofumpt + goimports formatting): `make lint`.
120- Postgres, xray-gRPC-e2e and scale tests `t.Skip` unless `XUI_TEST_PG_DSN`,
121 `XUI_DB_TYPE`+`XUI_DB_DSN`, `XRAY_E2E_BINARY` or `XUI_SCALE_TEST` is set — a
122 green `go test ./...` does not mean those paths ran.
123 
124## Frontend conventions (summary; full version in frontend/CLAUDE.md)
125- Ant Design 6 only — no Tailwind/shadcn. Targeted tweaks, not rewrites.
126- TS strict; `@typescript-eslint/no-explicit-any` is an error. Zod schemas in
127 `src/schemas/` are the source of truth; infer types with `z.infer`, never
128 hand-write. Do not edit `src/generated/`.
129- Node 24 (`.nvmrc`) — `make gen` imports `.ts` directly and needs its type
130 stripping; Node 22 dies with `ERR_UNKNOWN_FILE_EXTENSION`. `npm test` includes
131 a headless-Chromium Storybook project, so run
132 `npx playwright install --with-deps chromium` once or `make verify` fails.
133- Editing `frontend/src` does NOT change what users see until the Vite build is
134 regenerated into `internal/web/dist/`. In `XUI_DEBUG=true`, HTML is served from
135 the frozen embedded FS but JS/CSS off disk — after `npm run build` you MUST
136 restart `go run .` or you get a blank page with 404s.
137- After touching share-link logic (`src/lib/xray/`), run `npm run test` (golden
138 fixtures); regenerate snapshots (`npx vitest run -u`) only for intentional
139 output changes, never to make a red test green.
140 
141## Build, test, verify
142A fresh clone has no `internal/web/dist/`, so a bare `go build ./...` dies with
143`pattern all:dist: no matching files found` while ~35 other packages pass — it
144reads as a broken repo, not a missing step. Run `make dist-stub` once; every
145`make` Go target already depends on it, which is why `make test-go` beats
146`go test ./...`. Run `make help` for all targets. The local gate:
147 
148 make verify # gen-check + lint + typecheck + test + build + build-storybook
149 
150That is the *fast* gate, not all of CI. `ci.yml` also runs `make race`,
151`make vulncheck`, a live-Postgres job (where a SKIP counts as a failure) and a
15230s fuzz smoke on `FuzzParseLink`/`FuzzDecodeCertPin` — run those locally when
153you touch DB/dialect or parser code.
154 
155Common targets: `make gen` (regenerate Zod/OpenAPI), `make lint` (Go + frontend),
156`make test` (Go `-shuffle=on` + frontend), `make race`, `make build`. See `Makefile`.
157 
158## Definition of done (before opening a PR)
1591. `make verify` passes — its `gen-check` already runs `make gen` and fails on a
160 dirty `frontend/src/generated` / `frontend/public/openapi.json`.
1612. Diff is focused; refactors are separate from feature work.
162 

Commands it names

  • make verify
  • make gen
  • make test-go
  • npm test
  • make lint
  • go test ./...
  • npx playwright install --with-deps chromium
  • npm run build
  • go run .
  • npm run test
  • npx vitest run -u
  • go build ./...
  • make dist-stub
  • make
  • make help
  • make race
  • make vulncheck
  • make test
  • make build

Sections

  • CLAUDE.md
  • Stack
  • Repo map
  • Hard rules (non-negotiable)
  • Go conventions
  • Frontend conventions (summary; full version in frontend/CLAUDE.md)
  • Build, test, verify
  • Definition of done (before opening a PR)

What it covers

buildtestlint-formatcode-stylegit-prdeploymentdo-notagent-behaviour

Stack — with the evidence

go

(1.00)

node

(1.00)

docker

(1.00)

vitest

(0.95)

react

(0.70)

nextjs

(0.70)

tailwind

(0.70)

vite

(0.70)

eslint

(0.70)

typescript

(0.60)

github-actions

(0.60)

javascript

(0.50)

Format

CLAUDE.md

Claude Code's memory file. Shaped like AGENTS.md but with two things it lacks: @path imports, so shared rules live in one place, and a user-scope layer that follows the developer across repos rather than shipping with the code.

What the corpus says about it

Repository

Owner
MHSanaei
Language
—
License
—
Archived
no

All configs in this repo

Also in MHSanaei/3x-ui

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
MHSanaei/3x-uifrontend/CLAUDE.md · 44kCLAUDE.mdtypescriptgo+10buildtestapido-not+283/1003 days ago
Diff against frontend/CLAUDE.md

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
bagisto/bagistoCLAUDE.md · 28kCLAUDE.mdphplaravel+8setupbuildteststyle+5100/1003 days ago
filamentphp/filamentCLAUDE.md · 32kCLAUDE.mdphplaravel+5buildtestlint-formatstyle+7100/1003 days ago
nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4kCLAUDE.mdtypescriptnode+16setupbuildstylearch+2100/1003 days ago
stacklok/toolhiveCLAUDE.md · 2.0kCLAUDE.mdgogithub-actionsbuildteststylearch+4100/1003 days ago
dotCMS/corecore-web/CLAUDE.md · 949CLAUDE.mdjavanode+13teststylearchtesting-strategy+3100/1003 days ago
microsoft/playwrightCLAUDE.md · 94kCLAUDE.mdtypescriptjavascript+10buildtestlint-formatstyle+7100/1003 days ago
Adit-Jain-srm/NightmareNetCLAUDE.md · 45CLAUDE.mdtypescriptpython+18buildtestlint-formatstyle+6100/1003 days ago
dotCMS/coreCLAUDE.md · 949CLAUDE.mdjavanode+9setupbuildteststyle+799/100today
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack