v0.2.0 2026-08-17

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 .ts tab 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 .ts automation — 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 a debugger; statement with the browser pane's DevTools.

Security

  • Every script declares its permissions. A script with no // @permissions line is refused; none states 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 browser and clipboard. 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.set are scoped to tranquil-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.

  • .js automations are no longer run. Rename to .ts and import from tranquil/automation.
  • Running without declared permissions. Add // @permissions … to the leading comment block; scripts that drive the browser need browser.
  • The in-editor runner that executed script text with injected require, atom, __dirname and __filename globals.
  • 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() and tab.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.