@zhama/tego-plugin-sdk 0.0.0-stage → 1.36.0
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.
- package/LICENSE +172 -0
- package/README.md +846 -2
- package/access-catalog.schema.json +304 -0
- package/access-fixtures/resolve.json +1359 -0
- package/bin/tego-plugin-pack.mjs +2 -0
- package/bin/tego-plugin.mjs +3 -0
- package/dist/access-drizzle.cjs +1 -0
- package/dist/access-drizzle.d.cts +726 -0
- package/dist/access-drizzle.d.ts +726 -0
- package/dist/access-drizzle.js +1 -0
- package/dist/access-hono.cjs +3 -0
- package/dist/access-hono.d.cts +108 -0
- package/dist/access-hono.d.ts +108 -0
- package/dist/access-hono.js +3 -0
- package/dist/access-implications.cjs +1 -0
- package/dist/access-implications.d.cts +25 -0
- package/dist/access-implications.d.ts +25 -0
- package/dist/access-implications.js +1 -0
- package/dist/access.cjs +26 -0
- package/dist/access.d.cts +884 -0
- package/dist/access.d.ts +884 -0
- package/dist/access.js +26 -0
- package/dist/catalog-CSSbrfEf.d.cts +361 -0
- package/dist/catalog-CSSbrfEf.d.ts +361 -0
- package/dist/chunk-3KUOBGJN.js +19 -0
- package/dist/chunk-3WA3M347.cjs +1 -0
- package/dist/chunk-5CU33JVY.js +1 -0
- package/dist/chunk-7K37PVGV.js +5 -0
- package/dist/chunk-7XHF3YSK.js +1 -0
- package/dist/chunk-AJY7ZHXK.cjs +3 -0
- package/dist/chunk-BN6TGHSB.cjs +1 -0
- package/dist/chunk-BTHXQWHT.js +1 -0
- package/dist/chunk-C2OCOPZQ.cjs +1 -0
- package/dist/chunk-IMAVYQ4U.cjs +4 -0
- package/dist/chunk-OP64Y4IN.cjs +1 -0
- package/dist/chunk-QKSPPMVN.js +1 -0
- package/dist/chunk-ROFUQLOZ.cjs +1 -0
- package/dist/chunk-SNUCO2MK.js +1 -0
- package/dist/chunk-THMWRUAT.cjs +19 -0
- package/dist/chunk-VMCGDDGP.js +3 -0
- package/dist/chunk-W7C357A6.cjs +5 -0
- package/dist/chunk-WLTASJF6.js +4 -0
- package/dist/egress.cjs +7 -0
- package/dist/egress.d.cts +9 -0
- package/dist/egress.d.ts +9 -0
- package/dist/egress.js +7 -0
- package/dist/frontend.cjs +2 -0
- package/dist/frontend.d.cts +353 -0
- package/dist/frontend.d.ts +353 -0
- package/dist/frontend.js +2 -0
- package/dist/gateway-signature.cjs +1 -0
- package/dist/gateway-signature.d.cts +112 -0
- package/dist/gateway-signature.d.ts +112 -0
- package/dist/gateway-signature.js +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +528 -0
- package/dist/index.d.ts +528 -0
- package/dist/index.js +1 -0
- package/dist/manifest-types-DQARCQJt.d.cts +627 -0
- package/dist/manifest-types-DQARCQJt.d.ts +627 -0
- package/dist/manifest.cjs +1 -0
- package/dist/manifest.d.cts +2824 -0
- package/dist/manifest.d.ts +2824 -0
- package/dist/manifest.js +1 -0
- package/dist/mcp-identity.cjs +2 -0
- package/dist/mcp-identity.d.cts +106 -0
- package/dist/mcp-identity.d.ts +106 -0
- package/dist/mcp-identity.js +2 -0
- package/dist/pack.cjs +1 -0
- package/dist/pack.d.cts +169 -0
- package/dist/pack.d.ts +169 -0
- package/dist/pack.js +1 -0
- package/dist/publish.cjs +1 -0
- package/dist/publish.d.cts +96 -0
- package/dist/publish.d.ts +96 -0
- package/dist/publish.js +1 -0
- package/dist/scaffold.cjs +523 -0
- package/dist/scaffold.d.cts +182 -0
- package/dist/scaffold.d.ts +182 -0
- package/dist/scaffold.js +523 -0
- package/dist/server-runtime.cjs +1 -0
- package/dist/server-runtime.d.cts +63 -0
- package/dist/server-runtime.d.ts +63 -0
- package/dist/server-runtime.js +1 -0
- package/dist/server.cjs +1 -0
- package/dist/server.d.cts +1808 -0
- package/dist/server.d.ts +1808 -0
- package/dist/server.js +1 -0
- package/dist/testing.cjs +2 -0
- package/dist/testing.d.cts +92 -0
- package/dist/testing.d.ts +92 -0
- package/dist/testing.js +2 -0
- package/dist/vite.cjs +1 -0
- package/dist/vite.d.cts +133 -0
- package/dist/vite.d.ts +133 -0
- package/dist/vite.js +1 -0
- package/package.json +160 -4
- package/sql/access.sql +73 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
import { P as PluginPublicRoute, a as PluginBackendRuntime, b as PluginScope, c as PluginPartName, d as PluginDeclares, e as PluginConfigSection, f as PluginConfigSectionSummary, T as TegoPluginManifest, L as LocalizedText, g as PluginNavIcon, h as PluginNavEntry, i as PluginAgentReadinessDeclaration } from './manifest-types-DQARCQJt.cjs';
|
|
2
|
+
export { C as CLAW_MANIFEST_FILENAME, E as EMPTY_CONFIG_SECTION_SUMMARY, j as PLUGIN_BACKEND_PLATFORMS, k as PLUGIN_BACKEND_RUNTIMES, l as PLUGIN_CONFIG_SECRET_SENTINEL, m as PLUGIN_CONFIG_SECTIONS, n as PLUGIN_MANIFEST_FILENAME, o as PLUGIN_NAV_ICONS, p as PLUGIN_NAV_ICON_FALLBACK, q as PLUGIN_PART_DEFAULTS, r as PLUGIN_PART_NAMES, s as PluginAgentReadinessItem, t as PluginAgentReadinessResponse, u as PluginAuditDeclarations, v as PluginAuditToolDeclaration, w as PluginBackendLimits, x as PluginBackendPart, y as PluginBackendPlatform, z as PluginClawPart, A as PluginConfigDeclaration, B as PluginConfigFieldSchema, D as PluginConfigFieldType, F as PluginConfigSchema, G as PluginConfigUiHint, H as PluginFrontendPart, I as PluginParts, J as PluginPermissions, K as PluginPublicFrontendPart, M as PluginPublicRouteMethod, N as PluginSchemaRepair, O as PluginWorkDelegationDeclaration, R as ResolvedBackendPart, Q as ResolvedClawPart, S as ResolvedFrontendPart, U as ResolvedPluginParts, V as ResolvedPublicFrontendPart, W as applyConfigDefaults, X as configFieldLabel, Y as declaredPartNames, Z as redactSecrets, _ as resolvePluginDeclares, $ as resolvePluginParts, a0 as resolvePluginScope, a1 as restoreSecrets, a2 as summarizeClawConfig, a3 as summarizeConfigDeclaration } from './manifest-types-DQARCQJt.cjs';
|
|
3
|
+
import { A as AccessCatalog } from './catalog-CSSbrfEf.cjs';
|
|
4
|
+
import 'zod';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Anonymous entry points: how a `publicRoutes` declaration is written, and
|
|
8
|
+
* how a request is matched against it.
|
|
9
|
+
*
|
|
10
|
+
* Shared by the manifest validator, which refuses ambiguous declarations, and
|
|
11
|
+
* the gateway, which forwards only what matches. One definition, so a route
|
|
12
|
+
* the validator accepted cannot be matched differently at request time.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
declare const PLUGIN_PUBLIC_ROUTE_METHODS: readonly ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
16
|
+
/**
|
|
17
|
+
* Where anonymous traffic enters, under the API prefix. The two share a
|
|
18
|
+
* prefix so a public page can find its API from its own address.
|
|
19
|
+
*/
|
|
20
|
+
declare const PLUGIN_PUBLIC_API_PATH = "/public/plugins/api";
|
|
21
|
+
declare const PLUGIN_PUBLIC_PAGES_PATH = "/public/plugins/pages";
|
|
22
|
+
declare const PLUGIN_AVATAR_PUBLIC_API_PATH = "/public/plugins/avatars/api";
|
|
23
|
+
declare const PLUGIN_AVATAR_PUBLIC_PAGES_PATH = "/public/plugins/avatars/pages";
|
|
24
|
+
/** `GET /public/inspections/:token` — the form the gateway forwards and the backend reads. */
|
|
25
|
+
declare function formatPublicRoute(route: PluginPublicRoute): string;
|
|
26
|
+
interface PublicRouteMatch {
|
|
27
|
+
/** The declaration, formatted with {@link formatPublicRoute}. */
|
|
28
|
+
route: string;
|
|
29
|
+
/** Parameter values, still percent-encoded as they arrived. */
|
|
30
|
+
params: Record<string, string>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The declaration this request matches, or null.
|
|
34
|
+
*
|
|
35
|
+
* `path` is the part after the plugin's public prefix, as it appears on the
|
|
36
|
+
* wire. Exact on method and on the number of segments; a trailing slash or an
|
|
37
|
+
* empty segment matches nothing.
|
|
38
|
+
*/
|
|
39
|
+
declare function matchPublicRoute(routes: readonly PluginPublicRoute[], method: string, path: string): PublicRouteMatch | null;
|
|
40
|
+
/**
|
|
41
|
+
* The API prefix a public page should call, derived from the page's own path.
|
|
42
|
+
*
|
|
43
|
+
* `/api/v1/tego-os/public/plugins/pages/<tenant>/<plugin>/` →
|
|
44
|
+
* `/api/v1/tego-os/public/plugins/api/<tenant>/<plugin>`. Null when the page
|
|
45
|
+
* is not being served from the public pages route — a local dev server, say —
|
|
46
|
+
* so the caller can fall back to its own configuration.
|
|
47
|
+
*/
|
|
48
|
+
declare function publicApiBaseFromPagePath(pathname: string): string | null;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* What an operator is shown before confirming an install.
|
|
52
|
+
*
|
|
53
|
+
* Everything here is derived from facts the package already states — the claw
|
|
54
|
+
* manifest's tool contract, the nav entries, the declares block — and computed
|
|
55
|
+
* once at upload rather than at each install, so the admin UI never has to
|
|
56
|
+
* open an archive and the payload can be snapshotted onto the install row.
|
|
57
|
+
*
|
|
58
|
+
* That snapshot is the point. Upgrading to a release that adds five tools and
|
|
59
|
+
* a menu entry is the moment those additions are decided, and the only way to
|
|
60
|
+
* show "this is more than you accepted last time" is to have kept last time's
|
|
61
|
+
* answer.
|
|
62
|
+
*
|
|
63
|
+
* Disclosure is not itself authorisation. The host separately enforces gated
|
|
64
|
+
* capabilities such as `directory.read`; database declaration controls schema
|
|
65
|
+
* provisioning. Frontend code still runs with the shell's own privileges.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
interface PluginDisclosureNavEntry {
|
|
69
|
+
key: string;
|
|
70
|
+
/** Resolved against the plugin's own bundle, as everywhere else. */
|
|
71
|
+
labelKey: string;
|
|
72
|
+
/**
|
|
73
|
+
* The menu permission name derived from the entry. Older hosts wrote and
|
|
74
|
+
* granted it; this one does not, and keeps the field so stored snapshots
|
|
75
|
+
* keep their shape.
|
|
76
|
+
*/
|
|
77
|
+
permission: string;
|
|
78
|
+
/** Host route the entry links to. */
|
|
79
|
+
path: string;
|
|
80
|
+
}
|
|
81
|
+
interface PluginInstallDisclosure {
|
|
82
|
+
/** Optional only for snapshots created before host capability disclosure. */
|
|
83
|
+
requiredPermissions?: string[];
|
|
84
|
+
/**
|
|
85
|
+
* External targets the backend may reach through the egress proxy. Optional
|
|
86
|
+
* only for snapshots created before egress existed; those releases could
|
|
87
|
+
* reach none.
|
|
88
|
+
*/
|
|
89
|
+
egress?: string[];
|
|
90
|
+
/**
|
|
91
|
+
* Routes anyone can call without signing in, as `METHOD /path`. Optional
|
|
92
|
+
* only for snapshots created before public routes existed; those releases
|
|
93
|
+
* had none.
|
|
94
|
+
*/
|
|
95
|
+
publicRoutes?: string[];
|
|
96
|
+
/** Absent when there is no backend part, and on snapshots that predate it. */
|
|
97
|
+
backendRuntime?: PluginBackendRuntime;
|
|
98
|
+
scope: PluginScope;
|
|
99
|
+
parts: PluginPartName[];
|
|
100
|
+
declares: Required<PluginDeclares>;
|
|
101
|
+
nav: PluginDisclosureNavEntry[];
|
|
102
|
+
/**
|
|
103
|
+
* Tool names the claw part adds to every selected avatar's agent.
|
|
104
|
+
*
|
|
105
|
+
* From the claw manifest's own `contracts.tools`, which claw already treats
|
|
106
|
+
* as the extension's declared surface. Empty for a plugin with no claw part,
|
|
107
|
+
* and also for a claw part that declares no contract — the second case is
|
|
108
|
+
* indistinguishable here, which is why the UI phrases it as "declares no
|
|
109
|
+
* tools" rather than "adds nothing".
|
|
110
|
+
*/
|
|
111
|
+
clawTools: string[];
|
|
112
|
+
/**
|
|
113
|
+
* Claw tools with no `audit.tools` wording. The audit trail shows these by
|
|
114
|
+
* raw tool name and parameters. Absent on snapshots that predate it.
|
|
115
|
+
*/
|
|
116
|
+
auditUndeclaredTools?: string[];
|
|
117
|
+
/**
|
|
118
|
+
* What the operator will be asked to fill in, per section.
|
|
119
|
+
*
|
|
120
|
+
* Three summaries rather than one total, because only the backend section's
|
|
121
|
+
* required fields can hold a container back — the install screen has to be
|
|
122
|
+
* able to say which of the three is the blocking one.
|
|
123
|
+
*/
|
|
124
|
+
config: Record<PluginConfigSection, PluginConfigSectionSummary>;
|
|
125
|
+
/**
|
|
126
|
+
* Size of the plugin's own role model: permissions it defines (the two the
|
|
127
|
+
* SDK reserves for managing access are not counted) and the roles it ships.
|
|
128
|
+
* Absent when the release declares no access catalog.
|
|
129
|
+
*/
|
|
130
|
+
access?: {
|
|
131
|
+
permissions: number;
|
|
132
|
+
roles: number;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* How `audit.tools` lines up with the tools the claw part registers.
|
|
137
|
+
*
|
|
138
|
+
* `undeclared` tools still appear in the audit trail, only by raw name.
|
|
139
|
+
* `unknown` declarations can never match a call, which is almost always a
|
|
140
|
+
* renamed tool, so upload refuses them.
|
|
141
|
+
*/
|
|
142
|
+
declare function auditDeclarationGaps(manifest: TegoPluginManifest, clawTools: string[]): {
|
|
143
|
+
undeclared: string[];
|
|
144
|
+
unknown: string[];
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* @param clawManifest The parsed `openclaw.plugin.json` of the claw part, or
|
|
148
|
+
* null when the package ships none.
|
|
149
|
+
* @param accessCatalog The validated `manifest.access.catalog`, or null when
|
|
150
|
+
* the release declares none.
|
|
151
|
+
*/
|
|
152
|
+
declare function buildInstallDisclosure(manifest: TegoPluginManifest, clawManifest?: Record<string, unknown> | null, accessCatalog?: AccessCatalog | null): PluginInstallDisclosure;
|
|
153
|
+
/**
|
|
154
|
+
* Whether an operator has to fill something in before this release can run.
|
|
155
|
+
*
|
|
156
|
+
* Only the backend section counts. A missing frontend or claw setting is a
|
|
157
|
+
* page or an agent behaving with defaults, which is a choice the plugin made;
|
|
158
|
+
* a missing backend setting is a process that would start and fail.
|
|
159
|
+
*/
|
|
160
|
+
declare function requiresBackendConfig(disclosure: PluginInstallDisclosure): boolean;
|
|
161
|
+
/** One thing a target release discloses that the accepted snapshot did not. */
|
|
162
|
+
interface PluginDisclosureAddition {
|
|
163
|
+
kind: 'part' | 'declares' | 'nav' | 'clawTool' | 'configRequired' | 'permission' | 'egress' | 'publicRoute';
|
|
164
|
+
/**
|
|
165
|
+
* Part name, declares key, nav key, tool name, `<section>.<field>` for a
|
|
166
|
+
* newly required setting, or `METHOD /path` for a public route.
|
|
167
|
+
*/
|
|
168
|
+
value: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* What an upgrade adds relative to what was accepted.
|
|
172
|
+
*
|
|
173
|
+
* Additions only. A release that drops a tool or a menu entry needs no consent
|
|
174
|
+
* — the operator is not being asked for anything new — and listing removals
|
|
175
|
+
* alongside additions in the same confirmation makes the additions harder to
|
|
176
|
+
* see, which is the one thing the screen exists for.
|
|
177
|
+
*
|
|
178
|
+
* A null snapshot means the install predates disclosure, so everything the
|
|
179
|
+
* target declares is new to the record. Reporting it all is the honest answer:
|
|
180
|
+
* nobody ever saw a list for this install.
|
|
181
|
+
*/
|
|
182
|
+
declare function diffInstallDisclosure(accepted: PluginInstallDisclosure | null, target: PluginInstallDisclosure): PluginDisclosureAddition[];
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* The host API contract: which modules the shell shares with plugin frontends,
|
|
186
|
+
* and how a plugin declares the version it was built against.
|
|
187
|
+
*
|
|
188
|
+
* Plugin frontends are built as SystemJS modules with every id below marked
|
|
189
|
+
* external, so the shell hands them its own singletons at load time. That is
|
|
190
|
+
* what lets a plugin use `@tego/ui` and share one React instance with the host
|
|
191
|
+
* instead of shipping — and duplicating — its own copy.
|
|
192
|
+
*
|
|
193
|
+
* SystemJS rather than import maps: the app's Vite `build.target` is
|
|
194
|
+
* `chrome87 / firefox78 / safari14 / edge88`, and import maps need Chrome 89 /
|
|
195
|
+
* Safari 16.4 / Firefox 108. The shared module *ids* are the contract, so the
|
|
196
|
+
* loader can be swapped once those targets rise without touching plugins.
|
|
197
|
+
*/
|
|
198
|
+
/**
|
|
199
|
+
* Version of the shared module surface below.
|
|
200
|
+
*
|
|
201
|
+
* Bump the major whenever any shared module's public surface breaks — that
|
|
202
|
+
* includes upgrading `@tego/ui` or `@tego/chat` across a breaking change.
|
|
203
|
+
* Installed plugins declaring an incompatible range are then refused at load
|
|
204
|
+
* time with a readable reason instead of failing inside a hook.
|
|
205
|
+
*
|
|
206
|
+
* The minor moves when the surface gains something a plugin can require
|
|
207
|
+
* without older plugins caring: 1.1.0 added `ChatSurface` and the optional
|
|
208
|
+
* `metadata` argument to `useTopic().createTopic`, 1.2.0 added
|
|
209
|
+
* `PluginHostContext.route` and `user.displayName`, 1.3.0 added
|
|
210
|
+
* `PluginHostContext.events`, 1.4.0 added `PluginHostContext.config`, and
|
|
211
|
+
* 1.7.0 adds source-paragraph citations without model-transcribed quotes.
|
|
212
|
+
* 1.5.0 added the backend `directory` capability; 1.6.0 added verified
|
|
213
|
+
* references to existing platform knowledge through `knowledge`. 1.10.0 adds
|
|
214
|
+
* python backends, declared egress, public routes with
|
|
215
|
+
* `PluginHostContext.publicPagesUrl`, and plugin-owned knowledge
|
|
216
|
+
* collections. 1.12.0 adds browser uploads of large objects: backend
|
|
217
|
+
* `storage.uploadPath` / `head` / `signedPath` / `get` with `firstBytes`,
|
|
218
|
+
* resolved in the frontend by `PluginHostContext.hostUrl`. 1.14.0 adds
|
|
219
|
+
* `PluginHostContext.layout.collapseSidebar` for plugin pages that need the
|
|
220
|
+
* host navigation sidebar to yield space. A plugin needing a newer surface
|
|
221
|
+
* declares e.g. `^1.14.0` while one built against `^1.0.0` keeps loading.
|
|
222
|
+
*
|
|
223
|
+
* 1.18.0 adds ordinary platform account password resets through the existing\n * accounts.provision capability; platform administrator accounts remain protected.\n *
|
|
224
|
+
* 1.22.0 adds the manifest `access` field (plugin-owned roles and permissions
|
|
225
|
+
* through `@tego/plugin-sdk/access`) and `PluginHostApi.tenantId`, which the
|
|
226
|
+
* access engine needs before any request arrives.
|
|
227
|
+
*
|
|
228
|
+
* 1.24.0 adds authorized library reads and revision-checked Office artifact saves
|
|
229
|
+
* through PluginHostContext.office; all business ownership remains in plugins.
|
|
230
|
+
*
|
|
231
|
+
* 1.25.0 adds organization-mapped, multi-target file sync and visible sync locations.
|
|
232
|
+
*
|
|
233
|
+
* 1.26.0 adds backend `proactive.emit`: an event that starts the user's
|
|
234
|
+
* event-triggered scheduled tasks listening for this plugin.
|
|
235
|
+
*
|
|
236
|
+
* 1.27.0 adds an optional execution budget to frontend `ai.draft` through
|
|
237
|
+
* `timeoutMs`, with a separate final-response grace period.
|
|
238
|
+
*
|
|
239
|
+
* 1.28.0 adds `@tego/ui` analysis primitives: `ComboChart`, `WaterfallChart`,
|
|
240
|
+
* `Sparkline`, `DeltaIndicator`, `DateRangePicker` and the `chartScale` axis
|
|
241
|
+
* helpers behind them.
|
|
242
|
+
*
|
|
243
|
+
* 1.29.0 adds backend `mail.send`: email from the person's own connected
|
|
244
|
+
* mailbox, at most once per idempotency key, with the host's unsubscribe link.
|
|
245
|
+
*
|
|
246
|
+
* 1.30.0 adds the manifest `agentReadiness` endpoint and
|
|
247
|
+
* `workDelegation.settingsRoute`, both read by the employee usage guide.
|
|
248
|
+
*
|
|
249
|
+
* 1.31.0 adds `@tego/ui` `InfoTip`: the (?) that holds a label's explanation.
|
|
250
|
+
*
|
|
251
|
+
* 1.32.0 adds the `@tego/ui` token readers (`tokenColor`, `contrastRatio` and
|
|
252
|
+
* the HSL helpers), `useChartTheme` / `buildChartTheme` for ECharts,
|
|
253
|
+
* `MetricValue`, `PanelHeader`, the `live` `StatusDot` tone, and the shared
|
|
254
|
+
* Tailwind preset that plugin frontends compile against: the `success`,
|
|
255
|
+
* `warning`, `info`, `signal` tones with their `-soft` / `-foreground` forms,
|
|
256
|
+
* surfaces (`raised`, `sunken`, `inset`, `overlay`, `border-strong`),
|
|
257
|
+
* `chart-1..8`, `action`, `file-*`, the named shadows, durations, easings and
|
|
258
|
+
* radii, and the `.identity-surface` hue variables.
|
|
259
|
+
*
|
|
260
|
+
* 1.33.0 adds `PluginHostContext.delegation`: the host's work delegation
|
|
261
|
+
* consent dialog and state, plus the manifest `workDelegation.summary`,
|
|
262
|
+
* `privacyPolicyUrl` and `conversationCapture` it shows.
|
|
263
|
+
*
|
|
264
|
+
* 1.34.0 adds backend `attention.request` / `get` / `cancel`: ask a person
|
|
265
|
+
* to answer, approve or take over, on behalf of the user the plugin acts for.
|
|
266
|
+
*
|
|
267
|
+
* 1.35.0 adds `@tego/ui` design token `chatBubbles.user` (the bubble of a
|
|
268
|
+
* message the viewer sent), and `useResizableWidth` with `ResizeHandle`: a
|
|
269
|
+
* panel edge the user drags to resize, remembered per viewer.
|
|
270
|
+
*
|
|
271
|
+
* 1.36.0 adds write-side knowledge ACL projection: collection read suspension,
|
|
272
|
+
* identity revision fencing and durable document moves by externalId. Managed
|
|
273
|
+
* collection reads use existing ACLs; policyScope is deprecated.
|
|
274
|
+
*
|
|
275
|
+
* This numbers the *host API surface*, not the `@tego/plugin-sdk` npm package
|
|
276
|
+
* — the two move on their own clocks. A manifest declares compatibility
|
|
277
|
+
* against this constant through `hostApiRange`; the SDK's own package version
|
|
278
|
+
* is a build-time dependency and never reaches a manifest.
|
|
279
|
+
*/
|
|
280
|
+
declare const HOST_API_VERSION = "1.36.0";
|
|
281
|
+
/**
|
|
282
|
+
* Module specifiers the shell provides to plugin frontends.
|
|
283
|
+
*
|
|
284
|
+
* Everything listed here is frozen: its public surface is part of
|
|
285
|
+
* `HOST_API_VERSION`, so breaking any of it means a major bump that refuses
|
|
286
|
+
* every installed plugin declaring an older range. That cost is why the list
|
|
287
|
+
* is the minimum a native-looking page cannot be built without, and why two
|
|
288
|
+
* things are not on it.
|
|
289
|
+
*
|
|
290
|
+
* `@tego/chat/plugin-surface` is a narrow subpath rather than the `@tego/chat`
|
|
291
|
+
* barrel: plugins need the conversation panel and topic resolution (a
|
|
292
|
+
* record-page agent panel is the point), but freezing the store, every slice
|
|
293
|
+
* hook and the pages would stop chat from evolving.
|
|
294
|
+
*
|
|
295
|
+
* `@tego/shared` is absent for the same reason, having no subpath narrow
|
|
296
|
+
* enough to be worth one yet. Its barrel reaches from `HttpClient` and
|
|
297
|
+
* `TypedStorage` through the license payload and the paywall bridge to the
|
|
298
|
+
* chat store context — a contract nothing has asked for, over which a plugin
|
|
299
|
+
* would reach the platform's own APIs directly instead of through
|
|
300
|
+
* `PluginHostContext.api`, where the namespace and the tenant are enforced.
|
|
301
|
+
* `cn` — the one thing a plugin composing `@tego/ui` reliably needs — is
|
|
302
|
+
* re-exported by `@tego/ui` itself. When a plugin page genuinely cannot be
|
|
303
|
+
* built without something else from shared, add a `plugin-surface` subpath
|
|
304
|
+
* exporting that and bump the host API version.
|
|
305
|
+
*
|
|
306
|
+
* `@tanstack/react-query` is absent for a different reason: sharing it is a
|
|
307
|
+
* trap. A plugin mounts into its own React root (see `frontend.ts`), so the
|
|
308
|
+
* shell's `QueryClientProvider` is not an ancestor of anything the plugin
|
|
309
|
+
* renders, and the first `useQuery` throws "No QueryClient set" — the module
|
|
310
|
+
* would be shared while the provider that makes it usable is not. A plugin
|
|
311
|
+
* needing it brings its own client and provider, which costs a few KB and
|
|
312
|
+
* works. Passing the shell's client through the host context is the
|
|
313
|
+
* alternative, and it would put React in the SDK's contract to buy a shared
|
|
314
|
+
* cache nothing needs yet.
|
|
315
|
+
*
|
|
316
|
+
* The three React entries are what genuinely cannot be duplicated: two React
|
|
317
|
+
* instances break hooks on the first render. `react-i18next` is here because
|
|
318
|
+
* it resolves the default i18next instance the host has already merged the
|
|
319
|
+
* plugin's own bundle into, so it works without a provider.
|
|
320
|
+
*/
|
|
321
|
+
declare const SHARED_MODULE_IDS: readonly ["react", "react-dom", "react-dom/client", "react/jsx-runtime", "@tego/ui", "react-i18next", "lucide-react", "@tego/chat/plugin-surface"];
|
|
322
|
+
type SharedModuleId = (typeof SHARED_MODULE_IDS)[number];
|
|
323
|
+
/**
|
|
324
|
+
* Only `^X.Y.Z` and exact `X.Y.Z` are accepted.
|
|
325
|
+
*
|
|
326
|
+
* A plugin needs to say no more than "built against 1.2.0, fine with any
|
|
327
|
+
* later 1.x". Supporting the full npm range grammar would add a dependency and
|
|
328
|
+
* a set of ambiguities (`||`, `-`, `x` wildcards) that nothing here benefits
|
|
329
|
+
* from, and the repo already hand-rolls the comparison in `skill-semver.ts`
|
|
330
|
+
* for the same reason.
|
|
331
|
+
*/
|
|
332
|
+
declare function isValidHostApiRange(range: string): boolean;
|
|
333
|
+
/**
|
|
334
|
+
* Oldest host version a valid range admits — the version a manifest feature
|
|
335
|
+
* introduced in must not be newer than this.
|
|
336
|
+
*/
|
|
337
|
+
declare function hostApiRangeMinimum(range: string): string;
|
|
338
|
+
/**
|
|
339
|
+
* @param range A range accepted by {@link isValidHostApiRange}.
|
|
340
|
+
* @param hostVersion Usually {@link HOST_API_VERSION}.
|
|
341
|
+
* @throws Error when the range grammar is unsupported, so an invalid manifest
|
|
342
|
+
* fails loudly at validation rather than silently denying every load.
|
|
343
|
+
*/
|
|
344
|
+
declare function satisfiesHostApiRange(range: string, hostVersion: string): boolean;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* What the shell learns about a plugin before any of its code runs.
|
|
348
|
+
*
|
|
349
|
+
* The sidebar has to render a plugin's entries at startup, which is before the
|
|
350
|
+
* plugin module is fetched — otherwise every installed plugin would be on the
|
|
351
|
+
* critical path of the first paint. So the labels, the routes and the version
|
|
352
|
+
* gate all travel in this payload, and the plugin's own JavaScript is fetched
|
|
353
|
+
* only when the user opens one of its pages.
|
|
354
|
+
*
|
|
355
|
+
* The naming helpers live here rather than on either side because both sides
|
|
356
|
+
* derive the same strings: the server writes the permission rows at install
|
|
357
|
+
* time and the shell checks them at render time. Two copies of the format
|
|
358
|
+
* would drift, and the symptom would be a sidebar entry that is invisible for
|
|
359
|
+
* reasons no log explains.
|
|
360
|
+
*/
|
|
361
|
+
|
|
362
|
+
interface InstalledPluginFrontend {
|
|
363
|
+
/**
|
|
364
|
+
* SystemJS entry module, as a path under the API root.
|
|
365
|
+
*
|
|
366
|
+
* A path rather than a URL because the desktop shell is served from a
|
|
367
|
+
* custom protocol and its API lives on another origin: only the client
|
|
368
|
+
* knows which base to join this to. The path carries the version, and
|
|
369
|
+
* releases are immutable, so the module itself can be cached forever.
|
|
370
|
+
*/
|
|
371
|
+
entryPath: string;
|
|
372
|
+
/** Prefix the rest of the frontend part is served under, entry included. */
|
|
373
|
+
assetBasePath: string;
|
|
374
|
+
/**
|
|
375
|
+
* Where this plugin's locale bundles are served, one JSON per tag.
|
|
376
|
+
*
|
|
377
|
+
* Resolved by the host because the manifest lets a plugin move the
|
|
378
|
+
* directory; the shell only ever joins a language tag onto this.
|
|
379
|
+
*/
|
|
380
|
+
localeBasePath: string;
|
|
381
|
+
/**
|
|
382
|
+
* Locale tags the package ships a bundle for.
|
|
383
|
+
*
|
|
384
|
+
* The shell fetches only the active language, and falls back to the first
|
|
385
|
+
* listed tag when the active language is not among them.
|
|
386
|
+
*/
|
|
387
|
+
locales: string[];
|
|
388
|
+
/** The plugin's icon in the sidebar. Absent when it declared none. */
|
|
389
|
+
icon?: PluginNavIcon;
|
|
390
|
+
nav: PluginNavEntry[];
|
|
391
|
+
/**
|
|
392
|
+
* The `frontend` configuration section, with declared defaults applied.
|
|
393
|
+
*
|
|
394
|
+
* Travels with discovery rather than being fetched by the plugin, so a
|
|
395
|
+
* surface has its settings before it renders anything — a plugin whose theme
|
|
396
|
+
* or endpoint came in a second round trip would flash the wrong one first.
|
|
397
|
+
*
|
|
398
|
+
* This section only, and it carries no secrets: a frontend section that
|
|
399
|
+
* marks a field sensitive is refused at upload, because everything the
|
|
400
|
+
* browser receives is public.
|
|
401
|
+
*/
|
|
402
|
+
config: Record<string, unknown>;
|
|
403
|
+
}
|
|
404
|
+
interface InstalledPlugin {
|
|
405
|
+
pluginId: string;
|
|
406
|
+
version: string;
|
|
407
|
+
displayName: LocalizedText;
|
|
408
|
+
/**
|
|
409
|
+
* Host API range the release declares, or null for a claw-only plugin that
|
|
410
|
+
* loads nothing into this process.
|
|
411
|
+
*/
|
|
412
|
+
hostApiRange: string | null;
|
|
413
|
+
/** Absent when the plugin ships no frontend part. */
|
|
414
|
+
frontend?: InstalledPluginFrontend;
|
|
415
|
+
/** Whether {@link pluginApiPath} reaches a running backend. */
|
|
416
|
+
hasBackend: boolean;
|
|
417
|
+
/** What the manifest declares; decides whether {@link avatarIds} applies. */
|
|
418
|
+
scope: PluginScope;
|
|
419
|
+
/**
|
|
420
|
+
* Avatars this viewer can reach that have the plugin installed.
|
|
421
|
+
*
|
|
422
|
+
* The sidebar shows an avatar-scoped plugin only while the active avatar is
|
|
423
|
+
* in this list, so switching avatars changes which plugins are on offer
|
|
424
|
+
* without another round trip. Always empty for a tenant-scoped plugin,
|
|
425
|
+
* which belongs to no avatar and is always shown.
|
|
426
|
+
*
|
|
427
|
+
* Filtered to what the viewer may see, so it is never a listing of avatars
|
|
428
|
+
* they have no access to.
|
|
429
|
+
*/
|
|
430
|
+
avatarIds: string[];
|
|
431
|
+
/** Declared per-user business readiness endpoint when present. */
|
|
432
|
+
agentReadiness?: PluginAgentReadinessDeclaration;
|
|
433
|
+
/** Plugin page where a person delegates work to an employee, when declared. */
|
|
434
|
+
workDelegationSettingsRoute?: string;
|
|
435
|
+
/** What the host consent dialog shows; present exactly when the manifest declares `workDelegation`. */
|
|
436
|
+
workDelegation?: InstalledPluginWorkDelegation;
|
|
437
|
+
}
|
|
438
|
+
interface InstalledPluginWorkDelegation {
|
|
439
|
+
summary?: LocalizedText;
|
|
440
|
+
privacyPolicyUrl?: string;
|
|
441
|
+
conversationCapture?: boolean;
|
|
442
|
+
/** External targets the backend may reach, from the install disclosure. `*` means any. */
|
|
443
|
+
egress: string[];
|
|
444
|
+
}
|
|
445
|
+
interface InstalledPluginsResponse {
|
|
446
|
+
plugins: InstalledPlugin[];
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Locale tags every plugin that ships UI must provide a bundle for.
|
|
450
|
+
*
|
|
451
|
+
* The same ten the platform itself serves. A plugin page is not a separate
|
|
452
|
+
* product: shipping only `en` and `zh-CN` means a Japanese operator sees a
|
|
453
|
+
* sidebar where most rows are translated and this plugin's are not, which
|
|
454
|
+
* reads as the platform being half-finished rather than as one package
|
|
455
|
+
* lagging.
|
|
456
|
+
*
|
|
457
|
+
* Enforced at upload, where the author can act on it, rather than left to the
|
|
458
|
+
* runtime fallback — a fallback hides the gap forever.
|
|
459
|
+
*/
|
|
460
|
+
declare const PLUGIN_SUPPORTED_LOCALES: readonly ["zh-CN", "zh-TW", "en", "ja", "ko", "de", "es", "fr", "it", "pt"];
|
|
461
|
+
type PluginSupportedLocale = (typeof PLUGIN_SUPPORTED_LOCALES)[number];
|
|
462
|
+
/**
|
|
463
|
+
* i18next namespace a plugin's bundle is registered under.
|
|
464
|
+
*
|
|
465
|
+
* Namespaced because plugin bundles are merged into the host's i18n instance,
|
|
466
|
+
* and a plugin shipping a `common.save` key must not overwrite the host's.
|
|
467
|
+
*
|
|
468
|
+
* Dot-separated, not colon-separated: i18next splits `ns:key` on the first
|
|
469
|
+
* colon, so a namespace containing one would swallow part of the key. A plugin
|
|
470
|
+
* id may itself contain dots, which is harmless — only the colon matters.
|
|
471
|
+
*/
|
|
472
|
+
declare function pluginI18nNamespace(pluginId: string): string;
|
|
473
|
+
/** Fully qualified `ns:key` for one of a plugin's own translation keys. */
|
|
474
|
+
declare function pluginI18nKey(pluginId: string, labelKey: string): string;
|
|
475
|
+
/** The `system_menus.key` older hosts derived for one nav entry. */
|
|
476
|
+
declare function pluginMenuKey(pluginId: string, navKey: string): string;
|
|
477
|
+
/**
|
|
478
|
+
* Longest a derived permission name may be.
|
|
479
|
+
*
|
|
480
|
+
* Older hosts write the name into `permissions.name` and `system_menus.key`,
|
|
481
|
+
* both `varchar(100)`, and the id and nav key limits allow far more than that
|
|
482
|
+
* between them. A pair that overflows is refused at upload, with a message
|
|
483
|
+
* naming the two fields that are too long together, so a manifest that
|
|
484
|
+
* validates also installs on the older hosts its `hostApiRange` admits.
|
|
485
|
+
*/
|
|
486
|
+
declare const MAX_PLUGIN_MENU_PERMISSION_LENGTH = 100;
|
|
487
|
+
/** Route prefix one plugin's frontend owns. */
|
|
488
|
+
declare function pluginBasePath(pluginId: string): string;
|
|
489
|
+
/**
|
|
490
|
+
* Route for one nav entry a plugin contributes.
|
|
491
|
+
*
|
|
492
|
+
* `entryPath` is the plugin's own internal route, so `/deals` for plugin
|
|
493
|
+
* `acme-crm` becomes `/p/acme-crm/deals`. Every plugin page therefore lives
|
|
494
|
+
* under a prefix the host owns, which is what lets a single catch-all route
|
|
495
|
+
* serve all of them.
|
|
496
|
+
*/
|
|
497
|
+
declare function pluginNavPath(pluginId: string, entryPath?: string): string;
|
|
498
|
+
/**
|
|
499
|
+
* API-root-relative path for a call into one plugin's own backend part.
|
|
500
|
+
*
|
|
501
|
+
* Derived here, next to the route helpers, because the server mounts the
|
|
502
|
+
* gateway at this prefix and the shell has to hit the same one. When the shell
|
|
503
|
+
* owned its own copy it built `plugins/<id>/api/...` — the older proxy's
|
|
504
|
+
* prefix — and every plugin backend call 404'd on a plugin the platform had no
|
|
505
|
+
* reason to know about.
|
|
506
|
+
*
|
|
507
|
+
* The prefix is the host's, so a plugin cannot reach another plugin's backend
|
|
508
|
+
* or the platform API by writing a path: a crafted one 404s inside its own
|
|
509
|
+
* namespace.
|
|
510
|
+
*/
|
|
511
|
+
declare function pluginApiPath(pluginId: string, path?: string): string;
|
|
512
|
+
/**
|
|
513
|
+
* Pick one string out of a possibly per-locale display value.
|
|
514
|
+
*
|
|
515
|
+
* Used where a single string is unavoidable — a database column, a log line —
|
|
516
|
+
* not for rendering, which goes through i18n.
|
|
517
|
+
*/
|
|
518
|
+
declare function localizedTextToString(value: LocalizedText, preferred?: string): string;
|
|
519
|
+
/**
|
|
520
|
+
* The `menu.` permission name older hosts derived for one nav entry.
|
|
521
|
+
*
|
|
522
|
+
* The host no longer writes plugin menus or permissions — access follows the
|
|
523
|
+
* AI employees a plugin is installed on — but the name is still what the
|
|
524
|
+
* manifest length check and install disclosure snapshots are built from.
|
|
525
|
+
*/
|
|
526
|
+
declare function pluginMenuPermission(pluginId: string, navKey: string): string;
|
|
527
|
+
|
|
528
|
+
export { HOST_API_VERSION, type InstalledPlugin, type InstalledPluginFrontend, type InstalledPluginWorkDelegation, type InstalledPluginsResponse, LocalizedText, MAX_PLUGIN_MENU_PERMISSION_LENGTH, PLUGIN_AVATAR_PUBLIC_API_PATH, PLUGIN_AVATAR_PUBLIC_PAGES_PATH, PLUGIN_PUBLIC_API_PATH, PLUGIN_PUBLIC_PAGES_PATH, PLUGIN_PUBLIC_ROUTE_METHODS, PLUGIN_SUPPORTED_LOCALES, PluginAgentReadinessDeclaration, PluginBackendRuntime, PluginConfigSection, PluginConfigSectionSummary, PluginDeclares, type PluginDisclosureAddition, type PluginDisclosureNavEntry, type PluginInstallDisclosure, PluginNavEntry, PluginNavIcon, PluginPartName, PluginPublicRoute, PluginScope, type PluginSupportedLocale, type PublicRouteMatch, SHARED_MODULE_IDS, type SharedModuleId, TegoPluginManifest, auditDeclarationGaps, buildInstallDisclosure, diffInstallDisclosure, formatPublicRoute, hostApiRangeMinimum, isValidHostApiRange, localizedTextToString, matchPublicRoute, pluginApiPath, pluginBasePath, pluginI18nKey, pluginI18nNamespace, pluginMenuKey, pluginMenuPermission, pluginNavPath, publicApiBaseFromPagePath, requiresBackendConfig, satisfiesHostApiRange };
|