feat: verb-first navigation - #21
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
Range selection already enforced the group rule; toggle did not, which only stayed invisible while a queue held one file type. convertGroup gains an archive branch so a .cbz cannot batch with a .docx. v1 sessions migrate their files into the tab shape rather than being discarded. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
Rail becomes the verb; the queue belongs to what you are doing and can hold several convert groups at once, with a header per group and the options panel scoped to the selected one. Drops the OperationSwitcher (the rail names the operation now) for a scope chip that says what Run will act on. Adds the Tools grid and its per-card workspaces. shared/catalog.ts is gone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
Reusing convert/resize/upscale made Split, Burst and Extract read as the same action at a glance. Unpack and pack now differ by arrow direction. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
…t files Self-testing the real UI with files in it found three things: - ctrl+click on a row from another group did NOTHING. App.tsx still swallowed the click with the old guard, contradicting the reducer (which moves the selection) and the approved design. The reducer owns the rule; the guard is gone. - The scope chip named the file KIND, so a pdf plus a txt read as '2 PDFs' when it runs as one document batch. It now names the convert group. - The Run button said 'Convert 2 files', which in a mixed queue hides which two. It now says 'Convert 2 images'. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
Owner feedback: - Tools always opens its grid. Landing back inside the last card hid every other tool. - The scope banner is gone, and options no longer appear at all until files are selected. Offering PNG/JPG targets with an empty queue invited a choice that could not be acted on. - Archive to PDF, PDF to CBZ and archive repack are Converts, not Tools: they turn a file into another file, which is what people go to Convert for. The Archives section and the Extract card are gone from Tools. - Both directions now exist: a PDF offers comic containers, an archive offers PDF, and either still offers its own family. - The window holds up at its 900x580 minimum: the queue was squeezed until filenames truncated to one letter, and the drop zone kept 212px it did not need once files existed. Routing now depends on the TARGET as well as the source, and targets are the intersection across the selection so a pdf+docx pair never offers CBZ. The page-render quality is pageQuality, not quality: one option bag can now reach either the convert tool (where quality is a preset STRING) or the archive tool, and Number of 'balanced' is NaN. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
Maxaubert
force-pushed
the
feat/20-verb-first-nav
branch
from
August 31, 2026 13:56
0e8ee9c to
e4799af
Compare
Converting a PDF to CBZ showed two Target format grids, two Resolution sliders and two Quality controls: the panel was a flat list of `tool === x &&` lines, and two of them lost their guard in a reformat, so the Convert tab rendered its own options AND the archive tool's. Replaced the list with a single function that returns one panel, so a missing guard cannot duplicate anything again. Audited all 26 combinations of tab, file kind and engine-changing target in the running app; every one renders one of each section. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
Filesmith carried its own viewer: a second BrowserWindow with image, video, audio, PDF and Markdown renderers, a media transport bar and an audio visualiser, plus the IPC to keep its file list in sync with the queue. That is a second app living inside this one, for a job the desktop already does. Double-click and the context menu now hand the file to whatever the OS uses for it. Removes previewWindow.ts, PreviewWindow.tsx, MediaBar.tsx, AudioVisualizer.tsx, lib/markdown.ts, the PreviewItem/PreviewPayload types, six preload APIs and the file:bytes / file:text handlers that existed only to feed it. About 1,000 lines gone. The fsmedia:// protocol stays: generated-image thumbnails still use it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
Every workspace spent half its width on files the user had already finished with, and results were scattered across seven screens. The queue is now one column of the files you are working on, and everything produced lands in a Completed tab pinned to the bottom of the rail, newest first, each row saying which verb made it. Completed is a view rather than a verb, so it is not in TABS: it takes no dropped files, has no options panel, and does not move when the rail is reordered. Also sets the PDF page-render quality default to 100 as asked. Measured on a 184-page comic: at 150 DPI that is 1471 KB/page (264 MB), against 476 KB at q92 and 270 KB at q85. Not a bug, just what quality 100 costs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB
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 #20.
The rail names what you want to do, not what you happen to have. One navigation axis instead of two.
What changed
The two-column INPUT / OUTPUT queue is unchanged: same columns, same result rows, same re-run behaviour. A group header appears only when a queue actually holds more than one group, so the everyday single-kind batch looks exactly as it always has.
Tools is the one two-level tab: a grid of one-off verbs grouped by what they act on (PDF, Archives), each opening an ordinary workspace with a back control.
Two corrections made while implementing
The grouping axis is the convert group, not the raw file kind.
familyFormatsalready unions pdf + document + text into one family, so a.pdf,.docxand.txtbatch together. Grouping by kind would have split them into three and broken a batch that works today. Convert therefore also accepts PDFs, which my first draft wrongly excluded.The tab-to-tool mapping is not 1:1. Repacking a
.cbzon the Convert tab is thearchiveengine with oprepack, not theconverttool. AddedengineFor(tab, group, card)to resolve it per group.The rule that makes it work
A selection may never span two convert groups, because one options panel can only describe one target set. Most of this already existed: range selection already restricted itself to the anchor's group, and
addItemsalready auto-selected only the first group. The one real gap was ctrl+clicktoggle, which appended across groups; it was invisible only because a queue used to hold a single category.convertGroupalso gained anarchivebranch, without which a.cbzbatched with a.docx.Session migration
session.jsongoes to v2. A v1 blob is migrated, not discarded: each category queue moves to the tab its remembered operation names, merging duplicates. Options are dropped, because they were keyed by an axis that stops existing and re-deriving them per group would guess wrong more often than it would help. Files survive an upgrade; format settings reset once.Deleted
src/shared/catalog.ts,OperationSwitcher.tsx, and the two tests that only covered the catalog (replaced bytabs.test.tsandtabs-registry.test.ts, which still assert every navigation route resolves to a real engine module).Verification
Design:
docs/superpowers/specs/2026-08-31-verb-first-navigation-design.mdPlan:
docs/superpowers/plans/2026-08-31-verb-first-navigation.mdMockups:
docs/mockups/verb-first/index.html(variant A)🤖 Generated with Claude Code
https://claude.ai/code/session_01MSq6HRwmaRKAv1t2hrdkJB