feat(templating): (A1) route user-plugin actions through the sandbox#10293
Open
jackkav wants to merge 3 commits into
Open
feat(templating): (A1) route user-plugin actions through the sandbox#10293jackkav wants to merge 3 commits into
jackkav wants to merge 3 commits into
Conversation
✅ Circular References ReportGenerated at: 2026-07-24T18:24:25.545Z Summary
Click to view all circular references in PR (9)Click to view all circular references in base branch (9)Analysis✅ No Change: This PR does not introduce or remove any circular references. This report was generated automatically by comparing against the |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new sandbox execution path for user-plugin actions (request/requestGroup/workspace/document), routing them through the existing QuickJS templating sandbox when templateTagSandboxEnabled is enabled, and exposing a new host protocol endpoint to invoke these actions from the plugin window.
Changes:
- Extends the sandbox envelope and bootstrap to support
__invokeAction()and anACTION_RUNNER, selecting kind-specific action lists by label and executing actions as fire-and-effect (no marshaled return). - Adds a main-process
plugin.runUserActiontemplating-worker-database handler that resolves a trusted plugin install before dispatchingrunActionInSandbox(). - Updates the plugin-window
executeActionpath to route user plugins through the sandbox when the flag is enabled, while keeping bundle plugins and flag-off behavior in-process; adds unit + smoke coverage.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/insomnia/src/templating/sandbox/sandbox-surface.ts | Adds __invokeAction to the sandbox-internal globals allowlist. |
| packages/insomnia/src/templating/sandbox/sandbox-actions.test.ts | New unit tests validating label matching, domain data passthrough, and capability gating for sandboxed actions. |
| packages/insomnia/src/templating/sandbox/plugin-tag-sandbox.ts | Selects the new ACTION_RUNNER when actionKind is present in the envelope. |
| packages/insomnia/src/templating/sandbox/marshal.ts | Extends ContextEnvelope with actionKind, actionLabel, and actionDomainData. |
| packages/insomnia/src/templating/sandbox/in-sandbox-bootstrap.ts | Implements globalThis.__invokeAction, locks it down, and adds ACTION_RUNNER. |
| packages/insomnia/src/templating/sandbox/snapshots/sandbox-surface.test.ts.snap | Updates sandbox surface snapshot to include __invokeAction. |
| packages/insomnia/src/plugins/invoke-method.ts | Routes user-plugin executeAction through plugin.runUserAction when sandbox is enabled. |
| packages/insomnia/src/main/templating-worker-database.ts | Adds runActionInSandbox() and registers plugin.runUserAction handler with trusted-plugin resolution. |
| packages/insomnia/src/common/templating/types.ts | Extends PluginToMainAPIPaths with plugin.runUserAction. |
| packages/insomnia-smoke-test/tests/smoke/sandbox-template-tags.test.ts | Adds E2E proving action routing switches between in-process vs sandbox via a storage canary. |
| packages/insomnia-smoke-test/fixtures/sandbox-action-collection.yaml | Adds a fixture collection used by the new E2E test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Adds the sandbox core for routing user-plugin actions (request/requestGroup/ workspace/document) through the QuickJS sandbox, mirroring the H1 hook path. - marshal.ts: envelope gains actionKind/actionLabel/actionDomainData. An action is fire-and-effect — it reads the copied-in domain models and performs side effects only through the capability-gated context.* bridge; nothing marshals back. - in-sandbox-bootstrap.ts: __invokeAction() rebuilds context via __buildContext, resolves the kind-specific action list, finds the entry by label, and calls action(context, actionDomainData); ACTION_RUNNER drives it. Locked alongside the other internals. - plugin-tag-sandbox.ts: runner selection picks ACTION_RUNNER when actionKind is set. - sandbox-surface.ts + snapshot: __invokeAction added to the reviewed internal set. - sandbox-actions.test.ts: label match + domainData passthrough, capability gating (ungranted context.network absent), missing-label error, kind-specific list. Host wiring (plugin.runUserAction handler, invoke-method routing, e2e) follows.
Host + plugin-window wiring for the in-sandbox action API. - templating-worker-database.ts: runActionInSandbox() mirrors runRequestHookInSandbox (same bridge/grants/crypto), building an action envelope; nothing is marshaled back. New protocol handler plugin.runUserAction resolves the plugin via resolveTrustedPlugin (registry-trusted directory + permissions, not caller-supplied) before dispatch. - types.ts: PluginToMainAPIPaths gains 'plugin.runUserAction'. - invoke-method.ts (plugin window): executeAction routes user plugins (directory !== '') through plugin.runUserAction when the sandbox is enabled; bundle plugins and the flag-off path stay in-process. Tag actions (templateTag.actions) are unchanged — the L1 manifest does not discover them, so they remain a flag-off surface. Actions are UI-triggered only, so there is no node-runtime/inso path to gate.
…andbox A request action writes a path canary (INSOMNIA_TEMPLATE_SANDBOX) plus whether it received the domain models into plugin storage; a sibling template tag reads it back (actions are fire-and-effect, so the canary rides the side effect). Flag off → the action runs in-process; flag on → the same action runs in the sandbox (its in-process fn is a throw-stub after discovery, so a successful write proves routing) and the domain models still reach it. Asserts on unique canary values, not header names.
jackkav
force-pushed
the
claude/sandbox-pr11-actions
branch
from
July 24, 2026 18:18
e50adfe to
ce0483a
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
A1 — Plugin actions via the sandbox
Fourth ticket of Phase 2. Routes user-plugin actions (request / requestGroup / workspace / document) through the QuickJS sandbox, mirroring the H1 hook path (PR 10a/10b). Gated on the existing
templateTagSandboxEnabledflag.What changes
marshal.ts,in-sandbox-bootstrap.ts,plugin-tag-sandbox.ts): the envelope gainsactionKind/actionLabel/actionDomainData.__invokeAction()rebuilds the capability-gated context, resolves the kind-specific action list, finds the entry by label, and callsaction(context, actionDomainData). Actions are fire-and-effect — they read the copied-in domain models and act only through the gatedcontext.*bridge, so nothing is marshaled back.ACTION_RUNNERdrives it;__invokeActionis added to the reviewed sandbox-internal global set + surface snapshot.templating-worker-database.ts):runActionInSandbox()mirrorsrunRequestHookInSandbox(same bridge / grants / crypto). New protocol handlerplugin.runUserActionresolves the plugin viaresolveTrustedPlugin(registry-trusted directory + permissions — never caller-supplied) before dispatch.invoke-method.ts):executeActionroutes user plugins (directory !== '') throughplugin.runUserActionwhen the sandbox is on; bundle plugins and the flag-off path stay in-process. Actions are UI-triggered only, so there is no node-runtime / inso path to gate.Scope notes
templateTag.actions[]) are unchanged — the L1 manifest does not discover them, so they remain a flag-off surface (pre-existing).context.datais still not rebuilt in-sandbox (import/export actions that need it) — tracked follow-up, same as the hook PRs.Tests
sandbox-actions.test.ts): label match + domain-model passthrough, capability gating (ungrantedcontext.networkabsent), missing-label error, kind-specific list resolution.sandbox-template-tags.test.ts+sandbox-action-collection.yaml): a request action writes a path canary (INSOMNIA_TEMPLATE_SANDBOX) + whether it received the domain models into plugin storage; a sibling tag reads it back. Flag off → runs in-process; flag on → the same action runs in the sandbox (its in-process fn is a throw-stub after discovery, so a successful write proves routing).Validation
type-checkclean;eslintclean; full sandbox unit suite green (157). E2E runs in CI.Stacked draft — part of the plugin-sandbox plan.