@openclaw/lobster 2026.8.1-beta.2 → 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 +132 -119
  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
@@ -7,6 +7,7 @@ import { stat } from "node:fs/promises";
7
7
  import path from "node:path";
8
8
  import { Readable, Writable } from "node:stream";
9
9
  import { toErrorObject } from "openclaw/plugin-sdk/error-runtime";
10
+ import { isPathInside } from "openclaw/plugin-sdk/file-access-runtime";
10
11
  //#region extensions/lobster/src/lobster-runner.ts
11
12
  const workflowExts = /* @__PURE__ */ new Set([
12
13
  ".lobster",
@@ -14,19 +15,13 @@ const workflowExts = /* @__PURE__ */ new Set([
14
15
  ".yml",
15
16
  ".json"
16
17
  ]);
17
- function normalizeForCwdSandbox(p) {
18
- const normalized = path.normalize(p);
19
- return process.platform === "win32" ? normalized.toLowerCase() : normalized;
20
- }
21
18
  function resolveLobsterCwd(cwdRaw) {
22
19
  if (typeof cwdRaw !== "string" || !cwdRaw.trim()) return process.cwd();
23
20
  const cwd = cwdRaw.trim();
24
21
  if (path.isAbsolute(cwd)) throw new Error("cwd must be a relative path");
25
22
  const base = process.cwd();
26
23
  const resolved = path.resolve(base, cwd);
27
- const rel = path.relative(normalizeForCwdSandbox(base), normalizeForCwdSandbox(resolved));
28
- if (rel === "" || rel === ".") return resolved;
29
- if (rel.startsWith("..") || path.isAbsolute(rel)) throw new Error("cwd must stay within the gateway working directory");
24
+ if (!isPathInside(base, resolved)) throw new Error("cwd must stay within the gateway working directory");
30
25
  return resolved;
31
26
  }
32
27
  function createLimitedSink(maxBytes, label) {
@@ -40,10 +35,10 @@ function createLimitedSink(maxBytes, label) {
40
35
  callback();
41
36
  } });
42
37
  }
43
- function normalizeEnvelope(envelope) {
38
+ function normalizeEnvelope(envelope, maxStdoutBytes) {
44
39
  if (!envelope.ok) throw new Error(envelope.error?.message ?? "lobster runtime failed");
45
40
  if (envelope.status === "needs_input") throw new Error("Lobster input requests are not supported by the OpenClaw Lobster tool yet");
46
- return {
41
+ const normalized = {
47
42
  ok: true,
48
43
  status: envelope.status ?? "ok",
49
44
  output: Array.isArray(envelope.output) ? envelope.output : [],
@@ -55,6 +50,8 @@ function normalizeEnvelope(envelope) {
55
50
  ...envelope.requiresApproval.approvalId ? { approvalId: envelope.requiresApproval.approvalId } : {}
56
51
  } : null
57
52
  };
53
+ if (Buffer.byteLength(JSON.stringify(normalized, null, 2), "utf8") > maxStdoutBytes) throw new Error("lobster runtime result exceeded maxStdoutBytes");
54
+ return normalized;
58
55
  }
59
56
  function isMissingPathError(error) {
60
57
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
@@ -117,6 +114,7 @@ function createEmbeddedLobsterRunner(options) {
117
114
  const runtime = await runtimePromise;
118
115
  return await withTimeout(params.timeoutMs, async (signal) => {
119
116
  const ctx = createEmbeddedToolContext(params, signal);
117
+ let envelope;
120
118
  if (params.action === "run") {
121
119
  const pipeline = params.pipeline?.trim() ?? "";
122
120
  if (!pipeline) throw new Error("pipeline required");
@@ -129,27 +127,28 @@ function createEmbeddedLobsterRunner(options) {
129
127
  } catch {
130
128
  throw new Error("run --args-json must be valid JSON");
131
129
  }
132
- return normalizeEnvelope(await runtime.runToolRequest({
130
+ envelope = await runtime.runToolRequest({
133
131
  filePath,
134
132
  args,
135
133
  ctx
136
- }));
137
- }
138
- return normalizeEnvelope(await runtime.runToolRequest({
134
+ });
135
+ } else envelope = await runtime.runToolRequest({
139
136
  pipeline,
140
137
  ctx
141
- }));
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
+ });
142
150
  }
143
- const token = params.token?.trim() ?? "";
144
- const approvalId = params.approvalId?.trim() ?? "";
145
- if (!token && !approvalId) throw new Error("token or approvalId required");
146
- if (typeof params.approve !== "boolean") throw new Error("approve required");
147
- return normalizeEnvelope(await runtime.resumeToolRequest({
148
- ...token ? { token } : {},
149
- ...approvalId ? { approvalId } : {},
150
- approved: params.approve,
151
- ctx
152
- }));
151
+ return normalizeEnvelope(envelope, Math.max(1024, params.maxStdoutBytes));
153
152
  });
154
153
  } };
155
154
  }
@@ -157,29 +156,25 @@ function createEmbeddedLobsterRunner(options) {
157
156
  //#region extensions/lobster/src/lobster-taskflow.ts
158
157
  function toJsonLike(value, seen = /* @__PURE__ */ new WeakSet()) {
159
158
  if (value === null) return null;
160
- switch (typeof value) {
161
- case "boolean":
162
- case "string": return value;
163
- case "number": return Number.isFinite(value) ? value : String(value);
164
- case "bigint": return value.toString();
165
- case "undefined":
166
- case "function":
167
- case "symbol": return null;
168
- case "object": {
169
- if (value instanceof Date) return value.toISOString();
170
- if (Array.isArray(value)) return value.map((item) => toJsonLike(item, seen));
171
- if (seen.has(value)) return "[Circular]";
172
- seen.add(value);
173
- const jsonObject = {};
174
- for (const [key, entry] of Object.entries(value)) {
175
- if (entry === void 0 || typeof entry === "function" || typeof entry === "symbol") continue;
176
- jsonObject[key] = toJsonLike(entry, seen);
177
- }
178
- seen.delete(value);
179
- return jsonObject;
180
- }
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);
181
175
  }
182
- return null;
176
+ seen.delete(value);
177
+ return jsonObject;
183
178
  }
184
179
  function buildApprovalWaitState(envelope) {
185
180
  const approval = envelope.requiresApproval;
@@ -191,40 +186,51 @@ function buildApprovalWaitState(envelope) {
191
186
  ...approval?.approvalId ? { approvalId: approval.approvalId } : {}
192
187
  };
193
188
  }
194
- function applyEnvelopeToFlow(params) {
195
- const { taskFlow, flow, envelope, waitingStep } = params;
196
- const flowMutation = {
197
- flowId: flow.flowId,
198
- expectedRevision: flow.revision
199
- };
200
- if (!envelope.ok) return taskFlow.fail(flowMutation);
201
- if (envelope.status === "needs_approval") return taskFlow.setWaiting({
202
- ...flowMutation,
203
- currentStep: waitingStep,
204
- waitJson: buildApprovalWaitState(envelope)
205
- });
206
- return taskFlow.finish(flowMutation);
207
- }
208
- async function executeManagedLobsterFlow(params, flow, failureFlowId = flow.flowId) {
189
+ async function executeManagedLobsterFlow(params, flow) {
209
190
  try {
210
191
  const envelope = await params.runner.run(params.runnerParams);
211
- const mutation = applyEnvelopeToFlow({
212
- taskFlow: params.taskFlow,
213
- flow,
214
- envelope,
215
- waitingStep: params.waitingStep ?? "await_lobster_approval"
216
- });
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
+ };
217
219
  if (!envelope.ok) return {
218
220
  ok: false,
219
221
  flow,
220
- mutation,
222
+ mutation: params.taskFlow.fail(flowMutation),
221
223
  error: new Error(envelope.error.message)
222
224
  };
223
225
  return {
224
226
  ok: true,
225
227
  envelope,
226
228
  flow,
227
- 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)
228
234
  };
229
235
  } catch (error) {
230
236
  const err = error instanceof Error ? error : new Error(String(error));
@@ -233,7 +239,7 @@ async function executeManagedLobsterFlow(params, flow, failureFlowId = flow.flow
233
239
  ok: false,
234
240
  flow,
235
241
  mutation: params.taskFlow.fail({
236
- flowId: failureFlowId,
242
+ flowId: flow.flowId,
237
243
  expectedRevision: flow.revision
238
244
  }),
239
245
  error: err
@@ -273,7 +279,7 @@ async function resumeManagedLobsterFlow(params) {
273
279
  mutation: resumed,
274
280
  error: /* @__PURE__ */ new Error(`TaskFlow resume failed: ${resumed.code}`)
275
281
  };
276
- return await executeManagedLobsterFlow(params, resumed.flow, params.flowId);
282
+ return await executeManagedLobsterFlow(params, resumed.flow);
277
283
  }
278
284
  //#endregion
279
285
  //#region extensions/lobster/src/lobster-tool.ts
@@ -305,28 +311,29 @@ function parseOptionalFlowStateJson(value) {
305
311
  function isEmptyJsonObject(value) {
306
312
  return value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
307
313
  }
308
- function parseRunFlowParams(params) {
309
- const controllerId = readOptionalTrimmedString(params.flowControllerId, "flowControllerId");
310
- const goal = readOptionalTrimmedString(params.flowGoal, "flowGoal");
311
- const currentStep = readOptionalTrimmedString(params.flowCurrentStep, "flowCurrentStep");
312
- const waitingStep = readOptionalTrimmedString(params.flowWaitingStep, "flowWaitingStep");
313
- const stateJson = parseOptionalFlowStateJson(params.flowStateJson);
314
- const resumeFlowId = readOptionalTrimmedString(params.flowId, "flowId");
315
- const resumeRevision = readOptionalNumber(params.flowExpectedRevision, "flowExpectedRevision");
316
- const stateJsonSignalsRunMode = stateJson !== void 0 && !isEmptyJsonObject(stateJson);
317
- if (resumeFlowId !== void 0 || resumeRevision !== void 0 && resumeRevision !== 0) throw new Error("run action does not accept flowId or flowExpectedRevision");
318
- if (!(controllerId !== void 0 || goal !== void 0 || currentStep !== void 0 || waitingStep !== void 0 || stateJsonSignalsRunMode)) return null;
319
- if (!controllerId) throw new Error("flowControllerId required when using managed TaskFlow run mode");
320
- if (!goal) throw new Error("flowGoal required when using managed TaskFlow run mode");
321
- return {
322
- controllerId,
323
- goal,
324
- ...currentStep ? { currentStep } : {},
325
- ...waitingStep ? { waitingStep } : {},
326
- ...stateJson !== void 0 ? { stateJson } : {}
327
- };
328
- }
329
- 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
+ }
330
337
  const flowId = readOptionalTrimmedString(params.flowId, "flowId");
331
338
  const expectedRevision = readOptionalNumber(params.flowExpectedRevision, "flowExpectedRevision");
332
339
  const currentStep = readOptionalTrimmedString(params.flowCurrentStep, "flowCurrentStep");
@@ -342,13 +349,21 @@ function parseResumeFlowParams(params) {
342
349
  if (!(flowId !== void 0 || expectedRevision !== void 0 && expectedRevision !== 0 || currentStep !== void 0 || waitingStep !== void 0)) return null;
343
350
  if (!flowId) throw new Error("flowId required when using managed TaskFlow resume mode");
344
351
  if (expectedRevision === void 0) throw new Error("flowExpectedRevision required when using managed TaskFlow resume mode");
345
- 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");
346
354
  if (approve === void 0) throw new Error("approve required when using managed TaskFlow resume mode");
347
355
  return {
356
+ action,
348
357
  flowId,
349
358
  expectedRevision,
350
359
  ...currentStep ? { currentStep } : {},
351
- ...waitingStep ? { waitingStep } : {}
360
+ ...waitingStep ? { waitingStep } : {},
361
+ runnerParams: {
362
+ ...runnerParams,
363
+ ...credentialParams,
364
+ action,
365
+ approve
366
+ }
352
367
  };
353
368
  }
354
369
  function resolveManagedFlowToolResult(result) {
@@ -407,30 +422,28 @@ function createLobsterTool(api, options) {
407
422
  maxStdoutBytes
408
423
  };
409
424
  const taskFlow = options?.taskFlow;
410
- if (action === "run") {
411
- const flowParams = parseRunFlowParams(params);
412
- if (flowParams) return resolveManagedFlowToolResult(await runManagedLobsterFlow({
413
- taskFlow: requireTaskFlowRuntime(taskFlow, "run"),
414
- runner,
415
- runnerParams,
416
- controllerId: flowParams.controllerId,
417
- goal: flowParams.goal,
418
- ...flowParams.stateJson !== void 0 ? { stateJson: flowParams.stateJson } : {},
419
- ...flowParams.currentStep ? { currentStep: flowParams.currentStep } : {},
420
- ...flowParams.waitingStep ? { waitingStep: flowParams.waitingStep } : {}
421
- }));
422
- } else {
423
- const flowParams = parseResumeFlowParams(params);
424
- if (flowParams) return resolveManagedFlowToolResult(await resumeManagedLobsterFlow({
425
- taskFlow: requireTaskFlowRuntime(taskFlow, "resume"),
426
- runner,
427
- runnerParams,
428
- flowId: flowParams.flowId,
429
- expectedRevision: flowParams.expectedRevision,
430
- ...flowParams.currentStep ? { currentStep: flowParams.currentStep } : {},
431
- ...flowParams.waitingStep ? { waitingStep: flowParams.waitingStep } : {}
432
- }));
433
- }
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
+ }));
434
447
  const envelope = await runner.run(runnerParams);
435
448
  if (!envelope.ok) throw new Error(envelope.error.message);
436
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;