@capybara-hq/kernel 0.1.0-rc.11 → 0.1.0-rc.13
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/agents/agents.schemas.d.ts +3 -0
- package/dist/agents/agents.service.js +11 -1
- package/dist/agents/definition.d.ts +1 -0
- package/dist/agents/definition.js +7 -3
- package/dist/agents/org-templates.js +4 -0
- package/dist/agents/pending-connectors.service.js +1 -1
- 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/component-scope.controller.d.ts +18 -6
- package/dist/catalog/component-scope.controller.js +36 -13
- package/dist/catalog/component-scope.service.d.ts +11 -0
- package/dist/catalog/component-scope.service.js +4 -0
- package/dist/catalog/component-state.d.ts +8 -0
- package/dist/catalog/component-state.js +19 -11
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/plugin-import.js +4 -1
- package/dist/channels/channels.module.js +2 -2
- 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/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 +23 -14
- package/dist/conversations/conversations.service.js +28 -21
- 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 +2 -1
- package/dist/conversations/events.js +2 -2
- package/dist/ctx/create-ctx.d.ts +10 -1
- package/dist/ctx/create-ctx.js +86 -25
- package/dist/db/kernel-schema.d.ts +39 -23
- 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 +27 -25
- package/dist/errors.js +27 -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/host.d.ts +13 -2
- package/dist/extensions/host.js +24 -3
- package/dist/extensions/instance.d.ts +12 -1
- package/dist/extensions/instance.js +13 -0
- package/dist/extensions/permission-view.d.ts +10 -1
- package/dist/files/previewers.d.ts +1 -1
- package/dist/files/previewers.js +1 -1
- package/dist/http/api.module.js +10 -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/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/platform/exclusions.js +48 -3
- package/dist/platform/operation.js +6 -2
- package/dist/platform/ops/admin.ops.js +8 -2
- package/dist/platform/ops/agents.ops.js +19 -6
- 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/ui.ops.d.ts +8 -0
- package/dist/platform/ops/ui.ops.js +41 -0
- package/dist/platform/platform-ops.module.d.ts +3 -2
- package/dist/platform/platform-ops.module.js +8 -5
- package/dist/platform/route-schemas.js +6 -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/runtime/subagents/definition.d.ts +3 -2
- package/dist/runtime/subagents/definition.js +2 -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/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/connector-account-policies.d.ts +51 -0
- package/dist/tools/connector-account-policies.js +165 -0
- package/dist/tools/connectors.controller.d.ts +35 -4
- package/dist/tools/connectors.controller.js +66 -7
- package/dist/tools/connectors.schemas.d.ts +11 -0
- package/dist/tools/connectors.schemas.js +11 -0
- package/dist/tools/connectors.service.d.ts +2 -0
- package/dist/tools/connectors.service.js +1 -0
- package/dist/tools/pipeline.d.ts +1 -1
- package/dist/tools/pipeline.js +4 -3
- package/dist/tools/policy.d.ts +23 -1
- package/dist/tools/policy.js +99 -24
- package/dist/tools/registry.d.ts +2 -2
- package/dist/tools/tools.module.js +6 -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/0104_connector_tool_account_policies.sql +16 -0
- package/src/migrations/0105_devices_rename.sql +136 -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
|
@@ -9,6 +9,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
9
9
|
};
|
|
10
10
|
import { Controller, Get, HttpCode, Inject, Post, Put, Req } from "@nestjs/common";
|
|
11
11
|
import { ApiError } from "../errors.js";
|
|
12
|
+
import { orgIconScope, PluginIcons } from "../extensions/plugin-icons.js";
|
|
12
13
|
import { CurrentPrincipal, patTokenId, requireUser, SuperAdmin, } from "../identity/principal.js";
|
|
13
14
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
14
15
|
import { ZBody, ZParam, ZQuery } from "../infra/validation/zod-params.js";
|
|
@@ -36,6 +37,16 @@ class ComponentShownBody extends createZodDto(ShownBody, "ComponentShownBody") {
|
|
|
36
37
|
}
|
|
37
38
|
class ComponentSwitchBody extends createZodDto(SwitchBody, "ComponentSwitchBody") {
|
|
38
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Each component with `icon`: its plugin's icon URL on the reader's route (null without one, for
|
|
42
|
+
* a component without a plugin, or when the reader may not see the plugin; maintainer decision
|
|
43
|
+
* 2026-11-09: a connector template without an icon of its own shows its plugin's).
|
|
44
|
+
*/
|
|
45
|
+
async function withIcons(icons, rows, scope) {
|
|
46
|
+
const ids = rows.flatMap((r) => (r.itemId === null ? [] : [r.itemId]));
|
|
47
|
+
const urls = await icons.ofItems(ids, scope);
|
|
48
|
+
return rows.map((r) => ({ ...r, icon: r.itemId === null ? null : (urls.get(r.itemId) ?? null) }));
|
|
49
|
+
}
|
|
39
50
|
const actorOpts = (actor) => {
|
|
40
51
|
const tokenId = patTokenId(actor);
|
|
41
52
|
return tokenId !== undefined ? { actorTokenId: tokenId } : {};
|
|
@@ -49,9 +60,11 @@ const actorOpts = (actor) => {
|
|
|
49
60
|
let AdminComponentsController = class AdminComponentsController {
|
|
50
61
|
scope;
|
|
51
62
|
components;
|
|
52
|
-
|
|
63
|
+
icons;
|
|
64
|
+
constructor(scope, components, icons) {
|
|
53
65
|
this.scope = scope;
|
|
54
66
|
this.components = components;
|
|
67
|
+
this.icons = icons;
|
|
55
68
|
}
|
|
56
69
|
/**
|
|
57
70
|
* Updates a platform skill on its own (spec §7.2): the skill package (zip) as the raw body
|
|
@@ -73,9 +86,14 @@ let AdminComponentsController = class AdminComponentsController {
|
|
|
73
86
|
const actor = requireUser(principal);
|
|
74
87
|
return this.components.uploadAgentTemplateVersion({ accountId: actor.account.id, ...actorOpts(actor) }, p.id, body.content);
|
|
75
88
|
}
|
|
76
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* `GET ?kind=`: every platform component of the kind (plugin, owner, scope, version, orgs on),
|
|
91
|
+
* each with its display name and its plugin's icon (`icon`, the admin route; null without one).
|
|
92
|
+
*/
|
|
77
93
|
async list(q) {
|
|
78
|
-
return {
|
|
94
|
+
return {
|
|
95
|
+
components: await withIcons(this.icons, await this.scope.list(q.kind), { kind: "admin" }),
|
|
96
|
+
};
|
|
79
97
|
}
|
|
80
98
|
/**
|
|
81
99
|
* A component's versions, newest first: `{ versions: [{ version, catalogVersion, updatedOnOwn,
|
|
@@ -178,7 +196,8 @@ AdminComponentsController = __decorate([
|
|
|
178
196
|
Controller("api/v1/admin/components"),
|
|
179
197
|
SuperAdmin(),
|
|
180
198
|
__param(0, Inject(ComponentScopeService)),
|
|
181
|
-
__param(1, Inject(PlatformComponents))
|
|
199
|
+
__param(1, Inject(PlatformComponents)),
|
|
200
|
+
__param(2, Inject(PluginIcons))
|
|
182
201
|
], AdminComponentsController);
|
|
183
202
|
export { AdminComponentsController };
|
|
184
203
|
/**
|
|
@@ -189,21 +208,24 @@ export { AdminComponentsController };
|
|
|
189
208
|
*/
|
|
190
209
|
let OrgComponentsController = class OrgComponentsController {
|
|
191
210
|
scope;
|
|
192
|
-
|
|
211
|
+
icons;
|
|
212
|
+
constructor(scope, icons) {
|
|
193
213
|
this.scope = scope;
|
|
214
|
+
this.icons = icons;
|
|
194
215
|
}
|
|
195
216
|
/**
|
|
196
217
|
* The platform components offered to the org (`?kind=`, `?itemId=`: only those; Task 10): each
|
|
197
218
|
* with its state in the org (`on`, `locked` for `all`, the org's `switch`) and whether an org
|
|
198
|
-
* admin may switch it. Members read it (the workspace pages are read-only for them).
|
|
219
|
+
* admin may switch it. Members read it (the workspace pages are read-only for them). Each has
|
|
220
|
+
* its display name and `icon`, its plugin's icon on the org's catalog route (null without one,
|
|
221
|
+
* or when the org's catalog does not show the plugin to the reader: the share gate holds).
|
|
199
222
|
*/
|
|
200
223
|
async list(org, q) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
};
|
|
224
|
+
const rows = await this.scope.orgList(org.orgId, {
|
|
225
|
+
...(q.kind !== undefined && { kind: q.kind }),
|
|
226
|
+
...(q.itemId !== undefined && { itemId: q.itemId }),
|
|
227
|
+
});
|
|
228
|
+
return { components: await withIcons(this.icons, rows, orgIconScope(org)) };
|
|
207
229
|
}
|
|
208
230
|
async setSwitch(principal, org, p, body) {
|
|
209
231
|
const actor = requireUser(principal);
|
|
@@ -229,6 +251,7 @@ __decorate([
|
|
|
229
251
|
], OrgComponentsController.prototype, "setSwitch", null);
|
|
230
252
|
OrgComponentsController = __decorate([
|
|
231
253
|
Controller("api/v1/orgs/:orgId/components"),
|
|
232
|
-
__param(0, Inject(ComponentScopeService))
|
|
254
|
+
__param(0, Inject(ComponentScopeService)),
|
|
255
|
+
__param(1, Inject(PluginIcons))
|
|
233
256
|
], OrgComponentsController);
|
|
234
257
|
export { OrgComponentsController };
|
|
@@ -68,7 +68,13 @@ export type ComponentTarget = {
|
|
|
68
68
|
export interface ComponentView {
|
|
69
69
|
kind: ComponentKind;
|
|
70
70
|
id: string;
|
|
71
|
+
/** Skill or template name; a connector template's id (the file's base name). */
|
|
71
72
|
name: string;
|
|
73
|
+
/** A connector template's localized display name (null: show `name`). */
|
|
74
|
+
displayName: {
|
|
75
|
+
zh: string;
|
|
76
|
+
en: string;
|
|
77
|
+
} | null;
|
|
72
78
|
description: string | null;
|
|
73
79
|
/** The plugin it came from (null: none). */
|
|
74
80
|
plugin: string | null;
|
|
@@ -138,6 +144,11 @@ export interface OrgComponentView {
|
|
|
138
144
|
* show with their switches. Never a component the org cannot see.
|
|
139
145
|
*/
|
|
140
146
|
export interface OrgOfferedComponentView extends OrgComponentView {
|
|
147
|
+
/** A connector template's localized display name (null: show `name`). */
|
|
148
|
+
displayName: {
|
|
149
|
+
zh: string;
|
|
150
|
+
en: string;
|
|
151
|
+
} | null;
|
|
141
152
|
description: string | null;
|
|
142
153
|
itemId: string | null;
|
|
143
154
|
version: string;
|
|
@@ -204,6 +204,7 @@ let ComponentScopeService = class ComponentScopeService {
|
|
|
204
204
|
kind,
|
|
205
205
|
id: c.id,
|
|
206
206
|
name: c.name,
|
|
207
|
+
displayName: c.displayName,
|
|
207
208
|
description: c.description,
|
|
208
209
|
plugin: c.plugin,
|
|
209
210
|
itemId: c.itemId,
|
|
@@ -258,6 +259,7 @@ let ComponentScopeService = class ComponentScopeService {
|
|
|
258
259
|
kind,
|
|
259
260
|
id: c.id,
|
|
260
261
|
name: c.name,
|
|
262
|
+
displayName: c.displayName,
|
|
261
263
|
description: c.description,
|
|
262
264
|
plugin: c.plugin,
|
|
263
265
|
itemId: c.itemId,
|
|
@@ -360,6 +362,7 @@ let ComponentScopeService = class ComponentScopeService {
|
|
|
360
362
|
kind,
|
|
361
363
|
id: r.id,
|
|
362
364
|
name: r.name,
|
|
365
|
+
displayName: null,
|
|
363
366
|
description: r.description,
|
|
364
367
|
plugin: r.plugin,
|
|
365
368
|
itemId: r.catalog_item_id,
|
|
@@ -1084,6 +1087,7 @@ const virtualOf = (o) => ({
|
|
|
1084
1087
|
plugin: o.plugin,
|
|
1085
1088
|
version: String(o.version),
|
|
1086
1089
|
description: null,
|
|
1090
|
+
displayName: null,
|
|
1087
1091
|
itemId: null,
|
|
1088
1092
|
scopeMode: "own",
|
|
1089
1093
|
scope: "named",
|
|
@@ -68,6 +68,14 @@ export interface ComponentRow extends ComponentScopeFacts {
|
|
|
68
68
|
/** The current version (a connector template: the catalog version that last changed it). */
|
|
69
69
|
version: string;
|
|
70
70
|
description: string | null;
|
|
71
|
+
/**
|
|
72
|
+
* A connector template's localized display name (its file's `displayName`); null for skills and
|
|
73
|
+
* agent templates, whose name is what they are shown by.
|
|
74
|
+
*/
|
|
75
|
+
displayName: {
|
|
76
|
+
zh: string;
|
|
77
|
+
en: string;
|
|
78
|
+
} | null;
|
|
71
79
|
shownToOthers: boolean;
|
|
72
80
|
/** The owning org (null: the platform; ruling P3-1). */
|
|
73
81
|
ownerOrgId: string | null;
|
|
@@ -63,6 +63,11 @@ export function componentOffered(c, p, listed) {
|
|
|
63
63
|
export function componentLocked(_c, p) {
|
|
64
64
|
return p?.builtin === true;
|
|
65
65
|
}
|
|
66
|
+
/** A `{ zh, en }` display name from stored JSON (a template file's), else null. */
|
|
67
|
+
function localizedName(v) {
|
|
68
|
+
const n = v;
|
|
69
|
+
return typeof n?.zh === "string" && typeof n.en === "string" ? { zh: n.zh, en: n.en } : null;
|
|
70
|
+
}
|
|
66
71
|
/** The live platform components of `kind` (`ids` / `itemId`: only those). */
|
|
67
72
|
export async function loadComponents(db, kind, filter = {}) {
|
|
68
73
|
if (filter.ids !== undefined && filter.ids.length === 0)
|
|
@@ -105,17 +110,19 @@ export async function loadComponents(db, kind, filter = {}) {
|
|
|
105
110
|
q = q.where("p.template_id", "=", filter.name);
|
|
106
111
|
if (filter.forUpdate)
|
|
107
112
|
q = q.forUpdate("p");
|
|
108
|
-
return (await q.orderBy("p.id").execute()).map((r) =>
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
return (await q.orderBy("p.id").execute()).map((r) => {
|
|
114
|
+
const file = r.file;
|
|
115
|
+
return {
|
|
116
|
+
...common(r),
|
|
117
|
+
...(file?.defaultEnabled === false && { defaultOff: true }),
|
|
118
|
+
name: r.template_id,
|
|
119
|
+
plugin: r.item_name,
|
|
120
|
+
version: r.current_version,
|
|
121
|
+
description: typeof file?.description === "string" ? file.description : null,
|
|
122
|
+
displayName: localizedName(file?.displayName),
|
|
123
|
+
originOrgId: null,
|
|
124
|
+
};
|
|
125
|
+
});
|
|
119
126
|
}
|
|
120
127
|
const table = kind === "skill"
|
|
121
128
|
? "platform_skills"
|
|
@@ -154,6 +161,7 @@ export async function loadComponents(db, kind, filter = {}) {
|
|
|
154
161
|
plugin: r.plugin_name,
|
|
155
162
|
version: String(r.current_version),
|
|
156
163
|
description: r.description,
|
|
164
|
+
displayName: null,
|
|
157
165
|
originOrgId: r.origin_org_id,
|
|
158
166
|
}));
|
|
159
167
|
}
|
|
@@ -188,7 +188,7 @@ export declare function headsToResolve(entries: readonly MarketplaceEntry[], imp
|
|
|
188
188
|
/** The host versions (an entry's `minKernel` is judged against them). */
|
|
189
189
|
export declare const HOST_VERSIONS: {
|
|
190
190
|
readonly kernel: string;
|
|
191
|
-
readonly sdk: "0.1.0-rc.
|
|
191
|
+
readonly sdk: "0.1.0-rc.9";
|
|
192
192
|
};
|
|
193
193
|
/** Whether this deployment satisfies the entry's `minKernel`. */
|
|
194
194
|
export declare const entryCompatible: (e: Pick<MarketplaceEntry, "minKernel">) => boolean;
|
|
@@ -1714,7 +1714,10 @@ function actionOf(s, sha256, version) {
|
|
|
1714
1714
|
export function pluginReviewHash(r, files) {
|
|
1715
1715
|
const e = r.extension;
|
|
1716
1716
|
const lic = r.licenseText;
|
|
1717
|
-
|
|
1717
|
+
// canonicalJson, not JSON.stringify: the review is stored as jsonb, which reorders object keys,
|
|
1718
|
+
// so a template's auth / endpoint object would hash differently at confirm (plugin.review_stale
|
|
1719
|
+
// on every import of a plugin whose connector template has a non-trivial auth block).
|
|
1720
|
+
const canonical = canonicalJson([
|
|
1718
1721
|
r.name,
|
|
1719
1722
|
r.version,
|
|
1720
1723
|
r.contentDigest,
|
|
@@ -12,7 +12,7 @@ import { OnWorkerEvent, WorkerHost } from "@nestjs/bullmq";
|
|
|
12
12
|
import { Inject, Injectable, Module } from "@nestjs/common";
|
|
13
13
|
import { ConversationsModule } from "../conversations/conversations.module.js";
|
|
14
14
|
import { EventLogModule } from "../conversations/event-log.js";
|
|
15
|
-
import {
|
|
15
|
+
import { DevicesModule } from "../devices/devices.module.js";
|
|
16
16
|
import { ExtensionsModule } from "../extensions/extensions.module.js";
|
|
17
17
|
import { IdentityModule } from "../identity/identity.module.js";
|
|
18
18
|
import { configuredProcessor, } from "../infra/queue/configured-processor.js";
|
|
@@ -39,7 +39,7 @@ let ChannelsModule = class ChannelsModule {
|
|
|
39
39
|
ChannelsModule = __decorate([
|
|
40
40
|
Module({
|
|
41
41
|
imports: [
|
|
42
|
-
|
|
42
|
+
DevicesModule,
|
|
43
43
|
EventLogModule,
|
|
44
44
|
ExtensionsModule,
|
|
45
45
|
IdentityModule,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ChannelCard, InboundEvent, InboundSender, Logger } from "@capybara-hq/plugin-sdk";
|
|
2
2
|
import type { Redis } from "ioredis";
|
|
3
3
|
import { ConversationsService } from "../conversations/conversations.service.js";
|
|
4
|
-
import {
|
|
4
|
+
import { DevicesService } from "../devices/devices.service.js";
|
|
5
5
|
import { IdentityBinding } from "../identity/binding.js";
|
|
6
6
|
import { ExternalIdentities } from "../identity/external.js";
|
|
7
7
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
@@ -63,7 +63,7 @@ export declare class ChannelInbound {
|
|
|
63
63
|
/** The channel queue: inbound jobs (`onEvent` only dedupes and enqueues) and deliveries. */
|
|
64
64
|
private readonly jobs;
|
|
65
65
|
private readonly guests;
|
|
66
|
-
private readonly
|
|
66
|
+
private readonly devices;
|
|
67
67
|
private readonly log;
|
|
68
68
|
private readonly actions;
|
|
69
69
|
constructor(kdb: KernelDb, redis: Pick<Redis, "set">,
|
|
@@ -74,7 +74,7 @@ export declare class ChannelInbound {
|
|
|
74
74
|
/** The channel queue: inbound jobs (`onEvent` only dedupes and enqueues) and deliveries. */
|
|
75
75
|
jobs: Pick<ChannelJobs, "enqueue" | "enqueueInbound">,
|
|
76
76
|
/** 卡片操作:审批决定与提问回答(授权由这两个服务按点击者映射到的账号判定)。 */
|
|
77
|
-
approvals: Pick<ApprovalsService, "decide">, questions: Pick<QuestionsService, "answer">, guests: Pick<AnonymousGuests, "ensure">,
|
|
77
|
+
approvals: Pick<ApprovalsService, "decide">, questions: Pick<QuestionsService, "answer">, guests: Pick<AnonymousGuests, "ensure">, devices: Pick<DevicesService, "list" | "imDefault" | "setImDefault">, log: Pick<Logger, "warn" | "info">);
|
|
78
78
|
/**
|
|
79
79
|
* 插件 `onEvent`:去重并入队后返回(见类注释)。返回后插件才向平台确认;抛错时插件不确认。
|
|
80
80
|
*/
|
|
@@ -95,13 +95,13 @@ export declare class ChannelInbound {
|
|
|
95
95
|
handle(connectionId: string, e: InboundEvent): Promise<void>;
|
|
96
96
|
private message;
|
|
97
97
|
/**
|
|
98
|
-
* Direct-message `/
|
|
98
|
+
* Direct-message `/device` (environments spec §4.2 item 8): lists the person's usable devices,
|
|
99
99
|
* or with a name sets the IM default their next new conversation is bound to. The name matches
|
|
100
|
-
* case-insensitively against each label (`
|
|
101
|
-
* provider switch answers to e.g. "Personal (Docker sandbox)"); the default
|
|
102
|
-
* answers to
|
|
100
|
+
* case-insensitively against each label (`deviceLabel`: a former default demoted by a
|
|
101
|
+
* provider switch answers to e.g. "Personal (Docker sandbox)"); the default device also
|
|
102
|
+
* answers to 个人设备 / Personal.
|
|
103
103
|
*/
|
|
104
|
-
private
|
|
104
|
+
private deviceCommand;
|
|
105
105
|
/**
|
|
106
106
|
* Posts the person's message: `/name args` as a skill invocation when the kernel accepts it, else
|
|
107
107
|
* as typed (phase D spec §9). A retry of the job finds the first write by `clientMessageId`
|
package/dist/channels/inbound.js
CHANGED
|
@@ -11,8 +11,8 @@ import { randomUUID } from "node:crypto";
|
|
|
11
11
|
import { Inject, Injectable } from "@nestjs/common";
|
|
12
12
|
import { ConversationsService } from "../conversations/conversations.service.js";
|
|
13
13
|
import { imSenderContext, recipientLocale, } from "../conversations/message-context.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
14
|
+
import { DevicesService } from "../devices/devices.service.js";
|
|
15
|
+
import { DEFAULT_DEVICE_ALIASES, deviceLabel } from "../devices/label.js";
|
|
16
16
|
import { ApiError } from "../errors.js";
|
|
17
17
|
import { IdentityBinding } from "../identity/binding.js";
|
|
18
18
|
import { ExternalIdentities } from "../identity/external.js";
|
|
@@ -75,7 +75,7 @@ let ChannelInbound = class ChannelInbound {
|
|
|
75
75
|
directorySync;
|
|
76
76
|
jobs;
|
|
77
77
|
guests;
|
|
78
|
-
|
|
78
|
+
devices;
|
|
79
79
|
log;
|
|
80
80
|
actions;
|
|
81
81
|
constructor(kdb, redis,
|
|
@@ -86,7 +86,7 @@ let ChannelInbound = class ChannelInbound {
|
|
|
86
86
|
/** The channel queue: inbound jobs (`onEvent` only dedupes and enqueues) and deliveries. */
|
|
87
87
|
jobs,
|
|
88
88
|
/** 卡片操作:审批决定与提问回答(授权由这两个服务按点击者映射到的账号判定)。 */
|
|
89
|
-
approvals, questions, guests,
|
|
89
|
+
approvals, questions, guests, devices, log) {
|
|
90
90
|
this.kdb = kdb;
|
|
91
91
|
this.redis = redis;
|
|
92
92
|
this.locks = locks;
|
|
@@ -97,7 +97,7 @@ let ChannelInbound = class ChannelInbound {
|
|
|
97
97
|
this.directorySync = directorySync;
|
|
98
98
|
this.jobs = jobs;
|
|
99
99
|
this.guests = guests;
|
|
100
|
-
this.
|
|
100
|
+
this.devices = devices;
|
|
101
101
|
this.log = log;
|
|
102
102
|
this.actions = new ChannelCardActions({
|
|
103
103
|
get db() {
|
|
@@ -216,16 +216,16 @@ let ChannelInbound = class ChannelInbound {
|
|
|
216
216
|
await reply("newConversation");
|
|
217
217
|
return;
|
|
218
218
|
}
|
|
219
|
-
const
|
|
220
|
-
if (
|
|
221
|
-
await this.
|
|
219
|
+
const deviceCommand = !isGroup && threadAccount !== null ? parseDeviceCommand(e.text) : null;
|
|
220
|
+
if (deviceCommand !== null) {
|
|
221
|
+
await this.deviceCommand(row.orgId, accountId, deviceCommand.name, locale, replyText);
|
|
222
222
|
return;
|
|
223
223
|
}
|
|
224
224
|
let conversationId = await findThread(db, k);
|
|
225
225
|
if (conversationId === undefined) {
|
|
226
226
|
let created;
|
|
227
227
|
try {
|
|
228
|
-
// bound to the person's IM default
|
|
228
|
+
// bound to the person's IM default device, else their default (environments spec
|
|
229
229
|
// §4.2 item 8); an anonymous sender's stays unbound (no sandbox)
|
|
230
230
|
created = (await this.conversations.create(row.orgId, accountId, row.agentId, { im: true }))
|
|
231
231
|
.id;
|
|
@@ -294,49 +294,49 @@ let ChannelInbound = class ChannelInbound {
|
|
|
294
294
|
await this.jobs.enqueue(conversationId);
|
|
295
295
|
}
|
|
296
296
|
/**
|
|
297
|
-
* Direct-message `/
|
|
297
|
+
* Direct-message `/device` (environments spec §4.2 item 8): lists the person's usable devices,
|
|
298
298
|
* or with a name sets the IM default their next new conversation is bound to. The name matches
|
|
299
|
-
* case-insensitively against each label (`
|
|
300
|
-
* provider switch answers to e.g. "Personal (Docker sandbox)"); the default
|
|
301
|
-
* answers to
|
|
299
|
+
* case-insensitively against each label (`deviceLabel`: a former default demoted by a
|
|
300
|
+
* provider switch answers to e.g. "Personal (Docker sandbox)"); the default device also
|
|
301
|
+
* answers to 个人设备 / Personal.
|
|
302
302
|
*/
|
|
303
|
-
async
|
|
304
|
-
const { items, defaultId } = await this.
|
|
303
|
+
async deviceCommand(orgId, accountId, name, locale, replyText) {
|
|
304
|
+
const { items, defaultId } = await this.devices.list(orgId, accountId);
|
|
305
305
|
const usable = items.filter((v) => v.available);
|
|
306
|
-
const labelOf = (v) =>
|
|
307
|
-
const current = (await this.
|
|
306
|
+
const labelOf = (v) => deviceLabel(v, locale);
|
|
307
|
+
const current = (await this.devices.imDefault(orgId, accountId)) ?? defaultId;
|
|
308
308
|
const list = usable
|
|
309
|
-
.map((v) => `- ${labelOf(v)}${v.id === current ? phrase("
|
|
309
|
+
.map((v) => `- ${labelOf(v)}${v.id === current ? phrase("deviceCurrent", locale) : ""}`)
|
|
310
310
|
.join("\n");
|
|
311
311
|
const fill = (key, vars) => phrase(key, locale).replace(/\{(\w+)\}/g, (m, k) => vars[k] ?? m);
|
|
312
312
|
if (usable.length === 0)
|
|
313
|
-
return replyText(phrase("
|
|
313
|
+
return replyText(phrase("deviceNone", locale));
|
|
314
314
|
if (name === null)
|
|
315
|
-
return replyText(fill("
|
|
315
|
+
return replyText(fill("deviceList", { list }));
|
|
316
316
|
const wanted = name.toLowerCase();
|
|
317
317
|
const is = (v) => labelOf(v).toLowerCase() === wanted;
|
|
318
318
|
// a name the person gave wins over a generated label, and both over the default's aliases
|
|
319
319
|
const hit = usable.find((v) => v.name !== null && is(v)) ??
|
|
320
320
|
usable.find(is) ??
|
|
321
|
-
usable.find((v) => v.isDefault &&
|
|
321
|
+
usable.find((v) => v.isDefault && DEFAULT_DEVICE_ALIASES.includes(wanted));
|
|
322
322
|
if (hit === undefined) {
|
|
323
323
|
const unavailable = items.find((v) => !v.available && is(v));
|
|
324
324
|
if (unavailable !== undefined) {
|
|
325
|
-
return replyText(fill("
|
|
325
|
+
return replyText(fill("deviceUnavailable", { name: labelOf(unavailable), list }));
|
|
326
326
|
}
|
|
327
|
-
return replyText(fill("
|
|
327
|
+
return replyText(fill("deviceUnknown", { name, list }));
|
|
328
328
|
}
|
|
329
329
|
try {
|
|
330
|
-
await this.
|
|
330
|
+
await this.devices.setImDefault(orgId, accountId, hit.id);
|
|
331
331
|
}
|
|
332
332
|
catch (err) {
|
|
333
333
|
// deleted or made unusable since the list was read
|
|
334
|
-
if (err instanceof ApiError && err.code.startsWith("
|
|
335
|
-
return replyText(fill("
|
|
334
|
+
if (err instanceof ApiError && err.code.startsWith("device.")) {
|
|
335
|
+
return replyText(fill("deviceUnknown", { name, list }));
|
|
336
336
|
}
|
|
337
337
|
throw err;
|
|
338
338
|
}
|
|
339
|
-
return replyText(fill("
|
|
339
|
+
return replyText(fill("deviceSwitched", { name: labelOf(hit) }));
|
|
340
340
|
}
|
|
341
341
|
/**
|
|
342
342
|
* Posts the person's message: `/name args` as a skill invocation when the kernel accepts it, else
|
|
@@ -464,13 +464,13 @@ ChannelInbound = __decorate([
|
|
|
464
464
|
__param(9, Inject(ApprovalsService)),
|
|
465
465
|
__param(10, Inject(QuestionsService)),
|
|
466
466
|
__param(11, Inject(AnonymousGuests)),
|
|
467
|
-
__param(12, Inject(
|
|
467
|
+
__param(12, Inject(DevicesService)),
|
|
468
468
|
__param(13, Inject(KERNEL_LOGGER))
|
|
469
469
|
], ChannelInbound);
|
|
470
470
|
export { ChannelInbound };
|
|
471
|
-
/** `/
|
|
472
|
-
function
|
|
473
|
-
const m = /^\/
|
|
471
|
+
/** `/device` or `/device <name>` (the exact command word, case-insensitive); anything else is null. */
|
|
472
|
+
function parseDeviceCommand(text) {
|
|
473
|
+
const m = /^\/device(?:\s+([\s\S]*))?$/i.exec(text.trim());
|
|
474
474
|
if (m === null)
|
|
475
475
|
return null;
|
|
476
476
|
const name = m[1]?.trim();
|
|
@@ -11,33 +11,33 @@ export declare const CHANNEL_PHRASES: {
|
|
|
11
11
|
readonly zh: "已开始新对话";
|
|
12
12
|
readonly en: "Started a new conversation.";
|
|
13
13
|
};
|
|
14
|
-
/**
|
|
15
|
-
readonly
|
|
16
|
-
readonly zh: "
|
|
17
|
-
readonly en: "Your
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
readonly
|
|
21
|
-
readonly zh: "
|
|
22
|
-
readonly en: "Your next new conversation will use the
|
|
23
|
-
};
|
|
24
|
-
/**
|
|
25
|
-
readonly
|
|
26
|
-
readonly zh: "没有找到名为「{name}
|
|
27
|
-
readonly en: "No
|
|
28
|
-
};
|
|
29
|
-
/** `/
|
|
30
|
-
readonly
|
|
31
|
-
readonly zh: "
|
|
32
|
-
readonly en: "The
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
readonly
|
|
36
|
-
readonly zh: "
|
|
37
|
-
readonly en: "You have no usable
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
readonly
|
|
14
|
+
/** Direct message `/device`: lists the usable devices (`{list}` one per line, the current one marked). */
|
|
15
|
+
readonly deviceList: {
|
|
16
|
+
readonly zh: "你的设备:\n{list}\n发送 /device <名称> 选择下一个新对话使用的设备。";
|
|
17
|
+
readonly en: "Your devices:\n{list}\nSend /device <name> to choose the one your next new conversation uses.";
|
|
18
|
+
};
|
|
19
|
+
/** After a direct message `/device <name>` (`{name}` is the device's name). */
|
|
20
|
+
readonly deviceSwitched: {
|
|
21
|
+
readonly zh: "下一个新对话将使用设备「{name}」,发送 /new 开始。";
|
|
22
|
+
readonly en: "Your next new conversation will use the device “{name}”; send /new to start one.";
|
|
23
|
+
};
|
|
24
|
+
/** `/device <name>` matches no usable device (`{list}` as in deviceList). */
|
|
25
|
+
readonly deviceUnknown: {
|
|
26
|
+
readonly zh: "没有找到名为「{name}」的设备。你的设备:\n{list}";
|
|
27
|
+
readonly en: "No device named “{name}”. Your devices:\n{list}";
|
|
28
|
+
};
|
|
29
|
+
/** `/device <name>` names an existing device that is unavailable now (`{list}` as in deviceList). */
|
|
30
|
+
readonly deviceUnavailable: {
|
|
31
|
+
readonly zh: "设备「{name}」当前不可用(它的文件由未启用的沙箱提供方保存)。你的设备:\n{list}";
|
|
32
|
+
readonly en: "The device “{name}” is unavailable: its files are kept by a sandbox provider that is not active. Your devices:\n{list}";
|
|
33
|
+
};
|
|
34
|
+
/** Direct message `/device` when the person has no usable device (no cloud sandbox in the deployment). */
|
|
35
|
+
readonly deviceNone: {
|
|
36
|
+
readonly zh: "你目前没有可用的设备。";
|
|
37
|
+
readonly en: "You have no usable devices.";
|
|
38
|
+
};
|
|
39
|
+
/** The mark of the current IM default device in the device list. */
|
|
40
|
+
readonly deviceCurrent: {
|
|
41
41
|
readonly zh: "(当前)";
|
|
42
42
|
readonly en: " (current)";
|
|
43
43
|
};
|
package/dist/channels/phrases.js
CHANGED
|
@@ -6,33 +6,33 @@
|
|
|
6
6
|
export const CHANNEL_PHRASES = {
|
|
7
7
|
/** 私聊 `/new` 之后。 */
|
|
8
8
|
newConversation: { zh: "已开始新对话", en: "Started a new conversation." },
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
zh: "
|
|
12
|
-
en: "Your
|
|
13
|
-
},
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
zh: "
|
|
17
|
-
en: "Your next new conversation will use the
|
|
18
|
-
},
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
zh: "没有找到名为「{name}
|
|
22
|
-
en: "No
|
|
23
|
-
},
|
|
24
|
-
/** `/
|
|
25
|
-
|
|
26
|
-
zh: "
|
|
27
|
-
en: "The
|
|
28
|
-
},
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
zh: "
|
|
32
|
-
en: "You have no usable
|
|
33
|
-
},
|
|
34
|
-
/**
|
|
35
|
-
|
|
9
|
+
/** Direct message `/device`: lists the usable devices (`{list}` one per line, the current one marked). */
|
|
10
|
+
deviceList: {
|
|
11
|
+
zh: "你的设备:\n{list}\n发送 /device <名称> 选择下一个新对话使用的设备。",
|
|
12
|
+
en: "Your devices:\n{list}\nSend /device <name> to choose the one your next new conversation uses.",
|
|
13
|
+
},
|
|
14
|
+
/** After a direct message `/device <name>` (`{name}` is the device's name). */
|
|
15
|
+
deviceSwitched: {
|
|
16
|
+
zh: "下一个新对话将使用设备「{name}」,发送 /new 开始。",
|
|
17
|
+
en: "Your next new conversation will use the device \u201c{name}\u201d; send /new to start one.",
|
|
18
|
+
},
|
|
19
|
+
/** `/device <name>` matches no usable device (`{list}` as in deviceList). */
|
|
20
|
+
deviceUnknown: {
|
|
21
|
+
zh: "没有找到名为「{name}」的设备。你的设备:\n{list}",
|
|
22
|
+
en: "No device named \u201c{name}\u201d. Your devices:\n{list}",
|
|
23
|
+
},
|
|
24
|
+
/** `/device <name>` names an existing device that is unavailable now (`{list}` as in deviceList). */
|
|
25
|
+
deviceUnavailable: {
|
|
26
|
+
zh: "设备「{name}」当前不可用(它的文件由未启用的沙箱提供方保存)。你的设备:\n{list}",
|
|
27
|
+
en: "The device \u201c{name}\u201d is unavailable: its files are kept by a sandbox provider that is not active. Your devices:\n{list}",
|
|
28
|
+
},
|
|
29
|
+
/** Direct message `/device` when the person has no usable device (no cloud sandbox in the deployment). */
|
|
30
|
+
deviceNone: {
|
|
31
|
+
zh: "你目前没有可用的设备。",
|
|
32
|
+
en: "You have no usable devices.",
|
|
33
|
+
},
|
|
34
|
+
/** The mark of the current IM default device in the device list. */
|
|
35
|
+
deviceCurrent: { zh: "(当前)", en: " (current)" },
|
|
36
36
|
/** 未绑定的人在私聊里发消息:附绑定卡片。 */
|
|
37
37
|
bindPrompt: {
|
|
38
38
|
zh: "请先绑定你的 Capybara 账号,再与我对话。",
|
package/dist/config/docs.js
CHANGED
|
@@ -82,7 +82,7 @@ export function renderConfigDocs(schema) {
|
|
|
82
82
|
"| `CAPYBARA_WEB_OBJECT_STORE_URL` | Object storage on the web origin: the object store's address as web reaches it (e.g. `http://seaweedfs-s3:8333`). When set, web proxies `/<bucket>/**` (and `/<bucket>` itself for POST only) there, so browsers upload attachments (presigned POST) and download attachments and artifacts (presigned GET) through web; set the object-store extension's `publicEndpoint` to the web origin with `forcePathStyle: true`. Only GET, HEAD and POST; the path is forwarded unchanged; cookies and authorization are not forwarded; responses carry `X-Content-Type-Options: nosniff` and `Content-Security-Policy: sandbox`; uploads are capped at `CAPYBARA_WEB_MAX_PACKAGE_BYTES`. Unset (default): off |",
|
|
83
83
|
"| `CAPYBARA_WEB_OBJECT_STORE_BUCKET` | With `CAPYBARA_WEB_OBJECT_STORE_URL`: the bucket, equal to the object-store extension's `bucket` (it is the first path segment web proxies) |",
|
|
84
84
|
"| `CAPYBARA_WEB_OBJECT_STORE_PUBLIC_HOST` | With `CAPYBARA_WEB_OBJECT_STORE_URL`: the host of the extension's `publicEndpoint` (a host such as `capybara.example.com`, or that URL). Sent upstream as `Host` instead of the incoming one, because presigned URLs sign the host they were issued for and front proxies rewrite it |",
|
|
85
|
-
"| `CAPYBARA_WEB_GATEWAY_URL` |
|
|
85
|
+
"| `CAPYBARA_WEB_GATEWAY_URL` | Local devices on the web origin: a `gateway` replica's address as web reaches it (an http(s) URL, e.g. `http://gateway:8080`). WebSocket upgrades on exactly `/device/connect` are forwarded to it (`capybara-device` connects at `<http.publicUrl>/device/connect`). Unset, they go to `CAPYBARA_KERNEL_URL` (the kernel runs every role unless the deployment splits them), so only deployments with separate gateway replicas set it (compose does). A malformed value stops the web tier at startup |",
|
|
86
86
|
"| `CAPYBARA_DEV_UI` | When set to `1`, production builds also serve the `/dev/ui` component catalog page (off by default) |",
|
|
87
87
|
"",
|
|
88
88
|
].join("\n");
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -219,9 +219,9 @@ export declare const KernelConfigSchema: z.ZodObject<{
|
|
|
219
219
|
allowHosts: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
220
220
|
}, z.core.$strip>>;
|
|
221
221
|
}, z.core.$strip>>;
|
|
222
|
-
|
|
222
|
+
devices: z.ZodPrefault<z.ZodObject<{
|
|
223
223
|
maxPersonal: z.ZodDefault<z.ZodNumber>;
|
|
224
|
-
|
|
224
|
+
local: z.ZodPrefault<z.ZodObject<{
|
|
225
225
|
reconnectGraceSeconds: z.ZodDefault<z.ZodNumber>;
|
|
226
226
|
leaseTtlMs: z.ZodDefault<z.ZodNumber>;
|
|
227
227
|
authCodeTtlSeconds: z.ZodDefault<z.ZodNumber>;
|