| Age | Commit message (Collapse) | Author | Files | Lines |
|
Drafting the code found two holes in the spec. Awaiting build was
limited to the user's own recipes, so an SBo package whose recipe had
caught up but was not yet built (nessus) showed in no section; it now
covers any recipe. And "the newest ChangeLog line decides" would never
call a package new once it had been upgraded after being added; only
Added and Removed lines count now. The prefix rule for kernel suffixes
is dropped as redundant: version order already ranks a suffixed version
newer, which is never behind.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The conky updates card copies nvtable's table, where installed-behind and
repo-behind share a row and are told apart by colour, and it measured
"shipped" as the .info version: gamescope and kitty read as ready to
install while the binary repo still held the old build. The drawer module
sorts each tracked package into one action, from PACKAGES.TXT of the
binary repo rather than the recipe: upgrade here, awaiting build, upstream
newer, app updates. Slackware is compared mirror against installed, not
against slackpkg's local ChangeLog, which `slackpkg update` replaces
without installing anything; new and removed packages come from the
mirror's ChangeLog. NFS reads go through a timed-out child because the
mount is hard.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The drawer keeps its look and takes over: the island's controls panel goes,
since each of its tiles opened a drawer page that already existed, and SUPER
alone opens the drawer instead. The tile grid scrolls inside a three-row box
so new tiles do not eat the notification space. New: a performance page
reusing the island's Perf service, a cliphist clipboard page replacing the
rofi list, and a quiet mode in the status registry that mutes Claude and
opencode sounds through one notify-sound script while their popups stay.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
On screen the spiral alone read as loose: separation keeps the spiral's
gaps, and the previews filled 24 to 30% of the screen. Thirty rounds now
pull every window 15% closer to the centre and push them apart again,
which fills 35 to 55% and makes each preview up to 1.5x larger. Twenty
windows lay out in about 4ms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
layout() seeds windows on a golden-angle spiral, most recent at the centre,
pushes overlapping pairs apart along the axis that costs less screen, and
fits the result with one scale so sizes stay relative. The spec's first
seed, the windows' real positions, was prototyped and dropped: every window
on this desk fills its monitor, so they started in one pile, and pushing a
pile apart made a line that still overlapped after 300 passes and filled
8 to 15% of the screen. The spiral converged in 1 to 55 passes. Comparing
overlaps in raw pixels stacked wide windows into a column, which is why the
axis choice divides by the screen's width and height.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The window-switcher grid becomes a Mission Control scatter: previews keep
their real shape and relative size, seeded from their real positions and
pushed apart, then fitted with one scale. A top-right hot corner on DP-1
opens it after a 250ms glow that warns before it fires, and stays inert
while gaming. shared/Status.qml is not linked into window-switcher because
a second instance would run its own game poll and react to presentation
twice; the corner reads status.gaming directly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
IconImage cannot be recoloured without an effect layer, so the severity
shows as a dot on the icon's corner. A stale public IP is a dash with no
age, as the Errors section already said.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Nine tasks: two spec corrections, Perf.js with its node test, the
pinned IP in Prefs, the Perf service, the panel, the status pill
wiring, an on-screen check against the still-running conky widgets,
docs, and last the removal of those widgets from conky-theme-udt. The
plan's Perf.js was run against its test while planning.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Sub-project 4. An icon in the status pill opens a card grid of CPU,
RAM, temperatures, GPU, disks and network, read from the same /proc,
/sys and hwmon sources conky uses. The icon warns on temperatures,
RAM, disks and a public IP that drifts from a pinned address, since
the VPN depends on the ISP's fixed IP. CPU load is left out of the
icon because spikes would flicker it. The four conky widgets are
removed once the panel is verified beside them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
One JSON envelope on stdout for every calctl command, the event as an
argument rather than stdin, a get command because the editor edits the
series rather than the occurrence clicked, and a pure Cal.js for the
date logic so it is tested under node like the island's other helpers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Ten tasks: protocol corrections to the spec, calctl in two halves with
their CLI tests, the pure Cal.js with its node test, the service, the
editor, the panel, the island wiring, a pass with the user and docs.
Both test suites were run against the plan's own code before committing,
and a read-only list against the live calendars measured 0.11s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Sub-project 3. The clock pill opens a month grid beside the selected
day's agenda, and an editor that writes the vdirsyncer calendars
through a small Python tool, calctl, rather than khal: khal 0.11 has no
JSON output and keeps a cache that is a second view of the same files.
Recurrence stops at a plain FREQ and UNTIL, and the form owns one alarm;
anything richer in an existing event reads as custom and survives an
edit untouched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Edit mode let a right-click and the wheel through to the tile, so a
right-click opened the drawer and scroll changed volume, against the
spec. The drag area now takes both buttons and the wheel.
A scroll up on a level already above the cap, such as a mic set to 120%
elsewhere, snapped it down to the cap. The cap now only stops a step up.
Prefs logs a failed write, which printErrors off had silenced: the new
order would otherwise vanish at the next restart with no trace. Its
parsed object is renamed from data to doc, so it cannot shadow a base
property of that name.
The spec now says what was built: JSON.parse rather than a JsonAdapter,
and the helper list as it is.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Planning found two places where the spec diverged from the island it
extends. Icons go through the icon theme like every other island icon,
and drag is one MouseArea per tile with a pure drop-slot helper, which
is less code than DragHandler and DropArea and can be tested under node.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Nine tasks: two spec corrections found while planning, the pure helpers
with their node test, the preferences singleton, the tile, the panel,
the island and IPC wiring, the SUPER release bind with its fallback, a
visual pass with the user, and docs. The plan's test was run against
the plan's Controls.js before committing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Sub-project 2. A grid of seven toggles opened from the status pill and
by a bare SUPER release, with an edit mode to reorder, hide and show
tiles. The visible list lives in a JSON file under the state home, so a
tile added to the code later starts hidden rather than appearing
unasked. The drawer keeps the detail: right-click on a tile opens its
page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The sliver was the accent at rest, and udt had snapped the accent to the
same colour as the mic indicator (#36d190), so an idle sliver read as a
live microphone. It is Theme.overlay at rest now; captures keep their
colours whatever the wallpaper does.
The flag's WheelHandler never fired. MouseArea.onWheel, which SoundPage
already uses, does; scroll now switches layout, one step per notch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Twelve tasks from pure logic to waybar removal. The spec is corrected on
two points found while reading the code: Quickshell's PwNode has no running
state, so mic and screen detection poll pw-dump like the waybar script did,
and the VM dot rule now agrees with its own table on saved VMs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The same keyboard appears as a different device over USB and over its
dongle, so the main device is resolved per event, never cached.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Sub-project 1 of the move toward a Modesty-style integrated desktop: a
top-centre island on DP-1 hidden behind a sliver, a clock pill and a status
pill that slide out of it, a sound panel, and the removal of waybar.
Records the decisions taken while brainstorming: the island floats over
windows with no exclusive zone, privacy capture recolours the sliver rather
than revealing the pills, the clock pill flicks the desktop icon, app icon and
app name on workspace change and app open but not on focus change, the volume
icon has no gestures beyond opening its panel, and the flag images move into
this repo. Modesty is GPLv3, so only its ideas are used.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
fanfictioner runs sd-cli one-shot, not through sd-server, so the sd row
read down while a CLI run held VRAM and generated. A running sd-cli now
reads up and busy, its model marked (sd-cli), and outranks the web UI.
The model is the first --diffusion-model/-m: sd-cli's prompt follows and
is free text that may contain "-m".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Six TSV lines per sweep: llama and sd engines, four apps. llama's slot
probe passes autoload=false, since a plain /slots?model= loads the model
into VRAM. sd-server has no progress endpoint, so busy is its log
having been written in the last 5s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Engines (llama.cpp, sd.cpp) read-only, apps get start/stop through their
existing controls. Records that /slots?model= autoloads an unloaded model
unless autoload=false is passed, found when a design probe reloaded one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The list comes from hyprctl binds -j on every opening, so it is always
what Hyprland has loaded, loop-generated binds included. Labels come
from each bind's description option, since hyprctl reports Lua actions
as an opaque __lua handle.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Nine tasks over two repos. The daemon half gains a sourced config file and a
config verb that prints the effective settings, which is what makes the
config testable without running a thirty minute work block. The shell half
reads the daemon's three runtime files, adds a row and a tile line.
Three assumptions were probed rather than trusted while writing it, each
with a precedent for biting here: padStart exists in this QML engine
(matchAll does not), a Connections resync fires correctly on a singleton
property, and the config source line leaves unnamed variables alone.
The qs verification steps redirect rather than pipe. Piped output is lost
when timeout kills the process, which reads as a silent success, and that
failure happened twice while probing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
The daemon already publishes its phase, state and countdown as files under
XDG_RUNTIME_DIR, and the status module already shells out to it for
presentation mode. Reading those files makes the traffic two-way for the
cost of three FileViews, with no new interface to invent.
Into status/ rather than a module of its own: breaktimer state is one more
thing the desktop is doing, which is what that page already is, and
Status.qml is already where breaktimer.sh is called from.
The config file is the other half, and stands alone. Every tunable is a
shell variable in a tracked script, so the installed copy and the committed
one have already drifted over three sound paths pointing into a home
directory. One sourced file fixes that with no parser and no format.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Seven tasks: the hyprsunset model, the hypridle model, the icon/cursor
model, then the tab bar and one task per tab, finishing with docs and the
cross-repo unhardcode TODOs. Models are built and self-tested first so
every commit loads. Records the brace-in-command parsing trap and the
sunset-qt byte-for-byte serializer shape.
|
|
Design for three new appearance tabs: a hyprsunset-qt-equivalent profile
editor, a hypridle timeout/enable editor that preserves the file's comments,
and an icon/cursor selector with live previews. Records the preview
mechanisms probed on this box (GTK icon lookup, hyprcursor .hlc unzip,
xcur2png) and scopes the hardcoded-theme propagation out as follow-ups.
|
|
Two plans, one per subsystem: the notifyd daemon (hint parsing, PNG encode, theme-name resolution, the image field and its cleanup) and the quickshell renderers (the balloon preview and remote inline source stripping). Either can ship first; the renderer tolerates a daemon without the field.
|
|
The daemon drops every image hint today, so a screenshot and an application image never arrive. libnotify 0.8.8 sends the content image via -i/--icon (the image-path hint) while -n/--app-icon is app_icon. The spec adds the image contract field, daemon hint handling and theme-name resolution, the balloon preview, and a local-only inline image policy.
|
|
Plan two of two: the quickshell side of the notification daemon. The Notify
singleton reads the daemon's published files, a new notifications/ component
draws balloons and owns suppression, the drawer's reserved Item becomes the
live queue with a history page, and the Status page gains a snooze row.
Suppression lives in the balloon shell so the drawer can list what DND held
back, and the drawer flag is the single no-double-show mechanism. Per-id
history removal is a tracked TODO in the notifyd repo rather than an
untracked spec gap.
|
|
The freedesktop spec says -1 means the server decides and 0 means never; the
spec and plan had them reversed, which the shipped code inherited and the
live handover test caught. Corrected to match the spec, libnotify's -1
default and dunst.
|
|
The check has five assertions, not four.
|
|
The daemon binary was built at $tmp/notifyd, the same name RuntimeDir() gives
under XDG_RUNTIME_DIR, so the two collided. The runtime dir moves to $tmp/run,
which is what the shipped script does.
|
|
The test snippets omitted the header the global constraints require on every
.go file, which a task review flagged against the first one shipped. The
snippets now carry it, so later tasks do not repeat the gap.
|
|
Public under the Linux cgit section, cloned to ~/Programming/GIT/notifyd, so
Task 1 Step 1 is done and the executor starts at Step 2.
|
|
Plan one of two for the notification daemon: the Go daemon and notifyctl in
their own repo. The renderer plan is separate because the daemon is working,
testable software on its own, exercised through notifyctl.
The policy is pure and tested without a bus; the store's expiry, dismissal
and eviction are separate lifetimes, which the store tests pin; and
test-notifyctl.sh runs the daemon and CLI on a private session bus against a
temporary runtime directory.
|
|
The freedesktop expire_timeout is the notification's lifetime, and --wait
and -b clients block until the daemon closes it. So the daemon emits
NotificationClosed at expiry and frees the client, but keeps the entry in
the live queue: the drawer lists it until it is dismissed or evicted, inert
because its client is gone. History holds only what was dismissed or
evicted.
The reserved space is therefore scrollable, since the live queue can hold
20 at once, and a row past its expiry is read-only.
|
|
The second of the two specs the status registry named. A Go daemon owns
org.freedesktop.Notifications and holds the state; quickshell renders it.
The daemon and notifyctl live in a separate repo, the balloon shell and the
drawer's notification centre live here.
Rendering is split because quickshell has no generic D-Bus module, so
something outside QML has to own the bus name. Files are the interface in
the direction the renderers read, the same convention the registry set, and
notifyctl is the one surface back.
DND suppression lives in the balloon shell, not the daemon: the drawer's
reserved space lists every live notification including the suppressed ones,
because a list the user opened is not an interruption. This supersedes the
registry spec's assumption that the daemon would read dnd.
|
|
F1: after a click the shared Switch writes checked directly, dropping
StatusRow's declarative binding, so an external mode change from waybar
or statusctl no longer moved the switch. Resync via onValueChanged.
F2: the spec claimed hyprctl clients counts idle inhibitors, which is
false for a layer-surface inhibitor; replace with the behavioral
hypridle marker check.
F3: README said the check covers both watch states; it exercises the
activated report and the absent-file down report.
F4: give breakProc an onExited check so a failed breaktimer.sh verb is
visible instead of silent.
F5: drop StatusTile's unused required st property and its injection.
F6: comment the startup-order limit on dndBeforePresentation.
|
|
A FileView fires its own fileChanged on setText, so a handler that writes
in response to a change loops unless it compares first. IdleInhibitor has
no window of its own and does nothing without one, so the singleton is
handed the keepalive window by shell.qml.
Both were read from the documentation while designing and confirmed while
implementing.
|
|
read_mode() failed on a missing mode file with a shell redirection
error, 'statusctl: line 56: .../status.dnd: No such file or directory',
printed to stderr on every get/toggle before the file existed and
polluting waybar's exec stderr.
The '2>/dev/null' sat on the 'tr' command, but the error is the parent
shell's input redirection failure, which that redirect cannot suppress.
Guard on '[[ -e "$file" ]]' before reading; a missing file still
reads as 0, which was always the contract.
Mirror the fix into the plan so plan and script agree.
|
|
Two corrections to the plan, both found by running it rather than reading
it.
The test script the plan specifies makes nine assertions; the prose around
it claimed eight, in both the task step and the final check. An implementer
running it would see a passing suite that disagrees with its own expected
output, which reads as a failure of either the test or the plan. My
arithmetic.
The plan's statusctl also swallowed a failed rename and read the mode file
through cat piped into tr, so a write that did not land still reported
success and an unreadable file fell back to off by accident of pipeline
semantics rather than by intent. Review of the implemented script caught
both. The plan now carries the same fixes, so a future run of it does not
reintroduce them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7ThHHh5iTYbVfp3rNAkw2
|
|
Review of the first task caught that the commit message credited
atomicWrites while the code never set it. The property is already the
documented default in 0.3.1, so the behaviour was right, but statusctl
watches close_write,moved_to specifically because an atomic write arrives
as a rename, and leaning on a default for something the CLI depends on is
weaker than declaring it.
Both ModeFile blocks in the plan now set it, so task four does not
reintroduce the gap when it adds the second mode.
Worth recording: the review asserted atomicWrites defaults to false in
0.3.1 and concluded the shipped writes were not atomic. The v0.3.1 and
v0.3.0 documentation both read "If true (default)", so that conclusion was
wrong, though the underlying observation about the unset property was
right.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7ThHHh5iTYbVfp3rNAkw2
|
|
Eight tasks against the registry spec: the singleton with the dnd mode,
the statusctl CLI and its check, naming the keepalive window, presentation
mode and its three effects, the module and tile, the page and registration,
installing the CLI and swapping the waybar module, then the README and
traps.
The plan carries the facts probed while designing so the implementer does
not re-probe them: the runtime directory is tmpfs, elogind runs here with
the pam caveat that stops it guaranteeing logout cleanup, the compositor
advertises zwp_idle_inhibit_manager_v1, inotifywait is present, and
Inconsolata Nerd Font lives under ~/.fonts rather than either share
directory. That last one cost a failed cmap search that read as a missing
glyph when it was a bad search path.
Two claims stay marked unverified because they come from documentation and
have not been observed running: that a FileView fires its own fileChanged
on setText, and that IdleInhibitor does nothing without a non-null window.
The plan handles both and tells the implementer to confirm them and record
what actually happens.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7ThHHh5iTYbVfp3rNAkw2
|
|
Desktop modes as state: do not disturb and presentation mode, with one
place that owns them. First of two specs; the notification daemon that
replaces dunst is the second and consumes the registry's dnd mode rather
than owning it. The registry comes first because DND belongs to the
desktop rather than to the notification daemon, and because the daemon is
the larger and riskier component.
The design that needed deciding was not the toggle but the coupling.
Presentation mode sets DND, so DND has two writers, and turning
presentation mode off has to restore what the user had rather than
clearing it. That rule is why this is a registry and not two booleans.
State is one file per mode in XDG_RUNTIME_DIR, matching the convention
breaktimer already writes on this machine. That directory is /run/user/1000,
a tmpfs, so a reboot clears every mode with no cleanup code. Logout without
reboot is less certain and the design does not lean on it: elogind runs
here and its pam module documents removing the runtime directory at last
logout, but the same manual says the module does nothing when the system
was not booted with elogind as init, which on Slackware it is not. If
removal does not happen, a mode survives a logout, which is the same
behaviour as surviving a shell restart.
FileView covers both directions: atomicWrites for the write, watchChanges
for the watch, no shell-out. External watchers need close_write,moved_to
because an atomic write arrives as a rename, the same trap the mail watcher
hit with Xapian.
Confirmed while designing: the compositor advertises
zwp_idle_inhibit_manager_v1 and waybar's built-in idle_inhibitor already
drives it here, so the inhibitor is asserted over Wayland rather than D-Bus.
That module is replaced rather than demoted, because it owns its inhibitor
object and cannot display state owned by anything else; left alongside the
registry it would assert a second inhibitor and idle would resume only when
both released.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7ThHHh5iTYbVfp3rNAkw2
|
|
Absorbs the kdeconnect-indicator into the drawer: status, battery,
pairing, ping, clipboard send, file share, refresh and mount. State is
polled from a qdbus6 helper script while the drawer is open, since
quickshell 0.3.1 has no generic D-Bus module.
The spec notes the phone-to-PC clipboard is the daemon's plugin, not the
indicator's, so removing the indicator does not touch it.
|
|
The pairing flow needs isPairRequested, isPairRequestedByPeer and the
verification key, so the polled line carries them; the key is only queried
with a pairing in flight. A failed daemon query is a non-zero exit with no
output, which is how the module tells it apart from a valid empty list.
Pairing failure comes from the kdeconnect-cli exit code, not the
pairingFailed signal, since there is no generic D-Bus module to watch it.
|