4.0 KiB

SLICE 3 — scope: all (every notebook)

State-saving rule: update this file immediately after EVERY completed task (tick the checkbox, update Status and Resume notes) and whenever pausing for input — automatically, without being asked. State on disk must always match reality.

Status

COMPLETE (2026-07-15). SLICE1 & SLICE2 done; all tasks landed; 120/120 tests pass; full npm run dist builds clean.

Goal

scope: all on any view block scans every notebook in the Joplin profile. User explicitly wants this despite the cost ("very dangerous, yes").

Design

  • resolveScopedFolderIds gains an "all" path: return every folder id (skip BFS entirely). Config parsers map scope: all → a sentinel (e.g. scopeDepth = -1 or a separate scopeAll: boolean) — decide during implementation, keep the type honest.
  • Guardrails (agreed):
    • Prominent "scanned N notebooks / M notes" footnote when scope is all (stats plumbing already exists in every payload).
    • Body-fetch optimization from SLICE1 applies.
    • Soft warning in the rendered view when scanned notes exceed ~2000 (advisory only, never blocks).
  • notebook: + scope: all together: all wins; warn about the ignored notebook: key.

Design decisions (as implemented)

  • Representation: a separate scopeAll: boolean on each config (not a scopeDepth sentinel) — all is not a tree depth, so an honest flag reads cleaner and keeps scopeDepth meaningful.
  • Scope resolution lives in folderScope.ts: resolveScopedFolderIds gains a 4th scopeAll = false param; when true it returns folders.map(id) and skips BFS entirely (root/depth ignored).
  • notebook: + scope: all: parser emits a warning and all wins; resolveScanFolder short-circuits to the host folder (root is irrelevant when every notebook is scanned).
  • Soft cap: index.ts pushes a ⚠ warning when scopeAll and scanned notes

    2000 (SCOPE_ALL_SOFT_CAP), advisory only. Footnote: payloads carry scopeAll; the webview appends · scope: all (every notebook) to the existing stats meta line in all three render paths.

Tasks

  • Parser changes (all three view types) + warnings for conflicts. Done: scope: allscopeAll=true in calendar/kanban/matrix parsers; notebook+all conflict warning in each.
  • folderScope.ts all-folders path + tests. Done (4th param; collectors pass config.scopeAll).
  • Footnote + soft-cap warning in webview render paths. Done: scopeAll on payloads + meta-line marker (3 paths); soft-cap warning via warnings[] (rendered as ⚠, no extra webview work — existing warning path).
  • Tests: parser, scope resolution, collector with multi-root folders. src/tests/Gtd/scopeAll.test.ts — parser (all three + conflict + no-false- positive), folderScope scopeAll path + unchanged non-all behaviour, and a multi-root collector integration proving all spans disconnected notebooks. 8 new cases.
  • Docs: README (3 scope rows + calendar caution) + SPEC.md §2.1 row and all three example blocks, including the performance/guardrail caution.
  • Full test run: 120 passed, 120 total (11 suites) on 2026-07-15. npm run dist builds clean; archive rule confirmed working.

Resume notes

SLICE3 complete. Files touched:

  • src/Gtd/types.ts (scopeAll on all three configs)
  • src/Gtd/folderScope.ts (scopeAll param + all-folders path)
  • src/Gtd/parseCalendarConfig.ts, parseKanbanConfig.ts, parseMatrixConfig.ts (scope: all + notebook-conflict warning; kanban/matrix now parse notebook before the return so the conflict check has it)
  • src/Gtd/collectEvents.ts, collectKanban.ts, collectMatrix.ts (pass scopeAll)
  • src/index.ts (resolveScanFolder short-circuit, SCOPE_ALL_SOFT_CAP + scopeAllSoftCapWarning, scopeAll on 3 payloads)
  • src/gtd-calendar-webview.js (footnote marker in 3 stats blocks)
  • src/tests/Gtd/scopeAll.test.ts (new)
  • README.md, SPEC.md

Next: SLICE4.