* feat(templating): (H1) in-sandbox response-hook API + marshaling
First increment of PR 10b (response hooks). Adds the sandbox-side machinery to
run a user plugin's response hook, without yet wiring the network adapters:
- __buildResponseApi(resp): faithful ES5 rebuild of plugins/context/response.ts
getters (status/headers/time, case-insensitive getHeader returning
string|string[]|null). getBody() bridges to the existing response.getBodyBuffer
path; getBodyStream() throws (a Node Readable can't cross the sandbox); setBody()
base64-encodes the bytes over a new response.setBody bridge path (no fs in the
sandbox) and updates bytesContent locally.
- __invokeHook: for response hooks, attaches context.response and a READ-ONLY
context.request (matches pluginRequest.init(..., true)), and marshals both the
request and response back out.
- host-bridge: response.setBody mapped at baseline (models.read, grouped with the
other response ops) — a bounded write to the host-set bodyPath, matching the
ungated in-process behavior; not a general fs write.
Unit test drives a response hook that reads status/headers, reads the body via
the bridge, and rewrites it via setBody (asserting the base64 round-trip and the
read-only request). Host runner + adapter integration + e2e are the next increment.
* feat(templating): (H1) route user-plugin response hooks through the sandbox
Wires the response-hook sandbox core into both hook paths so a user plugin's
response hook runs in QuickJS (bundle plugins and the flag-off path unchanged).
- templating-worker-database: runResponseHookInSandbox + the
plugin.runUserResponseHook handler; the response.setBody bridge handler
(base64-decode -> fs.writeFileSync) guarded to the responses directory as
defense in depth (bodyPath is host-set); pickHookResponseFields.
- network-adapter.node.ts (main/CLI): runs the response hook in the sandbox for
user plugins, merging the returned response fields onto newResponse.
- invoke-method.ts (plugin window): reaches the same runner over the protocol.
E2E: a user plugin response hook rewrites the body via setBody; the echo
response pane shows the rewrite. Flag off it reports ranin-mainprocess (control),
flag on ranin-sandboxed. Completes H1 (request hooks in PR 10a).
* fix(templating): (H1) revive bridged Buffer in response getBody + reject empty setBody
Addresses Copilot review on #10286:
- in-sandbox-bootstrap.ts: context.response.getBody() now revives the JSON-marshaled
Buffer shape ({ type: 'Buffer', data: [...] }) back into a (shimmed) Buffer, so hooks
consume it exactly like the in-process response API instead of a plain object.
- templating-worker-database.ts: response.setBody rejects a missing/non-string bodyBase64
(TypeError) instead of defaulting to '' — a write primitive must not silently truncate
the body to zero bytes. An empty string stays a valid empty body.
- sandbox-hooks.test.ts: the getBodyBuffer stub now returns the real marshaled Buffer
shape and the hook decodes with toString('utf8'), exercising the revive end-to-end.
Move insomnia-data models, services, database code, and common utilities into a dedicated workspace package. Update consumers to import from the new package entrypoints and declare workspace dependencies for the extracted package.