@capybara-hq/kernel 0.1.0-rc.12 → 0.1.0-rc.14
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/dist/admin/admin.schemas.d.ts +13 -0
- package/dist/agents/agent-lookup.d.ts +5 -0
- package/dist/agents/agent-lookup.js +15 -0
- package/dist/background/background.module.js +2 -2
- package/dist/background/launch-lock.d.ts +1 -1
- package/dist/background/launch-lock.js +1 -1
- package/dist/background/poll.job.d.ts +2 -2
- package/dist/background/poll.job.js +10 -10
- package/dist/background/stop.d.ts +1 -1
- package/dist/background/stop.js +3 -3
- package/dist/background/store.d.ts +5 -5
- package/dist/background/store.js +5 -5
- package/dist/background/tasks.service.d.ts +6 -6
- package/dist/background/tasks.service.js +13 -13
- package/dist/catalog/admin-catalog.controller.d.ts +13 -2
- package/dist/catalog/admin-catalog.controller.js +24 -3
- package/dist/catalog/admin-catalog.schemas.d.ts +10 -0
- package/dist/catalog/admin-catalog.schemas.js +7 -0
- package/dist/catalog/catalog-content.d.ts +9 -1
- package/dist/catalog/catalog-content.js +2 -1
- package/dist/catalog/catalog-files.d.ts +3 -2
- package/dist/catalog/catalog-files.js +8 -5
- package/dist/catalog/component-scope.service.d.ts +14 -1
- package/dist/catalog/component-scope.service.js +12 -2
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/org-catalog.controller.d.ts +5 -4
- package/dist/catalog/org-catalog.controller.js +5 -4
- package/dist/catalog/org-catalog.schemas.d.ts +18 -2
- package/dist/catalog/org-catalog.schemas.js +16 -2
- package/dist/catalog/org-catalog.service.js +8 -2
- package/dist/catalog/plugin-import.js +1 -1
- package/dist/catalog/plugin-package.js +37 -9
- package/dist/catalog/plugin-upgrade.d.ts +15 -1
- package/dist/catalog/plugin-upgrade.js +18 -5
- package/dist/channels/channels.module.js +2 -2
- package/dist/channels/connections.controller.d.ts +1 -1
- package/dist/channels/connections.controller.js +1 -1
- package/dist/channels/connections.service.d.ts +22 -5
- package/dist/channels/connections.service.js +56 -10
- package/dist/channels/inbound.d.ts +8 -8
- package/dist/channels/inbound.js +31 -31
- package/dist/channels/phrases.d.ts +27 -27
- package/dist/channels/phrases.js +27 -27
- package/dist/channels/webhook.d.ts +21 -1
- package/dist/channels/webhook.js +39 -4
- package/dist/config/docs.js +1 -1
- package/dist/config/schema.d.ts +2 -2
- package/dist/config/schema.js +21 -21
- package/dist/conversations/conversations.controller.d.ts +11 -11
- package/dist/conversations/conversations.controller.js +15 -15
- package/dist/conversations/conversations.module.d.ts +1 -1
- package/dist/conversations/conversations.module.js +7 -7
- package/dist/conversations/conversations.schemas.js +1 -1
- package/dist/conversations/conversations.service.d.ts +14 -14
- package/dist/conversations/conversations.service.js +19 -19
- package/dist/conversations/{environment-status.d.ts → device-status.d.ts} +9 -9
- package/dist/conversations/{environment-status.js → device-status.js} +18 -18
- package/dist/conversations/event-log.d.ts +1 -1
- package/dist/conversations/event-log.js +1 -1
- package/dist/conversations/events.d.ts +1 -1
- package/dist/conversations/events.js +2 -2
- package/dist/ctx/create-ctx.d.ts +26 -3
- package/dist/ctx/create-ctx.js +134 -26
- package/dist/db/kernel-schema.d.ts +37 -25
- package/dist/{environments → devices}/access.d.ts +19 -19
- package/dist/{environments → devices}/access.js +28 -28
- package/dist/devices/conversation-devices.d.ts +75 -0
- package/dist/{environments/conversation-environments.js → devices/conversation-devices.js} +71 -72
- package/dist/devices/devices.controller.d.ts +36 -0
- package/dist/{environments/environments.controller.js → devices/devices.controller.js} +37 -37
- package/dist/devices/devices.module.d.ts +5 -13
- package/dist/devices/devices.module.js +16 -29
- package/dist/devices/devices.schemas.d.ts +3 -0
- package/dist/devices/devices.schemas.js +14 -0
- package/dist/{environments/environments.service.d.ts → devices/devices.service.d.ts} +70 -70
- package/dist/{environments/environments.service.js → devices/devices.service.js} +122 -122
- package/dist/devices/dto.d.ts +13 -54
- package/dist/devices/dto.js +7 -39
- package/dist/devices/label.d.ts +11 -0
- package/dist/{environments → devices}/label.js +7 -7
- package/dist/{environments → devices}/legacy-cleanup.job.d.ts +3 -3
- package/dist/{environments → devices}/legacy-cleanup.job.js +3 -3
- package/dist/errors.d.ts +29 -25
- package/dist/errors.js +29 -25
- package/dist/evals/recorded-tools.d.ts +2 -2
- package/dist/evals/recorded-tools.js +6 -6
- package/dist/extensions/admin-ops.js +1 -0
- package/dist/extensions/admin-view.js +2 -0
- package/dist/extensions/effective-config.d.ts +6 -0
- package/dist/extensions/effective-config.js +18 -7
- package/dist/extensions/guide-places.d.ts +66 -0
- package/dist/extensions/guide-places.js +152 -0
- package/dist/extensions/host.d.ts +13 -2
- package/dist/extensions/host.js +27 -6
- package/dist/extensions/instance.d.ts +17 -2
- package/dist/extensions/instance.js +21 -0
- package/dist/extensions/ledger.d.ts +1 -1
- package/dist/extensions/permission-set.d.ts +16 -2
- package/dist/extensions/permission-set.js +17 -3
- package/dist/extensions/permission-view.d.ts +10 -1
- package/dist/extensions/plugin-guides.d.ts +207 -54
- package/dist/extensions/plugin-guides.js +436 -165
- package/dist/files/previewers.d.ts +1 -1
- package/dist/files/previewers.js +1 -1
- package/dist/http/api.module.js +16 -6
- package/dist/http/gateway-routes.d.ts +1 -1
- package/dist/http/gateway-routes.js +1 -1
- package/dist/identity/settings.d.ts +32 -0
- package/dist/identity/settings.js +26 -2
- package/dist/infra/config/kernel-config.service.js +4 -4
- package/dist/infra/lock/lock.service.d.ts +8 -0
- package/dist/infra/lock/lock.service.js +27 -0
- package/dist/infra/throttler/named-throttlers.d.ts +4 -1
- package/dist/infra/throttler/named-throttlers.js +16 -1
- package/dist/infra/throttler/throttler.guard.js +1 -1
- package/dist/kernel.module.js +3 -3
- package/dist/{devices → local-devices}/device-auth.controller.d.ts +6 -6
- package/dist/{devices → local-devices}/device-auth.controller.js +5 -5
- package/dist/{devices → local-devices}/device-auth.d.ts +20 -20
- package/dist/{devices → local-devices}/device-auth.js +51 -53
- package/dist/local-devices/device-auth.module.d.ts +7 -0
- package/dist/{devices → local-devices}/device-auth.module.js +5 -5
- package/dist/{devices → local-devices}/device-routes.d.ts +3 -3
- package/dist/{devices → local-devices}/device-routes.js +2 -2
- package/dist/local-devices/dto.d.ts +66 -0
- package/dist/local-devices/dto.js +44 -0
- package/dist/{devices → local-devices}/keys.d.ts +11 -11
- package/dist/{devices → local-devices}/keys.js +11 -11
- package/dist/{devices/device-gateway.d.ts → local-devices/local-device-gateway.d.ts} +14 -14
- package/dist/{devices/device-gateway.js → local-devices/local-device-gateway.js} +44 -44
- package/dist/{devices/device-provider.d.ts → local-devices/local-device-provider.d.ts} +15 -15
- package/dist/{devices/device-provider.js → local-devices/local-device-provider.js} +23 -23
- package/dist/local-devices/local-devices.module.d.ts +16 -0
- package/dist/local-devices/local-devices.module.js +44 -0
- package/dist/{devices → local-devices}/machines.d.ts +26 -26
- package/dist/{devices → local-devices}/machines.js +71 -71
- package/dist/{devices → local-devices}/relay.d.ts +15 -15
- package/dist/{devices → local-devices}/relay.js +55 -55
- package/dist/{devices → local-devices}/targets.d.ts +8 -8
- package/dist/{devices → local-devices}/targets.js +14 -14
- package/dist/orgs/offboarding.d.ts +6 -6
- package/dist/orgs/offboarding.js +12 -12
- package/dist/orgs/settings.service.d.ts +28 -0
- package/dist/orgs/settings.service.js +20 -1
- package/dist/overrides.d.ts +3 -1
- package/dist/overrides.js +2 -0
- package/dist/platform/exclusions.js +48 -8
- package/dist/platform/operation.js +10 -2
- package/dist/platform/ops/admin.ops.js +8 -2
- package/dist/platform/ops/connectors.ops.js +2 -0
- package/dist/platform/ops/conversations.ops.d.ts +3 -3
- package/dist/platform/ops/conversations.ops.js +9 -9
- package/dist/platform/ops/devices.ops.d.ts +26 -0
- package/dist/platform/ops/devices.ops.js +311 -0
- package/dist/platform/ops/org-settings.ops.js +2 -2
- package/dist/platform/ops/orgs.ops.js +1 -0
- package/dist/platform/ops/setup.ops.d.ts +24 -0
- package/dist/platform/ops/setup.ops.js +212 -0
- package/dist/platform/ops/ui.ops.d.ts +8 -0
- package/dist/platform/ops/ui.ops.js +41 -0
- package/dist/platform/platform-ops.module.d.ts +4 -2
- package/dist/platform/platform-ops.module.js +13 -5
- package/dist/platform/route-schemas.js +11 -3
- package/dist/roles/gateway-role.d.ts +3 -3
- package/dist/roles/gateway-role.js +4 -4
- package/dist/roles/gateway.module.d.ts +1 -1
- package/dist/roles/gateway.module.js +5 -5
- package/dist/roles/worker.module.js +1 -1
- package/dist/runtime/context/build.d.ts +1 -1
- package/dist/runtime/context/build.js +6 -6
- package/dist/runtime/context/compaction.js +1 -1
- package/dist/runtime/context/{environment-paths.d.ts → device-paths.d.ts} +11 -11
- package/dist/runtime/context/{environment-paths.js → device-paths.js} +13 -13
- package/dist/runtime/maintenance.d.ts +1 -1
- package/dist/sandbox/jobs.d.ts +13 -13
- package/dist/sandbox/jobs.js +20 -20
- package/dist/sandbox/leases.d.ts +9 -9
- package/dist/sandbox/leases.js +14 -14
- package/dist/sandbox/providers.d.ts +8 -8
- package/dist/sandbox/providers.js +8 -8
- package/dist/sandbox/sandbox.module.d.ts +1 -1
- package/dist/sandbox/sandbox.module.js +1 -1
- package/dist/sandbox/sandbox.service.d.ts +76 -76
- package/dist/sandbox/sandbox.service.js +230 -230
- package/dist/setup/kernel-checks.d.ts +91 -0
- package/dist/setup/kernel-checks.js +295 -0
- package/dist/setup/oauth-token-probe.d.ts +47 -0
- package/dist/setup/oauth-token-probe.js +108 -0
- package/dist/setup/redact-check.d.ts +18 -0
- package/dist/setup/redact-check.js +46 -0
- package/dist/setup/setup-check-registry.d.ts +86 -0
- package/dist/setup/setup-check-registry.js +75 -0
- package/dist/setup/setup-checks.controller.d.ts +28 -0
- package/dist/setup/setup-checks.controller.js +78 -0
- package/dist/setup/setup-checks.schemas.d.ts +38 -0
- package/dist/setup/setup-checks.schemas.js +43 -0
- package/dist/setup/setup-checks.service.d.ts +144 -0
- package/dist/setup/setup-checks.service.js +683 -0
- package/dist/setup/setup-guides.controller.d.ts +18 -0
- package/dist/setup/setup-guides.controller.js +48 -0
- package/dist/setup/setup-guides.schemas.d.ts +10 -0
- package/dist/setup/setup-guides.schemas.js +6 -0
- package/dist/setup/setup-guides.service.d.ts +126 -0
- package/dist/setup/setup-guides.service.js +315 -0
- package/dist/setup/setup.module.d.ts +8 -0
- package/dist/setup/setup.module.js +31 -0
- package/dist/tools/builtins/builtin-tools.d.ts +2 -2
- package/dist/tools/builtins/builtin-tools.js +5 -5
- package/dist/tools/builtins/platform.js +1 -1
- package/dist/tools/builtins/sandbox/bash.js +6 -6
- package/dist/tools/builtins/sandbox/common.d.ts +25 -25
- package/dist/tools/builtins/sandbox/common.js +51 -51
- package/dist/tools/builtins/sandbox/edit.js +2 -2
- package/dist/tools/builtins/sandbox/index.d.ts +1 -1
- package/dist/tools/builtins/sandbox/index.js +1 -1
- package/dist/tools/builtins/sandbox/task-output.d.ts +6 -6
- package/dist/tools/builtins/sandbox/task-output.js +10 -10
- package/dist/tools/builtins/sandbox/task-stop.js +2 -2
- package/dist/tools/builtins/sandbox/write.js +2 -2
- package/dist/tools/builtins/skill-load.d.ts +1 -1
- package/dist/tools/builtins/skill-load.js +2 -2
- package/dist/tools/connectors.controller.d.ts +28 -11
- package/dist/tools/connectors.controller.js +49 -14
- package/dist/tools/connectors.schemas.d.ts +4 -0
- package/dist/tools/connectors.schemas.js +4 -0
- package/dist/tools/connectors.service.d.ts +30 -2
- package/dist/tools/connectors.service.js +98 -3
- package/dist/tools/credentials.d.ts +20 -0
- package/dist/tools/credentials.js +90 -1
- package/dist/tools/oauth/tokens.d.ts +20 -0
- package/dist/tools/oauth/tokens.js +49 -24
- package/dist/tools/pipeline.js +4 -3
- package/dist/tools/registry.d.ts +2 -2
- package/dist/tools/tools.module.js +3 -3
- package/dist/ui/admin-ui.controller.d.ts +56 -0
- package/dist/ui/admin-ui.controller.js +192 -0
- package/dist/ui/arrangement.d.ts +74 -0
- package/dist/ui/arrangement.js +98 -0
- package/dist/ui/embed-token.d.ts +2 -2
- package/dist/ui/embed-token.js +30 -5
- package/dist/ui/registry.d.ts +29 -14
- package/dist/ui/registry.js +31 -10
- package/dist/ui/slots.controller.d.ts +11 -0
- package/dist/ui/slots.controller.js +25 -0
- package/dist/ui/ui-stream.d.ts +20 -3
- package/dist/ui/ui-stream.js +25 -7
- package/dist/ui/ui.schemas.d.ts +66 -0
- package/dist/ui/ui.schemas.js +65 -0
- package/dist/ui/views.controller.d.ts +35 -49
- package/dist/ui/views.controller.js +48 -70
- package/dist/ui/views.d.ts +84 -18
- package/dist/ui/views.js +201 -38
- package/package.json +3 -3
- package/src/migrations/0105_devices_rename.sql +136 -0
- package/src/migrations/0106_setup_guides_v2.sql +10 -0
- package/dist/devices/device-auth.module.d.ts +0 -7
- package/dist/environments/conversation-environments.d.ts +0 -75
- package/dist/environments/dto.d.ts +0 -25
- package/dist/environments/dto.js +0 -12
- package/dist/environments/environments.controller.d.ts +0 -36
- package/dist/environments/environments.module.d.ts +0 -8
- package/dist/environments/environments.module.js +0 -31
- package/dist/environments/environments.schemas.d.ts +0 -3
- package/dist/environments/environments.schemas.js +0 -14
- package/dist/environments/label.d.ts +0 -11
- package/dist/platform/ops/environments.ops.d.ts +0 -26
- package/dist/platform/ops/environments.ops.js +0 -311
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// The kernel side of the setup guide places (spec 2026-11-09-setup-guides-v2-design.md §6.3, §9):
|
|
2
|
+
// the SDK registry (`SETUP_GUIDE_PLACE_INFO`) says which modes, audiences and variables a place
|
|
3
|
+
// has; this module adds, per place, the org action each audience needs, the target lookup (a live
|
|
4
|
+
// object of the org on the guide's plugin, else 404) and the variable values with the reason a
|
|
5
|
+
// known variable has no value. No value ever comes from a target's config, a secret, a token or a
|
|
6
|
+
// client id: only names, ids, versions and the two URL settings.
|
|
7
|
+
import { SETUP_GUIDE_PLACE_INFO, } from "@capybara-hq/plugin-sdk";
|
|
8
|
+
import { webhookBase, webhookUrlOf } from "../channels/webhook-url.js";
|
|
9
|
+
import { ApiError } from "../errors.js";
|
|
10
|
+
import { OAUTH_CALLBACK_PATH } from "../tools/oauth/flow-paths.js";
|
|
11
|
+
/** The org action each audience of a place needs besides `catalog.read` (spec §9.1). */
|
|
12
|
+
export const PLACE_ACTIONS = {
|
|
13
|
+
"channel-connection": { admin: "channels.manage" },
|
|
14
|
+
"connector-template": { admin: "connectors.manage", member: "connectors.use" },
|
|
15
|
+
};
|
|
16
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
17
|
+
const invalidQuery = (path, message) => new ApiError("validation_failed", "Request validation failed", [{ path, message }]);
|
|
18
|
+
/** The target parameters each place takes; another place's parameter is 400. */
|
|
19
|
+
const TARGET_PARAMS = {
|
|
20
|
+
"channel-connection": ["connectionId", "name"],
|
|
21
|
+
"connector-template": ["connectorId"],
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The variable values of a place for one rendering (spec §6.3): the common ones, then the place's
|
|
25
|
+
* own from its target. Throws 400 `validation_failed` for another place's target parameter and 404
|
|
26
|
+
* (`channel.not_found`, `connector.not_found`) for a target that is not a live object of the org on
|
|
27
|
+
* the guide's plugin.
|
|
28
|
+
*/
|
|
29
|
+
export async function resolvePlace(ctx) {
|
|
30
|
+
const place = ctx.guide.place;
|
|
31
|
+
for (const key of Object.keys(ctx.query)) {
|
|
32
|
+
if (ctx.query[key] !== undefined && !TARGET_PARAMS[place].includes(key)) {
|
|
33
|
+
throw invalidQuery(key, `${key} is not a target of a ${place} guide`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const publicUrl = ctx.config.http.publicUrl?.replace(/\/+$/, "") ?? null;
|
|
37
|
+
const values = {
|
|
38
|
+
publicUrl,
|
|
39
|
+
orgName: ctx.org?.name ?? null,
|
|
40
|
+
pluginName: ctx.item.name,
|
|
41
|
+
pluginVersion: ctx.item.version,
|
|
42
|
+
};
|
|
43
|
+
const reasons = {};
|
|
44
|
+
const signIn = publicUrl === null
|
|
45
|
+
? null
|
|
46
|
+
: `${publicUrl}/api/v1/auth/sso/${encodeURIComponent(ctx.item.name)}/callback`;
|
|
47
|
+
let target = null;
|
|
48
|
+
let storedMode = null;
|
|
49
|
+
if (place === "channel-connection") {
|
|
50
|
+
const connection = ctx.query.connectionId === undefined
|
|
51
|
+
? undefined
|
|
52
|
+
: await liveConnection(ctx, ctx.query.connectionId);
|
|
53
|
+
const base = webhookBase(ctx.config);
|
|
54
|
+
values.webhookUrl =
|
|
55
|
+
connection !== undefined && base !== undefined ? webhookUrlOf(base, connection.id) : null;
|
|
56
|
+
reasons.webhookUrl = connection === undefined ? "not_saved" : "webhook_base";
|
|
57
|
+
values.signInCallbackUrl = signIn;
|
|
58
|
+
const typed = ctx.query.name?.trim();
|
|
59
|
+
values.connectionName =
|
|
60
|
+
connection?.name ?? (typed === undefined || typed === "" ? null : typed);
|
|
61
|
+
reasons.connectionName = "not_saved";
|
|
62
|
+
if (connection !== undefined) {
|
|
63
|
+
target = { kind: "channel-connection", id: connection.id };
|
|
64
|
+
storedMode = connection.inbound_mode;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const connector = ctx.query.connectorId === undefined
|
|
69
|
+
? undefined
|
|
70
|
+
: await liveConnector(ctx, ctx.query.connectorId);
|
|
71
|
+
values.oauthCallbackUrl = publicUrl === null ? null : `${publicUrl}${OAUTH_CALLBACK_PATH}`;
|
|
72
|
+
values.signInCallbackUrl = signIn;
|
|
73
|
+
values.templateId = ctx.guide.template ?? null;
|
|
74
|
+
values.templateName = await templateName(ctx);
|
|
75
|
+
values.connectorName = connector?.name ?? null;
|
|
76
|
+
reasons.connectorName = "no_connector";
|
|
77
|
+
if (connector !== undefined)
|
|
78
|
+
target = { kind: "connector", id: connector.id };
|
|
79
|
+
}
|
|
80
|
+
reasons.publicUrl = "public_url";
|
|
81
|
+
reasons.signInCallbackUrl = "public_url";
|
|
82
|
+
reasons.oauthCallbackUrl = "public_url";
|
|
83
|
+
reasons.orgName = "no_org";
|
|
84
|
+
// keep only the reasons of variables that are the place's and have no value
|
|
85
|
+
const known = SETUP_GUIDE_PLACE_INFO[place].variables;
|
|
86
|
+
for (const name of Object.keys(reasons)) {
|
|
87
|
+
if (!Object.hasOwn(known, name) || values[name] !== null)
|
|
88
|
+
delete reasons[name];
|
|
89
|
+
}
|
|
90
|
+
return { values, reasons, target, storedMode };
|
|
91
|
+
}
|
|
92
|
+
/** A live connection of the org on the guide's plugin; otherwise `channel.not_found`. */
|
|
93
|
+
async function liveConnection(ctx, id) {
|
|
94
|
+
const notFound = () => new ApiError("channel.not_found", "Channel connection not found");
|
|
95
|
+
if (ctx.org === null || !UUID_RE.test(id))
|
|
96
|
+
throw notFound();
|
|
97
|
+
const c = await ctx.db
|
|
98
|
+
.selectFrom("channel_connections")
|
|
99
|
+
.select(["id", "name", "inbound_mode"])
|
|
100
|
+
.where("id", "=", id)
|
|
101
|
+
.where("org_id", "=", ctx.org.orgId)
|
|
102
|
+
.where("plugin", "=", ctx.item.name)
|
|
103
|
+
.where("deleted_at", "is", null)
|
|
104
|
+
.executeTakeFirst();
|
|
105
|
+
if (!c)
|
|
106
|
+
throw notFound();
|
|
107
|
+
return c;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A live connector of the org made from the guide's template (`connectors.platform_template_id` ->
|
|
111
|
+
* the platform component of the item's template, org-owned plugins included); otherwise
|
|
112
|
+
* `connector.not_found`, also for a custom connector or one made from another template.
|
|
113
|
+
*/
|
|
114
|
+
async function liveConnector(ctx, id) {
|
|
115
|
+
const notFound = () => new ApiError("connector.not_found", "Connector not found");
|
|
116
|
+
const template = ctx.guide.template;
|
|
117
|
+
if (ctx.org === null || template === undefined || !UUID_RE.test(id))
|
|
118
|
+
throw notFound();
|
|
119
|
+
const c = await ctx.db
|
|
120
|
+
.selectFrom("connectors as c")
|
|
121
|
+
.innerJoin("platform_connector_templates as t", "t.id", "c.platform_template_id")
|
|
122
|
+
.select(["c.id", "c.name"])
|
|
123
|
+
.where("c.id", "=", id)
|
|
124
|
+
.where("c.org_id", "=", ctx.org.orgId)
|
|
125
|
+
.where("c.deleted_at", "is", null)
|
|
126
|
+
.where("t.catalog_item_id", "=", ctx.item.id)
|
|
127
|
+
.where("t.template_id", "=", template)
|
|
128
|
+
.executeTakeFirst();
|
|
129
|
+
if (!c)
|
|
130
|
+
throw notFound();
|
|
131
|
+
return c;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The template's display name in the document's language, from the platform component made from
|
|
135
|
+
* it at import (`platform_connector_templates.file`); the template id when there is none.
|
|
136
|
+
*/
|
|
137
|
+
async function templateName(ctx) {
|
|
138
|
+
const id = ctx.guide.template;
|
|
139
|
+
if (id === undefined)
|
|
140
|
+
return null;
|
|
141
|
+
const row = await ctx.db
|
|
142
|
+
.selectFrom("platform_connector_templates")
|
|
143
|
+
.select("file")
|
|
144
|
+
.where("catalog_item_id", "=", ctx.item.id)
|
|
145
|
+
.where("template_id", "=", id)
|
|
146
|
+
.where("deleted_at", "is", null)
|
|
147
|
+
.executeTakeFirst();
|
|
148
|
+
const name = row?.file
|
|
149
|
+
?.displayName;
|
|
150
|
+
const localized = ctx.locale === "zh" ? name?.zh : name?.en;
|
|
151
|
+
return typeof localized === "string" && localized !== "" ? localized : id;
|
|
152
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ExtensionManifest, type ExtensionPointRef, type LocalizedName, type ToolHandler, type ToolSpec, type UiContribution } from "@capybara-hq/plugin-sdk";
|
|
1
|
+
import { type DroppedUiContribution, type ExtensionManifest, type ExtensionPointRef, type LocalizedName, type ToolHandler, type ToolSpec, type UiContribution, type UiSlotSpec } from "@capybara-hq/plugin-sdk";
|
|
2
2
|
import type { Redis } from "ioredis";
|
|
3
3
|
import type { core } from "zod";
|
|
4
4
|
import type { KernelAppOptions } from "../app.js";
|
|
@@ -24,10 +24,17 @@ import { type PermissionSet } from "./permission-set.js";
|
|
|
24
24
|
import { type ExtensionPointEntry, ExtensionRegistry } from "./registry.js";
|
|
25
25
|
import { type ExtensionSource, ReplicaStatusStore } from "./sources.js";
|
|
26
26
|
export { deploymentConfigHash };
|
|
27
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* One item of {@link ExtensionHost.uiContributions}: a UI contribution from the manifest whose slot
|
|
29
|
+
* resolved at load (dropped ones never appear), with its registered view / action (embeds have none).
|
|
30
|
+
*/
|
|
28
31
|
export interface LoadedUiContribution {
|
|
29
32
|
plugin: string;
|
|
30
33
|
contribution: UiContribution;
|
|
34
|
+
/** The catalog slot the contribution resolved to (from `slot`, or the deprecated `place`). */
|
|
35
|
+
slot: UiSlotSpec;
|
|
36
|
+
/** For a slot with anchors: the anchor it goes after (see `resolveUiSlots`). */
|
|
37
|
+
after?: string;
|
|
31
38
|
render?: UiRender;
|
|
32
39
|
action?: UiActionHandler;
|
|
33
40
|
}
|
|
@@ -494,6 +501,8 @@ export declare class ExtensionHost {
|
|
|
494
501
|
* 配置声明的插件启动时不设时限(见 {@link load})。
|
|
495
502
|
*/
|
|
496
503
|
private setup;
|
|
504
|
+
/** Logs once per load what slot resolution left out or flagged (UI slots spec §3.2). */
|
|
505
|
+
private logUiResolution;
|
|
497
506
|
/** 取能力实现:单选能力无需 providerName,多选能力必须指定。 */
|
|
498
507
|
get<T>(capability: ExtensionPointRef, providerName?: string): T;
|
|
499
508
|
/**
|
|
@@ -607,6 +616,8 @@ export declare class ExtensionHost {
|
|
|
607
616
|
* 是否在某组织启用由调用方另查(每次查询,不缓存)。
|
|
608
617
|
*/
|
|
609
618
|
uiContributions(): LoadedUiContribution[];
|
|
619
|
+
/** The UI contributions the loaded extension left out at load (UI slots spec §3.2); `[]` when not loaded. */
|
|
620
|
+
uiDropped(name: string): DroppedUiContribution[];
|
|
610
621
|
/** 串行执行生命周期操作(unload / reload 互不交错);宿主关闭后拒绝。 */
|
|
611
622
|
private serial;
|
|
612
623
|
/**
|
package/dist/extensions/host.js
CHANGED
|
@@ -38,7 +38,7 @@ import { ExtensionInstalls } from "./installs.js";
|
|
|
38
38
|
import { ImportTracker, importExtensionModule, ManifestMismatchError, matchesSection, setupInstance, warnUpgrades, } from "./instance.js";
|
|
39
39
|
import { parseLoadGate } from "./org-levels.js";
|
|
40
40
|
import { declaredDisplayName, permissionSetOfSection, readMigrationSql } from "./package.js";
|
|
41
|
-
import { blockingKeys, computePermissionSet, UI_VIEW_KEY_PREFIX, } from "./permission-set.js";
|
|
41
|
+
import { blockingKeys, computePermissionSet, SETUP_CHECK_KEY_PREFIX, UI_VIEW_KEY_PREFIX, } from "./permission-set.js";
|
|
42
42
|
import { ExtensionRegistry } from "./registry.js";
|
|
43
43
|
import { ExtensionResolveError, electSingleProviders, PROVIDER_CONFLICT, providerConflictMessage, resolveExtensions, } from "./resolve.js";
|
|
44
44
|
import { ReplicaStatusStore, } from "./sources.js";
|
|
@@ -1291,9 +1291,9 @@ let ExtensionHost = class ExtensionHost {
|
|
|
1291
1291
|
// 权限变少、不变(版本变了)或只多出视图(ui.view:*,不卡加载):直接加载,快照跟上当前清单。
|
|
1292
1292
|
// 补进视图不写审计(与 autoApprove 一样,Ruling A4),只记日志
|
|
1293
1293
|
const updated = await approvals.refresh(name, manifest.version, a.set);
|
|
1294
|
-
const merged = decision.added.filter((k) => k.startsWith(UI_VIEW_KEY_PREFIX));
|
|
1294
|
+
const merged = decision.added.filter((k) => k.startsWith(UI_VIEW_KEY_PREFIX) || k.startsWith(SETUP_CHECK_KEY_PREFIX));
|
|
1295
1295
|
if (updated && merged.length > 0 && blockingKeys(decision.added).length === 0) {
|
|
1296
|
-
this.log.info("plugin ui views merged into the permission snapshot", {
|
|
1296
|
+
this.log.info("plugin ui views and setup checks merged into the permission snapshot", {
|
|
1297
1297
|
plugin: name,
|
|
1298
1298
|
version: manifest.version,
|
|
1299
1299
|
merged,
|
|
@@ -1712,7 +1712,7 @@ let ExtensionHost = class ExtensionHost {
|
|
|
1712
1712
|
},
|
|
1713
1713
|
});
|
|
1714
1714
|
if (timeoutMs === undefined)
|
|
1715
|
-
return p;
|
|
1715
|
+
return p.then((inst) => this.logUiResolution(inst));
|
|
1716
1716
|
let timer;
|
|
1717
1717
|
let onClose = () => { };
|
|
1718
1718
|
const stop = new Promise((resolve) => {
|
|
@@ -1725,8 +1725,9 @@ let ExtensionHost = class ExtensionHost {
|
|
|
1725
1725
|
});
|
|
1726
1726
|
try {
|
|
1727
1727
|
const r = await Promise.race([p.then((inst) => ({ inst })), stop]);
|
|
1728
|
+
// a late instance that is disposed right away never logs its UI resolution
|
|
1728
1729
|
if (typeof r === "object")
|
|
1729
|
-
return r.inst;
|
|
1730
|
+
return this.logUiResolution(r.inst);
|
|
1730
1731
|
// setup 迟迟不返回:关闭它的 ctx(此后它的登记立即撤销),迟到完成的实例直接撤销
|
|
1731
1732
|
p.then((inst) => this.disposeQuietly(inst, 0), () => { });
|
|
1732
1733
|
if (this.settingUp === ctx)
|
|
@@ -1743,6 +1744,20 @@ let ExtensionHost = class ExtensionHost {
|
|
|
1743
1744
|
this.abort.signal.removeEventListener("abort", onClose);
|
|
1744
1745
|
}
|
|
1745
1746
|
}
|
|
1747
|
+
/** Logs once per load what slot resolution left out or flagged (UI slots spec §3.2). */
|
|
1748
|
+
logUiResolution(inst) {
|
|
1749
|
+
const at = { plugin: inst.name, version: inst.version };
|
|
1750
|
+
if (inst.uiDropped.length > 0) {
|
|
1751
|
+
this.log.warn("plugin ui contributions dropped", { ...at, dropped: inst.uiDropped });
|
|
1752
|
+
}
|
|
1753
|
+
if (inst.uiUnknownAnchors.length > 0) {
|
|
1754
|
+
this.log.warn("plugin ui anchors unknown", { ...at, anchors: inst.uiUnknownAnchors });
|
|
1755
|
+
}
|
|
1756
|
+
if (inst.uiDeprecatedPlace.length > 0) {
|
|
1757
|
+
this.log.info("plugin ui uses the deprecated place", { ...at, ids: inst.uiDeprecatedPlace });
|
|
1758
|
+
}
|
|
1759
|
+
return inst;
|
|
1760
|
+
}
|
|
1746
1761
|
/** 取能力实现:单选能力无需 providerName,多选能力必须指定。 */
|
|
1747
1762
|
get(capability, providerName) {
|
|
1748
1763
|
const providers = this.registry.all().filter((i) => i.provided.has(capability));
|
|
@@ -2087,17 +2102,23 @@ let ExtensionHost = class ExtensionHost {
|
|
|
2087
2102
|
* 是否在某组织启用由调用方另查(每次查询,不缓存)。
|
|
2088
2103
|
*/
|
|
2089
2104
|
uiContributions() {
|
|
2090
|
-
return this.registry.all().flatMap((i) =>
|
|
2105
|
+
return this.registry.all().flatMap((i) => i.ui.map(({ contribution: c, slot, after }) => {
|
|
2091
2106
|
const render = c.kind === "view" ? i.uiViews.get(c.id) : undefined;
|
|
2092
2107
|
const action = c.kind === "view" ? i.uiActions.get(c.id) : undefined;
|
|
2093
2108
|
return {
|
|
2094
2109
|
plugin: i.name,
|
|
2095
2110
|
contribution: c,
|
|
2111
|
+
slot,
|
|
2112
|
+
...(after !== undefined && { after }),
|
|
2096
2113
|
...(render !== undefined && { render }),
|
|
2097
2114
|
...(action !== undefined && { action }),
|
|
2098
2115
|
};
|
|
2099
2116
|
}));
|
|
2100
2117
|
}
|
|
2118
|
+
/** The UI contributions the loaded extension left out at load (UI slots spec §3.2); `[]` when not loaded. */
|
|
2119
|
+
uiDropped(name) {
|
|
2120
|
+
return [...(this.registry.current(name)?.uiDropped ?? [])];
|
|
2121
|
+
}
|
|
2101
2122
|
/** 串行执行生命周期操作(unload / reload 互不交错);宿主关闭后拒绝。 */
|
|
2102
2123
|
serial(fn) {
|
|
2103
2124
|
const guarded = () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ExtensionManifest, type ExtensionPointRef, type StaticExtensionManifest } from "@capybara-hq/plugin-sdk";
|
|
2
|
-
import { type ExtensionPointAccess, type KernelDeps, type KernelExtensionContext, LiveConfig, type RegisteredTool, type Route } from "../ctx/create-ctx.js";
|
|
1
|
+
import { type DroppedUiContribution, type ExtensionManifest, type ExtensionPointRef, type ResolvedUiContribution, type StaticExtensionManifest } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { type ExtensionPointAccess, type KernelDeps, type KernelExtensionContext, LiveConfig, type RegisteredSetupCheck, type RegisteredTool, type Route } from "../ctx/create-ctx.js";
|
|
3
3
|
import type { UiActionHandler, UiRender } from "../ui/registry.js";
|
|
4
4
|
import type { RegisteredHook } from "./hooks.js";
|
|
5
5
|
import { InflightTracker } from "./inflight.js";
|
|
@@ -44,6 +44,17 @@ export declare class ExtensionInstance {
|
|
|
44
44
|
readonly generation: number;
|
|
45
45
|
readonly manifest: ExtensionManifest;
|
|
46
46
|
readonly permissions: PermissionSet;
|
|
47
|
+
/** The manifest's UI contributions whose slot the catalog knows (UI slots spec §3.2), in manifest order. */
|
|
48
|
+
readonly ui: ResolvedUiContribution[];
|
|
49
|
+
/** The manifest's UI contributions left out at load (unknown slot or slot version). */
|
|
50
|
+
readonly uiDropped: DroppedUiContribution[];
|
|
51
|
+
/** `after` values that are not anchors of their slot (the contribution keeps the default position). */
|
|
52
|
+
readonly uiUnknownAnchors: {
|
|
53
|
+
id: string;
|
|
54
|
+
after: string;
|
|
55
|
+
}[];
|
|
56
|
+
/** Ids of contributions that still name the deprecated `place`. */
|
|
57
|
+
readonly uiDeprecatedPlace: string[];
|
|
47
58
|
private hash;
|
|
48
59
|
private readonly live;
|
|
49
60
|
readonly entryUrl: string;
|
|
@@ -68,6 +79,10 @@ export declare class ExtensionInstance {
|
|
|
68
79
|
get hooks(): readonly RegisteredHook[];
|
|
69
80
|
get uiViews(): ReadonlyMap<string, UiRender>;
|
|
70
81
|
get uiActions(): ReadonlyMap<string, UiActionHandler>;
|
|
82
|
+
/** Setup checks registered through `ctx.setup.check` (empty after revocation). */
|
|
83
|
+
get setupChecks(): ReadonlyMap<string, RegisteredSetupCheck>;
|
|
84
|
+
/** The instance's `ctx.signal`: aborted when it is revoked or disposed. */
|
|
85
|
+
get signal(): AbortSignal;
|
|
71
86
|
/** 账上仍在的登记(撤销后为空)。 */
|
|
72
87
|
registrations(): Registration[];
|
|
73
88
|
get disposed(): boolean;
|
|
@@ -60,6 +60,14 @@ export class ExtensionInstance {
|
|
|
60
60
|
generation;
|
|
61
61
|
manifest;
|
|
62
62
|
permissions;
|
|
63
|
+
/** The manifest's UI contributions whose slot the catalog knows (UI slots spec §3.2), in manifest order. */
|
|
64
|
+
ui;
|
|
65
|
+
/** The manifest's UI contributions left out at load (unknown slot or slot version). */
|
|
66
|
+
uiDropped;
|
|
67
|
+
/** `after` values that are not anchors of their slot (the contribution keeps the default position). */
|
|
68
|
+
uiUnknownAnchors;
|
|
69
|
+
/** Ids of contributions that still name the deprecated `place`. */
|
|
70
|
+
uiDeprecatedPlace;
|
|
63
71
|
hash;
|
|
64
72
|
live;
|
|
65
73
|
entryUrl;
|
|
@@ -77,6 +85,11 @@ export class ExtensionInstance {
|
|
|
77
85
|
this.source = init.source;
|
|
78
86
|
this.generation = init.generation;
|
|
79
87
|
this.permissions = init.permissions;
|
|
88
|
+
const ui = init.ctx.uiResolution;
|
|
89
|
+
this.ui = ui.resolved;
|
|
90
|
+
this.uiDropped = ui.dropped;
|
|
91
|
+
this.uiUnknownAnchors = ui.unknownAnchors;
|
|
92
|
+
this.uiDeprecatedPlace = ui.deprecatedPlace;
|
|
80
93
|
this.hash = init.configHash;
|
|
81
94
|
this.live = init.config;
|
|
82
95
|
this.entryUrl = init.entryUrl;
|
|
@@ -117,6 +130,14 @@ export class ExtensionInstance {
|
|
|
117
130
|
get uiActions() {
|
|
118
131
|
return this.ctx.uiActions;
|
|
119
132
|
}
|
|
133
|
+
/** Setup checks registered through `ctx.setup.check` (empty after revocation). */
|
|
134
|
+
get setupChecks() {
|
|
135
|
+
return this.ctx.setupChecks;
|
|
136
|
+
}
|
|
137
|
+
/** The instance's `ctx.signal`: aborted when it is revoked or disposed. */
|
|
138
|
+
get signal() {
|
|
139
|
+
return this.ctx.signal;
|
|
140
|
+
}
|
|
120
141
|
/** 账上仍在的登记(撤销后为空)。 */
|
|
121
142
|
registrations() {
|
|
122
143
|
return this.ctx.ledger.list();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** 插件经 ctx 做的一项登记的种类(C17)。 */
|
|
2
|
-
export type RegistrationKind = "tool" | "route" | "queue" | "bus" | "lease" | "ui.view" | "ui.action" | "provide" | "hook";
|
|
2
|
+
export type RegistrationKind = "tool" | "route" | "queue" | "bus" | "lease" | "ui.view" | "ui.action" | "provide" | "hook" | "setup.check";
|
|
3
3
|
/** 账上的一项:撤销时调用 `dispose()`。 */
|
|
4
4
|
export interface Registration {
|
|
5
5
|
kind: RegistrationKind;
|
|
@@ -49,6 +49,12 @@ export interface PermissionSet {
|
|
|
49
49
|
views: string[];
|
|
50
50
|
embeds: string[];
|
|
51
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Setup check ids (`permissions.setupChecks`, setup guides v2 §10.2): recorded and shown at
|
|
54
|
+
* review but never blocking loading, like `ui.views` (a check gets only data the extension
|
|
55
|
+
* already gets for the same target). Absent when none are declared (and in older snapshots).
|
|
56
|
+
*/
|
|
57
|
+
setupChecks?: string[];
|
|
52
58
|
};
|
|
53
59
|
/**
|
|
54
60
|
* 安装记录包迁移警告的摘要(`warningsDigest`,Ruling P4);没有警告或不是安装记录时省略。
|
|
@@ -106,8 +112,16 @@ export declare const POLICY_HOOK_KEY_PREFIX = "permissions.hooks.policy:";
|
|
|
106
112
|
/** 渲染 schema 视图的权限键前缀:记入快照但不卡加载(见 {@link blockingKeys})。 */
|
|
107
113
|
export declare const UI_VIEW_KEY_PREFIX = "ui.view:";
|
|
108
114
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
115
|
+
* Key prefix of a setup check id (`permissions.setupChecks`): recorded but never blocking
|
|
116
|
+
* ({@link blockingKeys}). Lower-case letters and dots before the colon, as catalog permission keys
|
|
117
|
+
* require (`PERMISSION_KEY_RE` of the marketplace format).
|
|
118
|
+
*/
|
|
119
|
+
export declare const SETUP_CHECK_KEY_PREFIX = "setup.check:";
|
|
120
|
+
/**
|
|
121
|
+
* 新增项里需要批准(卡加载)的部分:除 `ui.view:*` 与 `setup.check:*` 之外的全部。视图只是把插件已有的数据交给
|
|
122
|
+
* 内核组件来画,不给插件新能力(spec §4.1);setup checks get only data the extension already gets
|
|
123
|
+
* for the same target (setup guides v2 §10.2). An upgrade adding either loads as usual and the
|
|
124
|
+
* snapshot takes them.
|
|
111
125
|
*/
|
|
112
126
|
export declare function blockingKeys(added: readonly string[]): string[];
|
|
113
127
|
/** 两份权限集合的差异(按 {@link permissionKeys});`prev` 为空(无快照)时全部算新增。 */
|
|
@@ -108,6 +108,10 @@ export function buildPermissionSet(input) {
|
|
|
108
108
|
.sort((a, b) => cmp(a.purpose, b.purpose)),
|
|
109
109
|
network: sortedUnique(p.network),
|
|
110
110
|
ui: { views: sortedUnique(p.ui?.views), embeds: sortedUnique(p.ui?.embeds) },
|
|
111
|
+
// only when declared: sets (and snapshots) of plugins without setup checks stay as they were
|
|
112
|
+
...(p.setupChecks && p.setupChecks.length > 0
|
|
113
|
+
? { setupChecks: sortedUnique(p.setupChecks) }
|
|
114
|
+
: {}),
|
|
111
115
|
},
|
|
112
116
|
...(input.warningsDigest ? { warningsDigest: input.warningsDigest } : {}),
|
|
113
117
|
};
|
|
@@ -155,6 +159,8 @@ export function permissionKeys(set) {
|
|
|
155
159
|
keys.push(`${UI_VIEW_KEY_PREFIX}${v}`);
|
|
156
160
|
for (const e of p.ui?.embeds ?? [])
|
|
157
161
|
keys.push(`ui.embed:${e}`);
|
|
162
|
+
for (const c of p.setupChecks ?? [])
|
|
163
|
+
keys.push(`${SETUP_CHECK_KEY_PREFIX}${c}`);
|
|
158
164
|
if (s.warningsDigest)
|
|
159
165
|
keys.push(`${WARNINGS_KEY_PREFIX}${s.warningsDigest}`);
|
|
160
166
|
return sortedUnique(keys);
|
|
@@ -167,11 +173,19 @@ export const POLICY_HOOK_KEY_PREFIX = "permissions.hooks.policy:";
|
|
|
167
173
|
/** 渲染 schema 视图的权限键前缀:记入快照但不卡加载(见 {@link blockingKeys})。 */
|
|
168
174
|
export const UI_VIEW_KEY_PREFIX = "ui.view:";
|
|
169
175
|
/**
|
|
170
|
-
*
|
|
171
|
-
*
|
|
176
|
+
* Key prefix of a setup check id (`permissions.setupChecks`): recorded but never blocking
|
|
177
|
+
* ({@link blockingKeys}). Lower-case letters and dots before the colon, as catalog permission keys
|
|
178
|
+
* require (`PERMISSION_KEY_RE` of the marketplace format).
|
|
179
|
+
*/
|
|
180
|
+
export const SETUP_CHECK_KEY_PREFIX = "setup.check:";
|
|
181
|
+
/**
|
|
182
|
+
* 新增项里需要批准(卡加载)的部分:除 `ui.view:*` 与 `setup.check:*` 之外的全部。视图只是把插件已有的数据交给
|
|
183
|
+
* 内核组件来画,不给插件新能力(spec §4.1);setup checks get only data the extension already gets
|
|
184
|
+
* for the same target (setup guides v2 §10.2). An upgrade adding either loads as usual and the
|
|
185
|
+
* snapshot takes them.
|
|
172
186
|
*/
|
|
173
187
|
export function blockingKeys(added) {
|
|
174
|
-
return added.filter((k) => !k.startsWith(UI_VIEW_KEY_PREFIX));
|
|
188
|
+
return added.filter((k) => !k.startsWith(UI_VIEW_KEY_PREFIX) && !k.startsWith(SETUP_CHECK_KEY_PREFIX));
|
|
175
189
|
}
|
|
176
190
|
/** 两份权限集合的差异(按 {@link permissionKeys});`prev` 为空(无快照)时全部算新增。 */
|
|
177
191
|
export function diffPermissions(prev, next) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LocalizedName } from "@capybara-hq/plugin-sdk";
|
|
1
|
+
import type { LocalizedName, UiDropReason } from "@capybara-hq/plugin-sdk";
|
|
2
2
|
import type { PluginScope } from "../catalog/scope.js";
|
|
3
3
|
import { type PermissionSet } from "./permission-set.js";
|
|
4
4
|
import type { ExtensionSource } from "./sources.js";
|
|
@@ -142,6 +142,15 @@ export interface AdminExtensionView {
|
|
|
142
142
|
builtin: boolean;
|
|
143
143
|
/** Where the install record came from (`bootstrap` for the bootstrap step); null for config-declared. */
|
|
144
144
|
installSource: "npm" | "file" | "catalog" | "bootstrap" | null;
|
|
145
|
+
/**
|
|
146
|
+
* UI contributions this replica's loaded instance left out at load (UI slots spec §3.2): a slot the
|
|
147
|
+
* catalog does not know, or not at that version. `[]` when the extension is not loaded here.
|
|
148
|
+
*/
|
|
149
|
+
uiDropped: {
|
|
150
|
+
id: string;
|
|
151
|
+
ref: string;
|
|
152
|
+
reason: UiDropReason;
|
|
153
|
+
}[];
|
|
145
154
|
/**
|
|
146
155
|
* Only with status `conflict`: the single-provider extension point and the other extensions that
|
|
147
156
|
* provide it (they keep this one from loading; disabling them loads it, no restart).
|