@termix-ssh/plugin-sdk 1.0.15 → 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 (37) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/PLUGIN-GUIDE.md +92 -72
  3. package/dist/backend.d.ts +370 -0
  4. package/dist/capabilities.js +2 -0
  5. package/dist/frontend.d.ts +45 -0
  6. package/dist/host/{PluginsTab-S33WIIGC.js → PluginsTab-YAGYRBIE.js} +3 -3
  7. package/dist/host/{chunk-57DJU2ZA.js → chunk-2MU6WNSX.js} +1 -1
  8. package/dist/host/{chunk-VFTB2RDP.js → chunk-446UEDSK.js} +4 -2
  9. package/dist/host/{chunk-3L45NNT5.js → chunk-7LEJ3HYF.js} +20 -3
  10. package/dist/host/{chunk-V44FCJBQ.js → chunk-J2AILBXM.js} +540 -400
  11. package/dist/host/{chunk-2IV3VX7F.js → chunk-LQKK2JJA.js} +5 -1
  12. package/dist/host/core-classes.json +1 -1
  13. package/dist/host/{linked-server-SCJH7DSL.js → linked-server-OUF3POT7.js} +5 -3
  14. package/dist/host/{rbac-api-KA5IPQQL.js → rbac-api-LZVENREG.js} +1 -1
  15. package/dist/host/testing-host.js +4 -4
  16. package/dist/host/types/src/types/onboarding.d.ts +0 -1
  17. package/dist/host/types/src/ui/auth/Auth.d.ts +1 -0
  18. package/dist/host/types/src/ui/lib/linked-server.d.ts +2 -0
  19. package/dist/host/types/src/ui/plugin-host/NativeView.d.ts +19 -0
  20. package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +2 -6
  21. package/dist/host/types/src/ui/shell/CompanionFrame.d.ts +11 -0
  22. package/dist/host/types/src/ui/shell/companions.d.ts +63 -0
  23. package/dist/host/ui.js +149 -815
  24. package/dist/host/{use-permissions-LLN6TLAL.js → use-permissions-BYCDS5PD.js} +1 -1
  25. package/dist/manifest.d.ts +1 -1
  26. package/dist/manifest.js +1 -1
  27. package/dist/testing.d.ts +5 -1
  28. package/dist/testing.js +28 -0
  29. package/package.json +1 -1
  30. package/schema/manifest.schema.json +2 -0
  31. package/dist/host/types/src/ui/api/sync-api.d.ts +0 -93
  32. package/dist/host/types/src/ui/auth/ElectronLoginForm.d.ts +0 -9
  33. package/dist/host/types/src/ui/hooks/use-sync-status.d.ts +0 -4
  34. package/dist/host/types/src/ui/lib/sync-status.d.ts +0 -6
  35. package/dist/host/types/src/ui/settings/sync/LinkServerDialog.d.ts +0 -12
  36. package/dist/host/types/src/ui/settings/sync/ProxySettingsFields.d.ts +0 -15
  37. package/dist/host/types/src/ui/settings/sync/saved-servers.d.ts +0 -3
@@ -7,7 +7,7 @@ import {
7
7
  resetPermissionsCache,
8
8
  setPermissionsForTesting,
9
9
  usePermissions
10
- } from "./chunk-57DJU2ZA.js";
10
+ } from "./chunk-2MU6WNSX.js";
11
11
  import "./chunk-YGYBM7SQ.js";
12
12
  export {
13
13
  hasPermission,
@@ -20,7 +20,7 @@ export { ENV_NAME_PATTERN, MAX_ENV_DESCRIPTION_LENGTH, pluginDocsPage, pluginDoc
20
20
  * "^1.2" needs 1.2 or later). engine.termix is checked against the core
21
21
  * version by the server.
22
22
  */
23
- export declare const PLUGIN_API_VERSION = "1.7.0";
23
+ export declare const PLUGIN_API_VERSION = "1.9.0";
24
24
  /** The API major, the default engine.api for a new plugin. */
25
25
  export declare const SUPPORTED_PLUGIN_API_VERSION: string;
26
26
  /** Whether this build's plugin API satisfies a manifest's engine.api. */
package/dist/manifest.js CHANGED
@@ -22,7 +22,7 @@ export { ENV_NAME_PATTERN, MAX_ENV_DESCRIPTION_LENGTH, pluginDocsPage, pluginDoc
22
22
  * "^1.2" needs 1.2 or later). engine.termix is checked against the core
23
23
  * version by the server.
24
24
  */
25
- export const PLUGIN_API_VERSION = "1.7.0";
25
+ export const PLUGIN_API_VERSION = "1.9.0";
26
26
  /** The API major, the default engine.api for a new plugin. */
27
27
  export const SUPPORTED_PLUGIN_API_VERSION = String(semver.major(PLUGIN_API_VERSION));
28
28
  /** Whether this build's plugin API satisfies a manifest's engine.api. */
package/dist/testing.d.ts CHANGED
@@ -23,7 +23,7 @@ export interface FakeWsRoute {
23
23
  options?: PluginWebSocketOptions;
24
24
  }
25
25
  import type { PluginLoginMethod, PluginVerifiedIdentity, PluginSecondFactor, PluginSshAuthProvider, PluginSshConnectOptions, PluginSshHost, PluginHostSummary, PluginShareableUser, PluginShareableRole, PluginSshKeyCredential, PluginSshKeyCredentialInput } from "./backend.js";
26
- import type { SyncEntityRegistration } from "./backend.js";
26
+ import type { PluginSyncHost, SyncEntityRegistration } from "./backend.js";
27
27
  import type { PluginDatabase } from "./backend.js";
28
28
  import type { PluginExternalClientRequest, PluginProtocolTarget, PluginHostProbeTarget, PluginHostStatusEntry, PluginActivityProvider, PluginHostLockProvider, PluginAuthPolicyProvider, PluginCredentialSummary, PluginHostShareGrant, PluginHostStatusProvider, PluginNotification, PluginNotificationChannel, PluginNotifyHub, PluginFetchInit, PluginBinarySpec, PluginTlsCertificateInfo, PluginTlsStatus, PluginSummary, PluginKeyboardInteractiveHandler, PluginProcessHandle, PluginProcessOptions } from "./backend.js";
29
29
  /** A timer registered through ctx.schedule, run by hand with runScheduled. */
@@ -35,6 +35,8 @@ export interface FakeScheduledJob {
35
35
  }
36
36
  export interface FakeContextOptions {
37
37
  pluginId?: string;
38
+ /** What ctx.sync.host answers, for a sync provider's tests. */
39
+ syncHost?: Partial<PluginSyncHost>;
38
40
  manifest?: Partial<PluginManifest>;
39
41
  /** Acting user returned by currentActor and used by asUser. */
40
42
  actor?: string;
@@ -346,6 +348,8 @@ export interface FakePluginContext {
346
348
  export declare function createFakeContext(options?: FakeContextOptions): FakePluginContext;
347
349
  export interface MockContextOptions {
348
350
  pluginId?: string;
351
+ /** What ctx.sync.host answers, for a sync provider's tests. */
352
+ syncHost?: Partial<PluginSyncHost>;
349
353
  manifest?: Partial<PluginManifest>;
350
354
  /** Capabilities the plugin is granted. Anything else throws. */
351
355
  capabilities?: string[];
package/dist/testing.js CHANGED
@@ -301,6 +301,12 @@ export function createFakeContext(options = {}) {
301
301
  registerEntity: (entity) => {
302
302
  syncEntities.push(entity);
303
303
  },
304
+ provide: () => () => { },
305
+ get host() {
306
+ if (!options.syncHost)
307
+ throw new Error("Pass syncHost to use ctx.sync.host");
308
+ return options.syncHost;
309
+ },
304
310
  },
305
311
  registry: {
306
312
  provide: (key, value) => {
@@ -562,6 +568,10 @@ export function createFakeContext(options = {}) {
562
568
  };
563
569
  },
564
570
  },
571
+ folders: {
572
+ ensure: async () => { },
573
+ removeEmpty: async () => true,
574
+ },
565
575
  locks: {
566
576
  provide: (provider) => {
567
577
  hostLockProviders.push(provider);
@@ -633,6 +643,7 @@ export function createFakeContext(options = {}) {
633
643
  tcpProbe: async (host, port) => options.reachable?.(host, port) ?? false,
634
644
  },
635
645
  ssh: {
646
+ transports: { provide: () => () => { } },
636
647
  probe: async (hostId, probeOptions) => options.reachable?.(hostId, probeOptions?.port) ?? false,
637
648
  connect: async (host, connectOptions) => {
638
649
  sshConnections.push({ host, options: connectOptions });
@@ -1107,6 +1118,7 @@ export function createMockCtx(options = {}) {
1107
1118
  const checked = [];
1108
1119
  const base = createFakeContext({
1109
1120
  pluginId: options.pluginId,
1121
+ syncHost: options.syncHost,
1110
1122
  actor: options.actor,
1111
1123
  settings: options.settings,
1112
1124
  coreSettings: options.coreSettings,
@@ -1341,6 +1353,16 @@ export function createMockCtx(options = {}) {
1341
1353
  return ctx.hosts.activity.provide(provider);
1342
1354
  },
1343
1355
  },
1356
+ folders: {
1357
+ ensure: async (name, style) => {
1358
+ require("hosts:write");
1359
+ return ctx.hosts.folders.ensure(name, style);
1360
+ },
1361
+ removeEmpty: async (name) => {
1362
+ require("hosts:write");
1363
+ return ctx.hosts.folders.removeEmpty(name);
1364
+ },
1365
+ },
1344
1366
  locks: {
1345
1367
  provide: (provider) => {
1346
1368
  require("hosts:lock");
@@ -1373,6 +1395,12 @@ export function createMockCtx(options = {}) {
1373
1395
  },
1374
1396
  ssh: {
1375
1397
  ...ctx.ssh,
1398
+ transports: {
1399
+ provide: (provider) => {
1400
+ require("ssh:transport");
1401
+ return ctx.ssh.transports.provide(provider);
1402
+ },
1403
+ },
1376
1404
  probe: async (hostId, probeOptions) => {
1377
1405
  require("ssh:connect");
1378
1406
  return ctx.ssh.probe(hostId, probeOptions);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@termix-ssh/plugin-sdk",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "The contract between Termix core and a plugin: types, the capability catalog and the manifest schema.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -152,6 +152,8 @@
152
152
  "users:write",
153
153
  "auth:provide",
154
154
  "auth:policy",
155
+ "sync:provide",
156
+ "ssh:transport",
155
157
  "system:tls",
156
158
  "device:serial",
157
159
  "hosts:write",
@@ -1,93 +0,0 @@
1
- export type SyncState = "idle" | "syncing" | "offline" | "error" | "signed_out";
2
- export interface SyncProxyHeader {
3
- name: string;
4
- value: string;
5
- /** A saved header whose value is not sent back. */
6
- set?: boolean;
7
- }
8
- export interface SyncBasicAuth {
9
- username: string;
10
- password: string;
11
- set?: boolean;
12
- }
13
- export interface SyncEntityInfo {
14
- type: string;
15
- owner: string;
16
- ownerName: string | null;
17
- readOnly: boolean;
18
- onServer: boolean;
19
- onDevice: boolean;
20
- enabled: boolean;
21
- }
22
- export interface SyncStatus {
23
- linked: boolean;
24
- serverUrl?: string;
25
- serverName?: string | null;
26
- serverVersion?: string | null;
27
- account?: {
28
- username?: string;
29
- isAdmin?: boolean;
30
- roles?: string[];
31
- permissions?: string[];
32
- };
33
- status?: SyncState;
34
- lastError?: string | null;
35
- linkedAt?: string;
36
- lastSyncAt?: string | null;
37
- pending?: number;
38
- conflicts?: number;
39
- errors?: number;
40
- firstSyncDone?: boolean;
41
- allowInvalidCertificate?: boolean;
42
- customHeaders?: SyncProxyHeader[];
43
- basicAuth?: SyncBasicAuth | null;
44
- entities: SyncEntityInfo[];
45
- }
46
- export type ProbeProblem = "invalid_url" | "unreachable" | "tls_untrusted" | "basic_auth_required" | "proxy_login" | "not_termix" | "version_mismatch" | "different_account";
47
- export interface ProbeResult {
48
- ok: boolean;
49
- serverUrl?: string;
50
- name?: string;
51
- version?: string | null;
52
- problem?: ProbeProblem;
53
- message?: string;
54
- }
55
- export interface ServerTarget {
56
- serverUrl: string;
57
- customHeaders?: SyncProxyHeader[];
58
- basicAuth?: SyncBasicAuth | null;
59
- allowInvalidCertificate?: boolean;
60
- }
61
- export interface SyncConflictItem {
62
- id: number;
63
- entityType: string;
64
- syncId: string;
65
- name: string;
66
- createdAt: string;
67
- }
68
- export interface SyncErrorItem {
69
- entityType: string;
70
- syncId: string;
71
- reason: string | null;
72
- }
73
- export declare function getSyncStatus(): Promise<SyncStatus>;
74
- export declare function probeServer(target: ServerTarget): Promise<ProbeResult>;
75
- export declare function getLinkPreview(): Promise<Record<string, number>>;
76
- export declare function completeLink(input: ServerTarget & {
77
- token: string;
78
- mode: "merge" | "replace";
79
- serverName?: string;
80
- }): Promise<SyncStatus>;
81
- export declare function reloginLink(token: string): Promise<SyncStatus>;
82
- export declare function unlinkServer(keepData: boolean): Promise<SyncStatus>;
83
- export declare function syncNow(): Promise<SyncStatus>;
84
- export declare function updateSyncSettings(settings: {
85
- disabledTypes?: string[];
86
- customHeaders?: SyncProxyHeader[];
87
- basicAuth?: SyncBasicAuth | null;
88
- allowInvalidCertificate?: boolean;
89
- }): Promise<SyncStatus>;
90
- export declare function getSyncConflicts(): Promise<SyncConflictItem[]>;
91
- export declare function settleSyncConflict(id: number, keep: "mine" | "server"): Promise<void>;
92
- export declare function getSyncErrors(): Promise<SyncErrorItem[]>;
93
- export declare function retrySyncErrors(): Promise<SyncStatus>;
@@ -1,9 +0,0 @@
1
- import React from "react";
2
- interface ElectronLoginFormProps {
3
- serverUrl: string;
4
- onAuthSuccess: (token: string | null) => void | Promise<void>;
5
- onChangeServer: () => void;
6
- targetPurpose?: "local" | "link";
7
- }
8
- export declare function ElectronLoginForm({ serverUrl, onAuthSuccess, onChangeServer, targetPurpose, }: ElectronLoginFormProps): React.JSX.Element;
9
- export {};
@@ -1,4 +0,0 @@
1
- /** The desktop's sync status, kept current while the component is mounted. */
2
- export declare function useSyncStatus(): any;
3
- /** What needs the user's attention in Sync, for the rail badge. */
4
- export declare function useSyncAttentionCount(): number | null;
@@ -1,6 +0,0 @@
1
- import { type SyncStatus } from "../api/sync-api";
2
- export declare function subscribeSyncStatus(listener: () => void): () => void;
3
- export declare function getSyncStatusSnapshot(): SyncStatus | null;
4
- /** Takes a status a request already returned, and checks again soon. */
5
- export declare function setSyncStatus(next: SyncStatus): void;
6
- export declare function refreshSyncStatus(): void;
@@ -1,12 +0,0 @@
1
- import { type SyncStatus } from "../../api/sync-api";
2
- interface LinkServerDialogProps {
3
- open: boolean;
4
- onOpenChange: (open: boolean) => void;
5
- onLinked: (status: SyncStatus) => void;
6
- /** Sign back in to the server this desktop is already linked to. */
7
- relogin?: {
8
- serverUrl: string;
9
- };
10
- }
11
- export declare function LinkServerDialog({ open, onOpenChange, onLinked, relogin, }: LinkServerDialogProps): import("react").JSX.Element;
12
- export {};
@@ -1,15 +0,0 @@
1
- import type { SyncBasicAuth, SyncProxyHeader } from "../../api/sync-api";
2
- interface ProxySettingsFieldsProps {
3
- customHeaders: SyncProxyHeader[];
4
- basicAuth: SyncBasicAuth | null;
5
- onChange: (next: {
6
- customHeaders?: SyncProxyHeader[];
7
- basicAuth?: SyncBasicAuth | null;
8
- }) => void;
9
- }
10
- /**
11
- * What a reverse proxy in front of the server wants: extra headers (a
12
- * Cloudflare Access service token, a gateway key) and basic auth.
13
- */
14
- export declare function ProxySettingsFields({ customHeaders, basicAuth, onChange, }: ProxySettingsFieldsProps): import("react").JSX.Element;
15
- export {};
@@ -1,3 +0,0 @@
1
- export declare function getSavedServerUrls(): string[];
2
- export declare function rememberServerUrl(url: string): string[];
3
- export declare function forgetServerUrl(url: string): string[];