Skip to content

v0.3.4 — the app, not the workshop

Choose a tag to compare

@devclone20 devclone20 released this 31 Jul 23:27
· 22 commits to main since this release

Download the repository, double-click install.command, and you have the app.

That sentence is the release. Until today this repository was a mirror of the
development tree — panel sources, a 108-file test suite, build tooling, an Electron
shell, planning notes — and finding the app inside it was your problem. Now it
publishes the product: one index.html, the daemon it talks to, and an installer.

Getting it

  1. Download the source zip below (or clone-frame-hub-0.3.4.html alone if you only
    want the app file).
  2. Unzip, double-click install.command.
  3. It builds CLONE FRAME HUB.app into ~/Applications with the whole program
    inside the bundle
    and opens it. The folder you downloaded can then go in the Trash.

macOS quarantines anything from the web, so Finder may refuse the first double-click:
right-click → Open once, or run zsh install.command in Terminal, which never asks.

Updating is what you would guess. Trash the old app, download the new release, run
its installer. Your data is never inside the app — it lives in ~/CloneFrame and
~/.clone-frame-hub — so an update leaves every setting, session and folder alone.
Removing: uninstall.command stops the daemon, removes the app, and asks
separately about your data.

Closing an iT window now closes what was inside it

This is the fix that was costing you something. The code claimed to "reap every live
pty session". It dropped the sockets instead — and for a persistent session, which is
the default, a dropped socket means detach, not close.

So every shell in a window you closed kept running for the full sixty-minute detach
timeout. Builds still building. Dev servers still holding ports. Agents still spending
tokens. Invisible, against a 24-session cap you could not see, with nothing on screen to
tell you. Closing the window looked like closing the window.

Now it ends those sessions three ways, because a socket is not the only way one stays
alive: live tabs are killed in band; every session id the window owns is named to the
daemon, which reaches the ones whose sockets had already dropped and no in-band kill
could touch; and workspaces you restored but never opened — no terminal on screen, real
shells running — are reaped by the window that owns that layout.

Measured against a real daemon, with real login shells and a real marker process:

new  18/18   close kills · reload survives · detached sessions reachable
old  12/18   "no such fn: killMany" — the marker still running, unreachable

A reload still keeps your shells. That distinction is the entire value of persistent
sessions and it is untouched: ⌘R detaches and reattaches, scrollback and all. Keeper
sessions (the ⟳ tab) survive too, deliberately — they are this app's tmux: created on
purpose, listed by it sess list, ended by it sess kill. Closing a terminal window
does not kill your tmux, and nothing about them is hidden from you.

Every panel is one window. iT is the exception, and always was the point

Opening NOTES twice gave you two NOTES windows — the same store drawn twice, two scroll
positions, one set of data underneath. Asking for a panel you already have means show
it to me
, and now it does: including a window you had tucked into a frame square, which
comes back instead of a second empty copy opening on top of the live one.

iT is untouched and infinite on purpose. Terminal windows side by side, each with
its own workspaces, split panes and live shells, is the whole reason it exists.

BROWSER lost its second window, and it was never a decision that it had one. A single
list answered two different questions — may this panel have several windows? and does
docking hide this window or destroy it?
— and BROWSER only ever needed the second
answer, because a docked browser must keep its live pages. It got the first for free.
Two lists now: one window with tabs, docking still keeps every page alive, and the "New
browser window" button is gone. It could only have opened a copy of the window you were
already looking at; the tab strip's + is the control that does what that icon depicted.

Two things about this repository, said here rather than left to be found

  • You cannot rebuild index.html from this clone. Its sources are not here. You can
    read it — it is one plain document — and check its hash against the line below. The
    daemon is different: bridge/ is its source, every line of it, and it is the half
    that touches your machine.
  • The publisher's file list went from everything except a denylist to exactly these
    paths
    . A denylist fails open: anything not named is public by default, so every new
    folder was published until someone remembered to exclude it. A folder added tomorrow
    is private until it is named.

Also fixed

  • make-app.sh read the version through ${BASH_SOURCE[0]} under a #!/bin/zsh
    shebang. zsh leaves that empty, so the version came from whatever directory you were
    standing in — it looked right only because everyone ran it from bridge/.
  • The model's own tool list told it browse{newWindow:true} opens "a SEPARATE browser
    window… use several to research side-by-side", and that open_panel reached 27 panels.
    There are 20, and there is one browser window.
  • The publisher's secret scan aborted with GITLEAKS_CFG[@]: unbound variable the first
    time it ran without its config in staging — bash 3.2 under set -u. It died on the
    safety gate, skipping the two checks after it.

sha256  e04cf62990f65679d25a5b5dd5133a33c9e2fa9cc4de1a134abb5b558b666557

shasum -a 256 index.html must print that line. 923 tests pass upstream.