aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-02 14:16:09 -0400
committerCraig Jennings <c@cjennings.net>2026-07-02 14:16:09 -0400
commit33c89b1154360cb2ed9733465c1931521cdee136 (patch)
tree6099adf91363441f635b4ffb73bd5e605b957ab5
parent7091f3472be5d09fcf01a539f2ca1c8d88d618d1 (diff)
downloadarchsetup-33c89b1154360cb2ed9733465c1931521cdee136.tar.gz
archsetup-33c89b1154360cb2ed9733465c1931521cdee136.zip
docs(spec): bluetooth phase 2 shipped, AT-SPI smoke deferred until meeting ends
-rw-r--r--docs/design/2026-07-02-bluetooth-panel-spec.org17
-rw-r--r--todo.org4
2 files changed, 19 insertions, 2 deletions
diff --git a/docs/design/2026-07-02-bluetooth-panel-spec.org b/docs/design/2026-07-02-bluetooth-panel-spec.org
index a6b60ae..cde5ec8 100644
--- a/docs/design/2026-07-02-bluetooth-panel-spec.org
+++ b/docs/design/2026-07-02-bluetooth-panel-spec.org
@@ -363,6 +363,23 @@ Non-blocking; it's the donor default made explicit.
* Review and iteration history
+** 2026-07-02 Thu @ 14:15:27 -0400 — Claude Code (archsetup) — phase 2 builder
+- *What changed or was recommended:* Phase 2 shipped (dotfiles =76b2c05=):
+ the GTK panel — PanelModel/viewmodel presenter pair (69 tests), Blueprint
+ pages, pairing pty state machine with default-deny passkey confirms,
+ manage.py op envelopes shared by CLI and panel (power + discoverable verbs
+ added), =bt-panel= toggle, Super+Shift+B rebind. The shared dupre css
+ factoring landed as planned: net's inline =_CSS= became
+ =themes/dupre/panel.css= with =dupre-*= classes, both panels consume it.
+ 43 suites green. The AT-SPI smoke (=make test-panel-bt=) is written but
+ not yet run live — a Zoom meeting occupied the compositor; it runs when
+ the meeting ends, along with a visual check of both panels.
+- *Why:* Build order per the DOING decomposition; phases 3-5 (bar module,
+ bt-priv/sudoers, install defaults) remain.
+- *Artifacts:* dotfiles =bluetooth/src/bt/{panel,viewmodel,pairing,manage,
+ gui,pages}.py=, =ui/*.blp=, =tests/bt/test_btpanel.py=, the panel smoke;
+ dated phase 2 entry under the todo.org parent.
+
** 2026-07-02 Thu @ 13:31:00 -0400 — Claude Code (archsetup) — phase 1 builder
- *What changed or was recommended:* Phase 1 shipped (dotfiles =eb2230f=):
the =bt= engine package, 101 tests over fakes, live-verified read-only
diff --git a/todo.org b/todo.org
index 99c7309..fb20f5d 100644
--- a/todo.org
+++ b/todo.org
@@ -548,8 +548,8 @@ A bluetooth panel driving a CLI underneath (bluetoothctl one-shot verbs), consis
*** 2026-07-02 Thu @ 13:30:42 -0400 Shipped phase 1 — the bt engine package (dotfiles eb2230f)
=bluetooth/src/bt/= mirrors the net engine's layout: btctl parsing boundary (show/devices/info, connect-error classifier), sysio rfkill/airplane, audio module over pw-dump/wpctl (HSP probe + A2DP switch repair with verify-after), redacted eventlog, six repair tiers, and the doctor chain (adapter → rfkill → service → powered → devices → audio profile) with safe auto-repairs behind =--fix= (never auto-connects; airplane blocks are named, not fought). 101 tests over fake binaries; 42 suites green (=make test= glob auto-discovered =tests/bt/= — gate check verified). Live read-only on velox: =bt status= + =bt doctor= read the real adapter/devices/audio graph; =~/.local/bin/bt= hand-linked (no restow under running Hyprland). Ground truth vs spec: profile inventory needs =pw-dump= (wpctl can't enumerate), and the card's =bluez5.profile= prop is unreliable — sink node's =api.bluez5.profile= is authoritative. Deferred INTO phase 2: the shared dupre css factoring (net's css is an inline string in =gui.py=, not an asset — factoring it without the bt-panel consumer just risks the working net panel).
-*** TODO Phase 2 — panel (dotfiles) :feature:
-PanelModel presenter + Blueprint pages (Devices with Paired/Nearby, Diagnostics), worker-thread wiring, pairing-dialog pty state machine, bt-panel toggle wrapper, AT-SPI smoke. Super+Shift+B rebind. Carries the shared dupre css factoring deferred from phase 1 (extract net's inline =_CSS= to the common asset, point both panels at it).
+*** 2026-07-02 Thu @ 14:15:27 -0400 Shipped phase 2 — the GTK panel (dotfiles 76b2c05)
+Cloned the net panel's shape over the phase 1 engine: GTK-free PanelModel + viewmodel (69 new tests, display-free), Blueprint pages (Devices with the adapter power row + Paired/Nearby sub-views; Diagnostics with the doctor cascade, inline fix buttons mapped from step =repair= keys, Advanced tool selector), gui.py controller (layer-shell OVERLAY 380x520 TOP+RIGHT, Esc closes, single-instance toggle, bg worker, passkey + confirm dialogs), pairing pty state machine (=bt/pairing.py=: confirm-passkey yes/no with default-deny, display-passkey, bounded deadline, tested over the fake's interactive mode), manage.py op envelopes shared by CLI and panel (cli refactored onto it; power + discoverable verbs added), =bt panel= subcommand + =bt-panel= toggle wrapper (hand-linked into =~/.local/bin=, no restow under live Hyprland). Shared dupre css factored: net's inline =_CSS= → =hyprland/.config/themes/dupre/panel.css= with =dupre-*= classes, both panels load it (stowed path first, repo-relative fallback; hand-linked =~/.config/themes/dupre/panel.css=). Super+Shift+B rebound blueman-manager → bt-panel (hyprctl reloaded, live). 43 suites green (=make test= exit 0). DEFERRED pending Zoom ending: the AT-SPI smoke (=make test-panel-bt=, written and wired) and any visual check of either panel with the factored css — both need a visible window. Gotcha for posterity: the old =test_panel_stub_exits_two= CLI test ran =bt panel= for real once cmd_panel was wired and launched the panel on the live compositor mid-meeting for ~30s before the test timeout killed it; it now asserts parser wiring only — never run =bt panel= inside =make test=.
*** TODO Phase 3 — bar module custom/bluetooth (dotfiles) :feature:
Glyph states, tooltip with battery + keybind hints, low-battery surface, refresh signal, waybar config + suite coverage; blueman retirement per the decision.