collin/anvil
a522b9be624ac7509f7a99dab67e7e0b7dd23f8b / TODO.md
Todo10 open
pull mirror (maybe): a repo that virtually mirrors a GitHub repo
- just displays it here — periodically fetched, read-only on the anvil side
- pull requests (gix merge)
- webhooks (mind the SSRF item in
docs/untrusted-mode.md) Edit files in the web UI
Edit a file in the browser and have anvil make a proper commit (author = the logged-in user, sensible message), written straight onto the branch with gix — no working tree. The new commit just advances the branch tip, so anyone who pushed earlier can fast-forward pull it.
-
start minimal: an "Edit" button on the blob page → textarea → commit;
commits build the tree/commit objects via gix and move the ref (reject if the
branch moved under us — no non-fast-forward clobber).
anvil-git/src/edit.rsdoes the CAS commit;ui.rsedit_form/edit_submitwire the page. -
a structured way to add items to
TODO.md— an "Add task" form that appends a ticket (## title, the richer card style) to the right section per the todo-md round-trip rules (todomd::add_task/task_sections), rather than hand-editing the raw file -
then richer editing: a real markdown editor with a live render preview
(reuse
render_markdown) before committing
-
start minimal: an "Edit" button on the blob page → textarea → commit;
commits build the tree/commit objects via gix and move the ref (reject if the
branch moved under us — no non-fast-forward clobber).
Image uploads (attachments stored outside git)
Upload an image in the web editor and link to it from the markdown without the blob ever entering git history. Stored content-addressed per repo and served back; the file only carries the URL.
-
store: content-addressed blobs at
data/attachments/{repo_id}/{sha256}, deduped per repo;Attachmentmodel maps repo_id/hash → content-type, size, uploader, created-at. Kept out ofrepositories/so it's never a git object. (anvil-core:attachments,storage::attachment_path, schema shim.) -
serve:
GET /{owner}/{repo}/-/attachments/{hash}, read-access gated (private repos stay private), immutable cache +nosniff+ locked-down CSP. -
upload:
POST /{owner}/{repo}/-/attachmentsbehind write-access + CSRF (X-CSRF-Tokenheader), magic-byte sniffed to png/jpeg/gif/webp (SVG rejected), capped byhttp.attachment_max_mb, returns the markdown to splice. -
editor UX: paste or drop an image in the file editor → background upload →
inserted at the cursor. -
caps: per-repo attachment quota (
http.attachment_quota_mb, 0 = unlimited) — a new upload over the cap is rejected; deduped re-uploads are always free. (Reject, not evict: evicting would break live Markdown links.) -
carry attachments over git, credential-free: anvil mirrors each upload
into
refs/anvil/attachments(flathash → blobtree, off the branch namespace). A default pull never fetches it; opt in withgit fetch origin '+refs/anvil/attachments:refs/anvil/attachments'thengit cat-file -p refs/anvil/attachments:<hash>. Disk+DB stay canonical; the ref is a downstream mirror (anvil-git::attachments_ref). All uploads remain web-only. - within-repo reclaim: an orphan sweep (delete attachments no committed file references) and/or a per-attachment delete action — the recourse once a repo hits its quota. Deferred: deletion is destructive and "orphaned" is fuzzy (tip-only vs any-ref), so it wants its own design pass.
- remove a repo's attachment + artifact dirs on repo delete — blocked: there is no repo-delete path yet (only the create-rollback uses it).
-
store: content-addressed blobs at
Admin: site disk-usage dashboard
-
/-/admin/usage(admin-only; 404 for everyone else, nav link for admins): actual on-disk bytes per user, broken down by content type (repositories / CI artifacts / attachments) with column + grand totals.anvil-core::usagewalks the stores;storage::dir_sizesums them. - maybe: per-repo drill-down, and a cheap cached/periodic variant if the on-demand disk walk gets slow on large instances.
-
API tokens (read-only PATs)
-
ApiTokenmodel +anvil-core::api_tokens(create/list/revoke, SHA-256 hashed, scoped). CLIanvild user token create|list|revoke. -
bearer auth:
CurrentUseralso acceptsAuthorization: Bearer <pat>on GET/HEAD only — least-privilege read-only (writes need a session CSRF a bearer lacks). Lets tooling (and Claude) fetch private-repo attachments over HTTP. See the recipe inCLAUDE.md. -
token management on the user settings page (
/-/settings): create (secret shown once), list, and revoke — ownership-enforced. -
maybe later: a
writescope (would need CSRF-exempt write paths) andlast_used_attracking.
-
UI polish (done)
-
less vertical padding at the top of the screen (
maintop padding 24→12px) -
kanban card details: the disclosure toggle restyled to a clean uppercase
marker, and the expanded detail text is no longer de-emphasized (full
--fg, not muted) -
kanban card images constrained to the card width (
max-width:100%); they were rendering at natural size on the board while fine on the rendered page
-
less vertical padding at the top of the screen (
improve todo.md ui style
improve this part of the todo md ui. it looks bad. specifically the edit and add task buttons
Ability to reorder tasks in todo.md
I want to have the ability to reorder the tasks in the todo.md file.
This is just a test image to test functionality of a different feature and ignore it for this ticket