Two gaps that are really one. The framework's stated primary developer is an AI agent. An agent cannot open a browser, cannot look at a running dev server, and cannot read the GitHub web UI. It can read a file, and it can run a command that prints.
x shot <route> — a rendered route, on disk
There is no supported way to get a rendered page into a file. Every app that needs one will grow its own Playwright harness, and each will get the same details wrong. What a first-class one needs:
- boot
x dev on a scratch port — not 3000, which another project usually holds — and drive that,
not the static build (x build --target static prerenders site/ only, so an app/ route
photographs the landing page and reports its island as missing, which reads as a bug in the app);
- write
shot.png and verdict.json: console errors, page errors, mounted island count, canvas
size. A picture cannot tell you the island threw or logged, and that is the half that gates;
- never in
x verify. A gate that needs a browser goes red for reasons unrelated to the change,
and CI does not install one.
x pr review / x pr resolve / x ci
Addressing a review means reading inline review threads. gh pr view --comments does not show them — it shows issue comments, while the actionable findings are anchored to lines and reachable only through GraphQL. The thread id needed to resolve one exists nowhere else. Every team on Ultimate will rediscover that query.
Same for CI: gh run view prints a tree of ticks and one cross, and the error is inside a per-job log that is mostly setup noise. Triage should not cost three round-trips before it starts — and for a verify job the log tail is the findings block, with its X_* codes and executable fix: lines already in it.
Working implementations: scripts/dev/shot.ts, scripts/gh/.
Context: docs/framework/ultimate-gaps.md §8.
Two gaps that are really one. The framework's stated primary developer is an AI agent. An agent cannot open a browser, cannot look at a running dev server, and cannot read the GitHub web UI. It can read a file, and it can run a command that prints.
x shot <route>— a rendered route, on diskThere is no supported way to get a rendered page into a file. Every app that needs one will grow its own Playwright harness, and each will get the same details wrong. What a first-class one needs:
x devon a scratch port — not 3000, which another project usually holds — and drive that,not the static build (
x build --target staticprerenderssite/only, so anapp/routephotographs the landing page and reports its island as missing, which reads as a bug in the app);
shot.pngandverdict.json: console errors, page errors, mounted island count, canvassize. A picture cannot tell you the island threw or logged, and that is the half that gates;
x verify. A gate that needs a browser goes red for reasons unrelated to the change,and CI does not install one.
x pr review/x pr resolve/x ciAddressing a review means reading inline review threads.
gh pr view --commentsdoes not show them — it shows issue comments, while the actionable findings are anchored to lines and reachable only through GraphQL. The thread id needed to resolve one exists nowhere else. Every team on Ultimate will rediscover that query.Same for CI:
gh run viewprints a tree of ticks and one cross, and the error is inside a per-job log that is mostly setup noise. Triage should not cost three round-trips before it starts — and for averifyjob the log tail is the findings block, with itsX_*codes and executablefix:lines already in it.Working implementations:
scripts/dev/shot.ts,scripts/gh/.Context:
docs/framework/ultimate-gaps.md§8.