-
Notifications
You must be signed in to change notification settings - Fork 204
chore: bootstrap agent files (JUM-870) #2834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,89 @@ | ||||||||||
| # AGENTS.md — jumper-exchange | ||||||||||
|
|
||||||||||
| ## What this repo is | ||||||||||
|
|
||||||||||
| `jumper.exchange` — the Next.js frontend for [jumper.xyz](https://jumper.xyz). Talks primarily to `jumper-backend` over REST; some legacy paths still hit `strapi-cms` directly. See [ARCHITECTURE.md](./ARCHITECTURE.md) for the app shape, route map, and dependency rules. | ||||||||||
|
|
||||||||||
| ## Run, build, test | ||||||||||
|
|
||||||||||
| See @README.md | ||||||||||
|
laurentsenta marked this conversation as resolved.
|
||||||||||
|
|
||||||||||
| ## Coding conventions | ||||||||||
|
|
||||||||||
| ### Stack and idioms | ||||||||||
|
|
||||||||||
| - **Next.js 16 App Router** with locale segment `src/app/[lng]/…`. New pages go under `src/app/[lng]/<segment>/`; never under `src/app/` directly except for non-localized infrastructure (`api/`, `lib/`, root `layout.tsx`, etc.). | ||||||||||
| - **React 19** with the React Compiler enabled (see `babel-plugin-react-compiler`). Do not write manual `useMemo` / `useCallback` for cases the compiler handles; reach for them only when profiling shows it matters. | ||||||||||
| - **MUI v9 + Emotion** for styling. Prefer the `sx` prop or `styled()` over ad-hoc CSS modules. Theme tokens live under `src/theme/`. | ||||||||||
| - **State**: server state via `@tanstack/react-query`; client state via `zustand` stores under `src/stores/<feature>/`. Do not introduce a third state library. | ||||||||||
| - **Forms**: `@tanstack/react-form`. | ||||||||||
| - **i18n**: `next-i18n-router` + `i18next`. Translations under `src/i18n/translations/<lng>/`; regenerate the typed resources file with `pnpm i18next-resources-for-ts` after editing the `en` translation. | ||||||||||
| - **Wallet stack**: LI.FI SDK + widget, Wagmi/Viem for EVM, plus per-chain providers (Solana, Sui, Bitcoin, Tron). Wire new connectors through `src/providers/WalletProvider/` so the existing widget config picks them up. | ||||||||||
| - **API routes**: Next.js route handlers under `src/app/api/<name>/`. They proxy or wrap `jumper-backend`; do not put business logic here that belongs server-side. | ||||||||||
| - **Observability**: Sentry is wired via `instrumentation.ts`, `instrumentation-client.ts`, and `sentry.*.config.ts`. Use the existing helpers; do not call `Sentry.init` from feature code. | ||||||||||
|
|
||||||||||
| ### Style rules | ||||||||||
|
|
||||||||||
| - **No barrel files** (`index.ts` re-exports). Import directly from the source file. | ||||||||||
|
||||||||||
| - **No barrel files** (`index.ts` re-exports). Import directly from the source file. | |
| - **Avoid introducing new barrel files** (`index.ts` re-exports). Prefer direct imports from the source file in new code, and do not expand existing barrels unless there is a clear reason. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix broken link target for the style guide reference.
../../../.claude/CLAUDE.md points outside the repo and won’t resolve in GitHub. Point to an in-repo doc (or remove the link if intentionally external).
Suggested fix
-- **Function names should be self-documenting** — see [`~/.claude/CLAUDE.md`](../../../.claude/CLAUDE.md) for the user-level style guide we follow.
+- **Function names should be self-documenting** — see [CLAUDE.md](./CLAUDE.md) for the user-level style guide we follow.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - **Function names should be self-documenting** — see [`~/.claude/CLAUDE.md`](../../../.claude/CLAUDE.md) for the user-level style guide we follow. | |
| - **Function names should be self-documenting** — see [CLAUDE.md](./CLAUDE.md) for the user-level style guide we follow. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@AGENTS.md` at line 30, The markdown reference to an external style guide in
the sentence "Function names should be self-documenting" uses a broken relative
link (`../../../.claude/CLAUDE.md`); update that link in AGENTS.md so it points
to a valid in-repo document (e.g., replace with the correct path to the repo's
style guide) or remove the hyperlink if the guide is intentionally external,
ensuring the visible text "Function names should be self-documenting" remains
unchanged.
Copilot
AI
Apr 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This links to ../../../.claude/CLAUDE.md, but there’s no .claude/ directory in this repository, so the link will be broken on GitHub. If there’s a shared style guide, consider linking to a URL or adding a repo-local copy (or remove the link if it’s only intended for a specific local setup).
| - **Function names should be self-documenting** — see [`~/.claude/CLAUDE.md`](../../../.claude/CLAUDE.md) for the user-level style guide we follow. | |
| - **Function names should be self-documenting** and describe intent clearly at the call site. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| # ARCHITECTURE — jumper-exchange | ||
|
|
||
| Shape of this Next.js app. See [AGENTS.md](./AGENTS.md) for how to work in this repo (run, test, conventions, where new things go). | ||
|
|
||
| ## What this app is | ||
|
|
||
| The B2C frontend for [jumper.xyz](https://jumper.xyz). Users land here to bridge and swap between any tokens across any chains (EVM, SVM, Sui, Bitcoin, Tron). Retention features (earn, portfolio, quests, campaigns, missions) are layered on top of the core swap flow. | ||
|
|
||
| The app embeds the `@lifi/widget` for the swap UX and wraps it with Jumper-specific surfaces (auth, profile, XP, content, partner themes, …). | ||
|
|
||
| ## Stack | ||
|
|
||
| | Layer | Choice | | ||
| | --------------- | --------------------------------------------------------------------------------------------------- | | ||
| | Framework | Next.js 16 (App Router) on React 19 with the React Compiler | | ||
| | Styling | MUI v9 + Emotion | | ||
| | Server state | `@tanstack/react-query` | | ||
| | Client state | `zustand` (one store per feature, under `src/stores/<feature>/`) | | ||
| | Forms | `@tanstack/react-form` | | ||
| | i18n | `next-i18n-router` + `i18next`, locale segment in the URL (`/[lng]/…`) | | ||
| | Wallet | `@lifi/sdk` + `@lifi/widget` + per-chain providers (EVM via Wagmi/Viem, Solana, Sui, Bitcoin, Tron) | | ||
| | Observability | Sentry (browser + server + edge) | | ||
| | Tests | Playwright (E2E), Vitest (unit, snapshot, Storybook) | | ||
| | Package manager | pnpm (`packageManager` field pins the version) | | ||
|
|
||
| ## Directory layout | ||
|
|
||
| ``` | ||
| jumper-exchange/ | ||
| ├── src/ | ||
| │ ├── app/ # Next.js App Router | ||
| │ │ ├── [lng]/ # all user-facing pages — locale-prefixed | ||
| │ │ │ ├── (main)/ # route group: landing + main shell | ||
| │ │ │ ├── (infos)/ # route group: legal / informational pages | ||
| │ │ │ ├── bridge/, swap/ # core swap surfaces | ||
| │ │ │ ├── earn/, portfolio/, quests/, missions/, campaign/, zap/, scan/, onboard/ | ||
| │ │ │ ├── error-preview/, meta/ | ||
| │ │ │ ├── error.tsx, layout.tsx | ||
| │ │ ├── api/ # Next.js route handlers (thin proxies to jumper-backend) | ||
| │ │ ├── lib/, ui/ # framework-level helpers | ||
| │ │ ├── layout.tsx, global.css, global-error.tsx, not-found.tsx, robots.ts, sitemap.xml/ | ||
| │ ├── components/ # feature components (one folder per feature) | ||
| │ │ ├── core/, composite/, headless/ # primitives by composition level | ||
| │ │ ├── <FeatureName>/ # e.g. EarnDetails, ConnectButton, Cards, … | ||
| │ ├── providers/ # provider tree: WalletProvider, ThemeProvider, | ||
| │ │ # ReactQueryProvider, TranslationProvider, … | ||
| │ ├── stores/<feature>/ # zustand stores (one folder per feature) | ||
| │ ├── hooks/<feature>/ # react-query hooks + feature hooks | ||
| │ ├── config/ # runtime config (env, wallet connectors, widget) | ||
| │ ├── i18n/translations/<lng>/ # translation JSON; resources.d.ts is generated | ||
| │ ├── theme/ # MUI theme + design tokens | ||
| │ ├── const/, types/, utils/, fonts/, stories/ | ||
| │ ├── Layout.tsx, proxy.ts | ||
| ├── tests/ # Playwright E2E + page objects + test data | ||
| ├── public/ # static assets | ||
| ├── .storybook/ # Storybook config | ||
| ├── instrumentation.ts, instrumentation-client.ts, sentry.*.config.ts | ||
| ├── next.config.mjs, vitest.config.ts, playwright.config.ts, eslint.config.mjs | ||
| ├── gen-api.sh # regenerates the typed API client from jumper-backend's Swagger | ||
| ``` | ||
|
Comment on lines
+28
to
+60
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add language identifiers to fenced code blocks (MD040). These fenced blocks should specify a language to satisfy markdownlint and improve readability. Suggested fix-```
+```text
jumper-exchange/
...
-```
+```
-```
+```text
┌─────────────────────────────────────────────────────────┐
...
-```
+```Also applies to: 66-91 🧰 Tools🪛 markdownlint-cli2 (0.22.1)[warning] 30-30: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI Agents |
||
|
|
||
| ## Request and data flow | ||
|
|
||
| ``` | ||
| ┌─────────────────────────────────────────────────────────┐ | ||
| │ Browser (Next.js client) │ | ||
| │ ┌───────────────────────────────────────────────────┐ │ | ||
| │ │ React tree (App Router) │ │ | ||
| │ │ • providers/ wires query, wallet, theme, i18n │ │ | ||
| │ │ • components/ render features │ │ | ||
| │ │ • stores/ hold client state (zustand) │ │ | ||
| │ │ • hooks/ wrap react-query / wallet calls │ │ | ||
| │ └─────────────┬─────────────────────────────────────┘ │ | ||
| └────────────────┼────────────────────────────────────────┘ | ||
| │ | ||
| ┌───────────────┼─────────────────┐ | ||
| │ │ │ | ||
| ▼ ▼ ▼ | ||
| Next.js API jumper-backend LI.FI SDK | ||
| routes (REST, (chains, quotes, | ||
| (src/app/api/) primary) executions) | ||
| │ | ||
| ▼ | ||
| jumper-backend (proxied) | ||
| ┌─────────────────┐ | ||
| │ strapi-cms │ ← legacy direct paths | ||
| │ (REST) │ (content + campaigns) | ||
| └─────────────────┘ | ||
| ``` | ||
|
|
||
| - **Server state** (chains, tokens, quotes, profile, campaigns, …) is fetched through react-query hooks under `src/hooks/`. Most go through `jumper-backend` either directly or via a Next.js route handler under `src/app/api/`. A few legacy hooks still call `strapi-cms` directly. | ||
| - **Client state** (selected chain/token, route choice, settings, theme, modals, …) lives in zustand stores under `src/stores/<feature>/`. Stores never call APIs — they hold UI state and derived selectors. | ||
| - **The swap engine** is `@lifi/widget`. We embed it inside our pages and configure it via `src/config/widgetConfig.ts`. Wallet connectors are wired in `src/providers/WalletProvider/` so the widget sees them. | ||
| - **Sentry** is initialised once in `instrumentation*.ts` / `sentry.*.config.ts`. Feature code uses helpers — never `Sentry.init` directly. | ||
|
|
||
| ## Internal dependency rules | ||
|
|
||
| | From → To | components | hooks | stores | providers | config | app/ | utils | | ||
| | -------------- | ---------- | ----- | ------ | ------------------- | ------ | ---- | ----- | | ||
| | **components** | ✓ | ✓ | ✓ | ✓ (consume context) | ✓ | ✗ | ✓ | | ||
| | **hooks** | ✗ | ✓ | ✓ | ✓ (consume context) | ✓ | ✗ | ✓ | | ||
| | **stores** | ✗ | ✗ | ✓ | ✗ | ✓ | ✗ | ✓ | | ||
| | **providers** | ✓ (render) | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ | | ||
| | **config** | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✓ | | ||
| | **app/** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | ||
| | **utils** | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | | ||
|
|
||
| Read as: a row module _may_ import from a column module where ✓; _must not_ where ✗. | ||
|
|
||
| Contribution Rules: | ||
|
|
||
| - **`utils/` is a leaf.** It must not import from anything else inside `src/`. Pure helpers only. | ||
| - **`stores/` does not import from `components/`, `hooks/`, or `providers/`.** Stores must be renderable in isolation (and unit-testable) without pulling in the whole tree. | ||
| - **`hooks/` does not import from `components/`.** Hooks describe data; components consume them. | ||
| - **Nothing inside `src/` imports from `src/app/`.** App routes are leaves of the dependency graph — they compose everything else. | ||
| - **No barrel `index.ts` files.** Import from source files directly. This keeps the dependency graph honest and tree-shakeable. | ||
|
laurentsenta marked this conversation as resolved.
|
||
|
|
||
| If a change requires reversing one of these directions, **stop**. The right shape is usually to move the shared code down a level (often into `utils/` or `config/`) rather than to invert the arrow. | ||
|
|
||
| ## Invariants | ||
|
|
||
| | # | Invariant | Enforcement | | ||
| | --- | ------------------------------------------------------------------------------ | ---------------------- | | ||
| | 1 | All user-facing pages live under `src/app/[lng]/` | doc; obvious on review | | ||
| | 2 | API route handlers in `src/app/api/` are thin proxies — no business logic | doc | | ||
| | 3 | Server state goes through react-query; no direct `fetch` in components | doc | | ||
| | 4 | One zustand store per feature folder under `src/stores/` | doc | | ||
| | 5 | No barrel files (`index.ts` re-exports) | doc; ESLint candidate | | ||
| | 6 | Sentry is initialised only in `instrumentation*.ts` / `sentry.*.config.ts` | doc | | ||
| | 7 | Secrets never committed; new env vars documented in `src/config/env-config.ts` | per-repo CI (existing) | | ||
| | 8 | Pre-commit hook (`tsc --noEmit` + ESLint + Prettier) must pass | Husky + lint-staged | | ||
|
|
||
| ## Cross-repo position | ||
|
|
||
| - This app depends on `jumper-backend` (primary, via REST) and on `strapi-cms` (legacy direct paths, via REST). | ||
| - The TypeScript types of the backend API are vendored here, regenerated from `jumper-backend`'s Swagger via `pnpm api` (which calls `gen-api.sh`). Never hand-edit the generated file — change the upstream Swagger and regenerate. | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1 @@ | ||||||
| See @AGENTS.md | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Switch to a standard Markdown link for reliability. Use a normal relative link so the pointer renders consistently in GitHub and other Markdown viewers. Suggested fix-See `@AGENTS.md`
+See [AGENTS.md](./AGENTS.md)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
laurentsenta marked this conversation as resolved.
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a standard Markdown link instead of
@README.md.@README.mdis not a portable Markdown link format on GitHub. Use a regular relative link so it renders reliably.Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents