anvilsign in

collin/anvil

BoardRenderedSource

Todo

  • 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.rs does the CAS commit; ui.rs edit_form/edit_submit wire 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

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; Attachment model maps repo_id/hash → content-type, size, uploader, created-at. Kept out of repositories/ 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}/-/attachments behind write-access + CSRF (X-CSRF-Token header), magic-byte sniffed to png/jpeg/gif/webp (SVG rejected), capped by http.attachment_max_mb, returns the markdown to splice.
  • editor UX: paste or drop an image in the file editor → background upload → ![image](url) 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.)
  • 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).

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::usage walks the stores; storage::dir_size sums them.
  • maybe: per-repo drill-down, and a cheap cached/periodic variant if the on-demand disk walk gets slow on large instances.

adjust padding

There's too much vertical padding at the top of the screen.

todo kanban styling

I'm not a big fan of how the kanban styling looks currently. take a look here. I think the detail thing that needs to be clicked doesn't look very good. And also the text is Dee emphasized after you view the summary and clicking the detail thing. I don't want it to be deemphasized when viewing the details.

image

kanban board styling image sizing

The kanban board images are too huge when rendered in the board view. They look fine in the rendered markdown page though.