@openclaw/lobster 2026.8.1-beta.3 → 2026.8.1

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 (126) hide show
  1. package/dist/index.js +130 -112
  2. package/node_modules/typebox/build/format/date.d.mts +1 -1
  3. package/node_modules/typebox/build/format/date.mjs +1 -1
  4. package/node_modules/typebox/build/format/date_time.d.mts +2 -2
  5. package/node_modules/typebox/build/format/date_time.mjs +3 -3
  6. package/node_modules/typebox/build/format/email.d.mts +1 -1
  7. package/node_modules/typebox/build/format/email.mjs +2 -2
  8. package/node_modules/typebox/build/format/hostname.mjs +2 -10
  9. package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
  10. package/node_modules/typebox/build/format/idn_email.mjs +3 -3
  11. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
  12. package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
  13. package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
  14. package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
  15. package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
  16. package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
  17. package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
  18. package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
  19. package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
  20. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +23 -0
  21. package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
  22. package/node_modules/typebox/build/format/idna/index.mjs +2 -0
  23. package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
  24. package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
  25. package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
  26. package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
  27. package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
  28. package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
  29. package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
  30. package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
  31. package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
  32. package/node_modules/typebox/build/format/ipv4.mjs +2 -32
  33. package/node_modules/typebox/build/format/ipv6.mjs +2 -61
  34. package/node_modules/typebox/build/format/iri.d.mts +2 -2
  35. package/node_modules/typebox/build/format/iri.mjs +26 -8
  36. package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
  37. package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
  38. package/node_modules/typebox/build/format/regex.d.mts +1 -2
  39. package/node_modules/typebox/build/format/regex.mjs +2 -6
  40. package/node_modules/typebox/build/format/time.d.mts +2 -2
  41. package/node_modules/typebox/build/format/time.mjs +19 -14
  42. package/node_modules/typebox/build/format/uri.d.mts +1 -1
  43. package/node_modules/typebox/build/format/uri.mjs +3 -130
  44. package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
  45. package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
  46. package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
  47. package/node_modules/typebox/build/format/uri_template.mjs +4 -5
  48. package/node_modules/typebox/build/format/url.d.mts +3 -3
  49. package/node_modules/typebox/build/format/url.mjs +4 -5
  50. package/node_modules/typebox/build/guard/emit.d.mts +3 -1
  51. package/node_modules/typebox/build/guard/emit.mjs +12 -5
  52. package/node_modules/typebox/build/guard/guard.d.mts +8 -2
  53. package/node_modules/typebox/build/guard/guard.mjs +25 -4
  54. package/node_modules/typebox/build/guard/string.d.mts +2 -2
  55. package/node_modules/typebox/build/guard/string.mjs +7 -7
  56. package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
  57. package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
  58. package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
  59. package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
  60. package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
  61. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
  62. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
  63. package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
  64. package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
  65. package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
  66. package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
  67. package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
  68. package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
  69. package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
  70. package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
  71. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
  72. package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
  73. package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
  74. package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
  75. package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
  76. package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
  77. package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
  78. package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
  79. package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
  80. package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
  81. package/node_modules/typebox/build/schema/types/index.mjs +0 -2
  82. package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
  83. package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
  84. package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
  85. package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
  86. package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
  87. package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
  88. package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
  89. package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
  90. package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
  91. package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
  92. package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
  93. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
  94. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
  95. package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
  96. package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
  97. package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
  98. package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
  99. package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
  100. package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
  101. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
  102. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
  103. package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
  104. package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
  105. package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
  106. package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
  107. package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
  108. package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
  109. package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
  110. package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
  111. package/node_modules/typebox/build/type/script/parser.mjs +27 -23
  112. package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
  113. package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
  114. package/node_modules/typebox/package.json +27 -27
  115. package/node_modules/typebox/readme.md +79 -82
  116. package/package.json +5 -5
  117. package/node_modules/typebox/build/format/_idna.d.mts +0 -2
  118. package/node_modules/typebox/build/format/_idna.mjs +0 -246
  119. package/node_modules/typebox/build/format/_puny.d.mts +0 -1
  120. package/node_modules/typebox/build/format/_puny.mjs +0 -77
  121. package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
  122. package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
  123. package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
  124. package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
  125. package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
  126. package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
package/dist/index.js CHANGED
@@ -35,10 +35,10 @@ function createLimitedSink(maxBytes, label) {
35
35
  callback();
36
36
  } });
37
37
  }
38
- function normalizeEnvelope(envelope) {
38
+ function normalizeEnvelope(envelope, maxStdoutBytes) {
39
39
  if (!envelope.ok) throw new Error(envelope.error?.message ?? "lobster runtime failed");
40
40
  if (envelope.status === "needs_input") throw new Error("Lobster input requests are not supported by the OpenClaw Lobster tool yet");
41
- return {
41
+ const normalized = {
42
42
  ok: true,
43
43
  status: envelope.status ?? "ok",
44
44
  output: Array.isArray(envelope.output) ? envelope.output : [],
@@ -50,6 +50,8 @@ function normalizeEnvelope(envelope) {
50
50
  ...envelope.requiresApproval.approvalId ? { approvalId: envelope.requiresApproval.approvalId } : {}
51
51
  } : null
52
52
  };
53
+ if (Buffer.byteLength(JSON.stringify(normalized, null, 2), "utf8") > maxStdoutBytes) throw new Error("lobster runtime result exceeded maxStdoutBytes");
54
+ return normalized;
53
55
  }
54
56
  function isMissingPathError(error) {
55
57
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
@@ -112,6 +114,7 @@ function createEmbeddedLobsterRunner(options) {
112
114
  const runtime = await runtimePromise;
113
115
  return await withTimeout(params.timeoutMs, async (signal) => {
114
116
  const ctx = createEmbeddedToolContext(params, signal);
117
+ let envelope;
115
118
  if (params.action === "run") {
116
119
  const pipeline = params.pipeline?.trim() ?? "";
117
120
  if (!pipeline) throw new Error("pipeline required");
@@ -124,27 +127,28 @@ function createEmbeddedLobsterRunner(options) {
124
127
  } catch {
125
128
  throw new Error("run --args-json must be valid JSON");
126
129
  }
127
- return normalizeEnvelope(await runtime.runToolRequest({
130
+ envelope = await runtime.runToolRequest({
128
131
  filePath,
129
132
  args,
130
133
  ctx
131
- }));
132
- }
133
- return normalizeEnvelope(await runtime.runToolRequest({
134
+ });
135
+ } else envelope = await runtime.runToolRequest({
134
136
  pipeline,
135
137
  ctx
136
- }));
138
+ });
139
+ } else {
140
+ const token = params.token?.trim() ?? "";
141
+ const approvalId = params.approvalId?.trim() ?? "";
142
+ if (!token && !approvalId) throw new Error("token or approvalId required");
143
+ if (typeof params.approve !== "boolean") throw new Error("approve required");
144
+ envelope = await runtime.resumeToolRequest({
145
+ ...token ? { token } : {},
146
+ ...approvalId ? { approvalId } : {},
147
+ approved: params.approve,
148
+ ctx
149
+ });
137
150
  }
138
- const token = params.token?.trim() ?? "";
139
- const approvalId = params.approvalId?.trim() ?? "";
140
- if (!token && !approvalId) throw new Error("token or approvalId required");
141
- if (typeof params.approve !== "boolean") throw new Error("approve required");
142
- return normalizeEnvelope(await runtime.resumeToolRequest({
143
- ...token ? { token } : {},
144
- ...approvalId ? { approvalId } : {},
145
- approved: params.approve,
146
- ctx
147
- }));
151
+ return normalizeEnvelope(envelope, Math.max(1024, params.maxStdoutBytes));
148
152
  });
149
153
  } };
150
154
  }
@@ -152,29 +156,25 @@ function createEmbeddedLobsterRunner(options) {
152
156
  //#region extensions/lobster/src/lobster-taskflow.ts
153
157
  function toJsonLike(value, seen = /* @__PURE__ */ new WeakSet()) {
154
158
  if (value === null) return null;
155
- switch (typeof value) {
156
- case "boolean":
157
- case "string": return value;
158
- case "number": return Number.isFinite(value) ? value : String(value);
159
- case "bigint": return value.toString();
160
- case "undefined":
161
- case "function":
162
- case "symbol": return null;
163
- case "object": {
164
- if (value instanceof Date) return value.toISOString();
165
- if (Array.isArray(value)) return value.map((item) => toJsonLike(item, seen));
166
- if (seen.has(value)) return "[Circular]";
167
- seen.add(value);
168
- const jsonObject = {};
169
- for (const [key, entry] of Object.entries(value)) {
170
- if (entry === void 0 || typeof entry === "function" || typeof entry === "symbol") continue;
171
- jsonObject[key] = toJsonLike(entry, seen);
172
- }
173
- seen.delete(value);
174
- return jsonObject;
175
- }
159
+ if (typeof value === "number") return Number.isFinite(value) ? value : String(value);
160
+ if (typeof value === "bigint") return value.toString();
161
+ if (typeof value === "boolean" || typeof value === "string") return value;
162
+ if (typeof value !== "object") return null;
163
+ if (value instanceof Date) return value.toISOString();
164
+ if (seen.has(value)) return "[Circular]";
165
+ seen.add(value);
166
+ if (Array.isArray(value)) {
167
+ const jsonArray = value.map((item) => toJsonLike(item, seen));
168
+ seen.delete(value);
169
+ return jsonArray;
170
+ }
171
+ const jsonObject = {};
172
+ for (const [key, entry] of Object.entries(value)) {
173
+ if (entry === void 0 || typeof entry === "function" || typeof entry === "symbol") continue;
174
+ jsonObject[key] = toJsonLike(entry, seen);
176
175
  }
177
- return null;
176
+ seen.delete(value);
177
+ return jsonObject;
178
178
  }
179
179
  function buildApprovalWaitState(envelope) {
180
180
  const approval = envelope.requiresApproval;
@@ -186,40 +186,51 @@ function buildApprovalWaitState(envelope) {
186
186
  ...approval?.approvalId ? { approvalId: approval.approvalId } : {}
187
187
  };
188
188
  }
189
- function applyEnvelopeToFlow(params) {
190
- const { taskFlow, flow, envelope, waitingStep } = params;
191
- const flowMutation = {
192
- flowId: flow.flowId,
193
- expectedRevision: flow.revision
194
- };
195
- if (!envelope.ok) return taskFlow.fail(flowMutation);
196
- if (envelope.status === "needs_approval") return taskFlow.setWaiting({
197
- ...flowMutation,
198
- currentStep: waitingStep,
199
- waitJson: buildApprovalWaitState(envelope)
200
- });
201
- return taskFlow.finish(flowMutation);
202
- }
203
- async function executeManagedLobsterFlow(params, flow, failureFlowId = flow.flowId) {
189
+ async function executeManagedLobsterFlow(params, flow) {
204
190
  try {
205
191
  const envelope = await params.runner.run(params.runnerParams);
206
- const mutation = applyEnvelopeToFlow({
207
- taskFlow: params.taskFlow,
208
- flow,
209
- envelope,
210
- waitingStep: params.waitingStep ?? "await_lobster_approval"
211
- });
192
+ if (envelope.ok && envelope.status === "cancelled") try {
193
+ const mutation = await params.taskFlow.cancel({
194
+ flowId: flow.flowId,
195
+ cfg: params.config
196
+ });
197
+ return mutation.cancelled ? {
198
+ ok: true,
199
+ envelope,
200
+ flow,
201
+ mutation
202
+ } : {
203
+ ok: false,
204
+ flow,
205
+ mutation,
206
+ error: /* @__PURE__ */ new Error(`TaskFlow cancellation failed: ${mutation.reason ?? "unknown"}`)
207
+ };
208
+ } catch (error) {
209
+ return {
210
+ ok: false,
211
+ flow,
212
+ error: error instanceof Error ? error : new Error(String(error))
213
+ };
214
+ }
215
+ const flowMutation = {
216
+ flowId: flow.flowId,
217
+ expectedRevision: flow.revision
218
+ };
212
219
  if (!envelope.ok) return {
213
220
  ok: false,
214
221
  flow,
215
- mutation,
222
+ mutation: params.taskFlow.fail(flowMutation),
216
223
  error: new Error(envelope.error.message)
217
224
  };
218
225
  return {
219
226
  ok: true,
220
227
  envelope,
221
228
  flow,
222
- mutation
229
+ mutation: envelope.status === "needs_approval" ? params.taskFlow.setWaiting({
230
+ ...flowMutation,
231
+ currentStep: params.waitingStep ?? "await_lobster_approval",
232
+ waitJson: buildApprovalWaitState(envelope)
233
+ }) : params.taskFlow.finish(flowMutation)
223
234
  };
224
235
  } catch (error) {
225
236
  const err = error instanceof Error ? error : new Error(String(error));
@@ -228,7 +239,7 @@ async function executeManagedLobsterFlow(params, flow, failureFlowId = flow.flow
228
239
  ok: false,
229
240
  flow,
230
241
  mutation: params.taskFlow.fail({
231
- flowId: failureFlowId,
242
+ flowId: flow.flowId,
232
243
  expectedRevision: flow.revision
233
244
  }),
234
245
  error: err
@@ -268,7 +279,7 @@ async function resumeManagedLobsterFlow(params) {
268
279
  mutation: resumed,
269
280
  error: /* @__PURE__ */ new Error(`TaskFlow resume failed: ${resumed.code}`)
270
281
  };
271
- return await executeManagedLobsterFlow(params, resumed.flow, params.flowId);
282
+ return await executeManagedLobsterFlow(params, resumed.flow);
272
283
  }
273
284
  //#endregion
274
285
  //#region extensions/lobster/src/lobster-tool.ts
@@ -300,28 +311,29 @@ function parseOptionalFlowStateJson(value) {
300
311
  function isEmptyJsonObject(value) {
301
312
  return value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
302
313
  }
303
- function parseRunFlowParams(params) {
304
- const controllerId = readOptionalTrimmedString(params.flowControllerId, "flowControllerId");
305
- const goal = readOptionalTrimmedString(params.flowGoal, "flowGoal");
306
- const currentStep = readOptionalTrimmedString(params.flowCurrentStep, "flowCurrentStep");
307
- const waitingStep = readOptionalTrimmedString(params.flowWaitingStep, "flowWaitingStep");
308
- const stateJson = parseOptionalFlowStateJson(params.flowStateJson);
309
- const resumeFlowId = readOptionalTrimmedString(params.flowId, "flowId");
310
- const resumeRevision = readOptionalNumber(params.flowExpectedRevision, "flowExpectedRevision");
311
- const stateJsonSignalsRunMode = stateJson !== void 0 && !isEmptyJsonObject(stateJson);
312
- if (resumeFlowId !== void 0 || resumeRevision !== void 0 && resumeRevision !== 0) throw new Error("run action does not accept flowId or flowExpectedRevision");
313
- if (!(controllerId !== void 0 || goal !== void 0 || currentStep !== void 0 || waitingStep !== void 0 || stateJsonSignalsRunMode)) return null;
314
- if (!controllerId) throw new Error("flowControllerId required when using managed TaskFlow run mode");
315
- if (!goal) throw new Error("flowGoal required when using managed TaskFlow run mode");
316
- return {
317
- controllerId,
318
- goal,
319
- ...currentStep ? { currentStep } : {},
320
- ...waitingStep ? { waitingStep } : {},
321
- ...stateJson !== void 0 ? { stateJson } : {}
322
- };
323
- }
324
- function parseResumeFlowParams(params) {
314
+ function parseManagedFlowParams(action, params, runnerParams) {
315
+ if (action === "run") {
316
+ const controllerId = readOptionalTrimmedString(params.flowControllerId, "flowControllerId");
317
+ const goal = readOptionalTrimmedString(params.flowGoal, "flowGoal");
318
+ const currentStep = readOptionalTrimmedString(params.flowCurrentStep, "flowCurrentStep");
319
+ const waitingStep = readOptionalTrimmedString(params.flowWaitingStep, "flowWaitingStep");
320
+ const stateJson = parseOptionalFlowStateJson(params.flowStateJson);
321
+ const resumeFlowId = readOptionalTrimmedString(params.flowId, "flowId");
322
+ const resumeRevision = readOptionalNumber(params.flowExpectedRevision, "flowExpectedRevision");
323
+ const stateJsonSignalsRunMode = stateJson !== void 0 && !isEmptyJsonObject(stateJson);
324
+ if (resumeFlowId !== void 0 || resumeRevision !== void 0 && resumeRevision !== 0) throw new Error("run action does not accept flowId or flowExpectedRevision");
325
+ if (controllerId === void 0 && goal === void 0 && currentStep === void 0 && waitingStep === void 0 && !stateJsonSignalsRunMode) return null;
326
+ if (!controllerId) throw new Error("flowControllerId required when using managed TaskFlow run mode");
327
+ if (!goal) throw new Error("flowGoal required when using managed TaskFlow run mode");
328
+ return {
329
+ action,
330
+ controllerId,
331
+ goal,
332
+ ...currentStep ? { currentStep } : {},
333
+ ...waitingStep ? { waitingStep } : {},
334
+ ...stateJson !== void 0 ? { stateJson } : {}
335
+ };
336
+ }
325
337
  const flowId = readOptionalTrimmedString(params.flowId, "flowId");
326
338
  const expectedRevision = readOptionalNumber(params.flowExpectedRevision, "flowExpectedRevision");
327
339
  const currentStep = readOptionalTrimmedString(params.flowCurrentStep, "flowCurrentStep");
@@ -337,13 +349,21 @@ function parseResumeFlowParams(params) {
337
349
  if (!(flowId !== void 0 || expectedRevision !== void 0 && expectedRevision !== 0 || currentStep !== void 0 || waitingStep !== void 0)) return null;
338
350
  if (!flowId) throw new Error("flowId required when using managed TaskFlow resume mode");
339
351
  if (expectedRevision === void 0) throw new Error("flowExpectedRevision required when using managed TaskFlow resume mode");
340
- if (!token && !approvalId) throw new Error("token or approvalId required when using managed TaskFlow resume mode");
352
+ const credentialParams = token ? { token: runnerParams.token ?? token } : approvalId ? { approvalId: runnerParams.approvalId ?? approvalId } : null;
353
+ if (!credentialParams) throw new Error("token or approvalId required when using managed TaskFlow resume mode");
341
354
  if (approve === void 0) throw new Error("approve required when using managed TaskFlow resume mode");
342
355
  return {
356
+ action,
343
357
  flowId,
344
358
  expectedRevision,
345
359
  ...currentStep ? { currentStep } : {},
346
- ...waitingStep ? { waitingStep } : {}
360
+ ...waitingStep ? { waitingStep } : {},
361
+ runnerParams: {
362
+ ...runnerParams,
363
+ ...credentialParams,
364
+ action,
365
+ approve
366
+ }
347
367
  };
348
368
  }
349
369
  function resolveManagedFlowToolResult(result) {
@@ -402,30 +422,28 @@ function createLobsterTool(api, options) {
402
422
  maxStdoutBytes
403
423
  };
404
424
  const taskFlow = options?.taskFlow;
405
- if (action === "run") {
406
- const flowParams = parseRunFlowParams(params);
407
- if (flowParams) return resolveManagedFlowToolResult(await runManagedLobsterFlow({
408
- taskFlow: requireTaskFlowRuntime(taskFlow, "run"),
409
- runner,
410
- runnerParams,
411
- controllerId: flowParams.controllerId,
412
- goal: flowParams.goal,
413
- ...flowParams.stateJson !== void 0 ? { stateJson: flowParams.stateJson } : {},
414
- ...flowParams.currentStep ? { currentStep: flowParams.currentStep } : {},
415
- ...flowParams.waitingStep ? { waitingStep: flowParams.waitingStep } : {}
416
- }));
417
- } else {
418
- const flowParams = parseResumeFlowParams(params);
419
- if (flowParams) return resolveManagedFlowToolResult(await resumeManagedLobsterFlow({
420
- taskFlow: requireTaskFlowRuntime(taskFlow, "resume"),
421
- runner,
422
- runnerParams,
423
- flowId: flowParams.flowId,
424
- expectedRevision: flowParams.expectedRevision,
425
- ...flowParams.currentStep ? { currentStep: flowParams.currentStep } : {},
426
- ...flowParams.waitingStep ? { waitingStep: flowParams.waitingStep } : {}
427
- }));
428
- }
425
+ const flowParams = parseManagedFlowParams(action, params, runnerParams);
426
+ if (flowParams?.action === "run") return resolveManagedFlowToolResult(await runManagedLobsterFlow({
427
+ taskFlow: requireTaskFlowRuntime(taskFlow, "run"),
428
+ config: api.config,
429
+ runner,
430
+ runnerParams,
431
+ controllerId: flowParams.controllerId,
432
+ goal: flowParams.goal,
433
+ ...flowParams.stateJson !== void 0 ? { stateJson: flowParams.stateJson } : {},
434
+ ...flowParams.currentStep ? { currentStep: flowParams.currentStep } : {},
435
+ ...flowParams.waitingStep ? { waitingStep: flowParams.waitingStep } : {}
436
+ }));
437
+ if (flowParams?.action === "resume") return resolveManagedFlowToolResult(await resumeManagedLobsterFlow({
438
+ taskFlow: requireTaskFlowRuntime(taskFlow, "resume"),
439
+ config: api.config,
440
+ runner,
441
+ runnerParams: flowParams.runnerParams,
442
+ flowId: flowParams.flowId,
443
+ expectedRevision: flowParams.expectedRevision,
444
+ ...flowParams.currentStep ? { currentStep: flowParams.currentStep } : {},
445
+ ...flowParams.waitingStep ? { waitingStep: flowParams.waitingStep } : {}
446
+ }));
429
447
  const envelope = await runner.run(runnerParams);
430
448
  if (!envelope.ok) throw new Error(envelope.error.message);
431
449
  return jsonResult(envelope);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a ISO8601 Date component string
3
- * @source ajv-formats
3
+ * @description https://datatracker.ietf.org/doc/html/rfc3339
4
4
  * @example `2020-12-12`
5
5
  */
6
6
  export declare function IsDate(value: string): boolean;
@@ -5,7 +5,7 @@ function IsLeapYear(year) {
5
5
  }
6
6
  /**
7
7
  * Returns true if the value is a ISO8601 Date component string
8
- * @source ajv-formats
8
+ * @description https://datatracker.ietf.org/doc/html/rfc3339
9
9
  * @example `2020-12-12`
10
10
  */
11
11
  export function IsDate(value) {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a ISO8601 DateTime string
3
- * @source ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc3339
4
4
  * @example `2020-12-12T20:20:40+00:00`
5
5
  */
6
- export declare function IsDateTime(value: string, strictTimeZone?: boolean): boolean;
6
+ export declare function IsDateTime(value: string): boolean;
@@ -2,10 +2,10 @@ import { IsDate } from './date.mjs';
2
2
  import { IsTime } from './time.mjs';
3
3
  /**
4
4
  * Returns true if the value is a ISO8601 DateTime string
5
- * @source ajv-formats
5
+ * @specification https://datatracker.ietf.org/doc/html/rfc3339
6
6
  * @example `2020-12-12T20:20:40+00:00`
7
7
  */
8
- export function IsDateTime(value, strictTimeZone = true) {
8
+ export function IsDateTime(value) {
9
9
  const dateTime = value.split(/T/i);
10
- return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1], strictTimeZone);
10
+ return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1]);
11
11
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Returns true if the value is an Email
3
- * @specification ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc5322
4
4
  */
5
5
  export declare function IsEmail(value: string): boolean;
@@ -1,7 +1,7 @@
1
- const Email = /^(?!.*\.\.)[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i;
1
+ const Email = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[^"\\]|\\.)*")@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*|\[(?:IPv6:[a-f0-9:]+|(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})\])$/i;
2
2
  /**
3
3
  * Returns true if the value is an Email
4
- * @specification ajv-formats
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc5322
5
5
  */
6
6
  export function IsEmail(value) {
7
7
  return Email.test(value);
@@ -1,4 +1,4 @@
1
- import * as Idna from './_idna.mjs';
1
+ import * as Idna from './idna/index.mjs';
2
2
  /**
3
3
  * Returns true if the value is a valid hostname.
4
4
  * @specification https://tools.ietf.org/html/rfc1123
@@ -6,13 +6,5 @@ import * as Idna from './_idna.mjs';
6
6
  * @specification https://tools.ietf.org/html/rfc5892
7
7
  */
8
8
  export function IsHostname(value) {
9
- if (value.length === 0 || value.length > 253)
10
- return false;
11
- if (value.charCodeAt(value.length - 1) === 46)
12
- return false;
13
- for (const label of value.split('.')) {
14
- if (!Idna.IsLabel(label))
15
- return false;
16
- }
17
- return true;
9
+ return Idna.IsHostname(value);
18
10
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Returns true if the value is an IdnEmail
3
- * @specification ajv-formats (unicode-extension)
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc4952
4
4
  */
5
5
  export declare function IsIdnEmail(value: string): boolean;
@@ -1,8 +1,8 @@
1
- const IdnEmail = /^(?!.*\.\.)[\p{L}\p{N}!#$%&'*+/=?^_`{|}~-]+(?:\.[\p{L}\p{N}!#$%&'*+/=?^_`{|}~-]+)*@[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,61}[\p{L}\p{N}])?(?:\.[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,61}[\p{L}\p{N}])?)*$/iu;
1
+ const IdnEmail = /^(?:[A-Za-z0-9!#$%&'*+\/=?^_`{|}~\u{0080}-\u{10FFFF}-]+(?:\.[A-Za-z0-9!#$%&'*+\/=?^_`{|}~\u{0080}-\u{10FFFF}-]+)*|"(?:[^"\\]|\\.)*")@[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,62})(?<!-)(?:\.[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,62})(?<!-))*$/iu;
2
2
  /**
3
3
  * Returns true if the value is an IdnEmail
4
- * @specification ajv-formats (unicode-extension)
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc4952
5
5
  */
6
6
  export function IsIdnEmail(value) {
7
- return IdnEmail.test(value);
7
+ return IdnEmail.test(value.normalize('NFC'));
8
8
  }
@@ -3,5 +3,6 @@
3
3
  * @specification https://tools.ietf.org/html/rfc3490
4
4
  * @specification https://tools.ietf.org/html/rfc5891
5
5
  * @specification https://tools.ietf.org/html/rfc5892
6
+ * @specification https://tools.ietf.org/html/rfc5893
6
7
  */
7
8
  export declare function IsIdnHostname(value: string): boolean;
@@ -1,19 +1,11 @@
1
- import { IsIdnLabel } from './_idna.mjs';
1
+ import * as Idna from './idna/index.mjs';
2
2
  /**
3
3
  * Returns true if the value is a valid internationalized (IDN) hostname.
4
4
  * @specification https://tools.ietf.org/html/rfc3490
5
5
  * @specification https://tools.ietf.org/html/rfc5891
6
6
  * @specification https://tools.ietf.org/html/rfc5892
7
+ * @specification https://tools.ietf.org/html/rfc5893
7
8
  */
8
9
  export function IsIdnHostname(value) {
9
- if (value.length === 0 || value.includes(' '))
10
- return false;
11
- const canonical = value.normalize('NFC').replace(/[\u002E\u3002\uFF0E\uFF61]/g, '.');
12
- if (canonical.length > 253)
13
- return false;
14
- for (const label of canonical.split('.')) {
15
- if (!IsIdnLabel(label))
16
- return false;
17
- }
18
- return true;
10
+ return Idna.IsIdnHostname(value);
19
11
  }
@@ -0,0 +1,3 @@
1
+ export declare function HasBidiChars(value: string): boolean;
2
+ export declare function HasRightToLeftCharacters(value: string): boolean;
3
+ export declare function SatisfiesBidiRule(value: string): boolean;
@@ -0,0 +1,98 @@
1
+ // deno-fmt-ignore-file
2
+ import * as FormatPuny from './puny.mjs';
3
+ import * as Pattern from '../pattern/pattern.mjs';
4
+ // ------------------------------------------------------------------
5
+ // LOCAL REGEX: Allowed Bidi classes per direction (RFC 5893)
6
+ // ------------------------------------------------------------------
7
+ const RE_RTL_ALLOWED = /^(?:R|AL|AN|EN|ES|CS|ET|ON|BN|NSM)$/;
8
+ const RE_LTR_ALLOWED = /^(?:L|EN|ES|CS|ET|ON|BN|NSM)$/;
9
+ const RE_RTL_CLASSES = /^(?:R|AL|AN)$/;
10
+ // ------------------------------------------------------------------
11
+ // HasBidiChars
12
+ //
13
+ // Decodes a punycode label to its Unicode form (if it is one) and
14
+ // checks whether the result is an RTL label per RFC 5893 §1.4.
15
+ // ------------------------------------------------------------------
16
+ export function HasBidiChars(value) {
17
+ if (FormatPuny.IsAcePrefixed(value)) {
18
+ try {
19
+ return HasRightToLeftCharacters(FormatPuny.Decode(value.slice(4).toLowerCase()));
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ return HasRightToLeftCharacters(value);
26
+ }
27
+ // ------------------------------------------------------------------
28
+ // GetBidiClass
29
+ // ------------------------------------------------------------------
30
+ function GetBidiClass(codePoint) {
31
+ const char = String.fromCodePoint(codePoint);
32
+ return (Pattern.RE_EUROPEAN_NUMBER.test(char) ? 'EN' :
33
+ Pattern.RE_ARABIC_INDIC_DIGIT.test(char) ? 'AN' :
34
+ // Pattern.RE_EUROPEAN_SEPARATOR.test(char) ? 'ES' : // (no-spec-coverage)
35
+ // Pattern.RE_COMMON_SEPARATOR.test(char) ? 'CS' : // (no-spec-coverage)
36
+ Pattern.RE_MARK_NONSPACING.test(char) ? 'NSM' :
37
+ Pattern.RE_SCRIPT_HEBREW.test(char) ? 'R' :
38
+ Pattern.RE_SCRIPT_ARABIC_LETTER.test(char) ? 'AL' :
39
+ Pattern.RE_LETTER.test(char) ? 'L' :
40
+ 'ON');
41
+ }
42
+ // ------------------------------------------------------------------
43
+ // HasRightToLeftCharacters
44
+ //
45
+ // Per RFC 5893 §1.4: "An RTL label is a label that contains at least
46
+ // one character of type R, AL, or AN." Used to determine whether a
47
+ // domain name is a "Bidi domain name" (RFC 5893 §1.4), in which case
48
+ // the Bidi Rule applies to every label in the domain.
49
+ // ------------------------------------------------------------------
50
+ export function HasRightToLeftCharacters(value) {
51
+ for (const ch of value)
52
+ if (RE_RTL_CLASSES.test(GetBidiClass(ch.codePointAt(0))))
53
+ return true;
54
+ return false;
55
+ }
56
+ // ------------------------------------------------------------------
57
+ // SatisfiesBidiRule
58
+ // ------------------------------------------------------------------
59
+ export function SatisfiesBidiRule(value) {
60
+ let isRtl = false;
61
+ let allowed = RE_LTR_ALLOWED;
62
+ let sawEN = false;
63
+ let sawAN = false;
64
+ let isFirst = true;
65
+ // let lastClass: string | null = null // (no-spec-coverage)
66
+ for (const ch of value) {
67
+ const bidiClass = GetBidiClass(ch.codePointAt(0));
68
+ if (isFirst) {
69
+ // 1. The first character must be a character with Bidi property L, R, or AL.
70
+ if (bidiClass !== 'L' && bidiClass !== 'R' && bidiClass !== 'AL')
71
+ return false;
72
+ isRtl = bidiClass === 'R' || bidiClass === 'AL';
73
+ allowed = isRtl ? RE_RTL_ALLOWED : RE_LTR_ALLOWED;
74
+ isFirst = false;
75
+ }
76
+ // 2 / 5. Only characters in the allowed set for this direction may appear.
77
+ if (!allowed.test(bidiClass))
78
+ return false;
79
+ if (bidiClass === 'EN')
80
+ sawEN = true;
81
+ else if (bidiClass === 'AN')
82
+ sawAN = true;
83
+ // if (bidiClass !== 'NSM') lastClass = bidiClass // (no-spec-coverage)
84
+ }
85
+ if (isRtl && sawEN && sawAN)
86
+ return false; // spec coverage path
87
+ // (no-spec-coverage)
88
+ // if (isRtl) {
89
+ // // 3. The end of the label must be R, AL, EN, or AN (ignoring trailing NSM).
90
+ // // if (lastClass !== 'R' && lastClass !== 'AL' && lastClass !== 'EN' && lastClass !== 'AN') return false
91
+ // // 4. If an EN is present, no AN may be present, and vice versa.
92
+ // if (sawEN && sawAN) return false
93
+ // } else {
94
+ // // 6. The end of the label must be L or EN (ignoring trailing NSM).
95
+ // // if (lastClass !== 'L' && lastClass !== 'EN') return false
96
+ // }
97
+ return true;
98
+ }
@@ -0,0 +1,3 @@
1
+ export declare function IsAcePrefixed(value: string): boolean;
2
+ export declare function Decode(value: string): string;
3
+ export declare function Encode(input: string): string;