anvilsign in

collin/anvil · 12249ca5

docs: trim TODO.md to outstanding work

Collin Richards · 2026-06-10 16:39 UTC · 12249ca50f6643c02c992530842d3d16b9cf2266 · parent 43da2588 · browse files

modifiedTODO.md+8 −84
⋯ 3 unchanged lines
44 - just displays it here — periodically fetched, read-only on the anvil side
55 - [ ] pull requests (gix merge)
66 - [ ] webhooks (mind the SSRF item in `docs/untrusted-mode.md`)
7-
8-## Edit files in the web UI
9-
10-Edit a file in the browser and have anvil make a proper commit (author = the
11-logged-in user, sensible message), written straight onto the branch with gix —
12-no working tree. The new commit just advances the branch tip, so anyone who
13-pushed earlier can fast-forward pull it.
14-
15-- [x] start minimal: an "Edit" button on the blob page → textarea → commit;
16- commits build the tree/commit objects via gix and move the ref (reject if the
17- branch moved under us — no non-fast-forward clobber). `anvil-git/src/edit.rs`
18- does the CAS commit; `ui.rs` `edit_form`/`edit_submit` wire the page.
19-- [x] a structured way to add items to `TODO.md` — an "Add task" form that
20- appends a ticket (`## title`, the richer card style) to the right section per
21- the todo-md round-trip rules (`todomd::add_task` / `task_sections`), rather
22- than hand-editing the raw file
23-- [ ] then richer editing: a real markdown editor with a live render preview
7+- [ ] richer file editing: a real markdown editor with a live render preview
248 (reuse `render_markdown`) before committing
25-
26-## Image uploads (attachments stored outside git)
27-
28-Upload an image in the web editor and link to it from the markdown without the
29-blob ever entering git history. Stored content-addressed per repo and served
30-back; the file only carries the URL.
31-
32-- [x] store: content-addressed blobs at `data/attachments/{repo_id}/{sha256}`,
33- deduped per repo; `Attachment` model maps repo_id/hash → content-type, size,
34- uploader, created-at. Kept out of `repositories/` so it's never a git object.
35- (`anvil-core`: `attachments`, `storage::attachment_path`, schema shim.)
36-- [x] serve: `GET /{owner}/{repo}/-/attachments/{hash}`, read-access gated
37- (private repos stay private), immutable cache + `nosniff` + locked-down CSP.
38-- [x] upload: `POST /{owner}/{repo}/-/attachments` behind write-access + CSRF
39- (`X-CSRF-Token` header), magic-byte sniffed to png/jpeg/gif/webp (SVG
40- rejected), capped by `http.attachment_max_mb`, returns the markdown to splice.
41-- [x] editor UX: paste or drop an image in the file editor → background upload →
42- `![image](url)` inserted at the cursor.
43-- [x] caps: per-repo attachment quota (`http.attachment_quota_mb`, 0 =
44- unlimited) — a new upload over the cap is rejected; deduped re-uploads are
45- always free. (Reject, not evict: evicting would break live Markdown links.)
46-- [x] carry attachments over git, credential-free: anvil mirrors each upload
47- into `refs/anvil/attachments` (flat `hash → blob` tree, off the branch
48- namespace). A default pull never fetches it; opt in with
49- `git fetch origin '+refs/anvil/attachments:refs/anvil/attachments'` then
50- `git cat-file -p refs/anvil/attachments:<hash>`. Disk+DB stay canonical;
51- the ref is a downstream mirror (`anvil-git::attachments_ref`). All uploads
52- remain web-only.
53-- [ ] within-repo reclaim: an orphan sweep (delete attachments no committed file
9+- [ ] attachment reclaim: an orphan sweep (delete attachments no committed file
5410 references) and/or a per-attachment delete action — the recourse once a repo
5511 hits its quota. Deferred: deletion is destructive and "orphaned" is fuzzy
56- (tip-only vs any-ref), so it wants its own design pass.
12+ (tip-only vs any-ref), so it wants its own design pass
5713 - [ ] remove a repo's attachment + artifact dirs on repo delete — blocked: there
58- is no repo-delete path yet (only the create-rollback uses it).
59-
60-## Admin: site disk-usage dashboard
61-
62-- [x] `/-/admin/usage` (admin-only; 404 for everyone else, nav link for admins):
63- actual on-disk bytes per user, broken down by content type (repositories / CI
64- artifacts / attachments) with column + grand totals. `anvil-core::usage`
65- walks the stores; `storage::dir_size` sums them.
66-- [ ] maybe: per-repo drill-down, and a cheap cached/periodic variant if the
67- on-demand disk walk gets slow on large instances.
68-
69-## API tokens (read-only PATs)
70-
71-- [x] `ApiToken` model + `anvil-core::api_tokens` (create/list/revoke, SHA-256
72- hashed, scoped). CLI `anvild user token create|list|revoke`.
73-- [x] bearer auth: `CurrentUser` also accepts `Authorization: Bearer <pat>` on
74- GET/HEAD only — least-privilege read-only (writes need a session CSRF a bearer
75- lacks). Lets tooling (and Claude) fetch private-repo attachments over HTTP.
76- See the recipe in `CLAUDE.md`.
77-- [x] token management on the user settings page (`/-/settings`): create (secret
78- shown once), list, and revoke — ownership-enforced.
79-- [ ] maybe later: a `write` scope (would need CSRF-exempt write paths) and
80- `last_used_at` tracking.
81-
82-## improve todo.md ui style
83-
84-![image](/collin/anvil/-/attachments/ba1acb93ed73946496a070f018181892fc3ff786a19b92c305ad0623515d41a6)
85-
86-
87-improve this part of the todo md ui. it looks bad. specifically the edit and add task buttons
88-
89-## Ability to reorder tasks in todo.md
90-
91-I want to have the ability to reorder the tasks in the todo.md file.
92-
93-
94-This is just a test image to test functionality of a different feature and ignore it for this ticket![image](/collin/anvil/-/attachments/f27ccfc35cee6b280a1df2124b356d81bfebb3a70ae964d582595ed3a1000f3e)
14+ is no repo-delete path yet (only the create-rollback uses it)
15+- [ ] admin usage: per-repo drill-down, and a cheap cached/periodic variant if
16+ the on-demand disk walk gets slow on large instances
17+- [ ] API tokens: a `write` scope (would need CSRF-exempt write paths) and
18+ `last_used_at` tracking