@capybara-hq/kernel 0.1.0-rc.12 → 0.1.0-rc.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/admin.schemas.d.ts +13 -0
- package/dist/agents/agent-lookup.d.ts +5 -0
- package/dist/agents/agent-lookup.js +15 -0
- package/dist/background/background.module.js +2 -2
- package/dist/background/launch-lock.d.ts +1 -1
- package/dist/background/launch-lock.js +1 -1
- package/dist/background/poll.job.d.ts +2 -2
- package/dist/background/poll.job.js +10 -10
- package/dist/background/stop.d.ts +1 -1
- package/dist/background/stop.js +3 -3
- package/dist/background/store.d.ts +5 -5
- package/dist/background/store.js +5 -5
- package/dist/background/tasks.service.d.ts +6 -6
- package/dist/background/tasks.service.js +13 -13
- package/dist/catalog/admin-catalog.controller.d.ts +13 -2
- package/dist/catalog/admin-catalog.controller.js +24 -3
- package/dist/catalog/admin-catalog.schemas.d.ts +10 -0
- package/dist/catalog/admin-catalog.schemas.js +7 -0
- package/dist/catalog/catalog-content.d.ts +9 -1
- package/dist/catalog/catalog-content.js +2 -1
- package/dist/catalog/catalog-files.d.ts +3 -2
- package/dist/catalog/catalog-files.js +8 -5
- package/dist/catalog/component-scope.service.d.ts +14 -1
- package/dist/catalog/component-scope.service.js +12 -2
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/org-catalog.controller.d.ts +5 -4
- package/dist/catalog/org-catalog.controller.js +5 -4
- package/dist/catalog/org-catalog.schemas.d.ts +18 -2
- package/dist/catalog/org-catalog.schemas.js +16 -2
- package/dist/catalog/org-catalog.service.js +8 -2
- package/dist/catalog/plugin-import.js +1 -1
- package/dist/catalog/plugin-package.js +37 -9
- package/dist/catalog/plugin-upgrade.d.ts +15 -1
- package/dist/catalog/plugin-upgrade.js +18 -5
- package/dist/channels/channels.module.js +2 -2
- package/dist/channels/connections.controller.d.ts +1 -1
- package/dist/channels/connections.controller.js +1 -1
- package/dist/channels/connections.service.d.ts +22 -5
- package/dist/channels/connections.service.js +56 -10
- package/dist/channels/inbound.d.ts +8 -8
- package/dist/channels/inbound.js +31 -31
- package/dist/channels/phrases.d.ts +27 -27
- package/dist/channels/phrases.js +27 -27
- package/dist/channels/webhook.d.ts +21 -1
- package/dist/channels/webhook.js +39 -4
- package/dist/config/docs.js +1 -1
- package/dist/config/schema.d.ts +2 -2
- package/dist/config/schema.js +21 -21
- package/dist/conversations/conversations.controller.d.ts +11 -11
- package/dist/conversations/conversations.controller.js +15 -15
- package/dist/conversations/conversations.module.d.ts +1 -1
- package/dist/conversations/conversations.module.js +7 -7
- package/dist/conversations/conversations.schemas.js +1 -1
- package/dist/conversations/conversations.service.d.ts +14 -14
- package/dist/conversations/conversations.service.js +19 -19
- package/dist/conversations/{environment-status.d.ts → device-status.d.ts} +9 -9
- package/dist/conversations/{environment-status.js → device-status.js} +18 -18
- package/dist/conversations/event-log.d.ts +1 -1
- package/dist/conversations/event-log.js +1 -1
- package/dist/conversations/events.d.ts +1 -1
- package/dist/conversations/events.js +2 -2
- package/dist/ctx/create-ctx.d.ts +26 -3
- package/dist/ctx/create-ctx.js +134 -26
- package/dist/db/kernel-schema.d.ts +37 -25
- package/dist/{environments → devices}/access.d.ts +19 -19
- package/dist/{environments → devices}/access.js +28 -28
- package/dist/devices/conversation-devices.d.ts +75 -0
- package/dist/{environments/conversation-environments.js → devices/conversation-devices.js} +71 -72
- package/dist/devices/devices.controller.d.ts +36 -0
- package/dist/{environments/environments.controller.js → devices/devices.controller.js} +37 -37
- package/dist/devices/devices.module.d.ts +5 -13
- package/dist/devices/devices.module.js +16 -29
- package/dist/devices/devices.schemas.d.ts +3 -0
- package/dist/devices/devices.schemas.js +14 -0
- package/dist/{environments/environments.service.d.ts → devices/devices.service.d.ts} +70 -70
- package/dist/{environments/environments.service.js → devices/devices.service.js} +122 -122
- package/dist/devices/dto.d.ts +13 -54
- package/dist/devices/dto.js +7 -39
- package/dist/devices/label.d.ts +11 -0
- package/dist/{environments → devices}/label.js +7 -7
- package/dist/{environments → devices}/legacy-cleanup.job.d.ts +3 -3
- package/dist/{environments → devices}/legacy-cleanup.job.js +3 -3
- package/dist/errors.d.ts +29 -25
- package/dist/errors.js +29 -25
- package/dist/evals/recorded-tools.d.ts +2 -2
- package/dist/evals/recorded-tools.js +6 -6
- package/dist/extensions/admin-ops.js +1 -0
- package/dist/extensions/admin-view.js +2 -0
- package/dist/extensions/effective-config.d.ts +6 -0
- package/dist/extensions/effective-config.js +18 -7
- package/dist/extensions/guide-places.d.ts +66 -0
- package/dist/extensions/guide-places.js +152 -0
- package/dist/extensions/host.d.ts +13 -2
- package/dist/extensions/host.js +27 -6
- package/dist/extensions/instance.d.ts +17 -2
- package/dist/extensions/instance.js +21 -0
- package/dist/extensions/ledger.d.ts +1 -1
- package/dist/extensions/permission-set.d.ts +16 -2
- package/dist/extensions/permission-set.js +17 -3
- package/dist/extensions/permission-view.d.ts +10 -1
- package/dist/extensions/plugin-guides.d.ts +207 -54
- package/dist/extensions/plugin-guides.js +436 -165
- package/dist/files/previewers.d.ts +1 -1
- package/dist/files/previewers.js +1 -1
- package/dist/http/api.module.js +16 -6
- package/dist/http/gateway-routes.d.ts +1 -1
- package/dist/http/gateway-routes.js +1 -1
- package/dist/identity/settings.d.ts +32 -0
- package/dist/identity/settings.js +26 -2
- package/dist/infra/config/kernel-config.service.js +4 -4
- package/dist/infra/lock/lock.service.d.ts +8 -0
- package/dist/infra/lock/lock.service.js +27 -0
- package/dist/infra/throttler/named-throttlers.d.ts +4 -1
- package/dist/infra/throttler/named-throttlers.js +16 -1
- package/dist/infra/throttler/throttler.guard.js +1 -1
- package/dist/kernel.module.js +3 -3
- package/dist/{devices → local-devices}/device-auth.controller.d.ts +6 -6
- package/dist/{devices → local-devices}/device-auth.controller.js +5 -5
- package/dist/{devices → local-devices}/device-auth.d.ts +20 -20
- package/dist/{devices → local-devices}/device-auth.js +51 -53
- package/dist/local-devices/device-auth.module.d.ts +7 -0
- package/dist/{devices → local-devices}/device-auth.module.js +5 -5
- package/dist/{devices → local-devices}/device-routes.d.ts +3 -3
- package/dist/{devices → local-devices}/device-routes.js +2 -2
- package/dist/local-devices/dto.d.ts +66 -0
- package/dist/local-devices/dto.js +44 -0
- package/dist/{devices → local-devices}/keys.d.ts +11 -11
- package/dist/{devices → local-devices}/keys.js +11 -11
- package/dist/{devices/device-gateway.d.ts → local-devices/local-device-gateway.d.ts} +14 -14
- package/dist/{devices/device-gateway.js → local-devices/local-device-gateway.js} +44 -44
- package/dist/{devices/device-provider.d.ts → local-devices/local-device-provider.d.ts} +15 -15
- package/dist/{devices/device-provider.js → local-devices/local-device-provider.js} +23 -23
- package/dist/local-devices/local-devices.module.d.ts +16 -0
- package/dist/local-devices/local-devices.module.js +44 -0
- package/dist/{devices → local-devices}/machines.d.ts +26 -26
- package/dist/{devices → local-devices}/machines.js +71 -71
- package/dist/{devices → local-devices}/relay.d.ts +15 -15
- package/dist/{devices → local-devices}/relay.js +55 -55
- package/dist/{devices → local-devices}/targets.d.ts +8 -8
- package/dist/{devices → local-devices}/targets.js +14 -14
- package/dist/orgs/offboarding.d.ts +6 -6
- package/dist/orgs/offboarding.js +12 -12
- package/dist/orgs/settings.service.d.ts +28 -0
- package/dist/orgs/settings.service.js +20 -1
- package/dist/overrides.d.ts +3 -1
- package/dist/overrides.js +2 -0
- package/dist/platform/exclusions.js +48 -8
- package/dist/platform/operation.js +10 -2
- package/dist/platform/ops/admin.ops.js +8 -2
- package/dist/platform/ops/connectors.ops.js +2 -0
- package/dist/platform/ops/conversations.ops.d.ts +3 -3
- package/dist/platform/ops/conversations.ops.js +9 -9
- package/dist/platform/ops/devices.ops.d.ts +26 -0
- package/dist/platform/ops/devices.ops.js +311 -0
- package/dist/platform/ops/org-settings.ops.js +2 -2
- package/dist/platform/ops/orgs.ops.js +1 -0
- package/dist/platform/ops/setup.ops.d.ts +24 -0
- package/dist/platform/ops/setup.ops.js +212 -0
- package/dist/platform/ops/ui.ops.d.ts +8 -0
- package/dist/platform/ops/ui.ops.js +41 -0
- package/dist/platform/platform-ops.module.d.ts +4 -2
- package/dist/platform/platform-ops.module.js +13 -5
- package/dist/platform/route-schemas.js +11 -3
- package/dist/roles/gateway-role.d.ts +3 -3
- package/dist/roles/gateway-role.js +4 -4
- package/dist/roles/gateway.module.d.ts +1 -1
- package/dist/roles/gateway.module.js +5 -5
- package/dist/roles/worker.module.js +1 -1
- package/dist/runtime/context/build.d.ts +1 -1
- package/dist/runtime/context/build.js +6 -6
- package/dist/runtime/context/compaction.js +1 -1
- package/dist/runtime/context/{environment-paths.d.ts → device-paths.d.ts} +11 -11
- package/dist/runtime/context/{environment-paths.js → device-paths.js} +13 -13
- package/dist/runtime/maintenance.d.ts +1 -1
- package/dist/sandbox/jobs.d.ts +13 -13
- package/dist/sandbox/jobs.js +20 -20
- package/dist/sandbox/leases.d.ts +9 -9
- package/dist/sandbox/leases.js +14 -14
- package/dist/sandbox/providers.d.ts +8 -8
- package/dist/sandbox/providers.js +8 -8
- package/dist/sandbox/sandbox.module.d.ts +1 -1
- package/dist/sandbox/sandbox.module.js +1 -1
- package/dist/sandbox/sandbox.service.d.ts +76 -76
- package/dist/sandbox/sandbox.service.js +230 -230
- package/dist/setup/kernel-checks.d.ts +91 -0
- package/dist/setup/kernel-checks.js +295 -0
- package/dist/setup/oauth-token-probe.d.ts +47 -0
- package/dist/setup/oauth-token-probe.js +108 -0
- package/dist/setup/redact-check.d.ts +18 -0
- package/dist/setup/redact-check.js +46 -0
- package/dist/setup/setup-check-registry.d.ts +86 -0
- package/dist/setup/setup-check-registry.js +75 -0
- package/dist/setup/setup-checks.controller.d.ts +28 -0
- package/dist/setup/setup-checks.controller.js +78 -0
- package/dist/setup/setup-checks.schemas.d.ts +38 -0
- package/dist/setup/setup-checks.schemas.js +43 -0
- package/dist/setup/setup-checks.service.d.ts +144 -0
- package/dist/setup/setup-checks.service.js +683 -0
- package/dist/setup/setup-guides.controller.d.ts +18 -0
- package/dist/setup/setup-guides.controller.js +48 -0
- package/dist/setup/setup-guides.schemas.d.ts +10 -0
- package/dist/setup/setup-guides.schemas.js +6 -0
- package/dist/setup/setup-guides.service.d.ts +126 -0
- package/dist/setup/setup-guides.service.js +315 -0
- package/dist/setup/setup.module.d.ts +8 -0
- package/dist/setup/setup.module.js +31 -0
- package/dist/tools/builtins/builtin-tools.d.ts +2 -2
- package/dist/tools/builtins/builtin-tools.js +5 -5
- package/dist/tools/builtins/platform.js +1 -1
- package/dist/tools/builtins/sandbox/bash.js +6 -6
- package/dist/tools/builtins/sandbox/common.d.ts +25 -25
- package/dist/tools/builtins/sandbox/common.js +51 -51
- package/dist/tools/builtins/sandbox/edit.js +2 -2
- package/dist/tools/builtins/sandbox/index.d.ts +1 -1
- package/dist/tools/builtins/sandbox/index.js +1 -1
- package/dist/tools/builtins/sandbox/task-output.d.ts +6 -6
- package/dist/tools/builtins/sandbox/task-output.js +10 -10
- package/dist/tools/builtins/sandbox/task-stop.js +2 -2
- package/dist/tools/builtins/sandbox/write.js +2 -2
- package/dist/tools/builtins/skill-load.d.ts +1 -1
- package/dist/tools/builtins/skill-load.js +2 -2
- package/dist/tools/connectors.controller.d.ts +28 -11
- package/dist/tools/connectors.controller.js +49 -14
- package/dist/tools/connectors.schemas.d.ts +4 -0
- package/dist/tools/connectors.schemas.js +4 -0
- package/dist/tools/connectors.service.d.ts +30 -2
- package/dist/tools/connectors.service.js +98 -3
- package/dist/tools/credentials.d.ts +20 -0
- package/dist/tools/credentials.js +90 -1
- package/dist/tools/oauth/tokens.d.ts +20 -0
- package/dist/tools/oauth/tokens.js +49 -24
- package/dist/tools/pipeline.js +4 -3
- package/dist/tools/registry.d.ts +2 -2
- package/dist/tools/tools.module.js +3 -3
- package/dist/ui/admin-ui.controller.d.ts +56 -0
- package/dist/ui/admin-ui.controller.js +192 -0
- package/dist/ui/arrangement.d.ts +74 -0
- package/dist/ui/arrangement.js +98 -0
- package/dist/ui/embed-token.d.ts +2 -2
- package/dist/ui/embed-token.js +30 -5
- package/dist/ui/registry.d.ts +29 -14
- package/dist/ui/registry.js +31 -10
- package/dist/ui/slots.controller.d.ts +11 -0
- package/dist/ui/slots.controller.js +25 -0
- package/dist/ui/ui-stream.d.ts +20 -3
- package/dist/ui/ui-stream.js +25 -7
- package/dist/ui/ui.schemas.d.ts +66 -0
- package/dist/ui/ui.schemas.js +65 -0
- package/dist/ui/views.controller.d.ts +35 -49
- package/dist/ui/views.controller.js +48 -70
- package/dist/ui/views.d.ts +84 -18
- package/dist/ui/views.js +201 -38
- package/package.json +3 -3
- package/src/migrations/0105_devices_rename.sql +136 -0
- package/src/migrations/0106_setup_guides_v2.sql +10 -0
- package/dist/devices/device-auth.module.d.ts +0 -7
- package/dist/environments/conversation-environments.d.ts +0 -75
- package/dist/environments/dto.d.ts +0 -25
- package/dist/environments/dto.js +0 -12
- package/dist/environments/environments.controller.d.ts +0 -36
- package/dist/environments/environments.module.d.ts +0 -8
- package/dist/environments/environments.module.js +0 -31
- package/dist/environments/environments.schemas.d.ts +0 -3
- package/dist/environments/environments.schemas.js +0 -14
- package/dist/environments/label.d.ts +0 -11
- package/dist/platform/ops/environments.ops.d.ts +0 -26
- package/dist/platform/ops/environments.ops.js +0 -311
|
@@ -53,6 +53,19 @@ export declare const DeploymentSettingsBody: z.ZodObject<{
|
|
|
53
53
|
uiTheme: z.ZodOptional<z.ZodObject<{
|
|
54
54
|
id: z.ZodNullable<z.ZodString>;
|
|
55
55
|
}, z.core.$strict>>;
|
|
56
|
+
uiArrangement: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
57
|
+
"agent.detail.section": "agent.detail.section";
|
|
58
|
+
"conversation.panel": "conversation.panel";
|
|
59
|
+
"conversation.properties.section": "conversation.properties.section";
|
|
60
|
+
"conversation.tool-result.card": "conversation.tool-result.card";
|
|
61
|
+
"file.preview": "file.preview";
|
|
62
|
+
"org.page": "org.page";
|
|
63
|
+
"org.settings.section": "org.settings.section";
|
|
64
|
+
"platform.page": "platform.page";
|
|
65
|
+
}> & z.core.$partial, z.ZodNullable<z.ZodObject<{
|
|
66
|
+
hidden: z.ZodArray<z.ZodString>;
|
|
67
|
+
order: z.ZodArray<z.ZodString>;
|
|
68
|
+
}, z.core.$strict>>>>;
|
|
56
69
|
}, z.core.$strict>;
|
|
57
70
|
export declare const PurposeParams: z.ZodObject<{
|
|
58
71
|
purpose: z.ZodString;
|
|
@@ -49,6 +49,11 @@ export declare function visibleTo(viewerAccountId: string | null): (eb: Expressi
|
|
|
49
49
|
* the live org). Deleted agents are never visible.
|
|
50
50
|
*/
|
|
51
51
|
export declare function isAgentVisibleTo(db: KernelSchemaDb, agentId: string, accountId: string): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* {@link isAgentVisibleTo} for an agent of `orgId` only: an agent the account can read in another
|
|
54
|
+
* org is not visible here (UI slots spec R6, the `agent.detail.section` scope rule).
|
|
55
|
+
*/
|
|
56
|
+
export declare function isAgentVisibleIn(db: KernelSchemaDb, orgId: string, agentId: string, accountId: string): Promise<boolean>;
|
|
52
57
|
/**
|
|
53
58
|
* Reads agents for a viewer (the visibility rule {@link visibleTo}): the part of `AgentsService`
|
|
54
59
|
* the conversations, the skill invoker and the attachments read, with no dependency on the
|
|
@@ -67,6 +67,21 @@ export async function isAgentVisibleTo(db, agentId, accountId) {
|
|
|
67
67
|
.executeTakeFirst();
|
|
68
68
|
return row !== undefined;
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* {@link isAgentVisibleTo} for an agent of `orgId` only: an agent the account can read in another
|
|
72
|
+
* org is not visible here (UI slots spec R6, the `agent.detail.section` scope rule).
|
|
73
|
+
*/
|
|
74
|
+
export async function isAgentVisibleIn(db, orgId, agentId, accountId) {
|
|
75
|
+
const row = await db
|
|
76
|
+
.selectFrom("agents")
|
|
77
|
+
.select("id")
|
|
78
|
+
.where("id", "=", agentId)
|
|
79
|
+
.where("org_id", "=", orgId)
|
|
80
|
+
.where("deleted_at", "is", null)
|
|
81
|
+
.where(visibleTo(accountId))
|
|
82
|
+
.executeTakeFirst();
|
|
83
|
+
return row !== undefined;
|
|
84
|
+
}
|
|
70
85
|
/**
|
|
71
86
|
* Reads agents for a viewer (the visibility rule {@link visibleTo}): the part of `AgentsService`
|
|
72
87
|
* the conversations, the skill invoker and the attachments read, with no dependency on the
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { Module } from "@nestjs/common";
|
|
8
8
|
import { ConversationAccessModule } from "../conversations/access.js";
|
|
9
9
|
import { EventLogModule } from "../conversations/event-log.js";
|
|
10
|
-
import {
|
|
10
|
+
import { DevicesModule } from "../devices/devices.module.js";
|
|
11
11
|
import { SandboxModule } from "../sandbox/sandbox.module.js";
|
|
12
12
|
import { BackgroundTaskFinisher } from "./finish.js";
|
|
13
13
|
import { BackgroundTaskStopper } from "./stop.js";
|
|
@@ -28,7 +28,7 @@ BackgroundModule = __decorate([
|
|
|
28
28
|
imports: [
|
|
29
29
|
BackgroundStoreModule,
|
|
30
30
|
SandboxModule,
|
|
31
|
-
|
|
31
|
+
DevicesModule,
|
|
32
32
|
EventLogModule,
|
|
33
33
|
ConversationAccessModule,
|
|
34
34
|
],
|
|
@@ -3,7 +3,7 @@ import { XactLock } from "../infra/database/xact-lock.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* The launch lock of one root conversation (decision R9: one provider per transaction-scoped
|
|
5
5
|
* lock): serializes background task reservations in its tree, so the count of running tasks
|
|
6
|
-
* checked against `sandbox.background.maxTasks` (per root conversation, whatever
|
|
6
|
+
* checked against `sandbox.background.maxTasks` (per root conversation, whatever device it
|
|
7
7
|
* works in) and the insert of the new row are one step. Joins the
|
|
8
8
|
* caller's transaction (`mandatory`), which holds it until it ends.
|
|
9
9
|
*/
|
|
@@ -14,7 +14,7 @@ import { XactLock } from "../infra/database/xact-lock.js";
|
|
|
14
14
|
/**
|
|
15
15
|
* The launch lock of one root conversation (decision R9: one provider per transaction-scoped
|
|
16
16
|
* lock): serializes background task reservations in its tree, so the count of running tasks
|
|
17
|
-
* checked against `sandbox.background.maxTasks` (per root conversation, whatever
|
|
17
|
+
* checked against `sandbox.background.maxTasks` (per root conversation, whatever device it
|
|
18
18
|
* works in) and the insert of the new row are one step. Joins the
|
|
19
19
|
* caller's transaction (`mandatory`), which holds it until it ends.
|
|
20
20
|
*/
|
|
@@ -21,7 +21,7 @@ export declare const launchAbandonedAfterMs: (cfg: KernelConfig) => number;
|
|
|
21
21
|
/**
|
|
22
22
|
* The worker's background task jobs (spec 2026-11-05-background-bash-design §4.3), each once per
|
|
23
23
|
* tick across replicas:
|
|
24
|
-
* - `background-task-poll` (every `sandbox.background.pollSeconds`): for every
|
|
24
|
+
* - `background-task-poll` (every `sandbox.background.pollSeconds`): for every device
|
|
25
25
|
* instance with running tasks (of any conversation using it), one exec through
|
|
26
26
|
* `SandboxService.ifRunning` (which never creates or resumes an instance) reports each task's
|
|
27
27
|
* exit file and liveness; ended tasks finish through {@link BackgroundTaskFinisher}. Each poll
|
|
@@ -47,7 +47,7 @@ export declare class BackgroundTaskPollJob {
|
|
|
47
47
|
* result: they never started), with a `changed: "background"` frame to their conversations.
|
|
48
48
|
*/
|
|
49
49
|
pollOnce(signal?: AbortSignal): Promise<number>;
|
|
50
|
-
/** Polls the tasks of one
|
|
50
|
+
/** Polls the tasks of one device instance; returns how many finished. */
|
|
51
51
|
private pollSandbox;
|
|
52
52
|
/** The poll exec of one instance: each task's report by id. */
|
|
53
53
|
private pollExec;
|
|
@@ -44,7 +44,7 @@ const POLL_MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
|
|
|
44
44
|
/**
|
|
45
45
|
* The worker's background task jobs (spec 2026-11-05-background-bash-design §4.3), each once per
|
|
46
46
|
* tick across replicas:
|
|
47
|
-
* - `background-task-poll` (every `sandbox.background.pollSeconds`): for every
|
|
47
|
+
* - `background-task-poll` (every `sandbox.background.pollSeconds`): for every device
|
|
48
48
|
* instance with running tasks (of any conversation using it), one exec through
|
|
49
49
|
* `SandboxService.ifRunning` (which never creates or resumes an instance) reports each task's
|
|
50
50
|
* exit file and liveness; ended tasks finish through {@link BackgroundTaskFinisher}. Each poll
|
|
@@ -93,8 +93,8 @@ let BackgroundTaskPollJob = class BackgroundTaskPollJob {
|
|
|
93
93
|
for (const t of await this.store.runningStarted()) {
|
|
94
94
|
if (t.sid === null || t.sandboxCreatedAt === null)
|
|
95
95
|
continue;
|
|
96
|
-
// one exec per instance: the tasks of every conversation sharing the
|
|
97
|
-
const key = `${t.
|
|
96
|
+
// one exec per instance: the tasks of every conversation sharing the device
|
|
97
|
+
const key = `${t.deviceId} ${t.sandboxCreatedAt.getTime()}`;
|
|
98
98
|
groups.set(key, [...(groups.get(key) ?? []), t]);
|
|
99
99
|
}
|
|
100
100
|
let finished = 0;
|
|
@@ -102,9 +102,9 @@ let BackgroundTaskPollJob = class BackgroundTaskPollJob {
|
|
|
102
102
|
if (signal.aborted)
|
|
103
103
|
break;
|
|
104
104
|
try {
|
|
105
|
-
// the
|
|
105
|
+
// the device's provider is not there (no cloud provider, `@local` not served):
|
|
106
106
|
// its tasks stay as they are until it is
|
|
107
|
-
const env = tasks[0]?.
|
|
107
|
+
const env = tasks[0]?.deviceId ?? null;
|
|
108
108
|
if (env === null ? !this.sandbox.cloudAvailable : !(await this.sandbox.availableFor(env))) {
|
|
109
109
|
continue;
|
|
110
110
|
}
|
|
@@ -114,7 +114,7 @@ let BackgroundTaskPollJob = class BackgroundTaskPollJob {
|
|
|
114
114
|
if (signal.aborted)
|
|
115
115
|
break;
|
|
116
116
|
this.log.warn("cannot poll background tasks; retrying next tick", {
|
|
117
|
-
|
|
117
|
+
deviceId: tasks[0]?.deviceId,
|
|
118
118
|
err,
|
|
119
119
|
});
|
|
120
120
|
}
|
|
@@ -123,13 +123,13 @@ let BackgroundTaskPollJob = class BackgroundTaskPollJob {
|
|
|
123
123
|
this.log.info("background tasks finished", { count: finished });
|
|
124
124
|
return finished;
|
|
125
125
|
}
|
|
126
|
-
/** Polls the tasks of one
|
|
126
|
+
/** Polls the tasks of one device instance; returns how many finished. */
|
|
127
127
|
async pollSandbox(tasks, signal) {
|
|
128
128
|
const [first] = tasks;
|
|
129
|
-
// a task from before
|
|
130
|
-
const r = first.
|
|
129
|
+
// a task from before devices has no instance any more
|
|
130
|
+
const r = first.deviceId === null
|
|
131
131
|
? { kind: "not_running", status: "gone" }
|
|
132
|
-
: await this.sandbox.ifRunning(first.
|
|
132
|
+
: await this.sandbox.ifRunning(first.deviceId, { createdAt: first.sandboxCreatedAt }, (p, h, sig) => this.pollExec(actingAs(p, taskActor(first)), h, tasks, sig), signal);
|
|
133
133
|
const now = new Date();
|
|
134
134
|
let n = 0;
|
|
135
135
|
for (const t of tasks) {
|
|
@@ -43,7 +43,7 @@ export declare class BackgroundTaskStopper {
|
|
|
43
43
|
stop(task: BackgroundTaskRow, why: StopReason, signal?: AbortSignal): Promise<BackgroundTaskRow>;
|
|
44
44
|
/**
|
|
45
45
|
* SIGTERM, the grace period, SIGKILL until the session is empty, then the last lines: in the
|
|
46
|
-
* task's own instance only (`ifRunning`); a task from before
|
|
46
|
+
* task's own instance only (`ifRunning`); a task from before devices has none.
|
|
47
47
|
*/
|
|
48
48
|
private signalTask;
|
|
49
49
|
/**
|
package/dist/background/stop.js
CHANGED
|
@@ -138,12 +138,12 @@ let BackgroundTaskStopper = class BackgroundTaskStopper {
|
|
|
138
138
|
}
|
|
139
139
|
/**
|
|
140
140
|
* SIGTERM, the grace period, SIGKILL until the session is empty, then the last lines: in the
|
|
141
|
-
* task's own instance only (`ifRunning`); a task from before
|
|
141
|
+
* task's own instance only (`ifRunning`); a task from before devices has none.
|
|
142
142
|
*/
|
|
143
143
|
async signalTask(cur, sid, signal) {
|
|
144
|
-
if (cur.
|
|
144
|
+
if (cur.deviceId === null)
|
|
145
145
|
return { kind: "not_running", status: "gone" };
|
|
146
|
-
return this.sandbox.ifRunning(cur.
|
|
146
|
+
return this.sandbox.ifRunning(cur.deviceId, { createdAt: cur.sandboxCreatedAt }, async (tp, h, sig) => {
|
|
147
147
|
const p = actingAs(tp, taskActor(cur));
|
|
148
148
|
const term = await p.exec(h, {
|
|
149
149
|
command: termScript(cur.id, sid),
|
|
@@ -14,10 +14,10 @@ export interface BackgroundTaskRow {
|
|
|
14
14
|
*/
|
|
15
15
|
sandboxConversationId: string;
|
|
16
16
|
/**
|
|
17
|
-
* The
|
|
18
|
-
* is where the task's processes are. Null only for tasks from before
|
|
17
|
+
* The device the task runs in (the root conversation's when it was launched): its instance
|
|
18
|
+
* is where the task's processes are. Null only for tasks from before devices (all finished).
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
deviceId: string | null;
|
|
21
21
|
runId: string;
|
|
22
22
|
callId: string;
|
|
23
23
|
triggerAccountId: string;
|
|
@@ -157,10 +157,10 @@ export declare class BackgroundTaskStore {
|
|
|
157
157
|
/** Moves the read offset forward only (a concurrent reader never moves it back). */
|
|
158
158
|
advanceOffset(id: string, to: number): Promise<void>;
|
|
159
159
|
/**
|
|
160
|
-
* Finished tasks of
|
|
160
|
+
* Finished tasks of a device whose process may still exist (any conversation's: they
|
|
161
161
|
* share the instance).
|
|
162
162
|
*/
|
|
163
|
-
pendingKills(
|
|
163
|
+
pendingKills(deviceId: string): Promise<BackgroundTaskRow[]>;
|
|
164
164
|
clearKill(ids: string[]): Promise<void>;
|
|
165
165
|
/** Deletes finished tasks that ended before `before`; a running one is never deleted. */
|
|
166
166
|
pruneFinished(before: Date): Promise<number>;
|
package/dist/background/store.js
CHANGED
|
@@ -18,7 +18,7 @@ const toRow = (r) => ({
|
|
|
18
18
|
orgId: r.org_id,
|
|
19
19
|
conversationId: r.conversation_id,
|
|
20
20
|
sandboxConversationId: r.sandbox_conversation_id,
|
|
21
|
-
|
|
21
|
+
deviceId: r.device_id,
|
|
22
22
|
runId: r.run_id,
|
|
23
23
|
callId: r.call_id,
|
|
24
24
|
triggerAccountId: r.trigger_account_id,
|
|
@@ -195,7 +195,7 @@ let BackgroundTaskStore = class BackgroundTaskStore {
|
|
|
195
195
|
org_id: row.orgId,
|
|
196
196
|
conversation_id: row.conversationId,
|
|
197
197
|
sandbox_conversation_id: row.sandboxConversationId,
|
|
198
|
-
|
|
198
|
+
device_id: row.deviceId,
|
|
199
199
|
run_id: row.runId,
|
|
200
200
|
call_id: row.callId,
|
|
201
201
|
trigger_account_id: row.triggerAccountId,
|
|
@@ -314,14 +314,14 @@ let BackgroundTaskStore = class BackgroundTaskStore {
|
|
|
314
314
|
.execute();
|
|
315
315
|
}
|
|
316
316
|
/**
|
|
317
|
-
* Finished tasks of
|
|
317
|
+
* Finished tasks of a device whose process may still exist (any conversation's: they
|
|
318
318
|
* share the instance).
|
|
319
319
|
*/
|
|
320
|
-
async pendingKills(
|
|
320
|
+
async pendingKills(deviceId) {
|
|
321
321
|
const rows = await this.db
|
|
322
322
|
.selectFrom("background_tasks")
|
|
323
323
|
.selectAll()
|
|
324
|
-
.where("
|
|
324
|
+
.where("device_id", "=", deviceId)
|
|
325
325
|
.where("kill_pending", "=", true)
|
|
326
326
|
.orderBy("started_at", "asc")
|
|
327
327
|
.execute();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConversationAccess } from "../conversations/access.js";
|
|
2
2
|
import { EventLog } from "../conversations/event-log.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ConversationDevices } from "../devices/conversation-devices.js";
|
|
4
4
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
5
5
|
import { SandboxService } from "../sandbox/sandbox.service.js";
|
|
6
6
|
import { BackgroundTaskStopper } from "./stop.js";
|
|
@@ -45,8 +45,8 @@ export declare class BackgroundTasks {
|
|
|
45
45
|
private readonly sandbox;
|
|
46
46
|
private readonly eventLog;
|
|
47
47
|
private readonly db;
|
|
48
|
-
private readonly
|
|
49
|
-
constructor(access: Pick<ConversationAccess, "isAccessible">, store: Pick<BackgroundTaskStore, "listFor" | "get">, stopper: Pick<BackgroundTaskStopper, "stop">, sandbox: Pick<SandboxService, "availableFor" | "ifRunning">, eventLog: Pick<EventLog, "findByIdem">, db: KernelDb,
|
|
48
|
+
private readonly devices;
|
|
49
|
+
constructor(access: Pick<ConversationAccess, "isAccessible">, store: Pick<BackgroundTaskStore, "listFor" | "get">, stopper: Pick<BackgroundTaskStopper, "stop">, sandbox: Pick<SandboxService, "availableFor" | "ifRunning">, eventLog: Pick<EventLog, "findByIdem">, db: KernelDb, devices: Pick<ConversationDevices, "forTool">);
|
|
50
50
|
/**
|
|
51
51
|
* The conversation and every sub-agent conversation below it (grandchildren too: their tasks run
|
|
52
52
|
* in the root's sandbox, agent map spec §6); `conversation.not_found` when not visible.
|
|
@@ -63,12 +63,12 @@ export declare class BackgroundTasks {
|
|
|
63
63
|
*/
|
|
64
64
|
stop(orgId: string, conversationId: string, accountId: string, taskId: string, actorTokenId?: string, auditDetail?: Record<string, unknown>): Promise<BackgroundTaskView>;
|
|
65
65
|
/**
|
|
66
|
-
* Whether the task's
|
|
66
|
+
* Whether the task's device may still be used by its conversation's owner (the access
|
|
67
67
|
* re-check every sandbox tool call makes); when it may not, the live read is skipped.
|
|
68
68
|
*/
|
|
69
|
-
private
|
|
69
|
+
private deviceUsable;
|
|
70
70
|
/**
|
|
71
|
-
* The end of the task's output, at most `tail` bytes. Read live when the task's
|
|
71
|
+
* The end of the task's output, at most `tail` bytes. Read live when the task's device
|
|
72
72
|
* instance runs (never resuming a suspended one); a finished task whose sandbox does not run answers
|
|
73
73
|
* with the last lines its finished event kept. Anything else is
|
|
74
74
|
* `background_task.output_unavailable` (409).
|
|
@@ -12,7 +12,7 @@ import { Inject, Injectable } from "@nestjs/common";
|
|
|
12
12
|
import { ConversationAccess } from "../conversations/access.js";
|
|
13
13
|
import { EventLog } from "../conversations/event-log.js";
|
|
14
14
|
import { conversationTree } from "../conversations/tree.js";
|
|
15
|
-
import {
|
|
15
|
+
import { ConversationDevices } from "../devices/conversation-devices.js";
|
|
16
16
|
import { ApiError } from "../errors.js";
|
|
17
17
|
import { audit } from "../identity/audit.js";
|
|
18
18
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
@@ -44,15 +44,15 @@ let BackgroundTasks = class BackgroundTasks {
|
|
|
44
44
|
sandbox;
|
|
45
45
|
eventLog;
|
|
46
46
|
db;
|
|
47
|
-
|
|
48
|
-
constructor(access, store, stopper, sandbox, eventLog, db,
|
|
47
|
+
devices;
|
|
48
|
+
constructor(access, store, stopper, sandbox, eventLog, db, devices) {
|
|
49
49
|
this.access = access;
|
|
50
50
|
this.store = store;
|
|
51
51
|
this.stopper = stopper;
|
|
52
52
|
this.sandbox = sandbox;
|
|
53
53
|
this.eventLog = eventLog;
|
|
54
54
|
this.db = db;
|
|
55
|
-
this.
|
|
55
|
+
this.devices = devices;
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* The conversation and every sub-agent conversation below it (grandchildren too: their tasks run
|
|
@@ -119,12 +119,12 @@ let BackgroundTasks = class BackgroundTasks {
|
|
|
119
119
|
return this.view(after, conversationId);
|
|
120
120
|
}
|
|
121
121
|
/**
|
|
122
|
-
* Whether the task's
|
|
122
|
+
* Whether the task's device may still be used by its conversation's owner (the access
|
|
123
123
|
* re-check every sandbox tool call makes); when it may not, the live read is skipped.
|
|
124
124
|
*/
|
|
125
|
-
async
|
|
125
|
+
async deviceUsable(orgId, taskConversationId) {
|
|
126
126
|
try {
|
|
127
|
-
await this.
|
|
127
|
+
await this.devices.forTool(orgId, await rootConversationOf(this.db.db, taskConversationId));
|
|
128
128
|
return true;
|
|
129
129
|
}
|
|
130
130
|
catch (e) {
|
|
@@ -134,7 +134,7 @@ let BackgroundTasks = class BackgroundTasks {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
/**
|
|
137
|
-
* The end of the task's output, at most `tail` bytes. Read live when the task's
|
|
137
|
+
* The end of the task's output, at most `tail` bytes. Read live when the task's device
|
|
138
138
|
* instance runs (never resuming a suspended one); a finished task whose sandbox does not run answers
|
|
139
139
|
* with the last lines its finished event kept. Anything else is
|
|
140
140
|
* `background_task.output_unavailable` (409).
|
|
@@ -143,14 +143,14 @@ let BackgroundTasks = class BackgroundTasks {
|
|
|
143
143
|
const task = await this.owned(orgId, conversationId, accountId, taskId);
|
|
144
144
|
if (task.sid !== null &&
|
|
145
145
|
task.sandboxCreatedAt !== null &&
|
|
146
|
-
task.
|
|
147
|
-
(await this.sandbox.availableFor(task.
|
|
148
|
-
(await this.
|
|
146
|
+
task.deviceId !== null &&
|
|
147
|
+
(await this.sandbox.availableFor(task.deviceId)) &&
|
|
148
|
+
(await this.deviceUsable(orgId, task.conversationId))) {
|
|
149
149
|
const createdAt = task.sandboxCreatedAt;
|
|
150
150
|
// the person reading it acts in the task's conversation
|
|
151
151
|
const actor = { accountId, conversationId: task.conversationId };
|
|
152
152
|
try {
|
|
153
|
-
const r = await this.sandbox.ifRunning(task.
|
|
153
|
+
const r = await this.sandbox.ifRunning(task.deviceId, { createdAt }, async (p, h, signal) => {
|
|
154
154
|
const res = await actingAs(p, actor).exec(h, {
|
|
155
155
|
command: tailScript(task.id, tail),
|
|
156
156
|
cwd: rootsOf(h).workspace,
|
|
@@ -185,7 +185,7 @@ BackgroundTasks = __decorate([
|
|
|
185
185
|
__param(3, Inject(SandboxService)),
|
|
186
186
|
__param(4, Inject(EventLog)),
|
|
187
187
|
__param(5, Inject(KernelDb)),
|
|
188
|
-
__param(6, Inject(
|
|
188
|
+
__param(6, Inject(ConversationDevices))
|
|
189
189
|
], BackgroundTasks);
|
|
190
190
|
export { BackgroundTasks };
|
|
191
191
|
/** Prints `size <bytes>` and `out <base64 of the last `tail` bytes>`. Relative to the workspace root. */
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { FastifyReply } from "fastify";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { PluginGuides, type RenderedSetupGuide } from "../extensions/plugin-guides.js";
|
|
3
4
|
import { PluginIcons } from "../extensions/plugin-icons.js";
|
|
4
5
|
import { type Principal } from "../identity/principal.js";
|
|
5
|
-
import { CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogNpmImportBody as NpmBody, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody } from "./admin-catalog.schemas.js";
|
|
6
|
+
import { AdminCatalogGuideQuery, CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogNpmImportBody as NpmBody, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody } from "./admin-catalog.schemas.js";
|
|
6
7
|
import { type CatalogItemDetail, type CatalogItemView, CatalogService, type PermissionsMismatch } from "./catalog.service.js";
|
|
7
8
|
import { CatalogScopeService, type ScopePreview } from "./catalog-scope.service.js";
|
|
8
9
|
import { OrgCatalogService } from "./org-catalog.service.js";
|
|
@@ -38,7 +39,8 @@ export declare class AdminCatalogController {
|
|
|
38
39
|
private readonly scope;
|
|
39
40
|
private readonly updater;
|
|
40
41
|
private readonly icons;
|
|
41
|
-
|
|
42
|
+
private readonly guides;
|
|
43
|
+
constructor(catalog: CatalogService, pluginImport: PluginImport, orgCatalog: OrgCatalogService, scope: CatalogScopeService, updater: PlatformPluginUpdater, icons: PluginIcons, guides: PluginGuides);
|
|
42
44
|
/**
|
|
43
45
|
* Prepares the import of an uploaded plugin (an npm-pack tgz as the raw body,
|
|
44
46
|
* `application/octet-stream`, at most `packages.maxBytes`): reads and checks the whole plugin
|
|
@@ -124,6 +126,15 @@ export declare class AdminCatalogController {
|
|
|
124
126
|
* `sendCatalogIcon`). No icon -> 404 `catalog.icon_not_found`.
|
|
125
127
|
*/
|
|
126
128
|
icon(id: string, reply: FastifyReply): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* A setup guide of the item as the platform sees it (spec 2026-11-09-setup-guides-v2-design.md
|
|
131
|
+
* §9.3; the admin console's connector template page): any live item, the admin audience, no org
|
|
132
|
+
* (`orgName` unresolved, reason `no_org`), no target, no checks run. Unknown item -> 404
|
|
133
|
+
* `catalog.item_not_found`, unknown guide -> 404 `catalog.guide_not_found`.
|
|
134
|
+
*/
|
|
135
|
+
guide(itemId: string, guideId: string, q: z.infer<typeof AdminCatalogGuideQuery>): Promise<{
|
|
136
|
+
guide: RenderedSetupGuide;
|
|
137
|
+
}>;
|
|
127
138
|
/**
|
|
128
139
|
* What a scope change (`{ scope, orgs? }`, `orgs` only with `named`) or a disable
|
|
129
140
|
* (`{ disabled: true }`) would take away: `{ affected: [{ orgId, orgName, agents,
|
|
@@ -10,11 +10,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
10
10
|
import { Controller, Delete, Get, HttpCode, Inject, Param, Post, Put, Req, Res, } from "@nestjs/common";
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { ApiError } from "../errors.js";
|
|
13
|
+
import { PluginGuides } from "../extensions/plugin-guides.js";
|
|
13
14
|
import { PluginIcons } from "../extensions/plugin-icons.js";
|
|
14
15
|
import { CurrentPrincipal, patTokenId, requireUser, SuperAdmin, } from "../identity/principal.js";
|
|
15
16
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
16
17
|
import { ZBody, ZQuery } from "../infra/validation/zod-params.js";
|
|
17
|
-
import { CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogHash as Hash, CatalogNpmImportBody as NpmBody, CatalogScopeOrgs as Orgs, CatalogScope as Scope, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody, } from "./admin-catalog.schemas.js";
|
|
18
|
+
import { AdminCatalogGuideQuery, CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogHash as Hash, CatalogNpmImportBody as NpmBody, CatalogScopeOrgs as Orgs, CatalogScope as Scope, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody, } from "./admin-catalog.schemas.js";
|
|
18
19
|
import { CatalogService, } from "./catalog.service.js";
|
|
19
20
|
import { CatalogScopeService } from "./catalog-scope.service.js";
|
|
20
21
|
import { sendCatalogIcon } from "./org-catalog.controller.js";
|
|
@@ -42,6 +43,8 @@ class CatalogImportConfirmBody extends createZodDto(ConfirmBody, "CatalogImportC
|
|
|
42
43
|
}
|
|
43
44
|
class CatalogGitImportBody extends createZodDto(GitBody, "CatalogGitImportBody") {
|
|
44
45
|
}
|
|
46
|
+
class AdminCatalogGuideQueryDto extends createZodDto(AdminCatalogGuideQuery, "AdminCatalogGuideQuery") {
|
|
47
|
+
}
|
|
45
48
|
class CatalogItemsQueryDto extends createZodDto(CatalogItemsQuery, "CatalogItemsQuery") {
|
|
46
49
|
}
|
|
47
50
|
class CatalogNpmImportBody extends createZodDto(NpmBody, "CatalogNpmImportBody") {
|
|
@@ -75,13 +78,15 @@ let AdminCatalogController = class AdminCatalogController {
|
|
|
75
78
|
scope;
|
|
76
79
|
updater;
|
|
77
80
|
icons;
|
|
78
|
-
|
|
81
|
+
guides;
|
|
82
|
+
constructor(catalog, pluginImport, orgCatalog, scope, updater, icons, guides) {
|
|
79
83
|
this.catalog = catalog;
|
|
80
84
|
this.pluginImport = pluginImport;
|
|
81
85
|
this.orgCatalog = orgCatalog;
|
|
82
86
|
this.scope = scope;
|
|
83
87
|
this.updater = updater;
|
|
84
88
|
this.icons = icons;
|
|
89
|
+
this.guides = guides;
|
|
85
90
|
}
|
|
86
91
|
/**
|
|
87
92
|
* Prepares the import of an uploaded plugin (an npm-pack tgz as the raw body,
|
|
@@ -189,6 +194,15 @@ let AdminCatalogController = class AdminCatalogController {
|
|
|
189
194
|
async icon(id, reply) {
|
|
190
195
|
await sendCatalogIcon(reply, await this.orgCatalog.icon(id, true));
|
|
191
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* A setup guide of the item as the platform sees it (spec 2026-11-09-setup-guides-v2-design.md
|
|
199
|
+
* §9.3; the admin console's connector template page): any live item, the admin audience, no org
|
|
200
|
+
* (`orgName` unresolved, reason `no_org`), no target, no checks run. Unknown item -> 404
|
|
201
|
+
* `catalog.item_not_found`, unknown guide -> 404 `catalog.guide_not_found`.
|
|
202
|
+
*/
|
|
203
|
+
async guide(itemId, guideId, q) {
|
|
204
|
+
return { guide: await this.guides.renderForPlatform(itemId, guideId, q) };
|
|
205
|
+
}
|
|
192
206
|
/**
|
|
193
207
|
* What a scope change (`{ scope, orgs? }`, `orgs` only with `named`) or a disable
|
|
194
208
|
* (`{ disabled: true }`) would take away: `{ affected: [{ orgId, orgName, agents,
|
|
@@ -331,6 +345,12 @@ __decorate([
|
|
|
331
345
|
__param(0, Param("id")),
|
|
332
346
|
__param(1, Res())
|
|
333
347
|
], AdminCatalogController.prototype, "icon", null);
|
|
348
|
+
__decorate([
|
|
349
|
+
Get(":itemId/guides/:guideId"),
|
|
350
|
+
__param(0, Param("itemId")),
|
|
351
|
+
__param(1, Param("guideId")),
|
|
352
|
+
__param(2, ZQuery(AdminCatalogGuideQueryDto))
|
|
353
|
+
], AdminCatalogController.prototype, "guide", null);
|
|
334
354
|
__decorate([
|
|
335
355
|
Post("items/:id/scope/preview"),
|
|
336
356
|
HttpCode(200),
|
|
@@ -395,6 +415,7 @@ AdminCatalogController = __decorate([
|
|
|
395
415
|
__param(2, Inject(OrgCatalogService)),
|
|
396
416
|
__param(3, Inject(CatalogScopeService)),
|
|
397
417
|
__param(4, Inject(PlatformPluginUpdater)),
|
|
398
|
-
__param(5, Inject(PluginIcons))
|
|
418
|
+
__param(5, Inject(PluginIcons)),
|
|
419
|
+
__param(6, Inject(PluginGuides))
|
|
399
420
|
], AdminCatalogController);
|
|
400
421
|
export { AdminCatalogController };
|
|
@@ -69,4 +69,14 @@ export declare const CatalogDisabledBody: z.ZodObject<{
|
|
|
69
69
|
export declare const CatalogShownBody: z.ZodObject<{
|
|
70
70
|
shownToOthers: z.ZodBoolean;
|
|
71
71
|
}, z.core.$strict>;
|
|
72
|
+
/**
|
|
73
|
+
* `GET :itemId/guides/:guideId`, the super admin's preview of a setup guide (spec
|
|
74
|
+
* 2026-11-09-setup-guides-v2-design.md §9.3): only the document language; no org, no target.
|
|
75
|
+
*/
|
|
76
|
+
export declare const AdminCatalogGuideQuery: z.ZodObject<{
|
|
77
|
+
locale: z.ZodOptional<z.ZodEnum<{
|
|
78
|
+
en: "en";
|
|
79
|
+
zh: "zh";
|
|
80
|
+
}>>;
|
|
81
|
+
}, z.core.$strict>;
|
|
72
82
|
export declare const ADMIN_CATALOG_ROUTES: readonly RouteSchemas[];
|
|
@@ -52,6 +52,13 @@ export const CatalogDisabledBody = z
|
|
|
52
52
|
.object({ disabled: z.boolean(), scopeHash: CatalogHash.optional() })
|
|
53
53
|
.strict();
|
|
54
54
|
export const CatalogShownBody = z.object({ shownToOthers: z.boolean() }).strict();
|
|
55
|
+
/**
|
|
56
|
+
* `GET :itemId/guides/:guideId`, the super admin's preview of a setup guide (spec
|
|
57
|
+
* 2026-11-09-setup-guides-v2-design.md §9.3): only the document language; no org, no target.
|
|
58
|
+
*/
|
|
59
|
+
export const AdminCatalogGuideQuery = z
|
|
60
|
+
.object({ locale: z.enum(["en", "zh"]).optional() })
|
|
61
|
+
.strict();
|
|
55
62
|
export const ADMIN_CATALOG_ROUTES = [
|
|
56
63
|
{ route: "GET /api/v1/admin/catalog/items", query: CatalogItemsQuery },
|
|
57
64
|
{ route: "GET /api/v1/admin/catalog/items/:id", params: CatalogIdPathParams },
|
|
@@ -72,6 +72,14 @@ export interface OrgCatalogTemplate {
|
|
|
72
72
|
editableEndpoint: string[];
|
|
73
73
|
auth: Record<string, unknown>;
|
|
74
74
|
ownership: "org" | "personal" | null;
|
|
75
|
+
/**
|
|
76
|
+
* The template's setup guide in the item's latest version (`GET …/catalog/:itemId/guides/
|
|
77
|
+
* :guideId`), null without one (spec 2026-11-09-setup-guides-v2-design.md §9.3).
|
|
78
|
+
*/
|
|
79
|
+
guide: {
|
|
80
|
+
itemId: string;
|
|
81
|
+
guideId: string;
|
|
82
|
+
} | null;
|
|
75
83
|
}
|
|
76
84
|
/** `GET /orgs/:orgId/catalog/:itemId`: the item and what the install wizard needs (latest version). */
|
|
77
85
|
export interface OrgCatalogDetail {
|
|
@@ -105,7 +113,7 @@ export interface OrgCatalogDetail {
|
|
|
105
113
|
* A connector template as an org sees it (the install wizard and the upgrade preview's inputs):
|
|
106
114
|
* presets and editable paths, no credentials.
|
|
107
115
|
*/
|
|
108
|
-
export declare function orgTemplateView(id: string, file: ConnectorTemplateFile): OrgCatalogTemplate;
|
|
116
|
+
export declare function orgTemplateView(id: string, file: ConnectorTemplateFile, guide?: OrgCatalogTemplate["guide"]): OrgCatalogTemplate;
|
|
109
117
|
/** An item's icon (the latest version's plugin icon). */
|
|
110
118
|
export interface CatalogIcon {
|
|
111
119
|
data: Uint8Array;
|
|
@@ -16,7 +16,7 @@ import { satisfiesRange } from "./versions.js";
|
|
|
16
16
|
* A connector template as an org sees it (the install wizard and the upgrade preview's inputs):
|
|
17
17
|
* presets and editable paths, no credentials.
|
|
18
18
|
*/
|
|
19
|
-
export function orgTemplateView(id, file) {
|
|
19
|
+
export function orgTemplateView(id, file, guide = null) {
|
|
20
20
|
const t = file.template;
|
|
21
21
|
return {
|
|
22
22
|
id,
|
|
@@ -29,6 +29,7 @@ export function orgTemplateView(id, file) {
|
|
|
29
29
|
auth: t.auth,
|
|
30
30
|
ownership: t.ownership ??
|
|
31
31
|
(typeof t.auth.ownership === "string" ? t.auth.ownership : null),
|
|
32
|
+
guide,
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
35
|
const iconNotFound = () => new ApiError("catalog.icon_not_found", "This catalog item has no icon");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type PluginManifest } from "@capybara-hq/plugin-sdk";
|
|
2
2
|
import type { KernelSchemaDb } from "../db/kernel-schema.js";
|
|
3
3
|
type Db = Pick<KernelSchemaDb, "selectFrom" | "insertInto" | "deleteFrom">;
|
|
4
4
|
/** A stored file as a version row lists it. */
|
|
@@ -9,7 +9,8 @@ interface FileMeta {
|
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* The display file paths of a plugin (package paths): the plugin icon, the connector templates'
|
|
12
|
-
* icons (given by the caller, which parsed the templates) and the setup guide
|
|
12
|
+
* icons (given by the caller, which parsed the templates) and the setup guide documents (both
|
|
13
|
+
* languages; the caller keeps the ones the package has).
|
|
13
14
|
*/
|
|
14
15
|
export declare function displayFilePaths(m: PluginManifest, templateIcons?: string[]): Set<string>;
|
|
15
16
|
/**
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
// Catalog display files in PG (`catalog_files`, migration 0100): a plugin's icon, its connector
|
|
2
|
-
// templates' icons and its setup guide
|
|
2
|
+
// templates' icons and its setup guide documents. They are small (64 KiB each at most, by the plugin
|
|
3
3
|
// format) and must be readable without object storage: a bootstrap plugin is imported before any
|
|
4
4
|
// object-store extension runs, and the object-store plugin's own icon can never wait for itself.
|
|
5
5
|
// Skills, connector templates and agent templates stay in object storage under the version's
|
|
6
6
|
// `object_prefix` (they are copied into platform components there).
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
|
+
import { setupGuideDocPath } from "@capybara-hq/plugin-sdk";
|
|
8
9
|
import { sql } from "kysely";
|
|
9
10
|
import { ApiError } from "../errors.js";
|
|
10
11
|
import { packagePath } from "../packages/tgz.js";
|
|
11
12
|
/**
|
|
12
13
|
* The display file paths of a plugin (package paths): the plugin icon, the connector templates'
|
|
13
|
-
* icons (given by the caller, which parsed the templates) and the setup guide
|
|
14
|
+
* icons (given by the caller, which parsed the templates) and the setup guide documents (both
|
|
15
|
+
* languages; the caller keeps the ones the package has).
|
|
14
16
|
*/
|
|
15
17
|
export function displayFilePaths(m, templateIcons = []) {
|
|
16
18
|
const out = new Set();
|
|
@@ -18,9 +20,10 @@ export function displayFilePaths(m, templateIcons = []) {
|
|
|
18
20
|
out.add(packagePath(m.icon));
|
|
19
21
|
for (const icon of templateIcons)
|
|
20
22
|
out.add(packagePath(icon));
|
|
21
|
-
for (const g of m.setupGuides ?? [])
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
for (const g of m.setupGuides ?? []) {
|
|
24
|
+
out.add(setupGuideDocPath(g.id, "en"));
|
|
25
|
+
out.add(setupGuideDocPath(g.id, "zh"));
|
|
26
|
+
}
|
|
24
27
|
return out;
|
|
25
28
|
}
|
|
26
29
|
/**
|