Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
604 changes: 471 additions & 133 deletions .work/published.json

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions .work/todo.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,22 @@
{"actor":"richardhightower","ev":"01KYQA5XMKE7MMTXHD97EY8RDB","item":"01KYFZ6RBHABFSC9K9NJ90168Q","op":"close","set":{"status":"done"},"ts":"2026-07-29T16:09:03Z"}
{"actor":"richardhightower","ev":"01KYQA5XRXYK6WCREYZPZZVA8V","item":"01KYK6NHSFJNG9XV6D8K5SHWCV","op":"close","set":{"status":"done"},"ts":"2026-07-29T16:09:03Z"}
{"actor":"richardhightower","ev":"01KYQAJMJFWE0KBHQSRKBR92AV","item":"01KYFZ8RGR06XBSG9CH4TEWYJY","op":"close","set":{"status":"done"},"ts":"2026-07-29T16:16:00Z"}
{"actor":"richardhightower","ev":"01KYQYYN3SG7XSZXK65QXPJRFD","item":"01KYQYYN3SBWDT25TC6H3G4EAA","op":"create","set":{"body":"Make Save findable after New Note, lock create to edit to save to reload in Playwright, land dataset and SQL install E2E, and file post-v0.1 product gaps.","kind":"feature","level":"epic","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P1","status":"todo","title":"Save discoverability, new-note persistence E2E, and post-v0.1 follow-ups"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQYYN3T7DZWG7HJQFDMBWTF","item":"01KYQYYN3T5RXZWBXWV9VNP3ZH","op":"create","set":{"body":"Icon-only Save is why a user can create a note and not see how to keep edits.\nShow a visible \"Save\" label (or text button) next to the icon; keep \u2318S /\nCtrl+S; keep the live status region (Saving\u2026 / Saved / Save failed). Accessible\nname must stay matchable as /^Save/.","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P1","status":"todo","title":"Make the Save control discoverable"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQYYN3T72DT9EHMP1TKB5NZ","item":"01KYQYYN3T7R1V9546Q5NTJRZE","op":"create","set":{"body":"Open folder \u2192 New Note \u2192 type a unique marker in the editor \u2192 click Save\n(assert write 200) \u2192 full page reload \u2192 open the same untitled-* note \u2192\nmarker present. Locks the path the human just could not complete by eye.\nExtend e2e/persistence.spec.ts (or adjacent).","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P1","status":"todo","title":"E2E: create a new note, edit, save, reload \u2014 content survives"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQYYN3TJPMHPFHA09J2YCES","item":"01KYQYYN3T8MXHSF7JS4MA57GJ","op":"create","set":{"body":"Commit e2e/data.spec.ts and aligned seed (public/demo-shaped sample-data /\nsample-events): welcome datasets show rows without error banners; welcome JOIN\nreturns rows; two-table JOIN in a real note; missing source surfaces an error\n(not a silent empty table).","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P1","status":"todo","title":"Land Playwright coverage for dataset/SQL install"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQYYN3TZCKF8XGJHKAPDETE","item":"01KYQYYN3T3VB8RCTMJJ13FK2H","op":"create","set":{"body":"In Tauri, opening an arbitrary project folder leaves welcome pointing at\nsample-data.csv / sample-events.jsonl that are not in that folder \u2192 red\n\"Failed to load dataset\" and SQL catalog errors. Fix options: ship demo\nfixtures as app resources with a known source path, or degrade welcome demo\nblocks when files are missing with a clear \"demo data not in this workspace\"\nmessage and no false Catalog Error.","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P2","status":"todo","title":"Welcome / demo datasets resolve when the open folder is not Motion"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQYYN3TV47MHCCY6S4YNJHY","item":"01KYQYYN3T5W49QH05WCCYX7CE","op":"create","set":{"body":"Flat list of all .md files is useful; also need a tree of directories so large\nworkspaces are navigable. Toggle or split pane acceptable.","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P2","status":"todo","title":"Sidebar: directory tree view alongside flat markdown list"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQYYN3TCK9WWYW8XV2PTMTD","item":"01KYQYYN3TA69K8848E483HC82","op":"create","set":{"body":"Default name is fine; date (mtime) helps \"what did I touch last?\". Persist the\nchoice in local UI state for the session at minimum.","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P2","status":"todo","title":"Sidebar: sort by name or date"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQYYN3TFWND71Q160VM5W5D","item":"01KYQYYN3TKW93D9SVW07VKFZY","op":"create","set":{"body":"Filename search already works. Add content search: query + optional glob,\nresults list with path + line snippet, open file on select. Prefer workspace\njail APIs (no shelling out from the webview); web can use server-side walk,\ndesktop Tauri command.","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P2","status":"todo","title":"Search inside file contents (grep/glob UX)"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQYYN3TREA6TCRGFF1V3Y1H","item":"01KYQYYN3T2SSGG33ESEWPXKH8","op":"create","set":{"body":"Keep Playwright as the CI hard gate. Add bin/agent-pass.sh (or documented\nagent-browser dogfood steps) and a DoD line in Agents.md/CLAUDE.md: before\nhandoff, run agent-browser against localhost welcome + one real workspace.\nNot required in CI (flake risk).","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P2","status":"todo","title":"Agent-browser final pass in Definition of Done"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQYYN3T2DKZH490T48Z7D71","item":"01KYQYYN3T731B57N8NXQ8C0FQ","op":"create","set":{"body":"Human/ops: GitHub branch protection requiring the CI jobs\n`typecheck, guards, unit, e2e` and `cargo test + clippy`. Until then anyone\ncan merge red. Document exact check names from a green run.","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P3","status":"todo","title":"Require branch protection on main for verify + rust checks"},"ts":"2026-07-29T22:12:05Z"}
{"actor":"richardhightower","ev":"01KYQZ13EVDYTV4RXXGSKH8R7A","item":"01KYQYYN3T5RXZWBXWV9VNP3ZH","op":"close","set":{"resolution":"Visible Save label on toolbar; Cmd-S unchanged.","status":"done"},"ts":"2026-07-29T22:13:25Z"}
{"actor":"richardhightower","ev":"01KYQZ13JZ2MZRZR1GFSXXD6Z2","item":"01KYQYYN3T7R1V9546Q5NTJRZE","op":"close","set":{"resolution":"e2e/persistence: create edit Save reload with marker.","status":"done"},"ts":"2026-07-29T22:13:25Z"}
{"actor":"richardhightower","ev":"01KYQZ13Q2QN4MJ3SJCJRHZ01Q","item":"01KYQYYN3T8MXHSF7JS4MA57GJ","op":"close","set":{"resolution":"e2e/data.spec.ts + demo-shaped seed; welcome install and JOIN locked.","status":"done"},"ts":"2026-07-29T22:13:25Z"}
{"actor":"richardhightower","ev":"01KYQZ491V2V3PG1HG2WM84AW5","item":"01KYQZ491VF71K9KCDHAZYNE9S","op":"create","set":{"body":"Refresh docs/designs/current_design_doc.md (and code walkthrough if needed) for Save label, new-note persistence, dataset/SQL install coverage, and synthesis as shipped. Publish to the GitHub wiki so Design-Doc matches docs/.","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P2","status":"todo","title":"Write or update design docs for post-v0.1 dogfood work and publish to wiki"},"ts":"2026-07-29T22:15:09Z"}
{"actor":"richardhightower","ev":"01KYQZ4963643F4ZRCZRC0XHB6","item":"01KYQZ4963GCA86R8CP4P14DRV","op":"create","set":{"body":"User guide must describe labeled Save, create-edit-save-reload, dataset/SQL behaviour, and accurate known limitations. Publish User-Guide wiki page from docs/user_guide/user-guide.md.","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P2","status":"todo","title":"Update user guide for current behaviour and publish to wiki"},"ts":"2026-07-29T22:15:09Z"}
{"actor":"richardhightower","ev":"01KYQZ49A7BKXQF7F5YW9NHB2Q","item":"01KYQZ49A7NWRQZK83658CT4QT","op":"create","set":{"body":"README Features and Known limitations are the public feature list. Align with shipped behaviour: labeled Save, block round-trip, desktop build status, demo SQL, Synthesize. Remove fixed bugs listed as open limitations.","kind":"feature","level":"task","parent":"01KYQYYN3SBWDT25TC6H3G4EAA","plan":"docs/plans/2026-07-29-save-ux-and-next.md","priority":"P2","status":"todo","title":"Keep README feature list and known limitations current"},"ts":"2026-07-29T22:15:09Z"}
{"actor":"richardhightower","ev":"01KYQZ4F4CV4YC2DQEVEWXTXV9","item":"01KYQZ49A7NWRQZK83658CT4QT","op":"close","set":{"resolution":"README Features and Known limitations updated to match labeled Save, synthesis, block round-trip, and real remaining gaps.","status":"done"},"ts":"2026-07-29T22:15:15Z"}
{"actor":"richardhightower","ev":"01KYR1CWZSZXYRRQ4Q24TX7BR9","item":"01KYQZ4963GCA86R8CP4P14DRV","op":"close","set":{"resolution":"User guide updated for labeled Save and current limitations; published to wiki User-Guide (rev 740da3b).","status":"done"},"ts":"2026-07-29T22:54:49Z"}
{"actor":"richardhightower","ev":"01KYR1PYCYZ4D8Z9CYMVW683AE","item":"01KYQZ491VF71K9KCDHAZYNE9S","op":"close","set":{"resolution":"Design doc \u00a70 dogfood amendment + FR/NFR/roadmap updates; code walkthrough currency note; published Design-Doc and Code-Walkthrough to wiki.","status":"done"},"ts":"2026-07-29T23:00:18Z"}
41 changes: 38 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,32 @@ client-bundle guard, unit tests, then E2E.
| `bun run typecheck` | `tsc --noEmit`, strict |
| `bun run guard:client` | no `Bun.` reachable from `src/main.tsx` |
| `bun test src` | unit tests (scoped to `src` — unscoped, Bun would try to run the Playwright specs and fail) |
| `bunx playwright test` | E2E against the real dev server |
| `bunx playwright test` | **end-to-end** against the real dev server (Playwright *is* the E2E harness) |
| `cd src-tauri && cargo test --lib` | the workspace jail |

### Every feature ships with tests — no exceptions

When you add or change a **user-visible feature** (UI control, workflow, block
type, storage behaviour, synthesis, etc.), the PR must include **both**:

1. **Unit / focused tests** under `src/**` via `bun test src` — pure logic,
serialization, path resolution, duckdb helpers, synthesis orchestration,
etc. If the change is UI-only wiring with no extractable logic, still prefer
a small unit test for any new pure helper you introduce.
2. **Playwright end-to-end** under `e2e/` — a real browser journey against the
real dev server that exercises the feature the way a user would (roles and
accessible names, not CSS trivia). Extend an existing spec file when the
journey fits; add a new `e2e/<area>.spec.ts` when it does not.

A feature without both is **not done**, even if `verify` is green for unrelated
reasons. "Covered by an old smoke that only mounts the shell" does not count —
the new behaviour itself must be asserted (success path and the failure path
when the feature can fail observably).

Optional dogfood (not a CI gate): a final `agent-browser` pass against
localhost before human handoff for milestone work — see the open work item on
agent-browser in the Definition of Done.

Two probes are excluded from the suite and run by hand with `BASELINE=1`:
`e2e/baseline.capture.spec.ts` re-measures the console/network baseline, and
`e2e/guard.proof.capture.spec.ts` proves the gate still bites — **3 failed / 1
Expand Down Expand Up @@ -73,12 +96,24 @@ repo. Route UI-initiated CLI work through `src/lib/llmClient.ts` or
A change is done only when **all** of these hold:

1. `bun run verify` passes (typecheck + client-bundle guard + unit + E2E).
2. An E2E spec in `e2e/` covers the new or fixed behaviour.
2. **Feature work includes both layers of tests** (see Testing above):
- unit coverage under `src/` for new or changed logic, and
- a Playwright E2E in `e2e/` that drives the new or fixed user journey.
3. Zero console errors, zero uncaught exceptions, zero failed requests and zero
responses >= 400 during E2E — enforced automatically by `e2e/fixtures.ts`.
4. Rust or storage changes additionally pass `cargo test --lib` and
`cargo clippy --all-targets -- -D warnings` in `src-tauri/`.
5. Anything discovered along the way is filed via `worklog add --unplanned`.
5. **Docs stay truthful for features that change product surface:**
- update `docs/designs/current_design_doc.md` (and/or the code walkthrough)
when architecture, contracts, or major flows change;
- update `docs/user_guide/user-guide.md` when a user-visible behaviour is
added, fixed, or removed;
- update the **feature list** in `README.md` (and known limitations there)
so it matches what actually ships;
- register/publish to the GitHub wiki (`worklog wiki-add` / the wiki publish
flow under `.work/wiki-checkout`) so the wiki is not stale relative to
`docs/`.
6. Anything discovered along the way is filed via `worklog add --unplanned`.

**"I looked at it in the browser" is not done.** Not done means not handed over:
the human reviews design, not defects. If you cannot demonstrate it green, say
Expand Down
36 changes: 24 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@ natural-language prompts using CLI tools you already have installed.
### Editing

- **Three view modes** — WYSIWYG, raw Markdown, and Split, switchable at any time.
Edits carry across modes without loss.
- **Workspace management** — open a folder and Motion lists every markdown file
under it, recursively. Search filters the list as you type.
under it, recursively (flat list). **Search notes** filters by filename.
- **New Note** — creates `untitled-<timestamp>.md` in the open workspace.
- **Save** — labeled **Save** control in the toolbar, plus **⌘S** / **Ctrl+S**.
Status shows Saving… / Saved / Save failed.
- **Rich markdown** — headings, lists, blockquotes, and code blocks with syntax
highlighting across the common languages. (Tables are not supported yet — no
table extension is registered, so pipe-table syntax renders as text.)
- **AI Refine** — per-document refine action (needs `claude` on `PATH`).

### Content blocks

Five block types, insertable from the toolbar or by typing `/` at the start of a
line:
line. Blocks survive save/reload as real blocks (not plain code).

| Block | What it does |
|---|---|
Expand All @@ -30,21 +35,24 @@ line:
| **Image gen** | Generates an image from a prompt via the `imagen` CLI |
| **Diagram gen** | Generates a Mermaid diagram from a prompt via the `claude` CLI |

Dataset/Query need the data files inside the **open workspace** (demo files ship
under `public/demo/`). SQL is restricted to `SELECT`/`WITH` with validated
identifiers and a clamped row limit — the query box cannot modify your data.

### Workspace synthesis

**Synthesize** summarizes every note in the workspace, clusters them by topic,
and writes a generated `TOC.md` and `SKILL.md` back into the folder. Its own
output is excluded from the input, so re-running does not feed the index back to
itself. Capped at 40 notes per run, and it reports what it skipped.

SQL is restricted to `SELECT`/`WITH` with validated identifiers and a clamped
row limit — the query box cannot modify your data.
itself. Capped at 40 notes per run, and it reports what it skipped. Needs
`claude` on `PATH`.

### Safety

- Filesystem access is jailed to the folder you opened. Paths are canonicalized,
so `..` traversal and symlinks pointing outside the workspace are both refused.
- Rendered markdown and generated SVG are sanitized before insertion.
- Dev server binds to **localhost only**.

## Getting started

Expand Down Expand Up @@ -110,12 +118,16 @@ cannot pass quietly. See `CLAUDE.md` for the full definition of done.

Recorded here rather than discovered later:

- `bun run build` does not emit an entry HTML file, so the **packaged desktop
build does not work yet** — use `bun tauri dev`.
- Dataset, Query, Image gen and Diagram gen blocks do not survive a save/reload
cycle; they degrade into plain code blocks. Mermaid blocks round-trip fine.
- The bundled demo query returns no rows — the demo data disagrees on case in
its join condition.
- **Sidebar is flat** — every `.md` under the workspace, not a directory tree.
Sort is name-only; no content (in-file) search yet.
- **Welcome demo datasets** assume `sample-data.csv` / `sample-events.jsonl` exist
in the open workspace. Opening an unrelated folder shows load errors for those
blocks until those files are present or sources are re-pointed.
- **Markdown tables are not supported.** Pipe-table syntax renders as plain text.
- **No hot reload.** The dev server rebuilds the bundle on change but the page
does not refresh itself — reload manually.
- Generative blocks and **Synthesize** need the relevant CLI (`claude`, `imagen`)
on `PATH`.

See [CHANGELOG.md](CHANGELOG.md) for release history and
[docs/roadmap.md](docs/roadmap.md) for what is planned.
Expand Down
Loading
Loading