feat(menu): #140 — Ask opens a web chat, provider is in-flake state
All checks were successful
Check / eval (push) Successful in 3m57s

Bernardo: "opening claude-code is too disruptive". SUPER+CTRL+A spent a
terminal, an npm fetch and a REPL on "what's the syntax for…" — the prompt
was the right surface, the destination was not. The query is now
URL-encoded into the provider's web chat and handed to xdg-open.

settings.ask.provider (claude|chatgpt|gemini|grok, default claude) with a
Preferences row, read from state at RUN TIME so switching needs no
rebuild, and any unknown/absent value falls back rather than opening
nothing. He asked for chatgpt + grok alongside claude/gemini, and for the
CLI to go: claude-code is deleted and pkgs.nodejs leaves with it (carried
only for that npx). Keybind is "Ask AI" now the destination is the user's.

The failure mode is the design point: prefill is undocumented on all four
vendors, each can drop `?q=` unilaterally, and it fails SILENTLY — you
land in an empty chat having already typed the question. So the query is
also copied to the clipboard (a vendor breaking change costs one paste,
not the question), and the URLs sit in one attrset so the repair is one
line.

Verified against the generated script: bash -n clean; every bad state
value (unset/null/garbage) falls back to claude; a hostile query encodes
correctly (& → %26, ? → %3F, # → %23, $(whoami) neutralised, café →
caf%C3%A9). NOT verified on purpose: whether each vendor fills the box or
auto-submits — that means posting into Bernardo's own accounts.

Sweep: ROADMAP's shipped-modules line described the npx REPL; nix-ld's
comment cited claude-code as its example; both fixed. Menu row + keybind
renamed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-16 11:37:15 +01:00
parent 48e73ab6d3
commit 207b6f3c64
5 changed files with 91 additions and 46 deletions

View File

@@ -31,10 +31,10 @@ Design/decision records and a running log of shipped work (items marked
- ✓ shipped modules: `network` (nmtui in `$TERMINAL`) · `bluetooth`
(blueman-manager) · `capture` (grim/slurp submenu: region/full →
clipboard/file, saved to `~/Pictures/Screenshots`) · `keybinds` (the
cheatsheet, see below) · `ask` (free-text → claude CLI in a terminal;
auths via OAuth, no API key; pulled fresh via `npx
@anthropic-ai/claude-code@latest` rather than the nixpkgs package, which
lags model releases — `nodejs` is bundled for npx; REPL stays open)
cheatsheet, see below) · `ask` (free-text → the provider's web chat in
the default browser; provider from `settings.ask.provider`, Preferences ▸
Ask provider — see the #140 ✓ entry below for what it used to be and why
it changed)
- ✓ keybindings cheatsheet: `modules/home/keybinds.nix` is the **single
source** for both the Hyprland binds and the SUPER+? rofi list, so they
can't drift; `nomarchy-menu keybinds` renders the padded two-column
@@ -449,6 +449,28 @@ Design/decision records and a running log of shipped work (items marked
(#131). Those windows therefore carry float/center rules and deliberately no
`size` rule. Measured after: calendar 1536×936 = exactly 60%×65%, doctor
1408×1008 = 55%×70%, both centred in the Waybar work area.
- ✓ **Ask hands off to a web chat (#140, 2026-07-16):** Bernardo: "opening
claude-code is too disruptive." SUPER+CTRL+A used to spend a terminal, an npm
fetch and a REPL on "what's the syntax for…" — the prompt was the right
surface, the destination was not. Now the free-text line is URL-encoded into
the provider's web chat and handed to `xdg-open` (Chromium, per Decisions).
Provider is `settings.ask.provider` (claude · chatgpt · gemini · grok,
default claude) with a Preferences row, read from state **at run time**, so
switching takes effect on the next question with no rebuild — and an unknown
or absent value falls back rather than opening nothing. The `claude-code`
path is deleted and `pkgs.nodejs` left with it (it was carried only for that
`npx`); the keybind is "Ask AI" now that the destination is the user's.
**The interesting bit is the failure mode.** Prefill is undocumented on all
four vendors — each can drop `?q=` unilaterally, and it fails *silently*:
you land in an empty chat having already typed the question. So the query is
also copied to the clipboard, which turns a vendor's breaking change from
"your question is gone" into one paste; and the URLs live in a single
attrset (`askProviders`) so the repair is one line. Verified with the
generated script: every bad state value falls back to claude, and a hostile
query (`&`, `?`, `#`, quotes, `$(whoami)`, unicode) encodes correctly —
`%26`, `%3F`, `%23`, `caf%C3%A9`. **Unverified on purpose:** whether each
vendor's page fills the box or auto-submits — testing that means posting into
Bernardo's own accounts.
- ✓ **Menus are sized in `ch`, not in % of the monitor (#131, 2026-07-16):**
Bernardo saw Recovery's labels ellipsize **on a 2560×1440 external** — which
falsified the item's own model ("`width: 40%` + Inter 11 → only below ~1920;