@termix-ssh/plugin-sdk 1.0.13 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/PLUGIN-GUIDE.md +104 -69
  3. package/dist/backend.d.ts +500 -1
  4. package/dist/backend.js +7 -0
  5. package/dist/capabilities.js +4 -0
  6. package/dist/frontend.d.ts +45 -0
  7. package/dist/host/{PluginsTab-OXQQ7M4I.js → PluginsTab-YAGYRBIE.js} +3 -3
  8. package/dist/host/{chunk-T2PZWXFJ.js → chunk-2MU6WNSX.js} +1 -1
  9. package/dist/host/{chunk-54KCK6IZ.js → chunk-446UEDSK.js} +6 -2
  10. package/dist/host/{chunk-CN5UBTBP.js → chunk-7LEJ3HYF.js} +49 -3
  11. package/dist/host/{chunk-CALNJCHN.js → chunk-J2AILBXM.js} +561 -400
  12. package/dist/host/{chunk-ERGN4YW6.js → chunk-LQKK2JJA.js} +5 -1
  13. package/dist/host/core-classes.json +1 -1
  14. package/dist/host/{linked-server-5VFO4XQB.js → linked-server-OUF3POT7.js} +5 -3
  15. package/dist/host/{rbac-api-5YMBJAO5.js → rbac-api-LZVENREG.js} +1 -1
  16. package/dist/host/testing-host.js +4 -4
  17. package/dist/host/types/src/types/index.d.ts +10 -0
  18. package/dist/host/types/src/types/onboarding.d.ts +0 -1
  19. package/dist/host/types/src/types/ui-types.d.ts +3 -1
  20. package/dist/host/types/src/ui/api/auth-methods-api.d.ts +2 -0
  21. package/dist/host/types/src/ui/api/settings-api.d.ts +6 -0
  22. package/dist/host/types/src/ui/api/ssh-host-management-api.d.ts +6 -0
  23. package/dist/host/types/src/ui/auth/Auth.d.ts +1 -0
  24. package/dist/host/types/src/ui/lib/linked-server.d.ts +2 -0
  25. package/dist/host/types/src/ui/main-axios.d.ts +2 -2
  26. package/dist/host/types/src/ui/plugin-host/NativeView.d.ts +19 -0
  27. package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +4 -8
  28. package/dist/host/types/src/ui/shell/CompanionFrame.d.ts +11 -0
  29. package/dist/host/types/src/ui/shell/companions.d.ts +63 -0
  30. package/dist/host/types/src/ui/sidebar/AuthEnrollmentSections.d.ts +4 -1
  31. package/dist/host/ui.js +171 -820
  32. package/dist/host/{use-permissions-ISEDRY3J.js → use-permissions-BYCDS5PD.js} +1 -1
  33. package/dist/manifest.d.ts +1 -1
  34. package/dist/manifest.js +1 -1
  35. package/dist/testing.d.ts +26 -2
  36. package/dist/testing.js +89 -1
  37. package/dist/vitest-preset.js +23 -0
  38. package/package.json +1 -1
  39. package/schema/manifest.schema.json +4 -0
  40. package/dist/host/types/src/ui/api/sync-api.d.ts +0 -93
  41. package/dist/host/types/src/ui/auth/ElectronLoginForm.d.ts +0 -9
  42. package/dist/host/types/src/ui/hooks/use-sync-status.d.ts +0 -4
  43. package/dist/host/types/src/ui/lib/sync-status.d.ts +0 -6
  44. package/dist/host/types/src/ui/settings/sync/LinkServerDialog.d.ts +0 -12
  45. package/dist/host/types/src/ui/settings/sync/ProxySettingsFields.d.ts +0 -15
  46. package/dist/host/types/src/ui/settings/sync/saved-servers.d.ts +0 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.17
4
+
5
+ Plugin API 1.9.0.
6
+
7
+ ### Added
8
+
9
+ - `app.registerCompanion` and `app.toggleCompanion`, so a plugin can add a panel beside any host tab. The user opens, resizes and moves it, and the tab keeps running
10
+ - `NativeView` in `@termix-ssh/plugin-sdk/ui`, which shows a web page in a native view in the desktop app, for sites that do not work in an iframe
11
+
12
+ ## 1.0.16
13
+
14
+ Plugin API 1.8.0.
15
+
16
+ ### Added
17
+
18
+ - `ctx.sync.provide` and the `sync:provide` capability, so a plugin can answer every /sync request
19
+ - `ctx.ssh.transports.provide` and the `ssh:transport` capability, so a plugin can carry SSH connections over its own stream
20
+ - `ctx.hosts.folders.ensure` and `removeEmpty`
21
+
22
+ ### Removed
23
+
24
+ - The sync screens and calls in `@termix-ssh/plugin-sdk/ui`: `LinkServerDialog`, `ProxySettingsFields`, `useSyncStatus`, `refreshSyncStatus`, `setSyncStatus`, `getSyncConflicts`, `getSyncErrors`, `retrySyncErrors`, `settleSyncConflict`, `syncNow`, `unlinkServer`, `updateSyncSettings` and their types. They moved into the sync plugin
25
+
26
+ ## 1.0.15
27
+
28
+ Plugin API 1.7.0.
29
+
30
+ ### Added
31
+
32
+ - `ctx.auth.policy.provide` and the `auth:policy` capability, so a plugin can set an idle timeout, cap session length, turn off remember me and require a second factor
33
+ - `ctx.auth.listSecondFactors` lists the second factors from every running plugin
34
+ - `AuthEnrollmentSections` takes `factorsOnly`
35
+ - `getHttpsSettings` and `updateHttpsSettings` in `@termix-ssh/plugin-sdk/ui`
36
+
37
+ ### Fixed
38
+
39
+ - Plugin frontend tests against a locally linked SDK failed with a second copy of React
40
+
41
+ ## 1.0.14
42
+
43
+ Plugin API 1.6.0.
44
+
45
+ ### Added
46
+
47
+ - `ctx.hosts.locks.provide` and the `hosts:lock` capability, so a plugin can manage hosts that stay read only for everyone else and block adding hosts by hand
48
+ - `ctx.hosts.setShares` to replace every grant on a host in one call
49
+ - `ctx.credentials.list` returns the acting user's credentials by name, without secrets
50
+ - `ctx.hosts.create` and `update` take `password`, `key`, `keyPassword`, `keyType`, `sudoPassword`, `protocolAuth` and `pluginEnable`
51
+
3
52
  ## 1.0.13
4
53
 
5
54
  Plugin API 1.5.0.
package/PLUGIN-GUIDE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Termix plugin guide
2
2
 
3
- SDK 1.0.13 | Plugin API 1.5.0
3
+ SDK 1.0.17 | Plugin API 1.9.0
4
4
 
5
5
  This guide is for anyone, person or AI coding tool, building a Termix plugin. It ships inside
6
6
  `@termix-ssh/plugin-sdk`, so the copy in your `node_modules` always matches the SDK you have installed.
@@ -202,36 +202,40 @@ Bundled as ESM for Node 22+ into `dist/backend.js`. Backend imports of your own
202
202
 
203
203
  ### What ctx has
204
204
 
205
- | Member | Capability | What it does |
206
- | ---------------------- | -------------------------------- | -------------------------------------------------------------- |
207
- | `pluginId`, `manifest` | none | Your id and manifest |
208
- | `log` | none | Log lines tagged with your plugin |
209
- | `db` | `db:own` | Your own tables |
210
- | `kv` | `kv:own` | Small key value state |
211
- | `files.dataDir()` | `files:own` | A folder of your own |
212
- | `settings` | none | Your settings |
213
- | `secrets` | `secrets:own` | Encrypted values per user, `seal`/`unseal` for your own tables |
214
- | `http`, `ws` | `network:serve` | Routes and sockets |
215
- | `rbac` | none | Check the actor's permissions |
216
- | `hosts` | `hosts:read`, `hosts:write` | List, read, create, update and share hosts as the actor |
217
- | `ssh` | `ssh:connect`, `credentials:use` | Connect to hosts through Termix's SSH pipeline |
218
- | `credentials` | varies | The actor's saved keys, and protocol logins |
219
- | `services` | per service | Call other plugins and offer your own |
220
- | `events` | `events:core` for core topics | Emit and listen for events |
221
- | `notify` | `notify:send` | Send alerts to the Alerts inbox |
222
- | `fetch` | `network:outbound` | Outbound HTTP with SSRF protection |
223
- | `process` | `process:spawn` | Run programs on the server |
224
- | `schedule` | none | Timers that stop on disable and never overlap |
225
- | `audit.record` | none | Write your own audit line |
226
- | `sync` | none | Sync your tables to a linked desktop |
227
- | `auth` | `auth:provide` | Login methods, second factors, SSH auth types |
228
- | `auth.issueUserToken` | `users:impersonate` | A short-lived session for calling Termix's API as a user |
229
- | `users.getLocale` | `users:read` | A user's UI language |
230
- | `system` | `system:tls` | The server's HTTPS certificate |
231
- | `plugins.list()` | `plugins:read` | Which plugins are installed |
232
- | `asUser(userId, fn)` | always audited | Run background work as a user |
233
- | `currentActor()` | none | The user the current call runs for |
234
- | `disposables.add(fn)` | none | Extra cleanup on disable |
205
+ | Member | Capability | What it does |
206
+ | ---------------------- | -------------------------------- | --------------------------------------------------------------- |
207
+ | `pluginId`, `manifest` | none | Your id and manifest |
208
+ | `log` | none | Log lines tagged with your plugin |
209
+ | `db` | `db:own` | Your own tables |
210
+ | `kv` | `kv:own` | Small key value state |
211
+ | `files.dataDir()` | `files:own` | A folder of your own |
212
+ | `settings` | none | Your settings |
213
+ | `secrets` | `secrets:own` | Encrypted values per user, `seal`/`unseal` for your own tables |
214
+ | `http`, `ws` | `network:serve` | Routes and sockets |
215
+ | `rbac` | none | Check the actor's permissions |
216
+ | `hosts` | `hosts:read`, `hosts:write` | List, read, create, update and share hosts as the actor |
217
+ | `ssh` | `ssh:connect`, `credentials:use` | Connect to hosts through Termix's SSH pipeline |
218
+ | `credentials` | varies | The actor's saved keys, and protocol logins |
219
+ | `services` | per service | Call other plugins and offer your own |
220
+ | `events` | `events:core` for core topics | Emit and listen for events |
221
+ | `notify` | `notify:send` | Send alerts to the Alerts inbox |
222
+ | `fetch` | `network:outbound` | Outbound HTTP with SSRF protection |
223
+ | `process` | `process:spawn` | Run programs on the server |
224
+ | `schedule` | none | Timers that stop on disable and never overlap |
225
+ | `audit.record` | none | Write your own audit line |
226
+ | `sync` | none | Sync your tables to a linked desktop |
227
+ | `auth` | `auth:provide` | Login methods, second factors, SSH auth types |
228
+ | `auth.issueUserToken` | `users:impersonate` | A short-lived session for calling Termix's API as a user |
229
+ | `auth.policy` | `auth:policy` | Login rules: idle timeout, session length, second factors |
230
+ | `sync.provide` | `sync:provide` | Answers all /sync requests: server sync, linked desktops |
231
+ | `ssh.transports` | `ssh:transport` | Carries a host's SSH connection over your own stream |
232
+ | `hosts.folders` | `hosts:write` | Create a folder row with a color and icon, remove it when empty |
233
+ | `users.getLocale` | `users:read` | A user's UI language |
234
+ | `system` | `system:tls` | The server's HTTPS certificate |
235
+ | `plugins.list()` | `plugins:read` | Which plugins are installed |
236
+ | `asUser(userId, fn)` | always audited | Run background work as a user |
237
+ | `currentActor()` | none | The user the current call runs for |
238
+ | `disposables.add(fn)` | none | Extra cleanup on disable |
235
239
 
236
240
  ### The actor
237
241
 
@@ -300,6 +304,14 @@ router.post("/notes", async (req, res) => {
300
304
  - `ctx.rbac.require("manage")` on a single route, `await ctx.rbac.has("manage")` in code. A full id like
301
305
  `hosts.edit` checks a core permission.
302
306
  - Host access: `ctx.hosts.checkAccess(hostId, "connect" | "view" | "edit" | "manage")`.
307
+ - Transports: with `ssh:transport`, `ctx.ssh.transports.provide({ claims(hostId), open({ id, ip, port }) })`
308
+ returns a stream the SSH client uses instead of a direct, proxy or jump host connection. Core also serves
309
+ `/plugin-ws/core/ssh-relay?hostId=` for callers with connect access, so one Termix can relay to another.
310
+ - Managed hosts: with `hosts:lock`, `ctx.hosts.locks.provide({ isLocked, note, allowManualCreate })` makes
311
+ the hosts you manage read only for the UI, the API and other plugins (pins and order still work), and
312
+ `allowManualCreate: () => false` blocks adding hosts by hand. Your own `ctx.hosts` writes still go
313
+ through. `ctx.hosts.setShares(hostId, grants)` replaces a host's whole grant list, and
314
+ `ctx.credentials.list()` finds the acting user's credentials by name.
303
315
 
304
316
  ### Errors
305
317
 
@@ -483,6 +495,7 @@ your plugin's error boundary and Suspense.
483
495
  | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
484
496
  | `registerRailItem` | A sidebar rail button |
485
497
  | `registerTab`, `registerPanel` | A tab type or sidebar panel (id in `contributes.tabs` / `panels`) |
498
+ | `registerCompanion`, `toggleCompanion` | A panel beside any host tab, bound to its host and handle |
486
499
  | `registerDashboardCard` | A dashboard card (`contributes.dashboardCards`) |
487
500
  | `registerHostAction` | A host button, palette entry or default connect |
488
501
  | `registerHostEditorSection` | Your own host editor section (host settings get one for free) |
@@ -618,6 +631,9 @@ Build UI from `@termix-ssh/plugin-sdk/ui` so it matches Termix and follows the t
618
631
  exports with props is `ui.api.txt` in the Termix repo
619
632
  (https://github.com/Termix-SSH/Termix/blob/main/packages/plugin-sdk/ui.api.txt).
620
633
 
634
+ - Web pages that break in an iframe: `NativeView` (props `url`, `ignoreCert`, `hidden`, `fallback`) shows the
635
+ page in a native view in the desktop app. It fills its element, hides while a dialog or menu is open and renders
636
+ `fallback` in a browser.
621
637
  - Square: panels, cards and containers have no rounded corners. Small controls may stay rounded.
622
638
  - Flat: borders, not shadows. Use theme tokens like `border-border`, `bg-background`,
623
639
  `text-muted-foreground`, `text-destructive`. One accent, `text-accent-brand`. Don't add colors.
@@ -694,6 +710,21 @@ closely. Declare ids in `contributes.auth` and register them with `ctx.auth.regi
694
710
  `registerSecondFactor` or `registerSshAuthProvider`. Connection protocols go in `contributes.protocols`
695
711
  and `app.registerHostProtocol`. Read https://docs.termix.site/develop/auth before starting one.
696
712
 
713
+ Login rules need `auth:policy`. `ctx.auth.policy.provide({ evaluate, allowRememberDevice })` is asked at
714
+ every login with the user, the method, the device and every second factor (`ctx.auth.listSecondFactors()`
715
+ lists them too). `evaluate` returns `allowRememberDevice`, `maxSessionSeconds`, `idleTimeoutSeconds` and
716
+ `secondFactor` (`"always"` or `"new-device"`). The strictest answer from all plugins wins, and a throw
717
+ refuses the login. A user who must have a second factor but has none gets a session that can only set one
718
+ up, and `/users/me` reports `restriction: "second-factor-setup"`.
719
+
720
+ Sync is answered by one plugin. `sync:provide` is high risk: `ctx.sync.provide({ handle })` takes over every
721
+ request under `/sync` (an Express style handler, 404 when nothing provides it), and `ctx.sync.host` hands
722
+ over the neutral parts core keeps: the replica store (`replica`), the change feed and push applier
723
+ (`feed`), the linked server list (`links`, one per local user), desktop accounts (`accounts`), sessions
724
+ (`sessions`), host lookups, plugin mirroring and the proxy settings the desktop app needs. A test passes its
725
+ own `syncHost` to `createMockCtx`. An API key can ask `POST /users/ws-ticket/api-key` for a one minute
726
+ ticket that opens plugin sockets as its user, which is how one server opens sessions through another.
727
+
697
728
  ## Testing
698
729
 
699
730
  ```ts
@@ -880,44 +911,48 @@ To run your own registry instead, see https://docs.termix.site/develop/registrie
880
911
 
881
912
  ## Capabilities
882
913
 
883
- | Capability | Risk | What it allows |
884
- | ------------------------ | -------- | ------------------------------------------------------- |
885
- | `credentials:read` | critical | Read stored secrets for hosts the user can reach |
886
- | `system:tls` | critical | Replace the HTTPS certificate, answer CA domain checks |
887
- | `ssh:connect` | high | Run any command on hosts, with the user's access |
888
- | `process:spawn` | high | Run programs on the Termix server |
889
- | `users:write` | high | Add users and change their roles |
890
- | `users:impersonate` | high | Act as another user, or get a session for them, audited |
891
- | `db:core-refs` | high | Query core users, roles and hosts tables (read only) |
892
- | `auth:provide` | high | Add login methods, second factors, SSH auth types |
893
- | `device:serial` | high | Open serial and USB ports on the server |
894
- | `desktop:local` | high | Use the user's own computer, desktop app only |
895
- | `hosts:export` | high | Export hosts with their saved logins |
896
- | `notify:hub` | high | Receive every alert (the alerts hub only) |
897
- | `ui:layout` | high | Replace the whole app layout |
898
- | `hosts:write` | medium | Add and edit hosts |
899
- | `hosts:status-provide` | medium | Be the source of host status dots |
900
- | `hosts:activity-provide` | medium | Be the source of the recent activity list |
901
- | `network:probe` | medium | Check that a host answers on a TCP port |
902
- | `credentials:use` | medium | Connect with saved credentials without seeing them |
903
- | `credentials:write` | medium | Save new credentials |
904
- | `network:outbound` | medium | Outbound HTTP through `ctx.fetch` |
905
- | `network:serve` | medium | HTTP routes and sockets |
906
- | `network:broadcast` | medium | Local network broadcasts, like Wake-on-LAN |
907
- | `users:read` | medium | Usernames, roles and UI language |
908
- | `events:core` | medium | Listen to core events |
909
- | `notify:send` | medium | Send alerts |
910
- | `audit:read` | medium | Read the audit log |
911
- | `desktop:window` | medium | Open windows in the desktop app |
912
- | `hosts:read` | low | Read hosts the user can see |
913
- | `db:own` | low | Your own tables |
914
- | `kv:own` | low | Small key value state |
915
- | `files:own` | low | Your own folder on disk |
916
- | `secrets:own` | low | Your own encrypted secrets |
917
- | `settings:read-core` | low | Read Termix server settings |
918
- | `plugins:read` | low | See installed plugins |
919
- | `ui:surface` | low | Add tabs, panels and settings |
920
- | `ui:theme` | low | Add color themes, CSS only |
914
+ | Capability | Risk | What it allows |
915
+ | ------------------------ | -------- | ------------------------------------------------------------- |
916
+ | `credentials:read` | critical | Read stored secrets for hosts the user can reach |
917
+ | `system:tls` | critical | Replace the HTTPS certificate, answer CA domain checks |
918
+ | `ssh:connect` | high | Run any command on hosts, with the user's access |
919
+ | `process:spawn` | high | Run programs on the Termix server |
920
+ | `users:write` | high | Add users and change their roles |
921
+ | `users:impersonate` | high | Act as another user, or get a session for them, audited |
922
+ | `db:core-refs` | high | Query core users, roles and hosts tables (read only) |
923
+ | `auth:provide` | high | Add login methods, second factors, SSH auth types |
924
+ | `auth:policy` | high | Set login rules: idle timeout, session length, 2FA |
925
+ | `sync:provide` | high | Run sync: answer every /sync request |
926
+ | `device:serial` | high | Open serial and USB ports on the server |
927
+ | `desktop:local` | high | Use the user's own computer, desktop app only |
928
+ | `hosts:export` | high | Export hosts with their saved logins |
929
+ | `notify:hub` | high | Receive every alert (the alerts hub only) |
930
+ | `ui:layout` | high | Replace the whole app layout |
931
+ | `hosts:write` | medium | Add and edit hosts |
932
+ | `hosts:status-provide` | medium | Be the source of host status dots |
933
+ | `hosts:activity-provide` | medium | Be the source of the recent activity list |
934
+ | `ssh:transport` | high | Carry SSH connections for hosts it claims over its own stream |
935
+ | `hosts:lock` | medium | Make hosts it manages read only for everyone else |
936
+ | `network:probe` | medium | Check that a host answers on a TCP port |
937
+ | `credentials:use` | medium | Connect with saved credentials without seeing them |
938
+ | `credentials:write` | medium | Save new credentials |
939
+ | `network:outbound` | medium | Outbound HTTP through `ctx.fetch` |
940
+ | `network:serve` | medium | HTTP routes and sockets |
941
+ | `network:broadcast` | medium | Local network broadcasts, like Wake-on-LAN |
942
+ | `users:read` | medium | Usernames, roles and UI language |
943
+ | `events:core` | medium | Listen to core events |
944
+ | `notify:send` | medium | Send alerts |
945
+ | `audit:read` | medium | Read the audit log |
946
+ | `desktop:window` | medium | Open windows in the desktop app |
947
+ | `hosts:read` | low | Read hosts the user can see |
948
+ | `db:own` | low | Your own tables |
949
+ | `kv:own` | low | Small key value state |
950
+ | `files:own` | low | Your own folder on disk |
951
+ | `secrets:own` | low | Your own encrypted secrets |
952
+ | `settings:read-core` | low | Read Termix server settings |
953
+ | `plugins:read` | low | See installed plugins |
954
+ | `ui:surface` | low | Add tabs, panels and settings |
955
+ | `ui:theme` | low | Add color themes, CSS only |
921
956
 
922
957
  An update that adds a capability waits for an admin to approve it.
923
958