Commit Graph
34 Commits
Author SHA1 Message Date
pastilhas 90c546c098 §3: re-measure the multi-user premise, and say why it is not mine to fix tonight 2026-08-07 14:43:48 +00:00
pastilhas 6eac14a2b7 close §9: PanelSlot tested, the section is done 2026-08-07 14:41:54 +00:00
pastilhas 7addb8f1e3 note the WorkspaceView tests and the TrafficLights defect in §9 2026-08-07 14:38:19 +00:00
pastilhasandClaude Opus 5 873ccae32a record the defect the useDashboardState tests found
section 9 now carries a concrete instance of its own argument: a test found a bug that
two careful readings of the file had not, in code written three days earlier to prevent
exactly that failure. also records the two bun/testing-library harness facts that cost
more than the fix did, since both present as an unrelated file breaking for no reason.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 14:23:41 +00:00
pastilhas 212903ecd4 correct a stale untested list: two of its four entries already had tests 2026-08-07 14:09:37 +00:00
pastilhasandClaude Opus 5 aef8619c6c put the music library location in the url
/music?path=<rel> replaces the music:cwd channel. Each panel reads the param
itself through useMusicCwd(), so MusicBrowser, MusicDetail and FavoritesView
no longer tell each other where they are, and every drill-in is a <Link>:
library rows, folder rows, album/artist cards, both "up" affordances, the
favorites rows, and the dock's now-playing tile. Track rows stay buttons —
they play, which is a mutation.

A query param rather than a nested route because the location is only one of
the things this screen holds (the lyrics split and the favorites view are the
others), and a splat has to be a route's last segment.

MusicPlayerHost is mounted outside <Routes> and used to write the channel and
then navigate('/music') to make the write visible — the audit's only
navigate-with-a-side-effect. That collapses to one <Link>.

music:resync (a refresh signal) and music:favorites (a view of one panel) stay
channels, deliberately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 12:08:04 +00:00
pastilhasandClaude Opus 5 374140d3a6 put the previewed browser tab in the url
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 11:56:45 +00:00
pastilhasandClaude Opus 5 6c47cbeb74 make the email url the selection instead of a mirror of it
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 11:51:45 +00:00
pastilhas fd923bb9be give the soulseek workspace a url
The section is /soulseek/:section — nav entries are NavLinks, the view panel reads the same
URL instead of being told, and the dashboard's tiles and recent searches are real links (a
recent search now opens that search, not the search screen's front page).

The peer went in `?user=<name>` rather than the /soulseek/users/:name the audit sketched: a
second path segment would need a nested route just to keep the nav highlight, and `?search=`
had already set the convention there. That deletes the `soulseek:user` channel and with it a
`{username, nonce}` request the Users panel consumed-once and cleared — the nonce existed so
asking for the same peer twice counted twice. A link is idempotent, so there is nothing to
consume and nothing to disambiguate.

`soulseek:refresh` stays: it is a signal, which is what channels are for.
2026-08-07 11:45:33 +00:00
pastilhas 00332e275a put the monitor scope in the url
/system-monitor/:scope, the same shape as /photos: route pair, one Navigate guard after the
hooks, scope list as react-router NavLinks, and both panels reading useParams instead of
agreeing over a `monitor:scope` channel. The Dock's isActive is a startsWith, so its
highlight survives the redirect off the bare route.
2026-08-07 11:41:16 +00:00
pastilhas 2502c33804 put the settings section in the url
Five settings pages moved from a `*_SELECTED` global to `/settings/:page/:section`. The
sidebar entry is a react-router `<NavLink>` rather than a button holding the key in its
onClick closure, so a section is linkable, cmd-clickable and gets its active state from the
router; each page renders one `SettingsRoute` guard that canonicalises both the bare route
and a section that does not exist.

Integrations needed more than the shared factory. It builds its own sidebar, and it kept the
Enterprise/Personal tab in a second global — which is why a deep link to a Personal section
could never have worked: the link set the section, the tab stayed on Enterprise, and the
content pane said "Select a section" about a section that existed. The tab is derived from
the section key now.

Also removes the `/settings/resources` menu item (audit M8) and its two locale keys: there
has never been such a route, so it bounced to the catch-all and out to `/`.
2026-08-07 11:38:21 +00:00
pastilhas 98ba61f135 record the sweep commit 2026-08-07 11:26:39 +00:00
pastilhas b419af32de sweep the dead code in section 8
Each item re-verified before deleting; three of the ten entries were stale
and are corrected in place rather than silently fixed.

- WorkspaceLayout's isMobile/mobilePanelId/onMobileBack: none of its ten
  callers set them, so the mobile collapse they fed was permanently off in
  that renderer. WorkspaceView passes the same props to WorkspaceRenderer
  itself, where they are live.
- fixedHeight on AppRegistryEntry, and getFixedHeight with it: no app has
  ever declared one, so it only contributed undefined. The flex-column
  branch it shared with fitContent stays, keyed on fitContent alone.
- getDefaults: getAllDashboardState already folds the defaults row into the
  one payload the client fetches, which is why it never got a caller.
- upsertScreen's terminals/hostTerminals: never read is right, never
  written was not — it inserted them, which is why all 15 rows hold {}.
  The columns are left in place; dropping them needs a db:push, and this
  tree holds another agent's uncommitted schema file.
- SELECTED_DASHBOARD_KEY: H2 (01365cb) replaced it with ?selected= four
  months ago and it has had no reader since.
- ui/sidebar.tsx and the stray ui/hooks/ beside it. use-mobile was not
  orphaned as claimed — the sidebar imported it — and the use-toast in
  there was a near-identical copy of the live one.
- findChildById's unreachable duplicate condition, and the doc comment that
  described the wrong behaviour rather than the code being wrong.

Left deliberately: DragOverlay/LayoutEditor (gated on 5.3, an owner
decision) and the two chat-owned channels, whose docs are fixed here even
though the publishers are not mine to delete.
2026-08-07 11:26:33 +00:00
pastilhasandClaude Opus 5 f2ae10bd36 mark 5.10 resolved
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 11:15:00 +00:00
pastilhasandClaude Opus 5 30fcab2bd3 mark 5.6 resolved, and stop three docs claiming a channel that has no publisher
The todo entry said the file-viewer registration was dead; tracing it confirmed that and turned up the
reason it looked alive — the ephemeral file viewer is a different mounting path entirely. Recorded, with
what was checked in the database before deleting anything.

CLAUDE.md, navigation-audit.md and workspace-panels.md all listed FILE_VIEWER_CHANNEL among the
legitimate refresh/signal channels. It never had a publisher, and no longer exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 11:07:36 +00:00
pastilhasandClaude Opus 5 04ccb05b2c mark the effect-hygiene items resolved, and correct two of them
Two entries in 5.7 were wrong. HostTerminalWrapper was fixed in c92b51c, when
all three wrappers moved onto useTerminalSession — the item had simply not been
re-read since. And useTaskRunner does not abandon a running task: `stop` is sent
from the modal's Stop button, and closing the socket kills the process tree
server-side. Both were written from the hook alone without following the call
into the modal or the executor.

VideoPlayer and the remaining VideoPlayer-shaped case are left alone on purpose,
with the reason written down rather than the item deleted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:57:10 +00:00
pastilhas e2017cbbf2 correct 5.2: the key was never the cause 2026-08-07 10:46:31 +00:00
pastilhas 34b40cb094 mark preserve-sibling-sizes resolved 2026-08-07 10:41:32 +00:00
pastilhas 4ce7839b31 mark the panel-id and registry-key items resolved 2026-08-07 10:38:59 +00:00
pastilhasandClaude Opus 5 df00f6d7a5 tier b has no unblocked work left
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:16:09 +00:00
pastilhasandClaude Opus 5 49b635a489 drop §5.4's default-layout collapse, and say why
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:15:58 +00:00
pastilhasandClaude Opus 5 d546717676 note the unguarded screens are done too
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:10:32 +00:00
pastilhasandClaude Opus 5 99ee9dbb88 record §5.4's first item as landed
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:07:33 +00:00
pastilhas 2c84bb34be say which shells nobody is looking at
The sidecar has always sent `clients` on each session and this list has always dropped it, so a shell
you are typing into and a shell nothing is attached to rendered identically. It is now on the type,
shown as "N attached", and a zero earns the row an orphan badge — the count only helps if you do not
have to read it to notice.

Also records §5.1 and the whole of §1 in the todo, including that the diff-the-layout implementation
§5.1 used to propose is struck and why.
2026-08-07 09:58:04 +00:00
pastilhas fed2badd28 record the close of §5.9 2026-08-07 09:43:30 +00:00
pastilhas b1e0bac1e0 record the first three items of §5.9 2026-08-07 09:36:27 +00:00
pastilhas b1ec1e19a7 record the close of §4 2026-08-07 09:24:23 +00:00
pastilhas 2efd7ffba3 record §5.5 and the close of tier a 2026-08-07 09:19:59 +00:00
pastilhasandClaude Opus 5 d24f3faa5f record §4: the boundary, validate-on-read, and the layout default
Tier A now has only §5.5 left — the resize debounce and the stale cache.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 09:09:22 +00:00
pastilhasandClaude Opus 5 30eef86972 record what landed: A1, A2, the tests, and what tier A has left
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 08:57:13 +00:00
pastilhasandClaude Opus 5 ecc7fb90d8 rank the panel defects against the objective, not against severity
The re-rank the north star deferred, done now that the MVP is built and
running — so it is ranked against what the mechanism turned out to need.

The finding is that most of the list is not on this path. The mechanism is
server-side and a panel is a pointer to it, so a remount, a re-render or a
drag costs a replay, not a session. Section 5.2 and 5.3 are large downgrades;
5.3 was on the critical path when the north star was written and is disarmed
by resolving identity by name.

What is left is small and mostly one defect wearing four hats: a write that
silently does not land. Panel identity lives in the layout jsonb now, so the
swallowed persist catch, the dispatcher's missing else and the two debounce
lost-updates each become a panel that forgets which agent it is — invisibly,
for exactly as long as nobody is looking.

Also corrects two items the MVP made stale, and promotes layout-utils tests:
e588524 put agent identity inside those mutators and shipped them untested.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 08:40:33 +00:00
pastilhasandClaude Opus 5 7c99429872 write down the north star: agents coordinating with each other
docs/agent-coordination.md is the objective the workspace/panel work serves —
several agents on one dashboard handing work to each other instead of routing
every step through the human, with the human authoring the workflow at the top.
Written from the owner's own words during the 2026-08-07 conversation; where a
section records a decision, that decision is his.

It settles the questions that were blocking: sessions may be reaped and resumed
from the durable sessionKey→claudeSessionId map (no heartbeat), the address is
the human-assigned panel name rather than the panel id, roles are prompts rather
than features, and the protocol is turn-boundary-only by construction — which
routes around the mid-output restart failure instead of fixing it.

Cross-referenced from CLAUDE.md, workspace-panels.md and workspace-panel-todo.md
so it is findable from any of them. The todo is still ordered by defect severity
and now says so; the re-rank against the objective is deferred, not forgotten.

Also corrects two items dated 2026-08-08 to the day they were actually found.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 06:58:01 +00:00
pastilhas ce7968ac90 document how the workspace/panel framework works 2026-08-07 04:10:36 +00:00
pastilhasandClaude Opus 5 575b4a5966 add a living todo for the workspace/panel framework
the framework has no tests, no error boundaries and a handful of known
defects that keep resurfacing mid-feature. write them down once, ranked,
so they can be picked off in the context of whatever is being built.

notable: the dashboards PATCH dispatcher silently drops any key family it
has no branch for, and three in use today (tmux, nvim, claude-code, all
from Terminal's statePrefix) match nothing — so that state never persists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 02:58:16 +00:00