Skip to content

Comprehensive binary-file support: city building, preview card, and almanac #116

Description

@thalida

Binary files (.db, .wasm, .so, .dll, .node, .bin, …) are second-class everywhere: the city renders them wrong, the preview pane can't show them, and the almanac counts them as if they were code. This issue is the comprehensive fix — treat binary files as a first-class "data" type across the city, the right pane, and the left pane. Reported on tests/data/data.db and ui/*.wasm in pocketbase/pocketbase.

The through-line: a binary file has no line count / no readable text — its only real signal is byte size (+ its byte pattern). Everything below flows from representing that honestly, in-metaphor, instead of pretending it's code. (Precedent: M3triCity adds data files to the CodeCity metaphor as first-class-but-distinct elements; codecity already does this for media files, which is the model to mirror.)

0. Shared data (backend)

FileNode.binary already exists (api/services/scan.py:902, lines = 0 if binary). Add, per binary file:

  • Detected type via magic bytes ("SQLite 3 database," "WebAssembly module," "ELF shared object") — friendlier than a bare extension.
  • Byte-pattern fingerprint — a small fixed-size image (e.g. 64×64 byte-frequency / digram) computed server-side. Never ship raw binaries to the client (a big .wasm = MBs; ties to Large-repo render hang: architectural perf pass (profile-first) #75). One fingerprint feeds both the facade texture AND the preview card.
  • New manifest fields/endpoint → just gen-types + a cache-schema bump.

1. City — the building (windowless, byte-sized, byte-pattern facade)

Keep it in the city metaphor: a binary is a different type of building — codecity's windows show code, and a binary has none, so (like real data centers/warehouses) it's a windowless building.

  • Byte-driven size: branch on FileNode.binary in app/src/city/layout/dimensions.ts (currently height from lines → MIN_FLOORS for binaries; :104-126) and size both axes from bytes so a 5 MB .wasm is a big building, a tiny .db a small one.
  • Windowless facade: a per-instance "is-binary" flag so building.frag.glsl skips the window/door grid and renders a sealed data-center/warehouse facade.
  • Byte-pattern facade: texture that facade with the file's fingerprint (binary-viz examples) so a .wasm and a .db look different. Model the texture pipeline on the existing media path (city/components/buildings/adPanelTextureArray.ts, mediaBatch.ts, adPanels.ts).

2. Right sidebar — file preview (data card, not a failed text view)

FilePreviewPane currently falls to a "binary" state. Replace it with a data card for binary files:

  • Detected type + size + created/modified dates.
  • The byte-pattern fingerprint shown large (same image as the facade — building and detail card match).
  • Optional: a hexdump of the first N bytes.

3. Left sidebar — file tree + Overview almanac

  • File tree: a distinct icon/indicator for binary files so they read as data, not code, in the explorer.
  • Almanac (almanac.ts / OverviewPane): treat binaries like media — media is already excluded from the code-building count (overview.buildings = files − mediaCount) and gets its own "Billboards" section. Mirror it: exclude binaries from the code-building count + superlatives (a giant .db shouldn't win "widest building"), and give them their own section (e.g. "Data: N files, largest is data.db").

Secondary (separate concern)

A single huge binary (or any outlier) still inflates byteStats.max and thins every other building's width. Consider excluding outliers from the size-range normalization or capping — a general outlier problem (a giant generated text file too), independent of the representation above.

Out of scope

Auto-excluding generated text files (.d.ts, generated/) — left to .codecityignore / the UI ignore.

Metadata

Metadata

Assignees

No one assigned

    Labels

    cat:bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions