Battle.net now maps as steam_app_default, not steam_app_0, so the
suppress_event rule stopped applying — its activation spam clears
quickshell's focus grab, which kills the launcher in the same frame it
opens. Match either class; same for the tray-icon rule.
fd drops --hidden, so ~/.cache, ~/.local/share/Steam, .git trees and
friends are out of the search entirely — most of the files under $HOME
and none of them worth matching by name. The .git/.cache/.steam excludes
go with it; node_modules is the one junk tree that isn't hidden.
Also log the three points that can swallow a Super+R: the IPC handler
when no bar is registered, the toggle itself, and the focus grab closing
a panel the user didn't close. journalctl --user -u quickshell.
The results ListView had add/remove transitions animating opacity and
scale on the delegate root. The model is re-diffed on every keystroke, so
a row part-way through a fade frequently survived the next pass as a move
instead of a remove — and move animates x,y only, leaving the
half-finished opacity permanently unrestored. Rows accumulated stuck at
arbitrary opacities depending on typing speed, which read as the result
colours randomly fading.
Dropped both fades. x,y stay animated because the view re-asserts them on
every layout, so an interrupted slide self-corrects; opacity and scale
have no such backstop. Comment records that a future fade belongs on a
child item, not the root the view recycles.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
launchPin passed a bare DesktopEntry to activate(), but activate()
started dispatching on a `kind` field when the results list became
heterogeneous (apps + files + web). A bare entry has no `kind`, so every
pin click fell through to the no-op branch: the tiles rendered, hovered
and dragged correctly and simply never launched. Regression from
"launcher searches files and the web".
Wrap via appItem() so the pin takes the same path as a search result, and
make activate()'s fallthrough console.warn instead of returning quietly —
the silence is the only reason this survived a release.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
No API key and no separate billing: qs-ask now shells out to `claude -p`,
which draws on the existing subscription already authenticated on this
host. The trade is latency — Claude Code boots a Node process per
question, ~6s measured against the raw API's ~1s — so the launcher now
races Wikipedia and Claude instead of chaining them. Wikipedia fills the
card in under a second and Claude supersedes it on arrival; chaining
would have left the card blank for six seconds on every question.
Isolation, verified: --safe-mode drops CLAUDE.md, skills, hooks, plugins
and MCP while leaving auth working, which matters for correctness and not
just speed — the global CLAUDE.md here asks for caveman-mode replies and
that would have leaked into answers. --no-session-persistence writes no
transcript, and a dedicated empty cwd keeps launcher questions out of any
project's history or auto-memory. Confirmed no project namespace, no
transcript and no memory write after a run.
Not --bare, which looks right and is a trap: its auth is strictly
ANTHROPIC_API_KEY, so it cannot use the subscription at all.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds qs-ask on the mediaserver — the Anthropic key lives there and nowhere
else, so neither desktop holds a credential and there's one place to
rotate it. The launcher pipes the question over the same SSH path the
server monitor already uses; the query goes over stdin because
`ssh host cmd arg` would re-parse arg through the remote shell.
Claude answers first, Wikipedia is the fallback. The script is the
feature gate: with no key it exits silently, which is the same signal as
a failed call or an UNKNOWN reply, so the Wikipedia path stays the
default with zero configuration. The card names whichever answered.
Haiku 4.5, no thinking and no effort (effort errors on Haiku) — a
one-sentence fact needs no reasoning tokens. ~$0.0005 per query.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"where is K2" had no scoring signal at all — "where" is a stopword and
"k2" fell under the 3-char term floor, so every sentence tied at zero and
the card fell back to the opening line. Fixes:
- answer-type hints: a "where" question scores sentences carrying the
vocabulary of place, "when" of dates, "who" of attribution. Stems, not
whole words — the Telephone intro says "granted a United States
patent", never "invented". "is a"/"was a" deliberately excluded, since
they match the definitional opening of every article.
- term floor down to 2 chars so "K2" and "UK" count.
- fetch 3 candidates and choose: an exact title match wins, and a
disambiguated title loses unless the query asked for that sense.
Search rank alone put "Chernobyl (miniseries)" above the city.
Verified 11/11 on live responses by running the generated QML functions.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Wikipedia search+extract in one request gives the article for a
natural-language query, then the intro's sentences are ranked so the card
leads with the one that actually answers: +3 per query term, +4 for a
digit when a number was asked for, ties to the earliest sentence. Title
words are dropped from the terms unless they're the attribute asked
about, which is what makes "mount everest height" return 8,848.86 m
instead of a sentence restating the subject.
Fires on a 600ms debounce, only for query shapes that aren't app
searches, cached per query — Wikipedia throttles bursts, so restraint is
correctness here. Every triggered query goes to Wikipedia.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Results become one flat list — apps, then files, then a web fallback —
so a single set of arrow keys walks all of it and activate() dispatches
on the item kind.
Files come from one fd run per settled keystroke, scoped to $HOME and
capped with --max-results so fd exits as soon as it has enough; no index
and no daemon, so nothing is ever stale. Spaces in the query become
gaps ("report 2024" finds report-2024.pdf) and regex metacharacters are
escaped so a query can't make fd bail.
Web row is last and always there, with bangs (!yt !gh !no !np !w) to
retarget it. Suppressed for arithmetic so Enter keeps copying the sum.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Pinned apps move out of the results list into their own tile grid, three
across, wrapping to further rows. Drag a tile onto another slot to
reorder; the id list is rewritten on release rather than mid-drag, so
nothing shifts under the cursor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Type arithmetic in the launcher ("3+3") and a result card appears above
the list; click or Enter copies it. Right-click any result to pin it to
the top — pins persist in ~/.local/state and outrank ties in search.
CPU/RAM rows in the server card use a new knobless MeterBar instead of
PillSlider, which read as draggable controls.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fixed hues stayed legible but read as pasted on. Mix each 25% toward
base0D so they land in the wallpaper's family: err #e0525f -> #b86872,
ok #68c17c -> #5ebb88. statusHarmony is the one knob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Stylix base01/base02 come off the wallpaper and land off-hue (purple card
over a slate bar). Tint base00 instead: #1c1f26 -> #2f3440 -> #434a5b.
base08-base0C collapse to the same cyan on monochrome wallpapers, so
warning and critical were indistinguishable. Replace with fixed err/warn/
ok/info/alt tokens; base0D stays the themed accent.
Also fixes Theme.base06, which was referenced but never declared.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>