Commit Graph
126 Commits
Author SHA1 Message Date
ZacharyZhang-NYandClaude Opus 5.5 c5c35f90fc Files · Find and look: preview, recent files, search, duplicates and archives
FilePreview shows a file large: its picture in the host's shape, the first
lines of its text, or its kind's icon, over its name, kind, size and
change; the gallery opens it on Space as a quick look. RecentFiles lists
files newest first under a header a day, a list a day. FileSearch sits
over a field the host owns and lists what the host found with its folder.
DuplicateFinder marks copies to remove and keeps the last of each group,
its mark shut, with the bytes the marks free beside Remove. ArchiveViewer
draws an archive's entries as a tree with sizes and savings, from paths
gathered by the folder builder the file tree now shares. A checkbox's
label wraps inside its box instead of running past it. Favorites and the
hex viewer point to documents and debug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 20:42:06 -04:00
ZacharyZhang-NYandClaude Opus 5.5 78fc3f90c0 Files: a narrow listing keeps its names; a column starts fresh for a new folder
The directory listing's size and date columns are fixed, so at 280px the
name had no room and rows showed no names. The heading and rows now sit
in a sideways scroll box whose child keeps the least width: the name's
least, the fixed columns and each row's icon, gaps and padding. A column
of the explorer was keyed by its depth, so a new folder there inherited
the old list's cursor; columns and rows are keyed by their folder. The
explorer asserts each folder on its path is a folder in its parent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 20:22:12 -04:00
ZacharyZhang-NYandClaude Opus 5.5 f694f0d413 Files · Explorer: a folder as a list, tiles or columns, with one path and one order
FileExplorer shows the folder at the end of a path three ways: the
directory listing, a grid of tiles, or a column per folder along the
path with the next folder lit. Its name, its count and a switch of views
sit above one path bar that climbs. A folder opens in place; a file goes
to the host, which lists each folder it goes to. A pick in an earlier
column closes the columns past it, and a new deepest column scrolls into
view. The directory listing takes its pick from its owner and reports
it, so the pick carries across views; its path bar and its first order
are shared. The gallery walks a small file system and shows the tree,
the context menu, renaming in place and a drop zone in use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 20:07:33 -04:00
ZacharyZhang-NYandClaude Opus 5.5 906e6c8ac1 Files: a tile's name keeps its ends; the ellipses share one line cutter
gpui's line_clamp wraps once and lays the rest of a long name on the
second line, which a centered tile then clipped at both ends. A tile's
name is now one line, cut in the middle so the front and the extension
stay. MiddleEllipsis draws like Ellipsis: in the text style around it,
sized by its text, so a short name centers; the two share one cutter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:51:43 -04:00
ZacharyZhang-NYandClaude Opus 5.5 ebad5328ed Files · Items: one icon map, file icon, file row and file grid
The crate had two maps from a file's name to its icon, in chat and in the
file tree, and they disagreed. One map now lives in primitives, over the
Lucide file-* icons, and chat, agent, the file tree and the directory
listing use it. FileIcon draws it for a file or a folder. FileItem is a
file's row, a ListItem with its size and when it changed. FileList is the
directory listing. FileGrid lays tiles in the order given, with a cursor
seeded from the owner's pick: arrows by tile and by row, Home, End, Enter
and a double press to open. The count of what fits a width has one home,
layout's columns_for, and fit builds on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:40:10 -04:00
ZacharyZhang-NYandClaude Opus 5.5 9872adc5e9 Forms: an option list stays inside the window; media ratios are checked in one place
The floating list under a Select, Combobox or MultiSelect was at least its
trigger's width with no ceiling, so a long choice ran it past the window
and its rows never ellipsized. It now stops at the window's width less the
window margin on each side, so gpui snaps it inside. The camera preview
and the model viewer check their ratio through primitives::checked_ratio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:17:52 -04:00
ZacharyZhang-NYandClaude Opus 5.5 7f1cfe8c3d Media · Capture and devices: recorder, camera, mic meter, device choice and 3D model viewer
ScreenRecorderControls holds a recording in one pill: Record, then a live
dot and the time it has run beside pause or resume and stop, with mic and
camera toggles. CameraPreview shows host frames in the camera's shape, or
the camera off. MicLevelMeter lights segments up to the level, amber and
red near the top, with tones shared from data_display. DeviceSelector
picks a microphone, camera or speaker through Select, which may now be
empty while shut. ModelViewer shows the host's frame for an orbit that a
drag, the arrows, Command-scroll, + and - and a reset move; the orbit is
seeded from the host so fast drags add up. The gallery draws a stone
torus per orbit and frees each replaced frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:05:23 -04:00
ZacharyZhang-NYandClaude Opus 5.5 235f059c8e Lists: a selectable list's cursor starts on the owner's pick; the waveform's fit is tested
SelectableList keeps the owner's last selection and the one it last
sent. A selection the owner makes, on first paint or later, moves the
cursor to its first row; the echo of the list's own pick leaves the
cursor where the pick put it. The playlist's keys start from the song
under way. The waveform's bar count and inset move into `fit`, tested
beside `resample`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:44:38 -04:00
ZacharyZhang-NYandClaude Opus 5.5 4b86283d69 Media · Audio and controls: player, waveform, spectrum, volume, speed, transport and playlist
AudioPlayer sets a song's cover, title and artist over a scrubber with
the time played and left, the transport and the volume. AudioWaveform
draws peaks gathered to the bars that fit, dark as far as it has played,
and seeks by press, drag and keys, with the time tip the scrubber shares.
AudioSpectrum shows levels by pitch. VolumeControl mutes from its speaker,
and moving its slider while muted unmutes. PlaybackSpeedControl picks from
a menu. MediaControls holds shuffle, back, play, forward and repeat.
Playlist builds on SelectableList: the song under way is lit with moving
bars, and Enter or a double press plays another.

The video player's bar now rests while the stage itself holds focus, a
key it takes wakes the bar, and a press on a resting bar only wakes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:32:45 -04:00
ZacharyZhang-NYandClaude Opus 5.5 fcb1b2d9df Media: the player's bar fades by elapsed time, so its scrubber and buttons keep their state
The fade restarted an animation id at each rest and wake, and gpui hands
that id to every descendant: the scrubber's drag, hover and focus handle
and the buttons' focus were rebuilt under it. The bar's opacity now reads
the time since the last change through motion::since_change. The stage
tracks focus even without key handlers, so a focused bar button keeps
the bar up. The player's tests move to their own file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:14:06 -04:00
ZacharyZhang-NYandClaude Opus 5.5 fbf99ed4f7 Media: the caption outlasts the bar; one Space per press; narrow boxes hold
Only the bar fades now, so the caption stays while the controls rest, and
the caption chip can shrink, so a long line wraps inside a narrow player.
A focused media button keeps Space to itself, since gpui presses it on
the release. The player and the strip let Command and Control letters
pass. The scrubber's tip splits the free width by the pointer's share and
stays over the track at both ends. An inline edit's label gives way with
an ellipsis beside fixed parts.

The player is a Tab stop only when a key does something, logs its
captions, keys its fade by its own id, and logs a failed wake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 17:52:27 -04:00
ZacharyZhang-NYandClaude Opus 5.5 f7f20b5146 Reviews: T26b passes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 16:46:40 -04:00
ZacharyZhang-NYandClaude Opus 5.5 cb28c0e305 Media: a shaped corner follows the pointer up and down; the fitted crop is told once
With an aspect, a corner drag sizes the crop by whichever side the pointer
moved further, so a drag straight up or down resizes it too. The upload
tells the host the fitted crop once per file, whether the host keeps it or
not; a host that dropped it had set off a loop of reports. The annotator's
Escape stops only when it lets a chosen mark go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 16:38:22 -04:00
ZacharyZhang-NYandClaude Opus 5.5 0cf1d3679c Reviews: T26a passes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:58:02 -04:00
ZacharyZhang-NYandClaude Opus 5.5 12f0baab15 Media: the viewer's picture moves; a viewer with no picture takes no Tab
The stage's picture carries an id, so gpui keeps its frame and asks for
the next: an animated picture plays, turned or not. A viewer whose picture
has not loaded or cannot open is no Tab stop. AGENTS.md: img() moves an
animated picture's frames only with an id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:51:03 -04:00
ZacharyZhang-NYandClaude Opus 5.5 f8a51a5352 T26a Media: images
A new chapter, src/media. ImageViewer fits a picture to its stage and
zooms by the document steps, by keys, buttons and Cmd-scroll about the
pointer; a drag through gpui's drag, a scroll or the arrows pan it once it
overhangs; R turns it a quarter at a time. gpui paints pictures without a
transform, so media::turn turns the decoded frames off the main thread,
an asset keyed by the picture and the turn; `image` 0.25, which gpui
already decodes with, is now a dependency. ImageThumbnail shows a picture
in its own shape with a corner label and a ring when chosen, and is a Tab
stop only with a handler. Lightbox / Gallery Viewer points to
overlays::Lightbox, which the gallery opens from the thumbnails.

T26 splits into T26a–e. AGENTS.md: the drag rule says drags that pan,
turn or slide go through gpui's drag; pictures turn by their pixels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:34:45 -04:00
ZacharyZhang-NYandClaude Opus 5.5 4678773383 Reviews: T25f passes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:22:31 -04:00
ZacharyZhang-NYandClaude Opus 5.5 54e0384582 Generative: the embedding turns by drag past its edge; version diffs are tested
The turned embedding turns through gpui's drag, marked with its view, so a
drag keeps turning past the plot's edge. What a chosen version is set
against, and its heading, move into versions::compared, with a test. A
hidden legend entry dims its key and not its ring, and an embedding refuses
a group named twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:17:45 -04:00
ZacharyZhang-NYandClaude Opus 5.5 d196aa1e26 Reviews: T25e passes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 14:02:23 -04:00
ZacharyZhang-NYandClaude Opus 5.5 85f13b5455 Description rows wrap; the fine-tune share is tested
A DescriptionList row drops its value under its label once the value has
less than half a label's width beside it, so a 280px model card no longer
breaks its facts mid-word. FineTuneJobCard's bar share and its epoch line
move into tuning::progress, with a test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 13:57:14 -04:00
ZacharyZhang-NY 092d125eda Reviews: T25d passes
Round 2 of the Claude reviewer found no defects.
2026-09-26 13:37:25 -04:00
ZacharyZhang-NY cb1b1ca90a Generative: the video strip scrolls and reveals; tags wrap in their row
The timeline's scroll box is the flex row itself, so its reach is its
shots; a focused shot brings itself whole into view through
layout::bring_into_view, which table headers now share; Extend sits
with the caption under the strip. A voice's tags cap at the row's
width and wrap inside it.
2026-09-26 13:32:44 -04:00
ZacharyZhang-NY 6bfd53baee Reviews: T25c passes
Round 2 of the Claude reviewer found no defects.
2026-09-26 13:09:53 -04:00
ZacharyZhang-NY d5129675c9 Generative: a mask shown to read takes no pen; strokes fail loud
InpaintCanvas is a Tab stop with the focus ring only when on_brush
serves its keys, and takes the pen, the crosshair and the ring only
with on_stroke. new() asserts each stroke's radius within REACH and
its points on the picture. The settled strokes' cells stay cached, so
a drag paints only the stroke under the pen over a copy. The canvas
keeps square corners, so the wash fits the picture. The gallery drags
with moves.
2026-09-26 13:05:34 -04:00
ZacharyZhang-NY 8f20af49c3 Reviews: T25b passes
Round 2 of the Claude reviewer found no defects.
2026-09-26 12:47:12 -04:00
ZacharyZhang-NY 2a992f0399 Generative: a picture with nothing to open takes no focus
A done result tracks its focus only beside its press, so a grid with
no open handler leaves focus where it was. A decided comparison drops
its empty verdict row, so no gap is left under the sides.
2026-09-26 12:44:18 -04:00
ZacharyZhang-NY 406fe4cf0e Reviews: T25a passes
Round 2 of the Claude reviewer found no defects.
2026-09-26 12:26:37 -04:00
ZacharyZhang-NY 8be1e36c53 Forms: Cmd-Enter submits from any control in a form
Form sets the ElyForm key context and binds secondary-enter to Submit
under it, so a focused tile, chip or button submits too. The prompt
enhancer's wash trims anything but letters and digits from its runs,
its spacing sits on its parts so nothing gaps at rest, and its tests
check that the field takes focus back.
2026-09-26 12:24:05 -04:00
ZacharyZhang-NY 59b4673240 T25a Generative: prompt and settings
PromptEnhancer offers a fuller prompt with the words it adds washed,
split at punctuation; Use this takes it into the field, Keep mine
lets it go. StylePresetPicker and AspectRatioPicker are rows of Tab
stops, the chosen one in accent; a ratio chip draws its shape.
SeedInput keeps digits up to u32::MAX and rolls one with a die.
NegativePromptInput and ImageGenerationPanel point to forms::TagInput
and forms::Form. theme.generative() holds the chapter's sizes. The
gallery's preset pictures are the atrium photo in five styles.
2026-09-26 12:13:17 -04:00
ZacharyZhang-NY b651c05b1e Reviews: T24f passes
Round 2 of the Claude reviewer found no defects.
2026-09-26 12:06:06 -04:00
ZacharyZhang-NY 1f1166fef0 Tables: focused headers scroll into view; long tables scroll sideways
A sortable header is a tracked Tab stop; once focused it sets its
table's sideways offset whole from its painted bounds and asks one
frame. The virtualized branch scrolls sideways too, and its list
keeps a plain wheel to its rows. layout::on_axis keeps a scroll box's
wheel to its axes; tables, code blocks, the thumbnail strip and the
gallery's page use it. Footer figures move to tables/foot.rs; the
profiler's ruler takes theme.chart().label. HumanInputRequest's
answered state gets a test.
2026-09-26 12:00:27 -04:00
ZacharyZhang-NY 96c4fe01a6 Reviews: T24e passes
Round 2 of the Claude reviewer found no defects.
2026-09-26 11:12:29 -04:00
ZacharyZhang-NY bdb5a1093f Agent: fail loud on cpu past full; group tools in grouped()
SandboxStatus::cpu asserts its share lies in 0..=1 and hands it to
Meter unclamped. ToolRegistry gathers kept tools by source through
grouped(), tested for first-seen order and repeated sources.
2026-09-26 11:09:50 -04:00
ZacharyZhang-NY 85781635ff T24d round 3 fix, after the cap
- BrowserPreview marks the shown frame with accent; the focus color stays
  the focus ring's
- BrowserPreview and ComputerUseViewer take the host's ratio, 16:10 unless
  set, so frames keep their shape and a pointer's share lands on the picture;
  test a_screen_takes_its_pictures_shape
- TASKS: the review moves to a Claude Fable 5.1 max session after codex ran
  out of quota; round 3 fixed after the cap, no fourth review
- AGENTS: focus and choice colors part; host pictures keep their shape
2026-09-26 10:54:39 -04:00
ZacharyZhang-NY c013747b7c T24d round 2 fix
- BrowserPreview keeps a ScrollHandle for its strip and a tracked focus
  handle per thumbnail; the focused thumbnail scrolls into view once, through
  forms::options::reveal and the canvas now shared as revealer
- Popup draws its reveal through the same revealer
- test tab_brings_a_hidden_frame_into_view
2026-09-26 09:16:01 -04:00
ZacharyZhang-NY e99a86bed5 T24d round 1 fix
- BrowserPreview's frame strip scrolls sideways, so every frame stays in
  reach in a narrow card
- ArtifactPanel's header wraps: the title keeps label_width, the controls
  ride in one group that wraps inside the box
- tests: a_narrow_strip_scrolls_to_its_last_frame,
  a_narrow_panel_wraps_its_header
- AGENTS: everything works at 280px
2026-09-26 09:07:14 -04:00
ZacharyZhang-NY dbda2fd8c2 Reviews: T24c passes 2026-09-26 08:55:21 -04:00
ZacharyZhang-NY 58a5784124 T24c round 1 fix
- FileChangeCard's header wraps: the path keeps label_width, counts and
  verdict drop below as one group; MultiFileDiffReview's header wraps its
  counts and its all-buttons inside the box, parted by justify_between
- git::DiffViewer's fold rows are Tab stops with a focus ring when the
  owner opens folds; every row keeps a transparent border so heights match;
  an inert fold no longer shows a pointer
- tests: a_narrow_review_wraps_its_rows_inside_its_box,
  git::a_fold_opens_from_the_keyboard; the gallery adds a 280px review
- AGENTS: taffy drops gaps beside an auto margin; wrapping headers
2026-09-26 08:52:38 -04:00
ZacharyZhang-NY 882280cb25 Reviews: T24b passes 2026-09-26 08:34:31 -04:00
ZacharyZhang-NY fab0131168 T24b round 1 fix
- AgentProgress splits its bar only for two steps or more; a task of one
  step draws a plain bar
- test a_task_of_one_step_draws_before_and_after renders 0 of 1 and 1 of 1
2026-09-26 08:31:32 -04:00
ZacharyZhang-NY aaf212c53c Reviews: T24a passes 2026-09-26 08:21:23 -04:00
ZacharyZhang-NY f04bc081eb T24a round 2 fix
- a dialog's body scroll box holds one inner column, so the body keeps
  its height and scrolls instead of shrinking to the capped card
- test a_tall_dialog_body_keeps_its_height_and_scrolls: 2000px stays
  2000px and a 300px wheel moves it 300px
2026-09-26 08:17:18 -04:00
ZacharyZhang-NY a47d0b058b T24a round 1 fix
- overlays::Dialog caps its card at the window, a title bar's height clear
  at each end, and scrolls its body while heading and actions stay; the
  fullscreen body scrolls too; test a_tall_dialog_keeps_its_actions_in_the_window
- ToolCallCard's tool name gives way with an Ellipsis, so time and chevron
  stay in a narrow column; the gallery shows one at 280px
- the Agent script shuts the card it opened, so each theme's shot opens it
- AGENTS: dialogs fit the window
2026-09-26 08:09:46 -04:00
ZacharyZhang-NY 3d3ceee79d Reviews: T23e passes; T24 splits into six in PRD order 2026-09-26 07:56:18 -04:00
ZacharyZhang-NY 5b15a324ae Reviews: T23d passes 2026-09-26 07:46:11 -04:00
ZacharyZhang-NY e46974f055 T23d round 1 fix
- the conversation list reads the zone through format::system_zone, which
  fails loud; the gallery expects the system zone
- Combobox opens with its cursor on its value, MultiSelect on the first
  row ticked; tests for all three lists open r25 of thirty in view
- AGENTS: the zone rule; lists open on their choice
2026-09-26 07:42:45 -04:00
ZacharyZhang-NY 83e2cdeaa2 Reviews: T23c passes 2026-09-26 07:15:16 -04:00
ZacharyZhang-NY 1a00e19591 T23c round 2 fix
- a trigger opens only its word, so a path keeps its slashes in the query
- suggestions reveal the cursor once the list has its bounds: Popup takes a
  row to reveal, and a canvas inside the list asks for it and one more frame
2026-09-26 07:10:53 -04:00
ZacharyZhang-NY 4fafba4b20 T23c round 1 fix
- suggestions: arrows step past disabled rows and scroll the cursor into view;
  the cursor starts on an enabled row; Enter refuses a disabled one
- active_trigger takes the query's word test: one word for mentions, any
  non-space for the composer, so a file name keeps its dot
- DragDropOverlay takes the drop itself, which gives it the hitbox gpui needs
  to style a drag-over
- ParameterPanel shows the places of the step, value and both ends
- gallery: the prompt menu fills the draft; Reset restores the system prompt
- AGENTS: drag-over styles need a hitbox; debug_bounds never clear
2026-09-26 06:59:37 -04:00
ZacharyZhang-NY b2ce2df428 T23c: AI chat, input
- PromptInput: attachments and context above the field, the owner's tools and
  send below; Enter sends, Shift-Enter breaks the line; / offers commands and
  @ offers context over forms::Suggestions; files dropped on it attach behind a
  drop veil
- AttachmentButton, AttachmentChip with thumbnails and uploads, ContextChips
- VoiceInputButton and VoiceWaveform with a red dot and the time
- ParameterPanel, SystemPromptEditor, TokenCounter, CostEstimator
- forms: a Newline action on Shift-Enter keeps one-line fields to one line;
  replace_trigger moves beside Suggestions; choose and dropped shared
- gallery: composer, pickers and tuning
2026-09-26 06:29:20 -04:00