complete_chore:
  name: Complete Chore
  description: Mark a chore as completed by a child
  fields:
    chore_id:
      name: Chore ID
      description: The ID of the chore to complete
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      description: The ID of the child completing the chore
      required: true
      selector:
        text:
    as_parent:
      name: As parent
      description: Complete on behalf of the child and award points immediately, bypassing approval.
      required: false
      default: false
      selector:
        boolean:
    photo_url:
      name: Photo URL
      description: Optional URL or path to a photo submitted as evidence for the completion (e.g. a camera snapshot). Shown to the parent during approval.
      required: false
      selector:
        text:

complete_bonus_subtask:
  name: Complete Bonus Sub-task
  description: Complete a bonus sub-task after the parent chore is done
  fields:
    chore_id:
      name: Chore ID
      description: The ID of the parent chore
      required: true
      selector:
        text:
    bonus_subtask_id:
      name: Bonus Sub-task ID
      description: The ID of the bonus sub-task to complete
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      description: The ID of the child completing the bonus sub-task
      required: true
      selector:
        text:

approve_chore:
  name: Approve Chore
  description: Approve a completed chore and award points
  fields:
    completion_id:
      name: Completion ID
      description: The ID of the chore completion to approve
      required: true
      selector:
        text:

approve_all_chores:
  name: Approve All Chores
  description: Approve all pending chore completions (or a specific set) and award points
  fields:
    completion_ids:
      name: Completion IDs
      description: Specific completion IDs to approve; omit to approve all pending
      required: false
      selector:
        object:

reject_chore:
  name: Reject Chore
  description: Reject a completed chore
  fields:
    completion_id:
      name: Completion ID
      description: The ID of the chore completion to reject
      required: true
      selector:
        text:

apply_mandatory_penalty:
  name: Apply Mandatory Penalty
  description: Deduct the configured penalty points for a missed mandatory chore and clear the review item.
  fields:
    miss_id:
      name: Miss ID
      description: The ID of the mandatory-miss review item
      required: true
      selector:
        text:

postpone_mandatory_chore:
  name: Postpone Mandatory Chore
  description: Give a missed mandatory chore another period (or tomorrow) without a penalty, and clear the review item.
  fields:
    miss_id:
      name: Miss ID
      description: The ID of the mandatory-miss review item
      required: true
      selector:
        text:

dismiss_mandatory_chore:
  name: Dismiss Mandatory Chore
  description: Clear a missed mandatory chore review item with no penalty.
  fields:
    miss_id:
      name: Miss ID
      description: The ID of the mandatory-miss review item
      required: true
      selector:
        text:

undo_transaction:
  name: Undo Transaction
  description: Reverse a points transaction by its ID — penalties, bonuses, manual add/remove adjustments and gifts (both legs). Automatic transactions (weekend/streak/perfect-week bonuses, pool moves, decay, interest) can't be undone.
  fields:
    transaction_id:
      name: Transaction ID
      description: The ID of the points transaction to reverse
      required: true
      selector:
        text:

undo_chore_approval:
  name: Undo Chore Approval
  description: Reverse an accidental chore approval — removes the awarded points and returns the completion to pending so it can be approved again.
  fields:
    completion_id:
      name: Completion ID
      description: The ID of the approved chore completion to revert to pending
      required: true
      selector:
        text:

test_notification:
  name: Test Notification
  description: Send a sample notification of the given type to its enabled recipients (ignores the master on/off so routing can be verified).
  fields:
    type_id:
      name: Notification type
      description: "Notification type id, e.g. pending_chore_approval, badge_earned, streak_milestone"
      required: true
      selector:
        text:

record_allowance_payout:
  name: Record Allowance Payout
  description: Deduct points and record a real-money allowance payout in the ledger (fixed conversion rate; parent-controlled).
  fields:
    child_id:
      name: Child ID
      required: true
      selector:
        text:
    points:
      name: Points
      description: Points to convert to cash and deduct.
      required: true
      selector:
        number:
          min: 1
          max: 100000
          mode: box

gift_points:
  name: Gift Points
  description: Transfer spendable points from one child to another (parent-controlled).
  fields:
    from_child_id:
      name: From child ID
      required: true
      selector:
        text:
    to_child_id:
      name: To child ID
      required: true
      selector:
        text:
    points:
      name: Points
      required: true
      selector:
        number:
          min: 1
          max: 10000
          mode: box

request_swap:
  name: Request Chore Swap
  description: A child requests to take over today's rotation assignment of a chore (pending parent approval).
  fields:
    chore_id:
      name: Chore ID
      required: true
      selector:
        text:
    requester_id:
      name: Requester child ID
      required: true
      selector:
        text:

choose_avatar:
  name: Choose Avatar
  description: A child switches to an avatar they have unlocked.
  fields:
    child_id:
      name: Child ID
      required: true
      selector:
        text:
    icon:
      name: Avatar icon
      description: The mdi icon of an unlocked catalogue avatar (e.g. mdi:rocket-launch).
      required: true
      selector:
        text:

claim_reward:
  name: Claim Reward
  description: Child claims a reward using their points
  fields:
    reward_id:
      name: Reward ID
      description: The ID of the reward to claim
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      description: The ID of the child claiming the reward
      required: true
      selector:
        text:

approve_reward:
  name: Approve Reward
  description: Approve a reward claim
  fields:
    claim_id:
      name: Claim ID
      description: The ID of the reward claim to approve
      required: true
      selector:
        text:

allocate_points_to_pool:
  name: Allocate Points to Pool
  description: Move points from a child's spendable balance into a reward's savings pool (locked).
  fields:
    child_id:
      name: Child ID
      description: The ID of the child making the allocation
      required: true
      selector:
        text:
    reward_id:
      name: Reward ID
      description: The ID of the reward pool to deposit into
      required: true
      selector:
        text:
    points:
      name: Points
      description: Number of points to allocate (capped at pool capacity and spendable balance)
      required: true
      selector:
        number:
          min: 1
          max: 10000
          mode: box

add_points:
  name: Add Points
  description: Add bonus points to a child
  fields:
    child_id:
      name: Child ID
      description: The ID of the child to add points to
      required: true
      selector:
        text:
    points:
      name: Points
      description: The number of points to add
      required: true
      selector:
        number:
          min: 1
          max: 10000
          mode: box
    reason:
      name: Reason
      description: Optional reason for the bonus
      required: false
      selector:
        text:

remove_points:
  name: Remove Points
  description: Remove points from a child (penalty)
  fields:
    child_id:
      name: Child ID
      description: The ID of the child to remove points from
      required: true
      selector:
        text:
    points:
      name: Points
      description: The number of points to remove
      required: true
      selector:
        number:
          min: 1
          max: 10000
          mode: box
    reason:
      name: Reason
      description: Optional reason for the penalty
      required: false
      selector:
        text:

reject_reward:
  name: Reject Reward
  description: Reject a reward claim (no points deducted as approval was pending)
  fields:
    claim_id:
      name: Claim ID
      description: The ID of the reward claim to reject
      required: true
      selector:
        text:

preview_sound:
  name: Preview Sound
  description: Preview a completion sound effect in the browser
  fields:
    sound:
      name: Sound
      description: The sound to preview
      required: true
      selector:
        select:
          options:
            - "none"
            - "coin"
            - "levelup"
            - "fanfare"
            - "chime"
            - "powerup"
            - "undo"
            - "fart1"
            - "fart2"
            - "fart3"
            - "fart4"
            - "fart5"
            - "fart6"
            - "fart7"
            - "fart8"
            - "fart9"
            - "fart10"
            - "fart_random"

set_chore_order:
  name: Set Chore Order
  description: Set the display order of chores for a child
  fields:
    child_id:
      name: Child ID
      description: The ID of the child to set chore order for
      required: true
      selector:
        text:
    chore_order:
      name: Chore Order
      description: Ordered list of chore IDs
      required: true
      selector:
        object:

add_penalty:
  name: Add Penalty
  description: Create a new penalty definition
  fields:
    name:
      name: Name
      description: The name of the penalty
      required: true
      selector:
        text:
    points:
      name: Points
      description: The number of points to deduct when applied
      required: true
      selector:
        number:
          min: 1
          max: 10000
          mode: box
    description:
      name: Description
      description: Optional description of the penalty
      required: false
      selector:
        text:
    icon:
      name: Icon
      description: MDI icon for the penalty
      required: false
      selector:
        icon:
    assigned_to:
      name: Assigned To
      description: List of child IDs this penalty applies to (empty for all)
      required: false
      selector:
        object:

update_penalty:
  name: Update Penalty
  description: Update an existing penalty definition
  fields:
    penalty_id:
      name: Penalty ID
      description: The ID of the penalty to update
      required: true
      selector:
        text:
    name:
      name: Name
      description: New name for the penalty
      required: false
      selector:
        text:
    points:
      name: Points
      description: New points value for the penalty
      required: false
      selector:
        number:
          min: 1
          max: 10000
          mode: box
    description:
      name: Description
      description: New description for the penalty
      required: false
      selector:
        text:
    icon:
      name: Icon
      description: New icon for the penalty
      required: false
      selector:
        icon:
    assigned_to:
      name: Assigned To
      description: New list of child IDs this penalty applies to
      required: false
      selector:
        object:

remove_penalty:
  name: Remove Penalty
  description: Remove a penalty definition
  fields:
    penalty_id:
      name: Penalty ID
      description: The ID of the penalty to remove
      required: true
      selector:
        text:

apply_penalty:
  name: Apply Penalty
  description: Apply a penalty to a child, deducting points
  fields:
    penalty_id:
      name: Penalty ID
      description: The ID of the penalty to apply
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      description: The ID of the child to apply the penalty to
      required: true
      selector:
        text:

add_bonus:
  name: Add Bonus
  description: Create a new bonus definition
  fields:
    name:
      name: Name
      description: The name of the bonus
      required: true
      selector:
        text:
    points:
      name: Points
      description: The number of points to award when applied
      required: true
      selector:
        number:
          min: 1
          max: 10000
          mode: box
    description:
      name: Description
      description: Optional description of the bonus
      required: false
      selector:
        text:
    icon:
      name: Icon
      description: MDI icon for the bonus
      required: false
      selector:
        icon:
    assigned_to:
      name: Assigned To
      description: List of child IDs this bonus applies to (empty for all)
      required: false
      selector:
        object:

update_bonus:
  name: Update Bonus
  description: Update an existing bonus definition
  fields:
    bonus_id:
      name: Bonus ID
      description: The ID of the bonus to update
      required: true
      selector:
        text:
    name:
      name: Name
      description: New name for the bonus
      required: false
      selector:
        text:
    points:
      name: Points
      description: New points value for the bonus
      required: false
      selector:
        number:
          min: 1
          max: 10000
          mode: box
    description:
      name: Description
      description: New description for the bonus
      required: false
      selector:
        text:
    icon:
      name: Icon
      description: New icon for the bonus
      required: false
      selector:
        icon:
    assigned_to:
      name: Assigned To
      description: New list of child IDs this bonus applies to
      required: false
      selector:
        object:

remove_bonus:
  name: Remove Bonus
  description: Remove a bonus definition
  fields:
    bonus_id:
      name: Bonus ID
      description: The ID of the bonus to remove
      required: true
      selector:
        text:

apply_bonus:
  name: Apply Bonus
  description: Apply a bonus to a child, awarding points
  fields:
    bonus_id:
      name: Bonus ID
      description: The ID of the bonus to apply
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      description: The ID of the child to apply the bonus to
      required: true
      selector:
        text:

add_chore:
  name: Add Chore
  description: Create a new chore dynamically, typically from an automation or script
  fields:
    name:
      name: Name
      description: The name of the chore
      required: true
      selector:
        text:
    description:
      name: Description
      description: Optional description of the chore
      required: false
      selector:
        text:
    points:
      name: Points
      description: Points awarded when this chore is completed
      required: false
      default: 10
      selector:
        number:
          min: 1
          max: 10000
          mode: box
    assigned_to:
      name: Assigned To
      description: List of child IDs to assign this chore to. Leave empty to assign to all children
      required: false
      selector:
        object:
    time_category:
      name: Time Category
      description: When this chore should be completed
      required: false
      default: anytime
      selector:
        select:
          options:
            - morning
            - afternoon
            - evening
            - night
            - anytime
    difficulty:
      name: Difficulty
      description: Difficulty tier; scales awarded points by the tier multiplier (medium = ×1.0 baseline)
      required: false
      default: medium
      selector:
        select:
          options:
            - easy
            - medium
            - hard
    one_shot:
      name: One-Shot
      description: If true, this is a one-time chore that expires after being completed or at the end of the day
      required: false
      default: false
      selector:
        boolean:
    requires_approval:
      name: Requires Approval
      description: If true, a parent must approve the completion before points are awarded
      required: false
      default: true
      selector:
        boolean:
    expires_in_minutes:
      name: Expires in (minutes)
      description: >-
        Make this a reactive chore with a deadline this many minutes from now — e.g. the washing
        machine finished, empty it within 30 minutes. The chore disappears and is disabled once the
        deadline passes. 0 = no deadline.
      required: false
      default: 0
      selector:
        number:
          min: 0
          max: 10080
          mode: box
          unit_of_measurement: min
    speed_bonus_points:
      name: Speed bonus points
      description: Extra points awarded if the chore is completed before the deadline. Needs expires_in_minutes.
      required: false
      default: 0
      selector:
        number:
          min: 0
          max: 10000
          mode: box

read_aloud:
  name: Read Chores Aloud
  description: >-
    Speak a child's outstanding chores to a media player — "Ella, you have three things left...".
    Wording is set by the read-aloud templates in the TaskMate panel settings.
  fields:
    child_id:
      name: Child ID
      required: true
      selector:
        text:
    media_player:
      name: Media player
      description: Where to speak. Falls back to the default set in Settings.
      required: false
      selector:
        entity:
          domain: media_player
    tts_entity:
      name: Text-to-speech entity
      description: Which TTS service to use. Falls back to Settings, then to the only one installed.
      required: false
      selector:
        entity:
          domain: tts
    message:
      name: Message override
      description: Say this instead of the generated summary.
      required: false
      selector:
        text:

spin_roulette:
  name: Spin Chore Roulette
  description: >-
    Pick a random outstanding chore for a child at a points multiplier. Opt-in — enable it and set
    the multiplier and daily spin allowance in the TaskMate panel settings.
  fields:
    child_id:
      name: Child ID
      description: The ID of the child spinning
      required: true
      selector:
        text:

skip_chore:
  name: Skip Chore
  description: Skip today's assigned child for a rotating chore and move the pointer to the next child in the pool. Ephemeral — tomorrow the rotation resumes its normal schedule.
  fields:
    chore_id:
      name: Chore ID
      description: The ID of the chore to skip
      required: true
      selector:
        text:

set_chore_manual_start:
  name: Set Manual Start Child
  description: Set which child the rotation starts with for a rotating chore. For alternating mode this reorders the pool and resets the anchor; for random/balanced it overrides today's cached assignee only.
  fields:
    chore_id:
      name: Chore ID
      description: The ID of the chore to update
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      description: The ID of the child who should start the rotation
      required: true
      selector:
        text:

add_task_group:
  name: Add Task Group
  description: Create a task group that coordinates assignments across chores (sticky = same child, spread = different children).
  fields:
    name:
      name: Name
      description: Display name for the group
      required: true
      selector:
        text:
    policy:
      name: Policy
      description: sticky (same child) or spread (different children)
      required: true
      default: sticky
      selector:
        select:
          options:
            - sticky
            - spread
    chore_ids:
      name: Chore IDs
      description: List of chore IDs to include in the group. For sticky, the first chore is the leader.
      required: false
      selector:
        object:

update_task_group:
  name: Update Task Group
  description: Update a task group's name, policy, or chore membership.
  fields:
    group_id:
      name: Group ID
      description: The ID of the group to update
      required: true
      selector:
        text:
    name:
      name: Name
      description: New display name
      required: false
      selector:
        text:
    policy:
      name: Policy
      description: New policy (sticky or spread)
      required: false
      selector:
        select:
          options:
            - sticky
            - spread
    chore_ids:
      name: Chore IDs
      description: Replacement list of chore IDs. For sticky, the first chore is the leader.
      required: false
      selector:
        object:

remove_task_group:
  name: Remove Task Group
  description: Delete a task group. The member chores are not affected.
  fields:
    group_id:
      name: Group ID
      description: The ID of the group to delete
      required: true
      selector:
        text:

start_timed_task:
  name: Start Timed Task
  description: Start or resume the timer on a timed task
  fields:
    chore_id:
      name: Chore ID
      description: The ID of the timed chore
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      description: The ID of the child starting the timer
      required: true
      selector:
        text:

pause_timed_task:
  name: Pause Timed Task
  description: Pause a running timed task timer
  fields:
    chore_id:
      name: Chore ID
      description: The ID of the timed chore
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      description: The ID of the child pausing the timer
      required: true
      selector:
        text:

stop_timed_task:
  name: Stop Timed Task
  description: Stop a timed task timer and submit for approval
  fields:
    chore_id:
      name: Chore ID
      description: The ID of the timed chore
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      description: The ID of the child stopping the timer
      required: true
      selector:
        text:

add_badge:
  name: Add Badge
  description: Create a custom badge.
  fields:
    name:
      name: Name
      required: true
      example: "Holiday Helper"
      selector:
        text:
    description:
      name: Description
      example: "Earned for big effort during school holidays"
      selector:
        text:
    icon:
      name: Icon
      example: "mdi:beach"
      selector:
        icon:
    tier:
      name: Tier
      default: bronze
      selector:
        select:
          options:
            - bronze
            - silver
            - gold
            - platinum
    point_bonus:
      name: Point bonus
      default: 0
      selector:
        number:
          min: 0
          max: 1000
          step: 1
          mode: box
    criteria:
      name: Criteria
      description: "List of metric / operator / value dicts (operator one of >=, ==, <=, >, <, !=). Empty = manual-award only."
      selector:
        object:
    combinator:
      name: Combinator
      description: "How multiple criteria combine: AND (all must pass) or OR (any). Default AND."
      default: AND
      selector:
        select:
          options:
            - AND
            - OR
    assigned_to:
      name: Assigned to
      description: "List of child IDs (empty = all)"
      selector:
        object:
    notify_on_earn:
      name: Notify on earn
      default: true
      selector:
        boolean:

update_badge:
  name: Update Badge
  description: Update an existing badge. For built-ins, only point_bonus, tier, assigned_to, enabled, notify_on_earn are editable.
  fields:
    badge_id:
      name: Badge ID
      required: true
      selector:
        text:
    name:
      selector:
        text:
    description:
      selector:
        text:
    icon:
      selector:
        icon:
    tier:
      selector:
        select:
          options:
            - bronze
            - silver
            - gold
            - platinum
    point_bonus:
      selector:
        number:
          min: 0
          max: 1000
          step: 1
          mode: box
    criteria:
      selector:
        object:
    combinator:
      selector:
        select:
          options:
            - AND
            - OR
    assigned_to:
      selector:
        object:
    enabled:
      selector:
        boolean:
    notify_on_earn:
      selector:
        boolean:

remove_badge:
  name: Remove Badge
  description: Remove a custom badge. Built-ins cannot be removed.
  fields:
    badge_id:
      name: Badge ID
      required: true
      selector:
        text:

award_badge_manually:
  name: Award Badge Manually
  description: Manually award a badge to a child.
  fields:
    badge_id:
      name: Badge ID
      required: true
      selector:
        text:
    child_id:
      name: Child ID
      required: true
      selector:
        text:

revoke_badge:
  name: Revoke Badge
  description: Revoke an awarded badge. If a point bonus was credited, it is reversed.
  fields:
    awarded_badge_id:
      name: Awarded Badge ID
      required: true
      selector:
        text:

rebuild_badges:
  name: Rebuild Badges
  description: Re-evaluate all badges across all children silently (no notifications, no point bonuses).
