# Glaze Plan / TODO 🍯
This document tracks upcoming work for Glaze and its supporting Odin HTTP/library stack.
For a high-level description of what Glaze is, see `README.md`.
---
## Current Status
Glaze is a working web frontend for soft-serve.
It currently supports:
- Listing public repositories
- Reading repository visibility/configuration from `soft-serve.db`
- Browsing bare git repositories through libgit2
- Ref-aware tree/blob/raw URLs
- Tree listing and full path traversal
- Blob viewing with `
`
- Raw blob output
- Breadcrumb navigation
- Latest commit metadata on repo pages
- Rendered `README.md`
- Static assets and styling
- Custom templates
- Styled layout and visual identity
- Public Docker deployment
The HTTP layer is custom-built in Odin and currently supports:
- HTTP/1.x parsing
- keep-alive
- pipelining / carry buffer
- growing ring buffer
- thread-per-connection handling
- connection caps
- idle timeouts
- unsupported `Transfer-Encoding` rejection
- response header management
- static file serving
- routing
- route params
- middleware
---
## Immediate Priorities
### 1. Audit request/response memory lifetimes
Do a focused pass over the HTTP library and app code to confirm ownership rules.
Checklist:
- Request head/body memory lifetime is clear
- Route params do not outlive the request
- Response headers are always freed after sending
- Response bodies have clear ownership
- Middleware does not retain request-local memory accidentally
- Static file handling closes all file descriptors
- Connection job memory is freed after socket close
- Active connection counter decrements via `defer`
- No thread-local arena data leaks into shared/global caches
- Template-rendered output ownership is clear
- Error response paths clean up correctly
Goal:
- Make request/response lifecycle boring, predictable, and leak-free.
---
### 2. Refine template data model
The current template system works, but the data model should be simplified.
Current syntax:
```html
{{field}}
{{#block}}
...
{{/block}}
````
Desired direction:
* Split template data into fields and blocks
* Keep logic in Odin
* Keep templates intentionally dumb
* Use explicit view models instead of passing domain objects directly
* Prefer strings and block lists over rich runtime types
* Escape normal fields by default
* Allow explicitly safe/raw HTML for trusted content such as rendered Markdown
Possible model:
```text
Template_Context
fields: name -> string
blocks: name -> []Template_Context
```
Goal:
* Make templates easier to reason about and easier to feed from handlers.
---
### 3. Add styled error pages
Now that templates exist, replace plain/default errors with Glaze-styled pages.
Pages to support:
* 400 Bad Request
* 404 Not Found
* 408 Request Timeout
* 413 Payload Too Large
* 431 Request Header Fields Too Large
* 500 Internal Server Error
* 503 Service Unavailable
Notes:
* App-level missing repos/files/refs should render styled 404s
* Hidden/private repos should return 404, not 403
* Low-level malformed requests may stay minimal if necessary
* Error rendering should be overridable by applications using the HTTP library
Goal:
* Make failure states feel like part of the site.
---
### 4. Add branch/ref UI
Ref support works through URLs, but it needs to be discoverable in the UI.
Ideas:
* Show current ref in repo header
* List branches
* List tags
* Add ref dropdown or simple selector
* Preserve current path when switching refs
* Link each ref to the corresponding tree page
* Consider separating branches and tags visually
Goal:
* Make branch/ref browsing usable without manually editing URLs.
---
## Near-Term App Improvements
### 5. Improve README rendering and Markdown styling
Rendered README support exists. Improve presentation.
Tasks:
* Style headings
* Style lists
* Style links
* Style inline code
* Style code blocks
* Style blockquotes
* Ensure rendered Markdown is safely handled as trusted HTML only after conversion
* Handle missing README gracefully
Goal:
* Make repo root pages feel polished.
---
### 6. Improve tree/blob UI
Small UX improvements for browsing.
Ideas:
* File size column
* File/directory icons
* Parent directory link
* Better blob header
* Raw/view toggle links
* Copy path link
* Better mobile layout
* Improved focus states
* Better hover states
* Optional line numbers for blob view later
Goal:
* Make code browsing smoother and more pleasant.
---
### 7. Add semantic/IndieWeb metadata
Basic metadata is now planned or partially in place.
Site-wide:
* ``
* ``
* ``
* OpenGraph tags
* `theme-color`
* generator metadata
Body semantics:
* `h-card` for site/project identity
* `h-entry` on repo/tree/blob pages where appropriate
* `dt-updated` for latest commit time
* `p-name`, `p-summary`, `u-url`, `e-content` where useful
* semantic HTML: `header`, `main`, `nav`, `article`, `section`, `footer`
Goal:
* Make pages understandable to humans and machines.
---
## Library Cleanup
### 8. Odin-ify libgit2 wrapper
The libgit2 shim works but should be smoothed into an Odin-facing API.
Desired app-facing operations:
* open repository
* get latest commit metadata
* list refs
* list tree
* read blob
* check path type
* get blob size
* resolve ref
Desired style:
* Odin structs
* error enums
* explicit ownership
* no raw libgit2 pointers in app code
* no C-shaped API in route handlers
Goal:
* Make Git access pleasant, safe, and reusable.
---
### 9. Clean up HTTP library structure
The HTTP library is functional. Continue making it reusable.
Areas to review:
* public API surface
* naming consistency
* `Request` and `Response` ownership
* router API
* middleware API
* response writing helpers
* static handler API
* timeout/config options
* error handler customization
Goal:
* Make the HTTP library feel like a small personal framework, not just Glaze internals.
---
### 10. Improve middleware utilities
Middleware support works. Add useful built-in middleware.
Candidates:
* request logging
* timing
* panic recovery
* security headers
* cache-control headers
* compression later
* response cache later
Document:
* middleware execution order
* whether middleware may modify response after `next`
* how middleware user data is owned
Goal:
* Make common request/response behavior composable.
---
## Caching
### 11. Service-layer caching
Repo list caching exists. Add more targeted cache layers closer to expensive operations.
Good candidates:
* repo root view data
* tree listing by `(repo, ref, path)`
* rendered README by `(repo, ref)`
* latest commit metadata by `(repo, ref)`
* refs list by repo
Strategy:
* immutable snapshots
* short TTL, likely 30–60 seconds
* build off-lock where possible
* swap under lock
* avoid sharing thread-local arena memory
Goal:
* Reduce repeated libgit2 and Markdown work.
---
### 12. Response/page cache middleware
Possible later feature, after memory lifetime audit.
Good candidates:
* GET repo root pages
* GET tree pages
* GET blob pages
Cache only:
* GET/HEAD
* deterministic responses
* safe statuses like 200
* possibly short-lived 404s
Store:
* status
* headers
* body
* expiry time
Important:
* Deep-copy cached responses
* Never retain request-local memory
* Be careful with future auth/user-specific content
Goal:
* Add full-page caching without polluting handlers.
---
## HTTP Features for Later
### 13. Conditional requests
Add support for caching semantics.
Possible headers:
* `ETag`
* `Last-Modified`
* `If-None-Match`
* `If-Modified-Since`
Use cases:
* static files
* raw blobs
* rendered pages later
Goal:
* Reduce unnecessary transfers.
---
### 14. Thread pool mode
Current thread-per-connection model works.
Consider adding a thread pool later if needed.
Benefits:
* bounded worker count
* predictable resource usage
* less thread churn
Tradeoffs:
* queued connections may wait
* more scheduling logic
* more shutdown complexity
Goal:
* Add an optional concurrency mode if real load demands it.
---
## Longer-Term Glaze Features
### 15. Commit views
Add pages for individual commits.
Show:
* hash
* author
* date
* summary/message
* changed files
* diff later
Goal:
* Make commit metadata clickable and useful.
---
### 16. Ref pages
Add dedicated pages for branches/tags.
Show:
* branch list
* tag list
* latest commit per ref
* links into tree view
Goal:
* Make repository navigation more complete.
---
### 17. File history
For a blob path, show recent commits touching that file.
Possible route:
```text
/r/:repo/history/:ref/*path
```
Goal:
* Add useful code-browsing context.
---
### 18. Syntax highlighting
Later polish.
Possible approaches:
* server-side highlighting
* client-side highlighting
* minimal Odin-specific highlighting first
* no highlighting for huge files
Goal:
* Improve blob readability.
---
### 19. Search
Longer-term feature.
Possible levels:
* filename search
* repo search
* text search
* indexed search later
Goal:
* Make browsing larger repo sets easier.
---
### 20. Archive downloads
Add links for downloading refs as archives.
Formats:
* `.zip`
* `.tar.gz`
Possible implementation:
* libgit2 archive support if available
* shell out to git archive if acceptable
* custom archive generation later
Goal:
* Make repos easier to download.
---
## Guiding Principles
* Keep HTTP layer reusable
* Keep Glaze app logic separate from HTTP internals
* Prefer explicit ownership
* Prefer immutable snapshots for shared cached data
* Keep templates dumb
* Keep logic in Odin
* Return 404 for private/hidden repos
* Avoid exposing raw C APIs above integration layers
* Add transport features only when needed
* Favor small visible improvements over large rewrites