Skip to content

Add task breadcrumbs#660

Merged
maccman merged 3 commits into
nextfrom
codex/task-breadcrumbs
Jul 8, 2026
Merged

Add task breadcrumbs#660
maccman merged 3 commits into
nextfrom
codex/task-breadcrumbs

Conversation

@maccman

@maccman maccman commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Problem

Reflect V1's Tasks view showed the parent outline context above task rows, for example StartupToolbox -> Reflections on a Movement, so tasks made sense even when aggregated away from their source note. reflect-open only projected task text/raw/dates into SQLite, so the Tasks view lost that context and task search could not match parent outline labels.

Before -> After

Before After
Task rows only showed the checkbox text plus date/source affordances. Desktop and mobile rows show useful parent outline breadcrumbs above the task text.
Breadcrumb context was not part of the task projection. ParsedTask, IndexedTask, SQLite tasks, and OpenTask carry breadcrumbs.
Search only matched task.text. Search also matches breadcrumb context.
Adding breadcrumbs risked shifting the checkbox/date/open affordances. Rows keep checkbox, task text, source date, and open affordance aligned on the task line while breadcrumbs sit as context.

Changes

  1. Extract task breadcrumbs in parseNote by walking parent ListItem ancestors for round Meowdown task rows, preserving rendered plain text for links/emphasis.
  2. Add tasks.breadcrumbs with migration 0017_task_breadcrumbs.sql, bump schema/projection versions, regenerate Kysely schema, and serialize the breadcrumb array through the Rust and dev SQLite write paths.
  3. Read breadcrumbs back through Zod validation in getOpenTasks / getCompletedTasks and include them in optimistic task rows.
  4. Render breadcrumbs in desktop and mobile task rows with the V1 hiding rule for single generic Tasks / Todo breadcrumbs, while keeping row controls aligned with the task text.
  5. Extend task filtering so breadcrumb text participates in search.
  6. Tighten the extraction helper names/guards around task breadcrumb traversal so the Lezer Task -> ListItem assumption is explicit.

Tests

  • Parser tests cover nested parent outline items and parent task rows as breadcrumbs.
  • Parser tests also cover nested child due-date links so parent task due dates stay scoped to the parent task row.
  • Projection and Rust DB tests cover payload shape, migration versioning, and serialized breadcrumb storage.
  • Query-boundary tests cover parsing JSON breadcrumbs and normalizing SQLite boolean fields.
  • Desktop/mobile task tests cover the updated OpenTask shape, breadcrumb rendering, and breadcrumb search behavior.

Verification

  • pnpm --filter @reflect/core test -- src/markdown/extract.test.ts src/indexing/indexed-note.test.ts src/indexing/group-tasks.test.ts (passed; package ran 90 files / 1193 tests)
  • pnpm --filter @reflect/desktop test -- src/lib/tasks/task-breadcrumbs.test.ts src/components/tasks/tasks-screen.test.tsx src/dev/dev-index-db.test.ts src/mobile/screens/tasks.test.tsx (passed; package ran 206 files / 1788 tests)
  • pnpm --filter @reflect/core test -- src/indexing/queries.test.ts src/indexing/indexed-note.test.ts src/markdown/extract.test.ts (passed; package ran 90 files / 1193 tests)
  • pnpm --filter @reflect/desktop test -- src/lib/tasks/task-visibility.test.ts src/lib/tasks/task-breadcrumbs.test.ts (passed; package ran 206 files / 1789 tests)
  • pnpm --filter @reflect/core test -- src/indexing/queries.test.ts (passed; package ran 90 files / 1194 tests)
  • pnpm --filter @reflect/desktop test -- src/components/tasks/tasks-screen.test.tsx src/mobile/screens/tasks.test.tsx src/lib/tasks/task-breadcrumbs.test.ts src/lib/tasks/task-visibility.test.ts (passed; package ran 206 files / 1789 tests)
  • pnpm --filter @reflect/core test -- src/markdown/extract.test.ts (passed; package ran 90 files / 1195 tests)
  • pnpm --filter @reflect/desktop sidecar (passed)
  • cargo test -p reflect-open db::tests (passed; 50 tests)
  • pnpm check (passed; existing packages/core/src/indexing/indexer.ts max-lines warning still appears)
  • git diff --check (passed)

Risk / Rollout

This adds a rebuildable projection column only. Existing indexes get [] from the schema migration and then receive real breadcrumbs after the projection-version bump triggers reindexing. Chat tables and non-rebuildable data are untouched.


Note

Low Risk
Rebuildable projection column with a safe default and version-bump reindex; no auth or durable non-projection data changes.

Overview
Restores V1-style parent outline context on aggregated task rows by threading breadcrumbs from markdown parse through the index into the Tasks view.

Indexing: parseNote walks parent ListItem ancestors for round + [ ] tasks and records plain-text breadcrumb labels. IndexedTask / OpenTask gain breadcrumbs; migration 0017_task_breadcrumbs.sql adds tasks.breadcrumbs (JSON, default []); schema and projection version bumps trigger reindexing for real values. Rust and dev SQLite writers serialize the array; getOpenTasks parses it with Zod.

UI: Desktop and mobile rows render chevron-separated breadcrumbs above task text (strikethrough applies to text only). visibleTaskBreadcrumbs hides lone generic headings like “Tasks” / “Todo”. Task search also matches breadcrumb text.

Reviewed by Cursor Bugbot for commit c1f43a2. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features
    • Tasks can now display breadcrumb context in both desktop and mobile views.
    • Breadcrumbs are extracted from nested task structure and included in task data throughout the app.
  • Bug Fixes
    • Search and task grouping now match on breadcrumb text as well as task text.
    • Empty or generic breadcrumb labels are hidden for cleaner task lists.
  • Chores
    • Updated schema and projection versions to support the new task data format.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This PR adds a breadcrumbs field (parent outline/list item text) to tasks end-to-end: a new SQL migration and schema/version bumps, markdown extraction of breadcrumbs from ancestor list items, projection into indexed notes, persistence in Rust and dev index DB, UI rendering via a new TaskBreadcrumbs component in desktop and mobile task rows, breadcrumb-aware search matching, and widespread test fixture updates.

Changes

Task Breadcrumbs

Layer / File(s) Summary
Schema, migration, and data contracts
crates/index-schema/migrations/0017_task_breadcrumbs.sql, crates/index-schema/src/lib.rs, packages/db/src/schema.gen.ts, packages/core/src/markdown/model.ts
Adds a breadcrumbs column via migration, bumps LATEST_SCHEMA_VERSION to 17, adds breadcrumbs to Tasks/ParsedTask types, and bumps PARSED_NOTE_VERSION to 4.
Markdown extraction of breadcrumbs
packages/core/src/markdown/extract.ts, packages/core/src/markdown/extract.test.ts
Computes task breadcrumbs by walking ancestor ListItem nodes, updates readTask/parseNote to use task syntax nodes and return breadcrumbs, and adds tests including due-date non-inheritance.
Indexed-note projection and task queries
packages/core/src/indexing/indexed-note.ts, .../indexed-note.test.ts, .../queries-tasks.ts, .../queries.test.ts
Bumps PROJECTION_VERSION to 15, adds breadcrumbs to indexedTaskSchema/OpenTask, selects and JSON-parses breadcrumbs in toTaskRow, with new tests.
Desktop Rust persistence
apps/desktop/src-tauri/src/db/write.rs, apps/desktop/src-tauri/src/db/tests.rs
Adds breadcrumbs to IndexedTask, serializes it into the tasks INSERT, and asserts schema version and persisted breadcrumbs JSON in tests.
Dev index DB persistence
apps/desktop/src/dev/dev-index-db.ts, .../dev-index-db.test.ts
Serializes task.breadcrumbs into the browser tasks INSERT and updates fixture/assertions.
TaskBreadcrumbs UI component and utility
apps/desktop/src/lib/tasks/task-breadcrumbs.ts(.test.ts), apps/desktop/src/components/tasks/task-breadcrumbs.tsx
Adds visibleTaskBreadcrumbs to normalize/filter labels and a TaskBreadcrumbs component rendering a chevron-separated breadcrumb row.
Desktop and mobile task row rendering
apps/desktop/src/components/tasks/task-row.tsx, apps/desktop/src/mobile/task-row.tsx
Wires breadcrumbs into desktop TaskRow (with layout refactor) and mobile MobileTaskRow (grid layout with conditional spacing).
Breadcrumb-aware task search
apps/desktop/src/lib/tasks/task-visibility.ts(.test.ts)
Adds taskMatchesNeedle to match search needles against text or breadcrumbs, used in composeVisibleTaskGroups.
Task fixture updates across other test suites
apps/desktop/src/...test.ts(x) (multiple), packages/core/src/indexing/group-tasks.test.ts
Updates local task() helpers to include a breadcrumbs field matching the extended OpenTask shape.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related PRs

  • team-reflect/reflect-open#214: Both PRs modify apps/desktop/src/components/tasks/task-row.tsx, with this PR adding breadcrumb rendering on top of the prior TaskRow refactor.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding task breadcrumbs.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/task-breadcrumbs

Comment @coderabbitai help to get the list of available commands.

@maccman maccman merged commit 7013d46 into next Jul 8, 2026
6 of 7 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
packages/core/src/indexing/queries-tasks.ts (1)

15-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider readonly string[] for the new field.

Other array-ish immutable fields in this codebase's conventions favor readonly; breadcrumbs is derived, read-only data.

As per coding guidelines, "Use readonly fields for immutable data."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/indexing/queries-tasks.ts` around lines 15 - 16, The new
breadcrumbs field in the query task types should be modeled as immutable data,
so update the relevant type definition around breadcrumbs to use readonly
string[] instead of a mutable array. Keep the change localized to the task/query
model declarations in queries-tasks.ts and align it with the existing
conventions for read-only derived fields.

Source: Coding guidelines

apps/desktop/src/mobile/task-row.tsx (1)

44-49: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider an explicit row placement for TaskBreadcrumbs.

TaskBreadcrumbs here only sets col-start-2, relying on CSS grid auto-placement to land it in row 1 (since the button/div below it explicitly claim row 2). This works correctly per the grid auto-placement algorithm, but it's implicit — reordering elements or adding new explicitly-placed grid children later could silently shift it. Adding row-start-1 would make the intent explicit and guard against future breakage.

♻️ Optional clarity improvement
       {hasBreadcrumbs ? (
         <TaskBreadcrumbs
           breadcrumbs={breadcrumbs}
-          className="col-start-2 mb-0 min-w-0 pr-4 pt-3"
+          className="col-start-2 row-start-1 mb-0 min-w-0 pr-4 pt-3"
         />
       ) : null}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/mobile/task-row.tsx` around lines 44 - 49, TaskBreadcrumbs
is relying on implicit grid auto-placement for its row position; update the
TaskBreadcrumbs usage in task-row.tsx to explicitly claim the first row as well
as the second column so its placement is stable. Keep the existing
TaskBreadcrumbs props and className context, and add an explicit row-start
placement to the same element so future grid children or reordering cannot shift
it unexpectedly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/desktop/src/mobile/task-row.tsx`:
- Around line 44-49: TaskBreadcrumbs is relying on implicit grid auto-placement
for its row position; update the TaskBreadcrumbs usage in task-row.tsx to
explicitly claim the first row as well as the second column so its placement is
stable. Keep the existing TaskBreadcrumbs props and className context, and add
an explicit row-start placement to the same element so future grid children or
reordering cannot shift it unexpectedly.

In `@packages/core/src/indexing/queries-tasks.ts`:
- Around line 15-16: The new breadcrumbs field in the query task types should be
modeled as immutable data, so update the relevant type definition around
breadcrumbs to use readonly string[] instead of a mutable array. Keep the change
localized to the task/query model declarations in queries-tasks.ts and align it
with the existing conventions for read-only derived fields.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 489a8f6d-f0b0-4c9d-a875-57cf20febb75

📥 Commits

Reviewing files that changed from the base of the PR and between 0ede4a7 and b4ed6c6.

📒 Files selected for processing (30)
  • apps/desktop/src-tauri/src/db/tests.rs
  • apps/desktop/src-tauri/src/db/write.rs
  • apps/desktop/src/components/tasks/task-breadcrumbs.tsx
  • apps/desktop/src/components/tasks/task-row.tsx
  • apps/desktop/src/components/tasks/tasks-screen.test.tsx
  • apps/desktop/src/dev/dev-index-db.test.ts
  • apps/desktop/src/dev/dev-index-db.ts
  • apps/desktop/src/lib/tasks/recently-completed.test.ts
  • apps/desktop/src/lib/tasks/task-breadcrumbs.test.ts
  • apps/desktop/src/lib/tasks/task-breadcrumbs.ts
  • apps/desktop/src/lib/tasks/task-cache.test.ts
  • apps/desktop/src/lib/tasks/task-insert-target.ts
  • apps/desktop/src/lib/tasks/task-navigation.test.ts
  • apps/desktop/src/lib/tasks/task-visibility.test.ts
  • apps/desktop/src/lib/tasks/task-visibility.ts
  • apps/desktop/src/lib/tasks/use-task-keyboard.test.ts
  • apps/desktop/src/mobile/screens/tasks.test.tsx
  • apps/desktop/src/mobile/task-row.tsx
  • apps/desktop/src/mobile/use-task-sheet-finalizer.test.ts
  • crates/index-schema/migrations/0017_task_breadcrumbs.sql
  • crates/index-schema/src/lib.rs
  • packages/core/src/indexing/group-tasks.test.ts
  • packages/core/src/indexing/indexed-note.test.ts
  • packages/core/src/indexing/indexed-note.ts
  • packages/core/src/indexing/queries-tasks.ts
  • packages/core/src/indexing/queries.test.ts
  • packages/core/src/markdown/extract.test.ts
  • packages/core/src/markdown/extract.ts
  • packages/core/src/markdown/model.ts
  • packages/db/src/schema.gen.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant