aboutsummaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)AuthorFilesLines
10 hourscompanion: shoved's reference lives in refs/, not candidates/Danilo M.1-3/+3
candidates/ held rerolls to choose between and is cleared once a choice is made; the seed-7 attempt dress/shoved is edited from is a reference, so it moves to refs/ with the official art. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 hoursagents: llama-server's router unloads with POST /models/unloadDanilo M.1-1/+4
The counterpart of /models/load, measured: the same body, answers {"success":true}, and the next request loads the model again. sd-webui now calls it before starting sd-server, because a resident Gemma left Pony 1.1 GB of 12 GB and its first step failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 hourscompanion: the dress set, a shoved frame, several references per frameDanilo M.4-26/+61
The dress frames are made. What the tries taught is in frames.txt beside each line: klein turns the blindfold into an eye mask under strong expressions, so those take it off (BARE) and the rest name it as one solid band (EYES); standing "shoved" read as walking in four seeds, so it is airborne, edited from the seed-7 attempt kept in candidates/; a back view fits "watch", her watching the screen while the user types; klein would neither draw the game's Virtuous Treaty nor move a sword, nor turn her three-quarters, so muse takes only the arms of her official art. gen-frames now takes several references per frame (a + b): the first is edited, the rest are images the prompt points at. The leotard set loses the blindfold too. shoved gets a frame of its own instead of mad: in the spec's table and the plan's Mood.js and its test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
12 hourscompanion: frames.txt, gen-frames and prep-framesDanilo M.3-0/+255
The frames are a list now, not a session in the web UI: frames.txt holds one line per frame (output, the image klein edits, the prompt, with shared sentences as variables), and gen-frames makes the missing ones, or the ones named, through the running sd-server's job API (/sdcpp/v1/img_gen, polled at /sdcpp/v1/jobs/<id>). sd-cli would reload the model for every frame. Adding or changing a frame is an edit and a rerun; --seed rerolls one. Then prep-frames cuts each out of its white background at one common scale. Checked on dress/smile: about 2 minutes a frame on klein, pose and outfit kept. The art stays outside the repo, in ~/.local/share/keystone/companion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
12 hoursdocs: companion implementation planDanilo M.1-0/+1373
Eleven tasks: the Hyprland events first, since the spec's open checks gate the QML that depends on them; the shared balloon check; Mood.js and Lines.js with node checks; prep-frames; the assistant's replied signal; Sprite and Companion; notes; then the hand checks and the frame list for the user. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
12 hoursdocs: companion: standing rest poseDanilo M.1-5/+12
Lying down is what boredom ends in, so a sitting rest pose made it no change. The standing base is a klein edit of the sitting one, which stays as its source, and the smile and wave made from the sitting base are redone from the standing one so every frame descends from a single reference. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
13 hoursdocs: companion: a leotard set of every frameDanilo M.1-14/+23
The self-destruct leaves her in the leotard for 60 s. With one leotard frame she would freeze for that long while reactions played only as lines; a full second set keeps every state animated. Each leotard frame is a klein edit of its own dress frame, so the pose carries over, and a missing frame falls back within its outfit, never to the other one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
13 hoursdocs: companion designDanilo M.1-0/+215
A chibi 2B in the bottom-right corner of the focused monitor, part of desktop/ so she reads the assistant's state directly. The spec records what was measured while making the art (img2img moves faces, not limbs; klein moves limbs when every kept detail is named), the sd.cpp SDXL diffusers bug that forced the single-file Pony checkpoint, and the three Hyprland behaviours still to test before code depends on them. The art stays out of the repo: the character is Square Enix's and the repo is GPLv2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
15 hoursai: Restart for the desktop assistant and local chatDanilo M.4-12/+42
A Restart button sits before Stop on a running app that has a restart control. The assistant uses assistant.sh restart. llamachat has none, and its --quit answers before the app has exited, so a --daemon sent straight after finds an instance still running and does nothing: the restart quits, waits for --ping to fail (5s at most), then starts it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
15 hoursassistant: Ctrl+N for a new chat, Ctrl+H for the history panelDanilo M.2-1/+12
Handled on the card, where Escape already is: keys reach a focused item, and every field in the card bubbles unhandled keys up to it. Ctrl+N does what New does and is likewise ignored while disconnected; Ctrl+H toggles the panel the way the History button does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
27 hoursreload: turn off incremental QML garbage collectionDanilo M.1-0/+6
After a 33-minute suspend the desktop shell sat at ~45% of a core: its main thread ran flat out for about a second every two seconds, in step with the Perf 2s timer. Stack samples were almost all QV4 GC (GCStateMachine::transition, MarkStack::drain) entered from allocData via tryForceGCCompletion, under the regex loop in Perf.vram(), a 177-line parse that should take microseconds. The main thread also posted ~1000 events a second to its own eventfd, against a few dozen in the other shells. Reading: Qt 6.11's incremental collector, the default since 6.8, never completed a cycle after resume, so every allocation forced a full mark. QV4_GC_TIMELIMIT=0 is Qt's documented switch back to non-incremental collection. With it, after a 31-minute suspend the shell stayed at 0.3% and ~37 wakeups a second. The live autostart.lua sets it too; keep the two in step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
30 hoursassistant: notify when a reply ends while the card is closedDanilo M.2-0/+26
A reply streams into the canvas state while the card is closed, but nothing said when it was done, so working elsewhere meant checking back. Now a finished or failed turn sends a notification whose Open action brings the card back on that conversation. A stopped reply does not notify: stopping it was the user's own act. notify-send -A blocks until the notification is acted on or dismissed and prints the picked key, so one Process carries it. A newer reply restarts that Process and its stack tag replaces the balloon, which drops the older wait: only the latest reply's Open works. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
30 hoursvm: right-align unused image sizesDanilo M.1-5/+17
The name and size were one string, so sizes started wherever the name ended and a column of them could not be scanned. The size is now its own right-anchored Text in the main text colour, and a long name elides in the middle instead of pushing it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
30 hoursvm: update, open and prune for docker containersDanilo M.3-14/+191
Update runs `docker compose -p <project> -f <files> up -d --pull always` with the files read from the com.docker.compose.project.config_files label, so only stacks compose itself made get the button: a plain `docker run` container has no recipe to recreate it from, and the supabase CLI labels the project and nothing else. It has its own Process because a pull runs for minutes and must not be clobbered by a start or stop meanwhile. Published TCP ports become localhost:<port> buttons opened by the default browser. Docker cannot say which port is a web UI, so every published one gets a button and a port ending in 443 is guessed https. Prune images runs `docker image prune -a -f` behind a confirm step, since a re-pull can be gigabytes. The images it would delete are listed under the header from `docker image ls`'s {{.Containers}} count, which docker 29 fills in; images of stopped containers are kept. That count reads 0 for images only used by `--rm` containers, such as the test-build ones, so the list is the warning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
30 hoursagents: QML's JS engine has no Array.prototype.flatMapDanilo M.1-0/+3
Same class as matchAll and fromEntries: a TypeError that only reaches the log. In the docker Update button it threw after the busy flag was set, so the button read "Updating…" forever with no process behind it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 hourstheme: stage a scheme and commit it from the headerDanilo M.4-28/+36
The Theme page applied a scheme on click, so a stray click reinstalled the whole theme, and it was the one settings page without the header's commit point. Clicking now stages the scheme (outlined yellow, "selected"), and Reset / Apply in the header drop or apply it, as the wallpaper page does. The applied notice and any failure moved into the SaveBar, and the sidebar marks the page dirty while a scheme is staged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 hourssettings: a Theme status page for unified-desktop-themeDanilo M.6-5/+285
Shows the live scheme, accent and both wallpapers, the scheme and wallpapers linking to their own pages, then every udt consumer in a software and a hardware list, each with a Re-apply button running `install.sh <name>`, and Re-apply all in the header. The list comes from `install.sh --list`, so a consumer added in unified-desktop-theme shows up here with no edit. One run at a time, and none during a scheme switch. QML's JS engine has no Object.fromEntries either: it threw a TypeError that only reached the log and left the page without its list. Noted in AGENTS.md beside String.matchAll. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
37 hoursvm: show docker containers beside the VMsDanilo M.5-11/+379
Docker.qml mirrors Virsh: the docker CLI, an event stream that runs for the whole session, and `docker stats --no-stream` on the 2s timer only while the page is up. Containers are grouped by compose project, since a stack is a dozen containers that start and stop together; a container outside any project is a group of one. Verbs are start, stop, restart and resume, by container id, so no compose file is needed and nothing removes a container. The event stream is filtered to lifecycle events: health checks emit exec_* events every few seconds per container, which would make the stream a poll. It dies with the daemon, so it is retried every 10s. An inactive Loader keeps its last height and a Column still reserves it, so collapsing one card left an empty box where its detail had been. Both the container and VM detail loaders now hide while inactive; the VM one had the same bug, unseen with a single VM. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 daysisland: hide the media pill while the island is retractedDanilo M.1-2/+6
The pill faded to opacity 0 and slid off-screen with the rest of the island, but its visible stayed true for as long as a player was playing or paused. Its marquee animation is gated on pill.visible, so a title too long to fit kept scrolling off-screen all session, and the island's layer repainted every frame. Measured: the desktop shell sat at 42% of a core while idle (253 CPU-minutes over 10 hours), and 0.3% after. Opacity alone does not stop animations; visible does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 dayssbbuilder: list the default manifests, and keep them on the first editDanilo M.5-6/+37
The helper replaces its default [manifests] table with the file's, so adding one manifest to a file without the table dropped neovim's, and the page showed no rows for the default that was in effect. With no table in the file the page now lists the helper's defaults, and the first add, remove or URL edit writes them all before its own change. Toml.js gains sections(), to tell a missing table from an empty one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 dayssettings: a keyword hit stays out when a row matches tooDanilo M.1-5/+6
Searching "zoom" listed Mail twice: once for the module keyword, which opens the page at the top, and once for the Message zoom row, which scrolls to it and flashes it. The keyword hit looked like a reveal that failed. It now shows only when none of the page's rows match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 daysSwitch: never set checked itself, report the new state insteadDanilo M.13-42/+18
The shared Switch flipped its own checked on click, which replaced the caller's binding with a constant. Every use binds checked, so after a click the switch stopped following its source: Discard on a settings draft reverted the value and left the switch showing the click. Four status rows and the headphones panel each carried a resync workaround for it. toggled now carries the new state and the switch moves only when the caller's binding does. Handlers that read checked as the new value take the argument instead; the workarounds are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 daysdocs: the sbbuilder settings pagesDanilo M.2-0/+35
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 dayssbbuilder: fixes from reviewDanilo M.6-26/+66
Toml: a value followed by anything but a comment was parsed as if the line ended there, so a multi-line string (which opens with an empty one) or `x = "a" junk` read as valid and set() could write a duplicate or mangle it. entries() now skips such lines and set() refuses them with the existing "cannot edit" error. The ponytail comment names the ceilings. Store: a failed put left Save enabled with a stale draft; it now marks the key invalid. An empty manifest URL used to unset, which removed the row being typed in; it now marks the row invalid instead (Setting clears the mark just before set, so the one made inside set stays). Noted that list entries with spaces cannot be entered here. Sbb: refresh() ran an ssh fetch for the desktop page too and let two fetches overlap, or one run during a save. It is split into reloadDesktop() and fetch(false), and fetch() returns while busy. A successful config-get clears a stale VM error, and a missing text reads as empty. The put now writes and records the draft as sent, so typing during the save is not marked saved. SbbVmModule: fields are read-only while busy, a Reload button sits beside the status line, and the manifest URL field says Remove deletes the row. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
3 dayssbbuilder: Desktop and Build VM settings pagesDanilo M.3-0/+326
Under SB Builder in the settings window. The desktop page edits sb-builder's config.toml in place; VM control is a switch because an emptied field means the default domain, not "". The VM page is read-only until the helper answers config-get. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 dayssbbuilder: the two config draftsDanilo M.2-0/+229
The desktop config is a watched local file; the VM one goes through the helper's config-get and config-set over ssh, so the helper validates what lands in root's file. Field text is typed after the key's default, the same check sb-builder makes on load. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
3 daysqtmaildir: Setting and BoolSetting take the draft as a storeDanilo M.2-9/+13
The sb-builder pages need the same fields over another file. The store defaults to Qtm, so the Mail pages are unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
3 dayssbbuilder: a line editor for sb-builder's TOML configsDanilo M.2-0/+247
Same shape as qtmaildir's Ini.js, so a file the user annotated keeps its comments: unset comments a key out, set reactivates it. A value spanning lines throws instead of gaining a duplicate key, which TOML rejects. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
3 daysdocs: plan the sb-builder settings pagesDanilo M.1-0/+1157
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 daysdocs: spec the sb-builder settings pagesDanilo M.1-0/+92
Two pages under SB Builder in the settings window: the GUI's config.toml edited in place, and the helper's config on the VM through new config-get/config-set commands, so the helper keeps validating what is written to it. The sb-builder half is built in that repo. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 daysassistant: count seconds on the running tool chipDanilo M.1-4/+14
A lit chip alone looks frozen on a clone that takes a minute; the running tool now shows the elapsed seconds and resets when it finishes.
5 daysassistant: grey out the mic when the model cannot hearDanilo M.6-15/+37
AssistantModule keeps each router model's input_modalities and exposes hears: the model loading, else the first not unloaded (the daemon's rule), reports audio. Unknown inputs or a router that is down count as yes; the daemon's error covers the rest. The model list is now read on every canvas open, not only when a preferred model is set, so hears is current when the card shows. Checked: the rule against the router's live /models (Gemma resident: on; Qwen resident or loading: off; router down: on). Not yet seen by eye after a desktop shell reload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysassistant: a mic button asks by voiceDanilo M.5-7/+385
Each recording is a pw-record Process of its own, made from a Component like the Do row's runs, so a stopped recording's late exit cannot be read as the next one's. Stopping sets running to false (SIGTERM), which lets pw-record write the WAV header; the audio ask goes out from the process's exit, not from the click. Recording stops itself at 59 s: the daemon refuses over 60 s by file size, and the stop lands a little after the tick. Escape cancels a recording before it does anything else, and closing the card or losing the daemon cancels it too. A pw-record that ends on its own says "recording failed". Checked: a scratch harness saw transcribing, thinking, idle for a 2 s recording; by hand, every case in the spec passed with no pw-record left behind, a desktop shell reload mid-recording included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdocs: spec the assistant canvas micDanilo M.1-0/+90
A mic button records with pw-record and sends the WAV's path as an audio ask; the daemon transcribes it. pw-record writes a right header when stopped by SIGTERM, but one stray kept recording in a trial, so every path out stops it and the checks look for a stray each time. Recording stops at 59 s: the daemon refuses over 60 s by file size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysnotifications: quiet mode silences notification sounds tooDanilo M.3-2/+18
Quiet muted only the Claude and opencode hooks, which play their own sounds and check the flag themselves. With notification sounds it now means no sound at all while the balloons still show, so the balloon player reads status.quiet the way Notify reads status.dnd, without instantiating Status. A per-app quiet list was left out: the mute list already covers an app that should make no sound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysnotifications: write gsettings only when the theme changedDanilo M.2-8/+12
From the final review. Every save ran gsettings set, so saving a timeout on a first run, with no soundTheme in the file, silently reset a system theme set elsewhere to freedesktop; the page now writes it only when the draft's theme differs from the file's, and flags any other mismatch as before. An exit code outside 0-3, a save killed mid-run, now reads as an error rather than a partial success. The player's comment no longer claims the balloon's expiry check, which it does not need. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdesktop: report save results in the SaveBar, not at the page's footDanilo M.16-58/+58
A save's outcome sat at the bottom of the page, out of sight on a long one, while "unsaved changes" was already in the header. SaveBar gains notice, shown once the page is clean, and error, shown in red over the unsaved mark, since a refused or failed write leaves the draft dirty. Wired for notifications, HyprIdle, Sunset, Wallpaper and the four Mail pages, with their longer messages shortened to fit the header. Messages that are not save results stay in their pages: the icon theme's immediate apply, Sunset's location detection, the assistant restart. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdocs: notification soundsDanilo M.2-0/+16
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdesktop: notification sounds on the settings pageDanilo M.2-7/+129
A sound per urgency chosen with the widget file dialog, previewed with pw-play, and the sound theme for apps' sound-name hints. Save writes the theme to gsettings as well, and the page reads gsettings back on every open so a change made elsewhere is shown, with a button to adopt it, rather than overwritten. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysnotifications: play a sound for a new balloonDanilo M.1-0/+34
pw-play, once per new or replaced notification, only when the balloon would show: the drawer, snooze, mute and DND that withhold the balloon silence it too. A restart records the queue without playing it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysnotifications: resolve the sound keys and choose a balloon's soundDanilo M.2-2/+35
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdocs: plan notification soundsDanilo M.1-0/+696
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdocs: notification sound theme mirrors gsettingsDanilo M.1-3/+18
Save sets the system sound theme too, and the page reads it back on every open so a change made elsewhere shows instead of being overwritten. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdocs: spec notification soundsDanilo M.1-0/+123
A sound per urgency in config.json, played by the balloon shell under the same checks that decide the balloon. notifyd resolves the apps' sound-file, sound-name and suppress-sound hints into two published fields, looking names up in a configurable sound theme. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdesktop: tell muted apps from suggestions, explain the limitsDanilo M.1-4/+27
Muted and suggested apps were the same chip in two unlabelled rows. Each row now has a caption; muted chips are red, suggestions dimmed and cut to the eight most recent, newest first. The suggestions were already bounded by the live and history caps. Limits gains a line saying what the two numbers do, like the one under Timeouts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdesktop: notification page follows the file, saves once, keeps nested keysDanilo M.1-8/+19
From the final review. An edit broke the draft's binding to Notify.config and Discard assigned a plain value, so a later change to the file read as unsaved edits; discard and refresh now restore the binding. Save stays disabled while the write runs, since a second click killed the first mid-write. Unknown keys inside timeouts and balloons are merged rather than replaced, as the spec asks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdocs: a symlinked singleton needs a restart, not a forced reloadDanilo M.1-2/+7
Measured: after shared/Notify.qml changed, a reload triggered by editing Balloons.qml left the notifications shell on the old singleton, while a fresh instance read the new config correctly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdesktop: Tab moves between the hand-rolled text fieldsDanilo M.15-0/+27
A bare TextInput defaults activeFocusOnTab to false, unlike the Controls TextField some pages use, so Tab skipped every field built from one: the settings search, Field, the qtmaildir, git, autostart, assistant, OBS, user, VM and network rows, and the calendar editor. Multi-line TextEdits stay out of the chain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdesktop: rebind the notification page's fields after an editDanilo M.1-2/+12
Typing replaces a Field's value binding, so Discard left the typed text showing over the reverted draft, and a rejected timeout kept displaying. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysdocs: the notification settings page and config.jsonDanilo M.3-4/+28
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>