Skip to content

The GUI task form cannot show or edit a task's schedule windows, and carries its own copy of the minimum interval #2490

Closed

Description

@argszero

A task in tasks.yml can carry an optional schedule: a list of time-of-day windows, each with its own interval, so one task can run every 15 minutes during working hours and every 3 hours outside them.

The daemon side of that field is complete. task_create and task_update both accept it, validate_schedule refuses bad windows with a readable message, task_update preserves windows when a payload omits the key and treats an explicit null as "one frequency all day", and list_tasks() already reports each record's windows to the client.

The GUI task form cannot show or set them, and drops the field on the way in:

  1. TaskFormDialog.tsx renders one flat interval input (emrg/gui/renderer/src/components/TaskFormDialog.tsx). A task's windows are never displayed, and there is no way to add, edit or remove one — the payload it builds has no schedule key at all.
  2. emrg:taskCreate (emrg/gui/main.js) destructures a fixed field list — name, type, project, interval, enabled, repo, description, sandbox — and builds the task_create payload from it, so a schedule sent by the renderer is discarded and a task can only ever be created with one frequency. (emrg:taskUpdate spreads the remaining fields, so it passes the key through.)

Expected: a host who opens a task carrying windows sees those windows in the form, can change them, add new ones and remove them, and can create a task with windows from the GUI. A task with one flat interval behaves exactly as it does today.

The minimum interval is written in two languages

emrg/server/scheduler.py owns MIN_INTERVAL, and the loader, the daemon's create/update path and the schedule validator all read it. The renderer does not: TaskFormDialog.tsx compares against a literal 60, sets min={60} on its input, and its user-facing text says "≥60" in two more places, so raising the floor in Python would leave the GUI refusing a value the daemon accepts, or accepting one it refuses.

What the fix must satisfy

  1. Editing a task that carries schedule shows one row per window with that window's days, from, to and interval, prefilled from the task record.
  2. The form can add a window, edit any of its four fields, and remove a window; the saved payload carries the resulting list.
  3. A task with no windows saves exactly as today — the payload carries no schedule key at all, so a task that had none keeps today's behaviour and one that had windows keeps them when the form was not used to change them.
  4. Removing every window from a task that had some sends schedule: null, which the daemon already reads as "one frequency all day".
  5. Creating a task from the GUI can carry windows: emrg:taskCreate must forward schedule to task_create.
  6. The minimum interval has one source — the daemon's MIN_INTERVAL — and the renderer carries no copy of it: the daemon reports the value, the form reads it from that report, and both the refusal message and the label render that same number.
  7. Tests:
    • the daemon's task-list frame carries the minimum interval;
    • the form renders one row per existing window with its values, and an added/removed window round-trips into the submitted payload;
    • a form with no windows submits no schedule key, and clearing the windows of a task that had some submits null;
    • the form refuses a window interval below the reported minimum and accepts one above it, with a reported minimum that is not the literal the renderer used to carry — so a hidden copy of the number fails the test.

Activity

  1. argszero commented on Oct 22, 2026

    @argszero
    OwnerAuthor

    Handled by #2491

  2. added a commit that references this issue on Oct 22, 2026
    9f5ca50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions