Spec and claude
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Repository state
|
||||
|
||||
This repo currently contains only a spec (`NEXA_SPEC.md`), `README.md`, and `LICENSE` — no source code, `package.json`, or `manifest.json` exist yet. There are no build/lint/test commands to run because nothing has been scaffolded. When implementation begins, this file should be updated with the actual commands (build, lint, test, load-unpacked instructions) once a package manager and bundler are chosen.
|
||||
|
||||
## What this project is
|
||||
|
||||
Nexa is a blockchain-powered trading companion focused on the emotional/behavioral side of trading, not the trades themselves. Trades are already visible on-chain, so Nexa observes wallet activity rather than requiring manual logging. This repo is the **open-source frontend**: a browser extension. The backend (wallet/RPC listening via Solana/Helius, loss detection, auth, WebSocket push) is a separate private service and is out of scope here — treat it as an external API.
|
||||
|
||||
License: Apache 2.0. The backend stays closed-source; this frontend repo is the OSS component.
|
||||
|
||||
Full behavioral spec lives in `NEXA_SPEC.md` — read it before implementing the lockout feature or any site adapter/intervention. Key points below are a summary, not a replacement.
|
||||
|
||||
## Target platform
|
||||
|
||||
- Built and tested primarily on Zen (Firefox fork), must also work cross-platform on Firefox and Chromium-based browsers (WebExtensions API / Manifest V3 where possible).
|
||||
- Avoid browser-specific APIs unless behind a compatibility shim.
|
||||
|
||||
## Current milestone: "Lockout" feature
|
||||
|
||||
When the extension receives a "locked" state, it visually disables (not hides) buy-action elements on supported trading sites, shows a non-dismissible-to-unlock reason toast, and intercepts clicks that reach the underlying element. Sell/manage actions are never touched. Unlocking reverses all DOM changes cleanly with no leftover overlays/classes.
|
||||
|
||||
Escalation model: first disable new-position buy actions only; if circumvented, escalate to a full-site block (stub only for v1).
|
||||
|
||||
## Required architecture (modularity is the core constraint)
|
||||
|
||||
This is the most important design rule in the spec: **lock/unlock decision-making, site-specific detection, and enforcement/intervention must be three fully decoupled concerns.**
|
||||
|
||||
- Adding a new supported site = a new site adapter module, without touching core logic.
|
||||
- Adding a new intervention type (full-site block, delayed buy with countdown, confirmation modal) = a new intervention strategy module, without touching adapters.
|
||||
- The decision of *when/how long/why* to lock is decoupled from *how it's enforced on the page* and from *how it's detected on the page*.
|
||||
|
||||
Planned structure (from `NEXA_SPEC.md` §3.2):
|
||||
|
||||
```
|
||||
/src
|
||||
/background - owns WebSocket connection to backend, holds current lock state, messages content scripts
|
||||
/content-scripts
|
||||
/adapters
|
||||
axiom.ts - site-specific selectors + DOM strategy for axiom.trade
|
||||
adapter-interface.ts - shared type/interface all adapters implement
|
||||
/interventions
|
||||
blur-disable.ts - visual lock treatment (v1 default)
|
||||
full-block.ts - escalation: full page block overlay (stub for v1)
|
||||
intervention-interface.ts
|
||||
observer.ts - generic MutationObserver watching for adapter-declared selectors (SPA-safe)
|
||||
content-index.ts - wires adapter + intervention + background messages together
|
||||
/popup - status, reason for lock, threshold settings link
|
||||
/notifications - toast/banner injected into page or via browser notification API
|
||||
/shared
|
||||
messaging.ts - typed message contracts between background <-> content scripts <-> popup
|
||||
types.ts
|
||||
manifest.json
|
||||
```
|
||||
|
||||
A site adapter's contract: `matches` (URL pattern), `findBuyElements()`, `getContainer(el)` (stable ancestor to style, so the whole control is styled rather than an inner span).
|
||||
|
||||
## Axiom.trade adapter specifics (first target site)
|
||||
|
||||
- Axiom is a React SPA — buy elements mount/unmount without full page reloads. Use a `MutationObserver` on a stable root (e.g. `document.body`), not a one-time `querySelectorAll` on load.
|
||||
- Quick Buy button: find via `closest('.buy-click-container')`, not a hardcoded ancestor depth (DOM depth is not stable).
|
||||
- Noob Mode Buy button: match `button` elements with class `bg-increase` whose text matches `/^Buy\s/i`. Do not hardcode token names — they vary per token page.
|
||||
- Full selector details and example markup are in `NEXA_SPEC.md` §3.3.
|
||||
|
||||
## Lock state contract
|
||||
|
||||
The lock/unlock state is a simple typed interface: `{ locked: boolean, reason?: string, scope: 'buy-only' | 'full-block' }`. For v1 (no real backend yet), this is driven by a mock/dev toggle (e.g. via popup or `browser.storage`). The background script must expose a single isolated seam (`getLockState()` / `setLockState()`) where the real WebSocket client will later plug in — do not scatter lock-state reads/writes across modules.
|
||||
|
||||
## Visual treatment for v1 (`blur-disable`)
|
||||
|
||||
- Wrap or overlay the original element rather than mutating its classes destructively, so the original markup can be restored exactly on unlock.
|
||||
- `filter: blur(2-3px)`, ~0.5 opacity, `cursor: not-allowed`, a non-blurred centered lock icon overlay, and `pointer-events: none` (or a transparent click-catcher div).
|
||||
- A click on a locked element (or its click-catcher) must trigger the same reason toast as lock activation.
|
||||
|
||||
## Non-goals for this milestone
|
||||
|
||||
- No real backend/WebSocket connection (mock state only).
|
||||
- No cost-basis tracking logic (backend concern).
|
||||
- No full-site-block implementation beyond a stub module.
|
||||
- No threshold-setting UI (placeholder link only).
|
||||
- Only the axiom.trade adapter needs to be functional; the architecture just needs to make adding more sites trivial.
|
||||
Reference in New Issue
Block a user