Sandboxed Automations with Deno
Deno runs each automation as a subprocess, with permissions declared per script. Adds a debugger: breakpoints, stepping, and variable inspection.
Sandboxed Automations with Deno
Deno runs each automation as a subprocess, with permissions declared per script.
Automations
- TypeScript runs directly, with no build step.
- Deno's standard library and
jsr:/npm:imports. ui.notify()shows a notification and writes the same line to the run output.- Automation Runs panel: ⇧⌘U, or the buttons on any
.tstab bar. Copy, Cancel, Clear and Revoke Permissions sit in the panel's own tab bar. - Cancel goes green while a run can be stopped, and shows progress while stopping.
- Running a selection carries the file's imports, so a highlighted statement runs on its own.
tabs.active()opens a browser tab when none is open, instead of failing.
Debugging
- Breakpoints in any
.tsautomation — click the gutter or press F9. They persist across restarts. - Continue, Step Over, Step Into, Step Out — in the tab bar, or F5 / F10 / F11.
- Debug pane in the left dock: call stack, variables, watch expressions, and a console that evaluates in the paused frame.
- Uncaught errors pause where they were thrown.
- Breakpoints move to the line that actually runs; one that cannot be reached greys out.
- Breakpoints inside
tab.evaluate()are refused — that code runs in the browser page. Use adebugger;statement with the browser pane's DevTools.
Security
- Every script declares its permissions. A script with no
// @permissionsline is refused;nonestates that it needs nothing at all. - Nothing is granted implicitly, including the script's own folder. Reading or writing a
file beside the script needs
read=/write=naming it —write=output.md,write=results. A bare.is refused, because path grants are recursive. - Grants:
browser,clipboard,net=,read=,write=,env=,run=,import=. - Driving the browser and reading the clipboard require
browserandclipboard. An ungranted script has no access to them at all. - A script that asks for permissions requires approval the first time it runs, remembered until its grants change.
- Each run is a separate process. A script that hangs or crashes takes down only its own process, and can be cancelled.
- Editor capabilities — tabs, files, UI — arrive over a token-authenticated bridge.
- Scripts cannot write arbitrary app config;
config.get/config.setare scoped totranquil-automations.scriptState.*.
Examples
- The examples are now a separate repo you clone and open as a project — they are no longer installed into your config directory, and File → New Default Window is gone. See Examples.
- Nine runnable examples, one folder each: counting elements, page info, link highlighting, a page banner, reader mode, multi-tab fan-out, a cancellable long run, a full search-to-bookmarks scrape, and a CRUD catalogue that edits its own file across runs.
Browser
- History navigation — ⌘← / ⌘→ (Alt on Windows and Linux).
Fixes
- Running a partial selection reports that the selection is incomplete, instead of failing with a syntax error against a temporary file. The Runs panel now also labels selection runs, so an accidental one is obvious.
- Opening a window with a browser tab no longer opens DevTools by itself.
- Toggling the Automation Runs panel closes the panel rather than the whole bottom dock.
- The Debug pane's Variables list leads with your own values; imports sink to the bottom and not-yet-reached declarations are dimmed.
- The Automation Runs panel selects the newest run when one starts.
- Runs interrupted by closing a window are marked cancelled.
- Themed scrollbars in the Automation Runs and Debug panels.
What's removed
There is no compatibility shim; existing scripts need porting.
.jsautomations are no longer run. Rename to.tsand import fromtranquil/automation.- Running without declared permissions. Add
// @permissions …to the leading comment block; scripts that drive the browser needbrowser. - The in-editor runner that executed script text with injected
require,atom,__dirnameand__filenameglobals. tranquil.exec.ui.status()—ui.notify()does both now.- The bundled sample project and its first-run seeding, along with File → New Default Window. Clone tranquil-examples instead.
- puppeteer-core. Browser control is
tab.goto(),tab.evaluate(),tab.waitFor(),tab.screenshot()andtab.waitForNavigation().
Known limitations
Native builds and the in-app updater remain in private beta. Debugging covers automations running in Deno; code executing inside a web page is not covered.
Found a bug? File it on GitHub.