@nylorun/runtime 0.23.0-beta → 0.25.0-beta

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 (301) hide show
  1. package/CHANGELOG.md +252 -0
  2. package/README.md +87 -28
  3. package/dist/adapters/execution/restate.js +1 -1
  4. package/dist/adapters/replication/pgoutput.d.ts +2 -0
  5. package/dist/adapters/replication/pgoutput.js +6 -3
  6. package/dist/adapters/sandbox/local.d.ts +9 -1
  7. package/dist/adapters/sandbox/local.js +16 -4
  8. package/dist/adapters/sandbox/virtual.js +4 -1
  9. package/dist/api/a2a/card.d.ts +11 -1
  10. package/dist/api/a2a/card.js +26 -2
  11. package/dist/api/a2a/endpoint.js +9 -3
  12. package/dist/api/a2a/protocol.d.ts +25 -2
  13. package/dist/api/a2a/protocol.js +20 -3
  14. package/dist/api/a2a/routes.d.ts +6 -1
  15. package/dist/api/a2a/routes.js +67 -9
  16. package/dist/api/a2a/tasks.js +2 -1
  17. package/dist/api/ag-ui/endpoint.js +8 -3
  18. package/dist/api/ag-ui/history.d.ts +6 -1
  19. package/dist/api/ag-ui/history.js +39 -3
  20. package/dist/api/ag-ui/routes.d.ts +4 -1
  21. package/dist/api/ag-ui/routes.js +63 -20
  22. package/dist/api/ag-ui/translate.js +3 -2
  23. package/dist/api/components.d.ts +5327 -1091
  24. package/dist/api/components.js +40 -16
  25. package/dist/api/gate/keys.d.ts +2 -1
  26. package/dist/api/gate/keys.js +14 -1
  27. package/dist/api/gate/routes.d.ts +6 -0
  28. package/dist/api/gate/routes.js +52 -3
  29. package/dist/api/http/app.js +17 -6
  30. package/dist/api/http/body.d.ts +3 -3
  31. package/dist/api/http/body.js +7 -7
  32. package/dist/api/http/define.d.ts +6 -0
  33. package/dist/api/http/define.js +13 -1
  34. package/dist/api/http/respond.js +1 -1
  35. package/dist/api/http/routes/artifacts.js +35 -8
  36. package/dist/api/http/routes/coverage.d.ts +9 -0
  37. package/dist/api/http/routes/coverage.js +34 -0
  38. package/dist/api/http/routes/environment-manifests.d.ts +9 -0
  39. package/dist/api/http/routes/environment-manifests.js +118 -0
  40. package/dist/api/http/routes/environments.d.ts +11 -0
  41. package/dist/api/http/routes/environments.js +332 -0
  42. package/dist/api/http/routes/mcp.d.ts +1 -1
  43. package/dist/api/http/routes/mcp.js +2 -2
  44. package/dist/api/http/routes/me.js +1 -1
  45. package/dist/api/http/routes/reads.d.ts +94 -9
  46. package/dist/api/http/routes/reads.js +54 -5
  47. package/dist/api/http/routes/sessions.js +24 -9
  48. package/dist/api/http/routes/tenant.js +65 -15
  49. package/dist/api/inbound-files.d.ts +65 -0
  50. package/dist/api/inbound-files.js +115 -0
  51. package/dist/api/openapi.js +48 -28
  52. package/dist/artifacts/disk.d.ts +59 -0
  53. package/dist/artifacts/disk.js +569 -0
  54. package/dist/artifacts/export.d.ts +1 -1
  55. package/dist/artifacts/export.js +2 -3
  56. package/dist/artifacts/folders.d.ts +6 -3
  57. package/dist/artifacts/folders.js +17 -12
  58. package/dist/artifacts/media-types.d.ts +15 -0
  59. package/dist/artifacts/media-types.js +56 -4
  60. package/dist/artifacts/parts.d.ts +12 -3
  61. package/dist/artifacts/parts.js +15 -4
  62. package/dist/artifacts/service.d.ts +2 -1
  63. package/dist/artifacts/service.js +6 -1
  64. package/dist/artifacts/workspace.d.ts +5 -5
  65. package/dist/artifacts/workspace.js +7 -19
  66. package/dist/core/flow-host.d.ts +3 -4
  67. package/dist/core/flow-host.js +5 -2
  68. package/dist/core/provider.d.ts +3 -2
  69. package/dist/core/provider.js +5 -37
  70. package/dist/core/sandbox-routes.d.ts +2 -21
  71. package/dist/core/sandbox-routes.js +11 -44
  72. package/dist/core/turn-manifest.d.ts +3 -2
  73. package/dist/core/turn-manifest.js +29 -5
  74. package/dist/execution/types.d.ts +1 -1
  75. package/dist/gates/contract.d.ts +3 -24
  76. package/dist/gates/contract.js +1 -36
  77. package/dist/gates/egress-credentials.d.ts +9 -0
  78. package/dist/gates/egress-credentials.js +11 -4
  79. package/dist/gates/egress.d.ts +22 -1
  80. package/dist/gates/egress.js +116 -10
  81. package/dist/gates/fixture-model.d.ts +28 -0
  82. package/dist/gates/fixture-model.js +92 -0
  83. package/dist/gates/handler.js +4 -4
  84. package/dist/gates/http-tool.d.ts +9 -6
  85. package/dist/gates/http-tool.js +11 -17
  86. package/dist/gates/in-process.d.ts +5 -0
  87. package/dist/gates/in-process.js +12 -1
  88. package/dist/gates/journal.d.ts +30 -0
  89. package/dist/gates/journal.js +51 -0
  90. package/dist/gates/mcp-handler.d.ts +4 -0
  91. package/dist/gates/mcp-handler.js +7 -4
  92. package/dist/gates/meter.d.ts +10 -2
  93. package/dist/gates/meter.js +20 -5
  94. package/dist/gates/policy.d.ts +49 -0
  95. package/dist/gates/policy.js +132 -0
  96. package/dist/gates/tenant-vaults.d.ts +7 -7
  97. package/dist/gates/tenant-vaults.js +5 -5
  98. package/dist/gates/tool-calls.d.ts +10 -5
  99. package/dist/gates/tool-calls.js +28 -10
  100. package/dist/gates/tool-client.d.ts +8 -0
  101. package/dist/gates/tool-client.js +27 -11
  102. package/dist/gates/tool-contract.d.ts +11 -69
  103. package/dist/gates/tool-contract.js +1 -85
  104. package/dist/gates/tool-gate.d.ts +1 -1
  105. package/dist/harness/calls.d.ts +14 -7
  106. package/dist/harness/calls.js +30 -24
  107. package/dist/harness/executors.js +12 -9
  108. package/dist/harness/main.js +24 -5
  109. package/dist/harness/pod.d.ts +39 -0
  110. package/dist/harness/pod.js +46 -0
  111. package/dist/harness/service.d.ts +0 -1
  112. package/dist/harness/service.js +17 -9
  113. package/dist/harness/setup.d.ts +29 -0
  114. package/dist/harness/setup.js +174 -0
  115. package/dist/harness/ws-client.js +3 -2
  116. package/dist/harness/ws-port.d.ts +1 -5
  117. package/dist/harness/ws-port.js +1 -5
  118. package/dist/harness-api/in-process.js +3 -3
  119. package/dist/harness-api/record.d.ts +15 -1
  120. package/dist/harness-api/record.js +180 -50
  121. package/dist/harness-api/redact.d.ts +3 -0
  122. package/dist/harness-api/redact.js +45 -0
  123. package/dist/harness-api/server.d.ts +35 -4
  124. package/dist/harness-api/server.js +130 -17
  125. package/dist/harness-api/start.d.ts +10 -3
  126. package/dist/harness-api/start.js +40 -10
  127. package/dist/harness-api/tool-journal.d.ts +105 -0
  128. package/dist/harness-api/tool-journal.js +132 -0
  129. package/dist/harness-api/tool-status.d.ts +13 -0
  130. package/dist/harness-api/tool-status.js +26 -0
  131. package/dist/harness-api/workspace.d.ts +12 -7
  132. package/dist/harness-api/workspace.js +47 -25
  133. package/dist/harness-api/ws-server.d.ts +11 -3
  134. package/dist/harness-api/ws-server.js +94 -15
  135. package/dist/host/gates.d.ts +2 -1
  136. package/dist/host/gates.js +10 -2
  137. package/dist/host/main.js +54 -5
  138. package/dist/host/operate.js +67 -5
  139. package/dist/host/stack-config.d.ts +64 -0
  140. package/dist/host/stack-config.js +62 -2
  141. package/dist/keys/client.js +4 -1
  142. package/dist/keys/keys.d.ts +13 -6
  143. package/dist/keys/keys.js +9 -8
  144. package/dist/management-openapi.json +1264 -2171
  145. package/dist/mcp/connect.d.ts +26 -22
  146. package/dist/mcp/connect.js +30 -34
  147. package/dist/mcp/pool.d.ts +3 -6
  148. package/dist/mcp/pool.js +14 -28
  149. package/dist/mcp/preview.d.ts +3 -3
  150. package/dist/mcp/preview.js +10 -21
  151. package/dist/mcp/snapshot.d.ts +16 -24
  152. package/dist/mcp/snapshot.js +33 -45
  153. package/dist/model/capabilities.d.ts +26 -0
  154. package/dist/model/capabilities.js +44 -0
  155. package/dist/model/catalog.d.ts +34 -3
  156. package/dist/model/catalog.js +38 -2
  157. package/dist/model/models.d.ts +2 -0
  158. package/dist/model/models.js +1 -1
  159. package/dist/model/native-blocks.d.ts +35 -0
  160. package/dist/model/native-blocks.js +170 -0
  161. package/dist/model/pi-model.js +114 -94
  162. package/dist/openapi.json +12822 -3943
  163. package/dist/reads/types.d.ts +16 -3
  164. package/dist/record/append.d.ts +3 -1
  165. package/dist/record/append.js +1 -0
  166. package/dist/record/envelope.d.ts +5 -1
  167. package/dist/record/envelope.js +7 -3
  168. package/dist/record/environment.d.ts +25 -0
  169. package/dist/record/environment.js +44 -0
  170. package/dist/record/index.d.ts +1 -1
  171. package/dist/record/index.js +1 -1
  172. package/dist/sandbox/disk-fs.d.ts +95 -0
  173. package/dist/sandbox/disk-fs.js +206 -0
  174. package/dist/sandbox/join.d.ts +17 -18
  175. package/dist/sandbox/join.js +46 -15
  176. package/dist/sandbox/manager.d.ts +47 -21
  177. package/dist/sandbox/manager.js +162 -107
  178. package/dist/sandbox/placement.d.ts +14 -13
  179. package/dist/sandbox/placement.js +31 -14
  180. package/dist/sandbox/pods/client.d.ts +9 -2
  181. package/dist/sandbox/pods/lifecycle.d.ts +36 -27
  182. package/dist/sandbox/pods/lifecycle.js +29 -26
  183. package/dist/sandbox/pods/reconcile.js +18 -12
  184. package/dist/sandbox/pods/spec.d.ts +15 -13
  185. package/dist/sandbox/pods/spec.js +17 -20
  186. package/dist/sandbox/records.d.ts +2 -2
  187. package/dist/sandbox/records.js +3 -3
  188. package/dist/sandbox/resolve.d.ts +37 -27
  189. package/dist/sandbox/resolve.js +73 -41
  190. package/dist/sandbox/runtime-tools.d.ts +9 -0
  191. package/dist/sandbox/runtime-tools.js +16 -0
  192. package/dist/sandbox/session-sandbox.d.ts +4 -6
  193. package/dist/sandbox/session-sandbox.js +47 -94
  194. package/dist/sandbox/setup.d.ts +64 -0
  195. package/dist/sandbox/setup.js +160 -0
  196. package/dist/sandbox/share.d.ts +21 -26
  197. package/dist/sandbox/share.js +36 -63
  198. package/dist/sandbox/skills.d.ts +8 -6
  199. package/dist/sandbox/skills.js +24 -23
  200. package/dist/sandbox/tenant-config.d.ts +12 -14
  201. package/dist/sandbox/tenant-config.js +12 -17
  202. package/dist/sandbox/types.d.ts +6 -0
  203. package/dist/store/postgres/drizzle/0020_environments.sql +63 -0
  204. package/dist/store/postgres/drizzle/0021_disk_versions.sql +7 -0
  205. package/dist/store/postgres/drizzle/0022_model_usage_timing.sql +5 -0
  206. package/dist/store/postgres/drizzle/0023_artifact_pages.sql +1 -0
  207. package/dist/store/postgres/drizzle/0024_flat_manifest.sql +7 -0
  208. package/dist/store/postgres/drizzle/0025_environment_manifests.sql +14 -0
  209. package/dist/store/postgres/drizzle/0026_environment_forks.sql +1 -0
  210. package/dist/store/postgres/drizzle/0027_environment_image_digest.sql +1 -0
  211. package/dist/store/postgres/drizzle/meta/_journal.json +56 -0
  212. package/dist/store/postgres/reads.js +123 -17
  213. package/dist/store/postgres/record-writer.d.ts +4 -4
  214. package/dist/store/postgres/record-writer.js +9 -9
  215. package/dist/store/postgres/record.d.ts +7 -0
  216. package/dist/store/postgres/record.js +23 -2
  217. package/dist/store/postgres/schema.d.ts +1126 -736
  218. package/dist/store/postgres/schema.js +136 -73
  219. package/dist/store/postgres/store.js +195 -67
  220. package/dist/store/types.d.ts +165 -50
  221. package/dist/tenant/advance.d.ts +7 -6
  222. package/dist/tenant/advance.js +118 -42
  223. package/dist/tenant/artifact-tool.d.ts +1 -1
  224. package/dist/tenant/artifact-tool.js +46 -26
  225. package/dist/tenant/commands.d.ts +15 -2
  226. package/dist/tenant/commands.js +115 -14
  227. package/dist/tenant/context.d.ts +56 -24
  228. package/dist/tenant/context.js +4 -15
  229. package/dist/tenant/effects.d.ts +1 -1
  230. package/dist/tenant/effects.js +44 -29
  231. package/dist/tenant/environment-manifests.d.ts +57 -0
  232. package/dist/tenant/environment-manifests.js +200 -0
  233. package/dist/tenant/environments.d.ts +174 -0
  234. package/dist/tenant/environments.js +1044 -0
  235. package/dist/tenant/harness-tokens.d.ts +21 -0
  236. package/dist/tenant/harness-tokens.js +61 -0
  237. package/dist/tenant/host-token.d.ts +1 -1
  238. package/dist/tenant/host-token.js +2 -4
  239. package/dist/tenant/identity-file.d.ts +4 -4
  240. package/dist/tenant/identity-file.js +17 -8
  241. package/dist/tenant/issuers.js +3 -3
  242. package/dist/tenant/model-setting.d.ts +14 -0
  243. package/dist/tenant/model-setting.js +51 -0
  244. package/dist/tenant/principals.js +1 -1
  245. package/dist/tenant/reset.js +3 -3
  246. package/dist/tenant/runtime.d.ts +6 -1
  247. package/dist/tenant/runtime.js +7 -1
  248. package/dist/tenant/session.d.ts +3 -3
  249. package/dist/tenant/session.js +0 -14
  250. package/dist/tenant/sessions.d.ts +18 -14
  251. package/dist/tenant/sessions.js +99 -143
  252. package/dist/tenant/signing-keys.d.ts +5 -1
  253. package/dist/tenant/skill-tool.d.ts +3 -3
  254. package/dist/tenant/skill-tool.js +6 -11
  255. package/dist/tenant/status.js +3 -3
  256. package/dist/tenant/sweep.js +13 -7
  257. package/dist/tenant/tool-results.js +1 -1
  258. package/dist/tenant/tool-search.d.ts +7 -11
  259. package/dist/tenant/tool-search.js +8 -5
  260. package/dist/tenant/transcript.d.ts +245 -36
  261. package/dist/tenant/transcript.js +64 -12
  262. package/dist/tenant/turn-timing.d.ts +43 -0
  263. package/dist/tenant/turn-timing.js +39 -0
  264. package/dist/tenant/types.d.ts +2 -0
  265. package/dist/traces/ids.d.ts +41 -0
  266. package/dist/traces/ids.js +81 -0
  267. package/dist/traces/key.d.ts +6 -0
  268. package/dist/traces/key.js +37 -0
  269. package/dist/traces/map.d.ts +113 -0
  270. package/dist/traces/map.js +289 -0
  271. package/dist/traces/options.d.ts +7 -0
  272. package/dist/traces/options.js +1 -0
  273. package/dist/traces/otlp.d.ts +42 -0
  274. package/dist/traces/otlp.js +84 -0
  275. package/dist/traces/projector.d.ts +58 -0
  276. package/dist/traces/projector.js +200 -0
  277. package/dist/traces/read.d.ts +23 -0
  278. package/dist/traces/read.js +16 -0
  279. package/dist/vault/coverage.d.ts +26 -0
  280. package/dist/vault/coverage.js +62 -0
  281. package/dist/vault/error.d.ts +11 -1
  282. package/dist/vault/error.js +5 -1
  283. package/dist/vault/host-model.d.ts +4 -1
  284. package/dist/vault/host-model.js +10 -2
  285. package/dist/vault/service.d.ts +92 -48
  286. package/dist/vault/service.js +462 -376
  287. package/dist/vault/sources.d.ts +5 -16
  288. package/dist/vault/sources.js +6 -8
  289. package/dist/version.d.ts +1 -1
  290. package/dist/version.js +2 -2
  291. package/package.json +13 -13
  292. package/dist/api/http/routes/sandboxes.d.ts +0 -9
  293. package/dist/api/http/routes/sandboxes.js +0 -153
  294. package/dist/api/http/routes/vaults.d.ts +0 -10
  295. package/dist/api/http/routes/vaults.js +0 -139
  296. package/dist/record/sandbox.d.ts +0 -25
  297. package/dist/record/sandbox.js +0 -43
  298. package/dist/sandbox/capability.d.ts +0 -3
  299. package/dist/sandbox/capability.js +0 -10
  300. package/dist/tenant/sandboxes.d.ts +0 -123
  301. package/dist/tenant/sandboxes.js +0 -566
@@ -5,7 +5,7 @@
5
5
  * global registry.
6
6
  */
7
7
  import { z } from "zod";
8
- import { SessionListItemSchema, ModelCallSchema, SessionPageSchema, SessionManifestViewSchema, HistoryPageSchema, SessionUsageTotalsSchema, ModelCallsPageSchema, ModelCallExportPageSchema, SandboxPageSchema, JwksSchema, SigningKeyListSchema, SigningKeyViewSchema, RotateSigningKeysRequestSchema, RevokeSigningKeyRequestSchema, MeResponseSchema, TenantStatusSchema, ResetTenantRequestSchema, ResetTenantResponseSchema, SeedTenantConfigRequestSchema, SeedTenantConfigResponseSchema, HostModelCatalogSchema, TenantSandboxViewSchema, ModelUsageTotalsSchema, ModelBudgetsSchema, PutModelBudgetsRequestSchema, PutTenantSandboxRequestSchema, ListProvidersResponseSchema, HostModelViewSchema, PutHostModelRequestSchema, SelectHostModelRequestSchema, CreateVaultRequestSchema, VaultInfoSchema, ListVaultsResponseSchema, CreateCredentialRequestSchema, CredentialInfoSchema, ListCredentialsResponseSchema, RotateCredentialRequestSchema, McpPreviewRequestSchema, McpPreviewSchema, DeletedResponseSchema, ListAgentsResponseSchema, ListPublicAgentsResponseSchema, ListSessionsResponseSchema, LiveEventSchema, PutAgentRequestSchema, PutAgentResponseSchema, PutSessionRequestSchema, SessionItemsResponseSchema, SessionViewSchema, StreamClosedFrameSchema, AcceptedResponseSchema, SandboxToolOutcomeSchema, PutSandboxRequestSchema, SandboxViewSchema, ListSandboxesResponseSchema, DeleteSandboxResponseSchema, ListSandboxEventsResponseSchema, ArtifactViewSchema, ArtifactVersionViewSchema, ListArtifactsResponseSchema, UploadArtifactResponseSchema, DefinitionFileViewSchema, DeleteArtifactResponseSchema, CreateArtifactLinkRequestSchema, ArtifactLinkSchema, PutTenantArtifactsRequestSchema, TenantArtifactsViewSchema, ArtifactTreeSchema, ArtifactDiffSchema, SessionCommandSchema, ListOperatorKeysResponseSchema, PutOperatorKeyResponseSchema, DeleteOperatorKeyResponseSchema, OperatorKeySchema, ProtocolRejectedResponseSchema, RejectedResponseSchema, EVENT_SCHEMAS, EVENT_TYPES, } from "@nylorun/core/contracts";
8
+ import { EnvironmentManifestSchema, EnvironmentSecretSlotsSchema, DeleteEnvironmentManifestResponseSchema, EnvironmentManifestPlanSchema, EnvironmentManifestVersionsSchema, EnvironmentManifestViewSchema, ListEnvironmentManifestsResponseSchema, PutEnvironmentManifestRequestSchema, PutEnvironmentSecretValueRequestSchema, SaveEnvironmentManifestResponseSchema, SessionListItemSchema, ModelCallSchema, SessionPageSchema, SessionManifestViewSchema, HistoryPageSchema, SessionUsageTotalsSchema, ModelCallsPageSchema, ModelCallExportPageSchema, EnvironmentPageSchema, ToolCallSchema, ToolCallsPageSchema, TurnTraceSchema, JwksSchema, SigningKeyListSchema, SigningKeyViewSchema, RotateSigningKeysRequestSchema, RevokeSigningKeyRequestSchema, MeResponseSchema, TenantStatusSchema, ResetTenantRequestSchema, ResetTenantResponseSchema, SeedTenantConfigRequestSchema, SeedTenantConfigResponseSchema, HostModelCatalogSchema, TenantSandboxViewSchema, ModelUsageTotalsSchema, ModelBudgetsSchema, PutModelBudgetsRequestSchema, ToolPolicySchema, PutToolPolicyRequestSchema, PutModelInputsRequestSchema, ModelInputsViewSchema, PutTenantEnvironmentsRequestSchema, ListProvidersResponseSchema, HostModelViewSchema, PutHostModelRequestSchema, SelectHostModelRequestSchema, PutEnvironmentSecretRequestSchema, EnvironmentSecretViewSchema, ListEnvironmentSecretsResponseSchema, McpPreviewRequestSchema, McpPreviewSchema, CredentialCoverageRequestSchema, CredentialCoverageSchema, DeletedResponseSchema, ListAgentsResponseSchema, ListPublicAgentsResponseSchema, ListSessionsResponseSchema, LiveEventSchema, PutAgentRequestSchema, PutAgentResponseSchema, PutSessionRequestSchema, SessionItemsResponseSchema, SessionViewSchema, StreamClosedFrameSchema, AcceptedResponseSchema, SandboxToolOutcomeSchema, PutEnvironmentRequestSchema, EnvironmentViewSchema, EnvironmentSnapshotSchema, RestoreEnvironmentRequestSchema, ForkEnvironmentRequestSchema, EnvironmentForkPlanSchema, ForkEnvironmentResponseSchema, EnvironmentRestoreSchema, EnvironmentVersionsSchema, ListEnvironmentsResponseSchema, DeleteEnvironmentResponseSchema, ListEnvironmentEventsResponseSchema, ArtifactViewSchema, ArtifactListItemSchema, ArtifactPageSchema, ArtifactVersionViewSchema, ListArtifactsResponseSchema, UploadArtifactResponseSchema, DefinitionFileViewSchema, DeleteArtifactResponseSchema, CreateArtifactLinkRequestSchema, ArtifactLinkSchema, PutTenantArtifactsRequestSchema, TenantArtifactsViewSchema, ArtifactTreeSchema, ArtifactDiffSchema, SessionCommandSchema, ListOperatorKeysResponseSchema, PutOperatorKeyResponseSchema, DeleteOperatorKeyResponseSchema, OperatorKeySchema, ProtocolRejectedResponseSchema, RejectedResponseSchema, EVENT_SCHEMAS, EVENT_TYPES, } from "@nylorun/core/contracts";
9
9
  function named(id, schema) {
10
10
  return schema.meta({ id });
11
11
  }
@@ -16,13 +16,32 @@ export const ListOperatorKeysResponse = named("ListOperatorKeysResponse", ListOp
16
16
  export const PutOperatorKeyResponse = named("PutOperatorKeyResponse", PutOperatorKeyResponseSchema);
17
17
  export const DeleteOperatorKeyResponse = named("DeleteOperatorKeyResponse", DeleteOperatorKeyResponseSchema);
18
18
  export const SandboxToolOutcome = named("SandboxToolOutcome", SandboxToolOutcomeSchema);
19
- export const PutSandboxRequest = named("PutSandboxRequest", PutSandboxRequestSchema);
20
- export const SandboxView = named("SandboxView", SandboxViewSchema);
21
- export const ListSandboxesResponse = named("ListSandboxesResponse", ListSandboxesResponseSchema);
22
- export const DeleteSandboxResponse = named("DeleteSandboxResponse", DeleteSandboxResponseSchema);
23
- export const ListSandboxEventsResponse = named("ListSandboxEventsResponse", ListSandboxEventsResponseSchema);
19
+ export const PutEnvironmentRequest = named("PutEnvironmentRequest", PutEnvironmentRequestSchema);
20
+ export const EnvironmentView = named("EnvironmentView", EnvironmentViewSchema);
21
+ export const EnvironmentSecretSlots = named("EnvironmentSecretSlots", EnvironmentSecretSlotsSchema);
22
+ export const EnvironmentManifest = named("EnvironmentManifest", EnvironmentManifestSchema);
23
+ export const PutEnvironmentManifestRequest = named("PutEnvironmentManifestRequest", PutEnvironmentManifestRequestSchema);
24
+ export const EnvironmentManifestView = named("EnvironmentManifestView", EnvironmentManifestViewSchema);
25
+ export const EnvironmentManifestPlan = named("EnvironmentManifestPlan", EnvironmentManifestPlanSchema);
26
+ export const SaveEnvironmentManifestResponse = named("SaveEnvironmentManifestResponse", SaveEnvironmentManifestResponseSchema);
27
+ export const ListEnvironmentManifestsResponse = named("ListEnvironmentManifestsResponse", ListEnvironmentManifestsResponseSchema);
28
+ export const EnvironmentManifestVersions = named("EnvironmentManifestVersions", EnvironmentManifestVersionsSchema);
29
+ export const DeleteEnvironmentManifestResponse = named("DeleteEnvironmentManifestResponse", DeleteEnvironmentManifestResponseSchema);
30
+ export const PutEnvironmentSecretValueRequest = named("PutEnvironmentSecretValueRequest", PutEnvironmentSecretValueRequestSchema);
31
+ export const EnvironmentSnapshot = named("EnvironmentSnapshot", EnvironmentSnapshotSchema);
32
+ export const RestoreEnvironmentRequest = named("RestoreEnvironmentRequest", RestoreEnvironmentRequestSchema);
33
+ export const EnvironmentRestore = named("EnvironmentRestore", EnvironmentRestoreSchema);
34
+ export const ForkEnvironmentRequest = named("ForkEnvironmentRequest", ForkEnvironmentRequestSchema);
35
+ export const EnvironmentForkPlan = named("EnvironmentForkPlan", EnvironmentForkPlanSchema);
36
+ export const ForkEnvironmentResponse = named("ForkEnvironmentResponse", ForkEnvironmentResponseSchema);
37
+ export const EnvironmentVersions = named("EnvironmentVersions", EnvironmentVersionsSchema);
38
+ export const ListEnvironmentsResponse = named("ListEnvironmentsResponse", ListEnvironmentsResponseSchema);
39
+ export const DeleteEnvironmentResponse = named("DeleteEnvironmentResponse", DeleteEnvironmentResponseSchema);
40
+ export const ListEnvironmentEventsResponse = named("ListEnvironmentEventsResponse", ListEnvironmentEventsResponseSchema);
24
41
  export const ArtifactVersionView = named("ArtifactVersionView", ArtifactVersionViewSchema);
25
42
  export const ArtifactView = named("ArtifactView", ArtifactViewSchema);
43
+ export const ArtifactListItem = named("ArtifactListItem", ArtifactListItemSchema);
44
+ export const ArtifactPage = named("ArtifactPage", ArtifactPageSchema.extend({ artifacts: z.array(ArtifactListItem) }));
26
45
  export const ListArtifactsResponse = named("ListArtifactsResponse", ListArtifactsResponseSchema);
27
46
  export const UploadArtifactResponse = named("UploadArtifactResponse", UploadArtifactResponseSchema);
28
47
  export const DefinitionFileView = named("DefinitionFileView", DefinitionFileViewSchema);
@@ -43,7 +62,7 @@ export const ListSessionsResponse = named("ListSessionsResponse", ListSessionsRe
43
62
  export const PutSessionRequest = named("PutSessionRequest", PutSessionRequestSchema);
44
63
  export const SessionView = named("SessionView", SessionViewSchema);
45
64
  export const LiveEvent = named("LiveEvent", LiveEventSchema);
46
- /** `sandbox.state` → `SandboxStateEvent`. */
65
+ /** `environment.state` → `EnvironmentStateEvent`. */
47
66
  export function eventComponentName(type) {
48
67
  return `${type
49
68
  .split(/[._]/)
@@ -64,21 +83,23 @@ export const TenantSandboxView = named("TenantSandboxView", TenantSandboxViewSch
64
83
  export const ModelUsageTotals = named("ModelUsageTotals", ModelUsageTotalsSchema);
65
84
  export const ModelBudgets = named("ModelBudgets", ModelBudgetsSchema);
66
85
  export const PutModelBudgetsRequest = named("PutModelBudgetsRequest", PutModelBudgetsRequestSchema);
67
- export const PutTenantSandboxRequest = named("PutTenantSandboxRequest", PutTenantSandboxRequestSchema);
86
+ export const ToolPolicy = named("ToolPolicy", ToolPolicySchema);
87
+ export const PutToolPolicyRequest = named("PutToolPolicyRequest", PutToolPolicyRequestSchema);
88
+ export const PutModelInputsRequest = named("PutModelInputsRequest", PutModelInputsRequestSchema);
89
+ export const ModelInputsView = named("ModelInputsView", ModelInputsViewSchema);
90
+ export const PutTenantEnvironmentsRequest = named("PutTenantEnvironmentsRequest", PutTenantEnvironmentsRequestSchema);
68
91
  export const ListProvidersResponse = named("ListProvidersResponse", ListProvidersResponseSchema);
69
92
  export const HostModelView = named("HostModelView", HostModelViewSchema);
70
93
  export const PutHostModelRequest = named("PutHostModelRequest", PutHostModelRequestSchema);
71
94
  export const SelectHostModelRequest = named("SelectHostModelRequest", SelectHostModelRequestSchema);
72
- export const CreateVaultRequest = named("CreateVaultRequest", CreateVaultRequestSchema);
73
- export const VaultInfo = named("VaultInfo", VaultInfoSchema);
74
- export const ListVaultsResponse = named("ListVaultsResponse", ListVaultsResponseSchema);
75
- export const CreateCredentialRequest = named("CreateCredentialRequest", CreateCredentialRequestSchema);
76
- export const CredentialInfo = named("CredentialInfo", CredentialInfoSchema);
77
- export const ListCredentialsResponse = named("ListCredentialsResponse", ListCredentialsResponseSchema);
78
- export const RotateCredentialRequest = named("RotateCredentialRequest", RotateCredentialRequestSchema);
95
+ export const PutEnvironmentSecretRequest = named("PutEnvironmentSecretRequest", PutEnvironmentSecretRequestSchema);
96
+ export const EnvironmentSecretView = named("EnvironmentSecretView", EnvironmentSecretViewSchema);
97
+ export const ListEnvironmentSecretsResponse = named("ListEnvironmentSecretsResponse", ListEnvironmentSecretsResponseSchema);
79
98
  export const DeletedResponse = named("DeletedResponse", DeletedResponseSchema);
80
99
  export const McpPreviewRequest = named("McpPreviewRequest", McpPreviewRequestSchema);
81
100
  export const McpPreview = named("McpPreview", McpPreviewSchema);
101
+ export const CredentialCoverageRequest = named("CredentialCoverageRequest", CredentialCoverageRequestSchema);
102
+ export const CredentialCoverage = named("CredentialCoverage", CredentialCoverageSchema);
82
103
  export const Jwks = named("Jwks", JwksSchema);
83
104
  export const SigningKeyList = named("SigningKeyList", SigningKeyListSchema);
84
105
  export const SigningKeyView = named("SigningKeyView", SigningKeyViewSchema);
@@ -92,5 +113,8 @@ export const HistoryPage = named("HistoryPage", HistoryPageSchema.extend({ items
92
113
  export const SessionUsageTotals = named("SessionUsageTotals", SessionUsageTotalsSchema);
93
114
  export const ModelCallsPage = named("ModelCallsPage", ModelCallsPageSchema.extend({ calls: z.array(ModelCall) }));
94
115
  export const ModelCallExportPage = named("ModelCallExportPage", ModelCallExportPageSchema.extend({ calls: z.array(ModelCall) }));
95
- export const SandboxPage = named("SandboxPage", SandboxPageSchema.extend({ sandboxes: z.array(SandboxView) }));
116
+ export const EnvironmentPage = named("EnvironmentPage", EnvironmentPageSchema.extend({ environments: z.array(EnvironmentView) }));
117
+ export const ToolCall = named("ToolCall", ToolCallSchema);
118
+ export const ToolCallsPage = named("ToolCallsPage", ToolCallsPageSchema.extend({ calls: z.array(ToolCall) }));
119
+ export const TurnTrace = named("TurnTrace", TurnTraceSchema);
96
120
  export const MeResponse = named("MeResponse", MeResponseSchema);
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * The `keys` service's route on the gateway's listener (F4.2, `contract.ts`): one operation of
3
3
  * `Keys` per request, run with the vault key of the gateway's Tenant. Errors keep their status,
4
- * code and details. Logs the operation and its outcome, never an argument or a result.
4
+ * code and details. Logs the operation, its outcome and an internal failure's cause, never an
5
+ * argument or a result.
5
6
  */
6
7
  import type { Env, Hono, MiddlewareHandler } from "hono";
7
8
  import type { Logger } from "../../tenant/types.js";
@@ -29,6 +29,13 @@ export function mountKeysRoutes(app, options) {
29
29
  }
30
30
  catch (error) {
31
31
  answer = { error: errorOf(error) };
32
+ // The caller sees only "The keys service failed": the cause is logged, never the args.
33
+ if (answer.error.status === 500)
34
+ options.logger.error("keys_request_failed", {
35
+ operation,
36
+ error: error?.message ?? String(error),
37
+ stack: error?.stack,
38
+ });
32
39
  }
33
40
  options.logger.info("keys_request", {
34
41
  operation,
@@ -40,7 +47,13 @@ export function mountKeysRoutes(app, options) {
40
47
  }
41
48
  function errorOf(error) {
42
49
  if (error instanceof VaultError)
43
- return { kind: "vault", status: error.status, message: error.message };
50
+ return {
51
+ kind: "vault",
52
+ status: error.status,
53
+ message: error.message,
54
+ ...(error.rejection.code === undefined ? {} : { code: error.rejection.code }),
55
+ ...(error.rejection.details === undefined ? {} : { details: error.rejection.details }),
56
+ };
44
57
  if (error instanceof HttpError)
45
58
  return {
46
59
  kind: "http",
@@ -3,6 +3,7 @@ import type { ModelCallHandler } from "../../gates/handler.js";
3
3
  import { type InflightCalls } from "../../gates/inflight.js";
4
4
  import type { McpHandler } from "../../gates/mcp-handler.js";
5
5
  import type { ToolCalls } from "../../gates/tool-calls.js";
6
+ import type { JournalCheck } from "../../gates/journal.js";
6
7
  import type { HttpOutcome, HttpToolCall } from "../../gates/http-tool.js";
7
8
  import type { Keys } from "../../keys/keys.js";
8
9
  import type { Logger } from "../../tenant/types.js";
@@ -34,6 +35,11 @@ export interface GatesAppOptions {
34
35
  };
35
36
  /** Keyed MCP and HTTP tool calls, which outlive their client and run once (F4.1 G3). */
36
37
  readonly toolCalls?: ToolCalls;
38
+ /**
39
+ * The journal check (R5.6): a run's tool call must be keyed, and journaled as sent. Without
40
+ * it the gate sends what it is asked to.
41
+ */
42
+ readonly journal?: JournalCheck;
37
43
  /** The keys service's operations (F4.2). Without it the keys route answers 404. */
38
44
  readonly keys?: () => Promise<Keys>;
39
45
  /** Logs the keys service's requests and refused credentials. */
@@ -20,6 +20,7 @@
20
20
  import { createHash } from "node:crypto";
21
21
  import { Hono } from "hono";
22
22
  import { bodyLimit } from "hono/body-limit";
23
+ import { HTTPException } from "hono/http-exception";
23
24
  import { isTenantId } from "@nylorun/core/compatibility";
24
25
  import { MAX_MODEL_CALL_BYTES, MODEL_CALLS_PATH, ModelCallBodySchema, TENANT_HEADER, } from "../../gates/contract.js";
25
26
  import { InflightConflict, InflightStale } from "../../gates/inflight.js";
@@ -38,6 +39,18 @@ export function createGatesApp(options) {
38
39
  const app = new Hono();
39
40
  const maxSize = options.maxBodyBytes ?? MAX_MODEL_CALL_BYTES;
40
41
  const logger = options.logger ?? { info() { }, warn() { }, error() { } };
42
+ // Hono's default, but logged through the logger: never the body, which may hold secrets.
43
+ app.onError((error, c) => {
44
+ if (error instanceof HTTPException)
45
+ return error.getResponse();
46
+ logger.error("request_failed", {
47
+ method: c.req.method,
48
+ route: c.req.routePath,
49
+ error: error.message,
50
+ stack: error.stack,
51
+ });
52
+ return c.text("Internal Server Error", 500);
53
+ });
41
54
  app.get("/health", (c) => c.json({ status: "ok" }));
42
55
  app.get("/ready", async (c) => (await options.ready()) ? c.json({ ready: true }) : c.json({ ready: false }, 503));
43
56
  const bearerOf = (c) => /^Bearer (.+)$/.exec(c.req.header("authorization") ?? "")?.[1];
@@ -146,6 +159,24 @@ export function createGatesApp(options) {
146
159
  const claims = c.get("run");
147
160
  return claims ? { sessionId: claims.sessionId, epoch: claims.epoch } : undefined;
148
161
  };
162
+ /**
163
+ * Under a run token, the 400 or 409 for a tool call the effect journal does not hold, running,
164
+ * as sent (R5.6); else the call's span context from its row (R7.4), none under core's credential.
165
+ */
166
+ const unjournaled = async (c, tenantId, key, call) => {
167
+ const claims = c.get("run");
168
+ if (!claims || !options.journal)
169
+ return {};
170
+ if (!key)
171
+ return {
172
+ refused: c.json(gateError("key_required", "A run's tool call needs its effect id as its Idempotency-Key"), 400),
173
+ };
174
+ const answer = await options.journal.check(tenantId, claims, key, call);
175
+ if (answer.refused === undefined)
176
+ return answer.traceparent ? { traceparent: answer.traceparent } : {};
177
+ logger.warn("gate_call_unjournaled", { route: c.req.path, session: claims.sessionId, effect: key, reason: answer.refused });
178
+ return { refused: c.json(gateError("effect_not_journaled", answer.refused), 409) };
179
+ };
149
180
  /** 409 for a keyed re-send the in-flight map refused, or undefined. */
150
181
  const refusedJoin = (c, error) => {
151
182
  if (error instanceof InflightStale)
@@ -203,12 +234,21 @@ export function createGatesApp(options) {
203
234
  const body = { ...request.body, server: server.server };
204
235
  const signal = c.req.raw.signal;
205
236
  const key = c.req.header("idempotency-key");
237
+ const journaled = await unjournaled(c, request.tenantId, key, {
238
+ kind: "mcp",
239
+ server: body.server,
240
+ name: body.name,
241
+ arguments: body.arguments,
242
+ });
243
+ if (journaled.refused)
244
+ return journaled.refused;
245
+ const traced = journaled.traceparent ? { traceparent: journaled.traceparent } : {};
206
246
  try {
207
247
  // Keyed: the call runs under its own signal, once, and outlives this request (G3). The
208
248
  // hash covers the session, so a re-send joins only its own session's call.
209
249
  const answer = key && toolCalls
210
- ? await untilAborted(toolCalls.run(request.tenantId, key, createHash("sha256").update(canonical(body)).digest("hex"), (own) => mcp.call(request.tenantId, body, own), ownerOf(c)), signal)
211
- : await mcp.call(request.tenantId, body, signal);
250
+ ? await untilAborted(toolCalls.run(request.tenantId, key, createHash("sha256").update(canonical(body)).digest("hex"), (own) => mcp.call(request.tenantId, { ...body, key, ...traced }, own), ownerOf(c)), signal)
251
+ : await mcp.call(request.tenantId, { ...body, ...traced }, signal);
212
252
  if (signal.aborted)
213
253
  return new Response(null, { status: 499 });
214
254
  return c.json(answer);
@@ -233,13 +273,19 @@ export function createGatesApp(options) {
233
273
  if (!tool.ok)
234
274
  return tool.response;
235
275
  // A run token's turn is the call's: it names the request's `Nylorun-Turn-Id`.
236
- const call = {
276
+ let call = {
237
277
  ...request.body,
238
278
  tool: tool.ref,
239
279
  turnId: c.get("run")?.turnId ?? request.body.turnId,
240
280
  };
241
281
  const signal = c.req.raw.signal;
242
282
  const key = c.req.header("idempotency-key");
283
+ const journaled = await unjournaled(c, request.tenantId, key, { kind: "http", tool: call.tool, input: call.input });
284
+ if (journaled.refused)
285
+ return journaled.refused;
286
+ // The span context from the call's journal row (R7.4), never from the body.
287
+ if (journaled.traceparent)
288
+ call = { ...call, traceparent: journaled.traceparent };
243
289
  try {
244
290
  // Keyed: runs once under its own signal and outlives this request, as an MCP call.
245
291
  const answer = key && toolCalls
@@ -334,6 +380,9 @@ export function createGatesApp(options) {
334
380
  }
335
381
  /** `promise`, or a rejection as soon as `signal` aborts (the call itself keeps running). */
336
382
  function untilAborted(promise, signal) {
383
+ // Nobody may wait for it (the caller went away first); its rejection, a cancel or the gate's
384
+ // shutdown, is not an unhandled one.
385
+ promise.catch(() => { });
337
386
  if (signal.aborted)
338
387
  return Promise.reject(signal.reason);
339
388
  return new Promise((resolve, reject) => {
@@ -12,14 +12,15 @@ import { declaredRoute, pathSegments, routeNotFound } from "./define.js";
12
12
  import { jsonResponse, rejectionOf } from "./respond.js";
13
13
  import { accessRoutes } from "./routes/access.js";
14
14
  import { meRoutes } from "./routes/me.js";
15
- import { sandboxRoutes } from "./routes/sandboxes.js";
15
+ import { environmentRoutes } from "./routes/environments.js";
16
+ import { environmentManifestRoutes } from "./routes/environment-manifests.js";
16
17
  import { artifactRoutes } from "./routes/artifacts.js";
17
18
  import { readRoutes } from "./routes/reads.js";
18
19
  import { sessionRoutes } from "./routes/sessions.js";
19
20
  import { fileRoutes } from "./routes/files.js";
20
21
  import { keyRoutes } from "./routes/keys.js";
21
22
  import { tenantRoutes } from "./routes/tenant.js";
22
- import { vaultRoutes } from "./routes/vaults.js";
23
+ import { coverageRoutes } from "./routes/coverage.js";
23
24
  import { mcpRoutes } from "./routes/mcp.js";
24
25
  let app;
25
26
  /** The Tenant API, built on first use. */
@@ -44,11 +45,12 @@ function build() {
44
45
  });
45
46
  sessionRoutes(api);
46
47
  fileRoutes(api);
47
- sandboxRoutes(api);
48
+ environmentRoutes(api);
49
+ environmentManifestRoutes(api);
48
50
  artifactRoutes(api);
49
51
  tenantRoutes(api);
50
52
  keyRoutes(api);
51
- vaultRoutes(api);
53
+ coverageRoutes(api);
52
54
  mcpRoutes(api);
53
55
  accessRoutes(api);
54
56
  meRoutes(api);
@@ -56,13 +58,22 @@ function build() {
56
58
  a2aRoutes(api);
57
59
  api.notFound(routeNotFound);
58
60
  api.onError((error, c) => {
59
- const { outgoing } = c.env;
61
+ const { outgoing, tenant } = c.env;
62
+ const rejection = rejectionOf(error);
63
+ // The client sees only `internal_error`: the operator's log has the cause. The route's
64
+ // pattern, not its path, and never the body, which may hold secrets.
65
+ if (rejection.status === 500)
66
+ tenant.config.logger.error("request_failed", {
67
+ method: c.req.method,
68
+ route: c.req.routePath,
69
+ error: error.message,
70
+ stack: error.stack,
71
+ });
60
72
  // Once a response has started, the rejection can only end it.
61
73
  if (outgoing.headersSent) {
62
74
  outgoing.end();
63
75
  return RESPONSE_ALREADY_SENT;
64
76
  }
65
- const rejection = rejectionOf(error);
66
77
  return jsonResponse(rejection.status, rejection.body, rejection.headers);
67
78
  });
68
79
  readRoutes(api);
@@ -1,4 +1,4 @@
1
- /** The body as text. */
2
- export declare function readText(request: Request): Promise<string>;
1
+ /** The body as text; past `maxBytes`, `413 Request too large`. */
2
+ export declare function readText(request: Request, maxBytes?: number): Promise<string>;
3
3
  /** The body as JSON, before any schema. */
4
- export declare function readJson(request: Request): Promise<unknown>;
4
+ export declare function readJson(request: Request, maxBytes?: number): Promise<unknown>;
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Request bodies of Tenant routes, read as the router they replace read them
3
- * (`tenant/http.ts`): at most 1 MiB, UTF-8, and a missing or malformed JSON body is
4
- * `400 Invalid JSON`.
3
+ * (`tenant/http.ts`): at most 1 MiB unless a route allows more (an endpoint that takes files
4
+ * inline), UTF-8, and a missing or malformed JSON body is `400 Invalid JSON`.
5
5
  */
6
6
  import { fail } from "../../tenant/http.js";
7
7
  const MAX_BODY_BYTES = 1024 * 1024;
8
- /** The body as text. */
9
- export async function readText(request) {
8
+ /** The body as text; past `maxBytes`, `413 Request too large`. */
9
+ export async function readText(request, maxBytes = MAX_BODY_BYTES) {
10
10
  if (request.body === null)
11
11
  return "";
12
12
  const chunks = [];
@@ -17,7 +17,7 @@ export async function readText(request) {
17
17
  if (done)
18
18
  break;
19
19
  bytes += value.byteLength;
20
- if (bytes > MAX_BODY_BYTES) {
20
+ if (bytes > maxBytes) {
21
21
  await reader.cancel();
22
22
  fail(413, "Request too large");
23
23
  }
@@ -26,8 +26,8 @@ export async function readText(request) {
26
26
  return Buffer.concat(chunks).toString("utf8");
27
27
  }
28
28
  /** The body as JSON, before any schema. */
29
- export async function readJson(request) {
30
- const text = await readText(request);
29
+ export async function readJson(request, maxBytes = MAX_BODY_BYTES) {
30
+ const text = await readText(request, maxBytes);
31
31
  try {
32
32
  return JSON.parse(text);
33
33
  }
@@ -12,6 +12,7 @@
12
12
  import type { IncomingMessage } from "node:http";
13
13
  import type { OpenAPIHono, RouteConfig } from "@hono/zod-openapi";
14
14
  import type { Context, Handler } from "hono";
15
+ import { z } from "zod";
15
16
  import type { SubjectScope } from "@nylorun/core/contracts";
16
17
  import { type KeyAccess } from "../../tenant/auth.js";
17
18
  import type { AuthScope } from "../../tenant/context.js";
@@ -56,4 +57,9 @@ export declare function routeNotFound(c: Context<TenantEnv>): Promise<Response>;
56
57
  export declare function keyAccess(access: RouteAccess): KeyAccess;
57
58
  /** The declared route `method path` is, if any. `{param}` segments match any one segment. */
58
59
  export declare function declaredRoute(method: string, segments: readonly string[]): RouteAccess | undefined;
60
+ /** W3C trace context a request may send (R7.4): the turn it starts joins the caller's trace. */
61
+ export declare const TraceHeaders: z.ZodObject<{
62
+ traceparent: z.ZodOptional<z.ZodString>;
63
+ tracestate: z.ZodOptional<z.ZodString>;
64
+ }, z.core.$strip>;
59
65
  export declare function tenantRoute(api: OpenAPIHono<TenantEnv>, access: RouteAccess, route: RouteConfig, handler: Handler<TenantEnv>): void;
@@ -71,6 +71,14 @@ function authenticated(access) {
71
71
  await next();
72
72
  };
73
73
  }
74
+ /** W3C trace context a request may send (R7.4): the turn it starts joins the caller's trace. */
75
+ export const TraceHeaders = z.object({
76
+ traceparent: z
77
+ .string()
78
+ .optional()
79
+ .meta({ description: "W3C trace context: the turn this request starts joins the caller's trace (feature `traces`). A malformed value is ignored" }),
80
+ tracestate: z.string().optional().meta({ description: "W3C trace context, kept with `traceparent`" }),
81
+ });
74
82
  export function tenantRoute(api, access, route, handler) {
75
83
  const takes = (credential) => access.credentials.includes(credential);
76
84
  const schemes = [...new Set(access.credentials.map((credential) => SCHEMES[credential]))];
@@ -97,7 +105,11 @@ export function tenantRoute(api, access, route, handler) {
97
105
  ...schemes.map((scheme) => ({ [scheme]: [] })),
98
106
  ...(access.anonymous ? [{}] : []),
99
107
  ],
100
- request: { ...route.request, headers },
108
+ // A route's own headers (`traceparent`, R7.4) beside the common ones.
109
+ request: {
110
+ ...route.request,
111
+ headers: route.request?.headers instanceof z.ZodObject ? headers.extend(route.request.headers.shape) : headers,
112
+ },
101
113
  responses: {
102
114
  400: rejected("Invalid headers, path, body or cursor"),
103
115
  401: rejected(takes("token")
@@ -30,7 +30,7 @@ export function rejectionOf(error) {
30
30
  error?.message === "Invalid cursor"
31
31
  ? 400
32
32
  : 500;
33
- const rejection = error instanceof HttpError ? error.rejection : {};
33
+ const rejection = error instanceof HttpError || error instanceof VaultError ? error.rejection : {};
34
34
  return {
35
35
  status,
36
36
  body: {
@@ -14,8 +14,8 @@
14
14
  */
15
15
  import { posix } from "node:path";
16
16
  import { z } from "zod";
17
- import { ArtifactLabelsSchema, CreateArtifactLinkRequestSchema, PutTenantArtifactsRequestSchema, } from "@nylorun/core/contracts";
18
- import { ArtifactDiff, ArtifactTree, ArtifactLink, ArtifactView, CreateArtifactLinkRequest, DeleteArtifactResponse, ListArtifactsResponse, PutTenantArtifactsRequest, TenantArtifactsView, UploadArtifactResponse, } from "../../components.js";
17
+ import { ArtifactLabelsSchema, ArtifactKindSchema, CreateArtifactLinkRequestSchema, PutTenantArtifactsRequestSchema, } from "@nylorun/core/contracts";
18
+ import { ArtifactDiff, ArtifactTree, ArtifactLink, ArtifactView, ArtifactPage, CreateArtifactLinkRequest, DeleteArtifactResponse, ListArtifactsResponse, PutTenantArtifactsRequest, TenantArtifactsView, UploadArtifactResponse, } from "../../components.js";
19
19
  import { BlobRangeError } from "../../../blob/index.js";
20
20
  import { effectiveArtifactLimits, readArtifactsConfig, writeArtifactsConfig, } from "../../../artifacts/config.js";
21
21
  import { contentKey, diffManifests, entryAt, readManifest } from "../../../artifacts/folders.js";
@@ -24,10 +24,12 @@ import { zipStream, zipTooLarge } from "../../../artifacts/zip.js";
24
24
  import { normalizeContentType } from "../../../artifacts/media-types.js";
25
25
  import { artifactContent, deleteArtifact, folderContent, getArtifact, listArtifacts, readableArtifact, uploadArtifact, versionOf, } from "../../../artifacts/service.js";
26
26
  import { accessOf } from "../../../tenant/auth.js";
27
+ import { readAccess, readStoreOf } from "../../../reads/access.js";
27
28
  import { fail } from "../../../tenant/http.js";
28
29
  import { readJson } from "../body.js";
29
30
  import { tenantRoute } from "../define.js";
30
31
  import { jsonResponse } from "../respond.js";
32
+ import { pageQuery, parseQuery } from "./reads.js";
31
33
  /** Reading and writing artifacts: whoever may use sessions, a person only in their own. */
32
34
  const OWN = {
33
35
  credentials: ["application", "subject", "token"],
@@ -78,6 +80,15 @@ const labelQuery = z
78
80
  .union([z.string(), z.array(z.string())])
79
81
  .optional()
80
82
  .meta({ description: "`key=value`; repeat it for several labels" });
83
+ const artifactPageQuery = pageQuery
84
+ .extend({
85
+ sessionId: z.string().optional().meta({
86
+ description: "Only artifacts belonging to this session; excludes Tenant-owned artifacts",
87
+ }),
88
+ kind: ArtifactKindSchema.optional(),
89
+ label: labelQuery,
90
+ })
91
+ .strict();
81
92
  /** `label=k=v`, repeated. */
82
93
  function labelsOf(values) {
83
94
  if (values === undefined || values.length === 0)
@@ -216,7 +227,9 @@ function zipResponse(ctx, artifact, version, manifest, request) {
216
227
  const refused = zipTooLarge(manifest.entries.length, version.size);
217
228
  if (refused)
218
229
  fail(400, refused);
219
- const iterator = zipStream(manifest.entries.map((entry) => ({
230
+ const iterator = zipStream(
231
+ // A v2 manifest's links and empty directories are not files: the zip holds the files.
232
+ manifest.entries.filter((entry) => entry.type === undefined).map((entry) => ({
220
233
  name: entry.path,
221
234
  open: async () => {
222
235
  const got = await ctx.blobs.get(contentKey(entry.sha256), { signal: request.signal });
@@ -311,13 +324,24 @@ export function artifactRoutes(api) {
311
324
  path: "/v1/artifacts",
312
325
  tags: ["Artifacts"],
313
326
  summary: "List artifacts",
314
- description: "Oldest first: of one session, or of every session the caller reaches (an application key: every artifact).",
327
+ description: "Without limit, the existing metadata list, oldest first. Explicit limit (1–200) opts into metadata pages ordered by creation time and artifact ID descending, with an opaque nextCursor bound to the Tenant and filters. " +
328
+ "sessionId selects only that session's artifacts, excluding Tenant-owned artifacts. Paged reads support kind and repeated label=key=value equality filters. " +
329
+ "An application key as itself sees all artifacts, including Tenant-owned; a caller acting for a person sees only their sessions' artifacts of allowed agents. Authorization is checked on every page. " +
330
+ "Newer inserts appear on a fresh traversal, not in pages already passed.",
315
331
  request: {
316
- query: z.object({ sessionId: z.string().optional().meta({ description: "Only this session's" }) }),
332
+ query: artifactPageQuery,
333
+ },
334
+ responses: {
335
+ 200: json(z.union([ListArtifactsResponse, ArtifactPage]), "The artifacts; explicit limit opts into pagination"),
317
336
  },
318
- responses: { 200: json(ListArtifactsResponse, "The artifacts") },
319
337
  }, async (c) => {
320
338
  const sessionId = c.req.query("sessionId");
339
+ if (c.req.query("limit") !== undefined) {
340
+ const { limit, cursor, kind } = parseQuery(artifactPageQuery, c.req.query());
341
+ if (limit === undefined)
342
+ return fail(400, "Pagination requires limit");
343
+ return jsonResponse(200, await readStoreOf(c.env.tenant).artifacts({ sessionId, kind, labels: labelsOf(c.req.queries("label")) ?? {} }, { limit, cursor }, readAccess(c.get("scope"))));
344
+ }
321
345
  return jsonResponse(200, await listArtifacts(c.env.tenant, sessionId === undefined ? {} : { sessionId }, accessOf(c.get("scope"))));
322
346
  });
323
347
  tenantRoute(api, OWN, {
@@ -456,9 +480,12 @@ export function artifactRoutes(api) {
456
480
  path: "/v1/artifacts/{artifactId}",
457
481
  tags: ["Artifacts"],
458
482
  summary: "Delete an artifact",
459
- description: "Deletes every version and its bytes; its links stop working. A session's artifact gets `artifact.deleted` in its history.",
483
+ description: "Deletes every version and its bytes; its links stop working. A session's artifact gets `artifact.deleted` in its history. An Environment's disk versions are deleted through `/v1/environments/{environmentId}/versions/{version}` (`409` here).",
460
484
  request: { params: artifactId },
461
- responses: { 200: json(DeleteArtifactResponse, "Deleted") },
485
+ responses: {
486
+ 200: json(DeleteArtifactResponse, "Deleted"),
487
+ 409: { description: "The artifact holds an Environment's disk versions" },
488
+ },
462
489
  }, async (c) => jsonResponse(200, await deleteArtifact(c.env.tenant, c.req.param("artifactId"), accessOf(c.get("scope")))));
463
490
  tenantRoute(api, LINK, {
464
491
  method: "get",
@@ -0,0 +1,9 @@
1
+ /**
2
+ * `POST /v1/tenant/credential-coverage` (the Management API): what a session of a saved agent
3
+ * would send for each URL it names, in a given Environment. A dry run of each call's credential
4
+ * choice (`VaultService.coverage`); no secret is read. An Environment's secrets themselves are
5
+ * written on the Runtime API (`/v1/environments/{id}/secrets`, `routes/environments.ts`).
6
+ */
7
+ import type { OpenAPIHono } from "@hono/zod-openapi";
8
+ import type { TenantEnv } from "../app.js";
9
+ export declare function coverageRoutes(api: OpenAPIHono<TenantEnv>): void;
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ import { CredentialCoverageRequestSchema } from "@nylorun/core/contracts";
3
+ import { CredentialCoverage, CredentialCoverageRequest, Rejected } from "../../components.js";
4
+ import { readJson } from "../body.js";
5
+ import { tenantRoute } from "../define.js";
6
+ import { jsonResponse } from "../respond.js";
7
+ import { fail } from "../../../tenant/http.js";
8
+ /** A Management API route: a management key. */
9
+ const MANAGEMENT = { credentials: ["management"], scopes: "never" };
10
+ const json = (schema, description) => ({
11
+ description,
12
+ content: { "application/json": { schema } },
13
+ });
14
+ export function coverageRoutes(api) {
15
+ tenantRoute(api, MANAGEMENT, {
16
+ method: "post",
17
+ path: "/v1/tenant/credential-coverage",
18
+ tags: ["Environments"],
19
+ summary: "Check an agent's credentials against an Environment",
20
+ description: "For each remote MCP server and each HTTP tool with a `credential` that the saved agent `agentId` declares (its own, its agents used as tools' and a flow's), the credential a session that names `environmentId` would send: the Environment's secret bound to the URL (`covered`), or none (`missing`). No secret is read and no server is called.",
21
+ request: {
22
+ body: { required: true, content: { "application/json": { schema: CredentialCoverageRequest } } },
23
+ },
24
+ responses: {
25
+ 200: json(CredentialCoverage, "One entry per declared URL"),
26
+ 404: json(Rejected, "No such agent, or no such Environment"),
27
+ },
28
+ }, async (c) => {
29
+ const request = CredentialCoverageRequestSchema.parse(await readJson(c.req.raw));
30
+ const tenant = c.env.tenant;
31
+ const definition = (await tenant.store.tx((t) => t.get("definitions", request.agentId))) ?? fail(404, "Definition not found");
32
+ return jsonResponse(200, await tenant.vault.coverage(definition.manifest, request));
33
+ });
34
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Environment manifests (`/v1/environment-manifests/**`, protocol 14, D63): save, read, list and
3
+ * delete the named, versioned definitions Environments are made from. A save never changes an
4
+ * Environment. Reading needs what reading an Environment needs; saving and deleting need
5
+ * `environments:write`, from any client (Q12).
6
+ */
7
+ import type { OpenAPIHono } from "@hono/zod-openapi";
8
+ import type { TenantEnv } from "../app.js";
9
+ export declare function environmentManifestRoutes(api: OpenAPIHono<TenantEnv>): void;