Repository navigation
feat(server,web,mobile): let plugins show statuses on threads #16061
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
saphid
wants to merge
93
commits into
pingdotgg:main
Choose a base branch
from
saphid:stack/19-plugin-status
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+42,395
−1,455
Open
Changes from all commits
Commits
Show all changes
93 commits
Select commit
Hold shift + click to select a range
920770b
refactor(web): register the Diff side panel
saphid e1ae808
refactor(web): register the Preview side panel
github-actions[bot] 4851ae8
perf(web): keep the panel host stable across chat view renders
github-actions[bot] 30972c6
fix(web): send a late annotation only to the thread it was picked in
github-actions[bot] 52a78e7
fix(web): lend the annotation sender only after the chat view commits
github-actions[bot] 7be7fb5
refactor(web): move the thread terminal panel and drawer out of ChatView
github-actions[bot] a0ea164
refactor(web): open the right-panel terminal through the panel host
github-actions[bot] 02d7fe8
fix(web): keep a local-checkout terminal launch off the thread's work…
github-actions[bot] ca03345
fix(web): keep a terminal the server opened on the checkout off the t…
github-actions[bot] 4b7aa2e
fix(web): keep device results in the thread that started them
github-actions[bot] a1d256b
refactor(web): open the Device side panel through the panel host
github-actions[bot] bcb7b41
refactor(web): open the pull request side panels through the panel host
github-actions[bot] cfd56f6
test(web): build the pull request panel fixture against current main
github-actions[bot] 4a90882
refactor(web): open the Files side panel through the panel host
github-actions[bot] 3fe8920
test(web): stub the server environment atoms in the Files panel test
github-actions[bot] 8cf75b7
fix(web): drop Files actions that settle after leaving the thread
github-actions[bot] 4f15c62
fix(web): open tree clicks in the thread the Files panel shows now
github-actions[bot] 0e86f37
fix(web): keep a Files browser open across composer draft switches
github-actions[bot] 419306d
fix(web): point tree clicks at the new thread as soon as it commits
github-actions[bot] 3b7aa41
feat(pi): show extension statuses in the thread header
github-actions[bot] 083f6ab
fix(pi): keep statuses when Pi refuses a rollback fork
github-actions[bot] e8f8f57
fix(pi): carry each status generation's thread on its marker
github-actions[bot] b08374b
feat(mobile): show Pi extension statuses under the thread header
github-actions[bot] 20b745e
feat(server): run consented local plugins in supervised child processes
github-actions[bot] c4da6af
fix(server): answer every plugin result with a message the server can…
github-actions[bot] a3ca98c
fix(server): drop what a plugin registered before its activation failed
github-actions[bot] 1829ea3
fix(server): exit a plugin child on a corrupt IPC line and cover its …
github-actions[bot] c59bd7e
fix(server): hold a plugin's partial IPC line in one growing buffer
github-actions[bot] d563b47
fix(server): hold plugin calls made during startup until enabled plug…
github-actions[bot] 5b1946f
fix(server): count a plugin IPC line's newline against the read budget
github-actions[bot] d11ac2c
fix(server): restore enabled plugins before any management step at st…
github-actions[bot] 9ffc0ea
fix(server): let calls waiting on a plugin start hear how it ended
github-actions[bot] 7c900a8
fix(server): refuse a plugin file swapped for a FIFO while digesting
github-actions[bot] 4122e0d
chore(server): say why plugin host modules import Node builtins
github-actions[bot] 04704fb
fix(server): answer a plugin call cancelled before its handler started
github-actions[bot] 7a956a0
test(server): start the cooperative handler before timing it out
github-actions[bot] 8c823b3
fix(server): close a dead plugin's stderr that a process it started h…
github-actions[bot] 914b34e
refactor(server): build the plugin RPC handlers in their own layer
github-actions[bot] 14d57ad
test(server): answer a replayed request only once its card is projected
github-actions[bot] 5da52d5
feat(server): deliver finished runs to plugins from an acknowledged c…
github-actions[bot] 1a02508
fix(server): let a run's queued checkpoint capture decide its finaliz…
github-actions[bot] b82a25b
fix(server): refuse the events capability without the proposed API op…
github-actions[bot] 2e20f0a
fix(server): drop a plugin's event handlers when its activation fails
github-actions[bot] 6f11331
test(server): cover finalization of a run stopped through the ownersh…
github-actions[bot] 0e827f1
fix(server): stop a cancelled setup's branch rename before forgetting…
github-actions[bot] ff5dbc8
feat(server): let agents list and call plugin tools through MCP
github-actions[bot] ab90f2f
fix(server): list no plugins to MCP callers outside a T3 thread
github-actions[bot] 3c780d4
fix(server): drop a reused credential's reservation when its grant up…
github-actions[bot] 1561cf5
docs(plugins): say plugins run under the server's account
github-actions[bot] 1fcbcb2
fix(server): drop a reused credential's reservation when its reuse ch…
github-actions[bot] f1844a2
feat(server): typed plugin settings, write-only secrets and plugin st…
github-actions[bot] 428902e
docs(plugins): say plugins run under the server's account
github-actions[bot] 5605a8b
fix(server): refresh open plugin settings when the declared fields ch…
github-actions[bot] a2a5171
fix(server): finish a plugin's host work before disable returns
github-actions[bot] a4e2d88
fix(server): wake host calls waiting on a plugin below the stream buffer
github-actions[bot] 15a8bcf
feat: offer plugin actions in the palette, slash menu and thread menus
github-actions[bot] d7988f8
fix(contracts): keep a plugin action when only its placement is unknown
github-actions[bot] 265b135
fix: match plugin action names in the slash menu regardless of case
github-actions[bot] 52be65f
docs(plugins): say the slash menu opens only at the start of a line
github-actions[bot] 3b4ca09
fix(web,mobile): offer plugin actions only to connections that can ru…
github-actions[bot] 5cd5113
test(web): stub plugin actions in the thread action menu hook test
github-actions[bot] 545cbfe
fix(web,mobile): check the live permission when a plugin action runs
github-actions[bot] 7de52de
docs(plugins): say plugins run under the server's account
github-actions[bot] e982989
fix(mobile): offer environment plugin actions in the palette without …
github-actions[bot] 4c6cd43
test(web): pass the active project to the plugin actions composer fix…
github-actions[bot] c5b6a68
feat: show plugin views as isolated right-panel tabs on web and desktop
github-actions[bot] 4b74d88
fix: keep plugin view rate limits and navigation logs safe
github-actions[bot] 2fa3277
fix(server): refuse the views capability without the proposed API opt-in
github-actions[bot] 667d8f4
fix(web): keep the side-panel plugin view list stable across renders
github-actions[bot] 950642c
fix(server): type WebSocket handlers against the uninstrumented RPC g…
github-actions[bot] 97acb8c
fix(server): serve plugin view files whose names start with two dots
github-actions[bot] 8995989
fix(server): serve only plugin view bytes the approval digest covered
github-actions[bot] d42fae0
feat(server): install plugins from npm with integrity checks and stag…
github-actions[bot] dc7d7b1
fix(server): accept plain http npm registries only on this machine
github-actions[bot] beb9d20
fix(server): hold npm registry redirects and saved registries to the …
github-actions[bot] 846d385
fix(server): read npm tarball headers the way tar writers mean them
github-actions[bot] 095c1cf
fix(server): list a staged npm update's tools, settings, and actions
github-actions[bot] 9b0aab8
fix(server): size the npm unpack cap by archive entries, not files
github-actions[bot] 22014bc
fix(server): refuse a pax record that does not end in a newline
github-actions[bot] 232bcca
refactor(server): follow the Effect service rules in npm plugin installs
github-actions[bot] 9a29542
fix(server): size a GNU long name by its own header in npm tarballs
github-actions[bot] 574e4ca
fix(server): refuse npm tarball paths with a NUL byte
github-actions[bot] 1308f78
fix(server): report an applied npm update whose plugin could not be e…
github-actions[bot] 65966f6
fix(server): refuse an npm update to the files already installed
github-actions[bot] b09b51b
feat(web,mobile): manage plugins in Settings
github-actions[bot] ab5a245
docs(plugins): say plugins run under the server's account
github-actions[bot] 9f62660
fix(mobile): ask to select an environment when none is selected for p…
github-actions[bot] 61a2196
feat(web,mobile): fill in plugin settings from Settings
github-actions[bot] a0ebe84
feat(web,mobile): install and update plugins from npm in Settings
github-actions[bot] 2bbd01c
fix(client-runtime): show a downloaded same-version plugin update in …
github-actions[bot] 32eb7b0
feat(web,mobile): show what each plugin adds and what its capabilitie…
github-actions[bot] e21d19f
feat(server,web,mobile): let plugins show statuses on threads
github-actions[bot] bf6d3f0
fix(server): tell a plugin when the thread has no room for its status
github-actions[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| import { describe, expect, it } from "vite-plus/test"; | ||
|
|
||
| import { type NavigationFrame, shouldVetoViewFrameNavigation } from "./pluginViewNavigation.ts"; | ||
|
|
||
| const frame = ( | ||
| frameToken: string, | ||
| url: string, | ||
| origin: string, | ||
| parent: NavigationFrame | null, | ||
| ): NavigationFrame => ({ frameToken, url, origin, parent }); | ||
|
|
||
| const app = frame("app", "t3code-dev://app/", "t3code-dev://app", null); | ||
| const view = frame("view", "about:srcdoc", "null", app); | ||
| const wrapper = frame("wrapper", "about:srcdoc", "null", app); | ||
| const wrappedView = frame("inner", "about:srcdoc", "null", wrapper); | ||
|
|
||
| describe("shouldVetoViewFrameNavigation", () => { | ||
| it("refuses a view navigating itself, including through a policy wrapper", () => { | ||
| for (const target of [view, wrappedView]) { | ||
| for (const url of ["about:blank", "http://127.0.0.1:7391/page.html", "data:text/html,x"]) { | ||
| expect( | ||
| shouldVetoViewFrameNavigation({ url, frame: target, initiator: target, mainFrame: app }), | ||
| ).toBe(true); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| it("refuses a navigation with no known initiator", () => { | ||
| expect( | ||
| shouldVetoViewFrameNavigation({ | ||
| url: "http://127.0.0.1:7391/redirect", | ||
| frame: view, | ||
| initiator: null, | ||
| mainFrame: app, | ||
| }), | ||
| ).toBe(true); | ||
| }); | ||
|
|
||
| it("lets the app mount, wrap and dispose views", () => { | ||
| const fresh = frame("fresh", "about:blank", "t3code-dev://app", app); | ||
| expect( | ||
| shouldVetoViewFrameNavigation({ | ||
| url: "about:srcdoc", | ||
| frame: fresh, | ||
| initiator: app, | ||
| mainFrame: app, | ||
| }), | ||
| ).toBe(false); | ||
| const freshInner = frame("fresh-inner", "about:blank", "null", wrapper); | ||
| expect( | ||
| shouldVetoViewFrameNavigation({ | ||
| url: "about:srcdoc", | ||
| frame: freshInner, | ||
| initiator: wrapper, | ||
| mainFrame: app, | ||
| }), | ||
| ).toBe(false); | ||
| expect( | ||
| shouldVetoViewFrameNavigation({ | ||
| url: "about:blank", | ||
| frame: view, | ||
| initiator: app, | ||
| mainFrame: app, | ||
| }), | ||
| ).toBe(false); | ||
| }); | ||
|
|
||
| it("leaves frames outside views alone", () => { | ||
| const other = frame("other", "https://example.com/", "https://example.com", app); | ||
| expect( | ||
| shouldVetoViewFrameNavigation({ | ||
| url: "https://example.com/next", | ||
| frame: other, | ||
| initiator: other, | ||
| mainFrame: app, | ||
| }), | ||
| ).toBe(false); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /** | ||
| * Main-process navigation veto for isolated plugin view frames. | ||
| * | ||
| * A plugin view runs in an opaque-origin `about:srcdoc` frame inside a | ||
| * policy wrapper frame of the same kind. A document's own CSP cannot stop its | ||
| * frame navigating, so the main process refuses any navigation of a frame in | ||
| * such a subtree unless the app's main frame started it. Loading | ||
| * `about:srcdoc` stays allowed so the wrapper can mount its view. Electron | ||
| * does not report `about:blank` or `data:` here: the wrapper's CSP refuses | ||
| * `data:`, and the host's ping liveness check ends a view that blanked itself. | ||
| */ | ||
|
|
||
| export interface NavigationFrame { | ||
| readonly url: string; | ||
| readonly origin: string; | ||
| readonly frameToken: string; | ||
| readonly parent: NavigationFrame | null; | ||
| } | ||
|
|
||
| const isViewDocument = (frame: NavigationFrame) => | ||
| frame.url === "about:srcdoc" && frame.origin === "null"; | ||
|
|
||
| export function shouldVetoViewFrameNavigation(input: { | ||
| readonly url: string; | ||
| readonly frame: NavigationFrame | null; | ||
| readonly initiator: NavigationFrame | null | undefined; | ||
| readonly mainFrame: NavigationFrame; | ||
| }): boolean { | ||
| let insideView = false; | ||
| for (let frame = input.frame; frame !== null; frame = frame.parent) { | ||
| if (isViewDocument(frame)) insideView = true; | ||
| } | ||
| if (!insideView || input.url === "about:srcdoc") return false; | ||
| return input.initiator?.frameToken !== input.mainFrame.frameToken; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.