MyIP (Agent Skills)

GitHub

The best IP Toolbox. Check your IP address & geolocation, test IP for WebRTC and DNS IP leaks, run an IP quality check, browser fingerprint check, website availability check, network speed test, global latency test, MTR test, Whois search, and more.

AGENTS.md

# AGENTS.md

Single source of truth for anyone β€” human or AI β€” contributing to MyIP.
Area-specific details: @frontend/AGENTS.md (Vue SPA) Β· @api/AGENTS.md (Express API).

## 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. Single repo, two
halves: a Vue 3 SPA front-end and an Express 5 back-end API.

## Stack

| Layer | Technology |
|---|---|
| Frontend | Vue 3 (`<script setup>`) Β· Pinia Β· vue-router (HTML5 history) Β· vue-i18n (`en`/`zh`/`fr`/`ru`) |
| Build | Vite + `@vitejs/plugin-vue`; Tailwind CSS v4 + `tw-animate-css` |
| UI | shadcn-vue copy-in primitives (reka-ui) Β· lucide icons Β· circle-flags via `@iconify/vue` Β· vaul-vue drawer Β· vue-sonner toast |
| Backend | Express 5 |
| Logger | `pino` singleton at `common/logger.js` (+ `pino-http`, opt-in) |
| Auth | Firebase Auth (optional, env-gated) |
| Error monitoring | Sentry β€” optional & env-gated on both halves: `@sentry/vue` (no `VITE_SENTRY_DSN_FRONTEND`, no Sentry in the build β€” see frontend/AGENTS.md) + `@sentry/node` (no `SENTRY_DSN_BACKEND`, never loaded β€” see api/AGENTS.md) |
| PWA | `manifest.webmanifest` only β€” installable but online-only, no service worker |
| Tests | Node built-in test runner (`node --test`) |
| Runtime libs | chart.js Β· chartjs-chart-geo Β· @cloudflare/speedtest Β· maxmind Β· whoiser Β· thumbmarkjs Β· ua-parser-js Β· detect-gpu Β· @vueuse/core |

## Commands

| Command | What it does |
|---|---|
| `pnpm dev` | Vite + backend (nodemon) together |
| `pnpm build` | Front-end production build |
| `pnpm preview` | Vite preview of the build output |
| `pnpm start` | Built front-end + backend |
| `pnpm test` | Run all `tests/*.test.js` specs |
| `pnpm check` | `test` + `build` β€” the pre-commit self-check |

**pnpm only** (pinned via `packageManager`); `pnpm-lock.yaml` is committed and
`pnpm-workspace.yaml` holds the `allowBuilds` install-script approvals. Never
use npm / yarn β€” they'd produce a competing lockfile.

## Project layout

```
.
β”œβ”€β”€ AGENTS.md / CLAUDE.md        ← this file + Claude pointer to it
β”œβ”€β”€ frontend/                    ← Vue 3 SPA (see frontend/AGENTS.md)
β”œβ”€β”€ api/                         ← Express handlers (see api/AGENTS.md)
β”œβ”€β”€ common/                      ← code shared by both halves (valid-ip /
β”‚                                  fetch-with-timeout / guards / logger / …)
β”œβ”€β”€ tests/                       ← Node test runner specs
β”œβ”€β”€ backend-server.js            ← Express app (default port 11966)
β”œβ”€β”€ sentry-instrument.js         ← backend Sentry bootstrap via `node --import`;
β”‚                                  no-op without SENTRY_DSN_BACKEND
β”œβ”€β”€ frontend-server.js           ← static server for `pnpm start` (+ SPA fallback)
β”œβ”€β”€ ecosystem.config.cjs         ← pm2 definitions (carries the `--import` flag)
β”œβ”€β”€ index.html                   ← Vite entry
β”œβ”€β”€ vite.config.js / jsconfig.json (alias @ β†’ frontend/) / package.json
```

## Conventions

### Language

- **JavaScript only.** New files are `.js` / `.vue`; no `lang="ts"`, no
  TypeScript migration.
- **English by default** for code comments, commit messages, and AGENTS.md.
  Locale packs obviously carry their own language; planning docs are free.

### Functions

- **New functions use `const` arrow syntax** (`const fn = async () => {}`),
  not `function` declarations. Object methods keep shorthand. Arrow consts
  aren't hoisted β€” declare before use. Applies to new / rewritten code only;
  don't mass-convert existing declarations.

### Comments

- **Every new file opens with a header comment** stating its purpose.
- **Large templates / functions carry block comments** per meaningful region.
- **Comments describe the code as it is now** β€” no changelog narration
  (`previously…`, `…fixes that`); git history covers the past. A comment
  stays shorter than the code it explains.

### i18n coverage

- Copy-surfacing features land in **all four locales** in the same change β€”
  including `frontend/data/changelog.json` entries
  (`tests/changelog.test.js` enforces it).

### Logging (backend)

- **Always the shared logger** (`common/logger.js`) in backend files; bare
  `console.*` is banned there (frontend keeps using `console.*`).
- Pino first-arg-is-context: `logger.error({ err, ip }, 'short message')`.
- Env knobs: `LOG_LEVEL` (default info), `LOG_FORMAT=json` for shippers,
  `LOG_HTTP=true` to mount `pino-http` on `/api` (off by default; handlers
  never log "received request" lines themselves). No `NODE_ENV` anywhere.
- Startup-only lines lead with an emoji (πŸš€ listening Β· πŸ“¦ ready Β·
  πŸ“₯ downloading Β· πŸ›‘οΈ security Β· 🐒 throttling Β· πŸ—“οΈ schedule Β· ⚠️ recoverable
  · ❌ failure); per-request logs stay plain.

## Testing

- Any non-visual logic exercisable without a network call β€” pure functions,
  composables with mockable inputs, transforms, validators β€” ships with a
  spec in `tests/`, in the same change (don't defer; update affected tests
  when behavior shifts).
- UI rendering, real network behavior, and browser APIs are out of scope.
- **`pnpm check` must be green before handing off.**

## Security & Boundaries

Access control and timeouts live in shared middleware, not handlers
(details in @api/AGENTS.md):

- `requireReferer` is global on `/api/*`; `requirePublicIP()` per-route β€”
  handlers never repeat these checks.
- Every upstream HTTP call goes through `fetchUpstream`
  (`common/fetch-with-timeout.js`, 8s timeout). Never a bare `fetch()` in `api/`.

## Workflow

- **Branch discipline β€” `dev` in, `dev` out.** `main` only moves via
  dev β†’ main PRs. From a worktree, fast-forward dev with `git push . HEAD:dev`
  (repo has `receive.denyCurrentBranch=updateInstead`), not `git update-ref`.
- **No commits without explicit user approval** β€” AI edits β†’ user reviews β†’
  user tests β†’ user says "commit". Even with tests green, visual changes need
  user eyes before landing.
- **One concern per commit**, message style per `git log`
  (`Feat(xxx):` / `Fix(ui):` / `Refactor(xxx):` / `Style:` / `Chore:`),
  AI adds itself as co-author.
- **Self-test before handing off** (`pnpm check`); if a change is visual and
  headless-unverifiable, say so explicitly.
- **On every commit, scan AGENTS.md (root + relevant sub-file) for
  staleness** β€” conventions, renames, flipped rules, dead examples get fixed
  in the same commit. Doc drift is this file's main failure mode.

---

If [local-context.md](./local-context.md) exists in the workspace root, read
it too β€” it lists machine-local Knowledge Hub paths (not in git).