@capybara-hq/kernel 0.1.0-rc.13 → 0.1.0-rc.15
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 +5 -13
- package/dist/catalog/admin-catalog.controller.d.ts +39 -5
- package/dist/catalog/admin-catalog.controller.js +75 -6
- package/dist/catalog/admin-catalog.schemas.d.ts +10 -0
- package/dist/catalog/admin-catalog.schemas.js +7 -0
- package/dist/catalog/appearance.schemas.d.ts +10 -0
- package/dist/catalog/appearance.schemas.js +20 -0
- package/dist/catalog/appearance.service.d.ts +105 -0
- package/dist/catalog/appearance.service.js +306 -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/catalog-import.module.js +3 -0
- package/dist/catalog/catalog-items.d.ts +11 -0
- package/dist/catalog/catalog-items.js +21 -0
- package/dist/catalog/catalog-scope.service.d.ts +7 -0
- package/dist/catalog/catalog-scope.service.js +55 -15
- package/dist/catalog/catalog.service.js +10 -2
- package/dist/catalog/cli.js +3 -0
- 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/org-extension.controller.d.ts +27 -7
- package/dist/catalog/org-extension.controller.js +48 -6
- package/dist/catalog/plugin-import.d.ts +28 -4
- package/dist/catalog/plugin-import.js +96 -20
- package/dist/catalog/plugin-package.d.ts +4 -2
- package/dist/catalog/plugin-package.js +66 -12
- package/dist/catalog/plugin-upgrade.d.ts +15 -1
- package/dist/catalog/plugin-upgrade.js +18 -5
- 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/webhook.d.ts +21 -1
- package/dist/channels/webhook.js +39 -4
- package/dist/client/client-access.service.d.ts +101 -0
- package/dist/client/client-access.service.js +294 -0
- package/dist/client/client-builds.service.d.ts +109 -0
- package/dist/client/client-builds.service.js +229 -0
- package/dist/client/client-delivery.controller.d.ts +25 -0
- package/dist/client/client-delivery.controller.js +66 -0
- package/dist/client/client-files.d.ts +48 -0
- package/dist/client/client-files.js +136 -0
- package/dist/client/client-reports.cron.d.ts +13 -0
- package/dist/client/client-reports.cron.js +42 -0
- package/dist/client/client-reports.service.d.ts +30 -0
- package/dist/client/client-reports.service.js +102 -0
- package/dist/client/client.controller.d.ts +45 -0
- package/dist/client/client.controller.js +121 -0
- package/dist/client/client.module.d.ts +7 -0
- package/dist/client/client.module.js +26 -0
- package/dist/client/client.schemas.d.ts +55 -0
- package/dist/client/client.schemas.js +27 -0
- package/dist/ctx/create-ctx.d.ts +19 -4
- package/dist/ctx/create-ctx.js +51 -3
- package/dist/db/kernel-schema.d.ts +58 -2
- package/dist/errors.d.ts +33 -0
- package/dist/errors.js +33 -0
- package/dist/extensions/admin-ops.d.ts +4 -1
- package/dist/extensions/admin-ops.js +22 -1
- package/dist/extensions/admin-view.d.ts +8 -0
- package/dist/extensions/admin-view.js +78 -0
- package/dist/extensions/blobs.d.ts +14 -1
- package/dist/extensions/blobs.js +48 -5
- package/dist/extensions/guide-places.d.ts +66 -0
- package/dist/extensions/guide-places.js +152 -0
- package/dist/extensions/host.d.ts +6 -1
- package/dist/extensions/host.js +23 -12
- package/dist/extensions/instance.d.ts +5 -1
- package/dist/extensions/instance.js +8 -0
- package/dist/extensions/ledger.d.ts +1 -1
- package/dist/extensions/package.d.ts +4 -3
- package/dist/extensions/package.js +5 -1
- package/dist/extensions/permission-set.d.ts +35 -5
- package/dist/extensions/permission-set.js +36 -5
- package/dist/extensions/permission-view.d.ts +38 -7
- package/dist/extensions/permission-view.js +27 -8
- package/dist/extensions/plugin-guides.d.ts +207 -54
- package/dist/extensions/plugin-guides.js +436 -165
- package/dist/extensions/sources.d.ts +6 -0
- package/dist/extensions/sources.js +2 -0
- package/dist/extensions/state.module.js +9 -1
- package/dist/http/api.module.js +16 -0
- package/dist/identity/settings.d.ts +41 -26
- package/dist/identity/settings.js +87 -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 +8 -1
- package/dist/infra/throttler/named-throttlers.js +30 -1
- package/dist/infra/throttler/throttler.guard.js +1 -1
- package/dist/kernel.module.js +3 -0
- package/dist/orgs/settings.service.d.ts +2 -26
- package/dist/overrides.d.ts +3 -1
- package/dist/overrides.js +2 -0
- package/dist/platform/exclusions.js +37 -6
- package/dist/platform/operation.js +4 -0
- package/dist/platform/ops/admin.ops.js +17 -2
- package/dist/platform/ops/catalog-admin.ops.d.ts +19 -1
- package/dist/platform/ops/catalog-admin.ops.js +85 -2
- package/dist/platform/ops/connectors.ops.js +2 -0
- package/dist/platform/ops/org-plugins.ops.d.ts +7 -1
- package/dist/platform/ops/org-plugins.ops.js +63 -4
- 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.js +1 -1
- package/dist/platform/platform-ops.module.d.ts +2 -1
- package/dist/platform/platform-ops.module.js +7 -0
- package/dist/platform/route-schemas.js +8 -0
- package/dist/roles/worker.module.js +4 -0
- 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/themes/render-css.d.ts +2 -1
- package/dist/themes/render-css.js +5 -2
- package/dist/themes/theme-delivery.service.d.ts +4 -2
- package/dist/themes/theme-delivery.service.js +8 -3
- package/dist/themes/theme-state.d.ts +28 -7
- package/dist/themes/theme-state.js +24 -6
- package/dist/themes/themes-public.controller.d.ts +7 -2
- package/dist/themes/themes-public.controller.js +11 -5
- package/dist/themes/themes.service.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.d.ts +3 -2
- package/dist/ui/arrangement.d.ts +41 -50
- package/dist/ui/arrangement.js +88 -15
- package/dist/ui/registry.d.ts +13 -3
- package/dist/ui/registry.js +15 -4
- package/dist/ui/ui.schemas.d.ts +4 -0
- package/dist/ui/views.d.ts +36 -9
- package/dist/ui/views.js +58 -28
- package/package.json +3 -3
- package/src/migrations/0106_setup_guides_v2.sql +10 -0
- package/src/migrations/0107_extension_client_builds.sql +50 -0
|
@@ -53,19 +53,11 @@ export declare const DeploymentSettingsBody: z.ZodObject<{
|
|
|
53
53
|
uiTheme: z.ZodOptional<z.ZodObject<{
|
|
54
54
|
id: z.ZodNullable<z.ZodString>;
|
|
55
55
|
}, z.core.$strict>>;
|
|
56
|
-
uiArrangement: z.ZodOptional<z.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"file.preview": "file.preview";
|
|
62
|
-
"org.page": "org.page";
|
|
63
|
-
"org.settings.section": "org.settings.section";
|
|
64
|
-
"platform.page": "platform.page";
|
|
65
|
-
}> & z.core.$partial, z.ZodNullable<z.ZodObject<{
|
|
66
|
-
hidden: z.ZodArray<z.ZodString>;
|
|
67
|
-
order: z.ZodArray<z.ZodString>;
|
|
68
|
-
}, z.core.$strict>>>>;
|
|
56
|
+
uiArrangement: z.ZodOptional<z.ZodType<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry | null>>, unknown, z.core.$ZodTypeInternals<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry | null>>, unknown>>>;
|
|
57
|
+
clientExtensions: z.ZodOptional<z.ZodObject<{
|
|
58
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
59
|
+
disabled: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
60
|
+
}, z.core.$strict>>;
|
|
69
61
|
}, z.core.$strict>;
|
|
70
62
|
export declare const PurposeParams: z.ZodObject<{
|
|
71
63
|
purpose: z.ZodString;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import type { SuggestedAppearance } from "@capybara-hq/plugin-sdk";
|
|
1
2
|
import type { FastifyReply } from "fastify";
|
|
2
3
|
import { z } from "zod";
|
|
4
|
+
import { type ClientBuildSummary, ClientBuilds } from "../client/client-builds.service.js";
|
|
5
|
+
import { PluginGuides, type RenderedSetupGuide } from "../extensions/plugin-guides.js";
|
|
3
6
|
import { PluginIcons } from "../extensions/plugin-icons.js";
|
|
4
7
|
import { type Principal } from "../identity/principal.js";
|
|
5
|
-
import { CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogNpmImportBody as NpmBody, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody } from "./admin-catalog.schemas.js";
|
|
8
|
+
import { AdminCatalogGuideQuery, CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogNpmImportBody as NpmBody, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody } from "./admin-catalog.schemas.js";
|
|
9
|
+
import { AppearanceApplyBody } from "./appearance.schemas.js";
|
|
10
|
+
import { type AppearanceResult, AppearanceService } from "./appearance.service.js";
|
|
6
11
|
import { type CatalogItemDetail, type CatalogItemView, CatalogService, type PermissionsMismatch } from "./catalog.service.js";
|
|
7
12
|
import { CatalogScopeService, type ScopePreview } from "./catalog-scope.service.js";
|
|
8
13
|
import { OrgCatalogService } from "./org-catalog.service.js";
|
|
@@ -38,7 +43,10 @@ export declare class AdminCatalogController {
|
|
|
38
43
|
private readonly scope;
|
|
39
44
|
private readonly updater;
|
|
40
45
|
private readonly icons;
|
|
41
|
-
|
|
46
|
+
private readonly appearance;
|
|
47
|
+
private readonly clientBuilds;
|
|
48
|
+
private readonly guides;
|
|
49
|
+
constructor(catalog: CatalogService, pluginImport: PluginImport, orgCatalog: OrgCatalogService, scope: CatalogScopeService, updater: PlatformPluginUpdater, icons: PluginIcons, appearance: AppearanceService, clientBuilds: ClientBuilds, guides: PluginGuides);
|
|
42
50
|
/**
|
|
43
51
|
* Prepares the import of an uploaded plugin (an npm-pack tgz as the raw body,
|
|
44
52
|
* `application/octet-stream`, at most `packages.maxBytes`): reads and checks the whole plugin
|
|
@@ -113,17 +121,43 @@ export declare class AdminCatalogController {
|
|
|
113
121
|
nextOffset: number | null;
|
|
114
122
|
}>;
|
|
115
123
|
/**
|
|
116
|
-
*
|
|
117
|
-
* `
|
|
124
|
+
* The item with its versions, plus `hasIcon` (the latest version has an icon, served by `GET
|
|
125
|
+
* items/:id/icon`) and `suggestedAppearance` (the platform version's, null without one: the page
|
|
126
|
+
* offers 应用此插件的外观 when set). Each version carries `client`: its extension package's
|
|
127
|
+
* client build (files with sizes, total, client API version; null without one), what the
|
|
128
|
+
* permission confirmation of an org's upload shows in its 客户端代码 group (client extensions spec
|
|
129
|
+
* §5.4). Unknown -> 404 `catalog.item_not_found`.
|
|
118
130
|
*/
|
|
119
|
-
get(id: string): Promise<CatalogItemDetail & {
|
|
131
|
+
get(id: string): Promise<Omit<CatalogItemDetail, "versions"> & {
|
|
132
|
+
versions: (CatalogItemDetail["versions"][number] & {
|
|
133
|
+
client: ClientBuildSummary | null;
|
|
134
|
+
})[];
|
|
120
135
|
hasIcon: boolean;
|
|
136
|
+
suggestedAppearance: SuggestedAppearance | null;
|
|
121
137
|
}>;
|
|
138
|
+
/**
|
|
139
|
+
* 应用此插件的外观 (client extensions spec §6.5): sets the plugin's suggested theme as the platform
|
|
140
|
+
* default theme and each suggested replacement as the platform arrangement's `use` of its slot, in
|
|
141
|
+
* one transaction. `dryRun: true` answers the same changes and writes nothing. A theme that cannot
|
|
142
|
+
* be the platform default -> 400 `theme.not_available` (nothing written); a replacement not
|
|
143
|
+
* available on the platform is skipped. No such item, or no suggestion -> 404
|
|
144
|
+
* `catalog.item_not_found`.
|
|
145
|
+
*/
|
|
146
|
+
applyAppearance(principal: Principal, id: string, body: z.infer<typeof AppearanceApplyBody>): Promise<AppearanceResult>;
|
|
122
147
|
/**
|
|
123
148
|
* The item's icon (disabled items included; same response headers as the org side, see
|
|
124
149
|
* `sendCatalogIcon`). No icon -> 404 `catalog.icon_not_found`.
|
|
125
150
|
*/
|
|
126
151
|
icon(id: string, reply: FastifyReply): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* A setup guide of the item as the platform sees it (spec 2026-11-09-setup-guides-v2-design.md
|
|
154
|
+
* §9.3; the admin console's connector template page): any live item, the admin audience, no org
|
|
155
|
+
* (`orgName` unresolved, reason `no_org`), no target, no checks run. Unknown item -> 404
|
|
156
|
+
* `catalog.item_not_found`, unknown guide -> 404 `catalog.guide_not_found`.
|
|
157
|
+
*/
|
|
158
|
+
guide(itemId: string, guideId: string, q: z.infer<typeof AdminCatalogGuideQuery>): Promise<{
|
|
159
|
+
guide: RenderedSetupGuide;
|
|
160
|
+
}>;
|
|
127
161
|
/**
|
|
128
162
|
* What a scope change (`{ scope, orgs? }`, `orgs` only with `named`) or a disable
|
|
129
163
|
* (`{ disabled: true }`) would take away: `{ affected: [{ orgId, orgName, agents,
|
|
@@ -9,12 +9,16 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
9
9
|
};
|
|
10
10
|
import { Controller, Delete, Get, HttpCode, Inject, Param, Post, Put, Req, Res, } from "@nestjs/common";
|
|
11
11
|
import { z } from "zod";
|
|
12
|
+
import { ClientBuilds } from "../client/client-builds.service.js";
|
|
12
13
|
import { ApiError } from "../errors.js";
|
|
14
|
+
import { PluginGuides } from "../extensions/plugin-guides.js";
|
|
13
15
|
import { PluginIcons } from "../extensions/plugin-icons.js";
|
|
14
16
|
import { CurrentPrincipal, patTokenId, requireUser, SuperAdmin, } from "../identity/principal.js";
|
|
15
17
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
16
18
|
import { ZBody, ZQuery } from "../infra/validation/zod-params.js";
|
|
17
|
-
import { CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogHash as Hash, CatalogNpmImportBody as NpmBody, CatalogScopeOrgs as Orgs, CatalogScope as Scope, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody, } from "./admin-catalog.schemas.js";
|
|
19
|
+
import { AdminCatalogGuideQuery, CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogHash as Hash, CatalogNpmImportBody as NpmBody, CatalogScopeOrgs as Orgs, CatalogScope as Scope, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody, } from "./admin-catalog.schemas.js";
|
|
20
|
+
import { AppearanceApplyBody } from "./appearance.schemas.js";
|
|
21
|
+
import { AppearanceService, suggestedAppearanceOf, } from "./appearance.service.js";
|
|
18
22
|
import { CatalogService, } from "./catalog.service.js";
|
|
19
23
|
import { CatalogScopeService } from "./catalog-scope.service.js";
|
|
20
24
|
import { sendCatalogIcon } from "./org-catalog.controller.js";
|
|
@@ -42,6 +46,8 @@ class CatalogImportConfirmBody extends createZodDto(ConfirmBody, "CatalogImportC
|
|
|
42
46
|
}
|
|
43
47
|
class CatalogGitImportBody extends createZodDto(GitBody, "CatalogGitImportBody") {
|
|
44
48
|
}
|
|
49
|
+
class AdminCatalogGuideQueryDto extends createZodDto(AdminCatalogGuideQuery, "AdminCatalogGuideQuery") {
|
|
50
|
+
}
|
|
45
51
|
class CatalogItemsQueryDto extends createZodDto(CatalogItemsQuery, "CatalogItemsQuery") {
|
|
46
52
|
}
|
|
47
53
|
class CatalogNpmImportBody extends createZodDto(NpmBody, "CatalogNpmImportBody") {
|
|
@@ -62,6 +68,8 @@ class CatalogUpdatePreviewBodyDto extends createZodDto(CatalogUpdatePreviewBody,
|
|
|
62
68
|
}
|
|
63
69
|
class CatalogUpdateBodyDto extends createZodDto(CatalogUpdateBody, "CatalogUpdateBody") {
|
|
64
70
|
}
|
|
71
|
+
class AppearanceApplyBodyDto extends createZodDto(AppearanceApplyBody, "AppearanceApplyBody") {
|
|
72
|
+
}
|
|
65
73
|
/**
|
|
66
74
|
* The platform catalog (`/api/v1/admin/catalog/*`, super admins): plugin import (upload / npm
|
|
67
75
|
* prepare, then confirm, which installs the plugin's extension), the item list and detail, scope and
|
|
@@ -75,13 +83,19 @@ let AdminCatalogController = class AdminCatalogController {
|
|
|
75
83
|
scope;
|
|
76
84
|
updater;
|
|
77
85
|
icons;
|
|
78
|
-
|
|
86
|
+
appearance;
|
|
87
|
+
clientBuilds;
|
|
88
|
+
guides;
|
|
89
|
+
constructor(catalog, pluginImport, orgCatalog, scope, updater, icons, appearance, clientBuilds, guides) {
|
|
79
90
|
this.catalog = catalog;
|
|
80
91
|
this.pluginImport = pluginImport;
|
|
81
92
|
this.orgCatalog = orgCatalog;
|
|
82
93
|
this.scope = scope;
|
|
83
94
|
this.updater = updater;
|
|
84
95
|
this.icons = icons;
|
|
96
|
+
this.appearance = appearance;
|
|
97
|
+
this.clientBuilds = clientBuilds;
|
|
98
|
+
this.guides = guides;
|
|
85
99
|
}
|
|
86
100
|
/**
|
|
87
101
|
* Prepares the import of an uploaded plugin (an npm-pack tgz as the raw body,
|
|
@@ -175,12 +189,42 @@ let AdminCatalogController = class AdminCatalogController {
|
|
|
175
189
|
return { ...page, items: page.items.map((i) => ({ ...i, icon: icons.get(i.id) ?? null })) };
|
|
176
190
|
}
|
|
177
191
|
/**
|
|
178
|
-
*
|
|
179
|
-
* `
|
|
192
|
+
* The item with its versions, plus `hasIcon` (the latest version has an icon, served by `GET
|
|
193
|
+
* items/:id/icon`) and `suggestedAppearance` (the platform version's, null without one: the page
|
|
194
|
+
* offers 应用此插件的外观 when set). Each version carries `client`: its extension package's
|
|
195
|
+
* client build (files with sizes, total, client API version; null without one), what the
|
|
196
|
+
* permission confirmation of an org's upload shows in its 客户端代码 group (client extensions spec
|
|
197
|
+
* §5.4). Unknown -> 404 `catalog.item_not_found`.
|
|
180
198
|
*/
|
|
181
199
|
async get(id) {
|
|
182
200
|
const detail = await this.catalog.get(id);
|
|
183
|
-
|
|
201
|
+
const platform = detail.versions.find((v) => v.version === detail.item.platformVersion);
|
|
202
|
+
const [hasIcon, builds] = await Promise.all([
|
|
203
|
+
this.orgCatalog.hasIcon(id),
|
|
204
|
+
this.clientBuilds.summaries(detail.versions.flatMap((v) => (v.extensionSha256 === null ? [] : [v.extensionSha256]))),
|
|
205
|
+
]);
|
|
206
|
+
return {
|
|
207
|
+
...detail,
|
|
208
|
+
versions: detail.versions.map((v) => ({
|
|
209
|
+
...v,
|
|
210
|
+
client: v.extensionSha256 === null ? null : (builds.get(v.extensionSha256) ?? null),
|
|
211
|
+
})),
|
|
212
|
+
hasIcon,
|
|
213
|
+
suggestedAppearance: suggestedAppearanceOf(platform?.manifest),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* 应用此插件的外观 (client extensions spec §6.5): sets the plugin's suggested theme as the platform
|
|
218
|
+
* default theme and each suggested replacement as the platform arrangement's `use` of its slot, in
|
|
219
|
+
* one transaction. `dryRun: true` answers the same changes and writes nothing. A theme that cannot
|
|
220
|
+
* be the platform default -> 400 `theme.not_available` (nothing written); a replacement not
|
|
221
|
+
* available on the platform is skipped. No such item, or no suggestion -> 404
|
|
222
|
+
* `catalog.item_not_found`.
|
|
223
|
+
*/
|
|
224
|
+
applyAppearance(principal, id, body) {
|
|
225
|
+
const actor = requireUser(principal);
|
|
226
|
+
const tokenId = patTokenId(actor);
|
|
227
|
+
return this.appearance.apply({ platform: true }, id, { accountId: actor.account.id, ...(tokenId !== undefined && { tokenId }) }, body.dryRun === true);
|
|
184
228
|
}
|
|
185
229
|
/**
|
|
186
230
|
* The item's icon (disabled items included; same response headers as the org side, see
|
|
@@ -189,6 +233,15 @@ let AdminCatalogController = class AdminCatalogController {
|
|
|
189
233
|
async icon(id, reply) {
|
|
190
234
|
await sendCatalogIcon(reply, await this.orgCatalog.icon(id, true));
|
|
191
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* A setup guide of the item as the platform sees it (spec 2026-11-09-setup-guides-v2-design.md
|
|
238
|
+
* §9.3; the admin console's connector template page): any live item, the admin audience, no org
|
|
239
|
+
* (`orgName` unresolved, reason `no_org`), no target, no checks run. Unknown item -> 404
|
|
240
|
+
* `catalog.item_not_found`, unknown guide -> 404 `catalog.guide_not_found`.
|
|
241
|
+
*/
|
|
242
|
+
async guide(itemId, guideId, q) {
|
|
243
|
+
return { guide: await this.guides.renderForPlatform(itemId, guideId, q) };
|
|
244
|
+
}
|
|
192
245
|
/**
|
|
193
246
|
* What a scope change (`{ scope, orgs? }`, `orgs` only with `named`) or a disable
|
|
194
247
|
* (`{ disabled: true }`) would take away: `{ affected: [{ orgId, orgName, agents,
|
|
@@ -326,11 +379,24 @@ __decorate([
|
|
|
326
379
|
Get("items/:id"),
|
|
327
380
|
__param(0, Param("id"))
|
|
328
381
|
], AdminCatalogController.prototype, "get", null);
|
|
382
|
+
__decorate([
|
|
383
|
+
Post("items/:id/appearance"),
|
|
384
|
+
HttpCode(200),
|
|
385
|
+
__param(0, CurrentPrincipal()),
|
|
386
|
+
__param(1, Param("id")),
|
|
387
|
+
__param(2, ZBody(AppearanceApplyBodyDto))
|
|
388
|
+
], AdminCatalogController.prototype, "applyAppearance", null);
|
|
329
389
|
__decorate([
|
|
330
390
|
Get("items/:id/icon"),
|
|
331
391
|
__param(0, Param("id")),
|
|
332
392
|
__param(1, Res())
|
|
333
393
|
], AdminCatalogController.prototype, "icon", null);
|
|
394
|
+
__decorate([
|
|
395
|
+
Get(":itemId/guides/:guideId"),
|
|
396
|
+
__param(0, Param("itemId")),
|
|
397
|
+
__param(1, Param("guideId")),
|
|
398
|
+
__param(2, ZQuery(AdminCatalogGuideQueryDto))
|
|
399
|
+
], AdminCatalogController.prototype, "guide", null);
|
|
334
400
|
__decorate([
|
|
335
401
|
Post("items/:id/scope/preview"),
|
|
336
402
|
HttpCode(200),
|
|
@@ -395,6 +461,9 @@ AdminCatalogController = __decorate([
|
|
|
395
461
|
__param(2, Inject(OrgCatalogService)),
|
|
396
462
|
__param(3, Inject(CatalogScopeService)),
|
|
397
463
|
__param(4, Inject(PlatformPluginUpdater)),
|
|
398
|
-
__param(5, Inject(PluginIcons))
|
|
464
|
+
__param(5, Inject(PluginIcons)),
|
|
465
|
+
__param(6, Inject(AppearanceService)),
|
|
466
|
+
__param(7, Inject(ClientBuilds)),
|
|
467
|
+
__param(8, Inject(PluginGuides))
|
|
399
468
|
], AdminCatalogController);
|
|
400
469
|
export { AdminCatalogController };
|
|
@@ -69,4 +69,14 @@ export declare const CatalogDisabledBody: z.ZodObject<{
|
|
|
69
69
|
export declare const CatalogShownBody: z.ZodObject<{
|
|
70
70
|
shownToOthers: z.ZodBoolean;
|
|
71
71
|
}, z.core.$strict>;
|
|
72
|
+
/**
|
|
73
|
+
* `GET :itemId/guides/:guideId`, the super admin's preview of a setup guide (spec
|
|
74
|
+
* 2026-11-09-setup-guides-v2-design.md §9.3): only the document language; no org, no target.
|
|
75
|
+
*/
|
|
76
|
+
export declare const AdminCatalogGuideQuery: z.ZodObject<{
|
|
77
|
+
locale: z.ZodOptional<z.ZodEnum<{
|
|
78
|
+
en: "en";
|
|
79
|
+
zh: "zh";
|
|
80
|
+
}>>;
|
|
81
|
+
}, z.core.$strict>;
|
|
72
82
|
export declare const ADMIN_CATALOG_ROUTES: readonly RouteSchemas[];
|
|
@@ -52,6 +52,13 @@ export const CatalogDisabledBody = z
|
|
|
52
52
|
.object({ disabled: z.boolean(), scopeHash: CatalogHash.optional() })
|
|
53
53
|
.strict();
|
|
54
54
|
export const CatalogShownBody = z.object({ shownToOthers: z.boolean() }).strict();
|
|
55
|
+
/**
|
|
56
|
+
* `GET :itemId/guides/:guideId`, the super admin's preview of a setup guide (spec
|
|
57
|
+
* 2026-11-09-setup-guides-v2-design.md §9.3): only the document language; no org, no target.
|
|
58
|
+
*/
|
|
59
|
+
export const AdminCatalogGuideQuery = z
|
|
60
|
+
.object({ locale: z.enum(["en", "zh"]).optional() })
|
|
61
|
+
.strict();
|
|
55
62
|
export const ADMIN_CATALOG_ROUTES = [
|
|
56
63
|
{ route: "GET /api/v1/admin/catalog/items", query: CatalogItemsQuery },
|
|
57
64
|
{ route: "GET /api/v1/admin/catalog/items/:id", params: CatalogIdPathParams },
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { RouteSchemas } from "../platform/route-schemas.js";
|
|
3
|
+
/**
|
|
4
|
+
* The body of both "apply this plugin's appearance" routes (client extensions spec §6.5):
|
|
5
|
+
* `dryRun: true` answers what would change and writes nothing (the confirm dialog's preview).
|
|
6
|
+
*/
|
|
7
|
+
export declare const AppearanceApplyBody: z.ZodObject<{
|
|
8
|
+
dryRun: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
}, z.core.$strict>;
|
|
10
|
+
export declare const APPEARANCE_ROUTES: readonly RouteSchemas[];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CatalogIdPathParams } from "./admin-catalog.schemas.js";
|
|
3
|
+
import { OrgExtensionParams } from "./org-extension.schemas.js";
|
|
4
|
+
/**
|
|
5
|
+
* The body of both "apply this plugin's appearance" routes (client extensions spec §6.5):
|
|
6
|
+
* `dryRun: true` answers what would change and writes nothing (the confirm dialog's preview).
|
|
7
|
+
*/
|
|
8
|
+
export const AppearanceApplyBody = z.object({ dryRun: z.boolean().optional() }).strict();
|
|
9
|
+
export const APPEARANCE_ROUTES = [
|
|
10
|
+
{
|
|
11
|
+
route: "POST /api/v1/admin/catalog/items/:id/appearance",
|
|
12
|
+
params: CatalogIdPathParams,
|
|
13
|
+
body: AppearanceApplyBody,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
route: "POST /api/v1/orgs/:orgId/extensions/:extension/appearance",
|
|
17
|
+
params: OrgExtensionParams,
|
|
18
|
+
body: AppearanceApplyBody,
|
|
19
|
+
},
|
|
20
|
+
];
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { type SuggestedAppearance } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { ExtensionHost } from "../extensions/host.js";
|
|
3
|
+
import { SettingsService } from "../identity/settings.js";
|
|
4
|
+
import { SuperAdminLock } from "../identity/super-admin.js";
|
|
5
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
6
|
+
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
7
|
+
import { OrgLock } from "../orgs/org-lock.js";
|
|
8
|
+
import { OrgSettingsService } from "../orgs/settings.service.js";
|
|
9
|
+
/** Where the suggestion is applied: the platform defaults, or one org's. */
|
|
10
|
+
export type AppearanceLevel = {
|
|
11
|
+
platform: true;
|
|
12
|
+
} | {
|
|
13
|
+
orgId: string;
|
|
14
|
+
};
|
|
15
|
+
/** Why a replacement of the suggestion was left out (client extensions spec §6.5). */
|
|
16
|
+
export type AppearanceSkipReason = "unknown-slot" | "not-available" | "not-eligible";
|
|
17
|
+
/**
|
|
18
|
+
* What applying a suggestion changes at its level: the default theme (`from`: the theme in effect,
|
|
19
|
+
* null for none; `to`: the `platform_themes` id; null when the plugin suggests no theme or it is
|
|
20
|
+
* in effect already), each replacement slot's `use` (`to`: the contribution key
|
|
21
|
+
* `<extension>/<contribution>`; `from`: the key in effect, null for the built-in; a slot that
|
|
22
|
+
* already uses it is not listed) and what was skipped, in plugin.json order. At org level `from`
|
|
23
|
+
* is the org's own entry, else the platform's: `followsPlatform` says which (absent at platform
|
|
24
|
+
* level), and when the org follows a platform that already uses the suggestion nothing is pinned.
|
|
25
|
+
*/
|
|
26
|
+
export interface AppearanceResult {
|
|
27
|
+
theme: {
|
|
28
|
+
from: string | null;
|
|
29
|
+
to: string;
|
|
30
|
+
followsPlatform?: boolean;
|
|
31
|
+
} | null;
|
|
32
|
+
replacements: {
|
|
33
|
+
slot: string;
|
|
34
|
+
from: string | null;
|
|
35
|
+
to: string;
|
|
36
|
+
followsPlatform?: boolean;
|
|
37
|
+
}[];
|
|
38
|
+
skipped: {
|
|
39
|
+
what: string;
|
|
40
|
+
reason: AppearanceSkipReason;
|
|
41
|
+
}[];
|
|
42
|
+
}
|
|
43
|
+
/** Who applies it: the account, the PAT when one made the call, and extra audit detail. */
|
|
44
|
+
export interface AppearanceActor {
|
|
45
|
+
accountId: string;
|
|
46
|
+
tokenId?: string;
|
|
47
|
+
/** Merged into the settings writer's audit detail (the Platform tool's `via: "agent"`). */
|
|
48
|
+
auditDetail?: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
/** The suggestion of a plugin's catalog version, or null (none, or not an object). */
|
|
51
|
+
export declare function suggestedAppearanceOf(manifest: unknown): SuggestedAppearance | null;
|
|
52
|
+
/**
|
|
53
|
+
* "Apply this plugin's appearance" (client extensions spec §6.5): one step that sets the plugin's
|
|
54
|
+
* suggested theme as the level's default theme and each suggested replacement as the level's `use`
|
|
55
|
+
* of its single slot. The writes go through the settings writers (`SettingsService.update` for the
|
|
56
|
+
* platform, `OrgSettingsService.update` for an org), so their validation, theme checks, lock order
|
|
57
|
+
* (the level's lock, then catalog item, theme row, `uiTheme` row) and audit apply, both settings in
|
|
58
|
+
* one call and one transaction: a theme that cannot be set (`theme.not_available`) refuses the
|
|
59
|
+
* whole call; a replacement that cannot be used where it is set is skipped, never refused (the
|
|
60
|
+
* arrangement keeps unknown keys anyway). A dry run computes the same answer and writes nothing.
|
|
61
|
+
*/
|
|
62
|
+
export declare class AppearanceService {
|
|
63
|
+
private readonly db;
|
|
64
|
+
readonly txHost: TransactionHost;
|
|
65
|
+
private readonly settings;
|
|
66
|
+
private readonly orgSettings;
|
|
67
|
+
private readonly adminLock;
|
|
68
|
+
private readonly orgLock;
|
|
69
|
+
private readonly host;
|
|
70
|
+
constructor(db: KernelDb, txHost: TransactionHost, settings: SettingsService, orgSettings: OrgSettingsService, adminLock: SuperAdminLock, orgLock: OrgLock, host: ExtensionHost);
|
|
71
|
+
/**
|
|
72
|
+
* The suggestions of the live plugins named `names`, from the version their components come from
|
|
73
|
+
* (`platform_synced_version`, else the latest); a plugin without one maps to null.
|
|
74
|
+
*/
|
|
75
|
+
suggestions(names: readonly string[]): Promise<Map<string, SuggestedAppearance | null>>;
|
|
76
|
+
/** The live catalog item `itemId` with its suggestion; else `catalog.item_not_found`. */
|
|
77
|
+
private platformItem;
|
|
78
|
+
/**
|
|
79
|
+
* The live plugin of extension `extension`, which must be on in the org, with its suggestion;
|
|
80
|
+
* else `extension.not_found`.
|
|
81
|
+
*/
|
|
82
|
+
private orgItem;
|
|
83
|
+
/**
|
|
84
|
+
* Applies (or, with `dryRun`, previews) the suggestion of `item` at `level`: for the platform,
|
|
85
|
+
* `item` is the catalog item id (`POST /api/v1/admin/catalog/items/:id/appearance`, super
|
|
86
|
+
* admin); for an org, the extension name (`POST /api/v1/orgs/:orgId/extensions/:extension/
|
|
87
|
+
* appearance`, `org.update`). The writers re-check the actor under their lock.
|
|
88
|
+
*/
|
|
89
|
+
apply(level: AppearanceLevel, item: string, actor: AppearanceActor, dryRun: boolean): Promise<AppearanceResult>;
|
|
90
|
+
/** Refuses (`theme.not_available`) a theme the level's writer would refuse; reads only. */
|
|
91
|
+
private assertThemeSettable;
|
|
92
|
+
private applyPlatform;
|
|
93
|
+
private applyOrg;
|
|
94
|
+
/**
|
|
95
|
+
* What applying `found` at `level` changes, from the stored settings (no writes): the level's
|
|
96
|
+
* own, and at org level the platform's it follows where it stores nothing.
|
|
97
|
+
*/
|
|
98
|
+
private plan;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The suggested appearance action: its own module, since it writes through the org settings
|
|
102
|
+
* writer (`OrgsModule`, which imports `CatalogModule`) and the deployment settings writer.
|
|
103
|
+
*/
|
|
104
|
+
export declare class AppearanceModule {
|
|
105
|
+
}
|