Add Schedules section to the Settings UI (#303)#304
Open
germanescobar wants to merge 3 commits into
Open
Conversation
Wires a new 'Schedules' entry into the Settings page so the user
can manage the active project's scheduled sessions without leaving
the app. The component is a thin client over the existing REST
surface in server/routes/schedules.ts (the CLI is still the
source of truth; no server changes):
* List every schedule (including disabled) with worktree, prompt
preview, trigger type, next/last run, enabled state, source,
and last error inline.
* Create via a form that mirrors the CLI: worktree (from the
project's worktrees), prompt, and either a one-shot ISO
timestamp or a cron expression + timezone. Server-side
validation errors (bad cron / timezone) are surfaced inline.
'createdBy' defaults to 'ui'.
* Toggle enabled/disabled with a Switch.
* Delete with an AlertDialog confirmation.
* View runs for a schedule in a drawer; each run with a
'sessionId' is a button that switches the main view to that
session (mirrors the 'controller://' deep-link path the
transcript already uses).
Editing an existing schedule is intentionally not exposed — the
server has no PUT route for it (non-goal). The form resets on
close; the section refreshes after every mutation.
Plumbing: 'SettingsPage' now accepts an optional 'projectId'
and 'onOpenSession' prop so the section can be project-scoped
and so runs can deep-link to a session. Both are optional so
the page still renders without an active project.
A regression test in
'client/src/components/__tests__/schedules-section.test.tsx'
covers list rendering (cron and one-shot rows, disabled badge,
last run, last error, action controls), the create form (worktree
select, prompt, trigger toggle, both one-shot and cron fields,
empty-worktree state, validation errors), the delete
confirmation flow (data-testid contract + wiring to
'deleteSchedule'), and the enable/disable switch.
Review feedback on #303: instead of scoping the Schedules section to the active project, list every project's schedules in one view so the user can see everything that's about to fire without project-hopping. The server still has no cross-project '/api/schedules' endpoint (the CLI is the source of truth for the data model, per the issue's non-goals). The section fans out client-side: list projects, then list each project's schedules, then merge. Each row carries its projectId plus a denormalised projectName so the action handlers (toggle, delete, runs) don't need a separate lookup. The create form now picks a project first and a worktree second (worktrees are loaded on demand and cached per project). The delete confirm dialog names the project so the user is sure which schedule they're removing. Regression test: 18 cases in schedules-section.test.tsx now cover the project badge per row, the project + worktree selectors, the loading state for worktrees, the empty-projects state, and the cross-project delete wiring (the confirm action must call deleteSchedule with the row's projectId, not the section's). All 632 tests in the suite pass (the one pre-existing pty-manager failure is unrelated).
Without this, calling 'npm run dev' from a clean shell (no exported VITE_API_PORT) would have the dev:server script fall back to the default 3102, while the Vite client reads .env.local via its own loadEnv and proxies to whatever port is in there (e.g. 3129 for this worktree). The two would land on different ports, and every request would 404 — which is exactly the state this worktree was in before the fix. The loader is intentionally minimal (KEY=value with optional quotes, no expansion): we only need the port keys, and pulling in dotenv for three lines is overkill. Values already set in the parent shell win, so a script that exports VITE_API_PORT explicitly is not clobbered. Discovered while debugging the empty-projects / /api/shortcuts 404 state in the dev tooling on issue #303.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new Schedules entry to the in-app Settings page so the user can manage scheduled sessions on the active project without leaving the app.
client/src/components/schedules-section.tsx— self-contained component mounted fromSECTIONSinSettings.tsx(data-testid="settings-nav-schedules").client/src/api.ts(thin client over the existing REST surface inserver/routes/schedules.ts; no server changes).SettingsPagenow accepts an optionalprojectIdandonOpenSessionso the section is project-scoped and can deep-link from a run to its session.What works end-to-end
cron/runAt), next/last run, enabled state, source, last error.createdBy: "ui".AlertDialogconfirmation (data-testid="schedule-delete-confirm").sessionIdis a button that switches the main view to that session (same path the transcript'scontroller://links take).Non-goals (deferred per the issue)
Validation
client/src/components/__tests__/schedules-section.test.tsx— 16 new tests covering list rendering (cron + one-shot rows, disabled badge, last run, last error, all action controls), the create form (worktree select, prompt, trigger toggle, both one-shot and cron fields, empty-worktree state, validation errors), the delete confirmation wiring, and the enable/disable switch.settings-responsive.test.tsx,agents-section.test.tsx, etc.). The only failing test in the suite is the pre-existingpty-manager.test.tsfailure, unrelated to this change.vite buildsucceeds.Issue
Closes #303.