docs: refresh README content + regenerate screenshots/demo - #97
Merged
Conversation
…sections Content-quality pass for #96: - Rewrite the intro/value-prop (plain, honest-data framing) and CTA. - Add a user-facing "How it works" walkthrough (scan -> manifest -> render). - Add an "Info pane" section (Overview + Legend). Stale-content fixes verified against current code: - Quick start: Projects page + branch pick + header switcher (was "paste a git URL into the source picker"). - Settings: real three-tab layout (World draft/Save, Live updates, Appearance with the accent+surface theme switcher), was a flat list. - Scanning: note remote repos are cloned + cached, local read in place. - Development: add uv to prerequisites (just fmt / gen-types). - Drop two pre-existing em-dashes (house rule). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regenerate .github/readme/*.png deterministically instead of hand-capturing, so the shots stop drifting from the design. - app/src/city/capture: a debug-gated ?shot=<name> harness. It waits for the city's first render, poses the camera by reusing the real rig (reset / focus) with subjects picked from the manifest's precomputed leaderboards (tallest building, densest street, biggest commit), then marks the frame ready. Lazy imported from main.tsx only when ?shot is present, so it never ships normally. - scripts/screenshots.mjs + `just screenshots`: Playwright loads codecity pointed at its own repo, captures each shot's <canvas> to .github/readme/. - Needs `just dev` running; reads its URL from `just url`. The animated demo.gif is not automated (capture by hand). Shot framings are a first pass and can be tuned in app/src/city/capture/shots.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Node resolves ESM imports from the script's own directory, not the cwd, so scripts/screenshots.mjs couldn't find playwright (installed in app/node_modules) even when run from app/. Relocate it to app/scripts/ and run it from there. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Completes the move: the new app/scripts/screenshots.mjs, the `just screenshots` recipe now running it from app/, and the harness comment reference. (The prior commit only recorded the old file's deletion.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The rig's focus methods are all top-down, so the buildings/streets/gem shots
came out flat and far. Add:
- rig.captureView({target, distance, elevation, azimuth}): a generic snap to
any angle (not just top-down), for street-level framings.
- rig.captureAnchors(): world positions + scales (gem, tallest building, city
center/radius) the poses frame against, so distances scale with the repo.
- shots.ts: buildings/streets/gem now aim close + low; ?elev=&az=&dist= URL
overrides let you dial a shot in live in the browser before baking values.
trees/fireflies stay whole-city framings pending a bigger multi-author demo
repo (codecity itself is too sparse to show a forest / firefly swarm).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The trees + fireflies shots need a big multi-author repo, so capture them against fastapi/fastapi (per-shot src/branch override in the script; codecity stays the default for the other five). - trees: wide low pull-back (captureView on city center) so the dense forest ringing the city fills the frame. - fireflies: close on the busiest commit's tree (new rig.treeAnchor) so its authors' orbs are visible. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Targeting the gem/root point centered the glowing gem, so the shot read as a gem close-up. Add rig.streetAnchor(path) and aim the streets shot at the densest directory's street from a steeper top-down angle, so the labeled road grid fills the frame. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- trees: adopt the low forest-immersion framing (dense trees fill the foreground, city behind) instead of a far aerial. - fireflies: tighter on the busy tree so the author orbs read. - gem: was a street-level shot with the gem a speck at the top; now close and looking down at it, distance scaled off the root-street width (rig anchor). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- gem: was clipped and near-level; double the distance and raise elevation to ~46 so it looks down on a fully-framed gem. - fireflies: closer (radius*2, lower angle) so the orbs read bigger. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
reset() framed the whole city, leaving the repo-name label too small. Switch the banner to captureView centered on the gem/label at the same low angle, pulled in via cityRadius. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Targeting the gem put the city far-right with dead space; cityRadius*1.5 was also too far, so the label was unreadable. Center on the city and pull in to cityRadius*0.75. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eflies - banner: aim just above the gem (toward the floating label) and pull in to cityRadius*0.55 so the repo label reads and stays framed. - buildings: target the most color-varied street, excluding the root (whose street holds the gem), so the gem stays out of the shot. - swap the trees and fireflies framings per request (trees tight on a tree, fireflies a wider forest immersion). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tree.radius*2 put the camera inside fastapi's huge busiest-commit canopy (green blob). Pull back to radius*4 so the tree reads with its surroundings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ful (gem allowed) - trees: wide forest immersion (radius*6); fireflies: tighter on the busy tree (radius*4). - buildings: most color-varied street (mostColorfulDirPath), no longer excluding the root, so it can pick the gem-adjacent junction where the hues are. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
radius*4 -> radius*3 and a slightly lower angle, so a single tree with its author orbs fills more of the frame. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`just screenshots fireflies trees` redoes just those; `just screenshots` still does all. Unknown names are reported and skipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
radius*2, low angle, aim below canopy center so the whole tree frames. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- bump the ready-wait to 360s (a big repo's first git-log walk is slow). - capture harness signals ready even if a pose throws, logging the error, so a bad pose gives a screenshot instead of a 180s timeout. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The busy commit we target has a max-size canopy, so radius-based distance zoomed way out. Frame by tree height (consistent) for a genuinely tight tree shot. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
captureView can now fit a bounding sphere to the live camera FOV (same math as focusTree). fireflies uses it to fill the frame with one tree at a low angle, instead of my hand-rolled distance that kept landing too far out. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
treeAnchor(sha) is null for commits the layout didn't place a tree for, and the busiest commit often isn't placed, so both shots silently fell back to the whole-city view. Walk commits (most authors first, for more orbs) and use the first one that has a real placed tree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Temporary instrumentation: forward the page console to the terminal and log whether a placed tree was found and the distance the fit computed, to diagnose why fireflies keeps framing the whole city. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Root cause of the wide fireflies/trees shots: on a fresh big-repo scan, trees haven't finished placing at the first idle, so treeAnchor is null for every commit and the shot fell back to the whole-city view. Shots now return false when their target isn't ready; the harness polls (400ms x30, ~12s) until the pose lands, then captures. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ding 1.15->1.6) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the fireflies/captureView diagnostic logs; keep only real page-error forwarding in the capture script. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ance) radius*6 was a fireflies-style close-up once it targeted a normal tree. Scale the pull-back to cityRadius so the forest fills the frame with the city behind. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ist 0.2->0.16) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fresh .github/readme/*.png from `just screenshots`: codecity for banner/overview/buildings/streets/gem, fastapi/fastapi for trees/fireflies (multi-author forest). demo.gif still pending. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an `orbit` capture shot that installs a per-frame window.__ccOrbit(azimuth) framing the whole city, plus app/scripts/demo-gif.mjs + `just demo-gif`: step the camera a full turn, screenshot the canvas each frame, and encode to .github/readme/demo.gif with ffmpeg (two-pass palette). Requires ffmpeg. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The gif is automated now, so drop the "capture it by hand" notes in the screenshots script + recipe. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Gif was a poor fit (a smooth 3D orbit ballooned to 21MB). Record the orbit as video instead: - orbit shot self-drives one time-based 360deg turn (fps-independent, seamless loop), marking data-cc-orbit-start/done. - app/scripts/demo-video.mjs + `just demo-video`: Playwright records the canvas in real time (fast, no per-frame screenshots), pins it full-viewport via an init-script CSS so there's no chrome, trims to the orbit, and encodes a small h264 mp4 with ffmpeg. - README embeds it with <video autoplay loop muted>; drop demo.gif + demo-gif. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ppy) Headless Chromium renders WebGL in software at a low frame rate. Launch headed (+ uncapped fps) so the orbit records smoothly; a window appears during capture. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Generated via `just demo-video`; replaces the 21MB gif. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Audited every claim against the code and fixed the stale ones: - Trees: drop "age desaturation -> gray" (removed from code) and "facet detail" (facets are a fixed constant; only canopy width tracks files changed). - Settings > Trees: real controls (visibility, color, height, width, outlines), not "density falloff / age desaturation / facet detail". - Controls: clicking the gem resets the view, it doesn't select it; note that in the Controls table + Gem section. - Buildings: window glow tracks creation recency, not last-modified. Formatting: Settings > World as a list, How it works as numbered steps, Development commands as a table (incl. screenshots/demo-video/lint/clean), reworded the Scanning paragraph. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GitHub doesn't render <video> with a relative src. Point it at the raw main URL so it plays in the rendered README (once this is merged to main). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Removing the trailing sentences ran Live updates / Appearance / How it works together; put the paragraph breaks back. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match the World tab: bold lead-in + a bulleted list of each tab's controls. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tighten to match the terse, technical style of the original sections: drop marketing framing (Info pane "travel guide"), use the project's vocabulary (city model, skeleton/placeholder render, three.js), compact the How it works steps and Scanning, and cut filler. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Break the run-on sentences into lists (Local directories now has a Tips block like Quick start). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Group sections so concerns stop interleaving: - Advanced setup: Local directories + Ignoring files (always-skip list + .codecityignore). - Reading the city: the encodings (buildings/streets/trees/fireflies/gem) with the Info pane folded in. - Settings, then How it works (now absorbs the Scanning read mechanism). - Remove the Controls section. Also: gem = root marker + interaction only, Info pane Overview as nested bullets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Quick start as 1/2/3 steps + bold Tips; drop the recents/switcher tips. - "Local repo" (no hyphen); split Always skipped / .codecityignore headers and drop the no-slash/has-slash bullets. - Drop "Every model maps to real data"; gem as bullets; info pane "describes the city" (not "reads the city back to you"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Advanced setup: nest the default-skip list under .codecityignore. - Remove the Info pane section. - Settings: sub-bullets for each control; poll interval as min/max. - How it works: colon step labels, "Layout", note that Scan honors .codecityignore. - Development: Setup / Commands / Worktrees / Backend subsections (prereqs + backend as bullets). - Release: steps + a Verify signatures subheader. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the !.git/! prefix detail bullets, add a "Skipped by default" subheader for the default-skip list, and give the gem bullets bold labels like the rest. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Convert the Settings section to a Tab / Section / Tweaks table. - .codecityignore: drop the ! detail bullets, add a "Skipped by default" header. - Gem bullets get bold labels. - Clarify file created/last-modified dates vs commit date in How it works. - localStorage -> localstorage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #96.
Content
uvprereq). Verified the Controls table and encodings still match.Screenshots + demo
.github/readme/*.pngfrom a new capture harness: codecity for banner/overview/buildings/streets/gem,fastapi/fastapifor the trees/fireflies (a multi-author forest, since codecity itself is too sparse).demo.gifwith a 2 MB loopingdemo.mp4and a<video>embed.Tooling (new)
app/src/city/capture/— a debug-gated?shot=/?orbitcapture harness (reuses the real camera rig; never ships in a normal session).just screenshots [names]— regenerate all or specific shots (app/scripts/screenshots.mjs).just demo-video— record the orbit and encodedemo.mp4(app/scripts/demo-video.mjs, needs ffmpeg).Note
GitHub's rendering of
<video>with a relative path can be unreliable. If the demo doesn't autoplay in the rendered README, switch thesrcto the absolute raw URL (https://github.com/thalida/codecity/raw/main/.github/readme/demo.mp4), which resolves once merged tomain.🤖 Generated with Claude Code