@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.
Files changed (220) hide show
  1. package/dist/admin/admin.schemas.d.ts +13 -0
  2. package/dist/agents/agent-lookup.d.ts +5 -0
  3. package/dist/agents/agent-lookup.js +15 -0
  4. package/dist/agents/agents.schemas.d.ts +3 -0
  5. package/dist/agents/agents.service.js +11 -1
  6. package/dist/agents/definition.d.ts +1 -0
  7. package/dist/agents/definition.js +7 -3
  8. package/dist/agents/org-templates.js +4 -0
  9. package/dist/agents/pending-connectors.service.js +1 -1
  10. package/dist/background/background.module.js +2 -2
  11. package/dist/background/launch-lock.d.ts +1 -1
  12. package/dist/background/launch-lock.js +1 -1
  13. package/dist/background/poll.job.d.ts +2 -2
  14. package/dist/background/poll.job.js +10 -10
  15. package/dist/background/stop.d.ts +1 -1
  16. package/dist/background/stop.js +3 -3
  17. package/dist/background/store.d.ts +5 -5
  18. package/dist/background/store.js +5 -5
  19. package/dist/background/tasks.service.d.ts +6 -6
  20. package/dist/background/tasks.service.js +13 -13
  21. package/dist/catalog/component-scope.controller.d.ts +18 -6
  22. package/dist/catalog/component-scope.controller.js +36 -13
  23. package/dist/catalog/component-scope.service.d.ts +11 -0
  24. package/dist/catalog/component-scope.service.js +4 -0
  25. package/dist/catalog/component-state.d.ts +8 -0
  26. package/dist/catalog/component-state.js +19 -11
  27. package/dist/catalog/marketplaces.service.d.ts +1 -1
  28. package/dist/catalog/plugin-import.js +4 -1
  29. package/dist/channels/channels.module.js +2 -2
  30. package/dist/channels/inbound.d.ts +8 -8
  31. package/dist/channels/inbound.js +31 -31
  32. package/dist/channels/phrases.d.ts +27 -27
  33. package/dist/channels/phrases.js +27 -27
  34. package/dist/config/docs.js +1 -1
  35. package/dist/config/schema.d.ts +2 -2
  36. package/dist/config/schema.js +21 -21
  37. package/dist/conversations/conversations.controller.d.ts +11 -11
  38. package/dist/conversations/conversations.controller.js +15 -15
  39. package/dist/conversations/conversations.module.d.ts +1 -1
  40. package/dist/conversations/conversations.module.js +7 -7
  41. package/dist/conversations/conversations.schemas.js +1 -1
  42. package/dist/conversations/conversations.service.d.ts +23 -14
  43. package/dist/conversations/conversations.service.js +28 -21
  44. package/dist/conversations/{environment-status.d.ts → device-status.d.ts} +9 -9
  45. package/dist/conversations/{environment-status.js → device-status.js} +18 -18
  46. package/dist/conversations/event-log.d.ts +1 -1
  47. package/dist/conversations/event-log.js +1 -1
  48. package/dist/conversations/events.d.ts +2 -1
  49. package/dist/conversations/events.js +2 -2
  50. package/dist/ctx/create-ctx.d.ts +10 -1
  51. package/dist/ctx/create-ctx.js +86 -25
  52. package/dist/db/kernel-schema.d.ts +39 -23
  53. package/dist/{environments → devices}/access.d.ts +19 -19
  54. package/dist/{environments → devices}/access.js +28 -28
  55. package/dist/devices/conversation-devices.d.ts +75 -0
  56. package/dist/{environments/conversation-environments.js → devices/conversation-devices.js} +71 -72
  57. package/dist/devices/devices.controller.d.ts +36 -0
  58. package/dist/{environments/environments.controller.js → devices/devices.controller.js} +37 -37
  59. package/dist/devices/devices.module.d.ts +5 -13
  60. package/dist/devices/devices.module.js +16 -29
  61. package/dist/devices/devices.schemas.d.ts +3 -0
  62. package/dist/devices/devices.schemas.js +14 -0
  63. package/dist/{environments/environments.service.d.ts → devices/devices.service.d.ts} +70 -70
  64. package/dist/{environments/environments.service.js → devices/devices.service.js} +122 -122
  65. package/dist/devices/dto.d.ts +13 -54
  66. package/dist/devices/dto.js +7 -39
  67. package/dist/devices/label.d.ts +11 -0
  68. package/dist/{environments → devices}/label.js +7 -7
  69. package/dist/{environments → devices}/legacy-cleanup.job.d.ts +3 -3
  70. package/dist/{environments → devices}/legacy-cleanup.job.js +3 -3
  71. package/dist/errors.d.ts +27 -25
  72. package/dist/errors.js +27 -25
  73. package/dist/evals/recorded-tools.d.ts +2 -2
  74. package/dist/evals/recorded-tools.js +6 -6
  75. package/dist/extensions/admin-ops.js +1 -0
  76. package/dist/extensions/admin-view.js +2 -0
  77. package/dist/extensions/effective-config.d.ts +6 -0
  78. package/dist/extensions/effective-config.js +18 -7
  79. package/dist/extensions/host.d.ts +13 -2
  80. package/dist/extensions/host.js +24 -3
  81. package/dist/extensions/instance.d.ts +12 -1
  82. package/dist/extensions/instance.js +13 -0
  83. package/dist/extensions/permission-view.d.ts +10 -1
  84. package/dist/files/previewers.d.ts +1 -1
  85. package/dist/files/previewers.js +1 -1
  86. package/dist/http/api.module.js +10 -6
  87. package/dist/http/gateway-routes.d.ts +1 -1
  88. package/dist/http/gateway-routes.js +1 -1
  89. package/dist/identity/settings.d.ts +32 -0
  90. package/dist/identity/settings.js +26 -2
  91. package/dist/infra/config/kernel-config.service.js +4 -4
  92. package/dist/kernel.module.js +3 -3
  93. package/dist/{devices → local-devices}/device-auth.controller.d.ts +6 -6
  94. package/dist/{devices → local-devices}/device-auth.controller.js +5 -5
  95. package/dist/{devices → local-devices}/device-auth.d.ts +20 -20
  96. package/dist/{devices → local-devices}/device-auth.js +51 -53
  97. package/dist/local-devices/device-auth.module.d.ts +7 -0
  98. package/dist/{devices → local-devices}/device-auth.module.js +5 -5
  99. package/dist/{devices → local-devices}/device-routes.d.ts +3 -3
  100. package/dist/{devices → local-devices}/device-routes.js +2 -2
  101. package/dist/local-devices/dto.d.ts +66 -0
  102. package/dist/local-devices/dto.js +44 -0
  103. package/dist/{devices → local-devices}/keys.d.ts +11 -11
  104. package/dist/{devices → local-devices}/keys.js +11 -11
  105. package/dist/{devices/device-gateway.d.ts → local-devices/local-device-gateway.d.ts} +14 -14
  106. package/dist/{devices/device-gateway.js → local-devices/local-device-gateway.js} +44 -44
  107. package/dist/{devices/device-provider.d.ts → local-devices/local-device-provider.d.ts} +15 -15
  108. package/dist/{devices/device-provider.js → local-devices/local-device-provider.js} +23 -23
  109. package/dist/local-devices/local-devices.module.d.ts +16 -0
  110. package/dist/local-devices/local-devices.module.js +44 -0
  111. package/dist/{devices → local-devices}/machines.d.ts +26 -26
  112. package/dist/{devices → local-devices}/machines.js +71 -71
  113. package/dist/{devices → local-devices}/relay.d.ts +15 -15
  114. package/dist/{devices → local-devices}/relay.js +55 -55
  115. package/dist/{devices → local-devices}/targets.d.ts +8 -8
  116. package/dist/{devices → local-devices}/targets.js +14 -14
  117. package/dist/orgs/offboarding.d.ts +6 -6
  118. package/dist/orgs/offboarding.js +12 -12
  119. package/dist/orgs/settings.service.d.ts +28 -0
  120. package/dist/orgs/settings.service.js +20 -1
  121. package/dist/platform/exclusions.js +48 -3
  122. package/dist/platform/operation.js +6 -2
  123. package/dist/platform/ops/admin.ops.js +8 -2
  124. package/dist/platform/ops/agents.ops.js +19 -6
  125. package/dist/platform/ops/conversations.ops.d.ts +3 -3
  126. package/dist/platform/ops/conversations.ops.js +9 -9
  127. package/dist/platform/ops/devices.ops.d.ts +26 -0
  128. package/dist/platform/ops/devices.ops.js +311 -0
  129. package/dist/platform/ops/org-settings.ops.js +2 -2
  130. package/dist/platform/ops/orgs.ops.js +1 -0
  131. package/dist/platform/ops/ui.ops.d.ts +8 -0
  132. package/dist/platform/ops/ui.ops.js +41 -0
  133. package/dist/platform/platform-ops.module.d.ts +3 -2
  134. package/dist/platform/platform-ops.module.js +8 -5
  135. package/dist/platform/route-schemas.js +6 -3
  136. package/dist/roles/gateway-role.d.ts +3 -3
  137. package/dist/roles/gateway-role.js +4 -4
  138. package/dist/roles/gateway.module.d.ts +1 -1
  139. package/dist/roles/gateway.module.js +5 -5
  140. package/dist/roles/worker.module.js +1 -1
  141. package/dist/runtime/context/build.d.ts +1 -1
  142. package/dist/runtime/context/build.js +6 -6
  143. package/dist/runtime/context/compaction.js +1 -1
  144. package/dist/runtime/context/{environment-paths.d.ts → device-paths.d.ts} +11 -11
  145. package/dist/runtime/context/{environment-paths.js → device-paths.js} +13 -13
  146. package/dist/runtime/maintenance.d.ts +1 -1
  147. package/dist/runtime/subagents/definition.d.ts +3 -2
  148. package/dist/runtime/subagents/definition.js +2 -1
  149. package/dist/sandbox/jobs.d.ts +13 -13
  150. package/dist/sandbox/jobs.js +20 -20
  151. package/dist/sandbox/leases.d.ts +9 -9
  152. package/dist/sandbox/leases.js +14 -14
  153. package/dist/sandbox/providers.d.ts +8 -8
  154. package/dist/sandbox/providers.js +8 -8
  155. package/dist/sandbox/sandbox.module.d.ts +1 -1
  156. package/dist/sandbox/sandbox.module.js +1 -1
  157. package/dist/sandbox/sandbox.service.d.ts +76 -76
  158. package/dist/sandbox/sandbox.service.js +230 -230
  159. package/dist/tools/builtins/builtin-tools.d.ts +2 -2
  160. package/dist/tools/builtins/builtin-tools.js +5 -5
  161. package/dist/tools/builtins/platform.js +1 -1
  162. package/dist/tools/builtins/sandbox/bash.js +6 -6
  163. package/dist/tools/builtins/sandbox/common.d.ts +25 -25
  164. package/dist/tools/builtins/sandbox/common.js +51 -51
  165. package/dist/tools/builtins/sandbox/edit.js +2 -2
  166. package/dist/tools/builtins/sandbox/index.d.ts +1 -1
  167. package/dist/tools/builtins/sandbox/index.js +1 -1
  168. package/dist/tools/builtins/sandbox/task-output.d.ts +6 -6
  169. package/dist/tools/builtins/sandbox/task-output.js +10 -10
  170. package/dist/tools/builtins/sandbox/task-stop.js +2 -2
  171. package/dist/tools/builtins/sandbox/write.js +2 -2
  172. package/dist/tools/builtins/skill-load.d.ts +1 -1
  173. package/dist/tools/builtins/skill-load.js +2 -2
  174. package/dist/tools/connector-account-policies.d.ts +51 -0
  175. package/dist/tools/connector-account-policies.js +165 -0
  176. package/dist/tools/connectors.controller.d.ts +35 -4
  177. package/dist/tools/connectors.controller.js +66 -7
  178. package/dist/tools/connectors.schemas.d.ts +11 -0
  179. package/dist/tools/connectors.schemas.js +11 -0
  180. package/dist/tools/connectors.service.d.ts +2 -0
  181. package/dist/tools/connectors.service.js +1 -0
  182. package/dist/tools/pipeline.d.ts +1 -1
  183. package/dist/tools/pipeline.js +4 -3
  184. package/dist/tools/policy.d.ts +23 -1
  185. package/dist/tools/policy.js +99 -24
  186. package/dist/tools/registry.d.ts +2 -2
  187. package/dist/tools/tools.module.js +6 -3
  188. package/dist/ui/admin-ui.controller.d.ts +56 -0
  189. package/dist/ui/admin-ui.controller.js +192 -0
  190. package/dist/ui/arrangement.d.ts +74 -0
  191. package/dist/ui/arrangement.js +98 -0
  192. package/dist/ui/embed-token.d.ts +2 -2
  193. package/dist/ui/embed-token.js +30 -5
  194. package/dist/ui/registry.d.ts +29 -14
  195. package/dist/ui/registry.js +31 -10
  196. package/dist/ui/slots.controller.d.ts +11 -0
  197. package/dist/ui/slots.controller.js +25 -0
  198. package/dist/ui/ui-stream.d.ts +20 -3
  199. package/dist/ui/ui-stream.js +25 -7
  200. package/dist/ui/ui.schemas.d.ts +66 -0
  201. package/dist/ui/ui.schemas.js +65 -0
  202. package/dist/ui/views.controller.d.ts +35 -49
  203. package/dist/ui/views.controller.js +48 -70
  204. package/dist/ui/views.d.ts +84 -18
  205. package/dist/ui/views.js +201 -38
  206. package/package.json +3 -3
  207. package/src/migrations/0104_connector_tool_account_policies.sql +16 -0
  208. package/src/migrations/0105_devices_rename.sql +136 -0
  209. package/dist/devices/device-auth.module.d.ts +0 -7
  210. package/dist/environments/conversation-environments.d.ts +0 -75
  211. package/dist/environments/dto.d.ts +0 -25
  212. package/dist/environments/dto.js +0 -12
  213. package/dist/environments/environments.controller.d.ts +0 -36
  214. package/dist/environments/environments.module.d.ts +0 -8
  215. package/dist/environments/environments.module.js +0 -31
  216. package/dist/environments/environments.schemas.d.ts +0 -3
  217. package/dist/environments/environments.schemas.js +0 -14
  218. package/dist/environments/label.d.ts +0 -11
  219. package/dist/platform/ops/environments.ops.d.ts +0 -26
  220. package/dist/platform/ops/environments.ops.js +0 -311
@@ -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 { environmentNotFound, sandboxUnavailable } from "../sandbox/sandbox.service.js";
17
- import { EnvironmentAccess } from "./access.js";
18
- import { EnvironmentsService } from "./environments.service.js";
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 ANONYMOUS_NO_ENVIRONMENT = "anonymous";
21
- /** Anonymous IM senders have no environment (spec §4.2 item 8): their sandbox tools are off. */
22
- export const anonymousNoEnvironment = () => new ApiError("sandbox.unavailable", "Anonymous IM senders have no environment, so the sandbox is not available", [{ reason: ANONYMOUS_NO_ENVIRONMENT }]);
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 environment 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 an environment of its owner
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 environment. Its sub-agents use the root's. Access is
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 environment, so a conversation never reaches another person's.
29
+ * may use a personal device, so a conversation never reaches another person's.
30
30
  */
31
- let ConversationEnvironments = class ConversationEnvironments {
31
+ let ConversationDevices = class ConversationDevices {
32
32
  db;
33
33
  txHost;
34
34
  providers;
35
35
  access;
36
- environments;
37
- constructor(db, txHost, providers, access, environments) {
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.environments = environments;
42
+ this.devices = devices;
43
43
  }
44
44
  /**
45
- * The environment a new conversation of `accountId` is bound to: the chosen one when it is
46
- * usable by the person (else `environment.not_found` / `environment.unavailable`, and nothing
47
- * is created); without a choice the IM default (IM only) or the person's default environment.
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 environment, say) applies.
49
+ * IM default (a connected machine's device, say) applies.
50
50
  */
51
51
  async forNew(orgId, accountId, pick = {}) {
52
- if (pick.environmentId !== undefined) {
53
- return (await this.access.usable(orgId, accountId, pick.environmentId)).id;
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 environment a sandbox tool call of the conversation tree rooted at `rootConversationId`
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
- * environments, 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 environment; a racing call binds it once.
66
- * Throws `sandbox.unavailable` for a cloud environment (or none to bind) without a cloud
67
- * provider and for an anonymous IM conversation, and `environment.not_found` /
68
- * `environment.unavailable` when the owner may not use it now. A conversation bound to a
69
- * connected machine's environment (`@device`) does not need a cloud provider.
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", "environment_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 environmentNotFound();
79
+ throw deviceNotFound();
80
80
  if (await this.isAnonymous(orgId, conv.account_id))
81
- throw anonymousNoEnvironment();
82
- let environmentId = conv.environment_id;
83
- if (environmentId === null) {
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
- environmentId = await this.bind(rootConversationId, chosen);
88
+ deviceId = await this.bind(rootConversationId, chosen);
89
89
  }
90
- if (this.providers.cloud() === undefined && !(await this.isInternal(environmentId))) {
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, environmentId)).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 environment the conversation is bound to (an unbound IM thread:
99
- * its owner's IM default) runs on a registered kernel provider (`@device`). A forbidden or gone
100
- * environment still counts: the call then says why.
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", "environment_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 environmentId = conv.environment_id;
114
- if (environmentId === null) {
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("environment_defaults")
119
- .select("environment_id")
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
- environmentId = row.environment_id;
125
+ deviceId = row.device_id;
126
126
  }
127
127
  const env = await this.db
128
- .selectFrom("environments")
128
+ .selectFrom("devices")
129
129
  .select("provider")
130
- .where("id", "=", environmentId)
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 environment (created when missing); null when
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 `environment.not_found`.
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("environment_defaults")
147
- .select("environment_id")
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.environment_id)).id;
153
+ return (await this.access.usable(orgId, accountId, row.device_id)).id;
154
154
  }
155
155
  catch (e) {
156
- if (!isEnvironmentGone(e))
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.environments.ensureDefault(orgId, accountId);
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 environmentNotFound();
168
+ throw deviceNotFound();
169
169
  throw e;
170
170
  }
171
171
  }
172
- /** Binds an unbound conversation to `environmentId`; returns what it is bound to now. */
173
- async bind(conversationId, environmentId) {
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({ environment_id: environmentId })
176
+ .set({ device_id: deviceId })
177
177
  .where("id", "=", conversationId)
178
- .where("environment_id", "is", null)
178
+ .where("device_id", "is", null)
179
179
  .execute();
180
180
  const row = await this.db
181
181
  .selectFrom("conversations")
182
- .select("environment_id")
182
+ .select("device_id")
183
183
  .where("id", "=", conversationId)
184
184
  .executeTakeFirstOrThrow();
185
- return row.environment_id ?? environmentId;
185
+ return row.device_id ?? deviceId;
186
186
  }
187
- /** The environment runs on a kernel-internal provider (`@device`). */
188
- async isInternal(environmentId) {
187
+ /** The device runs on a kernel-internal provider (`@local`). */
188
+ async isInternal(deviceId) {
189
189
  const row = await this.db
190
- .selectFrom("environments")
190
+ .selectFrom("devices")
191
191
  .select("provider")
192
- .where("id", "=", environmentId)
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
- ], ConversationEnvironments.prototype, "bind", null);
221
- ConversationEnvironments = __decorate([
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(EnvironmentAccess)),
227
- __param(4, Inject(EnvironmentsService))
228
- ], ConversationEnvironments);
229
- export { ConversationEnvironments };
230
- const isEnvironmentGone = (e) => e instanceof ApiError &&
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
+ }
@@ -11,58 +11,58 @@ import { Controller, Delete, Get, HttpCode, Inject, Patch, Post } from "@nestjs/
11
11
  import { CurrentPrincipal, patTokenId, requireUser, } from "../identity/principal.js";
12
12
  import { ZBody, ZParam } from "../infra/validation/zod-params.js";
13
13
  import { CurrentOrg, OrgAction } from "../orgs/org.guard.js";
14
- import { EnvironmentCreateBodyDto, EnvironmentParamsDto, EnvironmentRenameBodyDto, } from "./dto.js";
15
- import { EnvironmentsService, } from "./environments.service.js";
14
+ import { DevicesService } from "./devices.service.js";
15
+ import { DeviceCreateBodyDto, DeviceParamsDto, DeviceRenameBodyDto, } from "./dto.js";
16
16
  /**
17
- * A person's environments in an org (`/api/v1/orgs/:orgId/environments`, spec
17
+ * A person's devices in an org (`/api/v1/orgs/:orgId/devices`, spec
18
18
  * 2026-11-07-environments-design §9; `agents.use`, human users only: a service token gets 403).
19
- * Phase 1 has personal cloud environments only, each visible to its owner alone: another member
20
- * gets 404 `environment.not_found`.
19
+ * Phase 1 has personal cloud devices only, each visible to its owner alone: another member
20
+ * gets 404 `device.not_found`.
21
21
  * - `GET /` → `{ items, defaultId, lastUsedId, cloudAvailable }` (`cloudAvailable`: there is a
22
22
  * current sandbox provider; ruling R4);
23
- * - `POST / { name }` → 201 `{ environment }`; `GET /:id`, `PATCH /:id { name }` → `{ environment }`;
23
+ * - `POST / { name }` → 201 `{ device }`; `GET /:id`, `PATCH /:id { name }` → `{ device }`;
24
24
  * - `DELETE /:id` → 202 (destroyed by a job after the response);
25
25
  * - `POST /:id/files/reset` → 202 (the reset is enqueued: a worker empties the files, the next use
26
26
  * starts empty);
27
- * - `DELETE /:id/machine` → 204: a device environment's machine is disconnected (its credential
27
+ * - `DELETE /:id/machine` → 204: a local device's machine is disconnected (its credential
28
28
  * revoked; it must sign in again).
29
29
  */
30
- let EnvironmentsController = class EnvironmentsController {
31
- environments;
32
- constructor(environments) {
33
- this.environments = environments;
30
+ let DevicesController = class DevicesController {
31
+ devices;
32
+ constructor(devices) {
33
+ this.devices = devices;
34
34
  }
35
35
  async list(principal, org) {
36
36
  const p = requireUser(principal);
37
- return this.environments.list(org.orgId, p.account.id);
37
+ return this.devices.list(org.orgId, p.account.id);
38
38
  }
39
39
  async create(principal, org, body) {
40
40
  const p = requireUser(principal);
41
41
  return {
42
- environment: await this.environments.create(org.orgId, p.account.id, { name: body.name }, patTokenId(p)),
42
+ device: await this.devices.create(org.orgId, p.account.id, { name: body.name }, patTokenId(p)),
43
43
  };
44
44
  }
45
45
  async get(principal, org, params) {
46
46
  const p = requireUser(principal);
47
- return { environment: await this.environments.get(org.orgId, p.account.id, params.id) };
47
+ return { device: await this.devices.get(org.orgId, p.account.id, params.id) };
48
48
  }
49
49
  async rename(principal, org, params, body) {
50
50
  const p = requireUser(principal);
51
51
  return {
52
- environment: await this.environments.rename(org.orgId, p.account.id, params.id, body.name, patTokenId(p)),
52
+ device: await this.devices.rename(org.orgId, p.account.id, params.id, body.name, patTokenId(p)),
53
53
  };
54
54
  }
55
55
  async remove(principal, org, params) {
56
56
  const p = requireUser(principal);
57
- await this.environments.remove(org.orgId, p.account.id, params.id, patTokenId(p));
57
+ await this.devices.remove(org.orgId, p.account.id, params.id, patTokenId(p));
58
58
  }
59
59
  async resetFiles(principal, org, params) {
60
60
  const p = requireUser(principal);
61
- await this.environments.resetFiles(org.orgId, p.account.id, params.id, patTokenId(p));
61
+ await this.devices.resetFiles(org.orgId, p.account.id, params.id, patTokenId(p));
62
62
  }
63
63
  async revokeMachine(principal, org, params) {
64
64
  const p = requireUser(principal);
65
- await this.environments.revokeMachine(org.orgId, p.account.id, params.id, patTokenId(p));
65
+ await this.devices.revokeMachine(org.orgId, p.account.id, params.id, patTokenId(p));
66
66
  }
67
67
  };
68
68
  __decorate([
@@ -70,55 +70,55 @@ __decorate([
70
70
  OrgAction("agents.use"),
71
71
  __param(0, CurrentPrincipal()),
72
72
  __param(1, CurrentOrg())
73
- ], EnvironmentsController.prototype, "list", null);
73
+ ], DevicesController.prototype, "list", null);
74
74
  __decorate([
75
75
  Post(),
76
76
  OrgAction("agents.use"),
77
77
  __param(0, CurrentPrincipal()),
78
78
  __param(1, CurrentOrg()),
79
- __param(2, ZBody(EnvironmentCreateBodyDto))
80
- ], EnvironmentsController.prototype, "create", null);
79
+ __param(2, ZBody(DeviceCreateBodyDto))
80
+ ], DevicesController.prototype, "create", null);
81
81
  __decorate([
82
82
  Get(":id"),
83
83
  OrgAction("agents.use"),
84
84
  __param(0, CurrentPrincipal()),
85
85
  __param(1, CurrentOrg()),
86
- __param(2, ZParam(EnvironmentParamsDto))
87
- ], EnvironmentsController.prototype, "get", null);
86
+ __param(2, ZParam(DeviceParamsDto))
87
+ ], DevicesController.prototype, "get", null);
88
88
  __decorate([
89
89
  Patch(":id"),
90
90
  OrgAction("agents.use"),
91
91
  __param(0, CurrentPrincipal()),
92
92
  __param(1, CurrentOrg()),
93
- __param(2, ZParam(EnvironmentParamsDto)),
94
- __param(3, ZBody(EnvironmentRenameBodyDto))
95
- ], EnvironmentsController.prototype, "rename", null);
93
+ __param(2, ZParam(DeviceParamsDto)),
94
+ __param(3, ZBody(DeviceRenameBodyDto))
95
+ ], DevicesController.prototype, "rename", null);
96
96
  __decorate([
97
97
  Delete(":id"),
98
98
  HttpCode(202),
99
99
  OrgAction("agents.use"),
100
100
  __param(0, CurrentPrincipal()),
101
101
  __param(1, CurrentOrg()),
102
- __param(2, ZParam(EnvironmentParamsDto))
103
- ], EnvironmentsController.prototype, "remove", null);
102
+ __param(2, ZParam(DeviceParamsDto))
103
+ ], DevicesController.prototype, "remove", null);
104
104
  __decorate([
105
105
  Post(":id/files/reset"),
106
106
  HttpCode(202),
107
107
  OrgAction("agents.use"),
108
108
  __param(0, CurrentPrincipal()),
109
109
  __param(1, CurrentOrg()),
110
- __param(2, ZParam(EnvironmentParamsDto))
111
- ], EnvironmentsController.prototype, "resetFiles", null);
110
+ __param(2, ZParam(DeviceParamsDto))
111
+ ], DevicesController.prototype, "resetFiles", null);
112
112
  __decorate([
113
113
  Delete(":id/machine"),
114
114
  HttpCode(204),
115
115
  OrgAction("agents.use"),
116
116
  __param(0, CurrentPrincipal()),
117
117
  __param(1, CurrentOrg()),
118
- __param(2, ZParam(EnvironmentParamsDto))
119
- ], EnvironmentsController.prototype, "revokeMachine", null);
120
- EnvironmentsController = __decorate([
121
- Controller("api/v1/orgs/:orgId/environments"),
122
- __param(0, Inject(EnvironmentsService))
123
- ], EnvironmentsController);
124
- export { EnvironmentsController };
118
+ __param(2, ZParam(DeviceParamsDto))
119
+ ], DevicesController.prototype, "revokeMachine", null);
120
+ DevicesController = __decorate([
121
+ Controller("api/v1/orgs/:orgId/devices"),
122
+ __param(0, Inject(DevicesService))
123
+ ], DevicesController);
124
+ export { DevicesController };
@@ -1,16 +1,8 @@
1
- import { type OnModuleInit } from "@nestjs/common";
2
- import { SandboxProviders } from "../sandbox/providers.js";
3
- import { DeviceSandboxProvider } from "./device-provider.js";
4
1
  /**
5
- * Connected machines (environments spec §6, §13): the caller side of the device relay and the
6
- * kernel-internal `@device` sandbox provider, registered with {@link SandboxProviders} on init, and
7
- * the machines and their credentials ({@link MachinesService}).
8
- * Imported on every role: any replica may run a sandbox operation on a connected environment
9
- * (the socket itself is held by the gateway role).
2
+ * Devices (spec 2026-11-07-environments-design): a person's devices
3
+ * ({@link DevicesService}), who may use one ({@link DeviceAccess}) and the one a
4
+ * conversation works in ({@link ConversationDevices}). The instances and file systems are the
5
+ * {@link SandboxModule}'s.
10
6
  */
11
- export declare class DevicesModule implements OnModuleInit {
12
- private readonly providers;
13
- private readonly device;
14
- constructor(providers: SandboxProviders, device: DeviceSandboxProvider);
15
- onModuleInit(): void;
7
+ export declare class DevicesModule {
16
8
  }
@@ -4,41 +4,28 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- var __param = (this && this.__param) || function (paramIndex, decorator) {
8
- return function (target, key) { decorator(target, key, paramIndex); }
9
- };
10
- import { Inject, Module } from "@nestjs/common";
11
- import { DEVICE_PROVIDER, SandboxProviders } from "../sandbox/providers.js";
7
+ import { Module } from "@nestjs/common";
8
+ import { ExtensionsModule } from "../extensions/extensions.module.js";
9
+ import { LocalDevicesModule } from "../local-devices/local-devices.module.js";
12
10
  import { SandboxModule } from "../sandbox/sandbox.module.js";
13
- import { DeviceSandboxProvider } from "./device-provider.js";
14
- import { MachinesService } from "./machines.js";
15
- import { DeviceRelay } from "./relay.js";
16
- import { DeviceTargets } from "./targets.js";
11
+ import { DeviceAccess } from "./access.js";
12
+ import { ConversationDevices } from "./conversation-devices.js";
13
+ import { DevicesService } from "./devices.service.js";
17
14
  /**
18
- * Connected machines (environments spec §6, §13): the caller side of the device relay and the
19
- * kernel-internal `@device` sandbox provider, registered with {@link SandboxProviders} on init, and
20
- * the machines and their credentials ({@link MachinesService}).
21
- * Imported on every role: any replica may run a sandbox operation on a connected environment
22
- * (the socket itself is held by the gateway role).
15
+ * Devices (spec 2026-11-07-environments-design): a person's devices
16
+ * ({@link DevicesService}), who may use one ({@link DeviceAccess}) and the one a
17
+ * conversation works in ({@link ConversationDevices}). The instances and file systems are the
18
+ * {@link SandboxModule}'s.
23
19
  */
24
20
  let DevicesModule = class DevicesModule {
25
- providers;
26
- device;
27
- constructor(providers, device) {
28
- this.providers = providers;
29
- this.device = device;
30
- }
31
- onModuleInit() {
32
- this.providers.register({ plugin: DEVICE_PROVIDER, impl: this.device });
33
- }
34
21
  };
35
22
  DevicesModule = __decorate([
36
23
  Module({
37
- imports: [SandboxModule],
38
- providers: [DeviceTargets, DeviceRelay, DeviceSandboxProvider, MachinesService],
39
- exports: [DeviceRelay, DeviceSandboxProvider, MachinesService],
40
- }),
41
- __param(0, Inject(SandboxProviders)),
42
- __param(1, Inject(DeviceSandboxProvider))
24
+ // ExtensionsModule: the provider display names of demoted defaults; LocalDevicesModule: deleting
25
+ // a local device revokes its machine
26
+ imports: [SandboxModule, ExtensionsModule, LocalDevicesModule],
27
+ providers: [DeviceAccess, DevicesService, ConversationDevices],
28
+ exports: [DeviceAccess, DevicesService, ConversationDevices],
29
+ })
43
30
  ], DevicesModule);
44
31
  export { DevicesModule };
@@ -0,0 +1,3 @@
1
+ import type { RouteSchemas } from "../platform/route-schemas.js";
2
+ /** The devices routes the Platform operations mirror (`check:platform-ops` keys). */
3
+ export declare const DEVICE_ROUTES: readonly RouteSchemas[];
@@ -0,0 +1,14 @@
1
+ import { DeviceNameBody, DeviceParams } from "./dto.js";
2
+ /** The devices routes the Platform operations mirror (`check:platform-ops` keys). */
3
+ export const DEVICE_ROUTES = [
4
+ { route: "GET /api/v1/orgs/:orgId/devices" },
5
+ { route: "POST /api/v1/orgs/:orgId/devices", body: DeviceNameBody },
6
+ { route: "GET /api/v1/orgs/:orgId/devices/:id", params: DeviceParams },
7
+ {
8
+ route: "PATCH /api/v1/orgs/:orgId/devices/:id",
9
+ params: DeviceParams,
10
+ body: DeviceNameBody,
11
+ },
12
+ { route: "DELETE /api/v1/orgs/:orgId/devices/:id", params: DeviceParams },
13
+ { route: "POST /api/v1/orgs/:orgId/devices/:id/files/reset", params: DeviceParams },
14
+ ];