Imported from Userneima/VerbaLab (
AGENTS.md). Install upstream withnpx skills add Userneima/VerbaLab. Copyright stays with the author.
Project Overview
Purpose
VerbaLab is a local-first English learning web app centered on three connected practice loops:
实验室 / Lab: use a target collocation to build an English sentence, get grammar feedback, and store successful output as personal corpus.单词卡片 / Vocab Cards: generate, review, and revisit vocabulary cards with register guidance, example sentences, and spaced review actions.实战仓 / Field: use accumulated corpus and vocabulary in longer-form speaking or writing tasks.
The product is designed to reduce “I know the meaning but can’t say it” friction. The app favors scaffolded output, explicit feedback, and reviewable artifacts over passive browsing.
Primary User
Chinese-speaking English learners preparing for real output:
- daily communication
- interviews and workplace English
- IELTS-style speaking/writing practice
- vocabulary-to-output transfer
Core Success Criteria
- Users can turn a Chinese thought or target collocation into a natural English sentence with as little dropout as possible.
- Correct sentences are preserved and reused as personal corpus.
- Wrong sentences become reviewable error items instead of disappearing.
- Vocabulary cards help users decide what to say in real usage, not just memorize definitions.
- Cloud sync is optional, but local-first usage must remain reliable.
Tech Stack
- Frontend: React 18 + Vite + TypeScript
- Styling: Tailwind CSS 4 + Radix UI primitives
- Routing:
react-router - State: custom app store via React context
- Persistence: localStorage first, optional Supabase sync
- Backend / AI: Supabase Edge Functions
- Monitoring: Sentry
- Speech: Azure Speech SDK
- Tests: Vitest + Testing Library
Useful commands:
npm run dev
npm run typecheck
npm run test
npm run build
High-Level Architecture
Frontend App Shell
- src/app/App.tsx: app root
- src/app/routes.ts: route definitions
- src/app/components/Layout.tsx: shared shell and navigation
Store and Persistence
- src/app/store/useStore.ts: main local-first domain store
- src/app/store/StoreContext.tsx: context wrapper
- src/app/store/useCloudSync.ts: cloud sync side effects
- src/app/store/AuthContext.tsx: auth/session state
AI and Backend Integration
- src/app/utils/api.ts: frontend API compatibility facade
- src/app/utils/api/: frontend API modules split by capability
- src/app/utils/grammarCheck.ts: lab grammar checks and local fallback behavior
- supabase/functions/make-server-1fc434d6/index.ts: main Edge Function for AI features
Core Product Areas
- src/app/pages/HomePage.tsx: overview dashboard, progress, calendar
- src/app/pages/LabPage.tsx: sentence-building lab
- src/app/pages/useLabPageController.ts: lab page orchestration
- src/app/pages/CorpusPage.tsx: personal corpus
- src/app/pages/ErrorBankPage.tsx: error review
- src/app/pages/WordLabPage.tsx: vocab card generation
- src/app/pages/VocabReviewPage.tsx: vocab card waterfall / browsing
- src/app/pages/VocabCardDetailPage.tsx: vocab card detail + review flow
- src/app/pages/FieldPage.tsx: longer-form output practice
- src/app/pages/FoundryPage.tsx: collocation/foundry workflow
- src/app/pages/StuckPointsPage.tsx: stuck-point review
- apps/weapp: WeChat Mini Program scaffold; keep it independent from the Vite web runtime
Shared Practice Utilities
- src/app/data/verbData.ts: built-in collocation bank and example data
- src/app/utils/sentenceTileBank.ts: tokenized sentence reconstruction logic
- src/app/components/VocabReproducePanel.tsx: tile-based vocab review
- src/app/components/VocabRegisterGuideCard.tsx: register analysis card
Domain Model
The app revolves around a few persistent learning objects:
CorpusEntry: successful user sentences stored for reuseErrorBankEntry: wrong sentences plus diagnosis and corrected sentence when availableVocabCard: headword-focused card with tags, examples, review state, and register analysisStuckPoint: Chinese thought + AI help trail for moments where the user could not phrase something
When changing data shape, check both local persistence and sync/merge behavior.
Especially relevant files:
- src/app/utils/syncMerge.ts
- src/app/utils/corpusDedupe.ts
- src/app/utils/errorBankDedupe.ts
- src/app/utils/reviewGate.ts
Product-Specific Working Notes
Lab
The lab is not just a grammar checker. It is a scaffolded output trainer.
When editing lab behavior, preserve this general order:
- user sees target collocation + Chinese context
- user attempts sentence production
- optional support appears (
卡壳了, lowering difficulty, etc.) - grammar feedback arrives without directly giving away the answer
- success writes to corpus; failure writes to error bank
Avoid turning the lab into passive answer consumption.
Vocab Cards
Vocab cards should help with “what should I say in real usage?” rather than dictionary-like explanation.
When changing vocab card generation or display:
- keep register analysis actionable
- prefer concise, high-signal explanations over generic prose
- avoid fake spoken replacements that are not semantically equivalent
- preserve review state and due scheduling
Error Bank
The error bank should reinforce the correct sentence, not burn in the wrong one.
Prefer:
- correct sentence as primary display
- wrong sentence visually de-emphasized
- key corrections surfaced clearly
Local-First Principle
Most learning state should still work without cloud sync.
Do not make core practice loops depend on network-only success unless there is a graceful fallback.
WeChat Mini Program UI Scale
Mini program form controls should stay visually quiet and never compete with titles or result content.
When editing apps/weapp:
InputandTextareatext should default to14pxunless a design decision explicitly changes the whole scale- search boxes, login fields, word inputs, and expression textareas should not use headline-sized text
- input containers should fit their content scale; avoid large
min-heightor padding that leaves obvious empty space - keep input text visually below page titles, primary buttons, and saved content
- if a new input style is reused, extract or align it instead of copying inconsistent inline styles across pages
File and Folder Guidance
src/app/pages/ Route-level screens
src/app/components/ Shared product components
src/app/components/lab/ Lab-specific UI
src/app/components/ui/ UI primitives
src/app/store/ App state, auth, sync
src/app/utils/ Business logic, review logic, API helpers
src/app/data/ Built-in learning content
apps/weapp/ WeChat Mini Program scaffold and future mini-program client
supabase/functions/ Edge Functions and backend helpers
General expectations:
- put route orchestration in
pages/or dedicated page controllers - keep reusable logic in
utils/ - keep product-specific view pieces in
components/ - avoid stuffing more unrelated logic into src/app/store/useStore.ts unless it truly belongs in core state
Testing and Verification
Minimum expectations after meaningful code changes:
- run
npm run typecheck
Also run when relevant:
npm run testfor logic-heavy changesnpm run buildwhen route structure, bundling, or import boundaries change
If you change any of the following, verify extra carefully:
- Edge Function request/response schema
- sync/merge behavior
- review scheduling
- vocab card generation schema
- lab grammar feedback flow
Problem Solving Principles
Fix Root Cause and Prevent Recurrence
When a problem is found, do not stop at fixing the visible symptom.
Always try to do all of the following:
- identify the direct cause
- identify why the issue was able to happen
- make the smallest effective change that prevents the same class of problem from happening again
- apply that preventive improvement immediately when appropriate
Typical preventive improvements include:
- add validation
- tighten types
- add error handling
- add tests
- add lint / build / verification coverage
- improve config defaults
- improve documentation or structure rules
Prefer root-cause fixes plus recurrence prevention over one-off patches.
Supabase and Deployment Notes
- Main Supabase project ref:
ztlrrovudbkmqqjaqhfu - Main AI function:
make-server-1fc434d6 - Vercel is used for deployment
Deployment default for this project:
- for meaningful product/code changes that affect behavior, treat
验证通过后推送并触发部署as the default - do not wait for an extra reminder to push/deploy after important validated changes
- still pause first for destructive, risky, or ambiguous deployment-impacting actions
- if the user explicitly says not to deploy, that instruction overrides this default
Change Management
Large product changes should be synchronized to GitHub automatically after local validation passes.
A large / major product change includes:
- new core feature
- major interaction flow change
- significant UI / UX revision
- architecture-affecting refactor
- important product logic change
Expected workflow:
- complete implementation
- run relevant validation (
typecheck,test,buildwhen applicable) - write a clear English commit message
- commit changes
- push to GitHub
Do not skip validation before push. If there is real risk of breaking production, note that risk clearly before pushing or deploying.
If changing cross-origin API behavior, check CORS settings in the Edge Function and Supabase secrets.
If changing AI output shape, update both:
- frontend consumers in src/app/utils/api.ts, src/app/utils/api/, and related UI
- backend schema/prompting in supabase/functions/make-server-1fc434d6/index.ts
Guardrails for Future Contributors
- Do not replace project-specific learning flows with generic CRUD UI.
- Do not optimize only for passing checks; optimize for actual learning value.
- Treat Chinese prompts, English output, review scaffolding, and correction visibility as core UX, not edge details.
- Keep terminology aligned with the product:
实验室 / Lab语料库 / Corpus语法错误库 / Error Bank词卡工坊 / Word Lab单词卡片 / Vocab Cards实战仓 / Field
When in doubt, prefer changes that help the user:
- speak sooner
- understand mistakes faster
- review more purposefully
- reuse what they have already learned