feat: add title and description fields to capture grammar

Implement | prefix for titles and // separator for descriptions
across the full stack: parser, schema, API, CLI, and web frontend.

- Parser: line-aware extraction for |title, |title // desc,
  // leading desc, body // inline desc. URL-safe (skips :// lines).
  Modifiers (#tag, @time, ^card) extracted from all segments.
- Schema: ALTER TABLE migration adds title, description columns
- DB: Entity/EntityUpdate structs, all CRUD queries updated
- API: title/description on create/update/response, body validation
  relaxed (title-only entries valid)
- CLI: shows title as scan label when present
- Web: parseInput mirrors Go parser, list shows title, detail pane
  renders title + description with double-click inline editing
- Tests: 10 new cases (grammar, entity, API) — 71 total, all pass
This commit is contained in:
2026-05-15 20:52:58 -04:00
parent e708ea5c13
commit f5b46585c3
11 changed files with 683 additions and 159 deletions
+12 -8
View File
@@ -18,6 +18,8 @@ type EntityResponse struct {
CreatedAt string `json:"created_at"`
ModifiedAt string `json:"modified_at"`
Body string `json:"body"`
Title *string `json:"title"`
Description *string `json:"description"`
Glyph string `json:"glyph"`
TimeAnchor *string `json:"time_anchor"`
CompletedAt *string `json:"completed_at"`
@@ -50,14 +52,16 @@ func decodeJSON(w http.ResponseWriter, r *http.Request, dst any) bool {
func entityToResponse(e *db.Entity) EntityResponse {
resp := EntityResponse{
ID: e.ID,
CreatedAt: e.CreatedAt.Format(time.RFC3339),
ModifiedAt: e.ModifiedAt.Format(time.RFC3339),
Body: e.Body,
Glyph: string(e.Glyph),
Pinned: e.Pinned,
Tags: e.Tags,
UseCount: e.UseCount,
ID: e.ID,
CreatedAt: e.CreatedAt.Format(time.RFC3339),
ModifiedAt: e.ModifiedAt.Format(time.RFC3339),
Body: e.Body,
Title: e.Title,
Description: e.Description,
Glyph: string(e.Glyph),
Pinned: e.Pinned,
Tags: e.Tags,
UseCount: e.UseCount,
}
if resp.Tags == nil {
resp.Tags = []string{}