Package and install
A Terminay extension is one ordinary npm package. Its manifest belongs in the
terminay object of package.json, and it installs from public npm or
from an npm pack tarball.
Prepare the package
Publish compiled ESM, not TypeScript source. The package needs a name, a
version, and an exports map that includes the manifest's
entrypoint as ./<entrypoint>.
{
"name": "@acme/terminay-typescript",
"version": "1.0.0",
"type": "module",
"exports": { ".": "./dist/index.js" },
"files": ["dist"],
"peerDependencies": { "@terminay/extension-api": "^3.0.0" },
"devDependencies": { "@terminay/extension-api": "^3.0.0" },
"terminay": {
"manifestVersion": 1,
"id": "com.acme.language.typescript",
"displayName": "Acme TypeScript",
"api": "^3.0.0",
"engines": { "terminay": ">=1.0.0", "node": ">=22" },
"entrypoint": "dist/index.js",
"permissions": [],
"contributes": {
"languageServers": [{
"id": "typescript",
"displayName": "TypeScript",
"languageIds": ["typescript", "typescriptreact"],
"fileExtensions": [".ts", ".tsx"]
}]
}
}
}
Depend on @terminay/extension-api as a peer and development dependency, as the
bundled extensions do. Never import private Terminay packages.
Validate and pack
npm run build
npx terminay-extension-conformance package.json
npm pack --dry-run
npm pack
# acme-terminay-typescript-1.0.0.tgz terminay-extension-conformance ships with @terminay/extension-api.
It validates the manifest and checks that the entrypoint is exported, printing each issue
with its path and code. Check the dry run too: the archive must contain the entrypoint.
Install
Open Settings → Extensions for the server that should run the extension. Extensions are installed server-wide, and the section manages the selected server.
| Section | What it does |
|---|---|
| Install from npm | Takes a public npm package name and an optional version, range, or tag. Terminay resolves it once, shows the exact version, and records only that version and its registry integrity. It never follows latest or updates automatically. |
| Install package file | Uploads one npm pack gzip tarball of at most 12 MiB to the selected server. The client sends bytes, never a local path. |
- Choose Preview or Choose package file….
- Review the exact package and version, integrity, permissions, dependencies, and the trusted-code warning.
- Confirm. Terminay materializes the package, probes it in a fresh extension host, activates it, and records the exact artifact.
A preview is bound to the exact archive digest and expires after ten minutes, or when the server restarts. An uploaded package is labelled Uploaded package · Unverified.
What the installer accepts
| Accepted | Rejected |
|---|---|
| Dependencies resolved from public npmjs with registry integrity. Only the uploaded root package may resolve from the upload. | Git, HTTP, alias, file, link, workspace, and alternative-registry dependency specifications. |
| Production and optional dependencies. Development dependencies are omitted. | Symbolic links, non-regular files, and paths that escape the package. |
Prebuilt native .node modules shipped inside a package. | Trees containing binding.gyp, and packages that need a preinstall, install, or postinstall script to work. |
| Up to 20,000 files and 256 MiB installed. | Anything larger. |
npm runs with lifecycle scripts and binary links disabled, against a Terminay-owned
configuration fixed to the public registry. It does not read the user's .npmrc
or tokens. A prebuilt native module must load under the server's Node runtime without a
build step; one that does not fails the activation probe.
Update, roll back, and remove
- An update installs side by side into a new slot and needs fresh confirmation when it adds permissions.
- A failed install, update, or activation leaves the previous active version in place.
- Terminay keeps a known-good slot, so Rollback can reselect it.
- Disable keeps the extension's data. Uninstall is blocked while the extension is enabled or required by another extension.
- A bundled extension can be disabled or superseded, but not removed.