mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
feat: make each plugin an npm workspace built by a termix-plugin CLI
This commit is contained in:
1 parent
4758016f41
commit
5796186a1c
448 files changed
+3087
-2003
No files matched your search
@@ -0,0 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## 1.0.0
|
||||
|
||||
Bundled with Termix 2.9.0.
|
||||
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* SSH Terminal - first-party, in-process plugin.
|
||||
*
|
||||
* This plugin runs on the main thread rather than in a worker, because it IS
|
||||
* the SSH transport rather than a consumer of one: it owns a WebSocket server
|
||||
* and long-lived ssh2 clients, and neither a live socket nor an ssh2 Client can
|
||||
* cross the structured-clone postMessage boundary a worker plugin talks over.
|
||||
* See src/backend/plugins/first-party.ts for why that tier is a hardcoded
|
||||
* allowlist and not something a manifest can ask for.
|
||||
*
|
||||
* The terminal's implementation stays in core (src/backend/hosts/terminal/)
|
||||
* rather than being copied in here. Two reasons:
|
||||
* - session-manager has six consumers outside the terminal (terminal routes,
|
||||
* open-tabs, user-image-storage, collab, and session-sharing twice), so it
|
||||
* is shared infrastructure, not plugin-private code.
|
||||
* - the terminal needs plaintext host credentials to connect, which ctx.hosts
|
||||
* deliberately never returns (PluginHostView is a 13-field allowlist that
|
||||
* excludes password, key and passphrase).
|
||||
*
|
||||
* What this plugin owns is the lifecycle: enabling it starts the WS server,
|
||||
* disabling it closes live sessions and frees the port.
|
||||
*/
|
||||
|
||||
import { createRequire } from "node:module";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
/**
|
||||
* Resolves the compiled core terminal module.
|
||||
*
|
||||
* The plugin ships beside dist/backend, so in a built server the module is at
|
||||
* dist/backend/backend/hosts/terminal/index.js. Under vitest and dev the
|
||||
* plugin is loaded from the repo instead, where the source .ts is the thing
|
||||
* that exists and tsx is already handling it.
|
||||
*/
|
||||
async function loadTerminalModule() {
|
||||
const here = path.dirname(fileURLToPath(import.meta.url));
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
const candidates = [
|
||||
// Built: plugins/ssh-terminal/backend -> dist/backend/backend/...
|
||||
path.resolve(here, "../../../backend/backend/hosts/terminal/index.js"),
|
||||
// Repo layout, compiled output present.
|
||||
path.resolve(here, "../../../dist/backend/backend/hosts/terminal/index.js"),
|
||||
// Repo layout, running from source under tsx.
|
||||
path.resolve(here, "../../../src/backend/hosts/terminal/index.ts"),
|
||||
];
|
||||
|
||||
for (const candidate of candidates) {
|
||||
try {
|
||||
require.resolve(candidate);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
return import(new URL(`file://${candidate.replace(/\\/g, "/")}`).href);
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`ssh-terminal could not locate the terminal module. Looked in:\n ${candidates.join("\n ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
let terminal = null;
|
||||
|
||||
export async function activate(ctx) {
|
||||
terminal = await loadTerminalModule();
|
||||
|
||||
await terminal.startTerminalServer();
|
||||
|
||||
// Published so collab and session-sharing can reach live sessions without
|
||||
// importing a plugin. Revoked automatically when this plugin is disabled.
|
||||
ctx.registry.provide("terminal.sessions", terminal.sessionManager ?? null);
|
||||
|
||||
ctx.log.info(
|
||||
`SSH terminal listening on ${terminal.TERMINAL_WS_PORT ?? 30002}`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function deactivate() {
|
||||
if (!terminal) return;
|
||||
await terminal.stopTerminalServer();
|
||||
terminal = null;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -37,8 +37,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"backend": "backend/index.mjs",
|
||||
"frontend": "frontend/index.mjs",
|
||||
"locales": "locales",
|
||||
"platforms": ["linux", "win32", "darwin"]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "@termix-plugin/ssh-terminal",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "termix-plugin build",
|
||||
"test": "termix-plugin test",
|
||||
"typecheck": "tsc -p tsconfig.json",
|
||||
"validate": "termix-plugin validate"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@termix/plugin-sdk": "*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { PluginContext } from "@termix/plugin-sdk/backend";
|
||||
import {
|
||||
TERMINAL_WS_PORT,
|
||||
sessionManager,
|
||||
startTerminalServer,
|
||||
stopTerminalServer,
|
||||
} from "../../../../src/backend/hosts/terminal/index.js";
|
||||
|
||||
export async function activate(ctx: PluginContext) {
|
||||
await startTerminalServer();
|
||||
|
||||
// Published so collab and session-sharing can reach live sessions without
|
||||
// importing a plugin. Revoked automatically when this plugin is disabled.
|
||||
ctx.registry.provide("terminal.sessions", sessionManager ?? null);
|
||||
|
||||
ctx.log.info(`SSH terminal listening on ${TERMINAL_WS_PORT ?? 30002}`);
|
||||
}
|
||||
|
||||
export async function deactivate() {
|
||||
await stopTerminalServer();
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "@termix/plugin-sdk/tsconfig.plugin.json",
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/types/*": ["../../src/types/*"],
|
||||
"@/*": ["../../src/ui/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "tests/**/*.ts", "tests/**/*.tsx"]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { pluginVitestConfig } from "@termix/plugin-sdk/vitest-preset";
|
||||
|
||||
export default pluginVitestConfig(import.meta.url);
|
||||
Reference in new issue
Block a user