@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
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ApiError } from "../errors.js";
|
|
2
2
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
3
3
|
import { SandboxProviders } from "../sandbox/providers.js";
|
|
4
|
-
/** What decides
|
|
4
|
+
/** What decides a device's provider: its own record and its instance row's (if any). */
|
|
5
5
|
export interface ProviderFacts {
|
|
6
|
-
/** `
|
|
6
|
+
/** `devices.provider`: the provider current when it was created. */
|
|
7
7
|
provider: string | null;
|
|
8
|
-
/** `
|
|
8
|
+
/** `device_instances.provider`; null without an instance row. */
|
|
9
9
|
instanceProvider: string | null;
|
|
10
10
|
/** The instance row's `fs_status`; null without an instance row. */
|
|
11
11
|
fsStatus: "none" | "ready" | "lost" | null;
|
|
@@ -13,15 +13,15 @@ export interface ProviderFacts {
|
|
|
13
13
|
hasInstance: boolean;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* The provider
|
|
17
|
-
* cloud
|
|
16
|
+
* The provider a device works with: a kernel-internal one (`@local`) as recorded; for a
|
|
17
|
+
* cloud device the one keeping its files or instance once it has any (they are never
|
|
18
18
|
* migrated, spec §4.2 item 13); before that, the current cloud provider (its first use creates
|
|
19
19
|
* them there), else the one recorded at creation. The same rule as `SandboxService`'s use.
|
|
20
20
|
*/
|
|
21
|
-
export declare function
|
|
21
|
+
export declare function deviceProvider(f: ProviderFacts, current: string | undefined): string | null;
|
|
22
22
|
/** It has files or an instance at some provider (a file system, even a lost one, or a handle). */
|
|
23
23
|
export declare const holdsResources: (f: ProviderFacts) => boolean;
|
|
24
|
-
/** `
|
|
24
|
+
/** `device_instances.status`. */
|
|
25
25
|
export type InstanceStatus = "none" | "creating" | "running" | "suspended" | "destroyed";
|
|
26
26
|
/**
|
|
27
27
|
* For replacing a default (which one is the person's default): it holds healthy files or an
|
|
@@ -36,30 +36,30 @@ export declare const inUseForDefault: (f: ProviderFacts & {
|
|
|
36
36
|
* The provider a former default belongs to (its label and the provider whose switch back restores
|
|
37
37
|
* it): the one holding its resources once it holds any, else the one it was demoted from (the
|
|
38
38
|
* marker). A former default demoted while empty and used afterwards keeps a stale marker; its
|
|
39
|
-
* resources decide. null for
|
|
39
|
+
* resources decide. null for a device that is not a former default.
|
|
40
40
|
*/
|
|
41
41
|
export declare function demotedProvider(marker: string | null, f: ProviderFacts): string | null;
|
|
42
42
|
/**
|
|
43
|
-
* The
|
|
44
|
-
* internal provider (`@
|
|
43
|
+
* The device's provider is not the current one, or there is no provider (503); for an
|
|
44
|
+
* internal provider (`@local`), this kernel does not serve it.
|
|
45
45
|
*/
|
|
46
|
-
export declare const
|
|
46
|
+
export declare const deviceUnavailable: (provider: string | null) => ApiError;
|
|
47
47
|
/**
|
|
48
|
-
* Who may use
|
|
49
|
-
*
|
|
48
|
+
* Who may use a device (spec §4.2 item 12): in phase 1 only the owner of a personal
|
|
49
|
+
* device. Anyone else gets `device.not_found`, never `forbidden`, so ids cannot be
|
|
50
50
|
* probed. Read live on every call (PG, no cache); phase 3 adds project membership.
|
|
51
51
|
*/
|
|
52
|
-
export declare class
|
|
52
|
+
export declare class DeviceAccess {
|
|
53
53
|
private readonly db;
|
|
54
54
|
private readonly providers;
|
|
55
55
|
constructor(db: KernelDb, providers: Pick<SandboxProviders, "cloud" | "forName">);
|
|
56
56
|
/**
|
|
57
|
-
* The
|
|
58
|
-
* missing, deleted, in another org or someone else's; `
|
|
59
|
-
* provider is not the current one (or there is none). A
|
|
60
|
-
* `@
|
|
57
|
+
* The device if `accountId` may use it in `orgId` now: `device.not_found` when it is
|
|
58
|
+
* missing, deleted, in another org or someone else's; `device.unavailable` when its
|
|
59
|
+
* provider is not the current one (or there is none). A local device is usable while
|
|
60
|
+
* `@local` is registered: whether its machine is online is the relay's concern, not access.
|
|
61
61
|
*/
|
|
62
|
-
usable(orgId: string, accountId: string,
|
|
62
|
+
usable(orgId: string, accountId: string, deviceId: string): Promise<{
|
|
63
63
|
id: string;
|
|
64
64
|
provider: string | null;
|
|
65
65
|
}>;
|
|
@@ -11,14 +11,14 @@ import { Inject, Injectable } from "@nestjs/common";
|
|
|
11
11
|
import { ApiError } from "../errors.js";
|
|
12
12
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
13
13
|
import { isInternalProvider, SandboxProviders } from "../sandbox/providers.js";
|
|
14
|
-
import {
|
|
14
|
+
import { deviceNotFound } from "../sandbox/sandbox.service.js";
|
|
15
15
|
/**
|
|
16
|
-
* The provider
|
|
17
|
-
* cloud
|
|
16
|
+
* The provider a device works with: a kernel-internal one (`@local`) as recorded; for a
|
|
17
|
+
* cloud device the one keeping its files or instance once it has any (they are never
|
|
18
18
|
* migrated, spec §4.2 item 13); before that, the current cloud provider (its first use creates
|
|
19
19
|
* them there), else the one recorded at creation. The same rule as `SandboxService`'s use.
|
|
20
20
|
*/
|
|
21
|
-
export function
|
|
21
|
+
export function deviceProvider(f, current) {
|
|
22
22
|
if (f.provider !== null && isInternalProvider(f.provider))
|
|
23
23
|
return f.provider;
|
|
24
24
|
if (holdsResources(f))
|
|
@@ -40,7 +40,7 @@ export const inUseForDefault = (f) => f.fsStatus === "ready" ||
|
|
|
40
40
|
* The provider a former default belongs to (its label and the provider whose switch back restores
|
|
41
41
|
* it): the one holding its resources once it holds any, else the one it was demoted from (the
|
|
42
42
|
* marker). A former default demoted while empty and used afterwards keeps a stale marker; its
|
|
43
|
-
* resources decide. null for
|
|
43
|
+
* resources decide. null for a device that is not a former default.
|
|
44
44
|
*/
|
|
45
45
|
export function demotedProvider(marker, f) {
|
|
46
46
|
if (marker === null)
|
|
@@ -48,20 +48,20 @@ export function demotedProvider(marker, f) {
|
|
|
48
48
|
return (holdsResources(f) ? f.instanceProvider : null) ?? marker;
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
|
-
* The
|
|
52
|
-
* internal provider (`@
|
|
51
|
+
* The device's provider is not the current one, or there is no provider (503); for an
|
|
52
|
+
* internal provider (`@local`), this kernel does not serve it.
|
|
53
53
|
*/
|
|
54
|
-
export const
|
|
54
|
+
export const deviceUnavailable = (provider) => new ApiError("device.unavailable", provider === null
|
|
55
55
|
? "No cloud sandbox is available in this deployment; ask the super admin to enable a sandbox plugin"
|
|
56
56
|
: isInternalProvider(provider)
|
|
57
|
-
? `This
|
|
58
|
-
: `This
|
|
57
|
+
? `This device runs on a connected machine (${provider}), which this deployment does not serve`
|
|
58
|
+
: `This device is kept by the sandbox provider ${provider}, which is not the current provider; it can be used again once ${provider} is the deployment's sandbox provider`);
|
|
59
59
|
/**
|
|
60
|
-
* Who may use
|
|
61
|
-
*
|
|
60
|
+
* Who may use a device (spec §4.2 item 12): in phase 1 only the owner of a personal
|
|
61
|
+
* device. Anyone else gets `device.not_found`, never `forbidden`, so ids cannot be
|
|
62
62
|
* probed. Read live on every call (PG, no cache); phase 3 adds project membership.
|
|
63
63
|
*/
|
|
64
|
-
let
|
|
64
|
+
let DeviceAccess = class DeviceAccess {
|
|
65
65
|
db;
|
|
66
66
|
providers;
|
|
67
67
|
constructor(db, providers) {
|
|
@@ -69,45 +69,45 @@ let EnvironmentAccess = class EnvironmentAccess {
|
|
|
69
69
|
this.providers = providers;
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
|
-
* The
|
|
73
|
-
* missing, deleted, in another org or someone else's; `
|
|
74
|
-
* provider is not the current one (or there is none). A
|
|
75
|
-
* `@
|
|
72
|
+
* The device if `accountId` may use it in `orgId` now: `device.not_found` when it is
|
|
73
|
+
* missing, deleted, in another org or someone else's; `device.unavailable` when its
|
|
74
|
+
* provider is not the current one (or there is none). A local device is usable while
|
|
75
|
+
* `@local` is registered: whether its machine is online is the relay's concern, not access.
|
|
76
76
|
*/
|
|
77
|
-
async usable(orgId, accountId,
|
|
77
|
+
async usable(orgId, accountId, deviceId) {
|
|
78
78
|
const row = await this.db
|
|
79
|
-
.selectFrom("
|
|
80
|
-
.leftJoin("
|
|
79
|
+
.selectFrom("devices as e")
|
|
80
|
+
.leftJoin("device_instances as i", "i.device_id", "e.id")
|
|
81
81
|
.select(["e.id", "e.provider", "i.provider as instance_provider", "i.fs_status", "i.handle"])
|
|
82
|
-
.where("e.id", "=",
|
|
82
|
+
.where("e.id", "=", deviceId)
|
|
83
83
|
.where("e.org_id", "=", orgId)
|
|
84
84
|
.where("e.owner_kind", "=", "personal")
|
|
85
85
|
.where("e.owner_account_id", "=", accountId)
|
|
86
86
|
.where("e.deleted_at", "is", null)
|
|
87
87
|
.executeTakeFirst();
|
|
88
88
|
if (!row)
|
|
89
|
-
throw
|
|
89
|
+
throw deviceNotFound();
|
|
90
90
|
if (row.provider !== null && isInternalProvider(row.provider)) {
|
|
91
91
|
if (this.providers.forName(row.provider) === undefined) {
|
|
92
|
-
throw
|
|
92
|
+
throw deviceUnavailable(row.provider);
|
|
93
93
|
}
|
|
94
94
|
return { id: row.id, provider: row.provider };
|
|
95
95
|
}
|
|
96
96
|
const current = this.providers.cloud()?.plugin;
|
|
97
|
-
const provider =
|
|
97
|
+
const provider = deviceProvider({
|
|
98
98
|
provider: row.provider,
|
|
99
99
|
instanceProvider: row.instance_provider,
|
|
100
100
|
fsStatus: row.fs_status,
|
|
101
101
|
hasInstance: row.handle !== null,
|
|
102
102
|
}, current);
|
|
103
103
|
if (current === undefined || provider !== current)
|
|
104
|
-
throw
|
|
104
|
+
throw deviceUnavailable(provider);
|
|
105
105
|
return { id: row.id, provider };
|
|
106
106
|
}
|
|
107
107
|
};
|
|
108
|
-
|
|
108
|
+
DeviceAccess = __decorate([
|
|
109
109
|
Injectable(),
|
|
110
110
|
__param(0, Inject(KernelDb)),
|
|
111
111
|
__param(1, Inject(SandboxProviders))
|
|
112
|
-
],
|
|
113
|
-
export {
|
|
112
|
+
], DeviceAccess);
|
|
113
|
+
export { DeviceAccess };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ApiError } from "../errors.js";
|
|
2
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
3
|
+
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
4
|
+
import { SandboxProviders } from "../sandbox/providers.js";
|
|
5
|
+
import { DeviceAccess } from "./access.js";
|
|
6
|
+
import { DevicesService } from "./devices.service.js";
|
|
7
|
+
/** `details[0].reason` of the error an anonymous IM conversation's sandbox call gets. */
|
|
8
|
+
export declare const ANONYMOUS_NO_DEVICE = "anonymous";
|
|
9
|
+
/** Anonymous IM senders have no device (spec §4.2 item 8): their sandbox tools are off. */
|
|
10
|
+
export declare const anonymousNoDevice: () => ApiError;
|
|
11
|
+
/** How a new conversation picks its device. */
|
|
12
|
+
export interface NewConversationDevice {
|
|
13
|
+
/** The device the person chose (the composer's picker); checked with `usable`. */
|
|
14
|
+
deviceId?: string;
|
|
15
|
+
/** An IM thread: the person's IM default (`device_defaults`) when still usable. */
|
|
16
|
+
im?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Which device a conversation works in (spec 2026-11-07-environments-design §4.1 items 1, 3;
|
|
20
|
+
* §4.2 items 8, 9, 12). A conversation is bound once, to a device of its owner
|
|
21
|
+
* (`conversations.account_id`): the one chosen at its first send, else the owner's IM default
|
|
22
|
+
* (IM threads), else the owner's default device. Its sub-agents use the root's. Access is
|
|
23
|
+
* checked when it is bound and again on every sandbox tool call ({@link forTool}); only the owner
|
|
24
|
+
* may use a personal device, so a conversation never reaches another person's.
|
|
25
|
+
*/
|
|
26
|
+
export declare class ConversationDevices {
|
|
27
|
+
private readonly db;
|
|
28
|
+
readonly txHost: TransactionHost;
|
|
29
|
+
private readonly providers;
|
|
30
|
+
private readonly access;
|
|
31
|
+
private readonly devices;
|
|
32
|
+
constructor(db: KernelDb, txHost: TransactionHost, providers: Pick<SandboxProviders, "cloud"> & Partial<Pick<SandboxProviders, "forName">>, access: Pick<DeviceAccess, "usable">, devices: Pick<DevicesService, "ensureDefault">);
|
|
33
|
+
/**
|
|
34
|
+
* The device a new conversation of `accountId` is bound to: the chosen one when it is
|
|
35
|
+
* usable by the person (else `device.not_found` / `device.unavailable`, and nothing
|
|
36
|
+
* is created); without a choice the IM default (IM only) or the person's default device.
|
|
37
|
+
* Null (unbound) for anonymous IM senders, and without a cloud sandbox provider when no usable
|
|
38
|
+
* IM default (a connected machine's device, say) applies.
|
|
39
|
+
*/
|
|
40
|
+
forNew(orgId: string, accountId: string, pick?: NewConversationDevice): Promise<string | null>;
|
|
41
|
+
/**
|
|
42
|
+
* The device a sandbox tool call of the conversation tree rooted at `rootConversationId`
|
|
43
|
+
* enters, checked for its owner now. A conversation still unbound (created before
|
|
44
|
+
* devices, or while no provider existed) is bound first, to the owner's IM default when it
|
|
45
|
+
* is an IM thread, else to the owner's default device; a racing call binds it once.
|
|
46
|
+
* Throws `sandbox.unavailable` for a cloud device (or none to bind) without a cloud
|
|
47
|
+
* provider and for an anonymous IM conversation, and `device.not_found` /
|
|
48
|
+
* `device.unavailable` when the owner may not use it now. A conversation bound to a
|
|
49
|
+
* connected machine's device (`@local`) does not need a cloud provider.
|
|
50
|
+
*/
|
|
51
|
+
forTool(orgId: string, rootConversationId: string): Promise<string>;
|
|
52
|
+
/**
|
|
53
|
+
* Whether a sandbox tool call of the tree rooted at `rootConversationId` has a provider to run
|
|
54
|
+
* on, for tool listings (ruling R8; no binding, no access check, never throws): a cloud
|
|
55
|
+
* provider is loaded, or the device the conversation is bound to (an unbound IM thread:
|
|
56
|
+
* its owner's IM default) runs on a registered kernel provider (`@local`). A forbidden or gone
|
|
57
|
+
* device still counts: the call then says why.
|
|
58
|
+
*/
|
|
59
|
+
usableNow(orgId: string, rootConversationId: string): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* The person's IM default when `im` and it is still theirs, live, in this org and usable (the
|
|
62
|
+
* table has no such guard), else their default device (created when missing); null when
|
|
63
|
+
* that is needed and there is no cloud provider to make or use it. The owner having left the org
|
|
64
|
+
* reads as `device.not_found`.
|
|
65
|
+
*/
|
|
66
|
+
private defaultFor;
|
|
67
|
+
/** Binds an unbound conversation to `deviceId`; returns what it is bound to now. */
|
|
68
|
+
private bind;
|
|
69
|
+
/** The device runs on a kernel-internal provider (`@local`). */
|
|
70
|
+
private isInternal;
|
|
71
|
+
/** The account is the org's anonymous IM guest (no person behind it). */
|
|
72
|
+
private isAnonymous;
|
|
73
|
+
/** The conversation is (or was) an IM thread's. */
|
|
74
|
+
private isImThread;
|
|
75
|
+
}
|
|
@@ -13,44 +13,44 @@ import { KernelDb } from "../infra/database/kernel-db.js";
|
|
|
13
13
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
14
14
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
15
15
|
import { isInternalProvider, SandboxProviders } from "../sandbox/providers.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
16
|
+
import { deviceNotFound, sandboxUnavailable } from "../sandbox/sandbox.service.js";
|
|
17
|
+
import { DeviceAccess } from "./access.js";
|
|
18
|
+
import { DevicesService } from "./devices.service.js";
|
|
19
19
|
/** `details[0].reason` of the error an anonymous IM conversation's sandbox call gets. */
|
|
20
|
-
export const
|
|
21
|
-
/** Anonymous IM senders have no
|
|
22
|
-
export const
|
|
20
|
+
export const ANONYMOUS_NO_DEVICE = "anonymous";
|
|
21
|
+
/** Anonymous IM senders have no device (spec §4.2 item 8): their sandbox tools are off. */
|
|
22
|
+
export const anonymousNoDevice = () => new ApiError("sandbox.unavailable", "Anonymous IM senders have no device, so the sandbox is not available", [{ reason: ANONYMOUS_NO_DEVICE }]);
|
|
23
23
|
/**
|
|
24
|
-
* Which
|
|
25
|
-
* §4.2 items 8, 9, 12). A conversation is bound once, to
|
|
24
|
+
* Which device a conversation works in (spec 2026-11-07-environments-design §4.1 items 1, 3;
|
|
25
|
+
* §4.2 items 8, 9, 12). A conversation is bound once, to a device of its owner
|
|
26
26
|
* (`conversations.account_id`): the one chosen at its first send, else the owner's IM default
|
|
27
|
-
* (IM threads), else the owner's default
|
|
27
|
+
* (IM threads), else the owner's default device. Its sub-agents use the root's. Access is
|
|
28
28
|
* checked when it is bound and again on every sandbox tool call ({@link forTool}); only the owner
|
|
29
|
-
* may use a personal
|
|
29
|
+
* may use a personal device, so a conversation never reaches another person's.
|
|
30
30
|
*/
|
|
31
|
-
let
|
|
31
|
+
let ConversationDevices = class ConversationDevices {
|
|
32
32
|
db;
|
|
33
33
|
txHost;
|
|
34
34
|
providers;
|
|
35
35
|
access;
|
|
36
|
-
|
|
37
|
-
constructor(db, txHost, providers, access,
|
|
36
|
+
devices;
|
|
37
|
+
constructor(db, txHost, providers, access, devices) {
|
|
38
38
|
this.db = db;
|
|
39
39
|
this.txHost = txHost;
|
|
40
40
|
this.providers = providers;
|
|
41
41
|
this.access = access;
|
|
42
|
-
this.
|
|
42
|
+
this.devices = devices;
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
|
-
* The
|
|
46
|
-
* usable by the person (else `
|
|
47
|
-
* is created); without a choice the IM default (IM only) or the person's default
|
|
45
|
+
* The device a new conversation of `accountId` is bound to: the chosen one when it is
|
|
46
|
+
* usable by the person (else `device.not_found` / `device.unavailable`, and nothing
|
|
47
|
+
* is created); without a choice the IM default (IM only) or the person's default device.
|
|
48
48
|
* Null (unbound) for anonymous IM senders, and without a cloud sandbox provider when no usable
|
|
49
|
-
* IM default (a connected machine's
|
|
49
|
+
* IM default (a connected machine's device, say) applies.
|
|
50
50
|
*/
|
|
51
51
|
async forNew(orgId, accountId, pick = {}) {
|
|
52
|
-
if (pick.
|
|
53
|
-
return (await this.access.usable(orgId, accountId, pick.
|
|
52
|
+
if (pick.deviceId !== undefined) {
|
|
53
|
+
return (await this.access.usable(orgId, accountId, pick.deviceId)).id;
|
|
54
54
|
}
|
|
55
55
|
if (pick.im !== true && this.providers.cloud() === undefined)
|
|
56
56
|
return null;
|
|
@@ -59,75 +59,75 @@ let ConversationEnvironments = class ConversationEnvironments {
|
|
|
59
59
|
return this.defaultFor(orgId, accountId, pick.im === true);
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
|
-
* The
|
|
62
|
+
* The device a sandbox tool call of the conversation tree rooted at `rootConversationId`
|
|
63
63
|
* enters, checked for its owner now. A conversation still unbound (created before
|
|
64
|
-
*
|
|
65
|
-
* is an IM thread, else to the owner's default
|
|
66
|
-
* Throws `sandbox.unavailable` for a cloud
|
|
67
|
-
* provider and for an anonymous IM conversation, and `
|
|
68
|
-
* `
|
|
69
|
-
* connected machine's
|
|
64
|
+
* devices, or while no provider existed) is bound first, to the owner's IM default when it
|
|
65
|
+
* is an IM thread, else to the owner's default device; a racing call binds it once.
|
|
66
|
+
* Throws `sandbox.unavailable` for a cloud device (or none to bind) without a cloud
|
|
67
|
+
* provider and for an anonymous IM conversation, and `device.not_found` /
|
|
68
|
+
* `device.unavailable` when the owner may not use it now. A conversation bound to a
|
|
69
|
+
* connected machine's device (`@local`) does not need a cloud provider.
|
|
70
70
|
*/
|
|
71
71
|
async forTool(orgId, rootConversationId) {
|
|
72
72
|
const conv = await this.db
|
|
73
73
|
.selectFrom("conversations")
|
|
74
|
-
.select(["account_id", "
|
|
74
|
+
.select(["account_id", "device_id"])
|
|
75
75
|
.where("id", "=", rootConversationId)
|
|
76
76
|
.where("org_id", "=", orgId)
|
|
77
77
|
.executeTakeFirst();
|
|
78
78
|
if (!conv)
|
|
79
|
-
throw
|
|
79
|
+
throw deviceNotFound();
|
|
80
80
|
if (await this.isAnonymous(orgId, conv.account_id))
|
|
81
|
-
throw
|
|
82
|
-
let
|
|
83
|
-
if (
|
|
81
|
+
throw anonymousNoDevice();
|
|
82
|
+
let deviceId = conv.device_id;
|
|
83
|
+
if (deviceId === null) {
|
|
84
84
|
const im = await this.isImThread(rootConversationId);
|
|
85
85
|
const chosen = await this.defaultFor(orgId, conv.account_id, im);
|
|
86
86
|
if (chosen === null)
|
|
87
87
|
throw sandboxUnavailable();
|
|
88
|
-
|
|
88
|
+
deviceId = await this.bind(rootConversationId, chosen);
|
|
89
89
|
}
|
|
90
|
-
if (this.providers.cloud() === undefined && !(await this.isInternal(
|
|
90
|
+
if (this.providers.cloud() === undefined && !(await this.isInternal(deviceId))) {
|
|
91
91
|
throw sandboxUnavailable();
|
|
92
92
|
}
|
|
93
|
-
return (await this.access.usable(orgId, conv.account_id,
|
|
93
|
+
return (await this.access.usable(orgId, conv.account_id, deviceId)).id;
|
|
94
94
|
}
|
|
95
95
|
/**
|
|
96
96
|
* Whether a sandbox tool call of the tree rooted at `rootConversationId` has a provider to run
|
|
97
97
|
* on, for tool listings (ruling R8; no binding, no access check, never throws): a cloud
|
|
98
|
-
* provider is loaded, or the
|
|
99
|
-
* its owner's IM default) runs on a registered kernel provider (`@
|
|
100
|
-
*
|
|
98
|
+
* provider is loaded, or the device the conversation is bound to (an unbound IM thread:
|
|
99
|
+
* its owner's IM default) runs on a registered kernel provider (`@local`). A forbidden or gone
|
|
100
|
+
* device still counts: the call then says why.
|
|
101
101
|
*/
|
|
102
102
|
async usableNow(orgId, rootConversationId) {
|
|
103
103
|
if (this.providers.cloud() !== undefined)
|
|
104
104
|
return true;
|
|
105
105
|
const conv = await this.db
|
|
106
106
|
.selectFrom("conversations")
|
|
107
|
-
.select(["account_id", "
|
|
107
|
+
.select(["account_id", "device_id"])
|
|
108
108
|
.where("id", "=", rootConversationId)
|
|
109
109
|
.where("org_id", "=", orgId)
|
|
110
110
|
.executeTakeFirst();
|
|
111
111
|
if (!conv)
|
|
112
112
|
return false;
|
|
113
|
-
let
|
|
114
|
-
if (
|
|
113
|
+
let deviceId = conv.device_id;
|
|
114
|
+
if (deviceId === null) {
|
|
115
115
|
if (!(await this.isImThread(rootConversationId)))
|
|
116
116
|
return false;
|
|
117
117
|
const row = await this.db
|
|
118
|
-
.selectFrom("
|
|
119
|
-
.select("
|
|
118
|
+
.selectFrom("device_defaults")
|
|
119
|
+
.select("device_id")
|
|
120
120
|
.where("org_id", "=", orgId)
|
|
121
121
|
.where("account_id", "=", conv.account_id)
|
|
122
122
|
.executeTakeFirst();
|
|
123
123
|
if (!row)
|
|
124
124
|
return false;
|
|
125
|
-
|
|
125
|
+
deviceId = row.device_id;
|
|
126
126
|
}
|
|
127
127
|
const env = await this.db
|
|
128
|
-
.selectFrom("
|
|
128
|
+
.selectFrom("devices")
|
|
129
129
|
.select("provider")
|
|
130
|
-
.where("id", "=",
|
|
130
|
+
.where("id", "=", deviceId)
|
|
131
131
|
.executeTakeFirst();
|
|
132
132
|
const provider = env?.provider ?? null;
|
|
133
133
|
return (provider !== null &&
|
|
@@ -136,24 +136,24 @@ let ConversationEnvironments = class ConversationEnvironments {
|
|
|
136
136
|
}
|
|
137
137
|
/**
|
|
138
138
|
* The person's IM default when `im` and it is still theirs, live, in this org and usable (the
|
|
139
|
-
* table has no such guard), else their default
|
|
139
|
+
* table has no such guard), else their default device (created when missing); null when
|
|
140
140
|
* that is needed and there is no cloud provider to make or use it. The owner having left the org
|
|
141
|
-
* reads as `
|
|
141
|
+
* reads as `device.not_found`.
|
|
142
142
|
*/
|
|
143
143
|
async defaultFor(orgId, accountId, im) {
|
|
144
144
|
if (im) {
|
|
145
145
|
const row = await this.db
|
|
146
|
-
.selectFrom("
|
|
147
|
-
.select("
|
|
146
|
+
.selectFrom("device_defaults")
|
|
147
|
+
.select("device_id")
|
|
148
148
|
.where("org_id", "=", orgId)
|
|
149
149
|
.where("account_id", "=", accountId)
|
|
150
150
|
.executeTakeFirst();
|
|
151
151
|
if (row) {
|
|
152
152
|
try {
|
|
153
|
-
return (await this.access.usable(orgId, accountId, row.
|
|
153
|
+
return (await this.access.usable(orgId, accountId, row.device_id)).id;
|
|
154
154
|
}
|
|
155
155
|
catch (e) {
|
|
156
|
-
if (!
|
|
156
|
+
if (!isDeviceGone(e))
|
|
157
157
|
throw e;
|
|
158
158
|
}
|
|
159
159
|
}
|
|
@@ -161,35 +161,35 @@ let ConversationEnvironments = class ConversationEnvironments {
|
|
|
161
161
|
if (this.providers.cloud() === undefined)
|
|
162
162
|
return null;
|
|
163
163
|
try {
|
|
164
|
-
return await this.
|
|
164
|
+
return await this.devices.ensureDefault(orgId, accountId);
|
|
165
165
|
}
|
|
166
166
|
catch (e) {
|
|
167
167
|
if (e instanceof ApiError && e.code === "org.not_found")
|
|
168
|
-
throw
|
|
168
|
+
throw deviceNotFound();
|
|
169
169
|
throw e;
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
|
-
/** Binds an unbound conversation to `
|
|
173
|
-
async bind(conversationId,
|
|
172
|
+
/** Binds an unbound conversation to `deviceId`; returns what it is bound to now. */
|
|
173
|
+
async bind(conversationId, deviceId) {
|
|
174
174
|
await this.db
|
|
175
175
|
.updateTable("conversations")
|
|
176
|
-
.set({
|
|
176
|
+
.set({ device_id: deviceId })
|
|
177
177
|
.where("id", "=", conversationId)
|
|
178
|
-
.where("
|
|
178
|
+
.where("device_id", "is", null)
|
|
179
179
|
.execute();
|
|
180
180
|
const row = await this.db
|
|
181
181
|
.selectFrom("conversations")
|
|
182
|
-
.select("
|
|
182
|
+
.select("device_id")
|
|
183
183
|
.where("id", "=", conversationId)
|
|
184
184
|
.executeTakeFirstOrThrow();
|
|
185
|
-
return row.
|
|
185
|
+
return row.device_id ?? deviceId;
|
|
186
186
|
}
|
|
187
|
-
/** The
|
|
188
|
-
async isInternal(
|
|
187
|
+
/** The device runs on a kernel-internal provider (`@local`). */
|
|
188
|
+
async isInternal(deviceId) {
|
|
189
189
|
const row = await this.db
|
|
190
|
-
.selectFrom("
|
|
190
|
+
.selectFrom("devices")
|
|
191
191
|
.select("provider")
|
|
192
|
-
.where("id", "=",
|
|
192
|
+
.where("id", "=", deviceId)
|
|
193
193
|
.executeTakeFirst();
|
|
194
194
|
const provider = row?.provider ?? null;
|
|
195
195
|
return provider !== null && isInternalProvider(provider);
|
|
@@ -217,15 +217,14 @@ let ConversationEnvironments = class ConversationEnvironments {
|
|
|
217
217
|
};
|
|
218
218
|
__decorate([
|
|
219
219
|
Transactional()
|
|
220
|
-
],
|
|
221
|
-
|
|
220
|
+
], ConversationDevices.prototype, "bind", null);
|
|
221
|
+
ConversationDevices = __decorate([
|
|
222
222
|
Injectable(),
|
|
223
223
|
__param(0, Inject(KernelDb)),
|
|
224
224
|
__param(1, Inject(TransactionHost)),
|
|
225
225
|
__param(2, Inject(SandboxProviders)),
|
|
226
|
-
__param(3, Inject(
|
|
227
|
-
__param(4, Inject(
|
|
228
|
-
],
|
|
229
|
-
export {
|
|
230
|
-
const
|
|
231
|
-
(e.code === "environment.not_found" || e.code === "environment.unavailable");
|
|
226
|
+
__param(3, Inject(DeviceAccess)),
|
|
227
|
+
__param(4, Inject(DevicesService))
|
|
228
|
+
], ConversationDevices);
|
|
229
|
+
export { ConversationDevices };
|
|
230
|
+
const isDeviceGone = (e) => e instanceof ApiError && (e.code === "device.not_found" || e.code === "device.unavailable");
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import { type Principal } from "../identity/principal.js";
|
|
3
|
+
import { type OrgContext } from "../orgs/org.guard.js";
|
|
4
|
+
import { type DeviceList, DevicesService, type DeviceView } from "./devices.service.js";
|
|
5
|
+
import { type DeviceNameBody, type DeviceParams } from "./dto.js";
|
|
6
|
+
/**
|
|
7
|
+
* A person's devices in an org (`/api/v1/orgs/:orgId/devices`, spec
|
|
8
|
+
* 2026-11-07-environments-design §9; `agents.use`, human users only: a service token gets 403).
|
|
9
|
+
* Phase 1 has personal cloud devices only, each visible to its owner alone: another member
|
|
10
|
+
* gets 404 `device.not_found`.
|
|
11
|
+
* - `GET /` → `{ items, defaultId, lastUsedId, cloudAvailable }` (`cloudAvailable`: there is a
|
|
12
|
+
* current sandbox provider; ruling R4);
|
|
13
|
+
* - `POST / { name }` → 201 `{ device }`; `GET /:id`, `PATCH /:id { name }` → `{ device }`;
|
|
14
|
+
* - `DELETE /:id` → 202 (destroyed by a job after the response);
|
|
15
|
+
* - `POST /:id/files/reset` → 202 (the reset is enqueued: a worker empties the files, the next use
|
|
16
|
+
* starts empty);
|
|
17
|
+
* - `DELETE /:id/machine` → 204: a local device's machine is disconnected (its credential
|
|
18
|
+
* revoked; it must sign in again).
|
|
19
|
+
*/
|
|
20
|
+
export declare class DevicesController {
|
|
21
|
+
private readonly devices;
|
|
22
|
+
constructor(devices: DevicesService);
|
|
23
|
+
list(principal: Principal, org: OrgContext): Promise<DeviceList>;
|
|
24
|
+
create(principal: Principal, org: OrgContext, body: z.infer<typeof DeviceNameBody>): Promise<{
|
|
25
|
+
device: DeviceView;
|
|
26
|
+
}>;
|
|
27
|
+
get(principal: Principal, org: OrgContext, params: z.infer<typeof DeviceParams>): Promise<{
|
|
28
|
+
device: DeviceView;
|
|
29
|
+
}>;
|
|
30
|
+
rename(principal: Principal, org: OrgContext, params: z.infer<typeof DeviceParams>, body: z.infer<typeof DeviceNameBody>): Promise<{
|
|
31
|
+
device: DeviceView;
|
|
32
|
+
}>;
|
|
33
|
+
remove(principal: Principal, org: OrgContext, params: z.infer<typeof DeviceParams>): Promise<void>;
|
|
34
|
+
resetFiles(principal: Principal, org: OrgContext, params: z.infer<typeof DeviceParams>): Promise<void>;
|
|
35
|
+
revokeMachine(principal: Principal, org: OrgContext, params: z.infer<typeof DeviceParams>): Promise<void>;
|
|
36
|
+
}
|