Skip to content

feat(plugins): show attributed statuses on threads - #31

Draft
saphid wants to merge 465 commits into
ashx-j:feat/plugin-systemfrom
saphid:feat/plugin-thread-status-20261110
Draft

saphid wants to merge 465 commits into
ashx-j:feat/plugin-systemfrom
saphid:feat/plugin-thread-status-20261110

Conversation

@saphid

@saphid saphid commented Nov 10, 2026 •

Copy link
Copy Markdown

Problem

Server plugins can expose tools and panels, but cannot show a short status on a thread. This recovers that use case from #16061.

Change

Server API version 2 adds keyed threads.setStatus and threads.clearStatus. Statuses are attributed to their plugin and delivered through the environment read subscription to web/desktop and native mobile. Limits are eight keys per thread, 64 threads per plugin, and 200 characters per text. Targets are validated; statuses clear on deactivation and a stale activation cannot restore them. Drafts and disconnected clients do not show retained status data. Pi statuses retain their existing presentation.

The included platform corrections preserve plugin discovery state at the scan limit, serialize plugin-list subscription snapshots, snapshot published RPC JSON before plugins can mutate it, and keep the installed version when writing configuration fails. Settings saves retain later edits and retries, refresh untouched fields from server answers, and expose a JSON editor for dynamic keys. Plugin rows show failed actions; web and stylesheet failures remain independent. The primary UI-source selector can recover from an off state. Desktop appearance follows the page canvas and can retry a failed background update; SDK builds reject separate worker output. Existing plugin diagnostic exposure and secret-format contracts are unchanged.

Published head 78714f68417 includes a separately committed, reviewed integration of main 2b07556d, retaining both the plugin region/style test and main's stash-chip regression. Original platform authorship and the ancestry-only owner-base merge are preserved.

Scope

This counterpart targets the original feat/plugin-system owner branch; it has not been retargeted. Platform #33606 and the previous upstream PR were closed unmerged by the maintainer because of conflicts, with a request for fresh submissions from current main. This PR remains open. No maintainer feature request or merge approval is claimed. The owner branch and platform PR were not pushed or changed. Tracked in personal-ops #128.

Verification

CI=true VITEST_MAX_WORKERS=1 vp run check:changed 2b07556d719a071390984eeb19347af72f71a565 passed against the final source: 4,096 tests in 155 files, format, lint, knip, GraphQL, unused patches, 42-package typecheck task graph (cached work reused), and React Compiler. The source was tested before the merge commit, so the command selected changes from its then merge-base ddc4f576; it included the merged main changes. The committed tree 5fb2aa24b52b99fea9d666bf7006163e4a11c796 equals that tested freeze exactly; commit hooks passed. New race regressions failed before their fixes. The final settings suites passed 7 focused tests and web typecheck; independent GPT-6.1 Sol/high reviewed the server/integration and original client scopes, then Claude Opus 5.5/high approved the corrected settings retry/invalid-draft scope with no actionable findings.

These are local checks, not fresh GitHub CI results. No checks were configured on the earlier counterpart heads. Native Windows/Linux Electron title-bar evidence is still missing; web proof does not establish shell/IPC behavior. Native iOS/Android status proof is missing, so the status pair remains draft. Platform trust/default-primary loading and public diagnostic exposure still require maintainer decisions. Macroscope's cost limit was not bypassed or retriggered.

Shared Plugins-page proof (isolated web client): the actual pre-fix form and row sources were overlaid onto the candidate for the before capture; this is not a full old-repository build. Disposable plugins and state were used. The labeled GIF alternates actual still states and makes no timing claim.

Before: missing dynamic settings editor and silent reload failure. After: JSON editor and inline reload error

Settings persistence: toggled values survived closing/reopening and matched the authoritative settings file. The GIF is sampled from the actual recording at 10 fps. Controlled regression tests cover slow saves, invalid numeric drafts, retries and refreshed settings; those races were not staged in this real-client pass.

Plugin settings changes retained after closing and reopening Settings

Recovery recordings and capture conditions

Reload failure clears after restoring configuration and retrying

Recover the sole primary environment after seeding its UI preference off

The primary-off state was explicitly seeded; a second live environment was not removed. For simultaneous failures, the fixture web part threw and a browser fetch wrapper rejected only its stylesheet request; restoring the request recovered styles while the web failure remained.

Independent plugin web and stylesheet failures, followed by stylesheet recovery

Settings recording · Action retry recording · Environment recovery recording · Failure recovery recording · Full before PNG · Full after PNG · Capture revisions and limitations

Captures use combined tree 8578edf1eeaeab611d67529fe67a1c06d9620a9e. The final numeric-draft correction and regression test are the only later source changes; they do not change the demonstrated flows. These are not new-head captures.

Before/after, web: the same enabled fixture plugin and thread on the actual platform baseline have no banner; the candidate displays “Machine label · Laptop · build ready” above the composer. Baseline: platform prerequisite plus the test-only CommandPalette correction; candidate capture: cf81e842563. These are earlier captures, retained because the current follow-up changes internal host error structure, CSS ownership and test coverage without changing the demonstrated status subscription, attribution or lifecycle behavior. They are not captures of the new head. The CSS selector compilation and inspected current cascade support the relocation; no new client capture was taken. The alternating GIF is a still-state comparison, 2.5 seconds per state.

Before and after: platform without statuses, then candidate with the attributed status above the composer

Candidate responsive web, captured at 500 CSS pixels, for readable status text in a narrow PR view. This is not native mobile proof.

Candidate responsive web: complete thread and attributed status above the composer

Lifecycle: disable in Plugins settings, return to see the banner cleared, re-enable, return to see it restored, then open a new draft without inherited status. The GIF comes from the actual recording at six frames per second, with operator pauses removed and original speed retained in each segment.

Actual plugin disable and re-enable flow, followed by draft isolation

Edited lifecycle video · Complete real-time lifecycle · Return-navigation recording · Verification conditions and recovery limits

Disposable synthetic project and plugin, isolated server, free Replay conversation, real API/subscription; no mocked client endpoint. CUA used synthetic DOM clicks after trusted input was unavailable, with actual client-state verification after each action. Candidate, baseline and restoration matched all 21 checked source hashes. Native iOS/Android and the Electron shell remain unverified: the device tool could not open the disposable simulator after its advised list refresh; Android Emulator is unavailable. This remains draft for native-client proof.

Created and integrated with Claude Opus 5.5 in Claude Code and GPT-6.1 Sol in Codex through T3 Code. Independent reviews used those actual models at high reasoning.

@ashx-j
ashx-j force-pushed the feat/plugin-system branch from e56923b to 4051d5e Compare November 10, 2026 09:59
@saphid
saphid force-pushed the feat/plugin-thread-status-20261110 branch from 7099a19 to ad771f9 Compare November 10, 2026 10:42
@saphid
saphid force-pushed the feat/plugin-thread-status-20261110 branch 5 times, most recently from 5ca4cbf to 323f696 Compare November 11, 2026 11:24
Jacksondr5 and others added 22 commits November 11, 2026 23:14
…orts (median 4.0× faster with eight running) (pingdotgg#33935)

Co-authored-by: Claude Opus 5.5 <[email protected]>
…ter (median 13,343 ms -> 2,759 ms) (pingdotgg#33937)

Co-authored-by: Claude Opus 5.5 <[email protected]>
juliusmarminge and others added 29 commits November 11, 2026 23:39
Keep plugin-owned failure diagnostics while storing host boundary context separately. Move route visibility styling to SidebarInset and remove the static home-region test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.