Agent skill

workout-domain

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/development/workout-domain

SKILL.md

Workout Domain

Block-Based Workout Model

Workouts are sequences of blocks using discriminated unions via kind:

ts
type WorkoutBlock = StrengthBlock | TimedBlock | CardioBlock

type TimedBlock = AmrapBlock | EmomBlock | TabataBlock | ForTimeBlock

Strength Block

Traditional sets/reps exercises:

ts
type StrengthBlock = {
  kind: 'strength'
  id: number
  exerciseName: string
  sets: Array<Set>
}

type Set = {
  id: number
  weight?: string    // User input as string
  reps?: string
  rir?: string       // Reps in reserve
  completed: boolean
}

Timed Blocks

AMRAP, EMOM, Tabata, ForTime:

ts
type AmrapBlock = {
  kind: 'amrap'
  id: number
  config: AmrapConfig
  exercises: Array<BlockExercise>
  result?: AmrapResult
}

type EmomBlock = {
  kind: 'emom'
  id: number
  config: EmomConfig
  exercises: Array<BlockExercise>
  result?: EmomResult
}

type TabataBlock = {
  kind: 'tabata'
  id: number
  config: TabataConfig
  exercises: Array<BlockExercise>
  result?: TabataResult
}

type ForTimeBlock = {
  kind: 'fortime'
  id: number
  config: ForTimeConfig
  exercises: Array<BlockExercise>
  result?: ForTimeResult
}

Cardio Block

ts
type CardioBlock = {
  kind: 'cardio'
  id: number
  exerciseName: string
  duration?: number
  distance?: number
  calories?: number
}

Type Files

File Purpose
src/types/blocks.ts Runtime block types
src/db/schema.ts Persistence types with Db prefix

Convention: Database types use Db prefix (e.g., DbStrengthBlock) and null instead of undefined.

Key Composables

Workout Feature

Composable Purpose
useWorkout.ts Singleton state, block/set CRUD operations
useWorkoutPersistence.ts Auto-save, complete, discard active workout
useWorkoutExercise.ts Exercise selection within workout
useWorkoutBuilder.ts Build workout from scratch or template

Benchmark Feature

Composable Purpose
useBenchmark.ts Core benchmark state and operations
useBenchmarkPersistence.ts Save benchmark attempts
useBenchmarkTimer.ts Timer for timed benchmarks

Template Feature

Composable Purpose
useTemplateForm.ts Create/edit template form state
useTemplatePicker.ts Select template to start workout

Working with Blocks

Adding a Block

ts
import { useWorkout } from '@/features/workout/composables/useWorkout'

const { addBlock } = useWorkout()

// Add strength block
addBlock({
  kind: 'strength',
  exerciseName: 'Squat',
  sets: []
})

// Add AMRAP block
addBlock({
  kind: 'amrap',
  config: { duration: 10 },
  exercises: []
})

Type-Safe Block Handling

Use exhaustive switch for block kinds:

ts
function getBlockTitle(block: WorkoutBlock): string {
  switch (block.kind) {
    case 'strength':
      return block.exerciseName
    case 'amrap':
      return `AMRAP ${block.config.duration}min`
    case 'emom':
      return `EMOM ${block.config.rounds}x${block.config.interval}s`
    case 'tabata':
      return 'Tabata'
    case 'fortime':
      return 'For Time'
    case 'cardio':
      return block.exerciseName
    default:
      // TypeScript exhaustiveness check
      const _exhaustive: never = block
      return _exhaustive
  }
}

Quick Find

bash
rg -n "kind: '(strength|amrap|emom|tabata|fortime|cardio)'" src/  # Block usage
rg -n "type.*Block = " src/types/blocks.ts                        # Block type definitions
rg -n "export function use" src/features/workout/composables      # Workout composables

Didn't find tool you were looking for?

Be as detailed as possible for better results