@capybara-hq/kernel 0.1.0-rc.5 → 0.1.0-rc.7
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/bootstrap.json +27 -3
- package/dist/admin/admin.controller.d.ts +21 -74
- package/dist/admin/admin.controller.js +50 -50
- package/dist/admin/admin.schemas.d.ts +57 -0
- package/dist/admin/admin.schemas.js +50 -0
- package/dist/admin/extensions.controller.d.ts +10 -0
- package/dist/admin/extensions.controller.js +18 -0
- package/dist/admin/extensions.schemas.d.ts +7 -0
- package/dist/admin/extensions.schemas.js +10 -0
- package/dist/admin/limit-defaults.d.ts +20 -0
- package/dist/admin/limit-defaults.js +10 -0
- package/dist/agents/agent-profile.service.d.ts +7 -5
- package/dist/agents/agent-profile.service.js +14 -9
- package/dist/agents/agents.controller.d.ts +7 -287
- package/dist/agents/agents.controller.js +7 -67
- package/dist/agents/agents.schemas.d.ts +389 -0
- package/dist/agents/agents.schemas.js +126 -0
- package/dist/agents/agents.service.d.ts +16 -6
- package/dist/agents/agents.service.js +75 -19
- package/dist/agents/definition.d.ts +47 -19
- package/dist/agents/definition.js +119 -38
- package/dist/agents/from-template.d.ts +2 -2
- package/dist/agents/from-template.js +76 -45
- package/dist/agents/from-template.service.d.ts +12 -0
- package/dist/agents/from-template.service.js +23 -6
- package/dist/agents/models.controller.d.ts +33 -5
- package/dist/agents/models.controller.js +50 -6
- package/dist/agents/org-templates.d.ts +13 -3
- package/dist/agents/org-templates.js +69 -28
- package/dist/agents/pending-connector-requests.d.ts +2 -0
- package/dist/agents/pending-connector-requests.js +1 -1
- package/dist/agents/pending-connectors.controller.d.ts +1 -1
- package/dist/agents/pending-connectors.controller.js +2 -2
- package/dist/agents/pending-connectors.service.d.ts +2 -2
- package/dist/agents/pending-connectors.service.js +19 -19
- package/dist/agents/profile.d.ts +18 -0
- package/dist/agents/profile.js +5 -1
- package/dist/agents/readiness.controller.d.ts +5 -5
- package/dist/agents/readiness.controller.js +6 -6
- package/dist/agents/templates.controller.d.ts +8 -17
- package/dist/agents/templates.controller.js +13 -31
- package/dist/agents/templates.schemas.d.ts +20 -0
- package/dist/agents/templates.schemas.js +45 -0
- package/dist/background/background.controller.js +3 -2
- package/dist/background/background.schemas.d.ts +10 -0
- package/dist/background/background.schemas.js +16 -0
- package/dist/background/tasks.service.d.ts +1 -1
- package/dist/background/tasks.service.js +7 -2
- package/dist/catalog/admin-catalog.controller.d.ts +4 -57
- package/dist/catalog/admin-catalog.controller.js +8 -45
- package/dist/catalog/admin-catalog.schemas.d.ts +72 -0
- package/dist/catalog/admin-catalog.schemas.js +92 -0
- package/dist/catalog/catalog-content.d.ts +12 -2
- package/dist/catalog/catalog-scope.service.js +8 -2
- package/dist/catalog/catalog.service.d.ts +2 -0
- package/dist/catalog/catalog.service.js +3 -0
- package/dist/catalog/component-scope.controller.d.ts +3 -65
- package/dist/catalog/component-scope.controller.js +3 -56
- package/dist/catalog/component-scope.schemas.d.ts +114 -0
- package/dist/catalog/component-scope.schemas.js +97 -0
- package/dist/catalog/component-scope.service.d.ts +28 -4
- package/dist/catalog/component-scope.service.js +55 -3
- package/dist/catalog/component-state.d.ts +9 -2
- package/dist/catalog/component-state.js +22 -13
- package/dist/catalog/marketplaces.controller.d.ts +5 -35
- package/dist/catalog/marketplaces.controller.js +6 -34
- package/dist/catalog/marketplaces.schemas.d.ts +48 -0
- package/dist/catalog/marketplaces.schemas.js +53 -0
- package/dist/catalog/marketplaces.service.d.ts +15 -1
- package/dist/catalog/marketplaces.service.js +22 -1
- package/dist/catalog/org-catalog.controller.d.ts +6 -62
- package/dist/catalog/org-catalog.controller.js +12 -66
- package/dist/catalog/org-catalog.schemas.d.ts +79 -0
- package/dist/catalog/org-catalog.schemas.js +82 -0
- package/dist/catalog/org-catalog.service.d.ts +9 -2
- package/dist/catalog/org-catalog.service.js +38 -5
- package/dist/catalog/org-extension.controller.d.ts +1 -12
- package/dist/catalog/org-extension.controller.js +1 -10
- package/dist/catalog/org-extension.schemas.d.ts +15 -0
- package/dist/catalog/org-extension.schemas.js +22 -0
- package/dist/catalog/org-plugin-uploads.controller.d.ts +2 -19
- package/dist/catalog/org-plugin-uploads.controller.js +15 -28
- package/dist/catalog/org-plugin-uploads.schemas.d.ts +20 -0
- package/dist/catalog/org-plugin-uploads.schemas.js +32 -0
- package/dist/catalog/owned-items.d.ts +6 -2
- package/dist/catalog/owned-items.js +16 -4
- package/dist/catalog/platform-components.d.ts +2 -0
- package/dist/catalog/platform-components.js +2 -0
- package/dist/catalog/plugin-import.js +1 -0
- package/dist/catalog/plugin-install.js +1 -1
- package/dist/catalog/requests.service.d.ts +2 -1
- package/dist/catalog/requests.service.js +6 -2
- package/dist/channels/channels.schemas.d.ts +33 -0
- package/dist/channels/channels.schemas.js +34 -0
- package/dist/channels/connections.controller.d.ts +2 -29
- package/dist/channels/connections.controller.js +1 -23
- package/dist/channels/connections.service.d.ts +8 -2
- package/dist/channels/connections.service.js +23 -5
- package/dist/channels/inbound.js +4 -0
- package/dist/config/schema.d.ts +4 -0
- package/dist/config/schema.js +24 -0
- package/dist/conversations/conversations.controller.d.ts +16 -37
- package/dist/conversations/conversations.controller.js +16 -56
- package/dist/conversations/conversations.schemas.d.ts +52 -0
- package/dist/conversations/conversations.schemas.js +79 -0
- package/dist/conversations/conversations.service.d.ts +13 -4
- package/dist/conversations/conversations.service.js +32 -26
- package/dist/conversations/events.d.ts +80 -6
- package/dist/conversations/events.js +60 -5
- package/dist/conversations/message-context.d.ts +28 -0
- package/dist/conversations/message-context.js +56 -0
- package/dist/conversations/queue.d.ts +2 -1
- package/dist/conversations/queue.js +11 -2
- package/dist/ctx/create-ctx.d.ts +15 -1
- package/dist/ctx/create-ctx.js +23 -2
- package/dist/db/kernel-schema.d.ts +44 -0
- package/dist/environments/environments.schemas.d.ts +3 -0
- package/dist/environments/environments.schemas.js +14 -0
- package/dist/environments/environments.service.d.ts +16 -4
- package/dist/environments/environments.service.js +58 -13
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +6 -0
- package/dist/evals/evals.schemas.d.ts +110 -0
- package/dist/evals/evals.schemas.js +107 -0
- package/dist/evals/reconstruct.js +18 -11
- package/dist/evals/recorded-tools.d.ts +2 -1
- package/dist/evals/recorded-tools.js +11 -3
- package/dist/evals/run-replay.d.ts +8 -1
- package/dist/evals/run-replay.js +17 -2
- package/dist/evals/runs.controller.d.ts +2 -57
- package/dist/evals/runs.controller.js +1 -42
- package/dist/evals/runs.service.d.ts +8 -7
- package/dist/evals/runs.service.js +45 -30
- package/dist/evals/sets.controller.d.ts +2 -28
- package/dist/evals/sets.controller.js +1 -31
- package/dist/evals/sets.service.d.ts +7 -7
- package/dist/evals/sets.service.js +23 -17
- package/dist/evals/snapshot.d.ts +3 -2
- package/dist/evals/snapshot.js +17 -4
- package/dist/evals/step-replay.d.ts +2 -1
- package/dist/evals/step-replay.js +3 -2
- package/dist/extensions/admin-ops.d.ts +5 -3
- package/dist/extensions/admin-ops.js +17 -12
- package/dist/extensions/config-hash.d.ts +10 -0
- package/dist/extensions/config-hash.js +38 -0
- package/dist/extensions/deployment-config.d.ts +16 -1
- package/dist/extensions/deployment-config.js +83 -0
- package/dist/extensions/extensions.module.js +9 -12
- package/dist/extensions/host.d.ts +39 -12
- package/dist/extensions/host.js +129 -51
- package/dist/extensions/installs.d.ts +5 -0
- package/dist/extensions/installs.js +12 -0
- package/dist/extensions/org-config.d.ts +17 -2
- package/dist/extensions/org-config.js +23 -4
- package/dist/extensions/point-defaults.controller.d.ts +2 -8
- package/dist/extensions/point-defaults.controller.js +1 -3
- package/dist/extensions/point-defaults.d.ts +3 -1
- package/dist/extensions/point-defaults.js +4 -2
- package/dist/extensions/point-defaults.schemas.d.ts +9 -0
- package/dist/extensions/point-defaults.schemas.js +14 -0
- package/dist/extensions/state.module.d.ts +9 -0
- package/dist/extensions/state.module.js +38 -0
- package/dist/extensions/unavailable.d.ts +49 -0
- package/dist/extensions/unavailable.js +113 -0
- package/dist/files/previewers.controller.js +2 -3
- package/dist/files/previewers.d.ts +1 -1
- package/dist/files/previewers.js +4 -4
- package/dist/files/previewers.schemas.d.ts +10 -0
- package/dist/files/previewers.schemas.js +9 -0
- package/dist/http/api.module.js +4 -0
- package/dist/http/plugin-dispatch.d.ts +4 -1
- package/dist/http/plugin-dispatch.js +14 -2
- package/dist/identity/accounts.d.ts +43 -4
- package/dist/identity/accounts.js +74 -6
- package/dist/identity/auth.guard.js +10 -1
- package/dist/identity/cookies.d.ts +6 -0
- package/dist/identity/cookies.js +14 -0
- package/dist/identity/identity.module.js +3 -0
- package/dist/identity/initial-passwords.controller.d.ts +22 -0
- package/dist/identity/initial-passwords.controller.js +49 -0
- package/dist/identity/initial-passwords.d.ts +61 -0
- package/dist/identity/initial-passwords.job.d.ts +16 -0
- package/dist/identity/initial-passwords.job.js +46 -0
- package/dist/identity/initial-passwords.js +159 -0
- package/dist/identity/me.controller.d.ts +14 -0
- package/dist/identity/me.controller.js +39 -1
- package/dist/identity/principal.d.ts +8 -0
- package/dist/identity/principal.js +8 -0
- package/dist/identity/settings.d.ts +3 -1
- package/dist/identity/settings.js +6 -4
- package/dist/inbox/inbox.schemas.d.ts +8 -0
- package/dist/inbox/inbox.schemas.js +11 -0
- package/dist/inbox/platform-inbox.controller.d.ts +1 -1
- package/dist/inbox/platform-inbox.controller.js +2 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -0
- package/dist/infra/config/kernel-config.service.js +3 -0
- package/dist/infra/events/kernel-events.d.ts +8 -0
- package/dist/lifecycle/kernel-lifecycle.js +4 -0
- package/dist/models/embeddings.d.ts +82 -0
- package/dist/models/embeddings.js +326 -0
- package/dist/models/enablement.controller.d.ts +40 -0
- package/dist/models/enablement.controller.js +74 -0
- package/dist/models/enablement.d.ts +101 -0
- package/dist/models/enablement.js +264 -0
- package/dist/models/models.module.d.ts +5 -1
- package/dist/models/models.module.js +16 -4
- package/dist/models/org-models.schemas.d.ts +8 -0
- package/dist/models/org-models.schemas.js +22 -0
- package/dist/models/prices.d.ts +3 -1
- package/dist/models/prices.js +7 -5
- package/dist/models/purposes.d.ts +30 -6
- package/dist/models/purposes.js +68 -17
- package/dist/orgs/orgs.controller.d.ts +2 -5
- package/dist/orgs/orgs.controller.js +3 -6
- package/dist/orgs/orgs.schemas.d.ts +8 -0
- package/dist/orgs/orgs.schemas.js +16 -0
- package/dist/orgs/orgs.service.d.ts +3 -1
- package/dist/orgs/orgs.service.js +6 -4
- package/dist/orgs/settings.service.d.ts +9 -1
- package/dist/orgs/settings.service.js +20 -5
- package/dist/overrides.d.ts +4 -0
- package/dist/overrides.js +2 -0
- package/dist/platform/errors.d.ts +21 -4
- package/dist/platform/errors.js +45 -6
- package/dist/platform/exclusions.d.ts +2 -3
- package/dist/platform/exclusions.js +68 -831
- package/dist/platform/method.js +1 -1
- package/dist/platform/operation.d.ts +82 -5
- package/dist/platform/operation.js +62 -7
- package/dist/platform/ops/accounts.ops.d.ts +32 -0
- package/dist/platform/ops/accounts.ops.js +291 -0
- package/dist/platform/ops/admin.ops.d.ts +36 -0
- package/dist/platform/ops/admin.ops.js +389 -0
- package/dist/platform/ops/agent-skills.ops.d.ts +24 -0
- package/dist/platform/ops/agent-skills.ops.js +226 -0
- package/dist/platform/ops/agent-templates.ops.d.ts +4 -1
- package/dist/platform/ops/agent-templates.ops.js +194 -14
- package/dist/platform/ops/agents.ops.d.ts +19 -1
- package/dist/platform/ops/agents.ops.js +481 -58
- package/dist/platform/ops/approvals.ops.d.ts +30 -0
- package/dist/platform/ops/approvals.ops.js +116 -0
- package/dist/platform/ops/background.ops.d.ts +14 -0
- package/dist/platform/ops/background.ops.js +134 -0
- package/dist/platform/ops/catalog-admin.ops.d.ts +74 -0
- package/dist/platform/ops/catalog-admin.ops.js +587 -0
- package/dist/platform/ops/channels.ops.d.ts +16 -0
- package/dist/platform/ops/channels.ops.js +195 -0
- package/dist/platform/ops/components.ops.d.ts +46 -0
- package/dist/platform/ops/components.ops.js +853 -0
- package/dist/platform/ops/connectors.ops.d.ts +4 -2
- package/dist/platform/ops/connectors.ops.js +68 -6
- package/dist/platform/ops/conversations.ops.d.ts +30 -0
- package/dist/platform/ops/conversations.ops.js +470 -0
- package/dist/platform/ops/environments.ops.d.ts +26 -0
- package/dist/platform/ops/environments.ops.js +289 -0
- package/dist/platform/ops/errors.d.ts +10 -5
- package/dist/platform/ops/errors.js +19 -11
- package/dist/platform/ops/evals.ops.d.ts +28 -0
- package/dist/platform/ops/evals.ops.js +783 -0
- package/dist/platform/ops/extensions-admin.ops.d.ts +25 -0
- package/dist/platform/ops/extensions-admin.ops.js +344 -0
- package/dist/platform/ops/extensions.ops.d.ts +7 -1
- package/dist/platform/ops/extensions.ops.js +248 -17
- package/dist/platform/ops/inbox.ops.d.ts +25 -0
- package/dist/platform/ops/inbox.ops.js +378 -0
- package/dist/platform/ops/marketplaces.ops.d.ts +7 -1
- package/dist/platform/ops/marketplaces.ops.js +326 -17
- package/dist/platform/ops/models.ops.d.ts +25 -0
- package/dist/platform/ops/models.ops.js +232 -0
- package/dist/platform/ops/org-plugins.ops.d.ts +29 -0
- package/dist/platform/ops/org-plugins.ops.js +329 -0
- package/dist/platform/ops/org-settings.ops.d.ts +16 -0
- package/dist/platform/ops/org-settings.ops.js +102 -0
- package/dist/platform/ops/orgs.ops.d.ts +28 -0
- package/dist/platform/ops/orgs.ops.js +295 -0
- package/dist/platform/ops/other-orgs.d.ts +20 -0
- package/dist/platform/ops/other-orgs.js +72 -0
- package/dist/platform/ops/platform.ops.d.ts +4 -4
- package/dist/platform/ops/platform.ops.js +23 -24
- package/dist/platform/ops/plugins.ops.d.ts +10 -8
- package/dist/platform/ops/plugins.ops.js +176 -77
- package/dist/platform/ops/previewers.ops.d.ts +14 -0
- package/dist/platform/ops/previewers.ops.js +109 -0
- package/dist/platform/ops/requests.ops.js +57 -19
- package/dist/platform/ops/skills.ops.d.ts +5 -1
- package/dist/platform/ops/skills.ops.js +129 -11
- package/dist/platform/ops/unavailable.d.ts +23 -0
- package/dist/platform/ops/unavailable.js +111 -0
- package/dist/platform/parity.d.ts +33 -0
- package/dist/platform/parity.js +272 -0
- package/dist/platform/platform-ops.module.d.ts +32 -0
- package/dist/platform/platform-ops.module.js +78 -11
- package/dist/platform/route-schemas.d.ts +18 -0
- package/dist/platform/route-schemas.js +60 -0
- package/dist/roles/worker.module.js +2 -0
- package/dist/runtime/context/build.d.ts +2 -0
- package/dist/runtime/context/build.js +28 -2
- package/dist/runtime/context/compaction.js +10 -1
- package/dist/runtime/context/run-context.d.ts +65 -0
- package/dist/runtime/context/run-context.js +215 -0
- package/dist/runtime/hook-calls.d.ts +8 -1
- package/dist/runtime/hook-calls.js +40 -9
- package/dist/runtime/model-call.d.ts +8 -3
- package/dist/runtime/model-call.js +30 -6
- package/dist/runtime/providers.d.ts +146 -32
- package/dist/runtime/providers.js +328 -67
- package/dist/runtime/run-context.service.d.ts +65 -0
- package/dist/runtime/run-context.service.js +220 -0
- package/dist/runtime/run-worker.d.ts +6 -1
- package/dist/runtime/run-worker.js +35 -10
- package/dist/runtime/runtime.module.js +2 -0
- package/dist/runtime/subagents/definition.d.ts +15 -15
- package/dist/runtime/subagents/definition.js +49 -118
- package/dist/runtime/usage-report-jobs.d.ts +88 -0
- package/dist/runtime/usage-report-jobs.js +158 -0
- package/dist/runtime/usage-report.d.ts +33 -38
- package/dist/runtime/usage-report.js +152 -84
- package/dist/skills/changes.controller.js +2 -1
- package/dist/skills/changes.service.d.ts +1 -1
- package/dist/skills/changes.service.js +4 -4
- package/dist/skills/invocable.controller.d.ts +1 -1
- package/dist/skills/invocable.controller.js +2 -2
- package/dist/skills/invoke.d.ts +2 -2
- package/dist/skills/invoke.js +8 -1
- package/dist/skills/skills.controller.d.ts +4 -13
- package/dist/skills/skills.controller.js +8 -24
- package/dist/skills/skills.schemas.d.ts +48 -0
- package/dist/skills/skills.schemas.js +61 -0
- package/dist/skills/skills.service.d.ts +11 -1
- package/dist/skills/skills.service.js +37 -14
- package/dist/time-zone.d.ts +5 -0
- package/dist/time-zone.js +19 -0
- package/dist/tools/approvals.controller.js +2 -3
- package/dist/tools/approvals.schemas.d.ts +21 -0
- package/dist/tools/approvals.schemas.js +15 -0
- package/dist/tools/builtin-names.d.ts +10 -8
- package/dist/tools/builtin-names.js +16 -11
- package/dist/tools/builtins/builtin-tools.d.ts +3 -1
- package/dist/tools/builtins/builtin-tools.js +15 -3
- package/dist/tools/builtins/current-time.d.ts +26 -0
- package/dist/tools/builtins/current-time.js +99 -0
- package/dist/tools/builtins/platform.d.ts +19 -2
- package/dist/tools/builtins/platform.js +105 -16
- package/dist/tools/connectors.controller.d.ts +1 -2
- package/dist/tools/connectors.controller.js +1 -4
- package/dist/tools/connectors.schemas.d.ts +12 -0
- package/dist/tools/connectors.schemas.js +19 -0
- package/dist/tools/connectors.service.d.ts +5 -2
- package/dist/tools/connectors.service.js +7 -5
- package/dist/tools/org-tool-switches.d.ts +16 -2
- package/dist/tools/org-tool-switches.js +26 -9
- package/dist/tools/pipeline.js +9 -1
- package/dist/tools/registry.d.ts +48 -51
- package/dist/tools/registry.js +222 -233
- package/package.json +3 -3
- package/src/migrations/0089_model_kinds_usage.sql +38 -0
- package/src/migrations/0090_initial_passwords.sql +27 -0
- package/src/migrations/0091_account_time_zone.sql +4 -0
- package/src/migrations/0092_tools_default_on.sql +27 -0
- package/dist/platform/redact-orgs.d.ts +0 -7
- package/dist/platform/redact-orgs.js +0 -52
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
10
|
+
import { ToolError } from "@capybara-hq/plugin-sdk";
|
|
11
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { CatalogDisabledBody, CatalogGitImportBody, CatalogIdPathParams, CatalogNpmImportBody, CatalogScope, CatalogScopeBody, CatalogScopeOrgs, CatalogShownBody, CatalogStagingPathParams, } from "../../catalog/admin-catalog.schemas.js";
|
|
14
|
+
import { CatalogService } from "../../catalog/catalog.service.js";
|
|
15
|
+
import { CatalogScopeService } from "../../catalog/catalog-scope.service.js";
|
|
16
|
+
import { PluginImport } from "../../catalog/plugin-import.js";
|
|
17
|
+
import { ApiError } from "../../errors.js";
|
|
18
|
+
import { KernelDb } from "../../infra/database/kernel-db.js";
|
|
19
|
+
import { defineOperation } from "../operation.js";
|
|
20
|
+
import { PlatformOperations } from "../registry.js";
|
|
21
|
+
import { precheckBy, viaAgent } from "./errors.js";
|
|
22
|
+
import { assertNotOtherOrgs, OTHER_ORG } from "./other-orgs.js";
|
|
23
|
+
import { localized, orElse } from "./summary.js";
|
|
24
|
+
/** A platform catalog item id (`:id` of the admin routes), named `itemId` like the org's. */
|
|
25
|
+
const ItemId = CatalogIdPathParams.shape.id.max(100);
|
|
26
|
+
const StagingId = CatalogStagingPathParams.shape.stagingId.max(100);
|
|
27
|
+
/** `plugins.set-shown` on a plugin an org owns. */
|
|
28
|
+
export const ORG_OWNED = "An org owns this plugin and manages who sees it; the super admin changes that in the admin console, not here.";
|
|
29
|
+
/** Where the person confirms a staged import (the admin console's import review). */
|
|
30
|
+
export const reviewUrl = (stagingId) => `/admin/plugins/import?staging=${stagingId}`;
|
|
31
|
+
/** What only a person does with a staged import, after reading its review on the web. */
|
|
32
|
+
export const CONFIRM_ON_WEB = "Nothing is imported yet. Give the person the reviewUrl: they read the review (the extension's permissions among it) and confirm the import on the web. Confirming approves extension permissions, which only a person does.";
|
|
33
|
+
/** A staged import's review as the model needs it: what it brings, not the files themselves. */
|
|
34
|
+
export const reviewBrief = (r) => ({
|
|
35
|
+
name: r.name,
|
|
36
|
+
version: r.version,
|
|
37
|
+
displayName: r.displayName ?? null,
|
|
38
|
+
publisher: r.publisher,
|
|
39
|
+
description: r.description,
|
|
40
|
+
format: r.format,
|
|
41
|
+
source: { kind: r.source.kind, ref: r.source.ref },
|
|
42
|
+
extension: r.extension === undefined
|
|
43
|
+
? null
|
|
44
|
+
: {
|
|
45
|
+
name: r.extension.name,
|
|
46
|
+
version: r.extension.version,
|
|
47
|
+
action: r.extension.action,
|
|
48
|
+
deployed: r.extension.deployed,
|
|
49
|
+
currentVersion: r.extension.currentVersion,
|
|
50
|
+
sensitive: r.extension.sensitive,
|
|
51
|
+
addedPermissions: r.extension.added,
|
|
52
|
+
warnings: r.extension.warnings.length,
|
|
53
|
+
},
|
|
54
|
+
skills: r.skills.map((s) => s.name),
|
|
55
|
+
connectorTemplates: r.connectorTemplates.map((t) => t.id),
|
|
56
|
+
agentTemplates: (r.agentTemplates ?? []).map((t) => t.name),
|
|
57
|
+
dependencies: r.dependencies,
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* Skills the change would offer twice, one line per org (the org named: platform data, spec §14.5
|
|
61
|
+
* item 1); the plugins already using a name are counted, never named (they may be another org's
|
|
62
|
+
* own plugins).
|
|
63
|
+
*/
|
|
64
|
+
const conflictText = (cs) => cs
|
|
65
|
+
.map((c) => `skill "${c.name}" is already used in org ${c.orgName} (${c.plugins.length > 0 ? `${c.plugins.length} plugin(s)` : "its own skill"})`)
|
|
66
|
+
.join("; ");
|
|
67
|
+
/** A scope preview as the admin console shows it (orgs named); conflicting plugins counted. */
|
|
68
|
+
const previewBrief = (p) => ({
|
|
69
|
+
affected: p.affected,
|
|
70
|
+
agentsAffected: p.affected.reduce((n, a) => n + a.agents.length, 0),
|
|
71
|
+
needsConfig: p.needsConfig,
|
|
72
|
+
replaced: p.replaced,
|
|
73
|
+
conflicts: p.conflicts.map((c) => ({
|
|
74
|
+
orgId: c.orgId,
|
|
75
|
+
orgName: c.orgName,
|
|
76
|
+
name: c.name,
|
|
77
|
+
skills: c.skills,
|
|
78
|
+
plugins: c.plugins.length,
|
|
79
|
+
})),
|
|
80
|
+
scopeHash: p.scopeHash,
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* The super admin's platform catalog operations of the `Platform` tool (spec §14.2, §14.5 item
|
|
84
|
+
* 1): prepare an import from npm or git and read its review (a person confirms it on the web: the
|
|
85
|
+
* confirm approves extension permissions), preview and change a plugin's scope, disable or enable
|
|
86
|
+
* it on the platform, show or hide it, and delete it. Platform plugins and the org's own come with
|
|
87
|
+
* the admin console's data in full (orgs named); another org's own plugin is refused (the phase-1
|
|
88
|
+
* rule), and the plugins in a name conflict are counted, never named.
|
|
89
|
+
*/
|
|
90
|
+
let CatalogAdminOperations = class CatalogAdminOperations {
|
|
91
|
+
registry;
|
|
92
|
+
catalog;
|
|
93
|
+
scope;
|
|
94
|
+
pluginImport;
|
|
95
|
+
kdb;
|
|
96
|
+
constructor(registry, catalog, scope, pluginImport, kdb) {
|
|
97
|
+
this.registry = registry;
|
|
98
|
+
this.catalog = catalog;
|
|
99
|
+
this.scope = scope;
|
|
100
|
+
this.pluginImport = pluginImport;
|
|
101
|
+
this.kdb = kdb;
|
|
102
|
+
}
|
|
103
|
+
/** The precheck refusal of another org's private plugin (the phase-1 rule), else null. */
|
|
104
|
+
async otherOrgs(itemId, orgId) {
|
|
105
|
+
try {
|
|
106
|
+
await assertNotOtherOrgs(this.kdb.db, itemId, orgId);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return { ok: false, code: "catalog.item_not_found", message: OTHER_ORG };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/** Whether an org owns the item (its owner org manages it, not the super admin's agent). */
|
|
114
|
+
async orgOwned(itemId) {
|
|
115
|
+
if (!/^[0-9a-f-]{36}$/i.test(itemId))
|
|
116
|
+
return false;
|
|
117
|
+
const row = await this.kdb.db
|
|
118
|
+
.selectFrom("catalog_items")
|
|
119
|
+
.select("owner_org_id")
|
|
120
|
+
.where("id", "=", itemId)
|
|
121
|
+
.executeTakeFirst();
|
|
122
|
+
return row?.owner_org_id != null;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A name conflict the service found at write time (the precheck skipped, or a change landed in
|
|
126
|
+
* between) without the plugins it names, which may be another org's own: the same error code,
|
|
127
|
+
* the orgs and skill names from the current preview, the plugins counted, no details.
|
|
128
|
+
*/
|
|
129
|
+
async withoutPluginNames(itemId, target, write) {
|
|
130
|
+
try {
|
|
131
|
+
return await write();
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
if (!(e instanceof ApiError) ||
|
|
135
|
+
(e.code !== "plugin.skill_conflict" && e.code !== "agent_template.name_taken")) {
|
|
136
|
+
throw e;
|
|
137
|
+
}
|
|
138
|
+
const conflicts = await orElse(async () => (target === null ? [] : (await this.scope.preview(itemId, target)).conflicts), []);
|
|
139
|
+
throw new ApiError(e.code, conflicts.length > 0
|
|
140
|
+
? `The change would offer a name twice: ${conflictText(conflicts)}`
|
|
141
|
+
: "The change would offer a skill or agent template name twice in an org that already uses it");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** The precheck refusal of an unknown or deleted item (`catalog.get` includes deleted ones). */
|
|
145
|
+
async live(itemId) {
|
|
146
|
+
let deleted = false;
|
|
147
|
+
const r = await precheckBy(async () => {
|
|
148
|
+
deleted = (await this.catalog.get(itemId)).item.deletedAt !== null;
|
|
149
|
+
});
|
|
150
|
+
if (!r.ok)
|
|
151
|
+
return r;
|
|
152
|
+
return deleted
|
|
153
|
+
? { ok: false, code: "catalog.item_not_found", message: "Catalog item not found" }
|
|
154
|
+
: { ok: true };
|
|
155
|
+
}
|
|
156
|
+
/** The item's names for a card, or the id when it cannot be read. */
|
|
157
|
+
names(itemId) {
|
|
158
|
+
return orElse(async () => {
|
|
159
|
+
const { item } = await this.catalog.get(itemId);
|
|
160
|
+
return localized(item.displayName, item.name);
|
|
161
|
+
}, { zh: itemId, en: itemId });
|
|
162
|
+
}
|
|
163
|
+
onModuleInit() {
|
|
164
|
+
this.registry.register([
|
|
165
|
+
defineOperation({
|
|
166
|
+
id: "plugins.import-npm",
|
|
167
|
+
description: "Prepare importing a plugin from the platform's npm registry into the catalog (super admin): fetches and checks the package (version: a version, dist-tag or range; default latest) and stages it for 24 hours. Returns what it brings and a reviewUrl; nothing is imported until the person confirms it there.",
|
|
168
|
+
input: CatalogNpmImportBody.strict(),
|
|
169
|
+
example: { package: "@acme/capybara-plugin-crm" },
|
|
170
|
+
authz: { superAdmin: true },
|
|
171
|
+
mirrors: ["POST /api/v1/admin/catalog/import/npm"],
|
|
172
|
+
confirm: "platform",
|
|
173
|
+
errors: [
|
|
174
|
+
{
|
|
175
|
+
code: "catalog.version_exists",
|
|
176
|
+
next: "This version is in the catalog already: update the plugin to it with plugins.update-preview.",
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
code: "catalog.name_conflict",
|
|
180
|
+
next: "A catalog plugin of this name comes from another npm package; check the package name.",
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
code: "catalog.invalid_manifest",
|
|
184
|
+
next: "The package is not a valid plugin (the details list each problem); tell the person.",
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
code: "packages.npm_failed",
|
|
188
|
+
next: "The registry could not be reached or has no such version; check the name and version, or try again later.",
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
summary: (i) => ({
|
|
192
|
+
zh: `从 npm 准备导入插件 ${i.package}${i.version !== undefined ? `@${i.version}` : ""}(确认在网页上进行)`,
|
|
193
|
+
en: `Prepare importing plugin ${i.package}${i.version !== undefined ? `@${i.version}` : ""} from npm (confirmed on the web)`,
|
|
194
|
+
}),
|
|
195
|
+
run: async (input, ctx) => {
|
|
196
|
+
const r = await this.pluginImport.prepareNpm(ctx.actorAccountId, {
|
|
197
|
+
package: input.package,
|
|
198
|
+
...(input.version !== undefined && { version: input.version }),
|
|
199
|
+
}, { auditDetail: viaAgent("plugins.import-npm", ctx) });
|
|
200
|
+
return {
|
|
201
|
+
stagingId: r.stagingId,
|
|
202
|
+
review: reviewBrief(r.review),
|
|
203
|
+
reviewUrl: reviewUrl(r.stagingId),
|
|
204
|
+
next: CONFIRM_ON_WEB,
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
}),
|
|
208
|
+
defineOperation({
|
|
209
|
+
id: "plugins.import-git",
|
|
210
|
+
description: "Prepare importing a plugin straight from git into the catalog (super admin; a one-off, no marketplace): url is an https git URL or owner/repo, ref a branch, tag or commit (default the remote HEAD), path the plugin's directory (default the root). Stages it for 24 hours and returns what it brings and a reviewUrl; nothing is imported until the person confirms it there.",
|
|
211
|
+
input: CatalogGitImportBody,
|
|
212
|
+
example: { url: "acme/capybara-plugin-crm", ref: "v1.2.0" },
|
|
213
|
+
authz: { superAdmin: true },
|
|
214
|
+
mirrors: ["POST /api/v1/admin/catalog/import/git"],
|
|
215
|
+
confirm: "platform",
|
|
216
|
+
errors: [
|
|
217
|
+
{
|
|
218
|
+
code: "marketplace.git_failed",
|
|
219
|
+
next: "The repository could not be read: check the URL and ref, or try again later.",
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
code: "marketplace.private_address",
|
|
223
|
+
next: "The URL points at a private address, which the platform refuses; use a public https URL.",
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
code: "catalog.version_exists",
|
|
227
|
+
next: "This version is in the catalog already: update the plugin to it with plugins.update-preview.",
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
code: "catalog.invalid_manifest",
|
|
231
|
+
next: "The directory is not a valid plugin (the details list each problem); check path, or tell the person.",
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
summary: (i) => ({
|
|
235
|
+
zh: `从 git 准备导入插件 ${i.url}${i.ref !== undefined ? `#${i.ref}` : ""}${i.path !== undefined ? ` ${i.path}` : ""}(确认在网页上进行)`,
|
|
236
|
+
en: `Prepare importing plugin ${i.url}${i.ref !== undefined ? `#${i.ref}` : ""}${i.path !== undefined ? ` ${i.path}` : ""} from git (confirmed on the web)`,
|
|
237
|
+
}),
|
|
238
|
+
run: async (input, ctx) => {
|
|
239
|
+
const r = await this.catalog.importFromGit(ctx.actorAccountId, {
|
|
240
|
+
url: input.url,
|
|
241
|
+
...(input.ref !== undefined && { ref: input.ref }),
|
|
242
|
+
...(input.path !== undefined && { path: input.path }),
|
|
243
|
+
}, { auditDetail: viaAgent("plugins.import-git", ctx) });
|
|
244
|
+
return {
|
|
245
|
+
stagingId: r.stagingId,
|
|
246
|
+
review: reviewBrief(r.review),
|
|
247
|
+
reviewUrl: reviewUrl(r.stagingId),
|
|
248
|
+
next: CONFIRM_ON_WEB,
|
|
249
|
+
};
|
|
250
|
+
},
|
|
251
|
+
}),
|
|
252
|
+
defineOperation({
|
|
253
|
+
id: "plugins.import-review",
|
|
254
|
+
description: "Read a staged platform import (super admin): what the plugin brings (extension and its added permissions, skills, connector and agent templates, dependencies) and the reviewUrl where the person confirms it.",
|
|
255
|
+
input: z.object({ stagingId: StagingId }).strict(),
|
|
256
|
+
example: { stagingId: "3f1c2a9e-5b7d-4e21-9c0a-1d2e3f4a5b6c" },
|
|
257
|
+
authz: { superAdmin: true },
|
|
258
|
+
mirrors: ["GET /api/v1/admin/catalog/imports/:stagingId"],
|
|
259
|
+
confirm: "read",
|
|
260
|
+
errors: [
|
|
261
|
+
{
|
|
262
|
+
code: "plugin.staging_not_found",
|
|
263
|
+
next: "The staged import expired (24 hours) or was confirmed already: prepare it again with plugins.import-npm or plugins.import-git.",
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
run: async (input) => {
|
|
267
|
+
const r = await this.pluginImport.staged(input.stagingId);
|
|
268
|
+
return {
|
|
269
|
+
stagingId: r.stagingId,
|
|
270
|
+
review: reviewBrief(r.review),
|
|
271
|
+
...(r.permissionsMismatch !== undefined && {
|
|
272
|
+
permissionsMismatch: r.permissionsMismatch,
|
|
273
|
+
}),
|
|
274
|
+
reviewUrl: reviewUrl(r.stagingId),
|
|
275
|
+
next: CONFIRM_ON_WEB,
|
|
276
|
+
};
|
|
277
|
+
},
|
|
278
|
+
}),
|
|
279
|
+
defineOperation({
|
|
280
|
+
id: "plugins.scope-preview",
|
|
281
|
+
description: "Preview changing where a platform plugin is on (super admin): a scope (all: every org; optional: orgs switch it on; named: only the orgs listed, with orgs) or disabled: true (off everywhere). Returns the orgs that lose it (with the agents there), the components it takes back, name conflicts, and the scopeHash plugins.set-scope or plugins.set-disabled needs. Nothing is written; show the preview to the person first.",
|
|
282
|
+
input: z
|
|
283
|
+
.object({
|
|
284
|
+
itemId: ItemId,
|
|
285
|
+
scope: CatalogScope.optional(),
|
|
286
|
+
orgs: CatalogScopeOrgs.optional(),
|
|
287
|
+
disabled: z.literal(true).optional(),
|
|
288
|
+
})
|
|
289
|
+
.strict()
|
|
290
|
+
.refine((b) => (b.disabled === true) !== (b.scope !== undefined), {
|
|
291
|
+
message: "send either scope (with orgs for named) or disabled: true",
|
|
292
|
+
})
|
|
293
|
+
.refine((b) => b.disabled === undefined || b.orgs === undefined, {
|
|
294
|
+
message: "orgs: only allowed with scope named",
|
|
295
|
+
path: ["orgs"],
|
|
296
|
+
}),
|
|
297
|
+
example: { itemId: "3f1c2a9e-5b7d-4e21-9c0a-1d2e3f4a5b6c", scope: "optional" },
|
|
298
|
+
authz: { superAdmin: true },
|
|
299
|
+
mirrors: ["POST /api/v1/admin/catalog/items/:id/scope/preview"],
|
|
300
|
+
renames: { itemId: "id" },
|
|
301
|
+
confirm: "read",
|
|
302
|
+
errors: [
|
|
303
|
+
{
|
|
304
|
+
code: "catalog.item_not_found",
|
|
305
|
+
next: "Check the plugin id with plugins.platform-list.",
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
code: "plugin.builtin",
|
|
309
|
+
next: "A built-in plugin is on in every org; its scope cannot change and it cannot be disabled.",
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
code: "validation_failed",
|
|
313
|
+
next: "Pass existing org ids in orgs (only with scope named); the orgs operations list them.",
|
|
314
|
+
},
|
|
315
|
+
],
|
|
316
|
+
run: async (input, ctx) => {
|
|
317
|
+
await assertNotOtherOrgs(this.kdb.db, input.itemId, ctx.orgId);
|
|
318
|
+
const p = await this.scope.preview(input.itemId, input.scope === undefined
|
|
319
|
+
? { disabled: true }
|
|
320
|
+
: { scope: input.scope, ...(input.orgs !== undefined && { orgs: input.orgs }) });
|
|
321
|
+
return previewBrief(p);
|
|
322
|
+
},
|
|
323
|
+
}),
|
|
324
|
+
defineOperation({
|
|
325
|
+
id: "plugins.set-scope",
|
|
326
|
+
description: "Change where a platform plugin is on (super admin), for every org at once: pass the scope (and orgs for named) and the scopeHash plugins.scope-preview returned for that same target. Orgs that lose it have it removed by the scope sync; a preview that is out of date is refused.",
|
|
327
|
+
input: z.object({ itemId: ItemId, ...CatalogScopeBody.shape }).strict(),
|
|
328
|
+
example: {
|
|
329
|
+
itemId: "3f1c2a9e-5b7d-4e21-9c0a-1d2e3f4a5b6c",
|
|
330
|
+
scope: "optional",
|
|
331
|
+
scopeHash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
332
|
+
},
|
|
333
|
+
authz: { superAdmin: true },
|
|
334
|
+
mirrors: ["PUT /api/v1/admin/catalog/items/:id/scope"],
|
|
335
|
+
renames: { itemId: "id" },
|
|
336
|
+
confirm: "platform",
|
|
337
|
+
errors: [
|
|
338
|
+
{
|
|
339
|
+
code: "catalog.item_not_found",
|
|
340
|
+
next: "Check the plugin id with plugins.platform-list.",
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
code: "plugin.builtin",
|
|
344
|
+
next: "A built-in plugin is on in every org; its scope cannot change and it cannot be disabled.",
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
code: "plugin.scope_stale",
|
|
348
|
+
next: "Call plugins.scope-preview again with the same target, show the new preview, and call again with its scopeHash.",
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
code: "catalog.item_pending",
|
|
352
|
+
next: "The plugin's first version waits for the super admin's confirmation in the admin console (Plugins → 待确认); confirm or reject it there first.",
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
code: "plugin.skill_conflict",
|
|
356
|
+
next: "Those orgs already have a skill of that name: narrow the target (scope named without them) or have the name resolved in those orgs, then preview again.",
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
precheck: async (i, ctx) => {
|
|
360
|
+
const other = await this.otherOrgs(i.itemId, ctx.orgId);
|
|
361
|
+
if (other !== null)
|
|
362
|
+
return other;
|
|
363
|
+
let hash = "";
|
|
364
|
+
let conflicts = [];
|
|
365
|
+
const r = await precheckBy(async () => {
|
|
366
|
+
const p = await this.scope.preview(i.itemId, {
|
|
367
|
+
scope: i.scope,
|
|
368
|
+
...(i.orgs !== undefined && { orgs: i.orgs }),
|
|
369
|
+
});
|
|
370
|
+
hash = p.scopeHash;
|
|
371
|
+
conflicts = p.conflicts;
|
|
372
|
+
});
|
|
373
|
+
if (!r.ok)
|
|
374
|
+
return r;
|
|
375
|
+
if (conflicts.length > 0) {
|
|
376
|
+
return {
|
|
377
|
+
ok: false,
|
|
378
|
+
code: "plugin.skill_conflict",
|
|
379
|
+
message: `The change would offer a skill twice: ${conflictText(conflicts)}`,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
return hash === i.scopeHash
|
|
383
|
+
? { ok: true }
|
|
384
|
+
: {
|
|
385
|
+
ok: false,
|
|
386
|
+
code: "plugin.scope_stale",
|
|
387
|
+
message: "What this change affects has changed since the preview",
|
|
388
|
+
};
|
|
389
|
+
},
|
|
390
|
+
summary: async (i) => {
|
|
391
|
+
const [n, p] = await Promise.all([
|
|
392
|
+
this.names(i.itemId),
|
|
393
|
+
this.scope.preview(i.itemId, {
|
|
394
|
+
scope: i.scope,
|
|
395
|
+
...(i.orgs !== undefined && { orgs: i.orgs }),
|
|
396
|
+
}),
|
|
397
|
+
]);
|
|
398
|
+
const named = i.scope === "named" ? `(${i.orgs?.length ?? 0} 个组织)` : "";
|
|
399
|
+
const namedEn = i.scope === "named" ? ` (${i.orgs?.length ?? 0} orgs)` : "";
|
|
400
|
+
return {
|
|
401
|
+
zh: `把平台插件「${n.zh}」的范围改为 ${i.scope}${named}:${p.affected.length} 个组织将失去它`,
|
|
402
|
+
en: `Change the scope of platform plugin "${n.en}" to ${i.scope}${namedEn}: ${p.affected.length} orgs lose it`,
|
|
403
|
+
};
|
|
404
|
+
},
|
|
405
|
+
run: async (input, ctx) => {
|
|
406
|
+
await assertNotOtherOrgs(this.kdb.db, input.itemId, ctx.orgId);
|
|
407
|
+
const target = {
|
|
408
|
+
scope: input.scope,
|
|
409
|
+
...(input.orgs !== undefined && { orgs: input.orgs }),
|
|
410
|
+
};
|
|
411
|
+
return {
|
|
412
|
+
item: await this.withoutPluginNames(input.itemId, target, () => this.scope.setScope(ctx.actorAccountId, input.itemId, { ...target, scopeHash: input.scopeHash }, { auditDetail: viaAgent("plugins.set-scope", ctx) })),
|
|
413
|
+
};
|
|
414
|
+
},
|
|
415
|
+
}),
|
|
416
|
+
defineOperation({
|
|
417
|
+
id: "plugins.set-disabled",
|
|
418
|
+
description: "Disable a platform plugin everywhere, or enable it again (super admin). Disabling needs the scopeHash of plugins.scope-preview with disabled: true (the scope sync then removes it from every org; its scope and the org switches are kept); enabling needs none.",
|
|
419
|
+
input: z
|
|
420
|
+
.object({ itemId: ItemId, ...CatalogDisabledBody.shape })
|
|
421
|
+
.strict()
|
|
422
|
+
.refine((b) => !b.disabled || b.scopeHash !== undefined, {
|
|
423
|
+
message: "scopeHash: required when disabling (plugins.scope-preview with disabled: true)",
|
|
424
|
+
path: ["scopeHash"],
|
|
425
|
+
}),
|
|
426
|
+
example: { itemId: "3f1c2a9e-5b7d-4e21-9c0a-1d2e3f4a5b6c", disabled: false },
|
|
427
|
+
authz: { superAdmin: true },
|
|
428
|
+
mirrors: ["PUT /api/v1/admin/catalog/items/:id/disabled"],
|
|
429
|
+
renames: { itemId: "id" },
|
|
430
|
+
confirm: "platform",
|
|
431
|
+
errors: [
|
|
432
|
+
{
|
|
433
|
+
code: "catalog.item_not_found",
|
|
434
|
+
next: "Check the plugin id with plugins.platform-list.",
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
code: "plugin.builtin",
|
|
438
|
+
next: "A built-in plugin is on in every org; its scope cannot change and it cannot be disabled.",
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
code: "plugin.scope_stale",
|
|
442
|
+
next: "Call plugins.scope-preview again with the same target, show the new preview, and call again with its scopeHash.",
|
|
443
|
+
},
|
|
444
|
+
],
|
|
445
|
+
precheck: async (i, ctx) => {
|
|
446
|
+
const other = await this.otherOrgs(i.itemId, ctx.orgId);
|
|
447
|
+
if (other !== null)
|
|
448
|
+
return other;
|
|
449
|
+
if (!i.disabled)
|
|
450
|
+
return this.live(i.itemId);
|
|
451
|
+
let hash = "";
|
|
452
|
+
const r = await precheckBy(async () => {
|
|
453
|
+
hash = (await this.scope.preview(i.itemId, { disabled: true })).scopeHash;
|
|
454
|
+
});
|
|
455
|
+
if (!r.ok)
|
|
456
|
+
return r;
|
|
457
|
+
return hash === i.scopeHash
|
|
458
|
+
? { ok: true }
|
|
459
|
+
: {
|
|
460
|
+
ok: false,
|
|
461
|
+
code: "plugin.scope_stale",
|
|
462
|
+
message: "What disabling affects has changed since the preview",
|
|
463
|
+
};
|
|
464
|
+
},
|
|
465
|
+
summary: async (i) => {
|
|
466
|
+
const n = await this.names(i.itemId);
|
|
467
|
+
if (!i.disabled) {
|
|
468
|
+
return {
|
|
469
|
+
zh: `在平台上重新启用插件「${n.zh}」`,
|
|
470
|
+
en: `Enable platform plugin "${n.en}" again`,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
const p = await this.scope.preview(i.itemId, { disabled: true });
|
|
474
|
+
return {
|
|
475
|
+
zh: `在平台上停用插件「${n.zh}」:从 ${p.affected.length} 个组织移除`,
|
|
476
|
+
en: `Disable platform plugin "${n.en}": removed from ${p.affected.length} orgs`,
|
|
477
|
+
};
|
|
478
|
+
},
|
|
479
|
+
run: async (input, ctx) => {
|
|
480
|
+
await assertNotOtherOrgs(this.kdb.db, input.itemId, ctx.orgId);
|
|
481
|
+
return {
|
|
482
|
+
item: await this.withoutPluginNames(input.itemId, null, () => this.scope.setDisabled(ctx.actorAccountId, input.itemId, {
|
|
483
|
+
disabled: input.disabled,
|
|
484
|
+
...(input.scopeHash !== undefined && { scopeHash: input.scopeHash }),
|
|
485
|
+
}, { auditDetail: viaAgent("plugins.set-disabled", ctx) })),
|
|
486
|
+
};
|
|
487
|
+
},
|
|
488
|
+
}),
|
|
489
|
+
defineOperation({
|
|
490
|
+
id: "plugins.set-shown",
|
|
491
|
+
description: "Show or hide a named platform plugin to the orgs outside its list (super admin): shown, they see it and can request it; hidden, they do not (pending requests stay). Never makes it usable anywhere. A plugin an org owns (shared or not) is managed by that org and refused here (the admin console still can).",
|
|
492
|
+
input: z.object({ itemId: ItemId, ...CatalogShownBody.shape }).strict(),
|
|
493
|
+
example: { itemId: "3f1c2a9e-5b7d-4e21-9c0a-1d2e3f4a5b6c", shownToOthers: true },
|
|
494
|
+
authz: { superAdmin: true },
|
|
495
|
+
mirrors: ["PUT /api/v1/admin/catalog/items/:id/shown"],
|
|
496
|
+
renames: { itemId: "id" },
|
|
497
|
+
confirm: "platform",
|
|
498
|
+
errors: [
|
|
499
|
+
{
|
|
500
|
+
code: "catalog.item_not_found",
|
|
501
|
+
next: "Check the plugin id with plugins.platform-list.",
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
code: "catalog.item_pending",
|
|
505
|
+
next: "The plugin's first version waits for the super admin's confirmation in the admin console (Plugins → 待确认); confirm or reject it there first.",
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
code: "catalog.org_owned",
|
|
509
|
+
next: "An org owns this plugin and manages who sees it; leave it to that org, or use the admin console.",
|
|
510
|
+
},
|
|
511
|
+
],
|
|
512
|
+
precheck: async (i, ctx) => {
|
|
513
|
+
const other = await this.otherOrgs(i.itemId, ctx.orgId);
|
|
514
|
+
if (other !== null)
|
|
515
|
+
return other;
|
|
516
|
+
if (await this.orgOwned(i.itemId)) {
|
|
517
|
+
return { ok: false, code: "catalog.org_owned", message: ORG_OWNED };
|
|
518
|
+
}
|
|
519
|
+
return this.live(i.itemId);
|
|
520
|
+
},
|
|
521
|
+
summary: async (i) => {
|
|
522
|
+
const n = await this.names(i.itemId);
|
|
523
|
+
return i.shownToOthers
|
|
524
|
+
? {
|
|
525
|
+
zh: `向名单外的组织展示平台插件「${n.zh}」(可申请)`,
|
|
526
|
+
en: `Show platform plugin "${n.en}" to orgs outside its list (requestable)`,
|
|
527
|
+
}
|
|
528
|
+
: {
|
|
529
|
+
zh: `对名单外的组织隐藏平台插件「${n.zh}」`,
|
|
530
|
+
en: `Hide platform plugin "${n.en}" from orgs outside its list`,
|
|
531
|
+
};
|
|
532
|
+
},
|
|
533
|
+
run: async (input, ctx) => {
|
|
534
|
+
await assertNotOtherOrgs(this.kdb.db, input.itemId, ctx.orgId);
|
|
535
|
+
if (await this.orgOwned(input.itemId))
|
|
536
|
+
throw new ToolError(ORG_OWNED);
|
|
537
|
+
return {
|
|
538
|
+
item: await this.scope.setShown(ctx.actorAccountId, input.itemId, input.shownToOthers, {
|
|
539
|
+
auditDetail: viaAgent("plugins.set-shown", ctx),
|
|
540
|
+
}),
|
|
541
|
+
};
|
|
542
|
+
},
|
|
543
|
+
}),
|
|
544
|
+
defineOperation({
|
|
545
|
+
id: "plugins.delete",
|
|
546
|
+
description: "Delete a platform catalog plugin (super admin): it leaves the catalog and its pending requests are cancelled; what orgs installed from it stays installed. To take it away from orgs, use plugins.set-disabled or plugins.set-scope instead.",
|
|
547
|
+
input: z.object({ itemId: ItemId }).strict(),
|
|
548
|
+
example: { itemId: "3f1c2a9e-5b7d-4e21-9c0a-1d2e3f4a5b6c" },
|
|
549
|
+
authz: { superAdmin: true },
|
|
550
|
+
mirrors: ["DELETE /api/v1/admin/catalog/items/:id"],
|
|
551
|
+
renames: { itemId: "id" },
|
|
552
|
+
confirm: "platform",
|
|
553
|
+
errors: [
|
|
554
|
+
{
|
|
555
|
+
code: "catalog.item_not_found",
|
|
556
|
+
next: "Check the plugin id with plugins.platform-list.",
|
|
557
|
+
},
|
|
558
|
+
],
|
|
559
|
+
precheck: async (i, ctx) => (await this.otherOrgs(i.itemId, ctx.orgId)) ?? this.live(i.itemId),
|
|
560
|
+
summary: async (i) => {
|
|
561
|
+
const { item } = await this.catalog.get(i.itemId);
|
|
562
|
+
const n = localized(item.displayName, item.name);
|
|
563
|
+
return {
|
|
564
|
+
zh: `从平台目录删除插件「${n.zh}」(${item.enabledOrgs} 个组织中已安装的内容保留)`,
|
|
565
|
+
en: `Delete plugin "${n.en}" from the platform catalog (what ${item.enabledOrgs} orgs installed stays)`,
|
|
566
|
+
};
|
|
567
|
+
},
|
|
568
|
+
run: async (input, ctx) => {
|
|
569
|
+
await assertNotOtherOrgs(this.kdb.db, input.itemId, ctx.orgId);
|
|
570
|
+
await this.catalog.remove(ctx.actorAccountId, input.itemId, {
|
|
571
|
+
auditDetail: viaAgent("plugins.delete", ctx),
|
|
572
|
+
});
|
|
573
|
+
return { deleted: input.itemId };
|
|
574
|
+
},
|
|
575
|
+
}),
|
|
576
|
+
]);
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
CatalogAdminOperations = __decorate([
|
|
580
|
+
Injectable(),
|
|
581
|
+
__param(0, Inject(PlatformOperations)),
|
|
582
|
+
__param(1, Inject(CatalogService)),
|
|
583
|
+
__param(2, Inject(CatalogScopeService)),
|
|
584
|
+
__param(3, Inject(PluginImport)),
|
|
585
|
+
__param(4, Inject(KernelDb))
|
|
586
|
+
], CatalogAdminOperations);
|
|
587
|
+
export { CatalogAdminOperations };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type OnModuleInit } from "@nestjs/common";
|
|
2
|
+
import { ChannelConnections } from "../../channels/connections.service.js";
|
|
3
|
+
import { PlatformOperations } from "../registry.js";
|
|
4
|
+
/**
|
|
5
|
+
* Channel connection operations of the `Platform` tool (spec §14): read a connection and change
|
|
6
|
+
* its binding (which agent answers, what happens to unbound people, on / off, inbound mode),
|
|
7
|
+
* or remove it. Creating a connection and changing its credentials or config stay on the web:
|
|
8
|
+
* they carry app secrets a person types (spec §6.4).
|
|
9
|
+
*/
|
|
10
|
+
export declare class ChannelsOperations implements OnModuleInit {
|
|
11
|
+
private readonly registry;
|
|
12
|
+
private readonly channels;
|
|
13
|
+
constructor(registry: PlatformOperations, channels: ChannelConnections);
|
|
14
|
+
private nameOf;
|
|
15
|
+
onModuleInit(): void;
|
|
16
|
+
}
|