Standardize on the .agents/ directory (shared with project skills): phases/, user_stories/, reports/, screenshots/, validate.sh, and phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves history; runtime artifacts move alongside). Updates every reference in AGENTS.md, README.md, .gitignore, app docstrings, and test story headers. Historical KB content in data/ and the runtime pipeline.log transcript are left untouched.
2.6 KiB
Story: Local directory sources
Phase: 38_local_directory_sources · E2E: tests/e2e/test_local_directory_sources.py
Narrative
As the admin (owner), some of my documents live in plain directories
that are not git repos — today the only way to index them is the CLI's
--source flag, which the web app's Sync path ignores. I want to add an
existing local directory as a source from the same admin page as the git
sources, and have the Sync button and import_docs import it alongside the
git checkouts.
- Given I am signed in as admin, and
~/Notesis a plain (non-git) directory - When I add it on the sources page and click Sync
- Then the directory is walked and imported together with the git checkouts in one run (pruning over the union), and a missing directory fails the run loudly instead of importing a partial KB.
Acceptance criteria
- Migration 0007:
git_sources.kind TEXT NOT NULL DEFAULT 'git'(check:git|local) +git_sources.path TEXT NULL(unique; non-null only for local) — reversible, up/down integration-tested (the 0004–0006 pattern). - The admin API (phase 35) accepts
kind:gitrows validateurlexactly as today;localrows requirepath(trimmed, expanded, absolute, existing directory on the server → else 422 naming the path); 409 on duplicate (per kind); GET rows carrykind+path(env fallback rows are git-only). - The sync pipeline and
import_docsresolve DB git + local rows together (git → clone/pull; local → direct directory walk; a missing local dir aborts the run before importing, with the path named);--sourcestill wins;BOR_GIT_SOURCESstays a git-only fallback; both-empty fails loudly ("no sources configured"). - The page: a second "Local directory" add form (labeled path input, inline error, never-stale button per §7.4); list rows show a kind badge (Git/Local, distinguishable by more than color); the hint says Sync imports git checkouts and local directories together (union prune).
- README: the two source types + add-time validation + "the DB is the local-source registry"; no new env var.
- Unit + integration green,
app/coverage >90%, story E2E green in isolation, ruff + pyright clean, one--no-gpg-signcommit.
Playwright Mapping Rule
tests/e2e/test_local_directory_sources.py — one story, one file, run in
isolation: the admin adds a temp local directory → it appears with the
Local badge; a missing path gets an inline error; Sync imports its fixture
file (visible via GET /api/docs); deleting the file and syncing again
prunes it; removing the row removes it from the list.