@capybara-hq/kernel 0.1.0-rc.20 → 0.1.0-rc.22
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 +10 -1
- package/dist/agents/admin-agents.d.ts +16 -3
- package/dist/agents/admin-agents.js +65 -7
- package/dist/agents/agents.schemas.d.ts +24 -6
- package/dist/agents/agents.service.d.ts +4 -3
- package/dist/agents/agents.service.js +39 -26
- package/dist/agents/definition.d.ts +44 -6
- package/dist/agents/definition.js +86 -18
- package/dist/agents/from-template.d.ts +6 -3
- package/dist/agents/from-template.js +57 -44
- package/dist/agents/org-templates.js +97 -41
- package/dist/agents/templates.d.ts +6 -0
- package/dist/agents/templates.js +15 -1
- package/dist/catalog/admin-catalog.controller.d.ts +2 -4
- package/dist/catalog/admin-catalog.controller.js +2 -6
- package/dist/catalog/catalog.module.js +3 -0
- package/dist/catalog/claude/report.d.ts +9 -2
- package/dist/catalog/claude/report.js +1 -0
- package/dist/catalog/claude/translate.js +1 -1
- package/dist/catalog/component-promotion.js +1 -2
- package/dist/catalog/component-state.d.ts +13 -1
- package/dist/catalog/component-state.js +14 -5
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/marketplaces.service.js +2 -1
- package/dist/catalog/org-catalog.controller.d.ts +13 -3
- package/dist/catalog/org-catalog.controller.js +26 -4
- package/dist/catalog/org-catalog.schemas.d.ts +13 -0
- package/dist/catalog/org-catalog.schemas.js +34 -0
- package/dist/catalog/org-plugin-uploads.controller.js +0 -1
- package/dist/catalog/org-plugin-uploads.d.ts +0 -1
- package/dist/catalog/org-plugin-uploads.js +0 -3
- package/dist/catalog/org-plugin-uploads.schemas.d.ts +0 -1
- package/dist/catalog/org-plugin-uploads.schemas.js +0 -2
- package/dist/catalog/platform-components.d.ts +0 -1
- package/dist/catalog/platform-components.js +3 -8
- package/dist/catalog/plugin-import.d.ts +0 -8
- package/dist/catalog/plugin-import.js +4 -35
- package/dist/catalog/plugin-install.d.ts +2 -2
- package/dist/catalog/plugin-install.js +2 -2
- package/dist/catalog/plugin-package.d.ts +7 -0
- package/dist/catalog/plugin-package.js +27 -1
- package/dist/catalog/plugin-upgrade.d.ts +5 -6
- package/dist/catalog/plugin-upgrade.js +5 -23
- package/dist/catalog/requests.service.d.ts +66 -10
- package/dist/catalog/requests.service.js +196 -15
- package/dist/channels/actions.d.ts +2 -0
- package/dist/channels/actions.js +19 -4
- package/dist/channels/cards.d.ts +16 -2
- package/dist/channels/cards.js +40 -7
- package/dist/channels/channels.module.js +3 -0
- package/dist/channels/outbound.d.ts +22 -1
- package/dist/channels/outbound.js +116 -7
- package/dist/channels/phrases.d.ts +25 -0
- package/dist/channels/phrases.js +19 -0
- package/dist/channels/threads.d.ts +12 -0
- package/dist/channels/threads.js +34 -0
- package/dist/config/schema.d.ts +23 -1
- package/dist/config/schema.js +105 -5
- package/dist/conversations/conversations.service.d.ts +42 -9
- package/dist/conversations/conversations.service.js +57 -25
- package/dist/conversations/events.d.ts +106 -11
- package/dist/conversations/events.js +121 -18
- package/dist/conversations/message-context.d.ts +6 -3
- package/dist/conversations/message-context.js +14 -10
- package/dist/conversations/queue.d.ts +15 -2
- package/dist/conversations/queue.js +22 -3
- package/dist/conversations/queue.service.d.ts +12 -6
- package/dist/conversations/queue.service.js +36 -13
- package/dist/db/kernel-schema.d.ts +105 -3
- package/dist/devices/conversation-devices.d.ts +8 -1
- package/dist/devices/conversation-devices.js +8 -0
- package/dist/devices/devices.controller.d.ts +21 -4
- package/dist/devices/devices.controller.js +46 -8
- package/dist/devices/devices.schemas.d.ts +9 -1
- package/dist/devices/devices.schemas.js +11 -3
- package/dist/devices/devices.service.d.ts +176 -4
- package/dist/devices/devices.service.js +341 -6
- package/dist/devices/dto.d.ts +56 -3
- package/dist/devices/dto.js +51 -1
- package/dist/devices/public-suffix.d.ts +6 -0
- package/dist/devices/public-suffix.js +79 -0
- package/dist/errors.d.ts +46 -5
- package/dist/errors.js +46 -5
- package/dist/evals/reconstruct.d.ts +18 -13
- package/dist/evals/reconstruct.js +50 -36
- package/dist/evals/recorded-tools.d.ts +7 -7
- package/dist/evals/recorded-tools.js +4 -3
- package/dist/evals/trajectory.d.ts +6 -1
- package/dist/evals/trajectory.js +7 -0
- package/dist/extensions/bootstrap.d.ts +49 -10
- package/dist/extensions/bootstrap.js +104 -27
- package/dist/extensions/package.js +2 -2
- package/dist/http/api.module.js +5 -0
- package/dist/inbox/inbox.module.js +2 -1
- package/dist/inbox/inbox.service.d.ts +19 -4
- package/dist/inbox/inbox.service.js +14 -3
- package/dist/infra/config/kernel-config.service.js +11 -0
- package/dist/infra/events/kernel-events.d.ts +2 -1
- package/dist/lifecycle/kernel-lifecycle.d.ts +5 -1
- package/dist/lifecycle/kernel-lifecycle.js +16 -4
- package/dist/local-devices/device-policy.service.d.ts +65 -0
- package/dist/local-devices/device-policy.service.js +217 -0
- package/dist/local-devices/local-device-gateway.js +4 -1
- package/dist/local-devices/local-device-provider.d.ts +40 -3
- package/dist/local-devices/local-device-provider.js +109 -7
- package/dist/local-devices/local-devices.module.d.ts +2 -1
- package/dist/local-devices/local-devices.module.js +19 -3
- package/dist/local-devices/machines.d.ts +14 -3
- package/dist/local-devices/machines.js +41 -3
- package/dist/local-devices/network-grants.d.ts +104 -0
- package/dist/local-devices/network-grants.js +288 -0
- package/dist/local-devices/policy-summary.d.ts +20 -0
- package/dist/local-devices/policy-summary.js +63 -0
- package/dist/orgs/orgs.module.js +4 -10
- package/dist/orgs/roles.d.ts +1 -1
- package/dist/orgs/roles.js +4 -0
- package/dist/orgs/settings.controller.js +2 -1
- package/dist/orgs/settings.service.d.ts +164 -12
- package/dist/orgs/settings.service.js +212 -24
- package/dist/platform/exclusions.js +11 -1
- package/dist/platform/operation.js +4 -0
- package/dist/platform/ops/admin-items.ops.js +1 -1
- package/dist/platform/ops/agent-skills.ops.js +2 -2
- package/dist/platform/ops/agent-templates.ops.js +2 -2
- package/dist/platform/ops/agents.ops.js +11 -15
- package/dist/platform/ops/devices.ops.js +3 -1
- package/dist/platform/ops/inbox.ops.js +19 -0
- package/dist/platform/ops/org-settings.ops.js +14 -5
- package/dist/platform/ops/platform.ops.d.ts +9 -1
- package/dist/platform/ops/platform.ops.js +34 -12
- package/dist/platform/ops/requests.ops.js +3 -2
- package/dist/platform/ops/schedules.ops.d.ts +21 -0
- package/dist/platform/ops/schedules.ops.js +470 -0
- package/dist/platform/ops/skills.ops.js +3 -3
- package/dist/platform/platform-ops.module.d.ts +2 -1
- package/dist/platform/platform-ops.module.js +5 -0
- package/dist/platform/route-schemas.js +3 -0
- package/dist/roles/worker.module.js +3 -0
- package/dist/runtime/context/build.js +13 -4
- package/dist/runtime/context/compaction.js +6 -3
- package/dist/runtime/context/device-paths.d.ts +43 -21
- package/dist/runtime/context/device-paths.js +104 -21
- package/dist/runtime/context/run-context.d.ts +9 -0
- package/dist/runtime/context/run-context.js +8 -0
- package/dist/runtime/context/skills.d.ts +14 -1
- package/dist/runtime/context/skills.js +36 -5
- package/dist/runtime/maintenance.d.ts +4 -2
- package/dist/runtime/maintenance.js +16 -5
- package/dist/runtime/run-finish.d.ts +6 -1
- package/dist/runtime/run-finish.js +16 -2
- package/dist/runtime/run-queue.js +21 -2
- package/dist/runtime/run-worker.js +14 -33
- package/dist/runtime/runtime.module.js +3 -0
- package/dist/runtime/subagents/definition.d.ts +32 -14
- package/dist/runtime/subagents/definition.js +106 -109
- package/dist/runtime/subagents/dispatch.js +4 -3
- package/dist/runtime/subagents/preamble.d.ts +2 -1
- package/dist/runtime/subagents/preamble.js +2 -1
- package/dist/runtime/waits.js +14 -4
- package/dist/sandbox/sandbox.service.d.ts +120 -10
- package/dist/sandbox/sandbox.service.js +335 -28
- package/dist/sandbox/tiers.d.ts +86 -0
- package/dist/sandbox/tiers.js +96 -0
- package/dist/schedules/effective-settings.d.ts +16 -0
- package/dist/schedules/effective-settings.js +17 -0
- package/dist/schedules/errors.d.ts +8 -0
- package/dist/schedules/errors.js +8 -0
- package/dist/schedules/fire.d.ts +118 -0
- package/dist/schedules/fire.js +625 -0
- package/dist/schedules/grant-rules.d.ts +94 -0
- package/dist/schedules/grant-rules.js +126 -0
- package/dist/schedules/job-ids.d.ts +32 -0
- package/dist/schedules/job-ids.js +27 -0
- package/dist/schedules/pause.d.ts +9 -0
- package/dist/schedules/pause.js +33 -0
- package/dist/schedules/run-tracker.d.ts +81 -0
- package/dist/schedules/run-tracker.js +333 -0
- package/dist/schedules/scan.job.d.ts +64 -0
- package/dist/schedules/scan.job.js +303 -0
- package/dist/schedules/schedule-math.d.ts +31 -0
- package/dist/schedules/schedule-math.js +223 -0
- package/dist/schedules/scheduled-tasks.service.d.ts +351 -0
- package/dist/schedules/scheduled-tasks.service.js +1193 -0
- package/dist/schedules/schedules.controller.d.ts +68 -0
- package/dist/schedules/schedules.controller.js +242 -0
- package/dist/schedules/schedules.module.d.ts +16 -0
- package/dist/schedules/schedules.module.js +65 -0
- package/dist/schedules/schedules.schemas.d.ts +316 -0
- package/dist/schedules/schedules.schemas.js +186 -0
- package/dist/schedules/store.d.ts +81 -0
- package/dist/schedules/store.js +390 -0
- package/dist/schedules/store.module.d.ts +6 -0
- package/dist/schedules/store.module.js +21 -0
- package/dist/schedules/types.d.ts +108 -0
- package/dist/schedules/types.js +1 -0
- package/dist/schedules/unattended.d.ts +117 -0
- package/dist/schedules/unattended.js +228 -0
- package/dist/setup/oauth-token-probe.js +8 -4
- package/dist/skills/agent-skills.service.d.ts +4 -8
- package/dist/skills/agent-skills.service.js +18 -53
- package/dist/skills/catalog.d.ts +65 -62
- package/dist/skills/catalog.js +109 -206
- package/dist/skills/conversation-catalog.d.ts +3 -3
- package/dist/skills/conversation-catalog.js +5 -12
- package/dist/skills/invoke.d.ts +2 -2
- package/dist/skills/skills.controller.d.ts +3 -1
- package/dist/skills/skills.service.d.ts +38 -37
- package/dist/skills/skills.service.js +168 -107
- package/dist/skills/usable.d.ts +57 -8
- package/dist/skills/usable.js +172 -38
- package/dist/tools/approvals.controller.d.ts +4 -2
- package/dist/tools/approvals.controller.js +17 -2
- package/dist/tools/approvals.schemas.d.ts +1 -0
- package/dist/tools/approvals.schemas.js +3 -1
- package/dist/tools/approvals.service.d.ts +182 -7
- package/dist/tools/approvals.service.js +597 -13
- package/dist/tools/builtin-names.d.ts +25 -4
- package/dist/tools/builtin-names.js +45 -4
- package/dist/tools/builtins/builtin-tools.d.ts +8 -0
- package/dist/tools/builtins/builtin-tools.js +23 -2
- package/dist/tools/builtins/sandbox/bash.js +16 -7
- package/dist/tools/builtins/sandbox/common.d.ts +1 -1
- package/dist/tools/builtins/sandbox/common.js +33 -10
- package/dist/tools/builtins/sandbox/edit.js +7 -3
- package/dist/tools/builtins/sandbox/file-state.d.ts +31 -1
- package/dist/tools/builtins/sandbox/file-state.js +33 -3
- package/dist/tools/builtins/sandbox/write.js +8 -4
- package/dist/tools/builtins/schedules.d.ts +107 -0
- package/dist/tools/builtins/schedules.js +789 -0
- package/dist/tools/elicitation.d.ts +2 -0
- package/dist/tools/elicitation.js +1 -1
- package/dist/tools/fixed-ask.d.ts +7 -0
- package/dist/tools/fixed-ask.js +9 -0
- package/dist/tools/network-asks.d.ts +109 -0
- package/dist/tools/network-asks.js +221 -0
- package/dist/tools/pipeline.d.ts +53 -6
- package/dist/tools/pipeline.js +202 -13
- package/dist/tools/policy.d.ts +21 -8
- package/dist/tools/policy.js +63 -9
- package/dist/tools/registry.d.ts +10 -1
- package/dist/tools/tools.module.js +12 -0
- package/package.json +2 -2
- package/src/migrations/0113_scheduled_tasks.sql +108 -0
- package/src/migrations/0114_network_asks.sql +23 -0
- package/src/migrations/0115_network_requests.sql +28 -0
- package/src/migrations/0116_skills_default_on.sql +37 -0
- package/src/migrations/0117_sandbox_tiers.sql +11 -0
|
@@ -31,6 +31,7 @@ import { expandGitUrl, GitSourceError, gitErrorDetails, gitLocationIdentity, git
|
|
|
31
31
|
import { CatalogSourceLock } from "./locks.js";
|
|
32
32
|
import { fetchMarketplaceManifest, MarketplaceFetchError, MarketplaceInvalidError, marketplaceNetPolicy, marketplaceUrlProblem, } from "./marketplace-fetch.js";
|
|
33
33
|
import { checkMarketplaceIcon, fetchMarketplaceIcon, gitIconPaths, MARKETPLACE_ICON_CONCURRENCY, MARKETPLACE_ICON_FETCHES_MAX, MARKETPLACE_ICON_MAX_BYTES, MARKETPLACE_ICON_RETRY_MS, marketplaceIconUrl, wantedIcons, } from "./marketplace-icons.js";
|
|
34
|
+
import { withoutRemovedManifestFields } from "./plugin-package.js";
|
|
34
35
|
import { compareVersions, newestFirst, sameRelease } from "./versions.js";
|
|
35
36
|
/** 官方清单来源的 id。 */
|
|
36
37
|
export const OFFICIAL_MARKETPLACE_ID = "official";
|
|
@@ -925,7 +926,7 @@ let MarketplacesService = class MarketplacesService {
|
|
|
925
926
|
const pj = files.get(PLUGIN_MANIFEST_FILE);
|
|
926
927
|
let entry;
|
|
927
928
|
if (pj !== undefined) {
|
|
928
|
-
const m = parsePluginManifest(dec(pj));
|
|
929
|
+
const m = parsePluginManifest(withoutRemovedManifestFields(dec(pj)));
|
|
929
930
|
if ("errors" in m) {
|
|
930
931
|
throw new MarketplaceInvalidError(`the repository is a single plugin, but its ${PLUGIN_MANIFEST_FILE} is invalid: ${m.errors.slice(0, 5).join("; ")}`, m.errors);
|
|
931
932
|
}
|
|
@@ -7,7 +7,7 @@ import { type OrgContext } from "../orgs/org.guard.js";
|
|
|
7
7
|
import type { ConnectorDetail, ToolIssue } from "../tools/connectors.service.js";
|
|
8
8
|
import type { MarketplaceImportResult } from "./catalog.service.js";
|
|
9
9
|
import type { CatalogIcon, OrgCatalogDetail, OrgCatalogItem, OrgInstallResult } from "./catalog-content.js";
|
|
10
|
-
import { CatalogGuideQuery, CatalogMarketplaceRequestBody, CatalogRequestBody, CatalogRequestsListQuery, OrgPluginInstallBody, OrgPluginSwitchBody } from "./org-catalog.schemas.js";
|
|
10
|
+
import { CatalogGuideQuery, CatalogMarketplaceRequestBody, CatalogRequestBody, CatalogRequestsListQuery, NetworkRequestBody, OrgPluginInstallBody, OrgPluginSwitchBody } from "./org-catalog.schemas.js";
|
|
11
11
|
import { OrgCatalogService } from "./org-catalog.service.js";
|
|
12
12
|
import { PluginInstaller, type PluginInstallView, type UninstallPreview, type UninstallReport } from "./plugin-install.js";
|
|
13
13
|
import { CatalogRequestsService, type CatalogRequestView } from "./requests.service.js";
|
|
@@ -57,6 +57,8 @@ declare const DecideBody: z.ZodObject<{
|
|
|
57
57
|
* - `POST catalog/:itemId/requests` (`catalog.request`; `access` needs an org admin): requests
|
|
58
58
|
* under plugin scope (spec §5.1), `enable` into the org admins' inbox, `access` to the super
|
|
59
59
|
* admin; `POST marketplace-requests` (org admins): an `import` request for a marketplace entry;
|
|
60
|
+
* - `POST catalog-requests/network` (`catalog.request`, web sessions only): a member asks the org
|
|
61
|
+
* admins to allow hosts in the org's sandbox network (network ask-to-allow spec §5.3);
|
|
60
62
|
* - `PUT catalog/:itemId/switch` (scope phase 1): `{ enabled: true, inputs? }` installs -> 200 `{ item }`;
|
|
61
63
|
* `{ enabled: false, confirm? }` -> 200 `{ preview, confirm }`, then with the hash 200 `{ item }`;
|
|
62
64
|
* - `POST catalog/:itemId/install` (an alias of switching on, no longer creates requests): the route only requires `catalog.read`; the service re-checks
|
|
@@ -69,8 +71,8 @@ declare const DecideBody: z.ZodObject<{
|
|
|
69
71
|
* admin (`PUT /admin/catalog/items/:id/update`, ruling F2);
|
|
70
72
|
* - `POST connector-templates/:templateId/connectors` (`connectors.manage`): one more connector
|
|
71
73
|
* from a platform connector template on in the org (ruling P4-T6-8);
|
|
72
|
-
* - `POST catalog-requests/:id/decide` (`catalog.decide`, org admins; `enable
|
|
73
|
-
* `connector_setup` requests, `{ approve, reason? }`; a `connector_setup` request is only
|
|
74
|
+
* - `POST catalog-requests/:id/decide` (`catalog.decide`, org admins; `enable`,
|
|
75
|
+
* `network_allowlist` and `connector_setup` requests, `{ approve, reason? }`; a `connector_setup` request is only
|
|
74
76
|
* rejected here, ruling P4-T6-6), `POST catalog-requests/:id/dismiss` (the requester, a decided
|
|
75
77
|
* request).
|
|
76
78
|
*/
|
|
@@ -156,6 +158,14 @@ export declare class OrgCatalogController {
|
|
|
156
158
|
installs: PluginInstallView[];
|
|
157
159
|
}>;
|
|
158
160
|
uninstall(principal: Principal, org: OrgContext, installId: string): Promise<UninstallReport>;
|
|
161
|
+
/**
|
|
162
|
+
* A member asks the org admins to allow hosts in the org's sandbox egress (from a blocked
|
|
163
|
+
* command's card) -> 201 `{ request }` (an identical pending request of the member is returned).
|
|
164
|
+
* Web sessions only: a personal token, a service token or an agent never files one.
|
|
165
|
+
*/
|
|
166
|
+
networkRequest(principal: Principal, org: OrgContext, body: z.infer<typeof NetworkRequestBody>): Promise<{
|
|
167
|
+
request: CatalogRequestView;
|
|
168
|
+
}>;
|
|
159
169
|
decide(principal: Principal, org: OrgContext, id: string, body: z.infer<typeof DecideBody>): Promise<{
|
|
160
170
|
request: CatalogRequestView;
|
|
161
171
|
}>;
|
|
@@ -11,12 +11,12 @@ import { Controller, Delete, Get, HttpCode, Inject, Param, Post, Put, Res } from
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { PluginGuides } from "../extensions/plugin-guides.js";
|
|
13
13
|
import { orgIconScope, PluginIcons } from "../extensions/plugin-icons.js";
|
|
14
|
-
import { CurrentPrincipal, patTokenId, requireUser, SuperAdmin, } from "../identity/principal.js";
|
|
14
|
+
import { CurrentPrincipal, patTokenId, requireUser, SessionOnly, SuperAdmin, } from "../identity/principal.js";
|
|
15
15
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
16
16
|
import { ZBody, ZQuery } from "../infra/validation/zod-params.js";
|
|
17
17
|
import { CurrentOrg, OrgAction } from "../orgs/org.guard.js";
|
|
18
18
|
import { roleAtLeast } from "../orgs/roles.js";
|
|
19
|
-
import { CatalogConnectorInput, CatalogGuideQuery, CatalogMarketplaceRequestBody, CatalogRequestBody, CatalogRequestsListQuery, OrgPluginInstallBody, OrgPluginSwitchBody, } from "./org-catalog.schemas.js";
|
|
19
|
+
import { CatalogConnectorInput, CatalogGuideQuery, CatalogMarketplaceRequestBody, CatalogRequestBody, CatalogRequestsListQuery, NetworkRequestBody, OrgPluginInstallBody, OrgPluginSwitchBody, } from "./org-catalog.schemas.js";
|
|
20
20
|
import { OrgCatalogService } from "./org-catalog.service.js";
|
|
21
21
|
import { PluginInstaller, } from "./plugin-install.js";
|
|
22
22
|
import { CatalogRequestsService } from "./requests.service.js";
|
|
@@ -67,6 +67,8 @@ class OrgTemplateConnectorBody extends createZodDto(TemplateConnectorBody, "OrgT
|
|
|
67
67
|
}
|
|
68
68
|
class CatalogRequestBodyDto extends createZodDto(CatalogRequestBody, "CatalogRequestBody") {
|
|
69
69
|
}
|
|
70
|
+
class NetworkRequestBodyDto extends createZodDto(NetworkRequestBody, "NetworkRequestBody") {
|
|
71
|
+
}
|
|
70
72
|
class CatalogMarketplaceRequestBodyDto extends createZodDto(CatalogMarketplaceRequestBody, "CatalogMarketplaceRequestBody") {
|
|
71
73
|
}
|
|
72
74
|
/**
|
|
@@ -75,6 +77,8 @@ class CatalogMarketplaceRequestBodyDto extends createZodDto(CatalogMarketplaceRe
|
|
|
75
77
|
* - `POST catalog/:itemId/requests` (`catalog.request`; `access` needs an org admin): requests
|
|
76
78
|
* under plugin scope (spec §5.1), `enable` into the org admins' inbox, `access` to the super
|
|
77
79
|
* admin; `POST marketplace-requests` (org admins): an `import` request for a marketplace entry;
|
|
80
|
+
* - `POST catalog-requests/network` (`catalog.request`, web sessions only): a member asks the org
|
|
81
|
+
* admins to allow hosts in the org's sandbox network (network ask-to-allow spec §5.3);
|
|
78
82
|
* - `PUT catalog/:itemId/switch` (scope phase 1): `{ enabled: true, inputs? }` installs -> 200 `{ item }`;
|
|
79
83
|
* `{ enabled: false, confirm? }` -> 200 `{ preview, confirm }`, then with the hash 200 `{ item }`;
|
|
80
84
|
* - `POST catalog/:itemId/install` (an alias of switching on, no longer creates requests): the route only requires `catalog.read`; the service re-checks
|
|
@@ -87,8 +91,8 @@ class CatalogMarketplaceRequestBodyDto extends createZodDto(CatalogMarketplaceRe
|
|
|
87
91
|
* admin (`PUT /admin/catalog/items/:id/update`, ruling F2);
|
|
88
92
|
* - `POST connector-templates/:templateId/connectors` (`connectors.manage`): one more connector
|
|
89
93
|
* from a platform connector template on in the org (ruling P4-T6-8);
|
|
90
|
-
* - `POST catalog-requests/:id/decide` (`catalog.decide`, org admins; `enable
|
|
91
|
-
* `connector_setup` requests, `{ approve, reason? }`; a `connector_setup` request is only
|
|
94
|
+
* - `POST catalog-requests/:id/decide` (`catalog.decide`, org admins; `enable`,
|
|
95
|
+
* `network_allowlist` and `connector_setup` requests, `{ approve, reason? }`; a `connector_setup` request is only
|
|
92
96
|
* rejected here, ruling P4-T6-6), `POST catalog-requests/:id/dismiss` (the requester, a decided
|
|
93
97
|
* request).
|
|
94
98
|
*/
|
|
@@ -216,6 +220,15 @@ let OrgCatalogController = class OrgCatalogController {
|
|
|
216
220
|
const tokenId = patTokenId(p);
|
|
217
221
|
return this.catalog.uninstall(org.orgId, p.account.id, installId, tokenId);
|
|
218
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* A member asks the org admins to allow hosts in the org's sandbox egress (from a blocked
|
|
225
|
+
* command's card) -> 201 `{ request }` (an identical pending request of the member is returned).
|
|
226
|
+
* Web sessions only: a personal token, a service token or an agent never files one.
|
|
227
|
+
*/
|
|
228
|
+
async networkRequest(principal, org, body) {
|
|
229
|
+
const p = requireUser(principal);
|
|
230
|
+
return { request: await this.requests.requestNetwork(org.orgId, p.account.id, body) };
|
|
231
|
+
}
|
|
219
232
|
async decide(principal, org, id, body) {
|
|
220
233
|
const p = requireUser(principal);
|
|
221
234
|
const tokenId = patTokenId(p);
|
|
@@ -319,6 +332,15 @@ __decorate([
|
|
|
319
332
|
__param(1, CurrentOrg()),
|
|
320
333
|
__param(2, Param("installId"))
|
|
321
334
|
], OrgCatalogController.prototype, "uninstall", null);
|
|
335
|
+
__decorate([
|
|
336
|
+
Post("catalog-requests/network"),
|
|
337
|
+
HttpCode(201),
|
|
338
|
+
SessionOnly(),
|
|
339
|
+
OrgAction("catalog.request"),
|
|
340
|
+
__param(0, CurrentPrincipal()),
|
|
341
|
+
__param(1, CurrentOrg()),
|
|
342
|
+
__param(2, ZBody(NetworkRequestBodyDto))
|
|
343
|
+
], OrgCatalogController.prototype, "networkRequest", null);
|
|
322
344
|
__decorate([
|
|
323
345
|
Post("catalog-requests/:id/decide"),
|
|
324
346
|
HttpCode(200),
|
|
@@ -7,6 +7,19 @@ export declare const CatalogRequestBody: z.ZodObject<{
|
|
|
7
7
|
}>;
|
|
8
8
|
note: z.ZodOptional<z.ZodString>;
|
|
9
9
|
}, z.core.$strict>;
|
|
10
|
+
/** The most hosts one network request asks for. */
|
|
11
|
+
export declare const NETWORK_REQUEST_HOSTS_MAX = 20;
|
|
12
|
+
/**
|
|
13
|
+
* A member asks the org admins to allow hosts in the org's sandbox egress (network ask-to-allow
|
|
14
|
+
* spec §5.3): exact hosts (no wildcard), lowercased, each passing `validateAllowHost`; the
|
|
15
|
+
* conversation and agent the blocked command ran in, for the admins' context.
|
|
16
|
+
*/
|
|
17
|
+
export declare const NetworkRequestBody: z.ZodObject<{
|
|
18
|
+
hosts: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
19
|
+
note: z.ZodOptional<z.ZodString>;
|
|
20
|
+
conversationId: z.ZodOptional<z.ZodString>;
|
|
21
|
+
agentId: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strict>;
|
|
10
23
|
/** An org admin's request for a marketplace entry not in the catalog yet. */
|
|
11
24
|
export declare const CatalogMarketplaceRequestBody: z.ZodObject<{
|
|
12
25
|
marketplaceId: z.ZodString;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validateAllowHost } from "@capybara-hq/plugin-sdk";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { CredentialValue } from "../tools/connectors.schemas.js";
|
|
3
4
|
export const CatalogRequestBody = z
|
|
@@ -6,6 +7,39 @@ export const CatalogRequestBody = z
|
|
|
6
7
|
note: z.string().max(1000).optional(),
|
|
7
8
|
})
|
|
8
9
|
.strict();
|
|
10
|
+
/** The most hosts one network request asks for. */
|
|
11
|
+
export const NETWORK_REQUEST_HOSTS_MAX = 20;
|
|
12
|
+
/**
|
|
13
|
+
* A member asks the org admins to allow hosts in the org's sandbox egress (network ask-to-allow
|
|
14
|
+
* spec §5.3): exact hosts (no wildcard), lowercased, each passing `validateAllowHost`; the
|
|
15
|
+
* conversation and agent the blocked command ran in, for the admins' context.
|
|
16
|
+
*/
|
|
17
|
+
export const NetworkRequestBody = z
|
|
18
|
+
.object({
|
|
19
|
+
hosts: z
|
|
20
|
+
.array(z
|
|
21
|
+
.string()
|
|
22
|
+
.max(253)
|
|
23
|
+
.transform((h) => h.trim().toLowerCase())
|
|
24
|
+
.superRefine((h, ctx) => {
|
|
25
|
+
if (h.startsWith("*.")) {
|
|
26
|
+
ctx.addIssue({
|
|
27
|
+
code: "custom",
|
|
28
|
+
message: `${h}: ask for an exact host, not a wildcard`,
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
for (const message of validateAllowHost(h)) {
|
|
33
|
+
ctx.addIssue({ code: "custom", message: `${h}: ${message}` });
|
|
34
|
+
}
|
|
35
|
+
}))
|
|
36
|
+
.min(1)
|
|
37
|
+
.max(NETWORK_REQUEST_HOSTS_MAX),
|
|
38
|
+
note: z.string().max(500).optional(),
|
|
39
|
+
conversationId: z.string().min(1).max(100).optional(),
|
|
40
|
+
agentId: z.string().min(1).max(100).optional(),
|
|
41
|
+
})
|
|
42
|
+
.strict();
|
|
9
43
|
/** An org admin's request for a marketplace entry not in the catalog yet. */
|
|
10
44
|
export const CatalogMarketplaceRequestBody = z
|
|
11
45
|
.object({
|
|
@@ -78,7 +78,6 @@ let OrgPluginUploadsController = class OrgPluginUploadsController {
|
|
|
78
78
|
return this.uploads.confirm(actor.account.id, org.orgId, params.stagingId, {
|
|
79
79
|
reviewHash: body.reviewHash,
|
|
80
80
|
...(body.shareable !== undefined && { shareable: body.shareable }),
|
|
81
|
-
...(body.pinnedSuggestions !== undefined && { pinnedSuggestions: body.pinnedSuggestions }),
|
|
82
81
|
}, actorOpts(actor));
|
|
83
82
|
}
|
|
84
83
|
};
|
|
@@ -64,7 +64,6 @@ export declare class OrgPluginUploads {
|
|
|
64
64
|
confirm(actor: string, orgId: string, stagingId: string, input: {
|
|
65
65
|
reviewHash: string;
|
|
66
66
|
shareable?: boolean;
|
|
67
|
-
pinnedSuggestions?: string[];
|
|
68
67
|
}, opts?: ActorOpts): Promise<OrgUploadResult>;
|
|
69
68
|
/** The review with the update preview of a new version and the combined hash (P3-12). */
|
|
70
69
|
private withUpdate;
|
|
@@ -70,9 +70,6 @@ let OrgPluginUploads = class OrgPluginUploads {
|
|
|
70
70
|
await this.scope.enqueueSync(r.item.id);
|
|
71
71
|
return { item: r.item, outcome: r.firstVersion ? "installed" : "updated" };
|
|
72
72
|
}
|
|
73
|
-
if (input.pinnedSuggestions !== undefined) {
|
|
74
|
-
throw new ApiError("validation_failed", "pinnedSuggestions: a new version keeps the plugin's own pinned suggestions", [{ path: "pinnedSuggestions", message: "not allowed for a new version" }]);
|
|
75
|
-
}
|
|
76
73
|
// The one hash covers the review and the update (P3-12): both recomputed now
|
|
77
74
|
const preview = await this.updater.previewForOwner(orgId, st.itemId, st.version, st.target);
|
|
78
75
|
if (input.reviewHash !== ownerUpdateHash(st.reviewHash, preview.diffHash)) {
|
|
@@ -9,7 +9,6 @@ export declare const OrgOwnedPluginParams: z.ZodObject<{
|
|
|
9
9
|
export declare const OrgUploadConfirmBody: z.ZodObject<{
|
|
10
10
|
reviewHash: z.ZodString;
|
|
11
11
|
shareable: z.ZodOptional<z.ZodBoolean>;
|
|
12
|
-
pinnedSuggestions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
13
12
|
}, z.core.$strict>;
|
|
14
13
|
export declare const OrgOwnedShareableBody: z.ZodObject<{
|
|
15
14
|
shareable: z.ZodBoolean;
|
|
@@ -6,8 +6,6 @@ export const OrgUploadConfirmBody = z
|
|
|
6
6
|
reviewHash: z.string().min(1).max(128),
|
|
7
7
|
/** The org shares the new item with other orgs (default false, P3-16). */
|
|
8
8
|
shareable: z.boolean().optional(),
|
|
9
|
-
/** Skill names suggested as pinned (spec §9.1); omitted keeps the plugin's flags. */
|
|
10
|
-
pinnedSuggestions: z.array(z.string().min(1).max(64)).max(50).optional(),
|
|
11
9
|
})
|
|
12
10
|
.strict();
|
|
13
11
|
export const OrgOwnedShareableBody = z.object({ shareable: z.boolean() }).strict();
|
|
@@ -242,7 +242,7 @@ let PlatformComponents = class PlatformComponents {
|
|
|
242
242
|
throw versionStale();
|
|
243
243
|
const cur = await t
|
|
244
244
|
.selectFrom("platform_skill_versions")
|
|
245
|
-
.select(["source_format"
|
|
245
|
+
.select(["source_format"])
|
|
246
246
|
.where("skill_id", "=", v.platformId)
|
|
247
247
|
.where("version", "=", row.current_version)
|
|
248
248
|
.executeTakeFirstOrThrow();
|
|
@@ -260,7 +260,6 @@ let PlatformComponents = class PlatformComponents {
|
|
|
260
260
|
object_prefix: v.prefix,
|
|
261
261
|
catalog_version: null,
|
|
262
262
|
source_format: cur.source_format,
|
|
263
|
-
suggest_pinned: cur.suggest_pinned,
|
|
264
263
|
created_by: actorAccountId,
|
|
265
264
|
})
|
|
266
265
|
.execute();
|
|
@@ -318,7 +317,7 @@ let PlatformComponents = class PlatformComponents {
|
|
|
318
317
|
throw ownedByOrg("skill", live.name);
|
|
319
318
|
const cur = await t
|
|
320
319
|
.selectFrom("platform_skill_versions")
|
|
321
|
-
.select(["source_format"
|
|
320
|
+
.select(["source_format"])
|
|
322
321
|
.where("skill_id", "=", live.id)
|
|
323
322
|
.where("version", "=", live.current_version)
|
|
324
323
|
.executeTakeFirstOrThrow();
|
|
@@ -337,7 +336,6 @@ let PlatformComponents = class PlatformComponents {
|
|
|
337
336
|
object_prefix: prefix,
|
|
338
337
|
catalog_version: null,
|
|
339
338
|
source_format: cur.source_format,
|
|
340
|
-
suggest_pinned: cur.suggest_pinned,
|
|
341
339
|
updated_on_own: true,
|
|
342
340
|
created_by: actor.accountId,
|
|
343
341
|
})
|
|
@@ -374,7 +372,7 @@ let PlatformComponents = class PlatformComponents {
|
|
|
374
372
|
throw ownedByOrg("agent template", live.name);
|
|
375
373
|
const cur = await t
|
|
376
374
|
.selectFrom("platform_agent_template_versions")
|
|
377
|
-
.select(["source_format"
|
|
375
|
+
.select(["source_format"])
|
|
378
376
|
.where("template_id", "=", live.id)
|
|
379
377
|
.where("version", "=", live.current_version)
|
|
380
378
|
.executeTakeFirstOrThrow();
|
|
@@ -392,7 +390,6 @@ let PlatformComponents = class PlatformComponents {
|
|
|
392
390
|
object_prefix: prefix,
|
|
393
391
|
catalog_version: null,
|
|
394
392
|
source_format: cur.source_format,
|
|
395
|
-
suggest_pinned: cur.suggest_pinned,
|
|
396
393
|
updated_on_own: true,
|
|
397
394
|
created_by: actor.accountId,
|
|
398
395
|
})
|
|
@@ -482,7 +479,6 @@ let PlatformComponents = class PlatformComponents {
|
|
|
482
479
|
prefix: syncVersionPrefix(platformSkillPrefix(id, to), version),
|
|
483
480
|
files,
|
|
484
481
|
manifest: skillManifest(pkg),
|
|
485
|
-
suggestPinned: s.pinned === true,
|
|
486
482
|
});
|
|
487
483
|
}
|
|
488
484
|
const agents = await readCatalogAgentTemplates(this.files, v);
|
|
@@ -661,7 +657,6 @@ let PlatformComponents = class PlatformComponents {
|
|
|
661
657
|
object_prefix: s.prefix,
|
|
662
658
|
catalog_version: plan.version,
|
|
663
659
|
source_format: plan.sourceFormat,
|
|
664
|
-
suggest_pinned: s.suggestPinned,
|
|
665
660
|
})
|
|
666
661
|
.execute();
|
|
667
662
|
out.skills.push({
|
|
@@ -237,8 +237,6 @@ export interface PluginReview {
|
|
|
237
237
|
body: string;
|
|
238
238
|
path: string;
|
|
239
239
|
files: number;
|
|
240
|
-
/** The plugin suggests pinning the skill (plugin.json `pinned`; changed at confirm). */
|
|
241
|
-
suggestPinned: boolean;
|
|
242
240
|
}[];
|
|
243
241
|
connectorTemplates: PluginReviewTemplate[];
|
|
244
242
|
/**
|
|
@@ -553,12 +551,6 @@ export declare class PluginImport {
|
|
|
553
551
|
scope?: PluginScope;
|
|
554
552
|
/** The orgs of a `named` scope. */
|
|
555
553
|
orgs?: string[];
|
|
556
|
-
/**
|
|
557
|
-
* The skills (by name, each in the review) suggested as pinned when an agent selects them
|
|
558
|
-
* (spec §9.1); replaces the plugin's `pinned` flags in the stored manifest. Omitted keeps
|
|
559
|
-
* them. An admin decision like the scope, so not part of `reviewHash`.
|
|
560
|
-
*/
|
|
561
|
-
pinnedSuggestions?: string[];
|
|
562
554
|
/** An org upload's new item: shared with other orgs by its owner (default false, P3-16). */
|
|
563
555
|
shareable?: boolean;
|
|
564
556
|
}, opts?: ActorOpts & {
|
|
@@ -54,7 +54,7 @@ import { CatalogItemLock } from "./locks.js";
|
|
|
54
54
|
import { assertNameFree, assertPackageFree, assertShareable, packageOwner, releaseExtensionClaim, shareGate, usableBy, } from "./ownership.js";
|
|
55
55
|
import { PlatformComponents } from "./platform-components.js";
|
|
56
56
|
import { PLATFORM_MIGRATION_JOB } from "./platform-migration.js";
|
|
57
|
-
import { PluginPackageError,
|
|
57
|
+
import { PluginPackageError, readPluginFiles, readPluginPackage, themeApiError, } from "./plugin-package.js";
|
|
58
58
|
import { hasImportRequests, importRequestOf, resolveImportRequests } from "./request-rules.js";
|
|
59
59
|
import { assertNameNotReserved } from "./reserved-names.js";
|
|
60
60
|
import { addScopeOrg } from "./scope-orgs.js";
|
|
@@ -725,7 +725,7 @@ let PluginImport = class PluginImport {
|
|
|
725
725
|
const src = row.source;
|
|
726
726
|
if (input.reviewHash !== review.reviewHash)
|
|
727
727
|
throw reviewStale(review);
|
|
728
|
-
const manifest =
|
|
728
|
+
const manifest = staged.manifest;
|
|
729
729
|
const reviewed = review.extension;
|
|
730
730
|
// Read the stored package outside the transaction (unless it was already installed as is, or
|
|
731
731
|
// an org upload, which approves nothing)
|
|
@@ -938,7 +938,6 @@ let PluginImport = class PluginImport {
|
|
|
938
938
|
stagingId,
|
|
939
939
|
scope: actual.scope,
|
|
940
940
|
...(actual.scope === "named" && { orgs: actual.orgs }),
|
|
941
|
-
suggestedPinned: pinnedNames(manifest, review),
|
|
942
941
|
...(now && { extension: { name: now.name, version: now.version, action: now.action } }),
|
|
943
942
|
},
|
|
944
943
|
});
|
|
@@ -1416,7 +1415,6 @@ let PluginImport = class PluginImport {
|
|
|
1416
1415
|
const m = pkg.manifest;
|
|
1417
1416
|
const notLoaded = [];
|
|
1418
1417
|
const templatePaths = new Map();
|
|
1419
|
-
const pinned = new Map((m.skills ?? []).map((s) => [packagePath(s.path), s.pinned === true]));
|
|
1420
1418
|
const problems = [];
|
|
1421
1419
|
const stored = new Map();
|
|
1422
1420
|
const keep = (path) => {
|
|
@@ -1449,7 +1447,6 @@ let PluginImport = class PluginImport {
|
|
|
1449
1447
|
body: "errors" in md ? "" : md.body,
|
|
1450
1448
|
path: `./${s.dir}`,
|
|
1451
1449
|
files: files.length,
|
|
1452
|
-
suggestPinned: pinned.get(s.dir) === true,
|
|
1453
1450
|
});
|
|
1454
1451
|
for (const f of s.files)
|
|
1455
1452
|
keepObject(`${s.dir}/${f}`);
|
|
@@ -1714,17 +1711,13 @@ PluginImport = __decorate([
|
|
|
1714
1711
|
export { PluginImport };
|
|
1715
1712
|
/**
|
|
1716
1713
|
* plugin.json as stored on the version: skills and connector templates listed explicitly (what was
|
|
1717
|
-
* scanned when the manifest omitted them)
|
|
1714
|
+
* scanned when the manifest omitted them).
|
|
1718
1715
|
*/
|
|
1719
1716
|
function normalizedManifest(pkg) {
|
|
1720
|
-
const pinned = new Map((pkg.manifest.skills ?? []).map((s) => [packagePath(s.path), s.pinned]));
|
|
1721
1717
|
const { agents: _, themes: __, ...manifest } = pkg.manifest;
|
|
1722
1718
|
return {
|
|
1723
1719
|
...manifest,
|
|
1724
|
-
skills: pkg.skills.map((s) => {
|
|
1725
|
-
const p = pinned.get(s.dir);
|
|
1726
|
-
return { path: `./${s.dir}`, ...(p !== undefined && { pinned: p }) };
|
|
1727
|
-
}),
|
|
1720
|
+
skills: pkg.skills.map((s) => ({ path: `./${s.dir}` })),
|
|
1728
1721
|
connectorTemplates: pkg.connectorTemplates.map((t) => ({ path: `./${t.path}` })),
|
|
1729
1722
|
// listed only when there are any, so the stored manifests of other plugins stay as they were
|
|
1730
1723
|
...(pkg.agentTemplates.length > 0 && {
|
|
@@ -1860,30 +1853,6 @@ function licenseOf(files) {
|
|
|
1860
1853
|
}
|
|
1861
1854
|
return { truncated: false };
|
|
1862
1855
|
}
|
|
1863
|
-
/**
|
|
1864
|
-
* The manifest with the confirm's suggested pinning: `names` (each a skill of the review, else
|
|
1865
|
-
* `validation_failed`) marks those skills `pinned: true` and clears the flag on the others;
|
|
1866
|
-
* undefined keeps the plugin's flags.
|
|
1867
|
-
*/
|
|
1868
|
-
function withPinned(m, review, names) {
|
|
1869
|
-
if (names === undefined)
|
|
1870
|
-
return m;
|
|
1871
|
-
const byName = new Map(review.skills.map((s) => [s.name, s.path]));
|
|
1872
|
-
const unknown = names.filter((n) => !byName.has(n));
|
|
1873
|
-
if (unknown.length > 0) {
|
|
1874
|
-
throw new ApiError("validation_failed", `pinnedSuggestions: ${unknown.map((n) => JSON.stringify(n)).join(", ")} ${unknown.length === 1 ? "is not a skill" : "are not skills"} of this plugin`);
|
|
1875
|
-
}
|
|
1876
|
-
const paths = new Set(names.map((n) => byName.get(n)));
|
|
1877
|
-
return {
|
|
1878
|
-
...m,
|
|
1879
|
-
skills: (m.skills ?? []).map(({ pinned: _, ...s }) => paths.has(s.path) ? { ...s, pinned: true } : s),
|
|
1880
|
-
};
|
|
1881
|
-
}
|
|
1882
|
-
/** Names of the skills the stored manifest suggests pinning (for the audit). */
|
|
1883
|
-
function pinnedNames(m, review) {
|
|
1884
|
-
const byPath = new Map(review.skills.map((s) => [s.path, s.name]));
|
|
1885
|
-
return (m.skills ?? []).filter((s) => s.pinned === true).map((s) => byPath.get(s.path) ?? s.path);
|
|
1886
|
-
}
|
|
1887
1856
|
/**
|
|
1888
1857
|
* The staging rows a route may see (P3-8): the platform's (`org_id` null) without an owner, else
|
|
1889
1858
|
* the owner org's.
|
|
@@ -432,8 +432,8 @@ export declare class PluginInstaller {
|
|
|
432
432
|
/**
|
|
433
433
|
* Uninstall (the plugin's component actions, see `requiredActions`, re-checked under the org row
|
|
434
434
|
* lock, one transaction). Removes only components with created=true:
|
|
435
|
-
* - a skill is kept when an agent
|
|
436
|
-
* org uses it too (used_by_other_install);
|
|
435
|
+
* - a skill is kept when an agent names it (an inline sub-agent template's `skills`;
|
|
436
|
+
* used_by_agents) or another plugin install in this org uses it too (used_by_other_install);
|
|
437
437
|
* - a connector is kept when an agent references it (used_by_agents);
|
|
438
438
|
* - an extension is kept when another plugin install uses it too (used_by_other_install), a
|
|
439
439
|
* connector still uses a connector it provides (used_by_connectors), or another enabled
|
|
@@ -1067,8 +1067,8 @@ let PluginInstaller = class PluginInstaller {
|
|
|
1067
1067
|
/**
|
|
1068
1068
|
* Uninstall (the plugin's component actions, see `requiredActions`, re-checked under the org row
|
|
1069
1069
|
* lock, one transaction). Removes only components with created=true:
|
|
1070
|
-
* - a skill is kept when an agent
|
|
1071
|
-
* org uses it too (used_by_other_install);
|
|
1070
|
+
* - a skill is kept when an agent names it (an inline sub-agent template's `skills`;
|
|
1071
|
+
* used_by_agents) or another plugin install in this org uses it too (used_by_other_install);
|
|
1072
1072
|
* - a connector is kept when an agent references it (used_by_agents);
|
|
1073
1073
|
* - an extension is kept when another plugin install uses it too (used_by_other_install), a
|
|
1074
1074
|
* connector still uses a connector it provides (used_by_connectors), or another enabled
|
|
@@ -121,6 +121,13 @@ export declare function contentDigest(files: ReadonlyMap<string, Uint8Array>): s
|
|
|
121
121
|
* zero are not valid semver).
|
|
122
122
|
*/
|
|
123
123
|
export declare const archiveFallbackVersion: (digest: string) => string;
|
|
124
|
+
/**
|
|
125
|
+
* A `plugin.json` with the fields the SDK no longer has dropped: `skills[].pinned` (the pinned
|
|
126
|
+
* suggestion, gone with pinning; skills default-on spec §8). Stored packages are history and still
|
|
127
|
+
* carry it, so every reader of a package passes the manifest through here before parsing. Anything
|
|
128
|
+
* else (not JSON, not an object) is returned as is for the parser to report.
|
|
129
|
+
*/
|
|
130
|
+
export declare function withoutRemovedManifestFields(text: string): unknown;
|
|
124
131
|
/** Largest icon (plugin or connector template) in bytes. */
|
|
125
132
|
export declare const PLUGIN_ICON_MAX_BYTES: number;
|
|
126
133
|
/**
|
|
@@ -52,6 +52,32 @@ export function contentDigest(files) {
|
|
|
52
52
|
*/
|
|
53
53
|
export const archiveFallbackVersion = (digest) => `0.0.0-sha256.h${digest.slice(0, 12)}`;
|
|
54
54
|
const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
55
|
+
/**
|
|
56
|
+
* A `plugin.json` with the fields the SDK no longer has dropped: `skills[].pinned` (the pinned
|
|
57
|
+
* suggestion, gone with pinning; skills default-on spec §8). Stored packages are history and still
|
|
58
|
+
* carry it, so every reader of a package passes the manifest through here before parsing. Anything
|
|
59
|
+
* else (not JSON, not an object) is returned as is for the parser to report.
|
|
60
|
+
*/
|
|
61
|
+
export function withoutRemovedManifestFields(text) {
|
|
62
|
+
let raw;
|
|
63
|
+
try {
|
|
64
|
+
raw = JSON.parse(text);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return text;
|
|
68
|
+
}
|
|
69
|
+
if (!isObj(raw) || !Array.isArray(raw.skills))
|
|
70
|
+
return raw;
|
|
71
|
+
return {
|
|
72
|
+
...raw,
|
|
73
|
+
skills: raw.skills.map((s) => {
|
|
74
|
+
if (!isObj(s) || !("pinned" in s))
|
|
75
|
+
return s;
|
|
76
|
+
const { pinned: _, ...rest } = s;
|
|
77
|
+
return rest;
|
|
78
|
+
}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
55
81
|
const decode = (data) => {
|
|
56
82
|
try {
|
|
57
83
|
return new TextDecoder("utf-8", { fatal: true }).decode(data);
|
|
@@ -227,7 +253,7 @@ export function readPluginFiles(files, opts) {
|
|
|
227
253
|
const undeclared = clientUndeclared(text);
|
|
228
254
|
if (undeclared !== undefined)
|
|
229
255
|
throw new PluginPackageError("client.undeclared", [undeclared]);
|
|
230
|
-
const parsed = parsePluginManifest(text);
|
|
256
|
+
const parsed = parsePluginManifest(withoutRemovedManifestFields(text));
|
|
231
257
|
if ("errors" in parsed) {
|
|
232
258
|
return invalid(parsed.errors.map((e) => `${PLUGIN_MANIFEST_FILE}: ${e}`));
|
|
233
259
|
}
|
|
@@ -179,12 +179,11 @@ export type UpdateTarget = VersionRow;
|
|
|
179
179
|
* permissions wait for the admin's approval as for any extension upgrade), then one transaction
|
|
180
180
|
* under the item name's lock that recomputes the diff (`plugin.upgrade_stale` on a difference)
|
|
181
181
|
* and writes the platform versions (`PlatformComponents.syncFromVersion`, which records
|
|
182
|
-
* `platform_synced_version`), the
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* credential shape), moves every org install to the version and audits
|
|
182
|
+
* `platform_synced_version`), the removals (a component no agent uses is soft-deleted, so
|
|
183
|
+
* unpinned linked copies go with it; pinned copies keep their own version; a removed connector
|
|
184
|
+
* template leaves its connectors as the orgs' own), clears the pins of linked copies, fans
|
|
185
|
+
* changed templates out to every connector made from them (`applyTemplateIn`, under each org's
|
|
186
|
+
* row lock, credentials cleared only for a changed credential shape), moves every org install to the version and audits
|
|
188
187
|
* `plugin.platform_updated`; the scope sync of the item and its dependencies is enqueued after
|
|
189
188
|
* the commit (orgs get new dependencies by rule 9). A failure rolls the transaction back and
|
|
190
189
|
* puts the extension back where it was (audit `plugin.platform_update_failed`, 502
|
|
@@ -106,12 +106,11 @@ const filesDigest = (row) => skillFilesDigest(row.files.map((f) => ({ path: f.pa
|
|
|
106
106
|
* permissions wait for the admin's approval as for any extension upgrade), then one transaction
|
|
107
107
|
* under the item name's lock that recomputes the diff (`plugin.upgrade_stale` on a difference)
|
|
108
108
|
* and writes the platform versions (`PlatformComponents.syncFromVersion`, which records
|
|
109
|
-
* `platform_synced_version`), the
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* credential shape), moves every org install to the version and audits
|
|
109
|
+
* `platform_synced_version`), the removals (a component no agent uses is soft-deleted, so
|
|
110
|
+
* unpinned linked copies go with it; pinned copies keep their own version; a removed connector
|
|
111
|
+
* template leaves its connectors as the orgs' own), clears the pins of linked copies, fans
|
|
112
|
+
* changed templates out to every connector made from them (`applyTemplateIn`, under each org's
|
|
113
|
+
* row lock, credentials cleared only for a changed credential shape), moves every org install to the version and audits
|
|
115
114
|
* `plugin.platform_updated`; the scope sync of the item and its dependencies is enqueued after
|
|
116
115
|
* the commit (orgs get new dependencies by rule 9). A failure rolls the transaction back and
|
|
117
116
|
* puts the extension back where it was (audit `plugin.platform_update_failed`, 502
|
|
@@ -523,16 +522,6 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
|
|
|
523
522
|
throw stale();
|
|
524
523
|
throw e;
|
|
525
524
|
}
|
|
526
|
-
for (const [id, pinned] of diff.suggest) {
|
|
527
|
-
await t
|
|
528
|
-
.updateTable("platform_skill_versions as v")
|
|
529
|
-
.set({ suggest_pinned: pinned })
|
|
530
|
-
.from("platform_skills as s")
|
|
531
|
-
.whereRef("s.id", "=", "v.skill_id")
|
|
532
|
-
.whereRef("s.current_version", "=", "v.version")
|
|
533
|
-
.where("s.id", "=", id)
|
|
534
|
-
.execute();
|
|
535
|
-
}
|
|
536
525
|
// Removals (spec §7.3): kept while agents use it; otherwise soft-deleted
|
|
537
526
|
const now = sql `now()`;
|
|
538
527
|
for (const c of diff.components) {
|
|
@@ -826,7 +815,6 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
|
|
|
826
815
|
// The platform's components of the plugin and the target's
|
|
827
816
|
const live = await this.liveComponents(itemId);
|
|
828
817
|
const components = [];
|
|
829
|
-
const suggest = new Map();
|
|
830
818
|
const direction = (fromVersion) => fromVersion === null || compareVersions(to.version, fromVersion) >= 0
|
|
831
819
|
? "upgrade"
|
|
832
820
|
: "downgrade";
|
|
@@ -847,7 +835,6 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
|
|
|
847
835
|
return {
|
|
848
836
|
name: n,
|
|
849
837
|
digest: dirDigest(to, packagePath(entry?.path)),
|
|
850
|
-
pinned: entry?.pinned === true,
|
|
851
838
|
};
|
|
852
839
|
});
|
|
853
840
|
for (const s of toSkills) {
|
|
@@ -857,8 +844,6 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
|
|
|
857
844
|
continue;
|
|
858
845
|
}
|
|
859
846
|
const same = skillFilesDigest(l.manifest.files) === s.digest;
|
|
860
|
-
if (same && l.suggestPinned !== s.pinned)
|
|
861
|
-
suggest.set(l.id, s.pinned);
|
|
862
847
|
components.push({
|
|
863
848
|
kind: "skill",
|
|
864
849
|
id: l.id,
|
|
@@ -1248,7 +1233,6 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
|
|
|
1248
1233
|
connectors,
|
|
1249
1234
|
connectorOrgs,
|
|
1250
1235
|
...(themes !== undefined && { themes }),
|
|
1251
|
-
suggest,
|
|
1252
1236
|
contents,
|
|
1253
1237
|
dependencies,
|
|
1254
1238
|
diffHash,
|
|
@@ -1374,7 +1358,6 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
|
|
|
1374
1358
|
"v.manifest",
|
|
1375
1359
|
"v.catalog_version",
|
|
1376
1360
|
"v.updated_on_own",
|
|
1377
|
-
"v.suggest_pinned",
|
|
1378
1361
|
])
|
|
1379
1362
|
.where("p.catalog_item_id", "=", itemId)
|
|
1380
1363
|
.where("p.deleted_at", "is", null)
|
|
@@ -1388,7 +1371,6 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
|
|
|
1388
1371
|
catalogVersion: r.catalog_version,
|
|
1389
1372
|
updatedOnOwn: r.updated_on_own,
|
|
1390
1373
|
ownScope: r.scope_mode === "own",
|
|
1391
|
-
suggestPinned: r.suggest_pinned,
|
|
1392
1374
|
}));
|
|
1393
1375
|
const agentTemplates = (await db
|
|
1394
1376
|
.selectFrom("platform_agent_templates as p")
|