- Added a new "Prompt Builder" tab in the Popup for generating AI prompts with customizable parameters. - Introduced new state variables for managing prompt styles, personas, formats, and models. - Enhanced the Options page to fetch and display models based on the provided API key. - Updated the actions and types to include the new 'prompt' action and its associated parameters. - Implemented migration logic for legacy plaintext API keys to encrypted storage. - Updated the getSystemPrompt function to incorporate prompt parameters for better instruction generation. - Added tests for the new functionality, including context menu entries and prompt generation logic.
4.4 KiB
Lessons learned — LexAI
Evidence-backed invariants and guardrails for this codebase. Not a transcript or issue tracker. The one-line active rules live in
CLAUDE.md→## Lessons; the detail lives here.
Active guardrails
CLAUDE.md → ## Lessons is the canonical active list loaded every session. The entries below are the established codebase invariants (from Phase 1 and the 2026-07-13 code read) that break things silently when violated.
L-CORE-01 — onMessage listener must return true
- Root cause / failure boundary: async provider responses need the message channel held open; a listener that doesn't
return truedrops every response with no error. - Prevention: never remove
return truefrom thechrome.runtime.onMessagehandler inbackground.ts. - Eval: manual (candidate: a unit test asserting the listener returns
true).
L-CORE-02 — Snapshot selection before any await
- Root cause / failure boundary: focus shifts to the toolbar and the live selection is gone by the time an async response returns.
- Prevention: in
content.ts, capture active element + offsets eagerly (mouseup + button mousedown) and snapshot before awaiting; Replace uses the snapshot. Handle textarea/input (selectionStart/End) and contenteditable/DOM (RangeAPI). - Eval: E-BASE-04 manual; DOM test tracked in TASKS #10.
L-CORE-03 — Keep both ANALYZE_TEXT message shapes
- Root cause / failure boundary: callers send both
{ payload: {…} }and flat{ text, action, style }; dropping either breaks a call path.fixnormalizes togrammar. - Prevention: if you touch the handler, keep both shapes and the action normalization.
L-CORE-04 — Preserve the data-lexai="true" guard
- Root cause / failure boundary: without it, LexAI's own injected UI re-triggers selection/click handlers.
- Prevention: set
data-lexai="true"on every injected node; handlers skiptarget.closest('[data-lexai="true"]').
L-CORE-05 — Never expose the API key; keep the plaintext fallback
- Root cause / failure boundary: the key is a user secret; and legacy installs still have plaintext
apiKey. - Prevention: prefer
apiKeyEnc+encKey; never log the key; never send it anywhere except the user's selected provider endpoint; don't drop the plaintextapiKeyfallback without a migration.
L-CORE-06 — Provider code is duplicated (callX + callXWithPrompt)
- Root cause / failure boundary: each provider has two near-identical functions; a request-shape change to one silently diverges from the other.
- Prevention: update both until the layer is refactored (TASKS #4). Keep error handling uniform (network → friendly string;
!res.ok→ provider message; empty → explicit message).
L-CORE-07 — Content script / popup must not call providers
- Root cause / failure boundary: CORS and key handling belong in the service worker; a direct provider
fetchfrom content/popup leaks the key path and fails CORS. - Prevention: route everything through
ANALYZE_TEXT/COPY_AStobackground.ts.
L-CORE-08 — Version lives in two files
- Root cause / failure boundary: manifest version comes from
wxt.config.ts;package.jsonhas its own — they drift and have caused git churn. - Prevention: bump
versionin bothpackage.jsonandwxt.config.ts(until T-16 single-sources it). Av*.*.*tag triggers the CWS deploy.
L-CORE-09 — UI is inline styles; Tailwind is inactive
- Root cause / failure boundary: Tailwind is installed but WXT PostCSS was never wired; Tailwind classes silently do nothing.
- Prevention: style with inline objects and the existing dark palette; don't add Tailwind classes unless the task is explicitly to wire PostCSS.
Recording policy
Add a lesson only after a material, evidenced learning signal (correction, unexpected failure, regression, rejected review, proven wrong assumption). Each needs a durable prevention; link a deterministic eval when possible. No secrets, credentials, personal data, or raw transcripts.
Lesson template
### L-YYYY-MM-DD-NN — [short imperative guardrail]
- **Status:** active | archived | superseded by [ID]
- **Trigger / Root cause / Prevention / Evidence / Eval / Owner-review**
Archive
Historical lessons move here with their original IDs and a one-line archival reason.