diff options
| author | Adam Malczewski <[email protected]> | 2026-06-29 21:40:39 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-29 21:40:39 +0900 |
| commit | 5a7a30ffbfcbcae3ae3049dc6330468a049fa9ba (patch) | |
| tree | e0d2aaadccbdfebea48d4d7b947295eb964a240c /src/features/vision | |
| parent | 1cdb866fbb708a1f6c5e802a075789cece85800d (diff) | |
| download | dispatch-web-5a7a30ffbfcbcae3ae3049dc6330468a049fa9ba.tar.gz dispatch-web-5a7a30ffbfcbcae3ae3049dc6330468a049fa9ba.zip | |
feat(heartbeat): add inactiveOnly checkbox (skip fires while workspace is busy)
Add the frontend UI for the backend's per-workspace heartbeat `inactiveOnly`
setting (default on): when on, the heartbeat skips a scheduled fire whenever
the configured workspace has any active agents (a conversation whose status is
"active" or "queued"); it stays quiet while the user is actively working and
only fires when the workspace is idle. When off, the heartbeat fires
unconditionally on every interval (the pre-existing behavior).
Contract (backend handoff: notes/heartbeat-setting-handoff.md):
- GET /workspaces/:id/heartbeat now includes inactiveOnly: boolean
- PUT /workspaces/:id/heartbeat accepts a partial { inactiveOnly?: boolean }
(absent = unchanged; explicit false = opt-out; non-boolean → 400)
The heartbeat shapes are FE-owned locally (consumer-defines-port — not in
@dispatch/transport-contract; verified the mirror has no heartbeat symbol), so
this is a FE-local type + view-model + UI change — no pinned file: dep bump or
.dispatch mirror regen needed. The network seam (store.svelte.ts) needed no
change: setHeartbeatConfig already JSON.stringify's the patch verbatim and
normalizes the response via normalizeHeartbeatConfig (now producing the field).
Implementation (pure core / injected shell):
- types.ts: inactiveOnly on HeartbeatConfig + HeartbeatConfigPatch
- view-model.ts (pure): inactiveOnly in HeartbeatFormState; formFromConfig/
emptyForm/patchFromForm/formDiffers carry it; normalizeHeartbeatConfig
coerces with `d.inactiveOnly !== false` (default ON — mirrors the backend
config-store deserializer; only explicit false opts out, so a legacy config
persisted before the field reads back as true)
- HeartbeatView.svelte: a checkbox (default checked) "Only run when idle" as
the first config section, save-on-change (mirrors the enable toggle): a
partial PUT { inactiveOnly } on toggle; a failed save reverts + surfaces the
error inline
Tests: new HeartbeatView.test.ts (renders checked/unchecked, partial-patch PUT,
failed-save revert); view-model.test.ts form/normalize/diff coverage; updated
PromptEditor.test.ts + store.test.ts echo fixtures for the new required field.
Verification: typecheck 0 errors; test 1133 passing (stable x2); biome clean;
build succeeds. Live read-only check: the running main backend (not the
feature worktree backend) has no inactiveOnly yet; the FE's defensive default
renders the checkbox checked and degrades gracefully — no crash. No backend
was booted by the agent.
backend-handoff.md §2l records the consumed contract + FE status.
Diffstat (limited to 'src/features/vision')
0 files changed, 0 insertions, 0 deletions
