@termix-ssh/plugin-sdk 1.0.22 → 1.0.24

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 (35) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/PLUGIN-GUIDE.md +69 -1
  3. package/dist/backend.d.ts +107 -0
  4. package/dist/capabilities.js +3 -0
  5. package/dist/frontend.d.ts +19 -0
  6. package/dist/host/{PluginsTab-CM2B33BD.js → PluginsTab-MNQU5OJ3.js} +4 -4
  7. package/dist/host/{chunk-HQ6NNFSX.js → chunk-5W6F6GJJ.js} +68 -3
  8. package/dist/host/{chunk-P26QKKU5.js → chunk-6WLECSNB.js} +35 -5
  9. package/dist/host/{chunk-ROB2SH5Q.js → chunk-C52NRTA6.js} +9 -5
  10. package/dist/host/{chunk-VKNGNEF3.js → chunk-DN6YKMFJ.js} +1 -1
  11. package/dist/host/{chunk-TK3Y437H.js → chunk-EKXGDM5P.js} +1 -1
  12. package/dist/host/{chunk-JRV2HIDK.js → chunk-GRH7GSKG.js} +1 -1
  13. package/dist/host/{chunk-7J4QNGFM.js → chunk-IMPLAAUM.js} +1 -1
  14. package/dist/host/{chunk-I5F2PSMR.js → chunk-RWFXGG4Q.js} +9 -9
  15. package/dist/host/core-classes.json +1 -1
  16. package/dist/host/frame-host.css +1 -1
  17. package/dist/host/frame-host.js +5 -5
  18. package/dist/host/{linked-server-J5G457OA.js → linked-server-YCAJ2NX3.js} +1 -1
  19. package/dist/host/{rbac-api-PY22W5UY.js → rbac-api-A64TXDL5.js} +1 -1
  20. package/dist/host/testing-host.js +10 -6
  21. package/dist/host/types/src/ui/lib/db-health-monitor.d.ts +5 -0
  22. package/dist/host/types/src/ui/lib/plugin-transport.d.ts +5 -0
  23. package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +4 -0
  24. package/dist/host/types/src/ui/shell/HostTabEmbed.d.ts +15 -0
  25. package/dist/host/types/src/ui/shell/host-sections.d.ts +25 -0
  26. package/dist/host/ui.js +51 -9
  27. package/dist/host/{use-permissions-EWRI3WLT.js → use-permissions-FLQAN6I7.js} +1 -1
  28. package/dist/manifest.d.ts +6 -1
  29. package/dist/manifest.js +7 -1
  30. package/dist/operations.d.ts +222 -0
  31. package/dist/operations.js +650 -0
  32. package/dist/testing.d.ts +9 -1
  33. package/dist/testing.js +45 -0
  34. package/package.json +5 -1
  35. package/schema/manifest.schema.json +25 -0
@@ -0,0 +1,222 @@
1
+ /**
2
+ * The operations contract: what a plugin declares it can do, in one shape every
3
+ * surface reads (Automations, Fleets, AI, CLI, Mobile, palette, API, MCP).
4
+ *
5
+ * Declarations are data in the manifest, so a surface can list and describe an
6
+ * action without loading the plugin's code. Handlers are registered at
7
+ * activation with ctx.operations.register and must match a declaration.
8
+ *
9
+ * No Node imports: the frontend, the CLI and Mobile read this file too.
10
+ */
11
+ import type { PluginSettingsOption } from "./manifest.js";
12
+ export declare const OPERATION_RISKS: readonly ["read", "change", "destructive"];
13
+ export type OperationRisk = (typeof OPERATION_RISKS)[number];
14
+ export declare const OPERATION_SCOPES: readonly ["host", "resource", "server"];
15
+ export type OperationScope = (typeof OPERATION_SCOPES)[number];
16
+ export declare const OPERATION_HOST_ACCESS: readonly ["connect", "view", "edit", "manage"];
17
+ export type OperationHostAccess = (typeof OPERATION_HOST_ACCESS)[number];
18
+ export declare const OPERATION_DRY_RUN: readonly ["native", "describe"];
19
+ /** native: the handler checks ctx.dryRun. describe: core reports its text. */
20
+ export type OperationDryRun = (typeof OPERATION_DRY_RUN)[number];
21
+ export declare const OPERATION_FIELD_TYPES: readonly ["boolean", "string", "number", "select", "multiselect", "secret", "textarea", "json", "resource"];
22
+ export type OperationFieldType = (typeof OPERATION_FIELD_TYPES)[number];
23
+ export declare const OPERATION_SEVERITIES: readonly ["info", "warning", "critical"];
24
+ export type OperationSeverity = (typeof OPERATION_SEVERITIES)[number];
25
+ export declare const SIGNAL_KINDS: readonly ["count", "gauge", "status", "list"];
26
+ export type SignalKind = (typeof SIGNAL_KINDS)[number];
27
+ export declare const SIGNAL_STATUSES: readonly ["ok", "warn", "fail", "unknown"];
28
+ export type SignalStatus = (typeof SIGNAL_STATUSES)[number];
29
+ export declare const RESOURCE_COLUMN_TYPES: readonly ["text", "status", "bytes", "percent", "time", "tags"];
30
+ export type ResourceColumnType = (typeof RESOURCE_COLUMN_TYPES)[number];
31
+ /** One input or output of an action. A subset of a settings field, plus rules. */
32
+ export interface OperationField {
33
+ key: string;
34
+ type: OperationFieldType;
35
+ labelKey?: string;
36
+ descriptionKey?: string;
37
+ placeholderKey?: string;
38
+ default?: unknown;
39
+ options?: PluginSettingsOption[];
40
+ min?: number;
41
+ max?: number;
42
+ /** Key of a boolean field in the same list that must be on. */
43
+ requires?: string;
44
+ group?: string;
45
+ required?: boolean;
46
+ /** string and textarea only. A regular expression the whole value matches. */
47
+ pattern?: string;
48
+ /** Read action whose rows fill the choices, for a list known only at run time. */
49
+ optionsFrom?: string;
50
+ /** type "resource" only: the resource id whose list fills the picker. */
51
+ resource?: string;
52
+ /** Outputs only: dropped before a run is stored or shown. */
53
+ sensitive?: boolean;
54
+ }
55
+ export interface OperationWhen {
56
+ /** Host setting values that must match, such as { enableDocker: true }. */
57
+ settings?: Record<string, boolean | string | number>;
58
+ /** Lowercase OS names. A host with no known OS passes. */
59
+ os?: string[];
60
+ }
61
+ export interface OperationSurfaces {
62
+ /** Offered to the AI assistant. Off unless set. */
63
+ assistant?: boolean;
64
+ /** Offered over MCP. Off unless set. */
65
+ mcp?: boolean;
66
+ /** Set false to keep out of the command palette. */
67
+ palette?: boolean;
68
+ /** Set false to keep out of Automations. */
69
+ automations?: boolean;
70
+ /** Set false to keep out of the phone app. */
71
+ mobile?: boolean;
72
+ /** Set false to keep out of the CLI. */
73
+ cli?: boolean;
74
+ }
75
+ export interface OperationAction {
76
+ /** `<pluginId>.<name>`. */
77
+ id: string;
78
+ /** Bump when inputs change in a way saved references cannot follow. */
79
+ version?: number;
80
+ titleKey: string;
81
+ descriptionKey?: string;
82
+ icon?: string;
83
+ scope: OperationScope;
84
+ /** Required for scope "resource": the resource this acts on. */
85
+ resource?: string;
86
+ inputs?: OperationField[];
87
+ outputs?: OperationField[];
88
+ risk: OperationRisk;
89
+ /** One of this plugin's own permissions, short or full. */
90
+ permission: string;
91
+ /** Lowest share level. Required for host and resource scopes. */
92
+ hostAccess?: OperationHostAccess;
93
+ dryRun?: OperationDryRun;
94
+ /** A read action of this plugin that proves the result. */
95
+ check?: string;
96
+ /** An action of this plugin that reverses this one. */
97
+ undo?: string;
98
+ /** Safe to run twice, so a rollout may retry it. */
99
+ idempotent?: boolean;
100
+ /** Only one such action per host at a time. */
101
+ exclusive?: boolean;
102
+ timeoutMs?: number;
103
+ when?: OperationWhen;
104
+ surfaces?: OperationSurfaces;
105
+ }
106
+ export interface OperationEvent {
107
+ id: string;
108
+ titleKey: string;
109
+ descriptionKey?: string;
110
+ severity?: OperationSeverity;
111
+ scope: "host" | "server";
112
+ payload?: OperationField[];
113
+ }
114
+ export interface ResourceColumn {
115
+ key: string;
116
+ titleKey: string;
117
+ type?: ResourceColumnType;
118
+ }
119
+ export interface OperationResource {
120
+ id: string;
121
+ titleKey: string;
122
+ icon?: string;
123
+ /** Read action that returns { rows: [...] } for one host. */
124
+ list: string;
125
+ /** Row field that is unique on a host. */
126
+ key: string;
127
+ /** Row field shown as the name. */
128
+ name: string;
129
+ /** Row field holding a status word. */
130
+ status?: string;
131
+ /** Row field holding a link, for auto links on the homepage. */
132
+ url?: string;
133
+ /** Tab type that opens this on a host. */
134
+ tab?: string;
135
+ columns?: ResourceColumn[];
136
+ filters?: string[];
137
+ }
138
+ export interface OperationSignal {
139
+ id: string;
140
+ titleKey: string;
141
+ /** Read action that returns a SignalResult. */
142
+ read: string;
143
+ scope: "host" | "server";
144
+ kind: SignalKind;
145
+ refreshSec?: number;
146
+ /** Action offered as the fix when this signal is not ok. */
147
+ fix?: string;
148
+ }
149
+ export interface PluginOperationsContribution {
150
+ actions?: OperationAction[];
151
+ events?: OperationEvent[];
152
+ resources?: OperationResource[];
153
+ signals?: OperationSignal[];
154
+ /**
155
+ * Actions this plugin may run through ctx.operations.invoke: exact ids,
156
+ * `<pluginId>.*`, or `*`.
157
+ */
158
+ invokes?: string[];
159
+ }
160
+ /** What a signal's read action returns. */
161
+ export interface SignalResult {
162
+ value?: number | string | null;
163
+ status: SignalStatus;
164
+ label?: string;
165
+ items?: {
166
+ label: string;
167
+ status?: SignalStatus;
168
+ }[];
169
+ link?: {
170
+ tab?: string;
171
+ data?: Record<string, unknown>;
172
+ };
173
+ }
174
+ /** What a resource's list action returns. */
175
+ export interface ResourceListResult {
176
+ rows: Record<string, unknown>[];
177
+ }
178
+ /** What a handler returns. */
179
+ export interface OperationResult {
180
+ /** One plain line for history and per host results. */
181
+ summary: string;
182
+ /** Whether anything actually changed. */
183
+ changed?: boolean;
184
+ data?: unknown;
185
+ /** Input for the `undo` action that reverses this exact run. */
186
+ undoInput?: Record<string, unknown>;
187
+ }
188
+ export declare const OPERATION_ID_PATTERN: RegExp;
189
+ export declare const MAX_OPERATION_TIMEOUT_MS = 3600000;
190
+ export declare const REDACTED_VALUE = "[redacted]";
191
+ /** Shape checks for contributes.operations, run by validateManifest. */
192
+ export declare function validateOperations(value: unknown, pluginId: string | undefined, errors: string[]): void;
193
+ /**
194
+ * The cross-field rules: every id one declaration names must exist in this
195
+ * plugin, or a surface would offer a button that goes nowhere.
196
+ */
197
+ export declare function checkOperationReferences(operations: PluginOperationsContribution | undefined, capabilities: readonly string[], hasPermission: (name: string) => boolean, errors: string[]): void;
198
+ /** Whether a plugin's invokes list lets it run an action. */
199
+ export declare function invokeAllowed(invokes: readonly string[] | undefined, actionId: string): boolean;
200
+ export declare function riskRank(risk: OperationRisk): number;
201
+ /** A surface's own switch. The assistant and MCP are opt in, the rest opt out. */
202
+ export declare function onSurface(action: Pick<OperationAction, "surfaces">, surface: keyof OperationSurfaces): boolean;
203
+ /** Whether an action applies to a host, from fields any client can read. */
204
+ export declare function matchesWhen(when: OperationWhen | undefined, host: {
205
+ settings?: Record<string, unknown>;
206
+ os?: string | null;
207
+ }): boolean;
208
+ export interface OperationInputResult {
209
+ values: Record<string, unknown>;
210
+ errors: string[];
211
+ }
212
+ /**
213
+ * Turns raw input into validated values. Keys no field declares are refused,
214
+ * so nothing a handler did not ask for ever reaches it.
215
+ */
216
+ export declare function parseOperationInput(fields: readonly OperationField[] | undefined, raw: unknown): OperationInputResult;
217
+ /** A copy safe to store or show: secret and sensitive values are replaced. */
218
+ export declare function redactFields(fields: readonly OperationField[] | undefined, values: unknown): unknown;
219
+ /** Trims text to a byte-friendly length with a plain marker. */
220
+ export declare function capText(text: string, maxLength: number): string;
221
+ /** JSON Schema for a field list, for AI tools, MCP and OpenAPI. */
222
+ export declare function toJsonSchema(fields: readonly OperationField[] | undefined, describe?: (field: OperationField) => string | undefined): Record<string, unknown>;