@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.
Files changed (267) 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/background/background.module.js +2 -2
  5. package/dist/background/launch-lock.d.ts +1 -1
  6. package/dist/background/launch-lock.js +1 -1
  7. package/dist/background/poll.job.d.ts +2 -2
  8. package/dist/background/poll.job.js +10 -10
  9. package/dist/background/stop.d.ts +1 -1
  10. package/dist/background/stop.js +3 -3
  11. package/dist/background/store.d.ts +5 -5
  12. package/dist/background/store.js +5 -5
  13. package/dist/background/tasks.service.d.ts +6 -6
  14. package/dist/background/tasks.service.js +13 -13
  15. package/dist/catalog/admin-catalog.controller.d.ts +13 -2
  16. package/dist/catalog/admin-catalog.controller.js +24 -3
  17. package/dist/catalog/admin-catalog.schemas.d.ts +10 -0
  18. package/dist/catalog/admin-catalog.schemas.js +7 -0
  19. package/dist/catalog/catalog-content.d.ts +9 -1
  20. package/dist/catalog/catalog-content.js +2 -1
  21. package/dist/catalog/catalog-files.d.ts +3 -2
  22. package/dist/catalog/catalog-files.js +8 -5
  23. package/dist/catalog/component-scope.service.d.ts +14 -1
  24. package/dist/catalog/component-scope.service.js +12 -2
  25. package/dist/catalog/marketplaces.service.d.ts +1 -1
  26. package/dist/catalog/org-catalog.controller.d.ts +5 -4
  27. package/dist/catalog/org-catalog.controller.js +5 -4
  28. package/dist/catalog/org-catalog.schemas.d.ts +18 -2
  29. package/dist/catalog/org-catalog.schemas.js +16 -2
  30. package/dist/catalog/org-catalog.service.js +8 -2
  31. package/dist/catalog/plugin-import.js +1 -1
  32. package/dist/catalog/plugin-package.js +37 -9
  33. package/dist/catalog/plugin-upgrade.d.ts +15 -1
  34. package/dist/catalog/plugin-upgrade.js +18 -5
  35. package/dist/channels/channels.module.js +2 -2
  36. package/dist/channels/connections.controller.d.ts +1 -1
  37. package/dist/channels/connections.controller.js +1 -1
  38. package/dist/channels/connections.service.d.ts +22 -5
  39. package/dist/channels/connections.service.js +56 -10
  40. package/dist/channels/inbound.d.ts +8 -8
  41. package/dist/channels/inbound.js +31 -31
  42. package/dist/channels/phrases.d.ts +27 -27
  43. package/dist/channels/phrases.js +27 -27
  44. package/dist/channels/webhook.d.ts +21 -1
  45. package/dist/channels/webhook.js +39 -4
  46. package/dist/config/docs.js +1 -1
  47. package/dist/config/schema.d.ts +2 -2
  48. package/dist/config/schema.js +21 -21
  49. package/dist/conversations/conversations.controller.d.ts +11 -11
  50. package/dist/conversations/conversations.controller.js +15 -15
  51. package/dist/conversations/conversations.module.d.ts +1 -1
  52. package/dist/conversations/conversations.module.js +7 -7
  53. package/dist/conversations/conversations.schemas.js +1 -1
  54. package/dist/conversations/conversations.service.d.ts +14 -14
  55. package/dist/conversations/conversations.service.js +19 -19
  56. package/dist/conversations/{environment-status.d.ts → device-status.d.ts} +9 -9
  57. package/dist/conversations/{environment-status.js → device-status.js} +18 -18
  58. package/dist/conversations/event-log.d.ts +1 -1
  59. package/dist/conversations/event-log.js +1 -1
  60. package/dist/conversations/events.d.ts +1 -1
  61. package/dist/conversations/events.js +2 -2
  62. package/dist/ctx/create-ctx.d.ts +26 -3
  63. package/dist/ctx/create-ctx.js +134 -26
  64. package/dist/db/kernel-schema.d.ts +37 -25
  65. package/dist/{environments → devices}/access.d.ts +19 -19
  66. package/dist/{environments → devices}/access.js +28 -28
  67. package/dist/devices/conversation-devices.d.ts +75 -0
  68. package/dist/{environments/conversation-environments.js → devices/conversation-devices.js} +71 -72
  69. package/dist/devices/devices.controller.d.ts +36 -0
  70. package/dist/{environments/environments.controller.js → devices/devices.controller.js} +37 -37
  71. package/dist/devices/devices.module.d.ts +5 -13
  72. package/dist/devices/devices.module.js +16 -29
  73. package/dist/devices/devices.schemas.d.ts +3 -0
  74. package/dist/devices/devices.schemas.js +14 -0
  75. package/dist/{environments/environments.service.d.ts → devices/devices.service.d.ts} +70 -70
  76. package/dist/{environments/environments.service.js → devices/devices.service.js} +122 -122
  77. package/dist/devices/dto.d.ts +13 -54
  78. package/dist/devices/dto.js +7 -39
  79. package/dist/devices/label.d.ts +11 -0
  80. package/dist/{environments → devices}/label.js +7 -7
  81. package/dist/{environments → devices}/legacy-cleanup.job.d.ts +3 -3
  82. package/dist/{environments → devices}/legacy-cleanup.job.js +3 -3
  83. package/dist/errors.d.ts +29 -25
  84. package/dist/errors.js +29 -25
  85. package/dist/evals/recorded-tools.d.ts +2 -2
  86. package/dist/evals/recorded-tools.js +6 -6
  87. package/dist/extensions/admin-ops.js +1 -0
  88. package/dist/extensions/admin-view.js +2 -0
  89. package/dist/extensions/effective-config.d.ts +6 -0
  90. package/dist/extensions/effective-config.js +18 -7
  91. package/dist/extensions/guide-places.d.ts +66 -0
  92. package/dist/extensions/guide-places.js +152 -0
  93. package/dist/extensions/host.d.ts +13 -2
  94. package/dist/extensions/host.js +27 -6
  95. package/dist/extensions/instance.d.ts +17 -2
  96. package/dist/extensions/instance.js +21 -0
  97. package/dist/extensions/ledger.d.ts +1 -1
  98. package/dist/extensions/permission-set.d.ts +16 -2
  99. package/dist/extensions/permission-set.js +17 -3
  100. package/dist/extensions/permission-view.d.ts +10 -1
  101. package/dist/extensions/plugin-guides.d.ts +207 -54
  102. package/dist/extensions/plugin-guides.js +436 -165
  103. package/dist/files/previewers.d.ts +1 -1
  104. package/dist/files/previewers.js +1 -1
  105. package/dist/http/api.module.js +16 -6
  106. package/dist/http/gateway-routes.d.ts +1 -1
  107. package/dist/http/gateway-routes.js +1 -1
  108. package/dist/identity/settings.d.ts +32 -0
  109. package/dist/identity/settings.js +26 -2
  110. package/dist/infra/config/kernel-config.service.js +4 -4
  111. package/dist/infra/lock/lock.service.d.ts +8 -0
  112. package/dist/infra/lock/lock.service.js +27 -0
  113. package/dist/infra/throttler/named-throttlers.d.ts +4 -1
  114. package/dist/infra/throttler/named-throttlers.js +16 -1
  115. package/dist/infra/throttler/throttler.guard.js +1 -1
  116. package/dist/kernel.module.js +3 -3
  117. package/dist/{devices → local-devices}/device-auth.controller.d.ts +6 -6
  118. package/dist/{devices → local-devices}/device-auth.controller.js +5 -5
  119. package/dist/{devices → local-devices}/device-auth.d.ts +20 -20
  120. package/dist/{devices → local-devices}/device-auth.js +51 -53
  121. package/dist/local-devices/device-auth.module.d.ts +7 -0
  122. package/dist/{devices → local-devices}/device-auth.module.js +5 -5
  123. package/dist/{devices → local-devices}/device-routes.d.ts +3 -3
  124. package/dist/{devices → local-devices}/device-routes.js +2 -2
  125. package/dist/local-devices/dto.d.ts +66 -0
  126. package/dist/local-devices/dto.js +44 -0
  127. package/dist/{devices → local-devices}/keys.d.ts +11 -11
  128. package/dist/{devices → local-devices}/keys.js +11 -11
  129. package/dist/{devices/device-gateway.d.ts → local-devices/local-device-gateway.d.ts} +14 -14
  130. package/dist/{devices/device-gateway.js → local-devices/local-device-gateway.js} +44 -44
  131. package/dist/{devices/device-provider.d.ts → local-devices/local-device-provider.d.ts} +15 -15
  132. package/dist/{devices/device-provider.js → local-devices/local-device-provider.js} +23 -23
  133. package/dist/local-devices/local-devices.module.d.ts +16 -0
  134. package/dist/local-devices/local-devices.module.js +44 -0
  135. package/dist/{devices → local-devices}/machines.d.ts +26 -26
  136. package/dist/{devices → local-devices}/machines.js +71 -71
  137. package/dist/{devices → local-devices}/relay.d.ts +15 -15
  138. package/dist/{devices → local-devices}/relay.js +55 -55
  139. package/dist/{devices → local-devices}/targets.d.ts +8 -8
  140. package/dist/{devices → local-devices}/targets.js +14 -14
  141. package/dist/orgs/offboarding.d.ts +6 -6
  142. package/dist/orgs/offboarding.js +12 -12
  143. package/dist/orgs/settings.service.d.ts +28 -0
  144. package/dist/orgs/settings.service.js +20 -1
  145. package/dist/overrides.d.ts +3 -1
  146. package/dist/overrides.js +2 -0
  147. package/dist/platform/exclusions.js +48 -8
  148. package/dist/platform/operation.js +10 -2
  149. package/dist/platform/ops/admin.ops.js +8 -2
  150. package/dist/platform/ops/connectors.ops.js +2 -0
  151. package/dist/platform/ops/conversations.ops.d.ts +3 -3
  152. package/dist/platform/ops/conversations.ops.js +9 -9
  153. package/dist/platform/ops/devices.ops.d.ts +26 -0
  154. package/dist/platform/ops/devices.ops.js +311 -0
  155. package/dist/platform/ops/org-settings.ops.js +2 -2
  156. package/dist/platform/ops/orgs.ops.js +1 -0
  157. package/dist/platform/ops/setup.ops.d.ts +24 -0
  158. package/dist/platform/ops/setup.ops.js +212 -0
  159. package/dist/platform/ops/ui.ops.d.ts +8 -0
  160. package/dist/platform/ops/ui.ops.js +41 -0
  161. package/dist/platform/platform-ops.module.d.ts +4 -2
  162. package/dist/platform/platform-ops.module.js +13 -5
  163. package/dist/platform/route-schemas.js +11 -3
  164. package/dist/roles/gateway-role.d.ts +3 -3
  165. package/dist/roles/gateway-role.js +4 -4
  166. package/dist/roles/gateway.module.d.ts +1 -1
  167. package/dist/roles/gateway.module.js +5 -5
  168. package/dist/roles/worker.module.js +1 -1
  169. package/dist/runtime/context/build.d.ts +1 -1
  170. package/dist/runtime/context/build.js +6 -6
  171. package/dist/runtime/context/compaction.js +1 -1
  172. package/dist/runtime/context/{environment-paths.d.ts → device-paths.d.ts} +11 -11
  173. package/dist/runtime/context/{environment-paths.js → device-paths.js} +13 -13
  174. package/dist/runtime/maintenance.d.ts +1 -1
  175. package/dist/sandbox/jobs.d.ts +13 -13
  176. package/dist/sandbox/jobs.js +20 -20
  177. package/dist/sandbox/leases.d.ts +9 -9
  178. package/dist/sandbox/leases.js +14 -14
  179. package/dist/sandbox/providers.d.ts +8 -8
  180. package/dist/sandbox/providers.js +8 -8
  181. package/dist/sandbox/sandbox.module.d.ts +1 -1
  182. package/dist/sandbox/sandbox.module.js +1 -1
  183. package/dist/sandbox/sandbox.service.d.ts +76 -76
  184. package/dist/sandbox/sandbox.service.js +230 -230
  185. package/dist/setup/kernel-checks.d.ts +91 -0
  186. package/dist/setup/kernel-checks.js +295 -0
  187. package/dist/setup/oauth-token-probe.d.ts +47 -0
  188. package/dist/setup/oauth-token-probe.js +108 -0
  189. package/dist/setup/redact-check.d.ts +18 -0
  190. package/dist/setup/redact-check.js +46 -0
  191. package/dist/setup/setup-check-registry.d.ts +86 -0
  192. package/dist/setup/setup-check-registry.js +75 -0
  193. package/dist/setup/setup-checks.controller.d.ts +28 -0
  194. package/dist/setup/setup-checks.controller.js +78 -0
  195. package/dist/setup/setup-checks.schemas.d.ts +38 -0
  196. package/dist/setup/setup-checks.schemas.js +43 -0
  197. package/dist/setup/setup-checks.service.d.ts +144 -0
  198. package/dist/setup/setup-checks.service.js +683 -0
  199. package/dist/setup/setup-guides.controller.d.ts +18 -0
  200. package/dist/setup/setup-guides.controller.js +48 -0
  201. package/dist/setup/setup-guides.schemas.d.ts +10 -0
  202. package/dist/setup/setup-guides.schemas.js +6 -0
  203. package/dist/setup/setup-guides.service.d.ts +126 -0
  204. package/dist/setup/setup-guides.service.js +315 -0
  205. package/dist/setup/setup.module.d.ts +8 -0
  206. package/dist/setup/setup.module.js +31 -0
  207. package/dist/tools/builtins/builtin-tools.d.ts +2 -2
  208. package/dist/tools/builtins/builtin-tools.js +5 -5
  209. package/dist/tools/builtins/platform.js +1 -1
  210. package/dist/tools/builtins/sandbox/bash.js +6 -6
  211. package/dist/tools/builtins/sandbox/common.d.ts +25 -25
  212. package/dist/tools/builtins/sandbox/common.js +51 -51
  213. package/dist/tools/builtins/sandbox/edit.js +2 -2
  214. package/dist/tools/builtins/sandbox/index.d.ts +1 -1
  215. package/dist/tools/builtins/sandbox/index.js +1 -1
  216. package/dist/tools/builtins/sandbox/task-output.d.ts +6 -6
  217. package/dist/tools/builtins/sandbox/task-output.js +10 -10
  218. package/dist/tools/builtins/sandbox/task-stop.js +2 -2
  219. package/dist/tools/builtins/sandbox/write.js +2 -2
  220. package/dist/tools/builtins/skill-load.d.ts +1 -1
  221. package/dist/tools/builtins/skill-load.js +2 -2
  222. package/dist/tools/connectors.controller.d.ts +28 -11
  223. package/dist/tools/connectors.controller.js +49 -14
  224. package/dist/tools/connectors.schemas.d.ts +4 -0
  225. package/dist/tools/connectors.schemas.js +4 -0
  226. package/dist/tools/connectors.service.d.ts +30 -2
  227. package/dist/tools/connectors.service.js +98 -3
  228. package/dist/tools/credentials.d.ts +20 -0
  229. package/dist/tools/credentials.js +90 -1
  230. package/dist/tools/oauth/tokens.d.ts +20 -0
  231. package/dist/tools/oauth/tokens.js +49 -24
  232. package/dist/tools/pipeline.js +4 -3
  233. package/dist/tools/registry.d.ts +2 -2
  234. package/dist/tools/tools.module.js +3 -3
  235. package/dist/ui/admin-ui.controller.d.ts +56 -0
  236. package/dist/ui/admin-ui.controller.js +192 -0
  237. package/dist/ui/arrangement.d.ts +74 -0
  238. package/dist/ui/arrangement.js +98 -0
  239. package/dist/ui/embed-token.d.ts +2 -2
  240. package/dist/ui/embed-token.js +30 -5
  241. package/dist/ui/registry.d.ts +29 -14
  242. package/dist/ui/registry.js +31 -10
  243. package/dist/ui/slots.controller.d.ts +11 -0
  244. package/dist/ui/slots.controller.js +25 -0
  245. package/dist/ui/ui-stream.d.ts +20 -3
  246. package/dist/ui/ui-stream.js +25 -7
  247. package/dist/ui/ui.schemas.d.ts +66 -0
  248. package/dist/ui/ui.schemas.js +65 -0
  249. package/dist/ui/views.controller.d.ts +35 -49
  250. package/dist/ui/views.controller.js +48 -70
  251. package/dist/ui/views.d.ts +84 -18
  252. package/dist/ui/views.js +201 -38
  253. package/package.json +3 -3
  254. package/src/migrations/0105_devices_rename.sql +136 -0
  255. package/src/migrations/0106_setup_guides_v2.sql +10 -0
  256. package/dist/devices/device-auth.module.d.ts +0 -7
  257. package/dist/environments/conversation-environments.d.ts +0 -75
  258. package/dist/environments/dto.d.ts +0 -25
  259. package/dist/environments/dto.js +0 -12
  260. package/dist/environments/environments.controller.d.ts +0 -36
  261. package/dist/environments/environments.module.d.ts +0 -8
  262. package/dist/environments/environments.module.js +0 -31
  263. package/dist/environments/environments.schemas.d.ts +0 -3
  264. package/dist/environments/environments.schemas.js +0 -14
  265. package/dist/environments/label.d.ts +0 -11
  266. package/dist/platform/ops/environments.ops.d.ts +0 -26
  267. package/dist/platform/ops/environments.ops.js +0 -311
package/dist/overrides.js CHANGED
@@ -10,6 +10,7 @@ import { RUN_HOOKS } from "./runtime/run-worker.js";
10
10
  import { SUBAGENT_MESSAGES_HOOKS, } from "./runtime/subagents/messages.js";
11
11
  import { USAGE_REPORT_RETRY } from "./runtime/usage-report.js";
12
12
  import { SANDBOX_LEASE_TIMINGS } from "./sandbox/leases.js";
13
+ import { SETUP_CHECK_TIMEOUT } from "./setup/setup-checks.service.js";
13
14
  import { TOOL_PIPELINE_HOOKS } from "./tools/pipeline.js";
14
15
  import { EMBED_TOKEN_CLOCK } from "./ui/embed-token.js";
15
16
  const SEAM_TOKENS = [
@@ -24,6 +25,7 @@ const SEAM_TOKENS = [
24
25
  USAGE_REPORT_RETRY,
25
26
  SANDBOX_LEASE_TIMINGS,
26
27
  CHANNEL_WEBHOOK_TIMINGS,
28
+ SETUP_CHECK_TIMEOUT,
27
29
  EMBED_TOKEN_CLOCK,
28
30
  RUN_CONTEXT_CLOCK,
29
31
  APP_INTERCEPTOR,
@@ -95,6 +95,11 @@ export const PLATFORM_EXCLUSIONS = [
95
95
  category: "transport",
96
96
  reason: "Serves icon image bytes",
97
97
  },
98
+ {
99
+ route: "GET /api/v1/admin/catalog/:itemId/guides/:guideId",
100
+ category: "internal",
101
+ reason: "The super admin's preview of a plugin's setup guide for the admin console, with no org and no target; agents assist with the org guides an org member sees",
102
+ },
98
103
  {
99
104
  route: "POST /api/v1/admin/catalog/items/:id/confirm",
100
105
  category: "human-only",
@@ -128,11 +133,6 @@ export const PLATFORM_EXCLUSIONS = [
128
133
  category: "transport",
129
134
  reason: "Serves icon image bytes",
130
135
  },
131
- {
132
- route: "GET /api/v1/orgs/:orgId/catalog/:itemId/guides/:guideId",
133
- category: "internal",
134
- reason: "A plugin's setup guide (an app manifest, URLs, steps) for the web's setup section; a person pastes it into the third-party platform's console, which an agent cannot reach",
135
- },
136
136
  {
137
137
  route: "POST /api/v1/orgs/:orgId/catalog/:itemId/install",
138
138
  category: "secret",
@@ -267,14 +267,14 @@ export const PLATFORM_EXCLUSIONS = [
267
267
  category: "transport",
268
268
  reason: "Serves sandbox file bytes",
269
269
  },
270
- // environments (personal cloud environments, environments design phase 1)
270
+ // devices (personal cloud devices, environments design phase 1)
271
271
  // connected machines (environments design phase 2): device sign-in by the program and on the
272
272
  // confirmation page, and disconnecting a machine. The machine's WebSocket (`GET /device/connect`)
273
273
  // is a raw gateway-role route, not a Nest controller, so it is not listed (like the webhook)
274
274
  {
275
- route: "DELETE /api/v1/orgs/:orgId/environments/:id/machine",
275
+ route: "DELETE /api/v1/orgs/:orgId/devices/:id/machine",
276
276
  category: "human-only",
277
- reason: "Disconnects a person's own machine (revokes its credential); a trust decision taken on the environment's page",
277
+ reason: "Disconnects a person's own machine (revokes its credential); a trust decision taken on the device's page",
278
278
  },
279
279
  {
280
280
  route: "POST /api/v1/device/authorize",
@@ -593,6 +593,11 @@ export const PLATFORM_EXCLUSIONS = [
593
593
  category: "secret",
594
594
  reason: "Edits connector endpoint config that can carry credentials",
595
595
  },
596
+ {
597
+ route: "POST /api/v1/orgs/:orgId/connectors/:connectorId/guide-ack",
598
+ category: "human-only",
599
+ reason: "A person confirms they updated the app on the third-party platform after a connector template's setup guide changed; only that person knows it was done",
600
+ },
596
601
  {
597
602
  route: "POST /api/v1/orgs/:orgId/connectors/:connectorId/tools/:name/review",
598
603
  category: "human-only",
@@ -654,6 +659,11 @@ export const PLATFORM_EXCLUSIONS = [
654
659
  category: "internal",
655
660
  reason: "Navigation entries of the web shell (panels, pages, embeds); nothing an agent acts on",
656
661
  },
662
+ {
663
+ route: "GET /api/v1/orgs/:orgId/ui/arrangement",
664
+ category: "internal",
665
+ reason: "Listing for the 界面位置 page; the arrangement is read and written through org-settings / admin settings",
666
+ },
657
667
  {
658
668
  route: "GET /api/v1/orgs/:orgId/ui/views/:plugin/:id",
659
669
  category: "transport",
@@ -674,6 +684,36 @@ export const PLATFORM_EXCLUSIONS = [
674
684
  category: "transport",
675
685
  reason: "Server-sent event stream of UI invalidations",
676
686
  },
687
+ {
688
+ route: "GET /api/v1/admin/ui/contributions",
689
+ category: "internal",
690
+ reason: "Navigation entries of the admin console (platform pages)",
691
+ },
692
+ {
693
+ route: "GET /api/v1/admin/ui/arrangement",
694
+ category: "internal",
695
+ reason: "Listing for the 界面位置 page; the arrangement is read and written through org-settings / admin settings",
696
+ },
697
+ {
698
+ route: "GET /api/v1/admin/ui/views/:plugin/:id",
699
+ category: "transport",
700
+ reason: "Renders an extension UI view for the web app",
701
+ },
702
+ {
703
+ route: "POST /api/v1/admin/ui/actions/:plugin/:id",
704
+ category: "transport",
705
+ reason: "Runs an extension UI action from the web app",
706
+ },
707
+ {
708
+ route: "POST /api/v1/admin/ui/embeds/:plugin/:id/token",
709
+ category: "transport",
710
+ reason: "Issues an embed token for an iframe",
711
+ },
712
+ {
713
+ route: "GET /api/v1/admin/ui/stream",
714
+ category: "transport",
715
+ reason: "Server-sent event stream of UI invalidations",
716
+ },
677
717
  // themes (themes spec §8-§9)
678
718
  {
679
719
  route: "GET /api/v1/themes/:id/:version/theme.css",
@@ -84,11 +84,19 @@ export const PLATFORM_DOMAINS = [
84
84
  description: "The org's settings (tool search, language, sandbox policy, the Platform tool switch, the default theme): read and change.",
85
85
  },
86
86
  {
87
- id: "environments",
88
- description: "Your own cloud environments (the workspaces your conversations run in): list, read, create, rename, delete, wipe the files.",
87
+ id: "devices",
88
+ description: "Your own cloud devices (the workspaces your conversations run in): list, read, create, rename, delete, wipe the files.",
89
+ },
90
+ {
91
+ id: "setup",
92
+ description: "Plugin setup guides: list the guides you may help with, read one as Markdown, the state of its checks for a channel connection or a connector, and running one check. Entering secrets, connecting an account and confirming the app was updated stay with the person on the web; read the docs topic `setup` first.",
89
93
  },
90
94
  {
91
95
  id: "themes",
92
96
  description: "The themes on in this org, the one in effect for you and the org's theme setting: list. Themes are set through your preferences, the org settings and the deployment settings.",
93
97
  },
98
+ {
99
+ id: "ui",
100
+ description: "The UI slots an extension can contribute to (the catalog): list. A slot id is a ui contribution's `slot` in a plugin manifest.",
101
+ },
94
102
  ];
@@ -40,6 +40,7 @@ const SettingsInput = DEPLOYMENT_SETTINGS_PATCH.pick({
40
40
  customSkills: true,
41
41
  orgMarketplaceBrowse: true,
42
42
  uiTheme: true,
43
+ uiArrangement: true,
43
44
  }).strict();
44
45
  const ProviderId = ModelProviderParams.shape.provider.describe("The model provider (models.platform-list), e.g. the plugin name of its extension.");
45
46
  /** `provider/model` of a purpose target, or null. */
@@ -121,7 +122,7 @@ let AdminOperations = class AdminOperations {
121
122
  }),
122
123
  defineOperation({
123
124
  id: "admin.update-settings",
124
- description: "Change deployment settings (super admin); give only the keys to change: orgCreation (anyone or super_admin), priceCurrency (ISO 4217 code), customConnectors / customSkills (allow or deny: whether orgs may create their own instead of installing from the catalog), orgMarketplaceBrowse (true or false), uiTheme ({ id }: the platform default theme, a platform theme whose scope is all, or null for the built-in theme; it is what every org falls back to and what the sign-in pages show). Per-org limits are orgs.set-limits.",
125
+ description: "Change deployment settings (super admin); give only the keys to change: orgCreation (anyone or super_admin), priceCurrency (ISO 4217 code), customConnectors / customSkills (allow or deny: whether orgs may create their own instead of installing from the catalog), orgMarketplaceBrowse (true or false), uiTheme ({ id }: the platform default theme, a platform theme whose scope is all, or null for the built-in theme; it is what every org falls back to and what the sign-in pages show), uiArrangement ({ <slot>: { hidden, order } }: the platform default arrangement of UI slots, with contribution keys <extension>/<contribution>; hidden ones are not listed but still open by URL; null for a slot removes its entry). Per-org limits are orgs.set-limits.",
125
126
  input: SettingsInput.refine((b) => Object.keys(b).length > 0, {
126
127
  message: "at least one setting is required",
127
128
  }),
@@ -148,7 +149,7 @@ let AdminOperations = class AdminOperations {
148
149
  : { ok: false, code: "validation_failed", message: r.error.issues[0]?.message ?? "" };
149
150
  },
150
151
  summary: async (i) => {
151
- const { uiTheme, ...rest } = i;
152
+ const { uiTheme, uiArrangement, ...rest } = i;
152
153
  const parts = Object.entries(rest).map(([k, v]) => `${k}=${String(v)}`);
153
154
  const zh = [...parts];
154
155
  const en = [...parts];
@@ -158,6 +159,11 @@ let AdminOperations = class AdminOperations {
158
159
  zh.push(`uiTheme=${uiTheme.id === null ? "内置主题" : (name?.zh ?? uiTheme.id)}`);
159
160
  en.push(`uiTheme=${uiTheme.id === null ? "built-in theme" : (name?.en ?? uiTheme.id)}`);
160
161
  }
162
+ if (uiArrangement !== undefined) {
163
+ const slots = Object.keys(uiArrangement).join(", ");
164
+ zh.push(`uiArrangement(${slots})`);
165
+ en.push(`uiArrangement (${slots})`);
166
+ }
161
167
  return {
162
168
  zh: `修改平台部署设置:${zh.join(",")}`,
163
169
  en: `Change the deployment settings: ${en.join(", ")}`,
@@ -120,6 +120,8 @@ let ConnectorsOperations = class ConnectorsOperations {
120
120
  on: t.on,
121
121
  switchable: t.switchable,
122
122
  owner: t.owner,
123
+ // where the template's setup guide is (catalog item and guide id), null without one
124
+ guide: t.guide ?? null,
123
125
  }));
124
126
  return pageOf(templates, startOf(input.cursor), PAGE);
125
127
  },
@@ -1,6 +1,6 @@
1
1
  import { type OnModuleInit } from "@nestjs/common";
2
2
  import { ConversationsService } from "../../conversations/conversations.service.js";
3
- import { ConversationEnvironmentStatus } from "../../conversations/environment-status.js";
3
+ import { ConversationDeviceStatus } from "../../conversations/device-status.js";
4
4
  import { ConversationFiles } from "../../conversations/files.js";
5
5
  import { KernelDb } from "../../infra/database/kernel-db.js";
6
6
  import { PlatformOperations } from "../registry.js";
@@ -14,9 +14,9 @@ export declare class ConversationsOperations implements OnModuleInit {
14
14
  private readonly registry;
15
15
  private readonly conversations;
16
16
  private readonly files;
17
- private readonly environment;
17
+ private readonly device;
18
18
  private readonly kdb;
19
- constructor(registry: PlatformOperations, conversations: ConversationsService, files: ConversationFiles, environment: ConversationEnvironmentStatus, kdb: KernelDb);
19
+ constructor(registry: PlatformOperations, conversations: ConversationsService, files: ConversationFiles, device: ConversationDeviceStatus, kdb: KernelDb);
20
20
  /**
21
21
  * Whether `id` is the conversation this run belongs to: its ROOT (the Platform tool also runs in
22
22
  * sub-agents, whose own id is not the person's conversation). Stopping or deleting it would end
@@ -11,7 +11,7 @@ import { Inject, Injectable } from "@nestjs/common";
11
11
  import { z } from "zod";
12
12
  import { EventsQuery, FilesQuery, IdParams, ListQuery, PatchBody, SubagentsQuery, } from "../../conversations/conversations.schemas.js";
13
13
  import { ConversationsService, } from "../../conversations/conversations.service.js";
14
- import { ConversationEnvironmentStatus } from "../../conversations/environment-status.js";
14
+ import { ConversationDeviceStatus } from "../../conversations/device-status.js";
15
15
  import { ConversationFiles } from "../../conversations/files.js";
16
16
  import { KernelDb } from "../../infra/database/kernel-db.js";
17
17
  import { rootConversationOf } from "../../runtime/subagents/child.js";
@@ -41,13 +41,13 @@ let ConversationsOperations = class ConversationsOperations {
41
41
  registry;
42
42
  conversations;
43
43
  files;
44
- environment;
44
+ device;
45
45
  kdb;
46
- constructor(registry, conversations, files, environment, kdb) {
46
+ constructor(registry, conversations, files, device, kdb) {
47
47
  this.registry = registry;
48
48
  this.conversations = conversations;
49
49
  this.files = files;
50
- this.environment = environment;
50
+ this.device = device;
51
51
  this.kdb = kdb;
52
52
  }
53
53
  /**
@@ -348,12 +348,12 @@ let ConversationsOperations = class ConversationsOperations {
348
348
  },
349
349
  }),
350
350
  defineOperation({
351
- id: "conversations.environment",
352
- description: "Read the environment one of your conversations works in and whether its instance is running or suspended; environment is null while the conversation has none. Takes the id from conversations.list.",
351
+ id: "conversations.device",
352
+ description: "Read the device one of your conversations works in and whether its instance is running or suspended; device is null while the conversation has none. Takes the id from conversations.list.",
353
353
  input: Id,
354
354
  example: { conversationId: "3f2b8a40-6c1d-4e0b-9a77-5d1e2c8b9f10" },
355
355
  authz: { orgAction: "agents.use" },
356
- mirrors: ["GET /api/v1/orgs/:orgId/conversations/:id/environment"],
356
+ mirrors: ["GET /api/v1/orgs/:orgId/conversations/:id/device"],
357
357
  renames: { conversationId: "id" },
358
358
  errors: [
359
359
  {
@@ -363,7 +363,7 @@ let ConversationsOperations = class ConversationsOperations {
363
363
  ],
364
364
  confirm: "read",
365
365
  run: async (input, ctx) => ({
366
- environment: await this.environment.get(ctx.orgId, input.conversationId, ctx.actorAccountId),
366
+ device: await this.device.get(ctx.orgId, input.conversationId, ctx.actorAccountId),
367
367
  }),
368
368
  }),
369
369
  defineOperation({
@@ -464,7 +464,7 @@ ConversationsOperations = __decorate([
464
464
  __param(0, Inject(PlatformOperations)),
465
465
  __param(1, Inject(ConversationsService)),
466
466
  __param(2, Inject(ConversationFiles)),
467
- __param(3, Inject(ConversationEnvironmentStatus)),
467
+ __param(3, Inject(ConversationDeviceStatus)),
468
468
  __param(4, Inject(KernelDb))
469
469
  ], ConversationsOperations);
470
470
  export { ConversationsOperations };
@@ -0,0 +1,26 @@
1
+ import { type OnModuleInit } from "@nestjs/common";
2
+ import { DevicesService } from "../../devices/devices.service.js";
3
+ import { KernelDb } from "../../infra/database/kernel-db.js";
4
+ import { PlatformOperations } from "../registry.js";
5
+ /**
6
+ * Device operations of the `Platform` tool (environments design, phase 1): a person's own
7
+ * cloud devices. Phase 1 has personal devices only, visible to their owner alone, so
8
+ * these are `personal` writes. A cloud device carries no credentials or device connection;
9
+ * deleting one and wiping its files are `personal` writes that are never remembered.
10
+ */
11
+ export declare class DevicesOperations implements OnModuleInit {
12
+ private readonly registry;
13
+ private readonly devices;
14
+ private readonly kdb;
15
+ constructor(registry: PlatformOperations, devices: DevicesService, kdb: KernelDb);
16
+ /**
17
+ * Whether `id` is the device the run works in: the one its root conversation is bound to
18
+ * (sub-agents use the root's). Deleting or wiping it would pull the sandbox from under the run.
19
+ */
20
+ private isRunsDevice;
21
+ /** The precheck of a destructive write: never the run's own device, then the service's. */
22
+ private precheckDestructive;
23
+ /** The device's name for a card; its id when it cannot be read. */
24
+ private label;
25
+ onModuleInit(): void;
26
+ }
@@ -0,0 +1,311 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
8
+ return function (target, key) { decorator(target, key, paramIndex); }
9
+ };
10
+ import { Inject, Injectable } from "@nestjs/common";
11
+ import { z } from "zod";
12
+ import { DevicesService } from "../../devices/devices.service.js";
13
+ import { DeviceNameBody, DeviceParams } from "../../devices/dto.js";
14
+ import { deviceLabel } from "../../devices/label.js";
15
+ import { KernelDb } from "../../infra/database/kernel-db.js";
16
+ import { rootConversationOf } from "../../runtime/subagents/child.js";
17
+ import { defineOperation } from "../operation.js";
18
+ import { PlatformOperations } from "../registry.js";
19
+ import { precheckBy, viaAgent } from "./errors.js";
20
+ import { named, orElse } from "./summary.js";
21
+ const DeviceId = z.object({ deviceId: DeviceParams.shape.id }).strict();
22
+ const Name = z.object({ name: DeviceNameBody.shape.name }).strict();
23
+ /**
24
+ * Model-facing names are English: the default is "Personal", a default demoted by a provider
25
+ * switch "Personal (Docker sandbox)" (the web shows 「个人设备」 / 「个人设备(Docker 沙箱)」).
26
+ */
27
+ const labelOf = (e) => deviceLabel(e, "en");
28
+ /** A row's state: why it cannot be used now, else whether its instance runs. */
29
+ function stateOf(e) {
30
+ if (!e.available) {
31
+ return {
32
+ state: "unavailable",
33
+ reason: "Its sandbox provider is no longer the deployment's current one.",
34
+ next: "Ask an org admin; use another device meanwhile.",
35
+ };
36
+ }
37
+ if (e.filesLost && e.source === "local") {
38
+ return {
39
+ state: "files_lost",
40
+ reason: "Its directory is gone from the connected machine.",
41
+ next: "Ask the person to run capybara-device logout, then capybara-device login into this device, on that machine.",
42
+ };
43
+ }
44
+ if (e.filesLost) {
45
+ return {
46
+ state: "files_lost",
47
+ reason: "Its file system is gone at the provider.",
48
+ next: "Wipe its files with devices.reset-files to use it again.",
49
+ };
50
+ }
51
+ return { state: e.instance?.status ?? "ready" };
52
+ }
53
+ const row = (e) => ({
54
+ id: e.id,
55
+ name: labelOf(e),
56
+ ...stateOf(e),
57
+ isDefault: e.isDefault,
58
+ source: e.source,
59
+ provider: e.provider,
60
+ online: e.online,
61
+ machine: e.machine && {
62
+ name: e.machine.name,
63
+ os: e.machine.os,
64
+ lastSeenAt: e.machine.lastSeenAt,
65
+ },
66
+ lastUsedAt: e.instance?.lastUsedAt ?? null,
67
+ });
68
+ /**
69
+ * Device operations of the `Platform` tool (environments design, phase 1): a person's own
70
+ * cloud devices. Phase 1 has personal devices only, visible to their owner alone, so
71
+ * these are `personal` writes. A cloud device carries no credentials or device connection;
72
+ * deleting one and wiping its files are `personal` writes that are never remembered.
73
+ */
74
+ let DevicesOperations = class DevicesOperations {
75
+ registry;
76
+ devices;
77
+ kdb;
78
+ constructor(registry, devices, kdb) {
79
+ this.registry = registry;
80
+ this.devices = devices;
81
+ this.kdb = kdb;
82
+ }
83
+ /**
84
+ * Whether `id` is the device the run works in: the one its root conversation is bound to
85
+ * (sub-agents use the root's). Deleting or wiping it would pull the sandbox from under the run.
86
+ */
87
+ async isRunsDevice(id, ctx) {
88
+ const root = await rootConversationOf(this.kdb.db, ctx.conversationId);
89
+ const row = await this.kdb.db
90
+ .selectFrom("conversations")
91
+ .select("device_id")
92
+ .where("id", "=", root)
93
+ .where("org_id", "=", ctx.orgId)
94
+ .executeTakeFirst();
95
+ return row?.device_id === id;
96
+ }
97
+ /** The precheck of a destructive write: never the run's own device, then the service's. */
98
+ async precheckDestructive(id, ctx, verb, read) {
99
+ if (await this.isRunsDevice(id, ctx)) {
100
+ return {
101
+ ok: false,
102
+ code: "device.current",
103
+ message: `The device you are running in cannot be ${verb} from here.`,
104
+ };
105
+ }
106
+ return precheckBy(read);
107
+ }
108
+ /** The device's name for a card; its id when it cannot be read. */
109
+ label(ctx, id) {
110
+ return orElse(async () => named(labelOf(await this.devices.get(ctx.orgId, ctx.actorAccountId, id))), id);
111
+ }
112
+ onModuleInit() {
113
+ this.registry.register([
114
+ defineOperation({
115
+ id: "devices.list",
116
+ description: "List your own devices in this org: one compact row each (name, state, whether it is the default, source: cloud or local, provider, whether a local one is online and its machine, last use), plus the default and last used ids and whether new cloud devices can be made. The default device is shown as Personal; a former default left behind by a sandbox provider switch is shown as Personal (<provider>) and becomes the default again when that provider is back.",
117
+ input: z.object({}).strict(),
118
+ example: {},
119
+ authz: { orgAction: "agents.use" },
120
+ mirrors: ["GET /api/v1/orgs/:orgId/devices"],
121
+ confirm: "read",
122
+ run: async (_input, ctx) => {
123
+ const l = await this.devices.list(ctx.orgId, ctx.actorAccountId);
124
+ return {
125
+ items: l.items.map(row),
126
+ defaultId: l.defaultId,
127
+ lastUsedId: l.lastUsedId,
128
+ cloudAvailable: l.cloudAvailable,
129
+ };
130
+ },
131
+ }),
132
+ defineOperation({
133
+ id: "devices.get",
134
+ description: "Read one of your devices with its source (cloud or local), provider, state, instance, the machine of a local one and whether it is online, limits and creation time. Takes the id from devices.list.",
135
+ input: DeviceId,
136
+ example: { deviceId: "4e8a0c1d-6b2f-4a37-8d19-3c5e7f9a1b20" },
137
+ authz: { orgAction: "agents.use" },
138
+ mirrors: ["GET /api/v1/orgs/:orgId/devices/:id"],
139
+ renames: { deviceId: "id" },
140
+ confirm: "read",
141
+ errors: [
142
+ {
143
+ code: "device.not_found",
144
+ next: "Check the id with devices.list: you only see your own devices.",
145
+ },
146
+ ],
147
+ run: async (input, ctx) => {
148
+ const e = await this.devices.get(ctx.orgId, ctx.actorAccountId, input.deviceId);
149
+ return { device: { ...e, name: labelOf(e), ...stateOf(e) } };
150
+ },
151
+ }),
152
+ defineOperation({
153
+ id: "devices.create",
154
+ description: "Create a personal cloud device with a name (1-64 characters, unique among yours, case-insensitive). It is ready at once; its instance and files are made on first use. It needs a sandbox provider and is limited per person.",
155
+ input: Name,
156
+ example: { name: "Data analysis" },
157
+ authz: { orgAction: "agents.use" },
158
+ mirrors: ["POST /api/v1/orgs/:orgId/devices"],
159
+ confirm: "personal",
160
+ errors: [
161
+ {
162
+ code: "device.name_taken",
163
+ next: "You have a device with this name: pick another name, or read yours with devices.list.",
164
+ },
165
+ {
166
+ code: "device.limit_reached",
167
+ next: "You are at the limit: delete a device you no longer need with devices.delete, or use an existing one.",
168
+ },
169
+ {
170
+ code: "device.current",
171
+ next: "This conversation works in it: ask the person to wipe it on the web, or wipe a different one.",
172
+ },
173
+ {
174
+ code: "device.unavailable",
175
+ next: {
176
+ superAdmin: "No sandbox provider is current: set one up in the admin console under extensions, then call again.",
177
+ orgAdmin: "No sandbox provider is set up; ask the super admin.",
178
+ member: "No sandbox provider is set up in this deployment; ask an org admin.",
179
+ },
180
+ },
181
+ ],
182
+ precheck: (i, ctx) => precheckBy(() => this.devices.checkCreate(ctx.orgId, ctx.actorAccountId, i.name)),
183
+ summary: (i) => ({
184
+ zh: `新建个人云端设备「${named(i.name)}」`,
185
+ en: `Create personal cloud device "${named(i.name)}"`,
186
+ }),
187
+ run: async (input, ctx) => {
188
+ const e = await this.devices.create(ctx.orgId, ctx.actorAccountId, { name: input.name }, undefined, viaAgent("devices.create", ctx));
189
+ return { device: row(e) };
190
+ },
191
+ }),
192
+ defineOperation({
193
+ id: "devices.delete",
194
+ description: "Delete one of your devices, the default one included: its instance and ALL its files are destroyed after the response and cannot be recovered. Conversations bound to it keep pointing at it and their sandbox tools then fail. The person confirms every delete; it is never remembered. The device this conversation works in cannot be deleted. Takes the id from devices.list.",
195
+ input: DeviceId,
196
+ example: { deviceId: "4e8a0c1d-6b2f-4a37-8d19-3c5e7f9a1b20" },
197
+ authz: { orgAction: "agents.use" },
198
+ mirrors: ["DELETE /api/v1/orgs/:orgId/devices/:id"],
199
+ renames: { deviceId: "id" },
200
+ confirm: "personal",
201
+ // destructive: asked every time and never remembered
202
+ rememberable: false,
203
+ errors: [
204
+ {
205
+ code: "device.not_found",
206
+ next: "Check the id with devices.list: you only see your own devices.",
207
+ },
208
+ {
209
+ code: "device.current",
210
+ next: "This conversation works in it: ask the person to delete it on the web, or delete a different one.",
211
+ },
212
+ ],
213
+ precheck: (i, ctx) => this.precheckDestructive(i.deviceId, ctx, "deleted", () => this.devices.get(ctx.orgId, ctx.actorAccountId, i.deviceId)),
214
+ summary: async (i, ctx) => {
215
+ const n = await this.label(ctx, i.deviceId);
216
+ const c = await orElse(() => this.devices.boundConversations(ctx.orgId, ctx.actorAccountId, i.deviceId), 0);
217
+ return {
218
+ zh: `删除设备「${n}」:其中所有文件将被销毁且无法恢复;使用它的 ${c} 个对话将失去沙箱(沙箱工具会失败)`,
219
+ en: `Delete device "${n}": all its files are destroyed and cannot be recovered; the ${c} conversations using it lose their sandbox (their sandbox tools fail)`,
220
+ };
221
+ },
222
+ run: async (input, ctx) => {
223
+ await this.devices.remove(ctx.orgId, ctx.actorAccountId, input.deviceId, undefined, viaAgent("devices.delete", ctx));
224
+ return { id: input.deviceId, deleted: true };
225
+ },
226
+ }),
227
+ defineOperation({
228
+ id: "devices.reset-files",
229
+ description: "Wipe one of your devices' files so it starts empty: ALL its files are destroyed (after running commands finish) and cannot be recovered; the next use creates a fresh workspace. Use it when a device reports its files are lost (not for a connected machine's device: its files are on the machine). The person confirms every reset; it is never remembered. The device this conversation works in cannot be wiped. Takes the id from devices.list.",
230
+ input: DeviceId,
231
+ example: { deviceId: "4e8a0c1d-6b2f-4a37-8d19-3c5e7f9a1b20" },
232
+ authz: { orgAction: "agents.use" },
233
+ mirrors: ["POST /api/v1/orgs/:orgId/devices/:id/files/reset"],
234
+ renames: { deviceId: "id" },
235
+ confirm: "personal",
236
+ rememberable: false,
237
+ errors: [
238
+ {
239
+ code: "device.not_found",
240
+ next: "Check the id with devices.list: you only see your own devices.",
241
+ },
242
+ {
243
+ code: "device.current",
244
+ next: "This conversation works in it: ask the person to wipe it on the web, or wipe a different one.",
245
+ },
246
+ {
247
+ code: "device.files_on_device",
248
+ next: "Its files are on its connected machine: ask the person to run capybara-device logout, then capybara-device login into this device, on that machine.",
249
+ },
250
+ {
251
+ code: "device.unavailable",
252
+ next: {
253
+ orgAdmin: "Its sandbox provider is no longer the current one: use another device, or ask the super admin about the provider.",
254
+ member: "Its sandbox provider is no longer the current one: use another device, or ask an org admin.",
255
+ },
256
+ },
257
+ ],
258
+ precheck: (i, ctx) => this.precheckDestructive(i.deviceId, ctx, "wiped", () => this.devices.checkReset(ctx.orgId, ctx.actorAccountId, i.deviceId)),
259
+ summary: async (i, ctx) => {
260
+ const n = await this.label(ctx, i.deviceId);
261
+ return {
262
+ zh: `清空设备「${n}」的文件:所有文件将被销毁且无法恢复`,
263
+ en: `Wipe the files of device "${n}": all files are destroyed and cannot be recovered`,
264
+ };
265
+ },
266
+ run: async (input, ctx) => {
267
+ await this.devices.resetFiles(ctx.orgId, ctx.actorAccountId, input.deviceId, undefined, viaAgent("devices.reset-files", ctx));
268
+ return { id: input.deviceId, reset: true };
269
+ },
270
+ }),
271
+ defineOperation({
272
+ id: "devices.rename",
273
+ description: "Rename one of your devices, the default one included (it then has a name). The new name is 1-64 characters and unique among yours, case-insensitive. Takes the id from devices.list.",
274
+ input: DeviceId.extend({ name: DeviceNameBody.shape.name }).strict(),
275
+ example: { deviceId: "4e8a0c1d-6b2f-4a37-8d19-3c5e7f9a1b20", name: "Reports" },
276
+ authz: { orgAction: "agents.use" },
277
+ mirrors: ["PATCH /api/v1/orgs/:orgId/devices/:id"],
278
+ renames: { deviceId: "id" },
279
+ confirm: "personal",
280
+ errors: [
281
+ {
282
+ code: "device.not_found",
283
+ next: "Check the id with devices.list: you only see your own devices.",
284
+ },
285
+ {
286
+ code: "device.name_taken",
287
+ next: "You have a device with this name: pick another name.",
288
+ },
289
+ ],
290
+ precheck: (i, ctx) => precheckBy(() => this.devices.checkRename(ctx.orgId, ctx.actorAccountId, i.deviceId, i.name)),
291
+ summary: async (i, ctx) => {
292
+ const from = await orElse(async () => named(labelOf(await this.devices.get(ctx.orgId, ctx.actorAccountId, i.deviceId))), i.deviceId);
293
+ return {
294
+ zh: `将设备「${from}」重命名为「${named(i.name)}」`,
295
+ en: `Rename device "${from}" to "${named(i.name)}"`,
296
+ };
297
+ },
298
+ run: async (input, ctx) => ({
299
+ device: row(await this.devices.rename(ctx.orgId, ctx.actorAccountId, input.deviceId, input.name, undefined, viaAgent("devices.rename", ctx))),
300
+ }),
301
+ }),
302
+ ]);
303
+ }
304
+ };
305
+ DevicesOperations = __decorate([
306
+ Injectable(),
307
+ __param(0, Inject(PlatformOperations)),
308
+ __param(1, Inject(DevicesService)),
309
+ __param(2, Inject(KernelDb))
310
+ ], DevicesOperations);
311
+ export { DevicesOperations };
@@ -39,7 +39,7 @@ let OrgSettingsOperations = class OrgSettingsOperations {
39
39
  this.registry.register([
40
40
  defineOperation({
41
41
  id: "org-settings.get",
42
- description: "Read this org's settings: toolSearch, locale, sandboxToolPolicy, platformTool (on, read-only or off), sandboxEgress and wakeOnBackgroundTask (absent means it follows the deployment), theme (the org's default theme id, null or absent following the platform, and personal: allowed or locked), the deployment's sandbox egress default and the sandbox cpu / memory limits in effect.",
42
+ description: "Read this org's settings: toolSearch, locale, sandboxToolPolicy, platformTool (on, read-only or off), sandboxEgress and wakeOnBackgroundTask (absent means it follows the deployment), theme (the org's default theme id, null or absent following the platform, and personal: allowed or locked), uiArrangement (per UI slot, the extension contributions the org hides and their order; a slot not listed follows the platform), the deployment's sandbox egress default and the sandbox cpu / memory limits in effect.",
43
43
  input: z.object({}).strict(),
44
44
  example: {},
45
45
  authz: { orgAction: "org.read" },
@@ -53,7 +53,7 @@ let OrgSettingsOperations = class OrgSettingsOperations {
53
53
  }),
54
54
  defineOperation({
55
55
  id: "org-settings.update",
56
- description: "Change this org's settings (org admins). Give only the settings to change; null clears sandboxEgress or wakeOnBackgroundTask so they follow the deployment again. theme: { id, personal } sets the org's default theme (a theme id from themes.list, or null to follow the platform) and whether members may pick their own (allowed) or not (locked); null clears it. Setting platformTool to off or read-only takes effect from the next call and cuts this Platform tool off in the org, so say so before asking; an org admin switches it back on in the web settings.",
56
+ description: "Change this org's settings (org admins). Give only the settings to change; null clears sandboxEgress or wakeOnBackgroundTask so they follow the deployment again. theme: { id, personal } sets the org's default theme (a theme id from themes.list, or null to follow the platform) and whether members may pick their own (allowed) or not (locked); null clears it. uiArrangement: { <slot>: { hidden, order } } replaces that slot's entry, where hidden and order list contribution keys <extension>/<contribution> (hidden ones are not listed in the web UI but their pages still open by URL); null for a slot makes it follow the platform again; platform.page is refused. Setting platformTool to off or read-only takes effect from the next call and cuts this Platform tool off in the org, so say so before asking; an org admin switches it back on in the web settings.",
57
57
  input: OrgSettingsPatchSchema.refine((i) => Object.values(i).some((v) => v !== undefined), {
58
58
  message: "give at least one setting",
59
59
  }),
@@ -159,6 +159,7 @@ let OrgsOperations = class OrgsOperations {
159
159
  "customSkills",
160
160
  "orgMarketplaceBrowse",
161
161
  "uiTheme",
162
+ "uiArrangement",
162
163
  ],
163
164
  extras: ["orgId", "runConcurrency", "sandbox", "subagents"],
164
165
  confirm: "platform",