@termix-ssh/plugin-sdk 1.0.12 → 1.0.13

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 (40) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/PLUGIN-GUIDE.md +91 -59
  3. package/dist/backend.d.ts +404 -0
  4. package/dist/capabilities.js +5 -0
  5. package/dist/db.js +1 -0
  6. package/dist/desktop.d.ts +0 -243
  7. package/dist/frontend.d.ts +23 -2
  8. package/dist/host/{PluginsTab-EV4MSGY6.js → PluginsTab-OXQQ7M4I.js} +511 -178
  9. package/dist/host/{chunk-X4QZKO5G.js → chunk-54KCK6IZ.js} +52 -5
  10. package/dist/host/{chunk-XKA3DBB2.js → chunk-CALNJCHN.js} +114 -54
  11. package/dist/host/{chunk-RUPLD6RF.js → chunk-CN5UBTBP.js} +2 -86
  12. package/dist/host/{chunk-AWR6FYDO.js → chunk-ERGN4YW6.js} +5552 -5550
  13. package/dist/host/{chunk-VEWOYAMZ.js → chunk-T2PZWXFJ.js} +1 -1
  14. package/dist/host/core-classes.json +1 -1
  15. package/dist/host/{linked-server-B4NEG4MA.js → linked-server-5VFO4XQB.js} +1 -1
  16. package/dist/host/{rbac-api-OUO3LUOC.js → rbac-api-5YMBJAO5.js} +1 -1
  17. package/dist/host/testing-host.js +4 -4
  18. package/dist/host/types/src/types/onboarding.d.ts +0 -2
  19. package/dist/host/types/src/ui/api/audit-log-api.d.ts +0 -10
  20. package/dist/host/types/src/ui/api/credentials-api.d.ts +0 -22
  21. package/dist/host/types/src/ui/api/plugins-api.d.ts +4 -0
  22. package/dist/host/types/src/ui/api/settings-api.d.ts +0 -6
  23. package/dist/host/types/src/ui/api/ssh-host-management-api.d.ts +0 -28
  24. package/dist/host/types/src/ui/main-axios.d.ts +2 -2
  25. package/dist/host/types/src/ui/onboarding/onboarding-registry.d.ts +3 -1
  26. package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +5 -6
  27. package/dist/host/types/src/ui/plugins/plugin-model.d.ts +20 -0
  28. package/dist/host/types/src/ui/plugins/use-plugins-manager.d.ts +3 -0
  29. package/dist/host/types/src/ui/sidebar/host-contributions.d.ts +10 -0
  30. package/dist/host/ui.js +14 -205
  31. package/dist/host/{use-permissions-6VSHHUMB.js → use-permissions-ISEDRY3J.js} +1 -1
  32. package/dist/manifest.d.ts +10 -1
  33. package/dist/manifest.js +16 -1
  34. package/dist/ssh-keys.d.ts +29 -0
  35. package/dist/ssh-keys.js +85 -0
  36. package/dist/testing.d.ts +32 -15
  37. package/dist/testing.js +218 -1
  38. package/package.json +5 -1
  39. package/schema/manifest.schema.json +10 -0
  40. package/dist/host/types/src/ui/sidebar/host-export-payload.d.ts +0 -30
package/dist/desktop.d.ts CHANGED
@@ -2,7 +2,6 @@
2
2
  * The desktop app's bridge (window.electronAPI), typed for plugins. It exists
3
3
  * only inside the Termix desktop app; check isElectron before calling it.
4
4
  */
5
- import type { PluginSshPromptRequest } from "./backend.js";
6
5
  export interface ServerConfig {
7
6
  serverUrl?: string;
8
7
  allowInvalidCertificate?: boolean;
@@ -30,27 +29,6 @@ export interface DialogResult {
30
29
  filePaths?: string[];
31
30
  [key: string]: unknown;
32
31
  }
33
- export interface LocalDirectoryResult {
34
- success: boolean;
35
- path: string;
36
- parent?: string;
37
- entries: LocalFileEntry[];
38
- error?: string;
39
- }
40
- export interface LocalCollectedFile {
41
- path: string;
42
- name: string;
43
- relativePath: string;
44
- size: number;
45
- created?: string;
46
- modified: string;
47
- }
48
- export type LocalPathMutationResult = ({
49
- success: true;
50
- } & Partial<LocalFileEntry>) | {
51
- success: false;
52
- error?: string;
53
- };
54
32
  export interface ElectronAPI {
55
33
  getAppVersion: () => Promise<string>;
56
34
  setZoomFactor?: (factor: number) => void;
@@ -62,51 +40,6 @@ export interface ElectronAPI {
62
40
  success: boolean;
63
41
  }>;
64
42
  testServerConnection: (serverUrl: string, allowInvalidCertificate?: boolean) => Promise<ConnectionTestResult>;
65
- answerC2SAuth: (id: string, answer: string | null) => Promise<boolean>;
66
- onC2SAuthPrompt: (callback: (prompt: {
67
- id: string;
68
- closed?: boolean;
69
- tunnelName?: string;
70
- request?: PluginSshPromptRequest;
71
- }) => void) => () => void;
72
- getC2STunnelConfig: () => Promise<unknown[]>;
73
- saveC2STunnelConfig: (config: unknown[]) => Promise<{
74
- success: boolean;
75
- error?: string;
76
- }>;
77
- checkLocalPortAvailable: (host: string, port: number) => Promise<{
78
- available: boolean;
79
- error?: string;
80
- }>;
81
- getC2STunnelPresetDefaultName: () => Promise<string>;
82
- startC2STunnel: (tunnel: unknown, index: number, authToken?: string) => Promise<{
83
- success: boolean;
84
- tunnelName?: string;
85
- error?: string;
86
- code?: string;
87
- }>;
88
- testC2STunnel: (tunnel: unknown, index: number, authToken?: string) => Promise<{
89
- success: boolean;
90
- message?: string;
91
- error?: string;
92
- code?: string;
93
- }>;
94
- stopC2STunnel: (tunnelName: string) => Promise<{
95
- success: boolean;
96
- error?: string;
97
- }>;
98
- getC2STunnelStatuses: () => Promise<Record<string, unknown>>;
99
- onC2STunnelStatuses?: (callback: (statuses: Record<string, unknown>) => void) => () => void;
100
- startC2SAutoStartTunnels: () => Promise<{
101
- success: boolean;
102
- started: number;
103
- errors: string[];
104
- }>;
105
- /** Where the linked server relays client tunnel streams, a /plugin-ws/ path. */
106
- setC2SRelayPath?: (relayPath: string) => Promise<{
107
- success: boolean;
108
- error?: string;
109
- }>;
110
43
  onCloseActiveTab?: (callback: () => void) => () => void;
111
44
  clearSessionCookies: () => Promise<void>;
112
45
  getSessionCookie: (name: string, targetUrl?: string) => Promise<string | null>;
@@ -117,46 +50,6 @@ export interface ElectronAPI {
117
50
  }>;
118
51
  showSaveDialog: (options: DialogOptions) => Promise<DialogResult>;
119
52
  showOpenDialog: (options: DialogOptions) => Promise<DialogResult>;
120
- getLocalHomeDirectory?: () => Promise<string>;
121
- listLocalDirectory?: (path?: string) => Promise<LocalDirectoryResult>;
122
- statLocalPaths?: (paths: string[]) => Promise<Array<(LocalFileEntry & {
123
- success: true;
124
- }) | {
125
- success: false;
126
- path: string;
127
- error?: string;
128
- }>>;
129
- collectLocalFiles?: (paths: string[]) => Promise<{
130
- success: boolean;
131
- files: LocalCollectedFile[];
132
- truncated?: boolean;
133
- error?: string;
134
- }>;
135
- createLocalFolder?: (parentPath: string, folderName: string) => Promise<LocalPathMutationResult>;
136
- renameLocalPath?: (path: string, newName: string) => Promise<LocalPathMutationResult>;
137
- trashLocalPath?: (path: string) => Promise<LocalPathMutationResult>;
138
- chmodLocalPath?: (path: string, permissions: string) => Promise<LocalPathMutationResult>;
139
- openExternalEditor: (fileData: {
140
- fileName: string;
141
- content: string;
142
- encoding?: "utf8" | "base64";
143
- editorPath?: string | null;
144
- }) => Promise<{
145
- success: boolean;
146
- editId?: string;
147
- path?: string;
148
- error?: string;
149
- }>;
150
- closeExternalEditor: (editId: string) => Promise<{
151
- success: boolean;
152
- error?: string;
153
- }>;
154
- onExternalEditorSaved?: (callback: (payload: {
155
- editId: string;
156
- content: string;
157
- encoding: "utf8";
158
- path: string;
159
- }) => void) => () => void;
160
53
  onUpdateAvailable: (callback: () => void) => void;
161
54
  onUpdateDownloaded: (callback: () => void) => void;
162
55
  removeAllListeners: (channel: string) => void;
@@ -197,142 +90,6 @@ export interface ElectronAPI {
197
90
  success: boolean;
198
91
  error?: string;
199
92
  }>;
200
- startLocalTerminal(dimensions: {
201
- cols: number;
202
- rows: number;
203
- shell?: "default" | "wsl";
204
- }): Promise<{
205
- sessionId: string;
206
- shell: string;
207
- }>;
208
- readyLocalTerminal(sessionId: string): Promise<boolean>;
209
- writeLocalTerminal(sessionId: string, data: string): Promise<boolean>;
210
- resizeLocalTerminal(sessionId: string, cols: number, rows: number): Promise<boolean>;
211
- closeLocalTerminal(sessionId: string): Promise<boolean>;
212
- onLocalTerminalData(sessionId: string, callback: (data: string) => void): () => void;
213
- onLocalTerminalExit(sessionId: string, callback: (exitCode: number) => void): () => void;
214
- /** Local disk browsing for the dual-pane file manager (desktop only). */
215
- localFs?: {
216
- home: () => Promise<LocalFsResult<LocalFsHomeInfo>>;
217
- list: (dirPath: string) => Promise<LocalFsResult<LocalDirectoryListing>>;
218
- mkdir: (parentPath: string, name: string) => Promise<LocalFsResult<{
219
- path: string;
220
- }>>;
221
- createFile: (parentPath: string, name: string) => Promise<LocalFsResult<{
222
- path: string;
223
- }>>;
224
- rename: (oldPath: string, newName: string) => Promise<LocalFsResult<{
225
- path: string;
226
- }>>;
227
- trash: (paths: string[]) => Promise<LocalFsResult<LocalTrashResult>>;
228
- ensureDir: (dirPath: string, rootPath?: string) => Promise<LocalFsResult<{
229
- path: string;
230
- }>>;
231
- exists: (paths: string[]) => Promise<LocalFsResult<{
232
- existing: string[];
233
- }>>;
234
- walk: (paths: string[]) => Promise<LocalFsResult<LocalWalkResult>>;
235
- reveal: (targetPath: string) => Promise<LocalFsResult<unknown>>;
236
- open: (targetPath: string) => Promise<LocalFsResult<unknown>>;
237
- };
238
- /** Streamed local<->remote transfers driven by the main process. */
239
- localTransfer?: {
240
- /** The /plugin-api/<id> path that serves the streaming routes. */
241
- setApiPath?: (apiPath: string) => Promise<LocalFsResult<object>>;
242
- upload: (options: LocalUploadRequest) => Promise<LocalFsResult<{
243
- bytes: number;
244
- }>>;
245
- download: (options: LocalDownloadRequest) => Promise<LocalFsResult<{
246
- path: string;
247
- }>>;
248
- cancel: (transferId: string) => Promise<LocalFsResult<{
249
- cancelled: boolean;
250
- }>>;
251
- onProgress: (callback: (payload: LocalTransferProgress) => void) => () => void;
252
- };
253
- }
254
- export type LocalFsResult<T> = ({
255
- success: true;
256
- } & T) | {
257
- success: false;
258
- error: string;
259
- code?: string;
260
- };
261
- export interface LocalFsHomeInfo {
262
- home: string;
263
- separator: string;
264
- platform: string;
265
- }
266
- export interface LocalFileEntry {
267
- name: string;
268
- path: string;
269
- type: "file" | "directory" | "link" | "other";
270
- created?: string;
271
- modified?: string;
272
- permissions?: string;
273
- owner?: string;
274
- group?: string;
275
- size: number;
276
- modifiedTimestamp?: number;
277
- linkTarget?: string;
278
- hidden: boolean;
279
- }
280
- export interface LocalDirectoryListing {
281
- path: string;
282
- parent: string | null;
283
- entries: LocalFileEntry[];
284
- }
285
- export interface LocalTrashResult {
286
- trashed: number;
287
- failed: Array<{
288
- path: string;
289
- error: string;
290
- }>;
291
- }
292
- export interface LocalWalkFile {
293
- localPath: string;
294
- /** Path relative to the drop root; "/"-separated and includes the root's own name. */
295
- relativePath: string;
296
- size: number;
297
- }
298
- export interface LocalWalkResult {
299
- files: LocalWalkFile[];
300
- emptyDirs: string[];
301
- totalBytes: number;
302
- }
303
- /**
304
- * Which Termix backend a transfer talks to. The main process resolves the
305
- * actual URL and credentials for the origin; the renderer never supplies them.
306
- */
307
- export type LocalTransferOrigin = "local" | "remote";
308
- export interface LocalUploadRequest {
309
- transferId: string;
310
- origin: LocalTransferOrigin;
311
- fields: Record<string, string>;
312
- localPath: string;
313
- fileName: string;
314
- deviceId?: string;
315
- /** The renderer's token for the embedded backend (origin "local"); sent as a Bearer header. */
316
- authToken?: string;
317
- }
318
- export interface LocalDownloadRequest {
319
- transferId: string;
320
- origin: LocalTransferOrigin;
321
- body: Record<string, unknown>;
322
- destPath: string;
323
- /** Selected download folder; destPath must resolve strictly inside it (code EINVAL otherwise). */
324
- rootPath: string;
325
- expectedSize?: number;
326
- /** Replace an existing file at destPath; otherwise the transfer is refused with code EEXIST. */
327
- overwrite?: boolean;
328
- deviceId?: string;
329
- /** The renderer's token for the embedded backend (origin "local"); sent as a Bearer header. */
330
- authToken?: string;
331
- }
332
- export interface LocalTransferProgress {
333
- transferId: string;
334
- transferred: number;
335
- total?: number;
336
93
  }
337
94
  declare global {
338
95
  interface Window {
@@ -629,7 +629,13 @@ export interface HostBadgeContribution {
629
629
  component: ComponentType<{
630
630
  host: PluginHostRecord;
631
631
  }>;
632
+ /** Lower comes first. Ties sort by id. */
633
+ order?: number;
632
634
  }
635
+ /** The dot or stripe that shows a host's status on its row. */
636
+ export type HostStatusIndicatorContribution = HostBadgeContribution;
637
+ /** A control in the host editor's toolbar. */
638
+ export type HostEditorToolbarItemContribution = HostBadgeContribution;
633
639
  export interface HostContextMenuItemContribution {
634
640
  id: string;
635
641
  titleKey: string;
@@ -795,10 +801,11 @@ export type OnboardingMode = "full" | "partial" | "rerun";
795
801
  * Where a plugin step sits in onboarding. "setup" comes right after the
796
802
  * appearance steps, for things that need doing before the feature works
797
803
  * (like pointing at a guacd server). "explore" (the default) comes after
798
- * that, "security" after the account security step. Onboarding is for
804
+ * that, "security" after the account security step. "start" comes before
805
+ * the appearance steps, for choices that shape how the rest looks. Onboarding is for
799
806
  * choices, not for explaining features.
800
807
  */
801
- export type OnboardingSection = "setup" | "explore" | "security";
808
+ export type OnboardingSection = "start" | "setup" | "explore" | "security";
802
809
  export interface OnboardingStepProps {
803
810
  /**
804
811
  * "full" is a new user's first run, "partial" shows only steps they have
@@ -839,6 +846,16 @@ export interface OnboardingStepContribution {
839
846
  permission?: string;
840
847
  section?: OnboardingSection;
841
848
  order?: number;
849
+ /**
850
+ * Exact place in the flow, 1 to 99, instead of a section. Core steps sit at
851
+ * 10 (plugins), 20, 25, 30 (preset), 40 (appearance) and 90 (security).
852
+ */
853
+ position?: number;
854
+ /**
855
+ * Older step keys this step took over, like "preset". People who already
856
+ * saw one of them are not shown this step again.
857
+ */
858
+ replaces?: string[];
842
859
  when?: (context: {
843
860
  isAdmin: boolean;
844
861
  isDesktop: boolean;
@@ -988,6 +1005,10 @@ export interface TermixApp extends TermixAppInfo {
988
1005
  registerHostAction: (action: HostActionContribution) => Disposer;
989
1006
  registerHostProtocol: (protocol: HostProtocolContribution) => Disposer;
990
1007
  registerHostBadge: (badge: HostBadgeContribution) => Disposer;
1008
+ /** Draws a host row's status. A layout renders every registered one. */
1009
+ registerHostStatusIndicator: (indicator: HostStatusIndicatorContribution) => Disposer;
1010
+ /** Adds a control to the host editor's toolbar. */
1011
+ registerHostEditorToolbarItem: (item: HostEditorToolbarItemContribution) => Disposer;
991
1012
  registerHostContextMenuItem: (item: HostContextMenuItemContribution) => Disposer;
992
1013
  registerPaletteEntry: (entry: PaletteEntryContribution) => Disposer;
993
1014
  registerPaletteGroup: (group: PaletteGroupContribution) => Disposer;