@zhama/tego-plugin-sdk 0.0.0-stage → 1.36.1

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 (98) hide show
  1. package/LICENSE +172 -0
  2. package/README.md +846 -2
  3. package/access-catalog.schema.json +304 -0
  4. package/access-fixtures/resolve.json +1359 -0
  5. package/bin/tego-plugin-pack.mjs +2 -0
  6. package/bin/tego-plugin.mjs +3 -0
  7. package/dist/access-drizzle.cjs +1 -0
  8. package/dist/access-drizzle.d.cts +726 -0
  9. package/dist/access-drizzle.d.ts +726 -0
  10. package/dist/access-drizzle.js +1 -0
  11. package/dist/access-hono.cjs +3 -0
  12. package/dist/access-hono.d.cts +108 -0
  13. package/dist/access-hono.d.ts +108 -0
  14. package/dist/access-hono.js +3 -0
  15. package/dist/access-implications.cjs +1 -0
  16. package/dist/access-implications.d.cts +25 -0
  17. package/dist/access-implications.d.ts +25 -0
  18. package/dist/access-implications.js +1 -0
  19. package/dist/access.cjs +26 -0
  20. package/dist/access.d.cts +884 -0
  21. package/dist/access.d.ts +884 -0
  22. package/dist/access.js +26 -0
  23. package/dist/catalog-CSSbrfEf.d.cts +361 -0
  24. package/dist/catalog-CSSbrfEf.d.ts +361 -0
  25. package/dist/chunk-3KUOBGJN.js +19 -0
  26. package/dist/chunk-3WA3M347.cjs +1 -0
  27. package/dist/chunk-5CU33JVY.js +1 -0
  28. package/dist/chunk-7K37PVGV.js +5 -0
  29. package/dist/chunk-7XHF3YSK.js +1 -0
  30. package/dist/chunk-AJY7ZHXK.cjs +3 -0
  31. package/dist/chunk-BN6TGHSB.cjs +1 -0
  32. package/dist/chunk-BTHXQWHT.js +1 -0
  33. package/dist/chunk-C2OCOPZQ.cjs +1 -0
  34. package/dist/chunk-IMAVYQ4U.cjs +4 -0
  35. package/dist/chunk-OP64Y4IN.cjs +1 -0
  36. package/dist/chunk-QKSPPMVN.js +1 -0
  37. package/dist/chunk-ROFUQLOZ.cjs +1 -0
  38. package/dist/chunk-SNUCO2MK.js +1 -0
  39. package/dist/chunk-THMWRUAT.cjs +19 -0
  40. package/dist/chunk-VMCGDDGP.js +3 -0
  41. package/dist/chunk-W7C357A6.cjs +5 -0
  42. package/dist/chunk-WLTASJF6.js +4 -0
  43. package/dist/egress.cjs +7 -0
  44. package/dist/egress.d.cts +9 -0
  45. package/dist/egress.d.ts +9 -0
  46. package/dist/egress.js +7 -0
  47. package/dist/frontend.cjs +2 -0
  48. package/dist/frontend.d.cts +353 -0
  49. package/dist/frontend.d.ts +353 -0
  50. package/dist/frontend.js +2 -0
  51. package/dist/gateway-signature.cjs +1 -0
  52. package/dist/gateway-signature.d.cts +112 -0
  53. package/dist/gateway-signature.d.ts +112 -0
  54. package/dist/gateway-signature.js +1 -0
  55. package/dist/index.cjs +1 -0
  56. package/dist/index.d.cts +528 -0
  57. package/dist/index.d.ts +528 -0
  58. package/dist/index.js +1 -0
  59. package/dist/manifest-types-DQARCQJt.d.cts +627 -0
  60. package/dist/manifest-types-DQARCQJt.d.ts +627 -0
  61. package/dist/manifest.cjs +1 -0
  62. package/dist/manifest.d.cts +2824 -0
  63. package/dist/manifest.d.ts +2824 -0
  64. package/dist/manifest.js +1 -0
  65. package/dist/mcp-identity.cjs +2 -0
  66. package/dist/mcp-identity.d.cts +106 -0
  67. package/dist/mcp-identity.d.ts +106 -0
  68. package/dist/mcp-identity.js +2 -0
  69. package/dist/pack.cjs +1 -0
  70. package/dist/pack.d.cts +169 -0
  71. package/dist/pack.d.ts +169 -0
  72. package/dist/pack.js +1 -0
  73. package/dist/publish.cjs +1 -0
  74. package/dist/publish.d.cts +96 -0
  75. package/dist/publish.d.ts +96 -0
  76. package/dist/publish.js +1 -0
  77. package/dist/scaffold.cjs +523 -0
  78. package/dist/scaffold.d.cts +182 -0
  79. package/dist/scaffold.d.ts +182 -0
  80. package/dist/scaffold.js +523 -0
  81. package/dist/server-runtime.cjs +1 -0
  82. package/dist/server-runtime.d.cts +63 -0
  83. package/dist/server-runtime.d.ts +63 -0
  84. package/dist/server-runtime.js +1 -0
  85. package/dist/server.cjs +1 -0
  86. package/dist/server.d.cts +1808 -0
  87. package/dist/server.d.ts +1808 -0
  88. package/dist/server.js +1 -0
  89. package/dist/testing.cjs +2 -0
  90. package/dist/testing.d.cts +92 -0
  91. package/dist/testing.d.ts +92 -0
  92. package/dist/testing.js +2 -0
  93. package/dist/vite.cjs +1 -0
  94. package/dist/vite.d.cts +133 -0
  95. package/dist/vite.d.ts +133 -0
  96. package/dist/vite.js +1 -0
  97. package/package.json +160 -4
  98. package/sql/access.sql +73 -0
@@ -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 };