Files
gems/docs/design/web-cli-parity.md
T
joakim 0e3750e755 fix: resolve all 15 svelte-check type errors
- Type headers as Record<string, string> in apiRequest (client.js)
- Annotate SyncResult on result object, cast catch vars to any (sync.js)
- Widen sync.push param to Partial<Task>[] (endpoints.js)
- Fix parse() return type to reflect {task?: Task} shape (endpoints.js)
- Narrow add() param from Partial<Task> to Task (tasks.js)
- Cast parseAndCreate result to Task (tasks.js)
- Type tasksByProject grouped object as Record<string, Task[]> (tasks.js)

svelte-check now reports 0 errors and 0 warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 01:09:18 +01:00

21 KiB

Web CLI Parity — Requirements Spec

Status: Draft Last updated: 2026-02-19 Related: cli-ux-improvements.md — CLI UX improvements being developed in parallel. Features marked with (CLI dep) depend on or benefit from CLI-side work landing first.

This document covers the features the CLI exposes that the web frontend does not. Each section maps a CLI capability to a proposed web feature, with acceptance criteria and priority.


Problem Statement

The opal CLI is the primary interface and offers rich task management: in-place editing, start/stop timers, detailed task info, project/tag browsing, bulk operations, and full sync controls. The web frontend currently only supports create, complete, delete, and report-based listing. Users who switch between CLI and web hit a wall — most tasks that go beyond "add" and "done" require falling back to the terminal.


Tier 1 — Core Gaps (the web feels broken without these)

1.1 Task Detail View (info equivalent)

CLI: opal info 2 shows every field on a task — UUID, status, description, urgency, priority, project, all timestamps (created, modified, started, ended, due, scheduled, wait, until), recurrence pattern, parent UUID, and tags.

Web gap: Tapping a task does nothing. There is no way to see a task's full state.

User story: As a user, I want to tap a task to see all of its fields so that I can understand its full context without switching to the CLI.

Acceptance criteria:

  • Given a task in the list, when I tap it, then a detail view opens showing every non-null field on the task
  • Given a task with a recurrence pattern, when I view its detail, then the recurrence interval and parent template link are visible
  • Given a task with scheduled/wait/until dates, when I view its detail, then those dates are displayed with labels
  • Given a task detail view, when I tap outside or press a close/back control, then the detail view closes and the list is restored

Interaction: Bottom sheet — slides up from the bottom of the screen. Natural on mobile, avoids a route change, and leaves the task list partially visible behind it. Light-dismiss (tap scrim to close).

Priority: MUST


1.2 Task Editing (modify / edit equivalent)

CLI: opal 2 modify priority:H due:friday changes attributes inline. opal 2 edit opens $EDITOR with all fields in a structured format.

Web gap: There is no way to edit a task after creation. Users must delete and recreate to fix a typo or change a due date.

User story: As a user, I want to edit any field on an existing task so that I can adjust it as my plans change.

Acceptance criteria:

  • Given a task detail view, when I tap an editable field, then I can modify its value
  • Given I change a field and confirm, when the update succeeds, then the task list reflects the change
  • Given I change a field and confirm, when the update fails, then the error is shown and the original value is preserved
  • Editable fields: description, project, priority, due, scheduled, wait, until, tags, recurrence (on templates)
  • Read-only fields (displayed but not editable): UUID, created, modified, end, parent UUID, status

Implementation notes:

  • Uses PUT /tasks/:uuid — already exists in the API
  • For tags, uses POST /tasks/:uuid/tags and DELETE /tasks/:uuid/tags/:tag — already exist
  • Field editing could be inline (tap field to edit) or form-based (edit mode that makes all fields editable). Inline feels lighter for single-field tweaks.

Priority: MUST


1.3 Start / Stop Timer (start / stop equivalent)

CLI: opal 1 start marks a task as actively being worked on (sets start timestamp). opal 1 stop clears it. The active report lists started tasks.

Web gap: The API endpoints (POST /tasks/:uuid/start, POST /tasks/:uuid/stop) are wired in endpoints.js but there are no UI controls. The active report works in the report picker but users can't actually start tasks.

User story: As a user, I want to mark a task as "in progress" so that I can track what I'm actively working on and see it in the Active report.

Acceptance criteria:

  • Given a pending task, when I tap a start control, then the task's start time is set and it appears in the Active report
  • Given a started task, when I tap a stop control, then the start time is cleared
  • Given a started task, when I view it in the list, then there is a visual indicator that it is active (distinguishable from non-started tasks)
  • The start/stop action should be accessible from both the task row and the detail view

Interaction: Swipe left to toggle start/stop — mirrors swipe right for complete. Also accessible from the detail view (1.1). No visible button on the task row.

Priority: MUST


1.4 Uncomplete / Revert (modify status:pending equivalent)

(CLI dep) — CLI is getting a dedicated uncomplete command and a generic undo (see IMP-1). The web feature should align with however the CLI exposes this so the mental model is consistent.

CLI: opal <id> modify status:pending reverts a completed task. IMP-1 proposes opal <id> uncomplete and opal undo as dedicated commands.

Web gap: Once a task is completed it disappears from the pending list. The only recovery is the completed report + CLI. This is also called out in BUGS.md as a missing feature.

User story: As a user, I want to undo an accidental completion so that the task reappears in my pending list.

Acceptance criteria:

  • Given a completed task (visible in the Completed report), when I tap an uncomplete action, then the task's status reverts to pending and it reappears in the pending list
  • Given I just completed a task, when I tap undo within a brief window (e.g. toast with undo button), then the task is reverted without navigating to the Completed report

Implementation notes:

  • Uses PUT /tasks/:uuid with {"status": "pending"} — works today
  • The undo toast after completion is a UX nicety but not strictly required for parity
  • If CLI IMP-1 lands an undo log table, the web could use the same mechanism for a more robust undo (revert any action, not just completion)

Priority: MUST


1.5 Delete Confirmation

(CLI dep) — CLI is improving confirmation prompts to show matched tasks before confirming (see IMP-3). The web confirmation should follow the same pattern.

CLI: opal delete always prompts Proceed? (y/N) before deleting. IMP-3 proposes showing the affected task(s) in the confirmation.

Web gap: Delete is instant with no confirmation. There is no undo.

User story: As a user, I want a confirmation before deleting a task so that I don't lose work by accident.

Acceptance criteria:

  • Given I trigger a delete action, when the confirmation appears, then I must explicitly confirm before the delete proceeds
  • Given I dismiss the confirmation, then the task is not deleted
  • The confirmation should show the task description (matching CLI IMP-3's approach of showing what will be affected)

Priority: MUST


Tier 2 — CLI Parity (brings the web up to feature-complete)

2.1 Projects View — DEFERRED

2.2 Tags View — DEFERRED

Projects and tags browsing is deferred. The existing filter syntax (project:foo, +tag) covers this adequately for now. When filter autocomplete is added later, discoverability will improve without needing dedicated views.


2.3 Display All Date Fields on Task Items

CLI: opal info and the table display show scheduled, wait, until, and start dates when present. The waiting report makes sense because you can see when the wait expires.

Web gap: Only the due date is shown on task rows. Scheduled, wait, until, and start dates are invisible. Users can set them via CLI syntax in the input bar but can't see them afterward.

User story: As a user, I want to see all relevant dates on a task so that I understand when it's scheduled, when it becomes visible, and when it expires.

Acceptance criteria:

  • Given a task with a scheduled date, then a "Scheduled: " indicator appears on the task row
  • Given a task with a wait date, then a "Wait: " indicator appears
  • Given a task with an until date, then an "Until: " indicator appears
  • Given a task with a start time set, then an "Active since
  • Date fields that are null are not shown (no empty labels)
  • The detail view (1.1) shows all dates; the task row shows them in a compact/abbreviated form

Priority: SHOULD


2.4 Recurrence Display and Management

(CLI dep) — CLI is improving recurring task feedback on completion (see IMP-7). The web should show equivalent feedback when completing a recurring task.

CLI: opal add "standup" due:mon recur:1w creates a recurring template + first instance. opal template and opal recurring list them. Completing an instance spawns the next one. opal edit <id> on an instance can update the template's recurrence pattern.

Web gap: Recurring tasks can be created via CLI syntax in the input bar, and the recurring/template reports work, but:

  • There is no visual indicator that a task is a recurring instance
  • There is no way to see or navigate to the parent template
  • There is no way to edit the recurrence pattern
  • Completing a recurring task gives no feedback about the next instance

User story: As a user, I want to see which tasks are recurring, view their schedule, and manage the recurrence pattern so that I can adjust repeating commitments.

Acceptance criteria:

  • Given a recurring instance, when I view it in the list, then a recurrence icon or badge is visible
  • Given a recurring instance, when I open its detail view, then the recurrence interval and parent template are shown
  • Given a recurring template, when I open its detail view, then I can edit the recurrence interval
  • Given I complete a recurring instance, then the next instance is automatically created (this already works server-side; just verify the list refreshes to show it)
  • Given I complete a recurring instance, then a toast or inline message shows the next instance's due date (mirrors CLI IMP-7)

Priority: SHOULD


2.5 Sync Controls — DEFERRED

Sync is deprioritized. The web has no client-side task parsing, so offline functionality is non-functioning. The web fetches directly from the server on every action — sync is only relevant if we move to an offline-first model, which is not planned.


2.6 Bulk Operations (opal 1 2 3 modify ... / opal +tag done)

CLI: Filters and numeric IDs can target multiple tasks. opal +urgent done completes all tasks tagged urgent. opal 1 2 3 modify project:sprint-2 moves three tasks at once. The CLI prompts for confirmation when multiple tasks are affected.

Web gap: All actions are single-task only. No multi-select, no batch complete, no batch modify.

User story: As a user, I want to select multiple tasks and perform an action on all of them so that I can manage tasks efficiently.

Acceptance criteria:

  • Given I enter selection mode (e.g., long-press a task), then I can tap additional tasks to add them to the selection
  • Given I have tasks selected, then I can batch-complete, batch-delete, or batch-modify (at minimum: change project, add/remove tag, change priority)
  • Given a batch action targets 2+ tasks, then a confirmation prompt appears before executing
  • Given I tap outside the selection or press a cancel control, then selection mode is exited

Priority: SHOULD


Tier 3 — Power User & Polish

3.1 Keyboard Shortcuts

CLI: The CLI is entirely keyboard-driven by nature.

Web gap: No keyboard shortcuts exist. Desktop users must use the mouse for everything.

User story: As a desktop user, I want keyboard shortcuts so that I can manage tasks without reaching for the mouse.

Suggested bindings:

Key Action
n Focus the input bar (new task)
j / k Move selection down / up in task list
x Complete selected task
e Open detail/edit for selected task
d Delete selected task (with confirmation)
s Start/stop selected task
Escape Close detail view / deselect / blur input
/ Open filter modal

Acceptance criteria:

  • Given I press n when not focused on an input, then the input bar is focused
  • Given I press j/k, then the visual selection moves through the task list
  • Given I press x with a task selected, then that task is completed
  • Shortcuts are disabled when an input or textarea is focused (except Escape)

Priority: COULD


CLI: Filtering by tags, project, priority, and status covers structured attributes, but there's no full-text description search in the CLI either.

Web opportunity: The web could add a search capability that the CLI lacks.

User story: As a user, I want to search tasks by description text so that I can find a specific task without remembering its tags or project.

Acceptance criteria:

  • Given I type in a search field, then the task list filters to tasks whose description contains the search text (case-insensitive)
  • Search can be client-side (filter the loaded report) or server-side (new query param)

Interaction: Extends the existing filter syntax. Bare text in the filter input is interpreted as a description search. The filter modal becomes filter/search — no separate search bar.

Priority: COULD


3.3 Display IDs — DROPPED

Not needed. The web uses touch/tap interaction, not keyboard-driven ID selection. Display IDs are a CLI affordance that doesn't translate to the web interaction model.


3.4 API Key Management — ON HOLD

Blocked on user management investigation. Open questions: Are API keys user-scoped? Should we move to per-user databases? This feature should wait until the auth/user model is settled.


3.5 Task Annotations (annotate equivalent)

(CLI dep) — The CLI is adding opal <id> annotate "<text>" (see IMP-11). This requires a backend schema change (annotations storage). Once that lands, the web should surface annotations.

CLI (proposed): opal 3 annotate "Traced to token expiry" adds a timestamped note. opal 3 info shows annotations. IMP-11 notes potential integration with jade-depo (the gems note management system).

Web gap: No concept of annotations exists. Tasks have only a description field for text.

User story: As a user, I want to add and view notes on a task so that I can record progress and context over time.

Acceptance criteria:

  • Given a task detail view (1.1), then any existing annotations are shown as a timestamped list below the task fields
  • Given a task detail view, when I tap an "Add note" control, then I can enter annotation text and it is saved with a timestamp
  • Annotations are ordered newest-first or oldest-first (decide which)
  • Annotations are read-only after creation (no inline editing — denotate removes the latest)

Decisions:

  • Annotations are visible only in the detail view (1.1), not on the task row.
  • jade-depo integration is not relevant to the web UI at this time.

Priority: COULD (blocked on CLI IMP-11 landing the backend schema)


3.6 Task History (log equivalent)

(CLI dep) — The CLI is adding opal <id> log (see IMP-12). This reads the existing change_log table which already exists for sync.

CLI (proposed): opal 3 log shows timestamped change history (created, modified, completed, etc.).

Web gap: No way to see what happened to a task over time.

User story: As a user, I want to see a task's change history so that I can understand when and how it was modified.

Acceptance criteria:

  • Given a task detail view (1.1), then a "History" section or tab shows the change log for that task
  • Each entry shows: timestamp, change type, and what changed (e.g., "priority: default -> high")
  • History is read-only

Implementation notes:

  • The change_log table already exists for sync. This likely needs a new API endpoint (GET /tasks/:uuid/log or similar) to expose it.
  • Alternatively, the change log could be included in the task detail response.

Priority: COULD (blocked on CLI IMP-12 / API endpoint)


3.7 Configurable Default Report

CLI: default_report in opal.yml controls what opal with no arguments shows (default: list). default_filter controls the base filter.

Web gap: The web always starts on the list report. There is no user preference for the landing view.

User story: As a user, I want to choose which report I see when I open the app so that my most-used view loads first.

Acceptance criteria:

  • Given I choose a default report in settings, then the app opens to that report on next launch
  • The preference is stored in localStorage (no backend change needed)

Priority: COULD


Non-Functional Requirements

# Requirement Priority
NFR-1 All new features must work on Android Chrome and desktop Chrome/Firefox (per architecture doc) MUST
NFR-2 Task detail and edit interactions must be touch-friendly (44px minimum tap targets) MUST
NFR-3 Editing a task must be optimistic — UI updates immediately, rolls back on failure SHOULD
NFR-4 Keyboard shortcuts must not conflict with browser defaults (Ctrl+T, etc.) MUST
NFR-5 New features must work with all three themes (Obsidian, Paper, Midnight) MUST
NFR-6 No new API endpoints are required for Tier 1 — all endpoints already exist N/A

Constraints & Assumptions

Constraints:

  • Single-screen architecture per the existing design doc — no new routes for projects/tags (use sheets/modals/filters instead)
  • Server-side parsing and sorting — the frontend stays a thin shell
  • SvelteKit + Vite stack, Svelte 5 runes

Assumptions:

  • The PUT /tasks/:uuid endpoint accepts partial updates (only fields present in the request body are changed)
  • The working set display IDs are not currently exposed via the API; Tier 3.3 would require an API change
  • Sync transport (pull/push) works correctly; the gap is only in applying pulled changes to the store

Cross-Reference: CLI UX Improvements

The following items from cli-ux-improvements.md directly affect web features in this spec:

CLI IMP CLI Feature Web Impact
IMP-1 Undo / uncomplete Enables 1.4 (uncomplete). If undo log is stored in DB, web can use same mechanism.
IMP-2 Better add feedback Web already shows the created task in-list. No direct web change, but if the API response for POST /tasks/parse is enriched (display ID, parsed modifiers), the web could show a richer confirmation toast.
IMP-3 Show matched tasks in confirmations Pattern for 1.5 (delete confirmation) and 2.6 (bulk ops).
IMP-5 Handle colons in descriptions Affects web input bar — same parsing runs server-side via /tasks/parse. No web change needed, but web benefits automatically.
IMP-7 Recurring task feedback Directly feeds 2.4 (recurrence display).
IMP-9 Relative dates in CLI Web already does this. No change needed.
IMP-11 Task annotations Enables 3.5 (annotations on web). Blocked on backend schema.
IMP-12 Task history Enables 3.6 (history on web). Blocked on API endpoint.

Items from the CLI spec with no web impact: IMP-4 (delete ID resolution bug), IMP-6 (consistent error codes), IMP-8 (shell completions), IMP-10 (dry-run flag), IMP-13 (version command).


Out of Scope

  • Collaboration / multi-user sharing
  • Notifications, reminders, or push alerts
  • Custom fields or metadata
  • Drag-to-reorder (ordering is report/urgency-driven)
  • Offline-first / IndexedDB task storage (tasks are server-side only)
  • iOS Safari support

Open Questions Summary

# Question Blocks Status
Q1 Detail view format 1.1 Resolved — bottom sheet
Q2 Start/stop control placement 1.3 Resolved — swipe left
Q3 Projects/tags view format 2.1, 2.2 Resolved — deferred, use filters
Q4 Description search format 3.2 Resolved — extend filter syntax
Q5 Display IDs 3.3 Resolved — dropped
Q6 Annotation visibility 3.5 Resolved — detail view only
Q7 jade-depo integration 3.5 Resolved — not for web