Runtime and security

An extension runs on the selected Terminay Server, never in the Desktop or browser client. Treat a third-party extension as trusted server-side Node.js code.

Where code runs

BoundaryWhat it means
Extension processEach enabled extension has its own child process under the server's bundled Node runtime, a private IPC channel, and its immutable package directory as the working directory.
ClientsDesktop and browser clients render host-owned surfaces from bounded data. They never download or execute extension code.
Language serversTerminay spawns a contributed language server as a child of the extension process, with the project root as its working directory.

Process isolation contains crashes and keeps extension IPC separate. It is not an operating-system sandbox: extension code can use public Node APIs with the selected server account's authority. Review and install it accordingly.

Process environment

The extension process does not inherit the server's environment. It receives:

  • PATH, HOME, USER, LOGNAME, TMPDIR, TMP, TEMP, LANG, LC_ALL, LC_CTYPE, and TZ, when set on the server.
  • Each name a session source lists in environmentVariables, when set on the server.
  • NODE_ENV=production and TERMINAY_EXTENSION_HOST=1.

Standard input, output, and error are not connected, so console output is discarded. Report problems by throwing, or through the diagnostic method of the publisher you were given.

Use the public boundary

The host provides typed registrations, publishers, cancellation signals, and deadlines. It does not expose raw PTYs, terminal output, client transports, Electron, host bridges, private Terminay packages, or direct mutation of Terminay's stores.

NeedUse
Read an agent's own filesNode filesystem APIs in the extension process. Watch files instead of polling.
Decide which terminal a session belongs toNothing. Report the session's pid and cwd; Terminay binds it by process ancestry.
A token for a forge origincredentials.token(origin) on a worktree insight source, after publisher.requestSignIn(). Terminay owns the prompt and stores the token in the server vault.
Draw status in the UINothing. Publish typed facts; Terminay renders them.

Lifecycle behaviour

  • Activation must finish within 15 seconds. An activation failure is shown as a failure, not as a running extension.
  • Disabling, updating, or shutting down aborts every start signal, disposes context.subscriptions, and calls deactivate(). A child that does not respond within 5 seconds is terminated.
  • A crash marks only that extension unavailable. It does not take down Terminay or other extensions.
  • A crashed host is restarted automatically after a backoff that grows with consecutive failures, up to 30 seconds.
  • Five failures within 60 seconds quarantine the extension. Automatic restarts stop until someone chooses Restart in Settings → Extensions, which clears the quarantine.
  • An unexpected exit of a contributed language server counts once against the same crash window.

Host diagnostics

Terminay records every extension host transition: spawned, ready, child exited (with exit code or signal), failed, restart scheduled, restart attempted, quarantined, quarantine cleared, and stopped. Each record carries the extension ID and, where relevant, the consecutive failure count and the scheduled restart time.

When the extension process fails with an uncaught exception or unhandled rejection, the record carries the error's name, message, and stack as reported, without redaction. On Terminay Desktop these records go to the local diagnostic history, which is never uploaded automatically. Keep credentials and conversation content out of error messages.