skedyul 1.4.5 → 1.4.7

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.
package/dist/cli/index.js CHANGED
@@ -2904,6 +2904,16 @@ var AppAuthInvalidError = class extends Error {
2904
2904
  }
2905
2905
  };
2906
2906
 
2907
+ // src/ratelimit/errors.ts
2908
+ var RateLimitExceededError = class extends Error {
2909
+ constructor(retryAfterMs, message = "Rate limit exceeded. Please try again later.") {
2910
+ super(message);
2911
+ this.code = "RATE_LIMITED";
2912
+ this.name = "RateLimitExceededError";
2913
+ this.retryAfterMs = retryAfterMs;
2914
+ }
2915
+ };
2916
+
2907
2917
  // src/server/context-logger.ts
2908
2918
  var import_async_hooks3 = require("async_hooks");
2909
2919
  var logContextStorage = new import_async_hooks3.AsyncLocalStorage();
@@ -2981,6 +2991,7 @@ function buildToolMetadata(registry) {
2981
2991
  const rawRetries = tool.retries ?? toolConfig.retries;
2982
2992
  const timeout = typeof rawTimeout === "number" && rawTimeout > 0 ? rawTimeout : 1e4;
2983
2993
  const retries = typeof rawRetries === "number" && rawRetries >= 1 ? rawRetries : 1;
2994
+ const queueTouchPoints = tool.queueTouchPoints ?? toolConfig.queueTouchPoints;
2984
2995
  return {
2985
2996
  name: tool.name,
2986
2997
  displayName: tool.label || tool.name,
@@ -2990,10 +3001,12 @@ function buildToolMetadata(registry) {
2990
3001
  // Include timeout/retries at top-level for tools/list response (used by syncExecutableTools)
2991
3002
  timeout,
2992
3003
  retries,
3004
+ queueTouchPoints,
2993
3005
  config: {
2994
3006
  timeout,
2995
3007
  retries,
2996
- completionHints: toolConfig.completionHints
3008
+ completionHints: toolConfig.completionHints,
3009
+ queueTouchPoints
2997
3010
  }
2998
3011
  };
2999
3012
  });
@@ -3136,6 +3149,27 @@ function createCallToolHandler(registry, state, onMaxRequests) {
3136
3149
  cursor: functionResult.cursor
3137
3150
  };
3138
3151
  } catch (error) {
3152
+ if (error instanceof RateLimitExceededError) {
3153
+ return {
3154
+ success: false,
3155
+ output: null,
3156
+ billing: { credits: 0 },
3157
+ meta: {
3158
+ success: false,
3159
+ message: error.message,
3160
+ toolName
3161
+ },
3162
+ error: {
3163
+ code: "RATE_LIMITED",
3164
+ message: error.message,
3165
+ category: "external"
3166
+ },
3167
+ retry: {
3168
+ allowed: true,
3169
+ afterMs: error.retryAfterMs
3170
+ }
3171
+ };
3172
+ }
3139
3173
  if (error instanceof AppAuthInvalidError) {
3140
3174
  return {
3141
3175
  output: null,
@@ -3499,7 +3533,8 @@ function serializeConfig(config) {
3499
3533
  description: tool.description,
3500
3534
  // Read timeout/retries from top-level first, then fallback to config
3501
3535
  timeout: tool.timeout ?? tool.config?.timeout,
3502
- retries: tool.retries ?? tool.config?.retries
3536
+ retries: tool.retries ?? tool.config?.retries,
3537
+ queueTouchPoints: tool.queueTouchPoints ?? tool.config?.queueTouchPoints
3503
3538
  })) : [],
3504
3539
  webhooks: webhookRegistry ? Object.values(webhookRegistry).map((w) => ({
3505
3540
  name: w.name,
@@ -5824,17 +5859,37 @@ var CONFIG_FILE_NAMES = [
5824
5859
  "skedyul.config.mjs",
5825
5860
  "skedyul.config.cjs"
5826
5861
  ];
5862
+ function loadTypeScriptConfigModule(absolutePath) {
5863
+ try {
5864
+ require("tsx/cjs");
5865
+ delete require.cache[absolutePath];
5866
+ const module2 = require(absolutePath);
5867
+ return module2.default ?? module2;
5868
+ } catch (error) {
5869
+ throw new Error(
5870
+ `Cannot load TypeScript config: ${absolutePath}: ${error instanceof Error ? error.message : String(error)}`
5871
+ );
5872
+ }
5873
+ }
5827
5874
  async function transpileTypeScript(filePath) {
5828
5875
  const content = fs10.readFileSync(filePath, "utf-8");
5829
5876
  const configDir = path10.dirname(path10.resolve(filePath));
5830
5877
  let transpiled = content.replace(/import\s+type\s+\{[^}]+\}\s+from\s+['"][^'"]+['"]\s*;?\n?/g, "").replace(/import\s+\{\s*defineConfig\s*\}\s+from\s+['"]skedyul['"]\s*;?\n?/g, "").replace(/:\s*SkedyulConfig/g, "").replace(/export\s+default\s+/, "module.exports = ").replace(/defineConfig\s*\(\s*\{/, "{").replace(/\}\s*\)\s*;?\s*$/, "}");
5831
5878
  transpiled = transpiled.replace(
5832
5879
  /import\s+(\w+)\s+from\s+['"](\.[^'"]+)['"]\s*(?:with\s*\{[^}]*\})?/g,
5833
- (match, varName, relativePath) => {
5880
+ (_match, varName, relativePath) => {
5834
5881
  const absolutePath = path10.resolve(configDir, relativePath);
5835
5882
  return `const ${varName} = require('${absolutePath.replace(/\\/g, "/")}')`;
5836
5883
  }
5837
5884
  );
5885
+ transpiled = transpiled.replace(
5886
+ /import\s+\{\s*([^}]+)\s*\}\s+from\s+['"](\.[^'"]+)['"]\s*;?\n?/g,
5887
+ (_match, namedImports, relativePath) => {
5888
+ const absolutePath = path10.resolve(configDir, relativePath);
5889
+ return `const { ${namedImports.trim()} } = require('${absolutePath.replace(/\\/g, "/")}')
5890
+ `;
5891
+ }
5892
+ );
5838
5893
  transpiled = transpiled.replace(/import\s*\(\s*['"][^'"]+['"]\s*\)/g, "null");
5839
5894
  return transpiled;
5840
5895
  }
@@ -5845,16 +5900,9 @@ async function loadConfig(configPath) {
5845
5900
  }
5846
5901
  const isTypeScript = absolutePath.endsWith(".ts");
5847
5902
  try {
5848
- let moduleToLoad = absolutePath;
5849
5903
  if (isTypeScript) {
5850
- const transpiled = await transpileTypeScript(absolutePath);
5851
- const tempDir = os2.tmpdir();
5852
- const tempFile = path10.join(tempDir, `skedyul-config-${Date.now()}.cjs`);
5853
- fs10.writeFileSync(tempFile, transpiled);
5854
- moduleToLoad = tempFile;
5855
5904
  try {
5856
- const module3 = require(moduleToLoad);
5857
- const config2 = module3.default || module3;
5905
+ const config2 = loadTypeScriptConfigModule(absolutePath);
5858
5906
  if (!config2 || typeof config2 !== "object") {
5859
5907
  throw new Error("Config file must export a configuration object");
5860
5908
  }
@@ -5862,16 +5910,31 @@ async function loadConfig(configPath) {
5862
5910
  throw new Error('Config must have a "name" property');
5863
5911
  }
5864
5912
  return config2;
5865
- } finally {
5913
+ } catch (tsxError) {
5914
+ const transpiled = await transpileTypeScript(absolutePath);
5915
+ const tempFile = path10.join(os2.tmpdir(), `skedyul-config-${Date.now()}.cjs`);
5916
+ fs10.writeFileSync(tempFile, transpiled);
5866
5917
  try {
5867
- fs10.unlinkSync(tempFile);
5868
- } catch {
5918
+ const module3 = require(tempFile);
5919
+ const config2 = module3.default || module3;
5920
+ if (!config2 || typeof config2 !== "object") {
5921
+ throw new Error("Config file must export a configuration object");
5922
+ }
5923
+ if (!config2.name || typeof config2.name !== "string") {
5924
+ throw new Error('Config must have a "name" property');
5925
+ }
5926
+ return config2;
5927
+ } finally {
5928
+ try {
5929
+ fs10.unlinkSync(tempFile);
5930
+ } catch {
5931
+ }
5869
5932
  }
5870
5933
  }
5871
5934
  }
5872
5935
  const module2 = await import(
5873
5936
  /* webpackIgnore: true */
5874
- moduleToLoad
5937
+ absolutePath
5875
5938
  );
5876
5939
  const config = module2.default || module2;
5877
5940
  if (!config || typeof config !== "object") {
@@ -9624,7 +9687,9 @@ var ThreadEventTypeSchema = import_v44.z.enum([
9624
9687
  "thread.workflow.completed",
9625
9688
  // Scheduled events
9626
9689
  "thread.follow_up.due",
9627
- "thread.reminder.due"
9690
+ "thread.reminder.due",
9691
+ // Signal events
9692
+ "thread.signal.created"
9628
9693
  ]);
9629
9694
  var CustomEventTypeSchema = import_v44.z.string().regex(/^custom\.[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$/, {
9630
9695
  message: "Custom event type must match pattern: custom.{namespace}.{event}"
@@ -13,4 +13,28 @@ export interface AppEventDefinition {
13
13
  description?: string;
14
14
  /** Optional grouping label (Members, Bookings, etc.) */
15
15
  group?: string;
16
+ /** Optional Lucide icon name for pickers */
17
+ icon?: string;
18
+ /**
19
+ * Example flat domain payload for liquid context reference (e.g. glofox_id, phone, …).
20
+ * Not the full emit payload — studio/branch metadata is added at emit time.
21
+ */
22
+ examplePayload?: Record<string, unknown>;
23
+ /**
24
+ * Typed context field tree for liquid input path browsing (data.* paths).
25
+ * When set, subscribers see explicit fields like data.phone.
26
+ */
27
+ contextFields?: AppEventContextField[];
28
+ /**
29
+ * Workflow input type for app-event payloads, e.g. @app/bft/member/updated.
30
+ * Workflows declare this on inputs.data and subscribe with {{ data }}.
31
+ */
32
+ workflowInputType?: string;
33
+ }
34
+ export interface AppEventContextField {
35
+ path: string;
36
+ label: string;
37
+ type?: string;
38
+ description?: string;
39
+ children?: AppEventContextField[];
16
40
  }
@@ -307,6 +307,16 @@ var AppAuthInvalidError = class extends Error {
307
307
  }
308
308
  };
309
309
 
310
+ // src/ratelimit/errors.ts
311
+ var RateLimitExceededError = class extends Error {
312
+ constructor(retryAfterMs, message = "Rate limit exceeded. Please try again later.") {
313
+ super(message);
314
+ this.code = "RATE_LIMITED";
315
+ this.name = "RateLimitExceededError";
316
+ this.retryAfterMs = retryAfterMs;
317
+ }
318
+ };
319
+
310
320
  // src/server/context-logger.ts
311
321
  var import_async_hooks3 = require("async_hooks");
312
322
  var logContextStorage = new import_async_hooks3.AsyncLocalStorage();
@@ -404,6 +414,7 @@ function buildToolMetadata(registry) {
404
414
  const rawRetries = tool.retries ?? toolConfig.retries;
405
415
  const timeout = typeof rawTimeout === "number" && rawTimeout > 0 ? rawTimeout : 1e4;
406
416
  const retries = typeof rawRetries === "number" && rawRetries >= 1 ? rawRetries : 1;
417
+ const queueTouchPoints = tool.queueTouchPoints ?? toolConfig.queueTouchPoints;
407
418
  return {
408
419
  name: tool.name,
409
420
  displayName: tool.label || tool.name,
@@ -413,10 +424,12 @@ function buildToolMetadata(registry) {
413
424
  // Include timeout/retries at top-level for tools/list response (used by syncExecutableTools)
414
425
  timeout,
415
426
  retries,
427
+ queueTouchPoints,
416
428
  config: {
417
429
  timeout,
418
430
  retries,
419
- completionHints: toolConfig.completionHints
431
+ completionHints: toolConfig.completionHints,
432
+ queueTouchPoints
420
433
  }
421
434
  };
422
435
  });
@@ -559,6 +572,27 @@ function createCallToolHandler(registry, state, onMaxRequests) {
559
572
  cursor: functionResult.cursor
560
573
  };
561
574
  } catch (error) {
575
+ if (error instanceof RateLimitExceededError) {
576
+ return {
577
+ success: false,
578
+ output: null,
579
+ billing: { credits: 0 },
580
+ meta: {
581
+ success: false,
582
+ message: error.message,
583
+ toolName
584
+ },
585
+ error: {
586
+ code: "RATE_LIMITED",
587
+ message: error.message,
588
+ category: "external"
589
+ },
590
+ retry: {
591
+ allowed: true,
592
+ afterMs: error.retryAfterMs
593
+ }
594
+ };
595
+ }
562
596
  if (error instanceof AppAuthInvalidError) {
563
597
  return {
564
598
  output: null,
@@ -922,7 +956,8 @@ function serializeConfig(config) {
922
956
  description: tool.description,
923
957
  // Read timeout/retries from top-level first, then fallback to config
924
958
  timeout: tool.timeout ?? tool.config?.timeout,
925
- retries: tool.retries ?? tool.config?.retries
959
+ retries: tool.retries ?? tool.config?.retries,
960
+ queueTouchPoints: tool.queueTouchPoints ?? tool.config?.queueTouchPoints
926
961
  })) : [],
927
962
  webhooks: webhookRegistry ? Object.values(webhookRegistry).map((w) => ({
928
963
  name: w.name,
@@ -391,7 +391,9 @@ var ThreadEventTypeSchema = z3.enum([
391
391
  "thread.workflow.completed",
392
392
  // Scheduled events
393
393
  "thread.follow_up.due",
394
- "thread.reminder.due"
394
+ "thread.reminder.due",
395
+ // Signal events
396
+ "thread.signal.created"
395
397
  ]);
396
398
  var CustomEventTypeSchema = z3.string().regex(/^custom\.[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$/, {
397
399
  message: "Custom event type must match pattern: custom.{namespace}.{event}"
@@ -3369,6 +3371,57 @@ var AppAuthInvalidError = class extends Error {
3369
3371
  }
3370
3372
  };
3371
3373
 
3374
+ // src/ratelimit/errors.ts
3375
+ var QueueContextError = class extends Error {
3376
+ constructor(message) {
3377
+ super(message);
3378
+ this.code = "QUEUE_CONTEXT_ERROR";
3379
+ this.name = "QueueContextError";
3380
+ }
3381
+ };
3382
+ var QueueNotFoundError = class extends Error {
3383
+ constructor(queueName) {
3384
+ super(`Queue "${queueName}" is not defined in skedyul.config queues`);
3385
+ this.code = "QUEUE_NOT_FOUND";
3386
+ this.name = "QueueNotFoundError";
3387
+ }
3388
+ };
3389
+ var QueuedFetchExhaustedError = class extends Error {
3390
+ constructor(attempts, maxRetries, causeError) {
3391
+ super(
3392
+ `queuedFetch exhausted retries after ${attempts} attempts (maxRetries=${maxRetries})`
3393
+ );
3394
+ this.code = "QUEUED_FETCH_EXHAUSTED";
3395
+ this.name = "QueuedFetchExhaustedError";
3396
+ this.attempts = attempts;
3397
+ this.maxRetries = maxRetries;
3398
+ this.causeError = causeError;
3399
+ }
3400
+ };
3401
+ var RequeueOutsideContextError = class extends Error {
3402
+ constructor() {
3403
+ super("requeue() can only be called inside an active queuedFetch operation");
3404
+ this.code = "REQUEUE_OUTSIDE_CONTEXT";
3405
+ this.name = "RequeueOutsideContextError";
3406
+ }
3407
+ };
3408
+ var RateLimitBackendError = class extends Error {
3409
+ constructor(message, statusCode) {
3410
+ super(message);
3411
+ this.code = "RATE_LIMIT_BACKEND_ERROR";
3412
+ this.name = "RateLimitBackendError";
3413
+ this.statusCode = statusCode;
3414
+ }
3415
+ };
3416
+ var RateLimitExceededError = class extends Error {
3417
+ constructor(retryAfterMs, message = "Rate limit exceeded. Please try again later.") {
3418
+ super(message);
3419
+ this.code = "RATE_LIMITED";
3420
+ this.name = "RateLimitExceededError";
3421
+ this.retryAfterMs = retryAfterMs;
3422
+ }
3423
+ };
3424
+
3372
3425
  // src/server/context-logger.ts
3373
3426
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
3374
3427
  var logContextStorage = new AsyncLocalStorage3();
@@ -3466,6 +3519,7 @@ function buildToolMetadata(registry) {
3466
3519
  const rawRetries = tool.retries ?? toolConfig.retries;
3467
3520
  const timeout = typeof rawTimeout === "number" && rawTimeout > 0 ? rawTimeout : 1e4;
3468
3521
  const retries = typeof rawRetries === "number" && rawRetries >= 1 ? rawRetries : 1;
3522
+ const queueTouchPoints = tool.queueTouchPoints ?? toolConfig.queueTouchPoints;
3469
3523
  return {
3470
3524
  name: tool.name,
3471
3525
  displayName: tool.label || tool.name,
@@ -3475,10 +3529,12 @@ function buildToolMetadata(registry) {
3475
3529
  // Include timeout/retries at top-level for tools/list response (used by syncExecutableTools)
3476
3530
  timeout,
3477
3531
  retries,
3532
+ queueTouchPoints,
3478
3533
  config: {
3479
3534
  timeout,
3480
3535
  retries,
3481
- completionHints: toolConfig.completionHints
3536
+ completionHints: toolConfig.completionHints,
3537
+ queueTouchPoints
3482
3538
  }
3483
3539
  };
3484
3540
  });
@@ -3621,6 +3677,27 @@ function createCallToolHandler(registry, state, onMaxRequests) {
3621
3677
  cursor: functionResult.cursor
3622
3678
  };
3623
3679
  } catch (error) {
3680
+ if (error instanceof RateLimitExceededError) {
3681
+ return {
3682
+ success: false,
3683
+ output: null,
3684
+ billing: { credits: 0 },
3685
+ meta: {
3686
+ success: false,
3687
+ message: error.message,
3688
+ toolName
3689
+ },
3690
+ error: {
3691
+ code: "RATE_LIMITED",
3692
+ message: error.message,
3693
+ category: "external"
3694
+ },
3695
+ retry: {
3696
+ allowed: true,
3697
+ afterMs: error.retryAfterMs
3698
+ }
3699
+ };
3700
+ }
3624
3701
  if (error instanceof AppAuthInvalidError) {
3625
3702
  return {
3626
3703
  output: null,
@@ -3984,7 +4061,8 @@ function serializeConfig(config) {
3984
4061
  description: tool.description,
3985
4062
  // Read timeout/retries from top-level first, then fallback to config
3986
4063
  timeout: tool.timeout ?? tool.config?.timeout,
3987
- retries: tool.retries ?? tool.config?.retries
4064
+ retries: tool.retries ?? tool.config?.retries,
4065
+ queueTouchPoints: tool.queueTouchPoints ?? tool.config?.queueTouchPoints
3988
4066
  })) : [],
3989
4067
  webhooks: webhookRegistry ? Object.values(webhookRegistry).map((w) => ({
3990
4068
  name: w.name,
@@ -5406,17 +5484,37 @@ var CONFIG_FILE_NAMES = [
5406
5484
  "skedyul.config.mjs",
5407
5485
  "skedyul.config.cjs"
5408
5486
  ];
5487
+ function loadTypeScriptConfigModule(absolutePath) {
5488
+ try {
5489
+ __require("tsx/cjs");
5490
+ delete __require.cache[absolutePath];
5491
+ const module = __require(absolutePath);
5492
+ return module.default ?? module;
5493
+ } catch (error) {
5494
+ throw new Error(
5495
+ `Cannot load TypeScript config: ${absolutePath}: ${error instanceof Error ? error.message : String(error)}`
5496
+ );
5497
+ }
5498
+ }
5409
5499
  async function transpileTypeScript(filePath) {
5410
5500
  const content = fs3.readFileSync(filePath, "utf-8");
5411
5501
  const configDir = path3.dirname(path3.resolve(filePath));
5412
5502
  let transpiled = content.replace(/import\s+type\s+\{[^}]+\}\s+from\s+['"][^'"]+['"]\s*;?\n?/g, "").replace(/import\s+\{\s*defineConfig\s*\}\s+from\s+['"]skedyul['"]\s*;?\n?/g, "").replace(/:\s*SkedyulConfig/g, "").replace(/export\s+default\s+/, "module.exports = ").replace(/defineConfig\s*\(\s*\{/, "{").replace(/\}\s*\)\s*;?\s*$/, "}");
5413
5503
  transpiled = transpiled.replace(
5414
5504
  /import\s+(\w+)\s+from\s+['"](\.[^'"]+)['"]\s*(?:with\s*\{[^}]*\})?/g,
5415
- (match, varName, relativePath) => {
5505
+ (_match, varName, relativePath) => {
5416
5506
  const absolutePath = path3.resolve(configDir, relativePath);
5417
5507
  return `const ${varName} = require('${absolutePath.replace(/\\/g, "/")}')`;
5418
5508
  }
5419
5509
  );
5510
+ transpiled = transpiled.replace(
5511
+ /import\s+\{\s*([^}]+)\s*\}\s+from\s+['"](\.[^'"]+)['"]\s*;?\n?/g,
5512
+ (_match, namedImports, relativePath) => {
5513
+ const absolutePath = path3.resolve(configDir, relativePath);
5514
+ return `const { ${namedImports.trim()} } = require('${absolutePath.replace(/\\/g, "/")}')
5515
+ `;
5516
+ }
5517
+ );
5420
5518
  transpiled = transpiled.replace(/import\s*\(\s*['"][^'"]+['"]\s*\)/g, "null");
5421
5519
  return transpiled;
5422
5520
  }
@@ -5427,16 +5525,9 @@ async function loadConfig(configPath) {
5427
5525
  }
5428
5526
  const isTypeScript = absolutePath.endsWith(".ts");
5429
5527
  try {
5430
- let moduleToLoad = absolutePath;
5431
5528
  if (isTypeScript) {
5432
- const transpiled = await transpileTypeScript(absolutePath);
5433
- const tempDir = os.tmpdir();
5434
- const tempFile = path3.join(tempDir, `skedyul-config-${Date.now()}.cjs`);
5435
- fs3.writeFileSync(tempFile, transpiled);
5436
- moduleToLoad = tempFile;
5437
5529
  try {
5438
- const module2 = __require(moduleToLoad);
5439
- const config2 = module2.default || module2;
5530
+ const config2 = loadTypeScriptConfigModule(absolutePath);
5440
5531
  if (!config2 || typeof config2 !== "object") {
5441
5532
  throw new Error("Config file must export a configuration object");
5442
5533
  }
@@ -5444,16 +5535,31 @@ async function loadConfig(configPath) {
5444
5535
  throw new Error('Config must have a "name" property');
5445
5536
  }
5446
5537
  return config2;
5447
- } finally {
5538
+ } catch (tsxError) {
5539
+ const transpiled = await transpileTypeScript(absolutePath);
5540
+ const tempFile = path3.join(os.tmpdir(), `skedyul-config-${Date.now()}.cjs`);
5541
+ fs3.writeFileSync(tempFile, transpiled);
5448
5542
  try {
5449
- fs3.unlinkSync(tempFile);
5450
- } catch {
5543
+ const module2 = __require(tempFile);
5544
+ const config2 = module2.default || module2;
5545
+ if (!config2 || typeof config2 !== "object") {
5546
+ throw new Error("Config file must export a configuration object");
5547
+ }
5548
+ if (!config2.name || typeof config2.name !== "string") {
5549
+ throw new Error('Config must have a "name" property');
5550
+ }
5551
+ return config2;
5552
+ } finally {
5553
+ try {
5554
+ fs3.unlinkSync(tempFile);
5555
+ } catch {
5556
+ }
5451
5557
  }
5452
5558
  }
5453
5559
  }
5454
5560
  const module = await import(
5455
5561
  /* webpackIgnore: true */
5456
- moduleToLoad
5562
+ absolutePath
5457
5563
  );
5458
5564
  const config = module.default || module;
5459
5565
  if (!config || typeof config !== "object") {
@@ -5504,49 +5610,6 @@ function getRequiredInstallEnvKeys(config) {
5504
5610
  return Object.entries(provision.env).filter(([, def]) => def.required).map(([key]) => key);
5505
5611
  }
5506
5612
 
5507
- // src/ratelimit/errors.ts
5508
- var QueueContextError = class extends Error {
5509
- constructor(message) {
5510
- super(message);
5511
- this.code = "QUEUE_CONTEXT_ERROR";
5512
- this.name = "QueueContextError";
5513
- }
5514
- };
5515
- var QueueNotFoundError = class extends Error {
5516
- constructor(queueName) {
5517
- super(`Queue "${queueName}" is not defined in skedyul.config queues`);
5518
- this.code = "QUEUE_NOT_FOUND";
5519
- this.name = "QueueNotFoundError";
5520
- }
5521
- };
5522
- var QueuedFetchExhaustedError = class extends Error {
5523
- constructor(attempts, maxRetries, causeError) {
5524
- super(
5525
- `queuedFetch exhausted retries after ${attempts} attempts (maxRetries=${maxRetries})`
5526
- );
5527
- this.code = "QUEUED_FETCH_EXHAUSTED";
5528
- this.name = "QueuedFetchExhaustedError";
5529
- this.attempts = attempts;
5530
- this.maxRetries = maxRetries;
5531
- this.causeError = causeError;
5532
- }
5533
- };
5534
- var RequeueOutsideContextError = class extends Error {
5535
- constructor() {
5536
- super("requeue() can only be called inside an active queuedFetch operation");
5537
- this.code = "REQUEUE_OUTSIDE_CONTEXT";
5538
- this.name = "RequeueOutsideContextError";
5539
- }
5540
- };
5541
- var RateLimitBackendError = class extends Error {
5542
- constructor(message, statusCode) {
5543
- super(message);
5544
- this.code = "RATE_LIMIT_BACKEND_ERROR";
5545
- this.name = "RateLimitBackendError";
5546
- this.statusCode = statusCode;
5547
- }
5548
- };
5549
-
5550
5613
  // src/ratelimit/resolve-queue-key.ts
5551
5614
  function resolveEndpointHandle(config, invocation) {
5552
5615
  if (config.endpoint) {
@@ -5990,11 +6053,30 @@ async function executeWithRetries(operation, maxRetries) {
5990
6053
  const timeoutMs = operation.resolved.config.timeout ?? 12e4;
5991
6054
  const retryDelayMs = operation.resolved.config.retryDelayMs ?? 1e3;
5992
6055
  const shouldRetryFn = getQueueConfigWithRetry(operation.resolved.name)?.shouldRetry ?? defaultShouldRetry;
5993
- const lease = await backend.acquire(
5994
- operation.resolved.queueKey,
5995
- operation.resolved.limits,
5996
- timeoutMs
5997
- );
6056
+ let lease;
6057
+ try {
6058
+ lease = await backend.acquire(
6059
+ operation.resolved.queueKey,
6060
+ operation.resolved.limits,
6061
+ timeoutMs
6062
+ );
6063
+ } catch (acquireError) {
6064
+ if (acquireError instanceof RateLimitBackendError && acquireError.statusCode === 408) {
6065
+ const retryAfterMs = Math.max(
6066
+ operation.resolved.limits.minTime ?? 1e3,
6067
+ operation.resolved.config.retryDelayMs ?? 1e3
6068
+ );
6069
+ throw new RateLimitExceededError(retryAfterMs);
6070
+ }
6071
+ if (acquireError instanceof Error && acquireError.message.includes("timed out")) {
6072
+ const retryAfterMs = Math.max(
6073
+ operation.resolved.limits.minTime ?? 1e3,
6074
+ operation.resolved.config.retryDelayMs ?? 1e3
6075
+ );
6076
+ throw new RateLimitExceededError(retryAfterMs);
6077
+ }
6078
+ throw acquireError;
6079
+ }
5998
6080
  operation.lease = lease;
5999
6081
  setActiveQueuedOperationLease(lease);
6000
6082
  try {
@@ -7565,6 +7647,7 @@ export {
7565
7647
  QueueNotFoundError,
7566
7648
  QueuedFetchExhaustedError,
7567
7649
  RateLimitBackendError,
7650
+ RateLimitExceededError,
7568
7651
  RelationshipCardinalitySchema,
7569
7652
  RelationshipDefinitionSchema,
7570
7653
  RelationshipExtensionSchema,
@@ -17,6 +17,7 @@ export declare const ThreadEventTypeSchema: z.ZodEnum<{
17
17
  "thread.workflow.completed": "thread.workflow.completed";
18
18
  "thread.follow_up.due": "thread.follow_up.due";
19
19
  "thread.reminder.due": "thread.reminder.due";
20
+ "thread.signal.created": "thread.signal.created";
20
21
  }>;
21
22
  export type ThreadEventType = z.infer<typeof ThreadEventTypeSchema>;
22
23
  /**
@@ -42,6 +43,7 @@ export declare const EventTypeSchema: z.ZodUnion<readonly [z.ZodEnum<{
42
43
  "thread.workflow.completed": "thread.workflow.completed";
43
44
  "thread.follow_up.due": "thread.follow_up.due";
44
45
  "thread.reminder.due": "thread.reminder.due";
46
+ "thread.signal.created": "thread.signal.created";
45
47
  }>, z.ZodString]>;
46
48
  export type EventType = z.infer<typeof EventTypeSchema>;
47
49
  /**
@@ -283,6 +285,7 @@ export declare const ThreadEventSchema: z.ZodObject<{
283
285
  "thread.workflow.completed": "thread.workflow.completed";
284
286
  "thread.follow_up.due": "thread.follow_up.due";
285
287
  "thread.reminder.due": "thread.reminder.due";
288
+ "thread.signal.created": "thread.signal.created";
286
289
  }>, z.ZodString]>;
287
290
  payload: z.ZodUnion<readonly [z.ZodObject<{
288
291
  threadId: z.ZodString;
@@ -388,6 +391,7 @@ export declare const CreateThreadEventInputSchema: z.ZodObject<{
388
391
  "thread.workflow.completed": "thread.workflow.completed";
389
392
  "thread.follow_up.due": "thread.follow_up.due";
390
393
  "thread.reminder.due": "thread.reminder.due";
394
+ "thread.signal.created": "thread.signal.created";
391
395
  }>, z.ZodString]>;
392
396
  payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
393
397
  emittedBy: z.ZodOptional<z.ZodString>;
@@ -411,6 +415,7 @@ export declare const EventSubscriptionSchema: z.ZodObject<{
411
415
  "thread.workflow.completed": "thread.workflow.completed";
412
416
  "thread.follow_up.due": "thread.follow_up.due";
413
417
  "thread.reminder.due": "thread.reminder.due";
418
+ "thread.signal.created": "thread.signal.created";
414
419
  }>, z.ZodString]>>;
415
420
  condition: z.ZodOptional<z.ZodString>;
416
421
  cancels: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
@@ -427,6 +432,7 @@ export declare const EventSubscriptionSchema: z.ZodObject<{
427
432
  "thread.workflow.completed": "thread.workflow.completed";
428
433
  "thread.follow_up.due": "thread.follow_up.due";
429
434
  "thread.reminder.due": "thread.reminder.due";
435
+ "thread.signal.created": "thread.signal.created";
430
436
  }>, z.ZodString]>>>;
431
437
  cancelCondition: z.ZodOptional<z.ZodString>;
432
438
  }, z.core.$strip>;
@@ -449,6 +455,7 @@ export declare const EventWaitSchema: z.ZodObject<{
449
455
  "thread.workflow.completed": "thread.workflow.completed";
450
456
  "thread.follow_up.due": "thread.follow_up.due";
451
457
  "thread.reminder.due": "thread.reminder.due";
458
+ "thread.signal.created": "thread.signal.created";
452
459
  }>, z.ZodString]>;
453
460
  timeout: z.ZodOptional<z.ZodString>;
454
461
  onTimeout: z.ZodOptional<z.ZodString>;
@@ -472,6 +479,7 @@ export declare const EventsConfigSchema: z.ZodObject<{
472
479
  "thread.workflow.completed": "thread.workflow.completed";
473
480
  "thread.follow_up.due": "thread.follow_up.due";
474
481
  "thread.reminder.due": "thread.reminder.due";
482
+ "thread.signal.created": "thread.signal.created";
475
483
  }>, z.ZodString]>>>;
476
484
  condition: z.ZodOptional<z.ZodString>;
477
485
  emits: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
@@ -488,6 +496,7 @@ export declare const EventsConfigSchema: z.ZodObject<{
488
496
  "thread.workflow.completed": "thread.workflow.completed";
489
497
  "thread.follow_up.due": "thread.follow_up.due";
490
498
  "thread.reminder.due": "thread.reminder.due";
499
+ "thread.signal.created": "thread.signal.created";
491
500
  }>, z.ZodString]>>>;
492
501
  waits: z.ZodOptional<z.ZodArray<z.ZodObject<{
493
502
  event: z.ZodUnion<readonly [z.ZodEnum<{
@@ -504,6 +513,7 @@ export declare const EventsConfigSchema: z.ZodObject<{
504
513
  "thread.workflow.completed": "thread.workflow.completed";
505
514
  "thread.follow_up.due": "thread.follow_up.due";
506
515
  "thread.reminder.due": "thread.reminder.due";
516
+ "thread.signal.created": "thread.signal.created";
507
517
  }>, z.ZodString]>;
508
518
  timeout: z.ZodOptional<z.ZodString>;
509
519
  onTimeout: z.ZodOptional<z.ZodString>;
@@ -522,6 +532,7 @@ export declare const EventsConfigSchema: z.ZodObject<{
522
532
  "thread.workflow.completed": "thread.workflow.completed";
523
533
  "thread.follow_up.due": "thread.follow_up.due";
524
534
  "thread.reminder.due": "thread.reminder.due";
535
+ "thread.signal.created": "thread.signal.created";
525
536
  }>, z.ZodString]>>>;
526
537
  cancelCondition: z.ZodOptional<z.ZodString>;
527
538
  }, z.core.$strip>;