Skip to content

Releases: teapotlaboratories/git-view

GitView v0.1.15

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 06 Aug 04:41

GitView v0.1.15

Boards get a third dimension: long-press a component in the PCB viewer and its 3D model opens.

What's new

3D part viewing (ADR-038, Phase 4a). Long-press a part on a board to see its model — drag to orbit,
pinch to zoom. Rendering is Filament core only; the glTF loader and runtime material compiler are
deliberately excluded, so the app grows by ~3.4 MB rather than ~24 MB.

Meshes are converted ahead of time, on the host. The bridge does not tessellate STEP inside a
request. gitview-models converts each unique model once into a content-addressed cache and the bridge
serves the result — which matters because reuse is heavy: one board here has 1,480 model references to 66
unique models. The bridge itself stays at ~4 MB.

Board viewer fixes. Pinch now zooms about the point under your fingers instead of the canvas origin,
so a large board no longer accelerates off-screen. Copper layers are no longer silently truncated — the
cap is by role now, after a survey found a real board's front copper at 20,887 elements against the old
flat 20,000 limit. Saving a file no longer discards the layers you had chosen.

Upgrading

Nothing to do. Existing pairings, tokens and repositories are unchanged, and no configuration is
required to keep what you already had working.

To actually see 3D you need meshes, which are converted on the host rather than downloaded by the app.
Boards whose models resolve to the official KiCad library or live inside the repository work once
converted; see docs/PLAN.md for the pipeline.

Things that will surprise you

Some parts will not appear, and that is usually not a bug. A board references its 3D models through
path variables that live in the designer's KiCad settings — private libraries, converter output
directories, sometimes absolute Windows paths. When those are somebody else's, the geometry was never
published and nothing can fetch it. Measured across the KiCad 10 demo boards, 27% of unique models are
unresolvable, and it is concentrated rather than spread: two of those boards are almost entirely
unresolvable, while others are fully covered. Your own boards, on a machine that has your own libraries,
should fare far better. Coverage is reported per board rather than hidden, so a near-empty 3D view is
never left looking like a broken viewer.

Long-press only offers parts that actually have a mesh. Components without one are skipped rather
than opening an empty viewer.

3D works under the Color E-Ink profile. Earlier planning assumed it would be pointless there; it is
not. The viewer takes its backdrop and default part colour from the active theme, so the model reads as
dark-on-paper on e-ink and light-on-dark on the standard theme.

The Android release build ships arm64-v8a and armeabi-v7a only. x86/x86_64 are emulator-only ABIs
that cost 4.4 MB every phone would download and never load. A release build therefore cannot render 3D on
an x86_64 emulator — use a debug build there.

Also fixed

tools/release.sh returned exit code 1 from every successful build. An EXIT trap whose last command was
a false test replaced the script's own status under set -e, so a run that assembled, signed, verified
and checksummed correctly still reported failure to anything reading its exit code.

Artifacts

Both components are published every release, even when only one changed:

  • gitview-0.1.15.apk — Android app, signed
  • gitview-bridge_0.1.15_*.deb — host bridge, one per architecture
  • SHA256SUMS
sha256sum -c SHA256SUMS
apksigner verify --print-certs gitview-0.1.15.apk   # cert SHA-256 must match the README

GitView v0.1.14

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 03 Aug 14:09

GitView v0.1.14 — KiCad boards, and cross-probing between schematic and PCB

GitView could already draw a KiCad schematic and highlight a net across it. This release adds the
board, and lets a selection cross between the two.

Open a .kicad_pcb

A board tab draws the PCB instead of showing its s-expression source.

It opens showing almost nothing, on purpose. You get the board outline immediately — a couple of
kilobytes — plus a row of layer chips carrying their populations (F.Cu 5376, B.Cu 4771, In2.Cu 540).
Copper is fetched only when you switch a layer on, because a copper layer on a real board is megabytes and
nothing should spend that before you have said what you want to look at. The counts are there so enabling a
layer is an informed choice rather than a surprise.

Tap a track or a pad to select its net. On colour the net goes accent and the rest dims; on the Color
E-Ink profile there is no accent to fall back on, so selection is carried by stroke weight — the same
rule the diff and schematic viewers already follow.

Only layers that actually hold something are offered. A board declares 39 and most are empty.

Cross-probe: schematic ⇄ board

Select a net on the schematic and an on board → action appears. It opens the .kicad_pcb beside it
with the same net already selected and copper switched on, so you land on the answer rather than a blank
outline. on schematic → goes back the same way.

The action only appears when there is genuinely a counterpart to open. GitView asks the bridge whether the
sibling file exists at the ref you are browsing rather than guessing from the filename, so it will not
offer you a button that fails.

A drawing that keeps up with its file

Previously, if a schematic or board changed on disk while you had it open, the picture quietly stopped
being true — the text refreshed underneath, the drawing did not. Editing a board in KiCad with GitView open
beside it now shows the change instead of a stale render.

A related hang is fixed too: resolving a save conflict on a KiCad tab left it on a loading skeleton
permanently.

Fixed: large boards failed at any committed ref

Reading a blob was capped at 64 MB. A KiCad board is the first thing GitView opens that is routinely
bigger — vme-wren.kicad_pcb is 66 MB — so browsing one at a branch or commit failed with an internal
buffer error while the working-tree copy worked fine. Blobs now have their own 128 MB ceiling, checked
before reading, so an oversized file gives a clear error naming the file and both sizes.

Also fixed

  • Copper was being silently truncated. A flat 20,000-primitive cap per layer, chosen from one board,
    cut real routing on a denser one — missing traces on the layer the feature exists to show. Caps are now
    by role: copper, silkscreen and the board outline get a much higher ceiling, annotation overlays keep the
    tight one, and truncation always says which kind of loss it was.
  • Net chips are properly tappable. They were a ~20 dp target with no accessibility role; now 48 dp,
    announced and operable by a screen reader.
  • The schematic no longer draws over the toolbar or under the navigation bar, and framing ignores
    stray annotation parked away from the circuit.
  • A memory fault on the bridge: browsing a few large boards could retain gigabytes.

Upgrading

Nothing to do. No re-pairing, no configuration change, no migration. Install the .deb on the bridge
host and the .apk on the device, in either order.

The .apk is signed with the same release key as previous versions, so it upgrades in place over
v0.1.13 — your saved bridges and pairings are kept.

Both artifacts

Every release ships both, whichever component changed. This time both did.

  • gitview-bridge_0.1.14_all.deb — the host bridge
  • gitview-0.1.14.apk — the Android client (release-signed)
  • SHA256SUMS

Verify the APK's signing certificate matches the SHA-256 published in the README before installing.

Known limits

  • Selecting a component on the board is not supported — only nets. Locating a footprint needs shape
    data the per-layer format does not carry, so it is absent rather than half-working.
  • 3D is not in this release.
  • On a multi-layer board, cross-probing a net that is a ground plane lights the whole plane. That is
    accurate, and it is visually heavy.

GitView v0.1.13

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 30 Jul 04:45

Bridge-only release, and an important one if you run the bridge on a machine with large repositories.

⚠️ The .deb filename has changed

There is no longer a single gitview-bridge_<version>_all.deb. The package is now architecture-specific:

gitview-bridge_0.1.13_amd64.deb     ← most machines
gitview-bridge_0.1.13_arm64.deb     ← Raspberry Pi, Apple-silicon VMs, ARM servers

Anything scripted against the old filename needs updating. Installing the wrong one now fails at
install time, which is the improvement — before, an architecture mismatch could only fail later, at
runtime.

Nothing else about installing or upgrading changes, and no re-pairing is needed.

The bridge was consuming every file watch on the machine

On a host with sizeable repositories the bridge would quietly take every inotify watch the kernel
allows
— on the dev box, 119,573 of 119,664. Two things followed, both silent:

  • The bridge stopped noticing file changes. It kept serving, kept answering health checks, and simply
    never pushed another update. Nothing in the log said so.
  • Everything else on the machine broke too. Once the budget is exhausted, any program that wants a
    file watcher fails — editors, build tools, test runners.

The cause was watching every file, not every directory. A directory watch already reports changes to the
files inside it, so the per-file watches bought nothing and cost everything. The bridge now uses the same
directory-level watcher VS Code does, and skips whatever the repository's own .gitignore excludes —
asked of git directly rather than guessed at, so build output and vendored dependencies are never walked.

Measured on the same machine and repositories: 119,573 watches → 8,458. On a second host with a
237,000-path repository, 14,007 — a repository that alone would previously have wanted twice the
kernel's entire limit.

If you have ever seen "unable to watch for file changes" from an editor on a machine running the bridge,
this was very likely why.

Also

  • A repository that cannot be watched now says so in the log instead of failing silently — it was
    indistinguishable from one whose initial scan was still running.
  • Removing a workspace while its initial scan was still in progress could leave a watcher behind that
    nothing could release. Fixed, with a test that fails without the fix.

Artifacts

Bridge 0.1.13 (amd64 and arm64), app 0.1.12 — unchanged this cycle and included so the tag
carries the complete pair. Verify the APK signature against the cert SHA-256 in the README before
installing.

GitView v0.1.12

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 29 Jul 16:03

App-only release. The bridge is unchanged — there is nothing to upgrade on your machines, and nothing
to re-pair.

Adding a bridge no longer hides the form behind the keyboard

If you already had bridges saved, tapping + Add a bridge and then a field put the whole form — Name,
Base URL, Save, Cancel — behind the soft keyboard. You were typing into a field you could not see, with no
way to reach Save. With an empty list it looked fine, which is why it went unnoticed for so long.

Two things were wrong. The keyboard inset was never applied to that screen, and the form sat outside the
scrollable list, so it only ever got whatever height the list left over — with the keyboard up, none, and
nothing could scroll it back into view. The form is now part of the list: it scrolls like any other row,
and opening it scrolls it into view.

Worst on a tablet, whose split keyboard takes roughly half the screen. Fixed and checked there, on a
phone, and on the 7" colour e-ink panel.

Where 0.1.11 went

The app jumps 0.1.10 → 0.1.12. Nothing is missing: the bridge is at 0.1.11 and the previous release
already used the tag v0.1.11, so the app skipped that number rather than collide with it. The two
components version independently and are expected to diverge.

Artifacts

Both are attached, as every release should be: app 0.1.12 (versionCode 12) and bridge 0.1.11.

The bridge .deb is byte-identical to the one in v0.1.11 — its version does not move because nothing in
it changed. It is here so this tag carries the complete pair and nobody has to work out which earlier
release holds the other half. If your bridges already run 0.1.11 there is nothing to install.

Verify the APK signature against the cert SHA-256 in the README before installing.

GitView v0.1.11

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 29 Jul 01:25

Host administration moves off signals and direct file edits onto a proper control socket, and legacy
bare-token authentication is removed.

⚠️ Read this before upgrading a bridge

Every device still holding a pre-0.1.8 token stops working and must pair again. Those tokens carried
no identity, could not be revoked individually, and sat in tokens.json in plaintext — the one thing the
hashed store exists to prevent. They are no longer accepted.

You do not have to guess whether this affects you. On start-up the bridge counts them and says so:

WARNING: /var/lib/gitview-bridge/tokens.json holds 6 pre-0.1.8 token(s), which are NO LONGER ACCEPTED.
         6 device(s) must pair again: gitview-bridgectl pair
         They are dropped from the store on its next write.

Recovery is one command per device — sudo gitview-bridgectl pair, then enter the code in the app.
Nothing restores the old tokens; a tokens.json from a backup is ignored just the same. Upgrade when
you can reach the affected devices
, not before.

Devices paired since 0.1.8 are unaffected and need no action.

Host administration over a unix socket

gitview-bridgectl no longer edits tokens.json or signals the process. It sends named commands to the
bridge over /run/gitview-bridge/control.sock (0600, created by systemd's RuntimeDirectory), and the
bridge is the single writer of the store. What changes for you:

  • revoke no longer invalidates a pairing code you just minted. A signal carries no payload, so the
    old handler had to mint a code and reload on every ring — meaning revoking a lost phone burned the
    code you had just generated to re-pair a good one.
  • pair prints the code from the bridge's reply instead of grepping the journal for a line it had
    just caused to be printed.
  • devices shows CONNECTED — live socket state, which a file-reading CLI could never know.
  • revoke reports what actually happened (— 1 credential, 1 connection(s) closed) rather than
    assuming its own write worked.

The cost, stated plainly: a stopped bridge has no socket, so these commands now fail with "bridge is not
running" instead of quietly editing the file. Hand-editing tokens.json remains the break-glass path.

A revoked device now says so

Revoking a connected device closes its live socket with 4401. The app previously handled only HTTP
401, so it treated that close as an ordinary network blip and reconnected forever — showing
"Connection lost — reconnecting…" indefinitely, never telling you access had been withdrawn. It now drops
the token and offers to pair again. An ordinary disconnect still reconnects silently and keeps its token.

If you are upgrading a bridge with pre-0.1.8 tokens, this is the fix that makes those six devices tell
you what happened instead of spinning.

Also

  • devices / revoke / pair are documented in SETUP for the first time; the old advice to restart the
    bridge for a fresh code is gone (it dropped every connection).
  • A second bridge can no longer steal a live control socket from the first.

Artifacts

Bridge 0.1.11 (.deb, all), app 0.1.9 (versionCode 10). Verify the APK signature against the
cert SHA-256 in the README before installing.

GitView v0.1.9

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 27 Jul 13:47

GitView v0.1.9

Bridge-only release. The bridge goes to 0.1.9; the app is unchanged and stays at 0.1.8 — the
gitview-0.1.8.apk from the previous release is still current, and there is no new APK here.

The diff view no longer refreshes on a loop

On a repository with submodules, simply viewing a diff could make it re-render about once a second,
which made reading or scrolling one almost impossible.

Serving a diff makes git take a lock file inside each submodule. The bridge treated that lock as a real
change and told the app, the app re-fetched the diff, and that took the lock again. The trigger was the
request itself, so it only appeared while you had a diff open — and it looked like a machine-specific
problem when it was really a matter of how recently a repo's submodules had been refreshed.

Transient git internals are now filtered at every level of a repository, not just the top, so this cannot
feed itself. Real changes are unaffected: editing a file inside a submodule still updates the view, as
does any genuine git activity — a fetch, a branch switch, a commit.

A submodule's own .gitignore is now honoured

Related and previously impossible: ignore rules inside a submodule had no effect, because the check the
bridge used refuses any path belonging to a submodule and quietly gave up on the whole batch when it hit
one. Ignore filtering is now done per repository, so build output under a submodule — an ESP-IDF build/
directory, for instance — no longer reaches the app at all.

This also means the gitignore filtering added in 0.1.8 genuinely applies to submodule repositories for the
first time; on those it had been silently inactive.

Upgrading

Nothing to do beyond installing the .deb. No re-pair, no configuration change, and no new APK — your
paired devices and tokens are untouched. The service restarts itself, so the app reconnects within a few
seconds.

Install

sudo dpkg -i gitview-bridge_0.1.9_all.deb

Debian/Ubuntu, Architecture: all; requires Node.js ≥ 20 on the host.

Verify

sha256sum -c SHA256SUMS

GitView v0.1.8

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 27 Jul 02:10

GitView v0.1.8

Both components changed this cycle, so both are released: bridge 0.1.8 and app 0.1.8
(versionCode 9).

Device authentication is now per-device (ADR-035)

The bridge used to hold a flat list of interchangeable bearer tokens. It now keeps a record per device,
which makes three things possible that weren't before.

  • See what's pairedGET /v1/devices lists each device with its name, when it was last seen, and
    whether it's connected right now. The app surfaces this at Repos ⋮ → "Paired devices…", and devices
    arrive named (your phone reports its model at pairing time) rather than as an anonymous entry.
  • Revoke one device without touching the others — previously the only remedy for a lost phone was
    wiping every token and re-pairing everything.
  • Revocation takes effect immediately. A WebSocket authenticates once when it connects, so a revoked
    device would otherwise keep streaming until it happened to disconnect. Revoking now closes that device's
    live connections (4401) and kills any shells it had open.

Secrets are no longer stored in a readable form: the bridge keeps only a SHA-256 of each token, so the
state file grants nothing if it leaves the host — a backup, a synced dotfile, a bad chmod. Note the
bound: this protects the file in transit, not against someone who already has shell access on the host,
who can run commands regardless. Token lookup also drops from a scan of every token to a direct lookup.

Audit entries now name the device that acted, instead of logging every write from every device as the
same anonymous app.

Upgrading — nothing to re-pair

Tokens issued before this release keep working. They appear together as one "unknown legacy device(s)"
entry, because they carry no identity and genuinely can't be told apart; revoking that entry drops all of
them at once. Re-pair a device to give it its own identity and individual revoke.

Two behaviours worth knowing: a device cannot revoke itself (un-pair from the device instead), and a
client still holding a pre-upgrade token is the legacy group, so it can't clear that group — re-pair it
first. Any paired device may revoke any other; pairing is the only privilege boundary.

Also fixed

  • The diff no longer flickers while a build runs. The file watcher was announcing changes for
    gitignored paths (build/, dist/, node_modules/), so the app kept refreshing a view that couldn't
    have changed. Ignored paths are now filtered out — and if the check ever fails, it errs toward
    announcing rather than swallowing a real change.
  • A body-less DELETE sent with Content-Type: application/json returned 500 instead of working.
    Affected any client that sets the header globally.
  • Concurrent writes to the device store are serialized, so an overlapping pair/revoke can't lose an
    update or fail on a temp-file collision.
  • The device list is scoped to its own bridge — connecting to a second bridge no longer carries the first
    one's device identity across.

Install

Bridgesudo dpkg -i gitview-bridge_0.1.8_all.deb (Debian/Ubuntu, Architecture: all; needs
Node.js ≥ 20 on the host). The service restarts itself; your config and tokens are preserved.

App — install gitview-0.1.8.apk. It upgrades 0.1.7 in place.

Verify

sha256sum -c SHA256SUMS
apksigner verify --print-certs gitview-0.1.8.apk   # cert SHA-256 must match the README

GitView v0.1.7

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 25 Jul 03:24

GitView v0.1.7

Adds an interactive Terminal to the workspace, plus a batch of git-workflow fixes. Both the app and the bridge change this release.

Terminal (new)

  • A third workspace view, beside Files and Chat. Open View ▾ → Terminal (phone / e-ink) for a real
    interactive shell on the bridge host, starting in the open repo. Colored output (ANSI/SGR), running
    commands, streaming logs — a line-oriented model, so full-screen TUIs (vim/htop/tmux) are out of scope.
  • Per-repo shells. Each repo keeps its own shell and scrollback; switching repos switches shells.
  • Type straight into the console — no separate input box. The keyboard appears on tap and the console
    resizes above it; a slim ^C / ^D / Tab / Esc / arrows row supplies the keys a soft keyboard can't send.
  • Pinch-to-zoom the font (remembered per repo).
  • On by default. Set terminal.enabled: false in config.yaml to turn it off (the app then hides the
    view). ⚠️ The terminal is a full host shell — arbitrary code execution as the bridge's run-user, outside
    the agent's sandbox/permission tiers. It's auth-gated, audited, and shells are capped per connection and
    killed on disconnect — but treat enabling it like handing out SSH. See docs/SECURITY.md.

Git workflow

  • Push just works on a new branch — the first push auto-sets the upstream (origin/<branch>) instead of
    failing with "no upstream branch".
  • The working-tree diff now shows untracked (new) files, not just tracked edits.
  • Create a branch on an empty repo (no commits yet) works instead of erroring.
  • Clear messages: committing with nothing staged says so; switching branches with uncommitted changes
    says "commit or stash first" instead of git's wall of text.

Bridge

  • Pure-JS PTY via script(1) — no native module, so the .deb stays small and Architecture: all.
  • New live-channel frames (terminal.*) and a features.terminal flag on /v1/health.

Upgrading

Both artifacts changed this release — install both. They install over the existing app / service:

sudo dpkg -i gitview-bridge_0.1.7_all.deb     # restarts the systemd service; config is preserved
# then sideload gitview-0.1.7.apk (installs over the existing app, same signing key)

Verify the downloads

sha256sum -c SHA256SUMS
apksigner verify --print-certs gitview-0.1.7.apk   # SHA-256: 67:53:4C:…:34 (CN=Aldwin Hermanudin)

See the README "Releases & verification" section for the full fingerprint.

GitView v0.1.6

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 24 Jul 07:25

GitView v0.1.6

Workspace-UI polish, all in the Android app — the bridge is unchanged from v0.1.5.

App

  • One top navigation bar. The phone / e-ink workspace had two stacked bars; they're now a single
    row — back · branch ▾ · … · View ▾ · ⋮. The branch chip ellipsizes so a long branch name can't
    crowd the actions off a narrow screen.
  • The right-side menu is now "View". It carries the Files ⇄ Chat switch and the explorer-tree ⇄
    editor toggle (moved off the bar into a "File tree" item), above the usual Git actions. On the tablet
    — which shows both panes with a permanent tree — it stays a plain "Git" menu.
  • Create files and folders from the explorer. Long-press a folder for New file… / New folder…
    (created inside it), or use the in the Explorer header to create at the repo root (works on an
    empty repo too). A new file opens straight in the editor.

Upgrading

The .deb is unchanged from v0.1.5 (same bridge); you only need the new .apk. It installs over your
existing app:

# (bridge only if you want the version to match — no functional change since v0.1.5)
sudo dpkg -i gitview-bridge_0.1.6_all.deb

Verify the downloads

sha256sum -c SHA256SUMS
apksigner verify --print-certs gitview-0.1.6.apk   # SHA-256: 67:53:4C:…:34 (CN=Aldwin Hermanudin)

See the README "Releases & verification" section for the full fingerprint.

GitView v0.1.5

Choose a tag to compare

@aldwinhermanudin aldwinhermanudin released this 24 Jul 04:10

GitView v0.1.5

A features + polish release: a reasoning-effort control, a nicer chat transcript, friendlier model
names, and a cleaner workspace toolbar — and the bridge now drives the Claude Code CLI already on your
host instead of bundling one.

Bridge

  • Chat drives the host's Claude Code CLI. The .deb no longer bundles the agent CLI (the SDK ships
    it as a ~222 MB per-architecture binary); the bridge points at the Claude Code installed on your
    machine, so the package stays ~3.7 MB and Architecture: all. Chat now requires Claude Code
    installed and signed in on the host
    — browsing, diffing, and editing don't. The CLI is
    auto-discovered on PATH (and the usual install dirs); set claude.cliPath in the config to pin a
    specific binary. A missing CLI now fails with a clear, actionable message instead of an opaque one.
  • Reasoning-effort selector. Choose low / medium / high / xhigh / max for the host agent
    at runtime (support varies by model — the CLI silently downgrades an unsupported level). Set a default
    with claude.effort in the config, or change it live from the app. Unset leaves the CLI's own default.

App

  • Chat opens at the newest message, and transcript text is now selectable and copyable — replies,
    code blocks, and tool output. Auto-tail resumes when you scroll back to the bottom.
  • Reasoning-effort dropdown under Model in the Claude-agent dialog.
  • Friendlier names in the pickers — Opus 4.8, Extra high — while the raw model ids / effort
    values remain exactly what's stored and sent.
  • Cleaner workspace toolbar — Files / Chat moved into the Git dropdown's View section (phone /
    e-ink); the branch chip sits in the top bar.

Upgrading

Install the .deb over your existing one — the service restarts itself:

sudo dpkg -i gitview-bridge_0.1.5_all.deb

For chat, make sure Claude Code is installed on the host (which claude).

Verify the downloads

sha256sum -c SHA256SUMS
apksigner verify --print-certs gitview-0.1.5.apk   # SHA-256: 67:53:4C:…:34 (CN=Aldwin Hermanudin)

See the README "Releases & verification" section for the full fingerprint.