This explains how commit analysis data becomes ASCII-style diagrams in myflow.
Scope:
- generation and storage in Flow
- API serving via Flow server
- runtime diagram rendering in myflow via
box-of-rain
Flow generates commit explanations with:
f explain-commits 3 --forceImplementation:
src/explain_commits.rs- Uses
ai-task.shwith provider/model fixed to Kimi defaults (nvidia+moonshotai/kimi-k2.5). - For each commit, Flow gathers:
sha,short_sha,subject,author,date- file list from
git diff --name-only - truncated diff payload (max chars guard)
Output per project (default):
docs/commits/<date>-<short_sha>-<slug>.mddocs/commits/<date>-<short_sha>-<slug>.jsondocs/commits/.index.json(digest/index cache)
Notes:
--forcebypasses digest skip logic.--out-dircan override default output location.
The sidecar .json mirrors Flow’s ExplainedCommit shape:
shashort_shasubjectauthordatesummarychangesfiles(array of changed file paths)markdown_filegenerated_at
This is the source of truth consumed by the UI.
Flow server exposes commit explanations over HTTP:
GET /projects/:name/commit-explanations?limit=50GET /projects/:name/commit-explanations/:sha
Implementation:
src/log_server.rs:project_commit_explanationsproject_commit_explanation_detail
- data loader functions are in
src/explain_commits.rs:list_explained_commitsget_explained_commit
myflow fetches these endpoints through flowFetch model atoms:
/projects/$project/commit-explanations/projects/$project/commit-explanations/$sha
Model file:
~/code/myflow/web/lib/models/flow-projects.ts
Relevant type:
FlowExplainedCommit
Diagram rendering is client-side in myflow and uses box-of-rain.
Theme/options:
~/code/myflow/web/lib/diagram-theme.ts- shared
DIAGRAM_SVG_OPTIONS:- transparent background
- mono font
- light/dark foreground colors
box-of-rain has two explicit stages:
- layout stage:
render(nodeDef)
Input is a graph description (NodeDef+connections).
Output is a multiline ASCII canvas (boxes, borders, arrows, connectors). - paint stage:
renderSvg(ascii, svgOptions)
Input is the ASCII text grid.
Output is an SVG string where each character is positioned with fixed-width metrics.
Important: layout and paint are separate.
If shape/connectors are wrong, the bug is in NodeDef/connections.
If colors/spacing/fonts are wrong, the bug is in SvgOptions.
Core graph primitives used in myflow:
id: stable node identifier for edge wiring.children: lines rendered inside a box.border: visual style (rounded,bold).childDirection: relative arrangement (horizontal).connections: explicit edges, each with:from,tofromSide,toSide(left|right|top|bottom).
Timeline shape (conceptual):
c0 ──> c1 ──> c2
Files impact shape (conceptual):
commit ──> dirA
commit ──> dirB
commit ──> dirC
File:
~/code/myflow/web/lib/commit-timeline-diagram.tsx
Algorithm:
- take up to 8 newest commits
- reverse to oldest -> newest
- build one rounded node per commit:
- line 1:
short_sha - lines 2+: truncated subject (2 lines max)
- line 1:
- connect node
i -> i+1(right to left sides) - render:
render(nodeDef)-> ASCII layoutrenderSvg(ascii, DIAGRAM_SVG_OPTIONS)-> SVG
- inject SVG into DOM with
dangerouslySetInnerHTML
Conceptual NodeDef sketch:
{
children: [
{ id: "c0", border: "rounded", children: ["2daa3fd", "feat: sub-agent"] },
{ id: "c1", border: "rounded", children: ["f298c48", "memories rollout"] },
],
childDirection: "horizontal",
connections: [{ from: "c0", to: "c1", fromSide: "right", toSide: "left" }],
}Mounted at:
~/code/myflow/web/pages/flow/$project/index.tsx
File:
~/code/myflow/web/lib/files-impact-diagram.tsx
Algorithm:
- group
commit.filesby top path bucket:- first 2 segments when possible
- create bold commit node
- create one rounded directory node per group:
- dir label
- up to 3 file names
+N moreoverflow line
- connect
commit -> each_dir - render ASCII then SVG with same theme options
Conceptual NodeDef sketch:
{
children: [
{ id: "commit", border: "bold", children: ["2daa3fd", "feat: sub-agent"] },
{ id: "d0", border: "rounded", children: ["codex-rs/core/", " agent.rs", " mod.rs"] },
],
childDirection: "horizontal",
connections: [{ from: "commit", to: "d0", fromSide: "right", toSide: "left" }],
}Mounted at:
~/code/myflow/web/pages/flow/$project/commit/$sha.tsx
- both diagram components are wrapped in
useMemo - timeline hard limit: 8 commits
- subject lines are truncated for stable node widths
- files list per group is capped in-node (full list still shown below diagram)
- No commit data:
- run
f explain-commits Nin the target repo
- run
- API empty:
- ensure Flow server is running (
f server) - ensure project is registered in Flow
- ensure Flow server is running (
- Diagram package missing:
- ensure
box-of-raindependency resolves in myflow runtime build
- ensure
- BetterAuth
/apibase URL error in browser:- use absolute URL normalization in
web/lib/auth-client.ts(relative/apialone is invalid for BetterAuth client config)
- use absolute URL normalization in
From target repo (example: codex):
cd ~/repos/openai/codex
f explain-commits 3 --forceFrom Flow:
f server --host 127.0.0.1 --port 9050
curl 'http://127.0.0.1:9050/projects/codex/commit-explanations?limit=3'Then open myflow:
- project view:
/flow/codex - commit view:
/flow/codex/commit/<sha>