Exclude files and directories from the city via the UI#104
Merged
Conversation
Object-valued persistedSignal used diff-vs-default, which only emits keys present in the default. EXCLUDES's keys are runtime repo hashes, so every write serialized to null and was removed. Add an opt-in whole-object mode and use it for EXCLUDES; add round-trip persistence tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The section header restore-all uses Section's reset affordance (via a new optional onReset for non-draft sections) and per-row restores reuse the shared theme-row-reset class, so both read as the accent reset glyph and line up at the content edge, instead of a bespoke gray 'Clear all' button.
The icon sizing hook was named after the icon library, hardcoding lucide into every icon call site's markup. Renamed to .icon so swapping icon libraries doesn't mean touching every component. Mechanical class rename, no behavior change.
Scan and Appearance sections now match World: expanded by default (defaultOpen), a section-header reset, and per-row resets in the standard head slot (right of the label) via ThemeRow's resetSlot. Converts the two Appearance sections from flat inline blocks to Section accordions. Only the save logic differs per tab; the settings UI is now consistent everywhere.
No SectionNode set inline: true after the Scan tab moved to real accordions; .controls-inline-section had no CSS rule. Drop the unused branch + field.
It's the generic settings-panel row used by every tab, not theme-specific. Renames the component + file + imports; leaves the theme-* CSS class vocabulary alone (a broader rename, and some theme-* classes are genuinely about themes).
) The theme-* class prefix was the settings panel's generic control vocabulary (row, slider, toggle, select, range-pair, subgroup, ...), not visual-theme styling. Renamed to setting-* to match the SettingRow component. The real theme system (accent/surface/syntax pickers, data-cc-*, themes.css) is untouched.
A count badge on the Settings activity-bar icon shows how many settings + excludes differ from default (pulses when it changes), and each subtab (Scan, Appearance, World) shows a dot when anything under it is changed. Reactive signals in settingsIndicators.ts; excludes are folded into the Scan count/dot and the total explicitly since they aren't settings-draft stores.
Solid accent with white text was muddy at 16px; invert to a surface pill with an accent border and accent text for legibility.
A keyed remount doesn't restart a CSS animation (Preact reuses the node), so the ring only played on first appearance. Restart it explicitly with an animation reset + reflow in a layout effect keyed on the count.
#98) The faint expanding ring was easy to miss; use a clear scale bounce, and under prefers-reduced-motion flash opacity instead of disabling the cue entirely.
Heights and widths were min-max normalized per repo, so the largest file always hit MAX_FLOORS/MAX_WIDTH regardless of its real size: a repo of tiny files became a cluster of similar tall buildings. Add a per-repo ceiling anchored to the absolute size of the biggest file (new FULL_HEIGHT_LINES / FULL_WIDTH_KB Buildings sliders): small-file repos read as a low-rise/narrow city while the per-repo relative spread is retained. Large repos (biggest file >= reference) are unchanged. Recaptured the layout + decoration golden baselines (counts identical, only dimensions shifted).
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 #98
Hide files and directories from the city through the UI, instead of only via a
.codecityignoreon disk. Select a road or building, click "Exclude from city" in the right pane, and it is gone. Works on remote URLs too, since nothing is written to the repo.This branch grew past the core feature into the settings pane it touches, plus a building-height fix that came out of QA. Details below.
Excludes (the #98 core)
Excludes go through the existing scan pipeline, not a separate client-side filter. The frontend keeps your per-repo exclude list in localStorage and sends it as
?exclude=params; the backend feeds those paths into the same_should_skiplogic that already handles.codecityignoreand the built-in skip list. So the manifest stays backend-authored: every rollup, stat, and signature is computed once, over the already-filtered tree, and the city, tree, search, and overview all drop the excluded path.extra_exclude_pathsthreaded throughscan_tree/signature_tree, plus a repeated?exclude=param on/api/manifestand/api/manifest/signature. Additive only, layered afterALWAYS_SKIP+.codecityignore(can't resurrect a default or reach.git).EXCLUDESstore (keyed by src, branch-invariant) + a new{ whole: true }mode onpersistedSignalso a dynamic-key map actually persists.Settings pane
The excludes list needed a home, which turned into consistency work across the Settings pane:
Refactors (folded in per review/feedback)
.lucide-iconclass renamed to a library-neutral.iconacross the app (call sites no longer name the icon library). Full<Icon>wrapper for the remaininglucide-preactimports is filed as Icon abstraction: decouple call sites from lucide-preact #105.ThemeRowcomponent renamed toSettingRow, and the wholetheme-*settings-control class vocabulary tosetting-*(the real theme system is untouched).inlinesection variant.Building heights + widths (from QA)
Heights/widths were min-max normalized per repo, so the largest file always hit MAX regardless of its real size: a repo of tiny files became a cluster of similar tall buildings. Added a per-repo ceiling anchored to the absolute size of the biggest file, tunable via two new Buildings sliders (Full height at (lines), Full width at (KB)). Small-file repos read as a low-rise/narrow city; repos whose biggest file is at/above the reference are unchanged. Layout + decoration golden baselines recaptured (counts identical, only dimensions shifted).
Testing
just test(api pytest + full app suite) andjust lintgreen. New coverage across the exclude flow (backend precedence/signature, persistence round-trip, the switch-guard, URL builders, store, pane/settings UI), the settings indicators, and the building-dimension ceiling. Still wants a manual pass in the running app: exclude a dir and a file, confirm live re-render + persistence across reload on a remote URL and a local path; and eyeball the height scaling on a small-file vs large-file repo.Out of scope
Editing the on-disk
.codecityignorefrom the UI, glob patterns (exact path only), and un-ignoring backend defaults.🤖 Generated with Claude Code