# 0.34.0 — 2026-07-24 — "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 `archiveTask` action 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)` and `bulkDeleteTasks(ids?)` use `Promise.allSettled` over strict task reads so a single failed file cannot abort the batch. An in-flight guard prevents two destructive runs from racing each other. `nextTaskId` now considers archived ids so new tasks cannot reuse a number that already lives in `tasks/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. `SubtaskEditor` owns the section UI while the drawer/workspace persists edits through the existing `saveDrawer` autosave path.
- **Fixed**: **Subtask markdown round-trip preserves hand-written prose** — `extractSubtasks` and `injectSubtasks` now preserve unrelated lines that share the `## Subtasks` section, 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 `Drawer` and `TaskWorkspace`, 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/:id` routes now read from and write to the `tasks/archive/` directory, accept `POST /api/tasks/:id/archive` and `…/unarchive`, validate task ids, and remove both the active and archived files on `DELETE`. The dev middleware in `vite.config.ts` resolves tasks at the project-root `tasks/` 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-label` and `aria-haspopup` attributes on the new menu, and a `Card isMountedRef` reset 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.
