Human-legible output: YAML/text variants for watch-curl routes #13

Closed
opened 2026-05-23 20:55:22 +00:00 by coilysiren · 1 comment
Owner

Originally filed by @coilysiren on 2026-05-21T09:18:30Z - https://github.com/coilysiren/repo-recall/issues/233

Idea

repo-recall's JSON is correct but not human-legible. A person who wants "what needs my attention across every repo" gets chatty JSON - maybe four items fit on a screen when twenty need action. Give every route a human cares about a flat, terse text variant that survives watch curl without line-wrapping.

This is also the UI decision: if watch curl over a YAML variant is good enough, repo-recall may never need the React SPA. The web/ tree could eventually retire.

Decisions locked

  • Push, not pull. commits_ahead > 0 becomes a push action-required signal. commits_behind stays informational - it's drift that self-resolves on the next pull, not a todo.
  • One line per signal. A repo with three issues takes three lines. Never wraps, flat, greppable. Not one-line-per-repo (a busy repo wraps).
  • Accept-header negotiation. Accept: application/yaml (a real registered media type since RFC 9512). No path-suffix or query-param routes.

Architecture

Not a routes/humans vs routes/robots directory fork. The same query feeds JSON, YAML, and MCP - forking the route directory would duplicate the handler and its spawn_blocking query just to swap a render tail.

Instead: one handler per route, content-negotiated render tail.

  • One typed body per route handler (unchanged).
  • A render step: json() (exists) plus human_lines() (new).
  • negotiate.rs already owns content negotiation - extend it to branch on Accept.
  • "Human routes" = the subset whose body type implements a HumanLines trait. That subset is the inventory below - no directory needed.

Line-wrap discipline lives in the data, not the renderer: DerivedSignal gets a terse field next to the chatty detail. detail stays for JSON, terse is the pre-capped one-liner.

Route inventory

Human-watchable, priority order:

  • action-required - the flat cross-repo todo slice. The watch route. Tracer bullet.
  • dashboard / repos - one terse line per repo. This becomes the canonical "short repo entry" - today short/long only exists in React RepoCard + config.rs, never server-side.
  • recent-activity - recent commits + sessions, the "what just happened" feed.
  • health - is repo-recall itself fresh: last scan age, scan version, gh status.

Robot-only (no human renderer): /api/sessions, /api/refresh, /openapi.json, /mcp.

Proposed terse vocabulary

First-pass strings - expect to iterate on the wording:

  • ci_failing - CI failing on <branch>
  • dirty_tree - <n> uncommitted files
  • in_progress_op - <op> in progress
  • detached_head - detached HEAD
  • review_requested - <n> PRs awaiting your review
  • my_draft_pr - <n> draft PRs to finish
  • pr_no_reviewer - <n> PRs need a reviewer
  • my_open_pr - <n> open PRs to test
  • issue_assigned - <n> issues assigned to you
  • deploy_failing - deploy failing
  • deploy_stale - deploy stale (<n>d)
  • stale_branches - stale branch <name> (<n>d), or <n> stale branches for many
  • push (new) - push <n> commits

Rendered line: <repo>: <terse>, e.g. backend: push 3 commits.

Children

Tracked as sliced issues, links added below as filed.

_Originally filed by @coilysiren on 2026-05-21T09:18:30Z - [https://github.com/coilysiren/repo-recall/issues/233](https://github.com/coilysiren/repo-recall/issues/233)_ ## Idea repo-recall's JSON is correct but not human-legible. A person who wants "what needs my attention across every repo" gets chatty JSON - maybe four items fit on a screen when twenty need action. Give every route a human cares about a flat, terse text variant that survives `watch curl` without line-wrapping. This is also the UI decision: if `watch curl` over a YAML variant is good enough, repo-recall may never need the React SPA. The `web/` tree could eventually retire. ## Decisions locked - **Push, not pull.** `commits_ahead > 0` becomes a `push` action-required signal. `commits_behind` stays informational - it's drift that self-resolves on the next pull, not a todo. - **One line per signal.** A repo with three issues takes three lines. Never wraps, flat, greppable. Not one-line-per-repo (a busy repo wraps). - **Accept-header negotiation.** `Accept: application/yaml` (a real registered media type since RFC 9512). No path-suffix or query-param routes. ## Architecture Not a `routes/humans` vs `routes/robots` directory fork. The same query feeds JSON, YAML, and MCP - forking the route directory would duplicate the handler and its `spawn_blocking` query just to swap a render tail. Instead: one handler per route, content-negotiated render tail. - One typed body per route handler (unchanged). - A `render` step: `json()` (exists) plus `human_lines()` (new). - `negotiate.rs` already owns content negotiation - extend it to branch on `Accept`. - "Human routes" = the subset whose body type implements a `HumanLines` trait. That subset *is* the inventory below - no directory needed. Line-wrap discipline lives in the data, not the renderer: `DerivedSignal` gets a `terse` field next to the chatty `detail`. `detail` stays for JSON, `terse` is the pre-capped one-liner. ## Route inventory Human-watchable, priority order: - **action-required** - the flat cross-repo todo slice. The watch route. Tracer bullet. - **dashboard / repos** - one terse line per repo. This becomes the canonical "short repo entry" - today short/long only exists in React `RepoCard` + `config.rs`, never server-side. - **recent-activity** - recent commits + sessions, the "what just happened" feed. - **health** - is repo-recall itself fresh: last scan age, scan version, gh status. Robot-only (no human renderer): `/api/sessions`, `/api/refresh`, `/openapi.json`, `/mcp`. ## Proposed terse vocabulary First-pass strings - expect to iterate on the wording: - `ci_failing` - `CI failing on <branch>` - `dirty_tree` - `<n> uncommitted files` - `in_progress_op` - `<op> in progress` - `detached_head` - `detached HEAD` - `review_requested` - `<n> PRs awaiting your review` - `my_draft_pr` - `<n> draft PRs to finish` - `pr_no_reviewer` - `<n> PRs need a reviewer` - `my_open_pr` - `<n> open PRs to test` - `issue_assigned` - `<n> issues assigned to you` - `deploy_failing` - `deploy failing` - `deploy_stale` - `deploy stale (<n>d)` - `stale_branches` - `stale branch <name> (<n>d)`, or `<n> stale branches` for many - `push` (new) - `push <n> commits` Rendered line: `<repo>: <terse>`, e.g. `backend: push 3 commits`. ## Children Tracked as sliced issues, links added below as filed.
Author
Owner

Backlog burndown 2026-06-17: closing low-priority (P3/P4) to bring the open count to a manageable level. Nothing lost — reopen if this resurfaces. Batch tag: burndown-2026-06.

Backlog burndown 2026-06-17: closing low-priority (P3/P4) to bring the open count to a manageable level. Nothing lost — reopen if this resurfaces. Batch tag: `burndown-2026-06`.
coilysiren 2026-06-17 08:24:37 +00:00
Commenting is not possible because the repository is archived.
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/repo-recall#13
No description provided.