From c7ef2cb810b8026fb530ad12fa5789ca6657a220 Mon Sep 17 00:00:00 2001 From: jason5ng32 Date: Sun, 19 Apr 2026 09:06:13 +0800 Subject: [PATCH] Docs: split AGENTS.md into root + frontend + api; slim CLAUDE.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CLAUDE.md is now a 10-line pointer to AGENTS.md plus a Claude-specific extension slot; everything contributor-facing lives in AGENTS.md. Root AGENTS.md is the index — Overview, Stack, Commands, Project layout, universal Conventions (language / comments / i18n), Testing, a short Security & Boundaries summary, and Workflow. It references @frontend/AGENTS.md and @api/AGENTS.md for area-specific details. frontend/AGENTS.md collects the UI system (primitives, design tokens, status tones, canonical patterns) plus the shadcn-vue-first rule and frontend-specific project layout / conventions. This is what a UI contributor needs — API rules never get in the way. api/AGENTS.md covers the backend handler shape (fetchUpstream, error shape, response normalization), the middleware model (requireReferer globally, requireValidIP per-route, handlers must not repeat those checks), the private-API header pass-through exception, and the smoke test layout. New rules captured across the three files: - Every new file opens with a header comment stating its purpose - Large templates / functions carry block comments on each meaningful section - Big features and modifications to tested features update tests in the same change; `npm run check` must be green before handing off - One concern per commit - Visual changes get an explicit "please test in npm run dev" handoff - User testing must pass before commit - shadcn-vue-first for new UI components (local primitives → shadcn-vue library → hand-rolled Tailwind as last resort) - Every commit scans AGENTS.md for staleness and updates it in the same change if the rules shifted Co-Authored-By: Claude Opus 4.7 (1M context) --- AGENTS.md | 225 ++++++++++++++------------------------------- CLAUDE.md | 17 ++-- api/AGENTS.md | 85 +++++++++++++++++ frontend/AGENTS.md | 153 ++++++++++++++++++++++++++++++ 4 files changed, 313 insertions(+), 167 deletions(-) create mode 100644 api/AGENTS.md create mode 100644 frontend/AGENTS.md diff --git a/AGENTS.md b/AGENTS.md index 2df12e4c..50a8d5cd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,12 @@ # AGENTS.md +Single source of truth for anyone — human or AI — contributing to MyIP. + +For area-specific details, see: + +- Frontend (Vue 3 SPA): @frontend/AGENTS.md +- Backend API (Express): @api/AGENTS.md + ## Overview **MyIP** (IPCheck.ing) is an open-source IP toolbox: IP lookup, connectivity tests, WebRTC / DNS-leak detection, speed test, MTR, Whois, security checklist, browser fingerprint, anonymity checks, and more. @@ -27,155 +34,6 @@ Single repo, two halves: a Vue 3 SPA front-end and an Express 5 back-end API, se | Tests | Node built-in test runner (`node --test`) | | Runtime libs | chart.js · svgmap · @cloudflare/speedtest · maxmind · whoiser · thumbmarkjs · ua-parser-js · detect-gpu · circle-progress.vue | -## Project layout - -``` -. -├── AGENTS.md ← this file (single source of truth) -├── CLAUDE.md ← pointer to AGENTS.md -├── refactor/ ← archived design notes -│ -├── index.html ← #app mounts vaul-drawer-wrapper -├── vite.config.js -├── jsconfig.json ← JS project, alias @ → frontend/ -├── package.json -│ -├── frontend/ ← Vite root -│ ├── App.vue ← thin shell, delegates to composables -│ ├── main.js -│ ├── store.js ← Pinia main store -│ ├── firebase-init.js -│ ├── sw.js ← Serwist service worker -│ ├── router/ ← Advanced Tools subroutes (opens Drawer) -│ ├── locales/ ← i18n copy (en / zh / fr / tr) + security-checklist data -│ ├── style/style.css ← Tailwind v4 entry + design tokens -│ ├── lib/ ← cn() helper (tailwind-merge + clsx) -│ ├── data/ ← static config (achievements / ip-databases / sections / default-preferences) -│ ├── utils/ ← pure helpers (valid-ip / getips / transform-ip-data / shortcut impls / …) -│ ├── composables/ ← reusable composition logic -│ │ ├── use-info-mask.js -│ │ ├── use-refresh-orchestrator.js -│ │ ├── use-scroll-to.js -│ │ ├── use-section-tracking.js -│ │ ├── use-shortcuts.js -│ │ └── use-status-tone.js ← shared 4-tier business-state → visual-color mapping -│ └── components/ -│ ├── *.vue ← top-level sections (IpInfos / Connectivity / WebRTC / DnsLeaks / SpeedTest / Advanced / Footer / Nav / Achievements / User / Additional) -│ ├── ip-infos/ ← IP-card subcomponents (IPCard / ASNInfo / DataPairBar) -│ ├── advanced-tools/ ← 10 tool subpages (MtrTest / GlobalLatencyTest / RuleTest / DnsResolver / CensorshipCheck / Whois / MacChecker / BrowserInfo / InvisibilityTest / SecurityChecklist + Empty) -│ ├── widgets/ ← small reusables (QueryIP / Help / Preferences / InfoMask / PWA / Toast) -│ ├── svgicons/ ← a few inline SVGs -│ └── ui/ ← shadcn-vue copy-in primitives (see UI system) -│ -├── api/ ← backend API handlers -├── common/ ← code shared between front- and back-end (valid-ip / maxmind-db / …) -├── public/ ← static assets -├── tests/ ← Node test runner specs -├── backend-server.js ← Express API (default port 11966) -└── frontend-server.js ← static file server for `npm start` -``` - -## UI system - -### Primitives - -Located at `frontend/components/ui/`. 21 primitives are copied in: - -`accordion` · `badge` · `button` · `button-group` · `card` · `collapsible` · `dialog` (with `DialogHeader`) · `drawer` (vaul-vue) · `dropdown-menu` · `input` · `input-group` · `progress` · `select` · `separator` · `sheet` · `sonner` · `spinner` · `switch` · `tabs` · `toggle-group` · `tooltip` - -Three are project-specific, not in stock shadcn-vue: - -- **`ButtonGroup`** — visual container for stitching buttons together -- **`InputGroup`** — flattens `Input + Button` (or `Input + Select`) into a single bordered control via `[&>input] / [&>button]` passthrough selectors. The group itself carries border / ring / shadow. Use this whenever an input is paired with a trigger button — never hand-roll `rounded-r-none / -ml-px` -- **`Spinner`** — lucide `Loader2` + `animate-spin` + `role="status"` - -Rule: before authoring a ` -``` - -**Input with trigger** — `InputGroup` flattens the pair. `SelectTrigger` renders as a button, so `Select` can swap in for `Input` with no extra work. - -```vue - - - - -``` - -**Status card** — homepage status cards (Connectivity / WebRTC / DnsLeak / IPCard / RuleTest) use: - -```vue - -``` - -`jn-card` is the project marker for shadow / border / keyboard-nav outline. `keyboard-shortcut-card` is the marker that the J/K keyboard-shortcut navigation queries for. - -**Flag** — always use the iconify circle-flags set: - -```vue - -``` - -**Tables vs lists** — two or three columns with independent header semantics → `` with `thead text-xs uppercase tracking-wide text-muted-foreground` + `tbody divide-y` + row `hover:bg-muted/50`. Mobile-friendly rows or asymmetric content with no header meaning → `
    ` + `
  • `. - -**Dialog header** — use the `` primitive to get an icon, title, and DialogClose in one element, matching the Sheet / Drawer header treatment. - -**Drawer** — reserved for the bottom drawer (Advanced Tools panel), via `vaul-vue`. Side panels (right / left) use `Sheet`. The Drawer defaults to `handleOnly: true` (only the top handle is draggable) and CSS is set so body text remains selectable. - -**Motion** — card hover lift: `transition-transform duration-300 ease-out hover:-translate-y-1.5`. Panel fade-slide: scoped `.fade-slide-*` transitions. Loading: ``, not hand-rolled `animate-pulse` dot clusters. - -## Code conventions - -- **JavaScript only.** New files are `.js` / `.vue`; `