Rules scripts¶
A rules script is a JavaScript file with functions Quena calls for every request and response. Use it for anything Mock Rules cannot express: rewrite headers, answer or redirect requests by your own logic, colour and comment sessions, add a custom column or your own commands to the context menu.

The editor¶
Open Capture → Rules Script… (Ctrl/⌘ R).
- Enable rules script switches the script on or off; the state next to it says loaded, not loaded or error.
- Edit the script and press Save & Reload (
Ctrl/⌘ S). The script is reloaded instantly; compile errors appear above the editor. - API reference shows the complete type definitions next to the editor. The editor also uses them for completion.
- Revert discards unsaved changes.
- The Console at the bottom shows the script's
console.log()output; Clear empties it.
The script is saved as rules.js in the data directory;
whether it is enabled is remembered across restarts.
Hooks¶
Define any of these top-level functions — each is optional:
function onBoot() {} // once, when the script loads
function onBeforeRequest(session) {} // before a request is forwarded
function onBeforeResponse(session) {} // before a response returns to the client
function onSessionComplete(summary) {} // after a session finished (id, method, url, status)
The session object¶
| Member | Phase | Meaning |
|---|---|---|
id, process, clientIp, phase |
both | read-only information |
url |
both | full URL; assign in the request phase to send the request elsewhere |
method, host, path, requestHeaders |
request | the request |
status, reason, responseHeaders |
response | the response |
comment(text) |
both | set the comment (Comments column) |
color(name) |
both | mark the row: red, blue, gold, green, orange, purple |
custom(value) |
both | value for the Custom column |
flag(key, value) |
both | attach a session flag |
redirect(url) |
request | send the request to another URL |
abort() |
both | drop the connection / cut the response |
respond(status, body, headers) |
request | answer locally without contacting the server |
Headers are ordered and case-insensitive: get, getAll, has, set (replaces
duplicates), add, remove, names, toArray. comment, color, custom and flag
return the session, so they can be chained.
Custom column and menu commands¶
In onBoot, the Quena object extends the UI:
Quena.registerColumn(title, fn?)— defines the Custom column (show it by right-clicking the column headings). Its value comes fromsession.custom()or fromfn(session)at response time.Quena.registerMenu(label, handler)— adds a command to the session context menu under Scripts. The handler gets the selected sessions (id,method,url,status,host,process,comment,contentType) and may return updates{ id, comment?, color?, custom? }to apply.
Example¶
function onBoot() {
// A "Custom" column filled from each response
Quena.registerColumn('Server', s => s.responseHeaders.get('Server') || '');
// A command in the session context menu (right click → Scripts)
Quena.registerMenu('Tag as reviewed', sessions =>
sessions.map(s => ({ id: s.id, comment: 'reviewed', color: 'green' })));
}
function onBeforeRequest(s) {
s.requestHeaders.set('X-Debug-Trace', 'quena-' + s.id);
if (s.host === 'ads.example.com') s.abort();
if (s.path === '/api/feature-flags') s.respond(200, '{"newCheckout":true}',
{ 'Content-Type': 'application/json' });
}
function onBeforeResponse(s) {
if (s.status >= 500) s.color('red').comment('server error');
s.responseHeaders.remove('Strict-Transport-Security');
}
Limits¶
Scripts are sandboxed (QuickJS) and cannot slow the proxy down:
- no file-system, network or environment access — only
consoleand the session; - headers and metadata only: bodies never enter the script and keep streaming, so enabling a script never turns a 5 GB download into a 5 GB buffer;
- a time budget of 250 ms per hook (2 s for loading and
onBoot) and 64 MB of memory; an endless loop is interrupted; - a request waits at most 2 s for its hook. After that it passes through unchanged and the late hook is skipped — a slow script degrades to "no rules" instead of stalling traffic.
The full API is in
quena.d.ts.