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
| Boundary | What it means |
|---|---|
| Extension process | Each 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. |
| Clients | Desktop and browser clients render host-owned surfaces from bounded data. They never download or execute extension code. |
| Language servers | Terminay 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, andTZ, when set on the server.- Each name a session source lists in
environmentVariables, when set on the server. NODE_ENV=productionandTERMINAY_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.
| Need | Use |
|---|---|
| Read an agent's own files | Node filesystem APIs in the extension process. Watch files instead of polling. |
| Decide which terminal a session belongs to | Nothing. Report the session's pid and cwd; Terminay binds it by process ancestry. |
| A token for a forge origin | credentials.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 UI | Nothing. 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 callsdeactivate(). 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.