@lostgradient/weft 0.14.0 → 0.16.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 (107) hide show
  1. package/README.md +3 -8
  2. package/dist/alerting/alert-manager.d.ts +2 -0
  3. package/dist/alerting/alert-manager.js +3 -0
  4. package/dist/cli/api.js +5 -19
  5. package/dist/cli/console.d.ts +12 -0
  6. package/dist/cli/console.js +62 -0
  7. package/dist/cli/generated/operation-catalog.snapshot.json +1061 -90
  8. package/dist/cli/generated/operation-client.generated.d.ts +29 -23
  9. package/dist/cli/generated/operation-client.generated.js +2 -0
  10. package/dist/cli/help-text.d.ts +1 -1
  11. package/dist/cli/help-text.js +1 -0
  12. package/dist/cli/index.d.ts +1 -0
  13. package/dist/cli/index.js +1 -0
  14. package/dist/cli/json-input.d.ts +20 -0
  15. package/dist/cli/json-input.js +33 -0
  16. package/dist/cli/parse-arguments.js +2 -0
  17. package/dist/cli/schedule.js +7 -9
  18. package/dist/cli/types.d.ts +1 -0
  19. package/dist/cli/workflow-commands.js +5 -25
  20. package/dist/cli-main.js +4 -2
  21. package/dist/core/aggregate-validation.d.ts +2 -5
  22. package/dist/core/aggregate-validation.js +2 -10
  23. package/dist/core/atomic-state.js +21 -24
  24. package/dist/core/engine/index.d.ts +3 -0
  25. package/dist/core/engine/index.js +3 -0
  26. package/dist/core/engine/schedules.js +4 -1
  27. package/dist/core/inline-execution-strategy.js +8 -46
  28. package/dist/core/list-filter-validation.d.ts +2 -5
  29. package/dist/core/list-filter-validation.js +2 -10
  30. package/dist/core/types/schedules.d.ts +13 -31
  31. package/dist/core/validation-issues.d.ts +13 -0
  32. package/dist/core/validation-issues.js +9 -0
  33. package/dist/diagnostics/recommendations.js +1 -9
  34. package/dist/http.js +2 -2
  35. package/dist/indexeddb.js +1 -1
  36. package/dist/mcp/session.js +2 -10
  37. package/dist/mcp/tools.js +2 -10
  38. package/dist/mcp/tuple-list-equality.d.ts +1 -0
  39. package/dist/mcp/tuple-list-equality.js +12 -0
  40. package/dist/server/authorization-scope.d.ts +1 -1
  41. package/dist/server/authorization-scope.js +0 -2
  42. package/dist/server/dashboard-assets.d.ts +26 -0
  43. package/dist/server/dashboard-assets.js +95 -0
  44. package/dist/server/index.d.ts +10 -1
  45. package/dist/server/index.js +11 -2
  46. package/dist/server/interactive-operations.js +1 -0
  47. package/dist/server/operation-catalog/types.d.ts +1 -1
  48. package/dist/server/operation-registry.d.ts +2 -31
  49. package/dist/server/operations/bulk-filter-helpers.d.ts +17 -17
  50. package/dist/server/operations/bulk-filter-helpers.js +16 -37
  51. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +27 -27
  52. package/dist/server/operations/bulk-signal-workflows.d.ts +26 -26
  53. package/dist/server/operations/create-schedule.js +26 -65
  54. package/dist/server/operations/event-stream-contracts.d.ts +20 -0
  55. package/dist/server/operations/event-stream-contracts.js +67 -0
  56. package/dist/server/operations/fleet-events-sse.js +21 -50
  57. package/dist/server/operations/fleet-events-subscription.js +8 -12
  58. package/dist/server/operations/list-alerts.d.ts +26 -0
  59. package/dist/server/operations/list-alerts.js +54 -0
  60. package/dist/server/operations/list-workflows.d.ts +43 -43
  61. package/dist/server/operations/list-workflows.js +9 -30
  62. package/dist/server/operations/purge-workflows.d.ts +11 -11
  63. package/dist/server/operations/schedule-faults.d.ts +9 -1
  64. package/dist/server/operations/schedule-faults.js +51 -0
  65. package/dist/server/operations/schedule-rest-body.d.ts +11 -0
  66. package/dist/server/operations/schedule-rest-body.js +28 -0
  67. package/dist/server/operations/update-schedule.js +13 -72
  68. package/dist/server/operations/workflow-events-sse.js +29 -67
  69. package/dist/server/operations/workflow-events-subscription.js +9 -27
  70. package/dist/server/rest-bindings.js +3 -0
  71. package/dist/server/runtime/task-polling.js +3 -5
  72. package/dist/server/task-state.d.ts +2 -8
  73. package/dist/server/task-state.js +10 -7
  74. package/dist/service-worker/index.d.ts +4 -1
  75. package/dist/service-worker/index.js +2 -2
  76. package/dist/service-worker/setup.d.ts +20 -0
  77. package/dist/service-worker/setup.js +5 -5
  78. package/dist/storage/bun-sql.js +65 -80
  79. package/dist/storage/conditional-batch-body.d.ts +7 -0
  80. package/dist/storage/conditional-batch-body.js +14 -0
  81. package/dist/storage/lmdb.js +1 -1
  82. package/dist/storage/memory.js +1 -1
  83. package/dist/storage/neon.js +2 -2
  84. package/dist/storage/node-sqlite-loader.d.ts +2 -2
  85. package/dist/storage/node-sqlite.js +32 -17
  86. package/dist/storage/postgres.js +2 -2
  87. package/dist/storage/resolve.js +1 -1
  88. package/dist/storage/scoped-storage.js +1 -1
  89. package/dist/storage/testing.js +1 -1
  90. package/dist/storage/turso.js +2 -2
  91. package/dist/version.d.ts +1 -1
  92. package/dist/version.js +1 -1
  93. package/dist/web-extension.js +1 -1
  94. package/dist/worker/execute-with-interceptors.d.ts +1 -1
  95. package/dist/worker/execute-with-interceptors.js +2 -2
  96. package/dist/worker/index.js +5 -5
  97. package/dist/worker/long-poll.js +3 -4
  98. package/dist/worker/protocol-messages.d.ts +11 -19
  99. package/dist/worker/protocol-schemas.d.ts +8 -8
  100. package/dist/worker/protocol-schemas.js +4 -4
  101. package/dist/worker/protocol-task-result.d.ts +1 -0
  102. package/dist/worker/protocol-task-result.js +1 -3
  103. package/dist/worker/protocol.js +1 -1
  104. package/dist/worker/registry/types.d.ts +2 -7
  105. package/dist/worker/registry.d.ts +3 -9
  106. package/dist/worker/registry.js +2 -5
  107. package/package.json +5 -1
@@ -4,6 +4,12 @@ import { EVENTS_READ_EVENT_TYPES } from "../runtime/client-visible-events.js";
4
4
  import {
5
5
  decodeCursor
6
6
  } from "../workflow-event-feed.js";
7
+ import {
8
+ createReplayAwareClosableIterable,
9
+ fleetEventEnvelopeSchema,
10
+ isClosableAsyncIterable,
11
+ isReplayAwareClosableIterable
12
+ } from "./event-stream-contracts.js";
7
13
  import { invalidParamsFault } from "./operation-helpers.js";
8
14
  import {
9
15
  createEventEnvelopeSSEStream,
@@ -19,14 +25,7 @@ const INITIAL_CURSOR = "-1", MAX_FLEET_SSE_REPLAY_EVENTS = 1000, cursorSchema =
19
25
  kind: fleetEventKindSchema.optional(),
20
26
  fromCursor: cursorSchema.optional(),
21
27
  lastEventId: cursorSchema.optional()
22
- }), fleetEventsSseOutputSchema = z.custom(isAsyncIterable, "Expected async iterable fleet event stream"), fleetEventEnvelopeSchema = z.object({
23
- kind: z.string(),
24
- workflowId: z.string().optional(),
25
- sequence: z.number(),
26
- cursor: z.string(),
27
- emittedAtMs: z.number(),
28
- payload: z.unknown()
29
- });
28
+ }), fleetEventsSseOutputSchema = z.custom(isAsyncIterable, "Expected async iterable fleet event stream");
30
29
  export const fleetEventsSseOperation = defineOperation({
31
30
  name: "weft.events.sse",
32
31
  mcpExposable: !1,
@@ -67,12 +66,6 @@ function isAsyncIterable(value) {
67
66
  return !1;
68
67
  return typeof value[Symbol.asyncIterator] === "function";
69
68
  }
70
- function isClosableFleetEventsIterable(value) {
71
- return "close" in value && typeof value.close === "function";
72
- }
73
- function isReplayAwareFleetEventsIterable(value) {
74
- return isClosableFleetEventsIterable(value) && "replayComplete" in value && value.replayComplete instanceof Promise;
75
- }
76
69
  function matchesFleetEventFilter(envelope, input) {
77
70
  if (input.workflowId !== void 0 && envelope.workflowId !== input.workflowId)
78
71
  return !1;
@@ -84,49 +77,27 @@ function createFleetEventsIterable(input, context) {
84
77
  const feed = context.fleetEventFeed;
85
78
  if (feed === void 0)
86
79
  throw unsupportedEventStreamContextFault("fleet event SSE requires a fleet event feed");
87
- const controller = new AbortController, replayComplete = Promise.withResolvers();
88
- let closed = !1;
89
- const close = async () => {
90
- if (closed)
91
- return;
92
- closed = !0;
93
- controller.abort();
94
- }, subscribeOptions = {
95
- fromCursor: input.lastEventId ?? input.fromCursor ?? INITIAL_CURSOR,
96
- signal: controller.signal,
97
- replayLimit: MAX_FLEET_SSE_REPLAY_EVENTS,
98
- filterEnvelope: (envelope) => matchesFleetEventFilter(envelope, input),
99
- onReplayComplete: () => replayComplete.resolve(),
100
- createReplayLimitError: (count, limit) => invalidParamsFault(`Fleet event replay window is ${count} matching events; maximum is ${limit}. Supply a more recent fromCursor.`)
101
- };
102
- let source;
103
- try {
104
- source = feed.subscribe(subscribeOptions);
105
- } catch (error) {
106
- close();
107
- throw error;
108
- }
109
- return {
110
- async* [Symbol.asyncIterator]() {
111
- try {
112
- for await (const envelope of source)
113
- yield envelope;
114
- } finally {
115
- await close();
116
- }
117
- },
118
- replayComplete: replayComplete.promise,
119
- close
120
- };
80
+ const controller = new AbortController, fromCursor = input.lastEventId ?? input.fromCursor ?? INITIAL_CURSOR;
81
+ return createReplayAwareClosableIterable((onReplayComplete) => {
82
+ const subscribeOptions = {
83
+ fromCursor,
84
+ signal: controller.signal,
85
+ replayLimit: MAX_FLEET_SSE_REPLAY_EVENTS,
86
+ filterEnvelope: (envelope) => matchesFleetEventFilter(envelope, input),
87
+ onReplayComplete,
88
+ createReplayLimitError: (count, limit) => invalidParamsFault(`Fleet event replay window is ${count} matching events; maximum is ${limit}. Supply a more recent fromCursor.`)
89
+ };
90
+ return feed.subscribe(subscribeOptions);
91
+ }, { close: () => controller.abort() });
121
92
  }
122
93
  function shapeFleetEventsSseSuccess(output, request) {
123
- const close = isClosableFleetEventsIterable(output) ? () => output.close() : async () => {
94
+ const close = isClosableAsyncIterable(output) ? () => output.close() : async () => {
124
95
  return;
125
96
  };
126
97
  return new Response(createEventEnvelopeSSEStream({
127
98
  iterable: output,
128
99
  close,
129
- ...isReplayAwareFleetEventsIterable(output) ? { ready: output.replayComplete } : {},
100
+ ...isReplayAwareClosableIterable(output) ? { ready: output.replayComplete } : {},
130
101
  signal: request.signal
131
102
  }), {
132
103
  status: 200,
@@ -3,6 +3,10 @@ import { raiseFault } from "../operation-catalog/raise-fault.js";
3
3
  import { defineOperation } from "../operation-registry.js";
4
4
  import { EVENTS_READ_EVENT_TYPES } from "../runtime/client-visible-events.js";
5
5
  import { decodeCursor } from "../workflow-event-feed.js";
6
+ import {
7
+ createReplayAwareClosableIterable,
8
+ fleetEventEnvelopeSchema
9
+ } from "./event-stream-contracts.js";
6
10
  import { invalidParamsFault } from "./operation-helpers.js";
7
11
  const INITIAL_SUBSCRIPTION_CURSOR = "-1", MAX_FLEET_SUBSCRIPTION_REPLAY_EVENTS = 1000, fleetEventKindSchema = z.enum(EVENTS_READ_EVENT_TYPES), fleetCursorSchema = z.string().regex(/^(?:-1|\d+)$/, "Invalid cursor").refine((cursor) => decodeCursor(cursor) !== null, {
8
12
  message: "Invalid cursor"
@@ -13,13 +17,6 @@ const INITIAL_SUBSCRIPTION_CURSOR = "-1", MAX_FLEET_SUBSCRIPTION_REPLAY_EVENTS =
13
17
  }), fleetEventsSubscriptionEnvelope = z.object({
14
18
  subscriptionId: z.string(),
15
19
  cursor: z.string()
16
- }), fleetEventEnvelopeSchema = z.object({
17
- kind: z.string(),
18
- workflowId: z.string().optional(),
19
- sequence: z.number(),
20
- cursor: z.string(),
21
- emittedAtMs: z.number(),
22
- payload: z.unknown()
23
20
  });
24
21
  export const fleetEventsSubscriptionOperation = defineOperation({
25
22
  name: "weft.events.subscribe",
@@ -44,19 +41,18 @@ export const fleetEventsSubscriptionOperation = defineOperation({
44
41
  const startingCursor = input.fromCursor ?? INITIAL_SUBSCRIPTION_CURSOR;
45
42
  if (decodeCursor(startingCursor) === null)
46
43
  raiseFault(fleetEventsSubscriptionOperation, invalidParamsFault("Invalid cursor"));
47
- const fleetFeed = getFleetEventFeed(engine, transport), controller = new AbortController, iterable = fleetFeed.subscribe({
44
+ const fleetFeed = getFleetEventFeed(engine, transport), controller = new AbortController, iterable = createReplayAwareClosableIterable((onReplayComplete) => fleetFeed.subscribe({
48
45
  ...input.fromCursor === void 0 ? {} : { fromCursor: input.fromCursor },
49
46
  signal: controller.signal,
50
47
  replayLimit: MAX_FLEET_SUBSCRIPTION_REPLAY_EVENTS,
51
48
  filterEnvelope: (envelope) => matchesFleetEventFilter(envelope, input),
49
+ onReplayComplete,
52
50
  createReplayLimitError: (count, limit) => fleetReplayLimitFault(count, limit)
53
- });
51
+ }), { close: () => controller.abort() });
54
52
  return {
55
53
  envelope: { subscriptionId: `sub_${crypto.randomUUID()}`, cursor: startingCursor },
56
54
  iterable,
57
- close: async () => {
58
- controller.abort();
59
- }
55
+ close: () => iterable.close()
60
56
  };
61
57
  }
62
58
  });
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `weft.alerts.list` operation + REST binding.
3
+ *
4
+ * Reports the alert rules that are currently firing. The response deliberately
5
+ * omits rule actions and webhook destinations: this is an operator diagnostic
6
+ * surface, not a configuration export.
7
+ */
8
+ import { z } from 'zod';
9
+ import type { AlertMetric } from '../../alerting/types.ts';
10
+ import type { UnknownRestBinding } from '../rest-bindings.ts';
11
+ declare const listAlertsInput: z.ZodObject<{}, z.core.$strip>;
12
+ declare const activeAlertSchema: z.ZodObject<{
13
+ metric: z.ZodType<AlertMetric, unknown, z.core.$ZodTypeInternals<AlertMetric, unknown>>;
14
+ threshold: z.ZodNumber;
15
+ currentValue: z.ZodNumber;
16
+ window: z.ZodNullable<z.ZodString>;
17
+ firedAt: z.ZodNullable<z.ZodNumber>;
18
+ }, z.core.$strip>;
19
+ export type ListAlertsInput = z.infer<typeof listAlertsInput>;
20
+ export type ActiveAlert = z.infer<typeof activeAlertSchema>;
21
+ export type ListAlertsOutput = {
22
+ items: ActiveAlert[];
23
+ };
24
+ export declare const listAlertsOperation: import("../operation-catalog.ts").OperationDefinition<Record<string, never>, ListAlertsOutput, unknown>;
25
+ export declare const listAlertsRestBinding: UnknownRestBinding;
26
+ export {};
@@ -0,0 +1,54 @@
1
+ import { z } from "zod";
2
+ import { shapeOperationFaultAsJson } from "../operation-fault.js";
3
+ import { defineOperation } from "../operation-registry.js";
4
+ const alertMetricSchema = z.enum([
5
+ "workflow.failure_rate",
6
+ "activity.p99_duration",
7
+ "storage.size"
8
+ ]), listAlertsInput = z.object({}), activeAlertSchema = z.object({
9
+ metric: alertMetricSchema,
10
+ threshold: z.number(),
11
+ currentValue: z.number(),
12
+ window: z.string().nullable(),
13
+ firedAt: z.number().nullable()
14
+ }), listAlertsOutput = z.object({
15
+ items: z.array(activeAlertSchema)
16
+ });
17
+ export const listAlertsOperation = defineOperation({
18
+ name: "weft.alerts.list",
19
+ mcpExposable: !1,
20
+ summary: "List currently firing alerts",
21
+ description: "List the alert rules that are currently firing, including their metric, threshold, current value, configured window, and firing timestamp. Read-only and limited to active in-memory alert state; resolved alerts are not returned.",
22
+ destructive: !1,
23
+ tags: ["Observability"],
24
+ inputSchema: listAlertsInput,
25
+ outputSchema: listAlertsOutput,
26
+ access: { kind: "scoped", scopes: { kind: "anyOf", scopes: ["system:read"] } },
27
+ discoverable: !0,
28
+ transports: { http: !0, jsonRpcHttp: !0, jsonRpcWebSocket: !0, jsonRpcStdio: !0 },
29
+ unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
30
+ invoke: async ({ engine }) => {
31
+ return {
32
+ items: engine.getActiveAlerts().map((state) => ({
33
+ metric: state.rule.metric,
34
+ threshold: state.rule.threshold,
35
+ currentValue: state.currentValue,
36
+ window: state.rule.window ?? null,
37
+ firedAt: state.lastFiredAt ?? null
38
+ }))
39
+ };
40
+ }
41
+ }), listAlertsRestBinding = {
42
+ method: "GET",
43
+ path: "/v1/alerts",
44
+ pathParamNames: [],
45
+ operationName: "weft.alerts.list",
46
+ inputSources: {},
47
+ extractInput: async () => ({}),
48
+ success: { kind: "json", status: 200 },
49
+ shapeSuccess: (output) => new Response(JSON.stringify(output), {
50
+ status: 200,
51
+ headers: { "Content-Type": "application/json" }
52
+ }),
53
+ shapeFault: shapeOperationFaultAsJson
54
+ };
@@ -1,85 +1,85 @@
1
1
  import { z } from 'zod';
2
- import type { FailureCategory, PaginatedResult, SearchAttributeValue, WorkflowStatus, WorkflowSummary } from '../../core/types.ts';
2
+ import type { PaginatedResult, WorkflowSummary } from '../../core/types.ts';
3
3
  import type { UnknownRestBinding } from '../rest-bindings.ts';
4
4
  declare const listWorkflowsInput: z.ZodObject<{
5
- status: z.ZodOptional<z.ZodUnion<readonly [z.ZodCustom<WorkflowStatus, WorkflowStatus>, z.ZodArray<z.ZodCustom<WorkflowStatus, WorkflowStatus>>]>>;
5
+ status: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
6
6
  type: z.ZodOptional<z.ZodString>;
7
- scheduleId: z.ZodOptional<z.ZodString>;
8
- parentWorkflowId: z.ZodOptional<z.ZodString>;
9
- parentWorkflowExecutionToken: z.ZodOptional<z.ZodString>;
10
- tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
11
- attributes: z.ZodOptional<z.ZodArray<z.ZodObject<{
12
- key: z.ZodString;
13
- value: z.ZodOptional<z.ZodCustom<SearchAttributeValue, SearchAttributeValue>>;
14
- gt: z.ZodOptional<z.ZodCustom<SearchAttributeValue, SearchAttributeValue>>;
15
- lt: z.ZodOptional<z.ZodCustom<SearchAttributeValue, SearchAttributeValue>>;
16
- gte: z.ZodOptional<z.ZodCustom<SearchAttributeValue, SearchAttributeValue>>;
17
- lte: z.ZodOptional<z.ZodCustom<SearchAttributeValue, SearchAttributeValue>>;
18
- }, z.core.$strip>>>;
19
- limit: z.ZodOptional<z.ZodNumber>;
20
- offset: z.ZodOptional<z.ZodNumber>;
21
7
  idPrefix: z.ZodOptional<z.ZodString>;
22
8
  createdAt: z.ZodOptional<z.ZodObject<{
23
9
  gte: z.ZodOptional<z.ZodNumber>;
24
- gt: z.ZodOptional<z.ZodNumber>;
25
10
  lte: z.ZodOptional<z.ZodNumber>;
11
+ gt: z.ZodOptional<z.ZodNumber>;
26
12
  lt: z.ZodOptional<z.ZodNumber>;
27
- }, z.core.$strip>>;
13
+ }, z.core.$strict>>;
28
14
  updatedAt: z.ZodOptional<z.ZodObject<{
29
15
  gte: z.ZodOptional<z.ZodNumber>;
30
- gt: z.ZodOptional<z.ZodNumber>;
31
16
  lte: z.ZodOptional<z.ZodNumber>;
17
+ gt: z.ZodOptional<z.ZodNumber>;
32
18
  lt: z.ZodOptional<z.ZodNumber>;
33
- }, z.core.$strip>>;
19
+ }, z.core.$strict>>;
34
20
  executionDeadline: z.ZodOptional<z.ZodObject<{
35
21
  gte: z.ZodOptional<z.ZodNumber>;
36
- gt: z.ZodOptional<z.ZodNumber>;
37
22
  lte: z.ZodOptional<z.ZodNumber>;
23
+ gt: z.ZodOptional<z.ZodNumber>;
38
24
  lt: z.ZodOptional<z.ZodNumber>;
39
- }, z.core.$strip>>;
40
- failureCategory: z.ZodOptional<z.ZodUnion<readonly [z.ZodCustom<FailureCategory, FailureCategory>, z.ZodArray<z.ZodCustom<FailureCategory, FailureCategory>>]>>;
25
+ }, z.core.$strict>>;
26
+ failureCategory: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
41
27
  include: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
42
- }, z.core.$strip>;
28
+ scheduleId: z.ZodOptional<z.ZodString>;
29
+ parentWorkflowId: z.ZodOptional<z.ZodString>;
30
+ parentWorkflowExecutionToken: z.ZodOptional<z.ZodString>;
31
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
32
+ attributes: z.ZodOptional<z.ZodArray<z.ZodObject<{
33
+ key: z.ZodUnion<readonly [z.ZodString, z.ZodAny]>;
34
+ value: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
35
+ gt: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
36
+ lt: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
37
+ gte: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
38
+ lte: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
39
+ }, z.core.$strip>>>;
40
+ limit: z.ZodOptional<z.ZodNumber>;
41
+ offset: z.ZodOptional<z.ZodNumber>;
42
+ }, z.core.$strict>;
43
43
  export type ListWorkflowsInput = z.infer<typeof listWorkflowsInput>;
44
44
  export type ListWorkflowsOutput = PaginatedResult<WorkflowSummary>;
45
45
  export declare const listWorkflowsOperation: import("../operation-catalog.ts").OperationDefinition<{
46
- status?: WorkflowStatus | WorkflowStatus[] | undefined;
46
+ status?: string | string[] | undefined;
47
47
  type?: string | undefined;
48
- scheduleId?: string | undefined;
49
- parentWorkflowId?: string | undefined;
50
- parentWorkflowExecutionToken?: string | undefined;
51
- tags?: string[] | undefined;
52
- attributes?: {
53
- key: string;
54
- value?: SearchAttributeValue | undefined;
55
- gt?: SearchAttributeValue | undefined;
56
- lt?: SearchAttributeValue | undefined;
57
- gte?: SearchAttributeValue | undefined;
58
- lte?: SearchAttributeValue | undefined;
59
- }[] | undefined;
60
- limit?: number | undefined;
61
- offset?: number | undefined;
62
48
  idPrefix?: string | undefined;
63
49
  createdAt?: {
64
50
  gte?: number | undefined;
65
- gt?: number | undefined;
66
51
  lte?: number | undefined;
52
+ gt?: number | undefined;
67
53
  lt?: number | undefined;
68
54
  } | undefined;
69
55
  updatedAt?: {
70
56
  gte?: number | undefined;
71
- gt?: number | undefined;
72
57
  lte?: number | undefined;
58
+ gt?: number | undefined;
73
59
  lt?: number | undefined;
74
60
  } | undefined;
75
61
  executionDeadline?: {
76
62
  gte?: number | undefined;
77
- gt?: number | undefined;
78
63
  lte?: number | undefined;
64
+ gt?: number | undefined;
79
65
  lt?: number | undefined;
80
66
  } | undefined;
81
- failureCategory?: FailureCategory | FailureCategory[] | undefined;
67
+ failureCategory?: string | string[] | undefined;
82
68
  include?: string | string[] | undefined;
69
+ scheduleId?: string | undefined;
70
+ parentWorkflowId?: string | undefined;
71
+ parentWorkflowExecutionToken?: string | undefined;
72
+ tags?: string[] | undefined;
73
+ attributes?: {
74
+ key: any;
75
+ value?: unknown;
76
+ gt?: unknown;
77
+ lt?: unknown;
78
+ gte?: unknown;
79
+ lte?: unknown;
80
+ }[] | undefined;
81
+ limit?: number | undefined;
82
+ offset?: number | undefined;
83
83
  }, ListWorkflowsOutput, unknown>;
84
84
  export declare const listWorkflowsRestBinding: UnknownRestBinding;
85
85
  export {};
@@ -2,45 +2,24 @@ import { z } from "zod";
2
2
  import { WorkflowListScanCapExceededError } from "../../core/engine/workflow-indexes.js";
3
3
  import {
4
4
  ListFilterValidationError,
5
+ listFilterObjectSchema,
5
6
  normalizeListFilter
6
7
  } from "../../core/list-filter-validation.js";
7
8
  import { coerceStartWorkflowTags } from "../../core/start-workflow-validation.js";
8
9
  import { defineOperation } from "../operation-registry.js";
9
10
  import { extractListFilterFromQuery } from "./list-filter-query-extractor.js";
10
11
  import { shapeRestFault } from "./operation-helpers.js";
11
- const workflowStatusSchema = z.custom((value) => typeof value === "string"), failureCategorySchema = z.custom((value) => typeof value === "string"), searchAttributeValueSchema = z.custom((value) => {
12
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
13
- return !0;
14
- return Array.isArray(value) && value.every((entry) => typeof entry === "string");
15
- }), attributeFilterSchema = z.object({
16
- key: z.string().min(1),
17
- value: searchAttributeValueSchema.optional(),
18
- gt: searchAttributeValueSchema.optional(),
19
- lt: searchAttributeValueSchema.optional(),
20
- gte: searchAttributeValueSchema.optional(),
21
- lte: searchAttributeValueSchema.optional()
22
- }), timeRangeSchema = z.object({
23
- gte: z.number().optional(),
24
- gt: z.number().optional(),
25
- lte: z.number().optional(),
26
- lt: z.number().optional()
27
- }), listIncludeSchema = z.union([z.string(), z.array(z.string()).min(1)]).refine((value) => Array.isArray(value) ? value.every((entry) => entry === "failureCategory") : value === "failureCategory", { message: 'include must be "failureCategory"' }), listWorkflowsInput = z.object({
28
- status: z.union([workflowStatusSchema, z.array(workflowStatusSchema)]).optional(),
12
+ const listIncludeSchema = z.union([z.string(), z.array(z.string()).min(1)]).refine((value) => Array.isArray(value) ? value.every((entry) => entry === "failureCategory") : value === "failureCategory", { message: 'include must be "failureCategory"' }), listWorkflowsInput = z.object({
13
+ ...listFilterObjectSchema.shape,
14
+ status: z.union([z.string(), z.array(z.string())]).optional(),
29
15
  type: z.string().optional(),
30
- scheduleId: z.string().min(1).optional(),
31
- parentWorkflowId: z.string().min(1).optional(),
32
- parentWorkflowExecutionToken: z.string().min(1).optional(),
33
- tags: z.array(z.string()).optional(),
34
- attributes: z.array(attributeFilterSchema).optional(),
35
- limit: z.number().int().min(1).max(1000).optional(),
36
- offset: z.number().int().min(0).optional(),
37
16
  idPrefix: z.string().optional(),
38
- createdAt: timeRangeSchema.optional(),
39
- updatedAt: timeRangeSchema.optional(),
40
- executionDeadline: timeRangeSchema.optional(),
41
- failureCategory: z.union([failureCategorySchema, z.array(failureCategorySchema)]).optional(),
17
+ createdAt: z.object(listFilterObjectSchema.shape.createdAt.unwrap().shape).strict().optional(),
18
+ updatedAt: z.object(listFilterObjectSchema.shape.updatedAt.unwrap().shape).strict().optional(),
19
+ executionDeadline: z.object(listFilterObjectSchema.shape.executionDeadline.unwrap().shape).strict().optional(),
20
+ failureCategory: z.union([z.string(), z.array(z.string())]).optional(),
42
21
  include: listIncludeSchema.optional()
43
- }), listWorkflowsOutput = z.unknown();
22
+ }).strict(), listWorkflowsOutput = z.unknown();
44
23
  export const listWorkflowsOperation = defineOperation({
45
24
  name: "weft.workflows.list",
46
25
  mcpExposable: !1,
@@ -11,34 +11,34 @@ export declare const purgeWorkflowsOperation: import("../operation-catalog.ts").
11
11
  parentWorkflowExecutionToken?: string | undefined;
12
12
  tags?: string[] | undefined;
13
13
  attributes?: {
14
- key: string;
15
- value?: import("../../index.ts").SearchAttributeValue | undefined;
16
- gt?: import("../../core/types.ts").AttributeFilterScalarValue | undefined;
17
- lt?: import("../../core/types.ts").AttributeFilterScalarValue | undefined;
18
- gte?: import("../../core/types.ts").AttributeFilterScalarValue | undefined;
19
- lte?: import("../../core/types.ts").AttributeFilterScalarValue | undefined;
14
+ key: any;
15
+ value?: unknown;
16
+ gt?: unknown;
17
+ lt?: unknown;
18
+ gte?: unknown;
19
+ lte?: unknown;
20
20
  }[] | undefined;
21
- limit?: number | undefined;
22
21
  offset?: number | undefined;
23
22
  idPrefix?: string | undefined;
24
- failureCategory?: import("../../index.ts").FailureCategory | import("../../index.ts").FailureCategory[] | undefined;
25
23
  createdAt?: {
26
24
  gte?: number | undefined;
27
- gt?: number | undefined;
28
25
  lte?: number | undefined;
26
+ gt?: number | undefined;
29
27
  lt?: number | undefined;
30
28
  } | undefined;
31
29
  updatedAt?: {
32
30
  gte?: number | undefined;
33
- gt?: number | undefined;
34
31
  lte?: number | undefined;
32
+ gt?: number | undefined;
35
33
  lt?: number | undefined;
36
34
  } | undefined;
37
35
  executionDeadline?: {
38
36
  gte?: number | undefined;
39
- gt?: number | undefined;
40
37
  lte?: number | undefined;
38
+ gt?: number | undefined;
41
39
  lt?: number | undefined;
42
40
  } | undefined;
41
+ failureCategory?: import("../../index.ts").FailureCategory | import("../../index.ts").FailureCategory[] | undefined;
42
+ limit?: number | undefined;
43
43
  }, PurgeResult, unknown>;
44
44
  export declare const purgeWorkflowsRestBinding: UnknownRestBinding;
@@ -1,6 +1,14 @@
1
- import type { ScheduleSpec } from '../../core/types.ts';
1
+ import type { ScheduleSpec, ScheduleUpdateOptions } from '../../core/types.ts';
2
2
  import type { OperationFault } from '../operation-fault.ts';
3
3
  export { isOperationFault } from './operation-helpers.ts';
4
+ export type ScheduleMutableOptionsInput = {
5
+ description?: unknown;
6
+ overlap?: unknown;
7
+ backfill?: unknown;
8
+ jitter?: unknown;
9
+ };
10
+ /** Validate the mutable schedule options shared by create and update. */
11
+ export declare function validateScheduleMutableOptions(input: ScheduleMutableOptionsInput): ScheduleUpdateOptions;
4
12
  export declare function mapScheduleErrorToFault(scheduleId: string, error: unknown): OperationFault;
5
13
  /**
6
14
  * Validate the mutually exclusive schedule cadence fields (`cronExpression` or
@@ -1,5 +1,56 @@
1
+ import {
2
+ isValidScheduleOverlapPolicy,
3
+ normalizeScheduleUpdateOptions
4
+ } from "../../core/engine/validation/schedule.js";
1
5
  import { invalidParamsFault } from "./operation-helpers.js";
2
6
  export { isOperationFault } from "./operation-helpers.js";
7
+ export function validateScheduleMutableOptions(input) {
8
+ const description = validateScheduleDescription(input.description), overlap = validateScheduleOverlap(input.overlap), backfill = validateScheduleBackfill(input.backfill), jitter = validateScheduleJitter(input.jitter);
9
+ return {
10
+ ...description !== void 0 ? { description } : {},
11
+ ...overlap !== void 0 ? { overlap } : {},
12
+ ...backfill !== void 0 ? { backfill } : {},
13
+ ...jitter !== void 0 ? { jitter } : {}
14
+ };
15
+ }
16
+ function validateScheduleDescription(value) {
17
+ if (value === void 0)
18
+ return;
19
+ if (typeof value !== "string")
20
+ throw invalidParamsFault('Field "description" must be a string');
21
+ return value;
22
+ }
23
+ function validateScheduleOverlap(value) {
24
+ if (value === void 0)
25
+ return;
26
+ if (!isValidScheduleOverlapPolicy(value))
27
+ throw invalidParamsFault('Field "overlap" must be one of skip, queue, cancel-running, allow');
28
+ return value;
29
+ }
30
+ function validateScheduleBackfill(value) {
31
+ if (value === void 0)
32
+ return;
33
+ if (typeof value !== "boolean")
34
+ throw invalidParamsFault('Field "backfill" must be a boolean');
35
+ return value;
36
+ }
37
+ function validateScheduleJitter(value) {
38
+ if (value === void 0)
39
+ return;
40
+ if (typeof value !== "string" && typeof value !== "number")
41
+ throw invalidParamsFault('Field "jitter" must be a duration string or a number of milliseconds');
42
+ try {
43
+ normalizeScheduleUpdateOptions({ jitter: value });
44
+ } catch (error) {
45
+ const message = error instanceof Error ? error.message : String(error);
46
+ throw invalidParamsFault(formatJitterValidationMessage(message));
47
+ }
48
+ return value;
49
+ }
50
+ function formatJitterValidationMessage(message) {
51
+ const enginePrefix = "Invalid options.jitter: ", hasEnginePrefix = message.startsWith(enginePrefix), wireDetail = (hasEnginePrefix ? message.slice(enginePrefix.length) : message).replaceAll("options.jitter", 'Field "jitter"');
52
+ return hasEnginePrefix ? `Field "jitter" is invalid: ${wireDetail}` : wireDetail;
53
+ }
3
54
  export function mapScheduleErrorToFault(scheduleId, error) {
4
55
  const message = error instanceof Error ? error.message : String(error), normalizedMessage = message.toLowerCase();
5
56
  if (normalizedMessage.includes("not found"))
@@ -0,0 +1,11 @@
1
+ import type { RestInputContext } from '../rest-binding.ts';
2
+ export type SharedScheduleRestFields = {
3
+ readonly cronExpression: unknown;
4
+ readonly every: unknown;
5
+ readonly description: unknown;
6
+ readonly overlap: unknown;
7
+ readonly backfill: unknown;
8
+ readonly jitter: unknown;
9
+ };
10
+ export declare function parseScheduleRestBodyRequestRecord(request: Request, context?: RestInputContext): Promise<Record<string, unknown>>;
11
+ export declare function extractSharedScheduleRestFields(record: Record<string, unknown>): SharedScheduleRestFields;
@@ -0,0 +1,28 @@
1
+ import { readRestJsonBody } from "../rest-body.js";
2
+ import { invalidParamsFault, isOperationFault } from "./operation-helpers.js";
3
+ function isJsonObjectLikeRecord(value) {
4
+ return typeof value === "object" && value !== null;
5
+ }
6
+ export async function parseScheduleRestBodyRequestRecord(request, context) {
7
+ let body;
8
+ try {
9
+ body = await readRestJsonBody(request, context);
10
+ } catch (error) {
11
+ if (isOperationFault(error))
12
+ throw error;
13
+ throw invalidParamsFault("Invalid JSON body");
14
+ }
15
+ if (!isJsonObjectLikeRecord(body))
16
+ throw invalidParamsFault("Request body must be a JSON object");
17
+ return body;
18
+ }
19
+ export function extractSharedScheduleRestFields(record) {
20
+ return {
21
+ cronExpression: Object.hasOwn(record, "cronExpression") ? record.cronExpression : void 0,
22
+ every: Object.hasOwn(record, "every") ? record.every : void 0,
23
+ description: record.description,
24
+ overlap: record.overlap,
25
+ backfill: record.backfill,
26
+ jitter: record.jitter
27
+ };
28
+ }