From d30c183979221cb23c54d5f2c27bd717a902b3ca Mon Sep 17 00:00:00 2001 From: ngosang Date: Sun, 27 Sep 2026 09:56:18 +0200 Subject: [PATCH] Make CLAUDE.md a symlink to AGENTS.md and bring it up to date Keep a single source of agent instructions and sync it with the project: add the missing configuration docs, key files (releaseInfo.ts, swizzled footer, plugins, static assets) and dependencies, fix stale homepage references, and avoid enumerating locales so the file does not go stale. --- AGENTS.md | 22 +++++++------ CLAUDE.md | 92 +------------------------------------------------------ 2 files changed, 14 insertions(+), 100 deletions(-) mode change 100644 => 120000 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md index 9c50792..456a397 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,11 +9,12 @@ ## Main Libraries - **Node.js**: `>=24` -- **Framework**: `@docusaurus/core`, `@docusaurus/preset-classic` (`^3.10`) +- **Framework**: `@docusaurus/core`, `@docusaurus/preset-classic` (`^3.10`); `@docusaurus/faster` (Rspack/SWC, `future.faster: true`) - **Language**: TypeScript (`tsx` components, `ts` config files) - **React**: `^18` - **Syntax highlighting**: `prism-react-renderer` -- **Search**: `@easyops-cn/docusaurus-search-local` — client-side, index built at compile time. Configured in `docusaurus.config.ts` (`themes` array). Add new locales to its `language` array when adding a new i18n locale. Search only works in the production build (`npm run build` + `npm run serve`), not in the dev server (`npm run start`). +- **Image zoom**: `docusaurus-plugin-image-zoom` (`themeConfig.zoom.selector`) +- **Search**: `@easyops-cn/docusaurus-search-local` — client-side, index built at compile time. Configured in `docusaurus.config.ts` (`themes` array). Add new locales to its `language` array when adding a new i18n locale, only if lunr has a stemmer for it (use the base language code for regional variants). Search only works in the production build (`npm run build` + `npm run serve`), not in the dev server (`npm run start`, which serves only `en`; other locales: `npm run start -- --locale `). ## Architecture @@ -24,22 +25,25 @@ - `sidebars.ts` — docs sidebar definition - `src/pages/index.tsx` — homepage, composes section components (Hero and closing CTA inlined here) - `src/pages/download.tsx` — Download page (`/download`) +- `src/releaseInfo.ts` — single source of truth for release versions/dates (homepage banner + Download page); edit only this file on a new release - `src/components//index.tsx` — one component per homepage section - `src/components//styles.module.css` — scoped styles per component - `src/css/custom.css` — global CSS variable overrides (color palette) +- `src/theme/Footer/LinkItem/` — swizzled footer link (adds icons) +- `plugins/` — `blog-changelog.js` (changelog blog wrapper: rewords translator context in `options.json`), `remark-zoom-large-images.js` - `docs/` — English documentation (Markdown) - `blog/` — Blog posts (`/blog`); `changelog/` — Changelog posts (`/changelog`, second blog plugin instance) - `i18n//` — translations (`code.json` for UI strings; mirrored `docs/`, `blog/`, `changelog/` for content) -- `static/img/` — images (`amule-logo.svg`, `social-card.png`, favicons, `screenshots/`, `docs/`) +- `static/img/` — images (`amule-logo.svg`, `social-card.png`, favicons, `screenshots/`, `docs/`); `static/manifest.webmanifest`; `static/skins/` (downloadable GUI skins) ## Documentation `docsSidebar` (see `sidebars.ts`) opens with two standalone docs — Overview (`docs/index.md`) and Quick Start (`docs/quickstart-guide.md`) — then **four top-level categories** by audience. Keep them separate — never mix audiences. -- **User Manual** (`docs/manual/`) — install, configure, use, troubleshoot; for basic and expert users. Subdivided into `installation/`, `configuration/` (network config: `directories`, `network-connectivity`, `firewall`, `upnp`, `proxy`, `events`, `macos` + **editable text config files** in `config-files/`: `amule.conf`, `remote.conf`), `interfaces/` (GUI under `gui/`, plus `amuled`, `amuleapi` (folder `amuleapi/`: daemon `index` + `web-ui` subpage), `amulecmd`, `amuleweb`), `utilities/` (standalone helpers), `migration/`, `troubleshooting/`, `faq/`. +- **User Manual** (`docs/manual/`) — install, configure, use, troubleshoot; for basic and expert users. Subdivided into `installation/`, `configuration/` (topic pages + **editable text config files** in `config-files/`: `amule.conf`, `remote.conf`, `amuleapi.conf`), `interfaces/` (GUI under `gui/`, plus `amuled`, `amuleapi` (folder `amuleapi/`: daemon `index` + `web-ui` subpage), `amulecmd`, `amuleweb`), `utilities/` (standalone helpers), `migration/`, `troubleshooting/`, `faq` (single doc). - **Developer Guide** (`docs/developer/`) — for aMule developers and advanced integrators: compilation (`compilation/`), debugging, testing, translations, documentation, code style, the **file-format reference** (`file-formats/`: byte layouts of `.met`/`.dat` files), and the **EC protocol**. - **P2P Networks** (`docs/p2p-networks/`) — general **protocol** description and historical reference: eD2k (`ed2k/`), Kademlia (`kademlia`), `concepts`, `other-networks`. **Do not mix protocol with aMule's concrete implementation** — implementation details belong in the User Manual / Developer Guide and are linked, not embedded. -- **Contributing** (`docs/contributing/`) — `bug-report`. +- **Contributing** (`docs/contributing/`) — `bug-report`, `translating` (translator-facing Weblate guide; admin setup stays in `developer/translations/weblate`). ## Homepage Components @@ -50,11 +54,11 @@ Inlined in `src/pages/index.tsx`: split Hero (logo, tagline, intro, CTA buttons | `FeaturesSection` | Alternating screenshot/feature rows + "And much more" card grid | - Screenshots: `static/img/screenshots/*.png`, cropped from `static/img/docs/` (the up-to-date captures). Class `home-zoom` enables click-to-zoom (`zoom.selector` in `docusaurus.config.ts`). -- Motion: CSS only (`animation-timeline: view()` scroll reveal), guarded by `prefers-reduced-motion`. +- Motion: CSS only (hero fade-in, `animation-timeline: view()` scroll reveal in `FeaturesSection`), always inside `@media (prefers-reduced-motion: no-preference)`. ## i18n -- Default locale: `en`. The enabled locales are defined in `docusaurus.config.ts` (`i18n.locales`) — that array is the source of truth; don't duplicate the list here. +- Default locale: `en`. The enabled locales are defined in `docusaurus.config.ts` (`i18n.locales`) — that array is the source of truth; don't duplicate the list here. `i18n/` also holds Weblate-synced locales not yet in that array; they are not built. - UI strings (React components): `i18n//code.json` — each entry has `message` (translate this) and `description` (context, do not translate). - **Translated JSON files contain only `message`** — the `description` is translator context and belongs **only** in the English base (`i18n/en/`). Never write `description` into any non-`en` locale file (`code.json`, `navbar.json`, `footer.json`, `current.json`, blog/changelog `options.json`). `write-translations -- --locale ` re-adds them and Docusaurus has no option to disable this, so strip them before committing (Weblate keeps the translated files `message`-only via the WebExtension JSON format). - Docs content: `i18n//docusaurus-plugin-content-docs/current/` mirrors `docs/`. @@ -63,7 +67,7 @@ Inlined in `src/pages/index.tsx`: split Hero (logo, tagline, intro, CTA buttons - Add a new locale: register in `docusaurus.config.ts`, run `npm run write-translations -- --locale `, then translate generated files. - Update translations after English changes: run `npm run write-translations -- --locale ` (adds new keys, preserves existing ones), then translate new entries in `code.json` and update changed docs files manually. - **Weblate base files**: `i18n/en/` holds the English source files for Weblate, generated by `npm run write-translations` (no `--locale`). After adding/changing any ``/`translate()` string, run it and commit `i18n/en/` — the `Build Check` CI runs the same command and **fails if `i18n/en/` drifts**. -- **All page/component text must be translatable**: wrap visible text in `text` (JSX) or `translate({id, message})` (attributes). ID convention: `homepage.
.`. The `id` and text **must be static string literals** — never `` nor `translate({id: variable})`, as `write-translations` extracts via static analysis and errors on dynamic values. In data-driven lists (`FEATURES`, `DOWNLOAD_OSES`, …) store the content as `` nodes (typed `React.ReactNode`) or `translate({...})` calls **inside** the array, not as `*Id`/`*Default` fields. +- **All page/component text must be translatable**: wrap visible text in `text` (JSX) or `translate({id, message})` (attributes). ID convention: `homepage.
.`. The `id` and text **must be static string literals** — never `` nor `translate({id: variable})`, as `write-translations` extracts via static analysis and errors on dynamic values. In data-driven lists (`SHOWCASES`, `DOWNLOAD_OSES`, …) store the content as `` nodes (typed `React.ReactNode`) or `translate({...})` calls **inside** the array, not as `*Id`/`*Default` fields. - **Interpolation in ``**: Docusaurus only supports `{varName}` placeholders — **not** `chunks` (FormatJS/react-intl syntax). For inline markup (``, ``, ``) or links use `values`, e.g. `values={{ code: flag }}` or `values={{ link: text }}` with `{code}` / `{link}` in the message. Prefer this over `dangerouslySetInnerHTML`. - **Translation reference**: English is always the source of truth. All translations must faithfully reflect the English original — do not paraphrase or simplify. - **Precision over naturalness**: Translations must be as accurate as possible. Readers are software users familiar with technical terminology, so use technical language freely. Keep English terms (e.g. "hash", "changelog", "release", "peer") when a translated equivalent would be less precise or less commonly used in the target language. @@ -76,7 +80,7 @@ Inlined in `src/pages/index.tsx`: split Hero (logo, tagline, intro, CTA buttons ## Important Notes -- **Theming**: All styling must be theme-aware (light/dark). Use Infima CSS variables (`--ifm-background-color`, `--ifm-background-surface-color`, `--ifm-heading-color`, `--ifm-color-emphasis-*`, `--ifm-color-primary`) — never hardcoded hex colors or `rgba(255 255 255 / …)` overlays in page/component CSS modules. Exception: overlays over their own dark backdrop (e.g. the screenshots lightbox modal). +- **Theming**: All styling must be theme-aware (light/dark). Use Infima CSS variables (`--ifm-background-color`, `--ifm-background-surface-color`, `--ifm-heading-color`, `--ifm-color-emphasis-*`, `--ifm-color-primary`) — never hardcoded hex colors or `rgba(255 255 255 / …)` overlays in page/component CSS modules. Exception: overlays over their own dark backdrop. - **Markdown line wrapping**: Do **not** hard-wrap prose. Write each paragraph/sentence on a single line (no manual line breaks mid-sentence). Keep tables, code blocks and list items as-is. - **Images in docs**: referenced as `/img/docs/` (served from `static/`). - **Image zoom**: always use plain Markdown (`![alt](/img/docs/)`), never hardcoded HTML `` (Markdown paths are build-validated, `` paths are not). Click-to-zoom is added automatically to large images (width ≥ 850px) by `plugins/remark-zoom-large-images.js`. diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 435ae6c..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,91 +0,0 @@ -# amule-org.github.io - AGENTS.md - -**⚠️ EXCLUDED FOLDERS**: The following folders must be **EXCLUDED** from any analysis, reading, or modification: `node_modules/`, `build/`, `.docusaurus/`. - -**⚠️ AGENTS.md** This document is for LLM use. Keep it short — preserve the format and use the minimum number of tokens. - -**amule-org.github.io** is the aMule project website, built with Docusaurus v3. Internationalized (i18n). - -## Main Libraries - -- **Node.js**: `>=24` -- **Framework**: `@docusaurus/core`, `@docusaurus/preset-classic` (`^3.10`) -- **Language**: TypeScript (`tsx` components, `ts` config files) -- **React**: `^18` -- **Syntax highlighting**: `prism-react-renderer` -- **Search**: `@easyops-cn/docusaurus-search-local` — client-side, index built at compile time. Configured in `docusaurus.config.ts` (`themes` array). Add new locales to its `language` array when adding a new i18n locale. Search only works in the production build (`npm run build` + `npm run serve`), not in the dev server (`npm run start`). - -## Architecture - -**Static site**: `src/pages/index.tsx` (orchestrator) → `src/components/` (section components) → Docusaurus build → GitHub Pages. - -**Key files**: -- `docusaurus.config.ts` — site config, navbar, footer, i18n locales, theme, plugins (changelog blog instance) -- `sidebars.ts` — docs sidebar definition -- `src/pages/index.tsx` — homepage, composes section components (Hero/What-is/screenshot inlined here) -- `src/pages/download.tsx` — Download page (`/download`) -- `src/components//index.tsx` — one component per homepage section -- `src/components//styles.module.css` — scoped styles per component -- `src/css/custom.css` — global CSS variable overrides (color palette) -- `docs/` — English documentation (Markdown) -- `blog/` — Blog posts (`/blog`); `changelog/` — Changelog posts (`/changelog`, second blog plugin instance) -- `i18n//` — translations (`code.json` for UI strings; mirrored `docs/`, `blog/`, `changelog/` for content) -- `static/img/` — images (`amule-logo.svg`, `social-card.png`, favicons, `screenshots/`, `docs/`) - -## Documentation - -`docsSidebar` (see `sidebars.ts`) opens with two standalone docs — Overview (`docs/index.md`) and Quick Start (`docs/quickstart-guide.md`) — then **four top-level categories** by audience. Keep them separate — never mix audiences. - -- **User Manual** (`docs/manual/`) — install, configure, use, troubleshoot; for basic and expert users. Subdivided into `installation/`, `configuration/` (network config: `directories`, `network-connectivity`, `firewall`, `upnp`, `proxy`, `events`, `macos` + **editable text config files** in `config-files/`: `amule.conf`, `remote.conf`), `interfaces/` (GUI under `gui/`, plus `amuled`, `amuleapi` (folder `amuleapi/`: daemon `index` + `web-ui` subpage), `amulecmd`, `amuleweb`), `utilities/` (standalone helpers), `migration/`, `troubleshooting/`, `faq/`. -- **Developer Guide** (`docs/developer/`) — for aMule developers and advanced integrators: compilation (`compilation/`), debugging, testing, translations, documentation, code style, the **file-format reference** (`file-formats/`: byte layouts of `.met`/`.dat` files), and the **EC protocol**. -- **P2P Networks** (`docs/p2p-networks/`) — general **protocol** description and historical reference: eD2k (`ed2k/`), Kademlia (`kademlia`), `concepts`, `other-networks`. **Do not mix protocol with aMule's concrete implementation** — implementation details belong in the User Manual / Developer Guide and are linked, not embedded. -- **Contributing** (`docs/contributing/`) — `bug-report`, `translating` (translator-facing Weblate guide; admin setup stays in `developer/translations/weblate`). - -## Homepage Components - -The Hero (logo, tagline, CTA buttons), "What is aMule?" description and the full-width transfers screenshot are inlined in `src/pages/index.tsx`. The remaining sections are components: - -| Component | Section | -|---|---| -| `HighlightsSection` | 3.0.0 release highlights grid | -| `FeaturesSection` | Bulleted feature list | -| `ScreenshotsSection` | Screenshot grid with lightbox | - -## i18n - -- Default locale: `en`. The enabled locales are defined in `docusaurus.config.ts` (`i18n.locales`) — that array is the source of truth; don't duplicate the list here. -- UI strings (React components): `i18n//code.json` — each entry has `message` (translate this) and `description` (context, do not translate). -- **Translated JSON files contain only `message`** — the `description` is translator context and belongs **only** in the English base (`i18n/en/`). Never write `description` into any non-`en` locale file (`code.json`, `navbar.json`, `footer.json`, `current.json`, blog/changelog `options.json`). `write-translations -- --locale ` re-adds them and Docusaurus has no option to disable this, so strip them before committing (Weblate keeps the translated files `message`-only via the WebExtension JSON format). -- Docs content: `i18n//docusaurus-plugin-content-docs/current/` mirrors `docs/`. -- Blog/changelog content: `i18n//docusaurus-plugin-content-blog/` mirrors `blog/`; `i18n//docusaurus-plugin-content-blog-changelog/` mirrors `changelog/`. -- Sidebar labels: `i18n//docusaurus-plugin-content-docs/current/current.json`. -- Add a new locale: register in `docusaurus.config.ts`, run `npm run write-translations -- --locale `, then translate generated files. -- Update translations after English changes: run `npm run write-translations -- --locale ` (adds new keys, preserves existing ones), then translate new entries in `code.json` and update changed docs files manually. -- **Weblate base files**: `i18n/en/` holds the English source files for Weblate, generated by `npm run write-translations` (no `--locale`). After adding/changing any ``/`translate()` string, run it and commit `i18n/en/` — the `Build Check` CI runs the same command and **fails if `i18n/en/` drifts**. -- **All page/component text must be translatable**: wrap visible text in `text` (JSX) or `translate({id, message})` (attributes). ID convention: `homepage.
.`. The `id` and text **must be static string literals** — never `` nor `translate({id: variable})`, as `write-translations` extracts via static analysis and errors on dynamic values. In data-driven lists (`FEATURES`, `DOWNLOAD_OSES`, …) store the content as `` nodes (typed `React.ReactNode`) or `translate({...})` calls **inside** the array, not as `*Id`/`*Default` fields. -- **Interpolation in ``**: Docusaurus only supports `{varName}` placeholders — **not** `chunks` (FormatJS/react-intl syntax). For inline markup (``, ``, ``) or links use `values`, e.g. `values={{ code: flag }}` or `values={{ link: text }}` with `{code}` / `{link}` in the message. Prefer this over `dangerouslySetInnerHTML`. -- **Translation reference**: English is always the source of truth. All translations must faithfully reflect the English original — do not paraphrase or simplify. -- **Precision over naturalness**: Translations must be as accurate as possible. Readers are software users familiar with technical terminology, so use technical language freely. Keep English terms (e.g. "hash", "changelog", "release", "peer") when a translated equivalent would be less precise or less commonly used in the target language. - -## Naming Conventions - -- **Project name**: Always write as "aMule" (not "Amule", "AMule", or "amule"). -- **Module names**: Always lowercase, always in code format: `amule`, `amulegui`, `amuled`, `amuleapi`, `amulecmd`, `amuleweb`, `ed2k`, `alc`, `alcc`, `wxcas`, `cas`, `xas`. -- **Platform order**: When listing supported platforms in any enumeration, list, or table, always use the order **Windows, macOS, Linux, BSD** — ordered by popularity. - -## Important Notes - -- **Theming**: All styling must be theme-aware (light/dark). Use Infima CSS variables (`--ifm-background-color`, `--ifm-background-surface-color`, `--ifm-heading-color`, `--ifm-color-emphasis-*`, `--ifm-color-primary`) — never hardcoded hex colors or `rgba(255 255 255 / …)` overlays in page/component CSS modules. Exception: overlays over their own dark backdrop (e.g. the screenshots lightbox modal). -- **Markdown line wrapping**: Do **not** hard-wrap prose. Write each paragraph/sentence on a single line (no manual line breaks mid-sentence). Keep tables, code blocks and list items as-is. -- **Images in docs**: referenced as `/img/docs/` (served from `static/`). -- **Image zoom**: always use plain Markdown (`![alt](/img/docs/)`), never hardcoded HTML `` (Markdown paths are build-validated, `` paths are not). Click-to-zoom is added automatically to large images (width ≥ 850px) by `plugins/remark-zoom-large-images.js`. -- **Images in components**: referenced as `/img/` (served from `static/`). -- **Social card**: `static/img/social-card.png` is the 1200×630 og:image (logo, wordmark, tagline). Rendered from `amule-logo.svg`; regenerate it rather than editing the raster, and keep it English-only — one static file serves every locale. -- **URLs to generated files**: For links to generated files (feeds, sitemaps) that the broken-links checker cannot verify, use the `pathname://` protocol: e.g. `pathname:///blog/atom.xml`. This bypasses the checker and renders as a correct relative path at runtime. Do **not** use absolute URLs with `url`/`baseUrl` — those break in local dev. - -## Workflow - -After any code change, before completing the task: - -1. Build **only the affected locales** (faster than the full build) with `npm run build -- --locale `: for changes to source code, `docs/`, `blog/`, `changelog/` or config, build `en`; for changes to a translation under `i18n//`, build that locale. Run the full `npm run build` only when the change affects all locales. -2. Fix any errors or warnings introduced by the change. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file