Files
Remote-Terminal-for-MeshCore/frontend/AGENTS.md

202 lines
5.9 KiB
Markdown

# Frontend AGENTS.md
This document is the frontend working guide for agents and developers.
Keep it aligned with `frontend/src` source code.
## Stack
- React 18 + TypeScript
- Vite
- Vitest + Testing Library
- shadcn/ui primitives
- Tailwind utility classes + local CSS (`index.css`, `styles.css`)
- Sonner (toasts)
- Leaflet / react-leaflet (map)
- `meshcore-hashtag-cracker` + `nosleep.js` (channel cracker)
## Frontend Map
```text
frontend/src/
├── App.tsx # App shell and orchestration
├── api.ts # Typed REST client
├── types.ts # Shared TS contracts
├── useWebSocket.ts # WS lifecycle + event dispatch
├── messageCache.ts # Conversation-scoped cache
├── index.css # Global styles/utilities
├── styles.css # Additional global app styles
├── hooks/
│ ├── useConversationMessages.ts
│ ├── useUnreadCounts.ts
│ ├── useRepeaterMode.ts
│ └── useAirtimeTracking.ts
├── utils/
│ ├── urlHash.ts
│ ├── conversationState.ts
│ ├── favorites.ts
│ ├── messageParser.ts
│ ├── pathUtils.ts
│ ├── pubkey.ts
│ └── contactAvatar.ts
├── components/
│ ├── StatusBar.tsx
│ ├── Sidebar.tsx
│ ├── MessageList.tsx
│ ├── MessageInput.tsx
│ ├── NewMessageModal.tsx
│ ├── SettingsModal.tsx
│ ├── RawPacketList.tsx
│ ├── MapView.tsx
│ ├── VisualizerView.tsx
│ ├── PacketVisualizer.tsx
│ ├── PathModal.tsx
│ ├── CrackerPanel.tsx
│ ├── BotCodeEditor.tsx
│ ├── ContactAvatar.tsx
│ └── ui/
└── test/
├── api.test.ts
├── appFavorites.test.tsx
├── appStartupHash.test.tsx
├── contactAvatar.test.ts
├── integration.test.ts
├── messageCache.test.ts
├── messageParser.test.ts
├── pathUtils.test.ts
├── radioPresets.test.ts
├── repeaterMode.test.ts
├── settingsModal.test.tsx
├── unreadCounts.test.ts
├── urlHash.test.ts
├── useConversationMessages.test.ts
├── useRepeaterMode.test.ts
├── useWebSocket.lifecycle.test.ts
├── websocket.test.ts
└── setup.ts
```
## Architecture Notes
### State ownership
`App.tsx` orchestrates high-level state (health, config, contacts/channels, active conversation, UI flags).
Specialized logic is delegated to hooks:
- `useConversationMessages`: fetch, pagination, dedup/update helpers
- `useUnreadCounts`: unread counters, mention tracking, recent-sort timestamps
- `useRepeaterMode`: repeater login/command workflow
### Initial load + realtime
- Initial data: REST fetches (`api.ts`) for config/settings/channels/contacts/unreads.
- WebSocket: realtime deltas/events.
- On WS connect, backend sends `health` only; contacts/channels still come from REST.
### Message behavior
- Outgoing sends are optimistic in UI and persisted server-side.
- Backend also emits WS `message` for outgoing sends so other clients stay in sync.
- ACK/repeat updates arrive as `message_acked` events.
## WebSocket (`useWebSocket.ts`)
- Auto reconnect (3s) with cleanup guard on unmount.
- Heartbeat ping every 30s.
- Event handlers: `health`, `contacts`, `channels`, `message`, `contact`, `raw_packet`, `message_acked`, `error`, `success`.
## URL Hash Navigation (`utils/urlHash.ts`)
Supported routes:
- `#raw`
- `#map`
- `#map/focus/{pubkey_or_prefix}`
- `#visualizer`
- `#channel/{channelKey}`
- `#channel/{channelKey}/{label}`
- `#contact/{publicKey}`
- `#contact/{publicKey}/{label}`
Legacy name-based hashes are still accepted for compatibility.
## Conversation State Keys (`utils/conversationState.ts`)
`getStateKey(type, id)` produces:
- channels: `channel-{channelKey}`
- contacts: `contact-{publicKey}`
Use full contact public key here (not 12-char prefix).
`conversationState.ts` keeps an in-memory cache and localStorage helpers used for migration/compatibility.
Canonical persistence for unread and sort metadata is server-side (`app_settings` + read-state endpoints).
## Utilities
### `utils/pubkey.ts`
Current public export:
- `getContactDisplayName(name, pubkey)`
It falls back to a 12-char prefix when `name` is missing.
### `utils/pathUtils.ts`
Distance/validation helpers used by path + map UI.
### `utils/favorites.ts`
LocalStorage migration helpers for favorites; canonical favorites are server-side.
## Types and Contracts (`types.ts`)
`AppSettings` currently includes:
- `max_radio_contacts`
- `experimental_channel_double_send`
- `favorites`
- `auto_decrypt_dm_on_advert`
- `sidebar_sort_order`
- `last_message_times`
- `preferences_migrated`
- `advert_interval`
- `bots`
Backend also tracks `last_advert_time` in settings responses.
## Repeater Mode
For repeater contacts (`type=2`):
1. Telemetry/login phase (`POST /api/contacts/{key}/telemetry`)
2. Command phase (`POST /api/contacts/{key}/command`)
CLI responses are rendered as local-only messages (not persisted to DB).
## Styling
UI styling is mostly utility-class driven (Tailwind-style classes in JSX) plus shared globals in `index.css` and `styles.css`.
Do not rely on old class-only layout assumptions.
## Security Posture (intentional)
- No authentication UI.
- Frontend assumes trusted network usage.
- Bot editor intentionally allows arbitrary backend bot code configuration.
## Testing
```bash
cd frontend
npm run test:run
npm run build
```
When touching cross-layer contracts, also run backend tests from repo root:
```bash
PYTHONPATH=. uv run pytest tests/ -v
```
## Editing Checklist
1. If API/WS payloads change, update `types.ts`, handlers, and tests.
2. If URL/hash behavior changes, update `utils/urlHash.ts` tests.
3. If read/unread semantics change, update `useUnreadCounts` tests.
4. Keep this file concise; prefer source links over speculative detail.