| Age | Commit message (Collapse) | Author | Files | Lines |
|
The focused window's class, from Hyprland's activewindow event, picks a
line from Lines.js keyed app:<class>. The event fires on every title
change too, so she reacts only when the class changes, and a third of
the time, under the existing 30 s line cooldown so alt-tabbing does not
make her chatter. Classes come from the window rules in the live config;
one without lines says nothing. Lines only, no frames of her own yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Twice in one session an edit adding an import to desktop/shell.qml
hot-reloaded into "UdtModule is not a type" and then "SunsetModule is
not a type", both existing appearance modules a fresh process resolved.
Recorded so the next one is met with a restart, not a debugging session.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
SUPER+\ only flipped a property, so every restart of the desktop shell
brought her back. Whether she is shown is now `companion` in Prefs.qml,
set by the IPC and by a switch on a new Settings > Desktop > Companion
page. Prefs gains `ready`, so she waits for the file rather than showing
at the default and then vanishing; the greeting now plays on every
appearance, the one at login included.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Her stages sat at 1, 3 and 5 minutes, and the saver starts at 5, so she
lay down under it. They are now 20, 40 and 70% of wscreensavers'
idleTimeoutMinutes, read live from its config: 1, 2 and 3.5 minutes at
its default.
She never idled at all while No lock was on: it holds an idle inhibitor
and her monitors respected inhibitors. Measured with a throwaway shell,
a 5 s monitor respecting them never fired while one ignoring them did.
They now ignore inhibitors, as the saver does, and presentation and
gaming mode keep her awake by name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Remapping only when the assistant opened left her under rofi and the
keybind reminder, which map on the same Overlay layer later. She now
remaps on Hyprland's openlayer event for any namespace but her own,
restarting the timer so a burst of openings ends with her on top.
The bare remap read as a flicker. Unmapped she now counts as away, so
her figure drops out unseen during the 400 ms and plays its entrance
when she is back: a vanish and a hop in.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The assistant canvas is a full-screen Overlay surface mapped on open,
so it covered her and her think and wave were never seen. She moves to
the Overlay layer and unmaps and maps again when the canvas opens, since
a later surface stacks above an earlier one and Hyprland 0.56.2 has no
layer rule to order them: an `order` key was tried, raised no config
error, and did nothing.
Every key sent her into watching, a shortcut included. The pulse comes
at most once a second, so a lone key is one pulse; she now watches from
the second pulse within 2.5 s. The hypr-theme hook drops modifiers and
chords on its side.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Hyprland 0.56.2 reports a Lua `code:N` bind with key "" and keycode 0
in `hyprctl binds -j`, while the bind itself works, so the reminder
printed "Win + " with nothing after it. Such a bind is now named by its
description, with "?" for one not listed, so a new keycode bind shows
up as a visible gap rather than a blank.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The balloon window is one layer surface for the whole stack and stays
mapped while any balloon is queued, so Hyprland's layer animation only
ever played for the first one; the rest just appeared. Each balloon now
animates its own x in from the side its corner sits against. The window
clips it, so it enters from the stack's edge, 12 px inside the screen's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The balloon arrives almost at once, so 1.2 s of stumbling outlasted the
push. She turns mad beside it after half a second.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The shoved frame held for as long as a balloon stayed, which read as
her stumbling for ten seconds. It now lasts T.shoveHold (1.2 s), then
she is mad beside the balloon until it goes. shovedAt is reset to 0 when
the shove ends and 0 reads as the shove's first instant, so the binding
cannot show mad for a tick before the handler stamps the time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The README records the measurements the code depends on: where typing
and BackSpace come from, why the dodge waits for the pointer, the
IdleMonitor enabled default, and fullscreen 2 against maximised 1.
AGENTS.md gains the QtQuick Sprite trap beside the Controls Button one,
since it took the desktop shell down on restart.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Companion.qml is a Top-layer PanelWindow bottom-right of the focused
monitor, masked to her body so every other click passes through. It
gathers the inputs (Hyprland's custom typing and delete events, the
assistant's state and replied signal, the balloons on her screen,
three IdleMonitors, clicks and a hover), hands a snapshot to Mood.js,
and speaks from Lines.js. Figure.qml crossfades frames, bobs, drops
out of view and back, and plays the self-destruct.
Figure.qml was planned as Sprite.qml, but QtQuick ships a Sprite type
and an explicit import beats the directory's own file: the shell failed
to load with "Cannot assign to non-existent property onSettled".
Maximised windows report fullscreen 1 and most windows here are, so
only 2 hides her. She only feels the pointer once it is on her, so the
dodge waits 0.6 s and a quick click still lands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The desktop companion waves when an answer is ready. The moment already
existed as the done branch that calls notifyDone; it is now a signal
too, so the companion connects to it instead of reading the turn list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Fixed English lines per reaction, terse in the game's register, and the
opening monologue split at its sentences so each fills one bubble.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The spec's priority table as a pure function over a snapshot of her
inputs, with the click burst, the outfit after the self-destruct, the
mock and line cooldowns and the monologue's odds beside it. Pure so the
node check can drive it with a fake clock; Companion.qml will own the
inputs and timers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The desktop companion needs to know when a balloon is showing in her
corner, and the rule lived inline in NotificationBalloon's visible
binding. It moves to the shared library so both shells ask the same
function: drawer, snooze, mute, DND, then expiry.
Shared files do not hot-reload through their links: restart the
notifications and desktop shells after pulling this.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
All 37 frames are made. The generic leotard line kept pose and mood
only where the dress frame showed her eyes; elsewhere klein drew new ones
and lost the mood (mad went sad, yawn laughed), so those name the mood.
It also could not take the blindfold off a face it could not see: through
three prompts, by name and by position, the back view and the sleeping
face kept its band. From leotard/base, which never had one, both are
ordinary pose edits. scorched names where the white shows, below the
waist only, after it painted the bodice white too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
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>
|
|
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.
|
|
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>
|