Skip to content
This repository was archived by the owner on Nov 8, 2026. It is now read-only.

Promote dev to main (v0.0.1 candidate) - #567

Merged
techmore merged 1174 commits into
mainfrom
dev
Oct 23, 2026
Merged

techmore merged 1174 commits into
mainfrom
dev

Conversation

@techmore

Copy link
Copy Markdown
Owner

Release PR requested by the owner on 2026-10-23: promote dev to main per BRANCHING.md.

Size: 1171 commits and 1160 files (about +177k/-3k lines) ahead of main. main has 5 commits dev lacks (#270 and its revert, #284, #458 untrack rust/target); the merge carries them in.

Not included: open draft/deferred PRs, including #525 and #526 (Signal and Messages, owner-deferred).

CI at dev head db4290d2 (before this PR): Software Updates app, Rust Pantheon SDK and System Monitor, Disk Space app and Pages build pass. Failing: Rust Pantheon Messages preview and Watch public upstreams. Checks on this PR are the authority.

Not verified: most of dev is source/fixture-tested, not hardware-accepted; per-feature acceptance is recorded in the individual docs (see mseries/releases/v0.0.1/README.md, mseries/MESSAGING-STATUS.md, mseries/dictation/F5-ENGLISH-ACCEPTANCE.md). No release tag is created by this PR.

🤖 Generated with Claude Code

techmore and others added 30 commits October 22, 2026 00:11
…restore to checkpoint

src/changes.rs replaces the flat list of collapsed diffs: the thread's full diff
(orchestration.getFullThreadDiff) is parsed into files with status (added, deleted, renamed,
modified) and counts, listed in a navigation-sidebar tree; the selected file shows hunk by hunk in
GtkSourceView with the diff language, inline or side by side (old and new reconstructed from the
hunk, context on both sides), with a copy button per hunk. "Restore to checkpoint…" lists the
thread's ready checkpoints (from the projection; checkpoint.captured events keep it current) and,
after a confirmation dialog, dispatches checkpoint.rollback with restoreFiles. The render test opens
the page for a thread and waits for its summary.

Closes #474

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-pantheon-rs: diff viewer with side-by-side/inline, file tree, revert to checkpoint
… stream

src/terminal.rs: a VTE terminal in a revealer under the chat (Ctrl+Shift+T, also in the menu),
one per thread, attached with terminal.attach in the thread's project folder (restartIfNotRunning,
resume): the snapshot's retained history is replayed, live output chunks fed, keystrokes sent with
terminal.write, size changes with terminal.resize; the client keeps at most 512 KiB (the contract's
client cap) by resetting scrollback past it, the server its 5,000 lines / 8 MiB. No local PTY.
elementary Terminal's palette on a light or dark background following the app. Hiding the pane or
leaving the thread interrupts the stream. The render test attaches to a thread's terminal on the
running server (pid shown), then detaches.

Closes #475

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-pantheon-rs: vte4 terminal pane fed from the server's terminal stream
src/settings.rs: a sidebar of pages (Appearance, Defaults, Server, Notifications, Advanced) with
switches and dropdowns, persisted in ~/.config/claude-pantheon-rs/settings.json. Appearance follows
the system, light or dark (Granite's stylesheet follows the same flag); Defaults set the provider and
permission mode new threads start with, with a per-project override of the mode (supervised stays
the default, full access a per-thread choice); Server shows the pairing state with Pair, Forget
pairing and the MCP endpoint to copy, and whether the keyring is used; Notifications toggles the
turn-finished and prompt notifications and the dock badge (honoured by notify_background and
refresh_launcher); Advanced picks the GSK renderer, read by main() before GTK starts unless
CLAUDE_PANTHEON_RENDERER is set, and opens the configuration folder. Ctrl+, and the menu open it. The
render test opens it and checks its pages.

Closes #476

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…entity

src/snapshot.rs: Ctrl+Shift+S (and the menu) reads the active window's title and PID from the
AT-SPI registry first (the portal's own flash would otherwise be the focused window), then calls
org.freedesktop.portal.Screenshot.Screenshot with a handle_token and waits for the Request's
Response signal, reads the PNG the portal wrote, names it snap-<title>-<stamp>.png and uploads it
through the composer's attachment path so it lands on the draft. Errors (denied, no image, bus)
show in the composer status. GlobalShortcuts portal availability is probed but Pantheon's backend
does not offer it, so the in-app accelerator is the binding. No portal under Xvfb, so the render
test covers the composer path and the unit test the file naming.

Closes #477

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-pantheon-rs: SnapShot through the portal with AT-SPI window identity
…nly on request

src/webview.rs: a completed html_render tool call (the server keeps its output as a JSON string
with an htmlRender reference: attachmentId, title, height) becomes a card with the title and a
Show page button; the webkit6 WebView and its web process exist only after that press and are
freed by the card's close button, so an idle window has no web process (idle RSS 69 MB, the 3 MB
over #477 is the library being linked). Signed URLs come from assets.createUrl on each open
(they expire); links leave for the browser through UriLauncher; a Granite palette style sheet is
injected so unstyled pages follow light and dark; full screen opens the page in its own window
(Escape closes). chat::set_page_resolver lets the app install the URL resolver.

CI: both workflows now install libgtksourceview-5-dev, libvte-2.91-gtk4-dev and
libwebkitgtk-6.0-dev (the Claude jobs have been red since #474/#475 on the missing -dev packages;
the checks are not required on dev, which is why those PRs merged); the .deb Depends lists the
three runtime libraries. README notes the toolchain.

Closes #478

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-pantheon-rs: visual replies in WebKitGTK page cards, created only on request
contracts/PROTOCOL_VERSION and contracts/METHODS are the vendored ORCHESTRATION_PROTOCOL_VERSION
and RPC tag lists (WS_METHODS + ORCHESTRATION_V2_WS_METHODS, 201 tags) from the sparse t3code
clone, regenerated by scripts/refresh-contracts.sh (clones sparse/blobless when missing, --check
reports drift, --record re-records tests/fixtures with --t3-dump). build.rs compiles them into
t3::contracts and, when ~/claude-work/repos/t3code (or T3_CONTRACTS_REPO) is present, fails the
build on drift with the diff and the script to run (T3_CONTRACTS_DRIFT=warn downgrades). The
client's PROTOCOL_VERSION now comes from the contracts; debug builds assert each RPC tag is known;
a unit test scans src/ for every literal tag after .call(/.subscribe( and checks it against the
list. The 426 message and the About dialog name the protocol version and contracts commit. CI
runs the drift check against t3code main as an advisory step (continue-on-error with a warning),
since upstream moves daily.

Closes #484

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-pantheon-rs: protocol version guard and contracts drift check
… Connect)

src/environments.rs: saved environments in ~/.config/claude-pantheon-rs/environments.json, each a
route: Direct (URL), Tailscale (a peer from `tailscale status --json`, the server listening on its
tailnet address), SSH (`ssh -N -L local:127.0.0.1:remote target` kept as a child process while the
environment is current, waited for before the first request) and T3 Connect (the relay environment
a pairing URL names). The sidebar footer gets a flat menu button with the current environment's
state and name; its popover lists every environment with kind, URL and state (connected, connecting,
offline, not connected), and Add/Edit/Remove open a small modal dialog with per-kind fields.
Switching drops the connection and tunnel, loads the new environment's credential (auth::load_for,
keyed by server URL in the keyring or credentials-<server>.json; the default server keeps its
original item) or shows the pairing page with that server prefilled; pasting a pairing URL for
another server creates its environment. Reconnect back-off reopens the route first. The render
test adds an unreachable environment, checks the switcher and the pairing page, switches back and
reconnects, then removes it.

Closes #479

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-pantheon-rs: environments switcher (direct, Tailscale, SSH, T3 Connect)
src/skeleton.rs: grey bars that pulse where content is about to appear (chat bubbles while a
transcript or thread loads, list rows while sessions index or the server connects, while gh answers,
while usage is read) and a compact icon/title/hint block for empty panes. The pulse is a CSS
animation added on map and removed on unmap: an always-on animation parked in a hidden stack page
cost 2.6 % idle CPU, gated it costs nothing. The thread list gets a ListBox placeholder (skeleton or
"No threads yet" / "Nothing matches" with a hint that depends on connection state); the Repos page
shows a Granite placeholder with an Import Sessions button when no project has a GitHub remote; the
issue list shows a placeholder when nothing matches and one with Retry when GitHub fails. toast_retry
adds a Retry action to Granite toasts for transient errors: server unreachable, a chat that could not
be read, a thread stream that ended, usage or GitHub failures. The render test checks the search
placeholder, that no spinner remains, and that the toast's Retry runs its closure.

Closes #480

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-pantheon-rs: empty states, skeleton loading rows and retry toasts
…ility pass

src/winstate.rs remembers size, maximised state and the sidebar width in window.json (clamped on
load, written on close-request). Text zoom (Ctrl+plus/equal/KP_Add, Ctrl+minus/KP_Subtract,
Ctrl+0/KP_0, 80–200 % in 10 % steps, and a spin row in Settings → Appearance) scales every font
through gtk-xft-dpi relative to the DPI GTK started with, so the system's text scaling and HiDPI
are kept; the value persists in settings.json. The render test now prints the scale factor and
asserts 2 under GDK_SCALE=2 (run once at 3000x2000: scale factor 2, all steps pass). Accessible
names on every icon-only control (New Thread, Send, Stop, Remove attachment, page card buttons,
markdown images), the search field, the three pickers, the thread list and sidebar rows ("title,
time, running, pinned"), and every chat item ("You: …", "Assistant: …", "Tool call Bash: …",
"Permission request: …"); the composer's TextView carries the text-box role. Keyboard focus is
outlined on list rows, flat buttons and issue rows.

Closes #481

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-pantheon-rs: window state, text zoom, HiDPI check and accessibility pass
workflow::webhook_task builds the scheduled task GitHub's issues.labeled event triggers: a webhook
schedule with filters headers.x-github-event == issues, body.action == labeled, body.label.name ==
agent:ready, HMAC-SHA256 over X-Hub-Signature-256 with a fresh secret, and a prompt templated from
the payload ({{body.issue.number}}, {{body.issue.title}}). The Repos page's Webhook button installs
it per pinned repo; when the server reports a webhook URL GitHub can reach (not loopback: the
Tailscale or T3 Connect environment) the client creates the repo hook with gh api repos/<repo>/hooks
(events issues, JSON, the same secret; the body goes over stdin) and remembers the hook id; until
then the card says the endpoint is not reachable yet and pressing Webhook again later creates it.
Per-run rotation: with every five-minute provider refresh the client lists the scheduled tasks and
re-points every Runner:/Webhook: task whose provider is not the one pick_provider would choose now
(workflow::rotate_tasks: requireExisting, the read model's schedule passed back so a webhook keeps
its stored secret), so the next run uses the provider with the most capacity. Unit tests for the
task shape, reachability, hook body and rotation; the render test runs a rotation pass against the
live list.

Closes #482

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-pantheon-rs: webhook runner tasks and per-run provider rotation
techmore and others added 24 commits October 23, 2026 05:47
…ices, msdk render, screenshots; introspection/streaming design (#551)

* T3 port in the SDK: t3.msdk, plug-in service registry, Transcript, list sections, enter-sends, dialogs/popovers, fixture; msdk render

t3.msdk (text form) + services manifest + gates + fixture, checked clean and gated.
Forced additions only: group_by, Transcript, enter_sends, service/feed registry with
manifests, open/close surfaces, Services provider hook. msdk render (headless
semantic tree) as the first slice of the introspection API; design for the live
API, WebRTC streaming and the standard shell/settings layout.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* SDK standard chrome (silver title band, controls left, options menu), layout standards, Tabs/Stack, optional auto-hide sidebar, --screenshot

Contrast fix for bubbles, composer height, button stretch, page-scoped primary-action
check, app metadata (version/license/website). T3 .msdk uses Tabs+Stack; 54 tests pass,
clippy clean. SDK shortfalls from the T3 screenshot recorded as the work list.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…ed tabs, symbolic icons (#552)

align/grow/width on every component, lines/maxLines on multiline entries, natural-size defaults for
buttons/tabs/dropdowns; msdk contrast and a built-in sdk-contrast gate (found and fixed muted text at
4.19:1); badge text readable in dark; segmented Tabs; -symbolic icons. 56 tests, clippy clean.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…tric rule, window radius CSS; corners policy and compositor contract (#553)

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…fetch fallback, early cache save) (#554)

codeload returned HTTP 429 on shared runner addresses for several branches at once; the
cache was never filled because it saves only after a fully green job.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…st slice

Design only. Reuses the dictation IBus lease for commit, keeps display separate from
commit because Chromium confirmed preedit on focus loss, and scopes a first slice with
acceptance gates. Does not resume the deferred Signal/Messages build-out.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
docs: smart reply design (window-aware drafts, Tab to insert)
…scope

Reconciles the design with the reply drafts already in #526 (mseries-ai, Tab insert in
Messages), adds allow/block rules and a Settings panel, scopes the first slice to marked
chat apps, and describes a right-click expose for other apps as a later step.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
docs: smart reply design update (builds on #526, rules, chat-first scope)
…n the right

Windows Work Mode left the Mac-style close,minimize,maximize: layout, so the Windows 11
mode had no obvious close button. Adds a window-buttons choice to the panel (default
Windows, or keep my layout), applied and restored like the icon theme, with tests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…261022

[INCOMPLETE / DEFERRED — DO NOT MERGE] Add Rust Pantheon SDK, Messages, System Monitor, and local AI drafts
work-mode: window buttons setting (minimize, maximize, close on the right)
…1022

Docs: report the wip3 dock-port issue
sdk: anchor dock through Pantheon panel protocol
…ker (#565)

* Design: SDK agent surface (app intents, entitlements and consent for the MCP broker)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Record owner decision: the SDK owns the MCP surface; desktop apps are rebuilt on it

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
main had 5 commits dev lacked (#270 and its revert, #284, #458). Conflicts in
validate-mseries.yml, .gitignore and OS9-HANDOFF.md are resolved in favor of dev, and
mseries/share-cost is kept: main reverted #270 because it belongs on dev. The tree is
identical to dev; this only records main's history so dev is no longer behind main.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
techmore and others added 2 commits October 23, 2026 12:00
…e restarts (#558)

GrabAccelerator grabs now belong to the connection that made them and are
released when it leaves the bus, so a restarted gsd-media-keys (or any
grabber) is no longer refused with 0 by its dead predecessor's grabs.
Re-grabbing a key the same client holds returns a fresh id, Ungrab only
releases the caller's own grabs, AcceleratorActivated goes only to the
grabbing client, and the session is announced ready only once
org.gnome.Shell is owned.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Sync main into dev (history only, tree unchanged)
@techmore
techmore merged commit 4df7517 into main Oct 23, 2026
31 of 34 checks passed

This branch was previously deployed

1 inactive deployment
github-pages — 3e7d3182 Deployed Oct 23, 2026 by techmore via deploy #592
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant