Changelog
2026-07-24v0.34.0— Quick-Wins Collection
- Added: Quick archive button on every card — task cards in the board and list views now expose a one-click archive action next to the existing guarded delete button. Archiving is reversible from the archive view and reuses the existing store
archiveTaskaction so files, watchers, and broadcasts stay consistent. - Added: Terminal-column bulk actions — the column whose name matches the configured terminal status now shows a dedicated Manage tasks menu with Archive all and Delete all entries. Both confirm the exact task count and column name before mutating anything; deletions are permanent, archive operations can be undone from the archive view.
- Added: Robust bulk task actions —
bulkArchiveTasks(ids)andbulkDeleteTasks(ids?)usePromise.allSettledover strict task reads so a single failed file cannot abort the batch. An in-flight guard prevents two destructive runs from racing each other.nextTaskIdnow considers archived ids so new tasks cannot reuse a number that already lives intasks/archive/. - Added: Subtask editor in the task drawer and workspace — both surfaces re-mount the original checklist editor (toggle, edit, enter-to-insert, backspace-to-remove, expand description/report) that was previously removed.
SubtaskEditorowns the section UI while the drawer/workspace persists edits through the existingsaveDrawerautosave path. - Fixed: Subtask markdown round-trip preserves hand-written prose —
extractSubtasksandinjectSubtasksnow preserve unrelated lines that share the## Subtaskssection, support multi-line[DESC]/[REPORT]markers, and treat- [ ](empty text) as a valid checklist row so a fresh row can be created without immediately supplying text. - Fixed: Subtask editor stays above hooks — the SubtaskEditor handler is defined before the desktop/media-query guard in both
DrawerandTaskWorkspace, restoring the React rules-of-hooks order and eliminating a mobile-drawer crash. - Fixed: Server-mode archive round-trip — the production daemon's
/api/tasks/:idroutes now read from and write to thetasks/archive/directory, acceptPOST /api/tasks/:id/archiveand…/unarchive, validate task ids, and remove both the active and archived files onDELETE. The dev middleware invite.config.tsresolves tasks at the project-roottasks/directory (the canonical location since v0.12) and exposes the same archive routes. - Fixed: SPA fallback for deep links — the daemon now serves the single-file app for any non-API path, so refreshing on a deep task URL (e.g.
/2?p=project) keeps the client routing intact. - Changed: File watcher covers the archive directory — the CLI content-hash watcher also tracks
tasks/archive/*.md, so archived task updates still trigger board reloads and notifications. - Changed: Card action group and a11y — the card's right-corner actions now live in a flex group that reveals both archive and delete on hover or keyboard focus, with
aria-labelandaria-haspopupattributes on the new menu, and aCard isMountedRefreset so React StrictMode double-mount doesn't disable the buttons. - Changed: i18n strings — English and French locales gain new keys for archive/delete-all prompts, subtask a11y labels, and progress messages. English remains the source of truth; untranslated keys fall back automatically.