A padel score tracking app for Amazfit watches running Zepp OS API Level 3.6+. Track match scores directly from your wrist with an intuitive interface designed for padel players.
- One-tap scoring for both teams (Team A and Team B)
- Undo functionality to correct scoring mistakes
- Real-time score display showing current game points and set scores
- Match persistence - resume interrupted games automatically
- Match summary screen with scrollable match history
- Screen keep-awake during active games to prevent interruptions
- Traditional padel scoring including deuce, advantage, and tie-break at 6-6
- Responsive design optimized for the supported square and round Zepp OS 3.6+ screen families
Mainline targets Zepp OS API Level 3.6+ screen families configured in app.json:
- Square:
w390 - Round:
w454,w466,w480
Device support is determined by the current Zepp OS API level and screen family matrix, not by legacy Zepp OS 1.x device-specific branches.
- Home Screen - Start new games or resume saved matches
- Setup Screen - Configure match settings before starting
- Game Screen - Main scoring interface with touch controls
- Summary Screen - View match history and final scores
- History Screen - Browse all past matches
- History Detail Screen - View full details of a specific match
- Settings Screen - Configure app preferences
- Node.js 24.x
- Zeus CLI installed globally:
npm i -g @zeppos/zeus-cli
- Zepp OS Simulator (for local testing)
- Zepp mobile app with Developer Mode enabled for real-device testing
- A Zepp/Open Platform account: https://console.zepp.com
-
Clone the repository:
git clone <repository-url> cd padelscore
-
Install dependencies:
npm install
-
Run the development server:
zeus dev
-
Login to your Zepp account:
zeus login
-
Generate a QR code and scan it with the Zepp app:
zeus preview
-
Enable Developer Mode in Zepp App:
- Profile → Settings → About → Tap the Zepp icon 7 times
zeus buildThis generates a .zab package file ready for distribution.
Note: This project uses automated releases via GitHub Actions. See RELEASE.md for details on the release process.
padelscore/
├── app.js # Main application entry point
├── app.json # App configuration (permissions, targets, i18n)
├── page/ # Watch UI screens
│ ├── index.js # Home screen entry point
│ ├── setup.js # Match setup screen
│ ├── game.js # Main game screen (orchestrator)
│ ├── game/ # Game screen modules
│ │ ├── logic.js # Scoring/state logic
│ │ ├── persistence.js # Match persistence
│ │ └── ui-binding.js # UI rendering
│ ├── summary.js # Match summary screen
│ ├── history.js # Match history list
│ ├── history-detail.js # Match history details
│ ├── score-view-model.js # Score display view model
│ ├── settings.js # App settings
│ └── i18n/ # Internationalization files (en-US, es-ES, pt-BR)
├── utils/ # Core business logic (key files shown)
│ ├── scoring-engine.js # Padel scoring logic
│ ├── match-state.js # State management
│ ├── match-storage.js # Persistence layer
│ └── history-stack.js # Undo/redo functionality
├── tests/ # Test suite
├── assets/ # Icons and resources
├── scripts/ # Build and utility scripts
└── docs/ # Documentation and development logs
The application has two key entry points:
app.js: Main application entry point that initializes global state, handles app lifecycle (onCreate/onDestroy), and manages match state persistencepage/index.js: Home screen entry point that provides the main user interface for starting new matches or resuming existing games
Both work together: app.js sets up the global context, while page/index.js provides the first user-facing screen.
- appId:
1108585 - Version baseline:
3.0.0(package.json,app.json, andutils/version.jskept in sync) - Module topology: dedicated
app-side/andsetting/modules were removed after confirming they were placeholder-only and unused at runtime
Run the complete quality check (linting, formatting, and tests):
npm run complete-checkThis command runs:
- Biome linting (
npm run lint:fix) - Checks and fixes code quality issues - Biome formatting (
npm run format) - Ensures consistent code style - Unit tests (
npm test) - Runs the test suite
Individual commands are also available:
npm test # Run tests only
npm run lint # Check for lint errors
npm run lint:fix # Fix lint errors automatically
npm run format # Format code
npm run format:check # Check formatting without changes- Indentation: 2 spaces
- Line endings: LF
- Naming: camelCase for variables/functions, kebab-case for files
- Responsive Units: Use
rpxfor layouts,pxonly for fixed sizing
This project uses an automated quality gate stack to enforce consistent code style, commit message conventions, and test health before any change reaches the repository.
Biome is the linter and formatter for all JavaScript and JSON files.
| Script | Command | Purpose |
|---|---|---|
npm run lint |
biome lint --error-on-warnings . |
Check all files for lint errors (warnings fail the check) |
npm run lint:fix |
biome lint --error-on-warnings --write . |
Auto-fix lint errors automatically |
npm run format |
biome format --error-on-warnings --write . |
Format all files (style only) |
Configuration is in biome.json. Key settings:
- Single quotes, no semicolons, 2-space indentation, LF line endings
- Build-time globals are kept minimal; mainline production code should prefer
@zos/*module imports over legacyhm*globals noConsoledisabled — intentional Zepp OS lifecycle logging is allowed
Husky manages git hooks. Hooks are installed automatically when you run npm install (via the prepare script).
| Hook | Trigger | Action |
|---|---|---|
pre-commit |
Before every commit | Runs lint-staged on staged files |
commit-msg |
After commit message written | Validates message against Conventional Commits |
pre-push |
Before every push | Runs npm test — blocks push if any test fails |
lint-staged ensures Biome only runs on the files you staged, keeping pre-commit hooks fast regardless of project size. Configuration is in .lintstagedrc.json.
Commitlint enforces the Conventional Commits specification on every commit message. Configuration is in commitlint.config.js.
Valid commit message examples:
feat: add match history screen
fix: resolve score reset on app resume
docs: update installation guide
chore: upgrade biome to v2
The app implements traditional padel/tennis scoring:
- Game Points: 0 → 15 → 30 → 40 → Game
- Deuce/Advantage: Enabled when both teams reach 40
- Set Win: First to 6 games with a 2-game margin
- Tie-Break: Played at 6-6 games (first to 7 points, win by 2)
- Match: Best of 3 sets (first to 2 sets wins)
- Runtime: Zepp OS (Amazfit devices)
- Framework: Zepp OS Mini Program Framework
- Language: JavaScript (ES6+)
- UI System: Zepp OS UI Widgets (Canvas-based rendering)
- Storage: Local storage via
device:os.local_storagepermission
- Getting Started Guide
- Release Process - Automated release workflow and version management
- Changelog - Version history and release notes
- Main PRD - Core product requirements
- QA Remediation PRD v1.1 - Quality assurance improvements
- Refactor Layout PRD - UI layout refactoring requirements
- Finish Match PRD - Match completion flow requirements
- Review PRD - Code review and quality requirements