76 lines
4.0 KiB
Markdown

# 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
- [x] Parser changes (all three view types) + warnings for conflicts. Done:
`scope: all``scopeAll=true` in calendar/kanban/matrix parsers;
notebook+all conflict warning in each.
- [x] `folderScope.ts` all-folders path + tests. Done (4th param; collectors
pass `config.scopeAll`).
- [x] 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).
- [x] 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.
- [x] Docs: README (3 scope rows + calendar caution) + SPEC.md §2.1 row and all
three example blocks, including the performance/guardrail caution.
- [x] 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.