@lostgradient/weft 0.12.0 → 0.13.0

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 (191) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/api.d.ts +2 -0
  3. package/dist/cli/api.js +3 -4
  4. package/dist/cli/generated/operation-catalog.snapshot.json +508 -12
  5. package/dist/cli/generated/operation-client.generated.d.ts +118 -10
  6. package/dist/cli/generated/operation-client.generated.js +74 -1
  7. package/dist/cli/operation-catalog-snapshot.d.ts +11 -2
  8. package/dist/cli/operation-catalog-snapshot.js +14 -5
  9. package/dist/cli/operation-client-runtime.d.ts +29 -0
  10. package/dist/client/client-storage.d.ts +24 -0
  11. package/dist/client/client-storage.js +14 -0
  12. package/dist/client/handle-delegation.d.ts +3 -3
  13. package/dist/client/handle-delegation.js +2 -2
  14. package/dist/client/http-client-requests.d.ts +5 -3
  15. package/dist/client/http-client-requests.js +20 -2
  16. package/dist/client/http-client-storage.d.ts +3 -0
  17. package/dist/client/http-client-storage.js +110 -0
  18. package/dist/client/http-client.d.ts +9 -6
  19. package/dist/client/http-client.js +13 -18
  20. package/dist/client/http-operations.d.ts +3 -1
  21. package/dist/client/http-operations.js +77 -1
  22. package/dist/client/http-request.d.ts +15 -8
  23. package/dist/client/http-request.js +19 -7
  24. package/dist/client/in-process-operations.d.ts +2 -2
  25. package/dist/client/in-process-operations.js +2 -2
  26. package/dist/client/index.d.ts +5 -1
  27. package/dist/client/index.js +13 -2
  28. package/dist/client/interface.d.ts +26 -26
  29. package/dist/client/local.d.ts +9 -6
  30. package/dist/client/local.js +9 -4
  31. package/dist/client/search-params.js +10 -6
  32. package/dist/client/start-body.d.ts +3 -1
  33. package/dist/client/start-body.js +9 -0
  34. package/dist/core/bulk-workflow-filter.d.ts +2 -1
  35. package/dist/core/bulk-workflow-filter.js +5 -1
  36. package/dist/core/engine/async-activity-records.d.ts +12 -1
  37. package/dist/core/engine/async-activity-records.js +81 -2
  38. package/dist/core/engine/bulk-operations-purge.js +16 -1
  39. package/dist/core/engine/bulk-operations-shared.js +2 -0
  40. package/dist/core/engine/callback-creators-schedule.d.ts +2 -1
  41. package/dist/core/engine/callback-creators-schedule.js +3 -3
  42. package/dist/core/engine/checkpoint-reads.js +11 -1
  43. package/dist/core/engine/child-workflow.js +15 -6
  44. package/dist/core/engine/construction.js +3 -0
  45. package/dist/core/engine/disposal.js +2 -0
  46. package/dist/core/engine/engine-internal-types.d.ts +4 -1
  47. package/dist/core/engine/fenced-write.d.ts +5 -3
  48. package/dist/core/engine/finalizer-status.d.ts +10 -0
  49. package/dist/core/engine/finalizer-status.js +82 -0
  50. package/dist/core/engine/index.d.ts +26 -2
  51. package/dist/core/engine/index.js +71 -8
  52. package/dist/core/engine/internals.d.ts +3 -0
  53. package/dist/core/engine/lease-health.d.ts +64 -0
  54. package/dist/core/engine/lease-health.js +0 -0
  55. package/dist/core/engine/lease-manager.d.ts +4 -2
  56. package/dist/core/engine/lease-manager.js +32 -4
  57. package/dist/core/engine/lifecycle/recovered-services.js +0 -2
  58. package/dist/core/engine/lifecycle/shared.d.ts +11 -8
  59. package/dist/core/engine/lifecycle/start-batch.js +12 -0
  60. package/dist/core/engine/lifecycle/start.d.ts +1 -1
  61. package/dist/core/engine/lifecycle/start.js +34 -5
  62. package/dist/core/engine/operations-coordination.d.ts +1 -12
  63. package/dist/core/engine/operations-coordination.js +57 -10
  64. package/dist/core/engine/operations-speculate.d.ts +1 -1
  65. package/dist/core/engine/operations-speculate.js +19 -5
  66. package/dist/core/engine/registration.js +14 -0
  67. package/dist/core/engine/schedule-handle.d.ts +4 -4
  68. package/dist/core/engine/schedule-handle.js +2 -2
  69. package/dist/core/engine/schedule-overlap.d.ts +11 -0
  70. package/dist/core/engine/schedule-overlap.js +50 -0
  71. package/dist/core/engine/schedule-run.d.ts +11 -3
  72. package/dist/core/engine/schedule-run.js +27 -4
  73. package/dist/core/engine/schedule-timer.js +10 -1
  74. package/dist/core/engine/schedules.d.ts +5 -4
  75. package/dist/core/engine/schedules.js +62 -56
  76. package/dist/core/engine/state-utilities.js +1 -1
  77. package/dist/core/engine/storage-io.d.ts +12 -0
  78. package/dist/core/engine/storage-io.js +49 -10
  79. package/dist/core/engine/termination/finalizer-claim.d.ts +8 -6
  80. package/dist/core/engine/termination/finalizer-claim.js +2 -1
  81. package/dist/core/engine/termination/finalizer.js +10 -14
  82. package/dist/core/engine/timeline-coordinator-constants.d.ts +3 -0
  83. package/dist/core/engine/timeline-coordinator-constants.js +1 -0
  84. package/dist/core/engine/timeline-coordinator-detail.d.ts +13 -0
  85. package/dist/core/engine/timeline-coordinator-detail.js +76 -0
  86. package/dist/core/engine/validation/schedule-options.d.ts +8 -1
  87. package/dist/core/engine/validation/schedule-options.js +18 -0
  88. package/dist/core/engine/validation/schedule.d.ts +1 -1
  89. package/dist/core/engine/validation/schedule.js +27 -3
  90. package/dist/core/engine/validation.js +66 -2
  91. package/dist/core/engine/workflow-state-stream.d.ts +5 -1
  92. package/dist/core/engine/workflow-state-stream.js +37 -14
  93. package/dist/core/events/schedule-events.d.ts +3 -4
  94. package/dist/core/events/workflow-events.d.ts +2 -1
  95. package/dist/core/list-filter-validation.d.ts +3 -0
  96. package/dist/core/list-filter-validation.js +11 -0
  97. package/dist/core/registry-snapshot.d.ts +32 -0
  98. package/dist/core/registry-snapshot.js +28 -0
  99. package/dist/core/review/index.d.ts +4 -4
  100. package/dist/core/types/activity.d.ts +52 -5
  101. package/dist/core/types/bulk.d.ts +1 -0
  102. package/dist/core/types/list-options.d.ts +6 -0
  103. package/dist/core/types/options.d.ts +6 -5
  104. package/dist/core/types/reviews.d.ts +2 -2
  105. package/dist/core/types/schedules.d.ts +45 -2
  106. package/dist/core/types/services-resolution.d.ts +5 -5
  107. package/dist/core/types/state.d.ts +64 -0
  108. package/dist/core/types/workflow-log.d.ts +3 -2
  109. package/dist/core/types/workflow-observability.d.ts +50 -0
  110. package/dist/core/types/workflow-observability.js +0 -0
  111. package/dist/core/types/workflow-registry.d.ts +7 -0
  112. package/dist/core/types.d.ts +1 -0
  113. package/dist/core/types.js +1 -0
  114. package/dist/http.js +2 -2
  115. package/dist/index.d.ts +4 -3
  116. package/dist/indexeddb.js +1 -1
  117. package/dist/server/access-policy-metadata.d.ts +92 -0
  118. package/dist/server/access-policy-metadata.js +78 -0
  119. package/dist/server/fault-to-http.d.ts +3 -7
  120. package/dist/server/fault-to-http.js +2 -34
  121. package/dist/server/handler/index.js +1 -1
  122. package/dist/server/handler/route-dispatch.d.ts +10 -3
  123. package/dist/server/handler/route-dispatch.js +19 -4
  124. package/dist/server/index.d.ts +1 -1
  125. package/dist/server/index.js +1 -0
  126. package/dist/server/interactive-operations.js +2 -0
  127. package/dist/server/openapi-error-responses.js +55 -4
  128. package/dist/server/openapi.d.ts +3 -1
  129. package/dist/server/openapi.js +4 -0
  130. package/dist/server/openrpc-document-schema.d.ts +64 -0
  131. package/dist/server/openrpc-document-schema.js +6 -26
  132. package/dist/server/openrpc.d.ts +4 -0
  133. package/dist/server/openrpc.js +9 -33
  134. package/dist/server/operation-fault.d.ts +24 -7
  135. package/dist/server/operation-fault.js +65 -13
  136. package/dist/server/operations/aggregate-workflows.d.ts +6 -0
  137. package/dist/server/operations/aggregate-workflows.js +3 -2
  138. package/dist/server/operations/async-activity.d.ts +14 -0
  139. package/dist/server/operations/async-activity.js +88 -4
  140. package/dist/server/operations/bulk-filter-helpers.d.ts +3 -0
  141. package/dist/server/operations/bulk-filter-helpers.js +27 -3
  142. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +6 -0
  143. package/dist/server/operations/bulk-signal-workflows.d.ts +6 -0
  144. package/dist/server/operations/get-stream-chunks.js +2 -7
  145. package/dist/server/operations/get-system-lease.d.ts +19 -0
  146. package/dist/server/operations/get-system-lease.js +48 -0
  147. package/dist/server/operations/get-workflow-observability.d.ts +24 -0
  148. package/dist/server/operations/get-workflow-observability.js +80 -0
  149. package/dist/server/operations/get-workflow-result.js +2 -2
  150. package/dist/server/operations/get-workflow.d.ts +2 -2
  151. package/dist/server/operations/list-filter-query-extractor.js +15 -0
  152. package/dist/server/operations/list-workflows.d.ts +6 -0
  153. package/dist/server/operations/list-workflows.js +12 -3
  154. package/dist/server/operations/operation-helpers.d.ts +9 -18
  155. package/dist/server/operations/operation-helpers.js +5 -23
  156. package/dist/server/operations/purge-workflows.d.ts +3 -0
  157. package/dist/server/operations/recover-all.js +2 -1
  158. package/dist/server/operations/single-workflow-tag-mutation.js +2 -2
  159. package/dist/server/operations/sse-stream.js +2 -7
  160. package/dist/server/operations/storage-capabilities.d.ts +34 -0
  161. package/dist/server/operations/storage-capabilities.js +38 -0
  162. package/dist/server/operations/storage.js +8 -17
  163. package/dist/server/operations/stream-workflow-sse.js +3 -9
  164. package/dist/server/operations/update-schedule.d.ts +8 -0
  165. package/dist/server/operations/update-schedule.js +70 -7
  166. package/dist/server/operations/workflow-events-sse.js +2 -2
  167. package/dist/server/rest-binding.d.ts +7 -6
  168. package/dist/server/rest-bindings.d.ts +2 -13
  169. package/dist/server/rest-bindings.js +19 -10
  170. package/dist/server/task-queue.d.ts +7 -5
  171. package/dist/storage/capabilities.d.ts +1 -1
  172. package/dist/storage/cloudflare-value-codec.d.ts +5 -3
  173. package/dist/storage/cloudflare-value-codec.js +1 -1
  174. package/dist/storage/compressed-storage.js +1 -1
  175. package/dist/storage/index.d.ts +7 -1
  176. package/dist/storage/interface.d.ts +16 -4
  177. package/dist/storage/interface.js +1 -1
  178. package/dist/storage/key-prefixes.d.ts +1 -1
  179. package/dist/storage/key-prefixes.js +4 -0
  180. package/dist/storage/lmdb.js +1 -1
  181. package/dist/storage/memory.js +1 -1
  182. package/dist/storage/neon.js +4 -4
  183. package/dist/storage/postgres.js +4 -4
  184. package/dist/storage/resolve.js +1 -1
  185. package/dist/storage/scoped-storage.js +1 -1
  186. package/dist/storage/testing.js +1 -1
  187. package/dist/storage/turso.js +2 -2
  188. package/dist/version.d.ts +1 -1
  189. package/dist/version.js +1 -1
  190. package/dist/web-extension.js +1 -1
  191. package/package.json +1 -1
@@ -94,19 +94,19 @@ export const DIRECT_ROUTE_EXECUTORS = {
94
94
  return jsonResponse(generateMcpDiscovery({ origin: originResolution.origin }));
95
95
  },
96
96
  openApiDocument: async ({ options }) => jsonResponse(generateOpenApiDocument({
97
- registry: options?.operationRegistry ?? defaultOperationRegistry(),
97
+ registry: options?.operationRegistry ?? defaultOperationRegistry(options),
98
98
  ...options?.restBindings !== void 0 ? { restBindings: options.restBindings } : {},
99
99
  ...options?.supportedAuthenticationSchemes !== void 0 ? { supportedSchemes: options.supportedAuthenticationSchemes } : {},
100
100
  ...options?.discoveryInfo !== void 0 ? { discoveryInfo: options.discoveryInfo } : {}
101
101
  })),
102
102
  openRpcDocument: async ({ engine, options }) => jsonResponse(generateOpenRpcDocument({
103
- registry: options?.operationRegistry ?? defaultOperationRegistry(),
103
+ registry: options?.operationRegistry ?? defaultOperationRegistry(options),
104
104
  transports: ["http", "websocket"],
105
105
  mcpTools: listMcpTools(engine),
106
106
  ...options?.discoveryInfo !== void 0 ? { discoveryInfo: options.discoveryInfo } : {}
107
107
  })),
108
108
  asyncApiDocument: async ({ options }) => jsonResponse(generateAsyncApiDocument({
109
- registry: options?.operationRegistry ?? defaultOperationRegistry(),
109
+ registry: options?.operationRegistry ?? defaultOperationRegistry(options),
110
110
  ...options?.restBindings !== void 0 ? { restBindings: options.restBindings } : {},
111
111
  ...options?.discoveryInfo !== void 0 ? { discoveryInfo: options.discoveryInfo } : {}
112
112
  }))
@@ -173,7 +173,22 @@ export function isOperationFaultLike(value) {
173
173
  return typeof fields.code === "string" && Object.hasOwn(FAULT_CODE_TO_HTTP_STATUS, fields.code) && typeof fields.message === "string" && typeof fields.data === "object" && fields.data !== null && !Array.isArray(fields.data);
174
174
  }
175
175
  let defaultOperationRegistryCache;
176
- export function defaultOperationRegistry() {
176
+ const missingWorkerRegistryCacheKey = {}, missingTaskQueueCacheKey = {}, liveOperationRegistryCache = new WeakMap;
177
+ export function defaultOperationRegistry(options) {
178
+ if (options?.workerRegistry !== void 0 || options?.taskQueue !== void 0) {
179
+ const workerRegistryCacheKey = options.workerRegistry ?? missingWorkerRegistryCacheKey, taskQueueCacheKey = options.taskQueue ?? missingTaskQueueCacheKey;
180
+ let registriesByTaskQueue = liveOperationRegistryCache.get(workerRegistryCacheKey);
181
+ if (registriesByTaskQueue === void 0) {
182
+ registriesByTaskQueue = new WeakMap;
183
+ liveOperationRegistryCache.set(workerRegistryCacheKey, registriesByTaskQueue);
184
+ }
185
+ let registry = registriesByTaskQueue.get(taskQueueCacheKey);
186
+ if (registry === void 0) {
187
+ registry = createLiveOperationRegistry(options);
188
+ registriesByTaskQueue.set(taskQueueCacheKey, registry);
189
+ }
190
+ return registry;
191
+ }
177
192
  if (defaultOperationRegistryCache === void 0)
178
193
  defaultOperationRegistryCache = createLiveOperationRegistry();
179
194
  return defaultOperationRegistryCache;
@@ -23,7 +23,7 @@ export { WorkerRegistry } from '../worker/registry.ts';
23
23
  export type { RoutingPolicy } from '../worker/registry.ts';
24
24
  export type { DiscoveryInfo } from './discovery-info.ts';
25
25
  export type { SchedulingPolicy } from './task-queue-types.ts';
26
- export type { TaskQueue } from './task-queue.ts';
26
+ export { TaskQueue } from './task-queue.ts';
27
27
  /**
28
28
  * Static route patterns at which an externally supplied dashboard shell is
29
29
  * served. Weft no longer bundles a dashboard, but `serve({ dashboard })`
@@ -33,6 +33,7 @@ export {
33
33
  validateRateLimitConfig
34
34
  } from "./authentication.js";
35
35
  export { WorkerRegistry } from "../worker/registry.js";
36
+ export { TaskQueue } from "./task-queue.js";
36
37
  export const DASHBOARD_PAGE_ROUTES = [
37
38
  "/",
38
39
  "/workflows",
@@ -1,6 +1,8 @@
1
1
  export const INTERACTIVE_OPERATION_NAMES = [
2
2
  "weft.workflows.start",
3
3
  "weft.workflows.get",
4
+ "weft.workflows.scheduleprovenance.get",
5
+ "weft.workflows.finalizer.get",
4
6
  "weft.workflows.list",
5
7
  "weft.workflows.signal",
6
8
  "weft.workflows.query",
@@ -2,11 +2,62 @@ import { UNIVERSAL_FAULT_DEFAULTS } from "./operation-catalog/raise-fault.js";
2
2
  import { FAULT_CODE_TO_HTTP_STATUS } from "./operation-fault.js";
3
3
  export const ERROR_SCHEMA = {
4
4
  type: "object",
5
- required: ["code", "message"],
5
+ required: ["error"],
6
+ additionalProperties: !1,
6
7
  properties: {
7
- code: { type: "string", description: "Machine-readable error code" },
8
- message: { type: "string", description: "Human-readable error description" },
9
- data: { description: "Additional fault-specific context" }
8
+ error: { type: "string", description: "Human-readable error description" },
9
+ weftCode: {
10
+ type: "string",
11
+ description: "Fine-grained public Weft error code when one is available"
12
+ },
13
+ missingTypes: {
14
+ type: "array",
15
+ items: { type: "string" },
16
+ description: "Established recovery-conflict field; also present under data"
17
+ },
18
+ missingWorkflowCount: {
19
+ type: "integer",
20
+ minimum: 0,
21
+ description: "Established recovery-conflict field; also present under data"
22
+ },
23
+ samplesTruncated: {
24
+ type: "boolean",
25
+ description: "Established recovery-conflict field; also present under data"
26
+ },
27
+ data: {
28
+ type: "object",
29
+ description: "Audited fault-specific context; omitted when no fields are safe to expose",
30
+ additionalProperties: !1,
31
+ properties: {
32
+ resource: { type: "string" },
33
+ identifier: { type: "string" },
34
+ missingTypes: { type: "array", items: { type: "string" } },
35
+ missingWorkflowCount: { type: "integer", minimum: 0 },
36
+ samplesTruncated: { type: "boolean" },
37
+ maxBytes: { type: "integer", minimum: 0 },
38
+ operationName: { type: "string" },
39
+ transport: { type: "string" },
40
+ supported: { type: "array", items: { type: "string" } },
41
+ droppedCount: { type: "integer", minimum: 0 },
42
+ issues: {
43
+ type: "array",
44
+ items: {
45
+ type: "object",
46
+ required: ["path", "message", "code"],
47
+ additionalProperties: !1,
48
+ properties: {
49
+ path: {
50
+ type: "array",
51
+ items: { oneOf: [{ type: "string" }, { type: "number" }] }
52
+ },
53
+ message: { type: "string" },
54
+ code: { type: "string" }
55
+ }
56
+ }
57
+ },
58
+ method: { type: "string" }
59
+ }
60
+ }
10
61
  }
11
62
  };
12
63
  export function buildErrorResponses(operation) {
@@ -4,7 +4,9 @@
4
4
  *
5
5
  * Produces a JSON-serializable OpenAPI document for the REST-ish HTTP
6
6
  * surface. Both `handleRequest()` and `serve()` expose this at
7
- * `GET /openapi.json`.
7
+ * `GET /openapi.json`. Every operation-catalog binding carries the canonical
8
+ * `x-weft-access` metadata and, when applicable,
9
+ * `x-weft-parameterizedAccess`; direct infrastructure routes do not.
8
10
  *
9
11
  * @module server/openapi
10
12
  */
@@ -1,5 +1,6 @@
1
1
  import { definitionSchemaToJsonSchema } from "../core/types/definition-schema-to-json.js";
2
2
  import { VERSION } from "../version.js";
3
+ import { serializeAccessPolicy, serializeParameterizedAccess } from "./access-policy-metadata.js";
3
4
  import { isDiscoverable } from "./discovery-filter.js";
4
5
  import { applyDiscoveryInfo } from "./discovery-info.js";
5
6
  import { asPlainObject, compareStrings } from "./json-schema-utilities.js";
@@ -184,11 +185,14 @@ function buildBindingEntry(binding, operation, schemaHelper) {
184
185
  summary: operation.summary,
185
186
  operationId: operation.name,
186
187
  tags: operation.tags,
188
+ "x-weft-access": serializeAccessPolicy(operation.access),
187
189
  responses: {
188
190
  ...successResponse,
189
191
  ...buildErrorResponses(operation)
190
192
  }
191
193
  };
194
+ if (operation.parameterizedAccess !== void 0)
195
+ entry["x-weft-parameterizedAccess"] = serializeParameterizedAccess(operation.parameterizedAccess);
192
196
  if (operation.description !== void 0)
193
197
  entry.description = operation.description;
194
198
  if (parameters.length > 0)
@@ -31,6 +31,38 @@ export declare const OpenRpcMethodSchema: z.ZodObject<{
31
31
  $ref: z.ZodString;
32
32
  }, z.core.$strict>>>;
33
33
  'x-weft-paramsSchema': z.ZodRecord<z.ZodString, z.ZodUnknown>;
34
+ 'x-weft-access': z.ZodDiscriminatedUnion<[z.ZodObject<{
35
+ kind: z.ZodLiteral<"public">;
36
+ }, z.core.$strict>, z.ZodObject<{
37
+ kind: z.ZodLiteral<"authenticated">;
38
+ }, z.core.$strict>, z.ZodObject<{
39
+ kind: z.ZodLiteral<"scoped">;
40
+ scopes: z.ZodObject<{
41
+ kind: z.ZodEnum<{
42
+ anyOf: "anyOf";
43
+ allOf: "allOf";
44
+ }>;
45
+ scopes: z.ZodArray<z.ZodString>;
46
+ }, z.core.$strict>;
47
+ }, z.core.$strict>, z.ZodObject<{
48
+ kind: z.ZodLiteral<"optionalAuth">;
49
+ authenticatedScopes: z.ZodObject<{
50
+ kind: z.ZodEnum<{
51
+ anyOf: "anyOf";
52
+ allOf: "allOf";
53
+ }>;
54
+ scopes: z.ZodArray<z.ZodString>;
55
+ }, z.core.$strict>;
56
+ }, z.core.$strict>, z.ZodObject<{
57
+ kind: z.ZodLiteral<"scopedAlternatives">;
58
+ alternatives: z.ZodArray<z.ZodObject<{
59
+ kind: z.ZodEnum<{
60
+ anyOf: "anyOf";
61
+ allOf: "allOf";
62
+ }>;
63
+ scopes: z.ZodArray<z.ZodString>;
64
+ }, z.core.$strict>>;
65
+ }, z.core.$strict>], "kind">;
34
66
  'x-weft-mcp': z.ZodOptional<z.ZodObject<{
35
67
  workflowType: z.ZodString;
36
68
  toolName: z.ZodString;
@@ -121,6 +153,38 @@ export declare const OpenRpcDocumentSchema: z.ZodObject<{
121
153
  $ref: z.ZodString;
122
154
  }, z.core.$strict>>>;
123
155
  'x-weft-paramsSchema': z.ZodRecord<z.ZodString, z.ZodUnknown>;
156
+ 'x-weft-access': z.ZodDiscriminatedUnion<[z.ZodObject<{
157
+ kind: z.ZodLiteral<"public">;
158
+ }, z.core.$strict>, z.ZodObject<{
159
+ kind: z.ZodLiteral<"authenticated">;
160
+ }, z.core.$strict>, z.ZodObject<{
161
+ kind: z.ZodLiteral<"scoped">;
162
+ scopes: z.ZodObject<{
163
+ kind: z.ZodEnum<{
164
+ anyOf: "anyOf";
165
+ allOf: "allOf";
166
+ }>;
167
+ scopes: z.ZodArray<z.ZodString>;
168
+ }, z.core.$strict>;
169
+ }, z.core.$strict>, z.ZodObject<{
170
+ kind: z.ZodLiteral<"optionalAuth">;
171
+ authenticatedScopes: z.ZodObject<{
172
+ kind: z.ZodEnum<{
173
+ anyOf: "anyOf";
174
+ allOf: "allOf";
175
+ }>;
176
+ scopes: z.ZodArray<z.ZodString>;
177
+ }, z.core.$strict>;
178
+ }, z.core.$strict>, z.ZodObject<{
179
+ kind: z.ZodLiteral<"scopedAlternatives">;
180
+ alternatives: z.ZodArray<z.ZodObject<{
181
+ kind: z.ZodEnum<{
182
+ anyOf: "anyOf";
183
+ allOf: "allOf";
184
+ }>;
185
+ scopes: z.ZodArray<z.ZodString>;
186
+ }, z.core.$strict>>;
187
+ }, z.core.$strict>], "kind">;
124
188
  'x-weft-mcp': z.ZodOptional<z.ZodObject<{
125
189
  workflowType: z.ZodString;
126
190
  toolName: z.ZodString;
@@ -1,4 +1,8 @@
1
1
  import { z } from "zod";
2
+ import {
3
+ AccessPolicyMetadataSchema,
4
+ ParameterizedAccessMetadataSchema
5
+ } from "./access-policy-metadata.js";
2
6
  import { MCP_DISCOVERY_PATH, MCP_TOOLS_LIST_METHOD } from "./mcp-discovery.js";
3
7
  export const ContentDescriptorSchema = z.strictObject({
4
8
  name: z.string(),
@@ -12,31 +16,6 @@ const OpenRpcMcpMethodMetadataSchema = z.strictObject({
12
16
  method: z.literal(MCP_TOOLS_LIST_METHOD),
13
17
  source: z.literal("live")
14
18
  })
15
- }), OpenRpcScopeRequirementSchema = z.strictObject({
16
- kind: z.enum(["anyOf", "allOf"]),
17
- scopes: z.array(z.string())
18
- }), OpenRpcAccessPolicySchema = z.discriminatedUnion("kind", [
19
- z.strictObject({ kind: z.literal("public") }),
20
- z.strictObject({ kind: z.literal("authenticated") }),
21
- z.strictObject({
22
- kind: z.literal("scoped"),
23
- scopes: OpenRpcScopeRequirementSchema
24
- }),
25
- z.strictObject({
26
- kind: z.literal("optionalAuth"),
27
- authenticatedScopes: OpenRpcScopeRequirementSchema
28
- }),
29
- z.strictObject({
30
- kind: z.literal("scopedAlternatives"),
31
- alternatives: z.array(OpenRpcScopeRequirementSchema)
32
- })
33
- ]), OpenRpcParameterizedAccessSchema = z.strictObject({
34
- discriminator: z.string(),
35
- defaultValue: z.string().optional(),
36
- variants: z.array(z.strictObject({
37
- value: z.string(),
38
- access: OpenRpcAccessPolicySchema
39
- }))
40
19
  });
41
20
  export const OpenRpcMethodSchema = z.strictObject({
42
21
  name: z.string(),
@@ -48,8 +27,9 @@ export const OpenRpcMethodSchema = z.strictObject({
48
27
  result: ContentDescriptorSchema,
49
28
  errors: z.array(z.strictObject({ $ref: z.string() })).optional(),
50
29
  "x-weft-paramsSchema": z.record(z.string(), z.unknown()),
30
+ "x-weft-access": AccessPolicyMetadataSchema,
51
31
  "x-weft-mcp": OpenRpcMcpMethodMetadataSchema.optional(),
52
- "x-weft-parameterizedAccess": OpenRpcParameterizedAccessSchema.optional()
32
+ "x-weft-parameterizedAccess": ParameterizedAccessMetadataSchema.optional()
53
33
  });
54
34
  const OpenRpcMcpMetadataSchema = z.strictObject({
55
35
  discoveryPath: z.literal(MCP_DISCOVERY_PATH),
@@ -16,6 +16,10 @@
16
16
  * authoritative top-level object schema used by runtime enforcement
17
17
  * and generator tooling; the per-field descriptors cannot drift
18
18
  * from it by the "names match" invariant enforced in tests.
19
+ * - Every operation-catalog method carries the canonical `x-weft-access`
20
+ * metadata and, when applicable, `x-weft-parameterizedAccess`. The
21
+ * synthetic `rpc.discover` method is not an operation-catalog entry,
22
+ * but advertises its dispatcher-enforced public access posture explicitly.
19
23
  * - `rpc.discover` is itself emitted as a method so clients can
20
24
  * locate the document via JSON-RPC.
21
25
  *
@@ -1,6 +1,10 @@
1
1
  import { z } from "zod";
2
2
  import { definitionSchemaToJsonSchema } from "../core/types/definition-schema-to-json.js";
3
3
  import { VERSION } from "../version.js";
4
+ import {
5
+ serializeAccessPolicy,
6
+ serializeParameterizedAccess
7
+ } from "./access-policy-metadata.js";
4
8
  import { isDiscoverable } from "./discovery-filter.js";
5
9
  import { applyDiscoveryInfo } from "./discovery-info.js";
6
10
  import { asPlainObject, compareStrings } from "./json-schema-utilities.js";
@@ -109,7 +113,8 @@ function buildMethod(operation) {
109
113
  paramStructure: "by-name",
110
114
  params: descriptors,
111
115
  result: { name: "result", schema: resultSchema, required: !0 },
112
- "x-weft-paramsSchema": paramsSchema
116
+ "x-weft-paramsSchema": paramsSchema,
117
+ "x-weft-access": serializeAccessPolicy(operation.access)
113
118
  };
114
119
  if (operation.summary)
115
120
  method.summary = operation.summary;
@@ -118,40 +123,10 @@ function buildMethod(operation) {
118
123
  if (operation.tags.length > 0)
119
124
  method.tags = [...operation.tags].toSorted(compareStrings).map((name) => ({ name }));
120
125
  if (operation.parameterizedAccess !== void 0)
121
- method["x-weft-parameterizedAccess"] = {
122
- discriminator: operation.parameterizedAccess.discriminator,
123
- ...operation.parameterizedAccess.defaultValue === void 0 ? {} : { defaultValue: operation.parameterizedAccess.defaultValue },
124
- variants: operation.parameterizedAccess.variants.map((variant) => ({
125
- value: variant.value,
126
- access: accessPolicyExtension(variant.access)
127
- }))
128
- };
126
+ method["x-weft-parameterizedAccess"] = serializeParameterizedAccess(operation.parameterizedAccess);
129
127
  method.errors = buildMethodErrorReferences(operation);
130
128
  return method;
131
129
  }
132
- function accessPolicyExtension(access) {
133
- if (access.kind === "public")
134
- return { kind: "public" };
135
- if (access.kind === "authenticated")
136
- return { kind: "authenticated" };
137
- if (access.kind === "scoped")
138
- return { kind: "scoped", scopes: scopeRequirementExtension(access.scopes) };
139
- if (access.kind === "optionalAuth")
140
- return {
141
- kind: "optionalAuth",
142
- authenticatedScopes: scopeRequirementExtension(access.authenticatedScopes)
143
- };
144
- return {
145
- kind: "scopedAlternatives",
146
- alternatives: access.alternatives.map(scopeRequirementExtension)
147
- };
148
- }
149
- function scopeRequirementExtension(requirement) {
150
- return {
151
- kind: requirement.kind,
152
- scopes: [...requirement.scopes].toSorted(compareStrings)
153
- };
154
- }
155
130
  function buildDiscoverMethod() {
156
131
  return {
157
132
  name: "rpc.discover",
@@ -169,7 +144,8 @@ function buildDiscoverMethod() {
169
144
  properties: {},
170
145
  required: [],
171
146
  additionalProperties: !1
172
- }
147
+ },
148
+ "x-weft-access": { kind: "public" }
173
149
  };
174
150
  }
175
151
  const UNIVERSAL_FAULT_CODES = [...UNIVERSAL_FAULT_DEFAULTS];
@@ -35,7 +35,7 @@
35
35
  * serialized consistently across REST and JSON-RPC transports.
36
36
  */
37
37
  import type { FaultCode } from '../core/fault-code.ts';
38
- import type { WeftErrorCode } from '../core/weft-error.ts';
38
+ import { type WeftErrorCode } from '../core/weft-error.ts';
39
39
  export type { FaultCode };
40
40
  /** Transport identifiers as seen by `executeOperation`. */
41
41
  export type TransportKind = 'http-rest' | 'jsonRpcHttp' | 'jsonRpcWebSocket' | 'jsonRpcStdio';
@@ -149,14 +149,31 @@ export declare const FAULT_CODE_TO_HTTP_STATUS: Readonly<Record<FaultCode, numbe
149
149
  export declare function formatInvalidParamsMessage(fault: Extract<OperationFault, {
150
150
  code: 'InvalidParams';
151
151
  }>): string;
152
+ export type RestFaultResponseOptions = {
153
+ /** REST-only status override for a binding with an established non-canonical status. */
154
+ readonly status?: number;
155
+ /** REST-only public message override for a binding with an established response message. */
156
+ readonly message?: string;
157
+ };
158
+ export type RestFaultBody = {
159
+ readonly error: string;
160
+ readonly weftCode?: WeftErrorCode;
161
+ readonly data?: Readonly<Record<string, unknown>>;
162
+ };
152
163
  /**
153
- * Map an `OperationFault` to a JSON `Response` with an `{ error }` body.
154
- * Treats `InvalidParams` as 400 with a flattened issues message, masks
155
- * `EngineFailure` as `Internal server error` at 500, and uses
156
- * {@link FAULT_CODE_TO_HTTP_STATUS} for every other code. Used by REST
157
- * bindings that serve a single resource and want a uniform error shape.
164
+ * Map an `OperationFault` to the canonical additive REST body:
165
+ * `{ error, weftCode?, data? }`. The existing string `error` and optional
166
+ * fine-grained `weftCode` remain unchanged; `data` contains only fields from
167
+ * the audited allowlist above. JSON-RPC uses its own broader projection.
168
+ *
169
+ * `EngineFailure` is a hard exception: its exact body remains
170
+ * `{ "error": "Internal server error" }`, regardless of response overrides.
158
171
  */
159
- export declare function shapeOperationFaultAsJson(fault: OperationFault): Response;
172
+ export declare function shapeOperationFaultAsJson(fault: OperationFault, options?: RestFaultResponseOptions): Response;
173
+ /** Canonical flat REST response used by bindings and route-dispatch fallback. */
174
+ export declare function shapeRestFaultAsJson(fault: OperationFault, options?: RestFaultResponseOptions): Response;
175
+ /** Build the audited body for bespoke REST shapers that retain extra legacy fields. */
176
+ export declare function shapeRestFaultBody(fault: OperationFault, message?: string): RestFaultBody;
160
177
  /**
161
178
  * JSON-RPC error code for each fault. Reserved codes (-32700..-32603) keep
162
179
  * the spec meanings (`InvalidParams`, `MethodNotFound`); Weft domain codes
@@ -1,3 +1,4 @@
1
+ import { isWeftErrorCode } from "../core/weft-error.js";
1
2
  export const FAULT_CODE_TO_HTTP_STATUS = Object.freeze({
2
3
  Unauthorized: 401,
3
4
  Forbidden: 403,
@@ -19,22 +20,73 @@ export function formatInvalidParamsMessage(fault) {
19
20
  return path.length > 0 ? `${path}: ${issue.message}` : issue.message;
20
21
  }).join("; ");
21
22
  }
22
- export function shapeOperationFaultAsJson(fault) {
23
- if (fault.code === "InvalidParams")
24
- return new Response(JSON.stringify({ error: formatInvalidParamsMessage(fault) }), {
25
- status: 400,
26
- headers: { "Content-Type": "application/json" }
27
- });
28
- if (fault.code === "EngineFailure")
29
- return new Response(JSON.stringify({ error: "Internal server error" }), {
30
- status: 500,
31
- headers: { "Content-Type": "application/json" }
32
- });
33
- return new Response(JSON.stringify({ error: fault.message }), {
34
- status: FAULT_CODE_TO_HTTP_STATUS[fault.code],
23
+ const NO_REST_FAULT_DATA = Object.freeze({}), REST_FAULT_DATA_EXTRACTORS = {
24
+ Unauthorized: () => NO_REST_FAULT_DATA,
25
+ Forbidden: () => NO_REST_FAULT_DATA,
26
+ NotFound: (data) => filterDefined({
27
+ resource: data.resource,
28
+ identifier: data.identifier === void 0 || data.identifier.length === 0 ? void 0 : data.identifier
29
+ }),
30
+ Conflict: (data) => filterDefined({
31
+ missingTypes: data.missingTypes === void 0 ? void 0 : [...data.missingTypes],
32
+ missingWorkflowCount: data.missingWorkflowCount,
33
+ samplesTruncated: data.samplesTruncated
34
+ }),
35
+ Unprocessable: () => NO_REST_FAULT_DATA,
36
+ PayloadTooLarge: (data) => ({ maxBytes: data.maxBytes }),
37
+ Timeout: (data) => filterDefined({ operationName: data.operationName }),
38
+ NotImplemented: () => NO_REST_FAULT_DATA,
39
+ UnsupportedTransport: (data) => ({
40
+ transport: data.transport,
41
+ supported: [...data.supported]
42
+ }),
43
+ SubscriptionOverflow: (data) => ({ droppedCount: data.droppedCount }),
44
+ InvalidParams: (data) => data.issues.length === 0 ? NO_REST_FAULT_DATA : {
45
+ issues: data.issues.map((issue) => ({
46
+ path: [...issue.path],
47
+ message: issue.message,
48
+ code: issue.code
49
+ }))
50
+ },
51
+ MethodNotFound: (data) => ({ method: data.method })
52
+ };
53
+ export function shapeOperationFaultAsJson(fault, options = {}) {
54
+ const message = options.message ?? (fault.code === "InvalidParams" ? formatInvalidParamsMessage(fault) : void 0);
55
+ return shapeRestFaultAsJson(fault, { ...options, ...message === void 0 ? {} : { message } });
56
+ }
57
+ export function shapeRestFaultAsJson(fault, options = {}) {
58
+ const body = shapeRestFaultBody(fault, options.message), status = fault.code === "EngineFailure" ? 500 : options.status ?? FAULT_CODE_TO_HTTP_STATUS[fault.code];
59
+ return new Response(JSON.stringify(body), {
60
+ status,
35
61
  headers: { "Content-Type": "application/json" }
36
62
  });
37
63
  }
64
+ export function shapeRestFaultBody(fault, message) {
65
+ if (fault.code === "EngineFailure")
66
+ return { error: "Internal server error" };
67
+ const error = message ?? fault.message, weftCode = weftCodeFromFaultData(fault.data), data = restDataFromFault(fault), body = { error };
68
+ if (weftCode !== void 0)
69
+ body.weftCode = weftCode;
70
+ if (Object.keys(data).length > 0)
71
+ body.data = data;
72
+ return body;
73
+ }
74
+ function restDataFromFault(fault) {
75
+ const extractor = REST_FAULT_DATA_EXTRACTORS[fault.code];
76
+ return extractor(fault.data);
77
+ }
78
+ function weftCodeFromFaultData(data) {
79
+ if (typeof data !== "object" || data === null || !("weftCode" in data))
80
+ return;
81
+ return isWeftErrorCode(data.weftCode) ? data.weftCode : void 0;
82
+ }
83
+ function filterDefined(input) {
84
+ const output = {};
85
+ for (const [key, value] of Object.entries(input))
86
+ if (value !== void 0)
87
+ output[key] = value;
88
+ return output;
89
+ }
38
90
  export const FAULT_CODE_TO_JSON_RPC_CODE = Object.freeze({
39
91
  Unauthorized: -32010,
40
92
  Forbidden: -32011,
@@ -13,6 +13,9 @@ declare const aggregateWorkflowsInput: z.ZodObject<{
13
13
  gte: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
14
14
  lte: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
15
15
  }, z.core.$strip>>>;
16
+ scheduleId: z.ZodOptional<z.ZodString>;
17
+ parentWorkflowId: z.ZodOptional<z.ZodString>;
18
+ parentWorkflowExecutionToken: z.ZodOptional<z.ZodString>;
16
19
  idPrefix: z.ZodOptional<z.ZodString>;
17
20
  createdAt: z.ZodOptional<z.ZodObject<{
18
21
  gte: z.ZodOptional<z.ZodNumber>;
@@ -55,6 +58,9 @@ export declare const aggregateWorkflowsOperation: import("../operation-catalog.t
55
58
  gte?: unknown;
56
59
  lte?: unknown;
57
60
  }[] | undefined;
61
+ scheduleId?: string | undefined;
62
+ parentWorkflowId?: string | undefined;
63
+ parentWorkflowExecutionToken?: string | undefined;
58
64
  idPrefix?: string | undefined;
59
65
  createdAt?: {
60
66
  gte?: number | undefined;
@@ -14,7 +14,7 @@ import {
14
14
  } from "../../core/list-filter-validation.js";
15
15
  import { defineOperation } from "../operation-registry.js";
16
16
  import { extractListFilterFromQuery } from "./list-filter-query-extractor.js";
17
- import { jsonErrorResponse, shapeRestFault } from "./operation-helpers.js";
17
+ import { shapeRestFault } from "./operation-helpers.js";
18
18
  const aggregateWorkflowsInput = listFilterObjectSchema.omit({ limit: !0, offset: !0 }).extend(aggregateOptionsObjectSchema.shape), aggregateWorkflowsOutput = z.object({
19
19
  total: z.number().int().min(0),
20
20
  groups: z.array(z.object({
@@ -87,7 +87,7 @@ function shapeAggregateWorkflowsSuccess(result) {
87
87
  }
88
88
  function shapeAggregateWorkflowsFault(fault) {
89
89
  if (fault.code === "Unprocessable")
90
- return jsonErrorResponse(fault.message, 400);
90
+ return shapeRestFault(fault, { status: 400 });
91
91
  return shapeRestFault(fault);
92
92
  }
93
93
  export const aggregateWorkflowsRestBinding = {
@@ -98,6 +98,7 @@ export const aggregateWorkflowsRestBinding = {
98
98
  inputSources: {
99
99
  status: { kind: "query", queryParam: "status", repeating: !0 },
100
100
  type: { kind: "query", queryParam: "type" },
101
+ scheduleId: { kind: "query", queryParam: "schedule_id" },
101
102
  tags: { kind: "query", queryParam: "tag", repeating: !0 },
102
103
  idPrefix: { kind: "query", queryParam: "id_prefix" },
103
104
  limit: { kind: "query", queryParam: "limit" },
@@ -1,9 +1,15 @@
1
1
  import { z } from 'zod';
2
+ import type { PendingAsyncActivityPage } from '../../core/types.ts';
2
3
  import type { UnknownRestBinding } from '../rest-bindings.ts';
3
4
  declare const completeAsyncActivityInput: z.ZodObject<{
4
5
  token: z.ZodString;
5
6
  result: z.ZodOptional<z.ZodUnknown>;
6
7
  }, z.core.$strip>;
8
+ declare const listPendingAsyncActivitiesInput: z.ZodObject<{
9
+ workflowId: z.ZodString;
10
+ limit: z.ZodDefault<z.ZodNumber>;
11
+ cursor: z.ZodOptional<z.ZodString>;
12
+ }, z.core.$strip>;
7
13
  /**
8
14
  * The failure payload is a *serializable* error description, not a live `Error`.
9
15
  * The engine already reduces an async-activity failure to `message` + `name`
@@ -24,6 +30,13 @@ declare const okOutput: z.ZodObject<{
24
30
  export type CompleteAsyncActivityInput = z.infer<typeof completeAsyncActivityInput>;
25
31
  export type FailAsyncActivityInput = z.infer<typeof failAsyncActivityInput>;
26
32
  export type AsyncActivityOutput = z.infer<typeof okOutput>;
33
+ export type ListPendingAsyncActivitiesInput = z.infer<typeof listPendingAsyncActivitiesInput>;
34
+ export type ListPendingAsyncActivitiesOutput = PendingAsyncActivityPage;
35
+ export declare const listPendingAsyncActivitiesOperation: import("../operation-catalog.ts").OperationDefinition<{
36
+ workflowId: string;
37
+ limit: number;
38
+ cursor?: string | undefined;
39
+ }, PendingAsyncActivityPage, unknown>;
27
40
  export declare const completeAsyncActivityOperation: import("../operation-catalog.ts").OperationDefinition<{
28
41
  token: string;
29
42
  result?: unknown;
@@ -39,6 +52,7 @@ export declare const failAsyncActivityOperation: import("../operation-catalog.ts
39
52
  }, {
40
53
  ok: true;
41
54
  }, unknown>;
55
+ export declare const listPendingAsyncActivitiesRestBinding: UnknownRestBinding;
42
56
  export declare const completeAsyncActivityRestBinding: UnknownRestBinding;
43
57
  export declare const failAsyncActivityRestBinding: UnknownRestBinding;
44
58
  export {};