@probelabs/visor 0.1.178 → 0.1.179-ee

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 (101) hide show
  1. package/defaults/assistant.yaml +38 -16
  2. package/defaults/skills/code-explorer.yaml +8 -8
  3. package/dist/agent-protocol/tasks-cli-handler.d.ts.map +1 -1
  4. package/dist/agent-protocol/track-execution.d.ts.map +1 -1
  5. package/dist/defaults/assistant.yaml +38 -16
  6. package/dist/defaults/skills/code-explorer.yaml +8 -8
  7. package/dist/frontends/slack-frontend.d.ts +6 -0
  8. package/dist/frontends/slack-frontend.d.ts.map +1 -1
  9. package/dist/index.js +2143 -108
  10. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  11. package/dist/sdk/{a2a-frontend-WYBMBBYG.mjs → a2a-frontend-KJFLIZJT.mjs} +2 -2
  12. package/dist/sdk/{check-provider-registry-3DZOXYIA.mjs → check-provider-registry-J27YX4IT.mjs} +5 -5
  13. package/dist/sdk/{check-provider-registry-T5J3H2N7.mjs → check-provider-registry-SYAHJMWJ.mjs} +5 -5
  14. package/dist/sdk/{chunk-6YGCACBF.mjs → chunk-CHARL3TY.mjs} +2 -2
  15. package/dist/sdk/{chunk-6YGCACBF.mjs.map → chunk-CHARL3TY.mjs.map} +1 -1
  16. package/dist/sdk/{chunk-B7XHSG3L.mjs → chunk-FTPLYUQ3.mjs} +163 -124
  17. package/dist/sdk/chunk-FTPLYUQ3.mjs.map +1 -0
  18. package/dist/sdk/{chunk-AK64Y6Y2.mjs → chunk-KWHLB5E3.mjs} +164 -125
  19. package/dist/sdk/chunk-KWHLB5E3.mjs.map +1 -0
  20. package/dist/sdk/{chunk-4ECMTCOM.mjs → chunk-OYHDBTKY.mjs} +2 -2
  21. package/dist/sdk/{chunk-ENSZDV3O.mjs → chunk-ZJYQMNPA.mjs} +3 -3
  22. package/dist/sdk/{failure-condition-evaluator-P3MS5DRL.mjs → failure-condition-evaluator-V2YGFRKO.mjs} +3 -3
  23. package/dist/sdk/{github-frontend-7RLEBJWG.mjs → github-frontend-4LM4NAZK.mjs} +3 -3
  24. package/dist/sdk/{host-I2TBBKD5.mjs → host-GBXJKNHL.mjs} +4 -4
  25. package/dist/sdk/{host-SE3MQHWG.mjs → host-XXPPPC76.mjs} +4 -4
  26. package/dist/sdk/knex-store-QCEW4I4R.mjs +527 -0
  27. package/dist/sdk/knex-store-QCEW4I4R.mjs.map +1 -0
  28. package/dist/sdk/loader-Q7K76ZIY.mjs +89 -0
  29. package/dist/sdk/loader-Q7K76ZIY.mjs.map +1 -0
  30. package/dist/sdk/opa-policy-engine-QCSSIMUF.mjs +655 -0
  31. package/dist/sdk/opa-policy-engine-QCSSIMUF.mjs.map +1 -0
  32. package/dist/sdk/{routing-2X6QF5IW.mjs → routing-YAYBIVPL.mjs} +4 -4
  33. package/dist/sdk/{schedule-tool-R6JJIDZ6.mjs → schedule-tool-OIVJDIDK.mjs} +5 -5
  34. package/dist/sdk/{schedule-tool-W4SQ334O.mjs → schedule-tool-WACIV77L.mjs} +5 -5
  35. package/dist/sdk/{schedule-tool-handler-AOMZV3Q3.mjs → schedule-tool-handler-ODKY57FO.mjs} +5 -5
  36. package/dist/sdk/{schedule-tool-handler-MPJFLH4J.mjs → schedule-tool-handler-SJF4ZKSB.mjs} +5 -5
  37. package/dist/sdk/sdk.js +1778 -328
  38. package/dist/sdk/sdk.js.map +1 -1
  39. package/dist/sdk/sdk.mjs +4 -4
  40. package/dist/sdk/{slack-frontend-XKSIOUXB.mjs → slack-frontend-OWD7BSWF.mjs} +22 -3
  41. package/dist/sdk/slack-frontend-OWD7BSWF.mjs.map +1 -0
  42. package/dist/sdk/{trace-helpers-4ADQ4GB3.mjs → trace-helpers-QL2B75AK.mjs} +2 -2
  43. package/dist/sdk/{track-execution-XTCZBUWX.mjs → track-execution-2Q66SXBZ.mjs} +20 -2
  44. package/dist/sdk/{track-execution-XTCZBUWX.mjs.map → track-execution-2Q66SXBZ.mjs.map} +1 -1
  45. package/dist/sdk/validator-XTZJZZJH.mjs +134 -0
  46. package/dist/sdk/validator-XTZJZZJH.mjs.map +1 -0
  47. package/dist/sdk/{workflow-check-provider-WHZP7BDF.mjs → workflow-check-provider-IXW6BMQA.mjs} +5 -5
  48. package/dist/sdk/{workflow-check-provider-WZN3B2S2.mjs → workflow-check-provider-UZQZYPOE.mjs} +5 -5
  49. package/dist/utils/workspace-manager.d.ts +2 -0
  50. package/dist/utils/workspace-manager.d.ts.map +1 -1
  51. package/package.json +2 -2
  52. package/dist/output/traces/run-2026-03-11T06-33-05-398Z.ndjson +0 -138
  53. package/dist/output/traces/run-2026-03-11T06-33-47-884Z.ndjson +0 -2296
  54. package/dist/sdk/a2a-frontend-U3PTNCLR.mjs +0 -1658
  55. package/dist/sdk/a2a-frontend-WYBMBBYG.mjs.map +0 -1
  56. package/dist/sdk/check-provider-registry-ZX76MY2L.mjs +0 -30
  57. package/dist/sdk/chunk-AK64Y6Y2.mjs.map +0 -1
  58. package/dist/sdk/chunk-ANEKFNAS.mjs +0 -45424
  59. package/dist/sdk/chunk-ANEKFNAS.mjs.map +0 -1
  60. package/dist/sdk/chunk-B7XHSG3L.mjs.map +0 -1
  61. package/dist/sdk/chunk-CDRKH5HH.mjs +0 -739
  62. package/dist/sdk/chunk-CDRKH5HH.mjs.map +0 -1
  63. package/dist/sdk/chunk-KG6PM4OL.mjs +0 -516
  64. package/dist/sdk/chunk-KG6PM4OL.mjs.map +0 -1
  65. package/dist/sdk/chunk-WZS4ARZB.mjs +0 -1502
  66. package/dist/sdk/chunk-WZS4ARZB.mjs.map +0 -1
  67. package/dist/sdk/failure-condition-evaluator-MMPKQGUA.mjs +0 -18
  68. package/dist/sdk/github-frontend-QTKOYB56.mjs +0 -1394
  69. package/dist/sdk/github-frontend-QTKOYB56.mjs.map +0 -1
  70. package/dist/sdk/routing-QHXBQS6X.mjs +0 -26
  71. package/dist/sdk/schedule-tool-MKT5FZ6J.mjs +0 -36
  72. package/dist/sdk/schedule-tool-handler-MPJFLH4J.mjs.map +0 -1
  73. package/dist/sdk/schedule-tool-handler-WY7WCFE5.mjs +0 -40
  74. package/dist/sdk/schedule-tool-handler-WY7WCFE5.mjs.map +0 -1
  75. package/dist/sdk/slack-frontend-XKSIOUXB.mjs.map +0 -1
  76. package/dist/sdk/trace-helpers-4ADQ4GB3.mjs.map +0 -1
  77. package/dist/sdk/trace-helpers-K47ZVJSU.mjs +0 -29
  78. package/dist/sdk/trace-helpers-K47ZVJSU.mjs.map +0 -1
  79. package/dist/sdk/workflow-check-provider-A3YH2UZJ.mjs +0 -30
  80. package/dist/sdk/workflow-check-provider-A3YH2UZJ.mjs.map +0 -1
  81. package/dist/sdk/workflow-check-provider-WHZP7BDF.mjs.map +0 -1
  82. package/dist/sdk/workflow-check-provider-WZN3B2S2.mjs.map +0 -1
  83. package/dist/traces/run-2026-03-11T06-33-05-398Z.ndjson +0 -138
  84. package/dist/traces/run-2026-03-11T06-33-47-884Z.ndjson +0 -2296
  85. /package/dist/sdk/{a2a-frontend-U3PTNCLR.mjs.map → a2a-frontend-KJFLIZJT.mjs.map} +0 -0
  86. /package/dist/sdk/{check-provider-registry-3DZOXYIA.mjs.map → check-provider-registry-J27YX4IT.mjs.map} +0 -0
  87. /package/dist/sdk/{check-provider-registry-T5J3H2N7.mjs.map → check-provider-registry-SYAHJMWJ.mjs.map} +0 -0
  88. /package/dist/sdk/{chunk-4ECMTCOM.mjs.map → chunk-OYHDBTKY.mjs.map} +0 -0
  89. /package/dist/sdk/{chunk-ENSZDV3O.mjs.map → chunk-ZJYQMNPA.mjs.map} +0 -0
  90. /package/dist/sdk/{check-provider-registry-ZX76MY2L.mjs.map → failure-condition-evaluator-V2YGFRKO.mjs.map} +0 -0
  91. /package/dist/sdk/{github-frontend-7RLEBJWG.mjs.map → github-frontend-4LM4NAZK.mjs.map} +0 -0
  92. /package/dist/sdk/{host-I2TBBKD5.mjs.map → host-GBXJKNHL.mjs.map} +0 -0
  93. /package/dist/sdk/{host-SE3MQHWG.mjs.map → host-XXPPPC76.mjs.map} +0 -0
  94. /package/dist/sdk/{failure-condition-evaluator-MMPKQGUA.mjs.map → routing-YAYBIVPL.mjs.map} +0 -0
  95. /package/dist/sdk/{failure-condition-evaluator-P3MS5DRL.mjs.map → schedule-tool-OIVJDIDK.mjs.map} +0 -0
  96. /package/dist/sdk/{routing-2X6QF5IW.mjs.map → schedule-tool-WACIV77L.mjs.map} +0 -0
  97. /package/dist/sdk/{routing-QHXBQS6X.mjs.map → schedule-tool-handler-ODKY57FO.mjs.map} +0 -0
  98. /package/dist/sdk/{schedule-tool-MKT5FZ6J.mjs.map → schedule-tool-handler-SJF4ZKSB.mjs.map} +0 -0
  99. /package/dist/sdk/{schedule-tool-R6JJIDZ6.mjs.map → trace-helpers-QL2B75AK.mjs.map} +0 -0
  100. /package/dist/sdk/{schedule-tool-W4SQ334O.mjs.map → workflow-check-provider-IXW6BMQA.mjs.map} +0 -0
  101. /package/dist/sdk/{schedule-tool-handler-AOMZV3Q3.mjs.map → workflow-check-provider-UZQZYPOE.mjs.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  fallback_ndjson_exports,
4
4
  init_fallback_ndjson,
5
5
  init_trace_helpers
6
- } from "./chunk-6YGCACBF.mjs";
6
+ } from "./chunk-CHARL3TY.mjs";
7
7
  import {
8
8
  addFailIfTriggered,
9
9
  init_metrics
@@ -736,4 +736,4 @@ export {
736
736
  failure_condition_evaluator_exports,
737
737
  init_failure_condition_evaluator
738
738
  };
739
- //# sourceMappingURL=chunk-4ECMTCOM.mjs.map
739
+ //# sourceMappingURL=chunk-OYHDBTKY.mjs.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  FailureConditionEvaluator,
3
3
  init_failure_condition_evaluator
4
- } from "./chunk-4ECMTCOM.mjs";
4
+ } from "./chunk-OYHDBTKY.mjs";
5
5
  import {
6
6
  addEvent,
7
7
  init_trace_helpers
8
- } from "./chunk-6YGCACBF.mjs";
8
+ } from "./chunk-CHARL3TY.mjs";
9
9
  import {
10
10
  createExtendedLiquid,
11
11
  init_liquid_extensions
@@ -1499,4 +1499,4 @@ export {
1499
1499
  evaluateTransitions,
1500
1500
  init_routing
1501
1501
  };
1502
- //# sourceMappingURL=chunk-ENSZDV3O.mjs.map
1502
+ //# sourceMappingURL=chunk-ZJYQMNPA.mjs.map
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  FailureConditionEvaluator,
3
3
  init_failure_condition_evaluator
4
- } from "./chunk-4ECMTCOM.mjs";
5
- import "./chunk-6YGCACBF.mjs";
4
+ } from "./chunk-OYHDBTKY.mjs";
5
+ import "./chunk-CHARL3TY.mjs";
6
6
  import "./chunk-6VVXKXTI.mjs";
7
7
  import "./chunk-34QX63WK.mjs";
8
8
  import "./chunk-25IC7KXZ.mjs";
@@ -15,4 +15,4 @@ init_failure_condition_evaluator();
15
15
  export {
16
16
  FailureConditionEvaluator
17
17
  };
18
- //# sourceMappingURL=failure-condition-evaluator-P3MS5DRL.mjs.map
18
+ //# sourceMappingURL=failure-condition-evaluator-V2YGFRKO.mjs.map
@@ -5,8 +5,8 @@ import {
5
5
  import {
6
6
  failure_condition_evaluator_exports,
7
7
  init_failure_condition_evaluator
8
- } from "./chunk-CDRKH5HH.mjs";
9
- import "./chunk-KG6PM4OL.mjs";
8
+ } from "./chunk-OYHDBTKY.mjs";
9
+ import "./chunk-CHARL3TY.mjs";
10
10
  import {
11
11
  generateShortHumanId,
12
12
  init_human_id
@@ -1391,4 +1391,4 @@ init_github_frontend();
1391
1391
  export {
1392
1392
  GitHubFrontend
1393
1393
  };
1394
- //# sourceMappingURL=github-frontend-7RLEBJWG.mjs.map
1394
+ //# sourceMappingURL=github-frontend-4LM4NAZK.mjs.map
@@ -24,10 +24,10 @@ var init_host = __esm({
24
24
  const { NdjsonSink } = await import("./ndjson-sink-FD2PSXGD.mjs");
25
25
  this.frontends.push(new NdjsonSink(spec.config));
26
26
  } else if (spec.name === "github") {
27
- const { GitHubFrontend } = await import("./github-frontend-QTKOYB56.mjs");
27
+ const { GitHubFrontend } = await import("./github-frontend-4LM4NAZK.mjs");
28
28
  this.frontends.push(new GitHubFrontend());
29
29
  } else if (spec.name === "slack") {
30
- const { SlackFrontend } = await import("./slack-frontend-XKSIOUXB.mjs");
30
+ const { SlackFrontend } = await import("./slack-frontend-OWD7BSWF.mjs");
31
31
  this.frontends.push(new SlackFrontend(spec.config));
32
32
  } else if (spec.name === "tui") {
33
33
  const { TuiFrontend } = await import("./tui-frontend-T56PZB67.mjs");
@@ -45,7 +45,7 @@ var init_host = __esm({
45
45
  const { TeamsFrontend } = await import("./teams-frontend-DNW5GZP3.mjs");
46
46
  this.frontends.push(new TeamsFrontend(spec.config));
47
47
  } else if (spec.name === "a2a") {
48
- const { A2AFrontend } = await import("./a2a-frontend-U3PTNCLR.mjs");
48
+ const { A2AFrontend } = await import("./a2a-frontend-KJFLIZJT.mjs");
49
49
  this.frontends.push(new A2AFrontend(spec.config));
50
50
  } else {
51
51
  this.log.warn(`[FrontendsHost] Unknown frontend '${spec.name}', skipping`);
@@ -84,4 +84,4 @@ export {
84
84
  FrontendsHost,
85
85
  isActiveFrontend
86
86
  };
87
- //# sourceMappingURL=host-I2TBBKD5.mjs.map
87
+ //# sourceMappingURL=host-GBXJKNHL.mjs.map
@@ -24,10 +24,10 @@ var init_host = __esm({
24
24
  const { NdjsonSink } = await import("./ndjson-sink-FD2PSXGD.mjs");
25
25
  this.frontends.push(new NdjsonSink(spec.config));
26
26
  } else if (spec.name === "github") {
27
- const { GitHubFrontend } = await import("./github-frontend-7RLEBJWG.mjs");
27
+ const { GitHubFrontend } = await import("./github-frontend-4LM4NAZK.mjs");
28
28
  this.frontends.push(new GitHubFrontend());
29
29
  } else if (spec.name === "slack") {
30
- const { SlackFrontend } = await import("./slack-frontend-XKSIOUXB.mjs");
30
+ const { SlackFrontend } = await import("./slack-frontend-OWD7BSWF.mjs");
31
31
  this.frontends.push(new SlackFrontend(spec.config));
32
32
  } else if (spec.name === "tui") {
33
33
  const { TuiFrontend } = await import("./tui-frontend-T56PZB67.mjs");
@@ -45,7 +45,7 @@ var init_host = __esm({
45
45
  const { TeamsFrontend } = await import("./teams-frontend-DNW5GZP3.mjs");
46
46
  this.frontends.push(new TeamsFrontend(spec.config));
47
47
  } else if (spec.name === "a2a") {
48
- const { A2AFrontend } = await import("./a2a-frontend-WYBMBBYG.mjs");
48
+ const { A2AFrontend } = await import("./a2a-frontend-KJFLIZJT.mjs");
49
49
  this.frontends.push(new A2AFrontend(spec.config));
50
50
  } else {
51
51
  this.log.warn(`[FrontendsHost] Unknown frontend '${spec.name}', skipping`);
@@ -84,4 +84,4 @@ export {
84
84
  FrontendsHost,
85
85
  isActiveFrontend
86
86
  };
87
- //# sourceMappingURL=host-SE3MQHWG.mjs.map
87
+ //# sourceMappingURL=host-XXPPPC76.mjs.map
@@ -0,0 +1,527 @@
1
+ import {
2
+ init_logger,
3
+ logger
4
+ } from "./chunk-FT3I25QV.mjs";
5
+ import "./chunk-UCMJJ3IM.mjs";
6
+ import {
7
+ __esm,
8
+ __require
9
+ } from "./chunk-J7LXIPZS.mjs";
10
+
11
+ // src/enterprise/scheduler/knex-store.ts
12
+ import * as fs from "fs";
13
+ import * as path from "path";
14
+ import { v4 as uuidv4 } from "uuid";
15
+ function toNum(val) {
16
+ if (val === null || val === void 0) return void 0;
17
+ return typeof val === "string" ? parseInt(val, 10) : val;
18
+ }
19
+ function safeJsonParse(value) {
20
+ if (!value) return void 0;
21
+ try {
22
+ return JSON.parse(value);
23
+ } catch {
24
+ return void 0;
25
+ }
26
+ }
27
+ function fromTriggerRow(row) {
28
+ return {
29
+ id: row.id,
30
+ creatorId: row.creator_id,
31
+ creatorContext: row.creator_context ?? void 0,
32
+ creatorName: row.creator_name ?? void 0,
33
+ description: row.description ?? void 0,
34
+ channels: safeJsonParse(row.channels),
35
+ fromUsers: safeJsonParse(row.from_users),
36
+ fromBots: row.from_bots === true || row.from_bots === 1,
37
+ contains: safeJsonParse(row.contains),
38
+ matchPattern: row.match_pattern ?? void 0,
39
+ threads: row.threads,
40
+ workflow: row.workflow,
41
+ inputs: safeJsonParse(row.inputs),
42
+ outputContext: safeJsonParse(row.output_context),
43
+ status: row.status,
44
+ enabled: row.enabled === true || row.enabled === 1,
45
+ createdAt: toNum(row.created_at)
46
+ };
47
+ }
48
+ function toTriggerInsertRow(trigger) {
49
+ return {
50
+ id: trigger.id,
51
+ creator_id: trigger.creatorId,
52
+ creator_context: trigger.creatorContext ?? null,
53
+ creator_name: trigger.creatorName ?? null,
54
+ description: trigger.description ?? null,
55
+ channels: trigger.channels ? JSON.stringify(trigger.channels) : null,
56
+ from_users: trigger.fromUsers ? JSON.stringify(trigger.fromUsers) : null,
57
+ from_bots: trigger.fromBots,
58
+ contains: trigger.contains ? JSON.stringify(trigger.contains) : null,
59
+ match_pattern: trigger.matchPattern ?? null,
60
+ threads: trigger.threads,
61
+ workflow: trigger.workflow,
62
+ inputs: trigger.inputs ? JSON.stringify(trigger.inputs) : null,
63
+ output_context: trigger.outputContext ? JSON.stringify(trigger.outputContext) : null,
64
+ status: trigger.status,
65
+ enabled: trigger.enabled,
66
+ created_at: trigger.createdAt
67
+ };
68
+ }
69
+ function fromDbRow(row) {
70
+ return {
71
+ id: row.id,
72
+ creatorId: row.creator_id,
73
+ creatorContext: row.creator_context ?? void 0,
74
+ creatorName: row.creator_name ?? void 0,
75
+ timezone: row.timezone,
76
+ schedule: row.schedule_expr,
77
+ runAt: toNum(row.run_at),
78
+ isRecurring: row.is_recurring === true || row.is_recurring === 1,
79
+ originalExpression: row.original_expression,
80
+ workflow: row.workflow ?? void 0,
81
+ workflowInputs: safeJsonParse(row.workflow_inputs),
82
+ outputContext: safeJsonParse(row.output_context),
83
+ status: row.status,
84
+ createdAt: toNum(row.created_at),
85
+ lastRunAt: toNum(row.last_run_at),
86
+ nextRunAt: toNum(row.next_run_at),
87
+ runCount: row.run_count,
88
+ failureCount: row.failure_count,
89
+ lastError: row.last_error ?? void 0,
90
+ previousResponse: row.previous_response ?? void 0
91
+ };
92
+ }
93
+ function toInsertRow(schedule) {
94
+ return {
95
+ id: schedule.id,
96
+ creator_id: schedule.creatorId,
97
+ creator_context: schedule.creatorContext ?? null,
98
+ creator_name: schedule.creatorName ?? null,
99
+ timezone: schedule.timezone,
100
+ schedule_expr: schedule.schedule,
101
+ run_at: schedule.runAt ?? null,
102
+ is_recurring: schedule.isRecurring,
103
+ original_expression: schedule.originalExpression,
104
+ workflow: schedule.workflow ?? null,
105
+ workflow_inputs: schedule.workflowInputs ? JSON.stringify(schedule.workflowInputs) : null,
106
+ output_context: schedule.outputContext ? JSON.stringify(schedule.outputContext) : null,
107
+ status: schedule.status,
108
+ created_at: schedule.createdAt,
109
+ last_run_at: schedule.lastRunAt ?? null,
110
+ next_run_at: schedule.nextRunAt ?? null,
111
+ run_count: schedule.runCount,
112
+ failure_count: schedule.failureCount,
113
+ last_error: schedule.lastError ?? null,
114
+ previous_response: schedule.previousResponse ?? null
115
+ };
116
+ }
117
+ var KnexStoreBackend;
118
+ var init_knex_store = __esm({
119
+ "src/enterprise/scheduler/knex-store.ts"() {
120
+ init_logger();
121
+ KnexStoreBackend = class {
122
+ knex = null;
123
+ driver;
124
+ connection;
125
+ constructor(driver, storageConfig, _haConfig) {
126
+ this.driver = driver;
127
+ this.connection = storageConfig.connection || {};
128
+ }
129
+ async initialize() {
130
+ const { createRequire } = __require("module");
131
+ const runtimeRequire = createRequire(__filename);
132
+ let knexFactory;
133
+ try {
134
+ knexFactory = runtimeRequire("knex");
135
+ } catch (err) {
136
+ const code = err?.code;
137
+ if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
138
+ throw new Error(
139
+ "knex is required for PostgreSQL/MySQL/MSSQL schedule storage. Install it with: npm install knex"
140
+ );
141
+ }
142
+ throw err;
143
+ }
144
+ const clientMap = {
145
+ postgresql: "pg",
146
+ mysql: "mysql2",
147
+ mssql: "tedious"
148
+ };
149
+ const client = clientMap[this.driver];
150
+ let connection;
151
+ if (this.connection.connection_string) {
152
+ connection = this.connection.connection_string;
153
+ } else if (this.driver === "mssql") {
154
+ connection = this.buildMssqlConnection();
155
+ } else {
156
+ connection = this.buildStandardConnection();
157
+ }
158
+ this.knex = knexFactory({
159
+ client,
160
+ connection,
161
+ pool: {
162
+ min: this.connection.pool?.min ?? 0,
163
+ max: this.connection.pool?.max ?? 10
164
+ }
165
+ });
166
+ await this.migrateSchema();
167
+ logger.info(`[KnexStore] Initialized (${this.driver})`);
168
+ }
169
+ buildStandardConnection() {
170
+ return {
171
+ host: this.connection.host || "localhost",
172
+ port: this.connection.port,
173
+ database: this.connection.database || "visor",
174
+ user: this.connection.user,
175
+ password: this.connection.password,
176
+ ssl: this.resolveSslConfig()
177
+ };
178
+ }
179
+ buildMssqlConnection() {
180
+ const ssl = this.connection.ssl;
181
+ const sslEnabled = ssl === true || typeof ssl === "object" && ssl.enabled !== false;
182
+ return {
183
+ server: this.connection.host || "localhost",
184
+ port: this.connection.port,
185
+ database: this.connection.database || "visor",
186
+ user: this.connection.user,
187
+ password: this.connection.password,
188
+ options: {
189
+ encrypt: sslEnabled,
190
+ trustServerCertificate: typeof ssl === "object" ? ssl.reject_unauthorized === false : !sslEnabled
191
+ }
192
+ };
193
+ }
194
+ resolveSslConfig() {
195
+ const ssl = this.connection.ssl;
196
+ if (ssl === false || ssl === void 0) return false;
197
+ if (ssl === true) return { rejectUnauthorized: true };
198
+ if (ssl.enabled === false) return false;
199
+ const result = {
200
+ rejectUnauthorized: ssl.reject_unauthorized !== false
201
+ };
202
+ if (ssl.ca) {
203
+ const caPath = this.validateSslPath(ssl.ca, "CA certificate");
204
+ result.ca = fs.readFileSync(caPath, "utf8");
205
+ }
206
+ if (ssl.cert) {
207
+ const certPath = this.validateSslPath(ssl.cert, "client certificate");
208
+ result.cert = fs.readFileSync(certPath, "utf8");
209
+ }
210
+ if (ssl.key) {
211
+ const keyPath = this.validateSslPath(ssl.key, "client key");
212
+ result.key = fs.readFileSync(keyPath, "utf8");
213
+ }
214
+ return result;
215
+ }
216
+ validateSslPath(filePath, label) {
217
+ const resolved = path.resolve(filePath);
218
+ if (resolved !== path.normalize(resolved)) {
219
+ throw new Error(`SSL ${label} path contains invalid sequences: ${filePath}`);
220
+ }
221
+ if (!fs.existsSync(resolved)) {
222
+ throw new Error(`SSL ${label} not found: ${filePath}`);
223
+ }
224
+ return resolved;
225
+ }
226
+ async shutdown() {
227
+ if (this.knex) {
228
+ await this.knex.destroy();
229
+ this.knex = null;
230
+ }
231
+ }
232
+ async migrateSchema() {
233
+ const knex = this.getKnex();
234
+ const exists = await knex.schema.hasTable("schedules");
235
+ if (!exists) {
236
+ await knex.schema.createTable("schedules", (table) => {
237
+ table.string("id", 36).primary();
238
+ table.string("creator_id", 255).notNullable().index();
239
+ table.string("creator_context", 255);
240
+ table.string("creator_name", 255);
241
+ table.string("timezone", 64).notNullable().defaultTo("UTC");
242
+ table.string("schedule_expr", 255);
243
+ table.bigInteger("run_at");
244
+ table.boolean("is_recurring").notNullable();
245
+ table.text("original_expression");
246
+ table.string("workflow", 255);
247
+ table.text("workflow_inputs");
248
+ table.text("output_context");
249
+ table.string("status", 20).notNullable().index();
250
+ table.bigInteger("created_at").notNullable();
251
+ table.bigInteger("last_run_at");
252
+ table.bigInteger("next_run_at");
253
+ table.integer("run_count").notNullable().defaultTo(0);
254
+ table.integer("failure_count").notNullable().defaultTo(0);
255
+ table.text("last_error");
256
+ table.text("previous_response");
257
+ table.index(["status", "next_run_at"]);
258
+ });
259
+ }
260
+ const triggersExist = await knex.schema.hasTable("message_triggers");
261
+ if (!triggersExist) {
262
+ await knex.schema.createTable("message_triggers", (table) => {
263
+ table.string("id", 36).primary();
264
+ table.string("creator_id", 255).notNullable().index();
265
+ table.string("creator_context", 255);
266
+ table.string("creator_name", 255);
267
+ table.text("description");
268
+ table.text("channels");
269
+ table.text("from_users");
270
+ table.boolean("from_bots").notNullable().defaultTo(false);
271
+ table.text("contains");
272
+ table.text("match_pattern");
273
+ table.string("threads", 20).notNullable().defaultTo("any");
274
+ table.string("workflow", 255).notNullable();
275
+ table.text("inputs");
276
+ table.text("output_context");
277
+ table.string("status", 20).notNullable().defaultTo("active").index();
278
+ table.boolean("enabled").notNullable().defaultTo(true);
279
+ table.bigInteger("created_at").notNullable();
280
+ });
281
+ }
282
+ const locksExist = await knex.schema.hasTable("scheduler_locks");
283
+ if (!locksExist) {
284
+ await knex.schema.createTable("scheduler_locks", (table) => {
285
+ table.string("lock_id", 255).primary();
286
+ table.string("node_id", 255).notNullable();
287
+ table.string("lock_token", 36).notNullable();
288
+ table.bigInteger("acquired_at").notNullable();
289
+ table.bigInteger("expires_at").notNullable();
290
+ });
291
+ }
292
+ }
293
+ getKnex() {
294
+ if (!this.knex) {
295
+ throw new Error("[KnexStore] Not initialized. Call initialize() first.");
296
+ }
297
+ return this.knex;
298
+ }
299
+ // --- CRUD ---
300
+ async create(schedule) {
301
+ const knex = this.getKnex();
302
+ const newSchedule = {
303
+ ...schedule,
304
+ id: uuidv4(),
305
+ createdAt: Date.now(),
306
+ runCount: 0,
307
+ failureCount: 0,
308
+ status: "active"
309
+ };
310
+ await knex("schedules").insert(toInsertRow(newSchedule));
311
+ logger.info(`[KnexStore] Created schedule ${newSchedule.id} for user ${newSchedule.creatorId}`);
312
+ return newSchedule;
313
+ }
314
+ async importSchedule(schedule) {
315
+ const knex = this.getKnex();
316
+ const existing = await knex("schedules").where("id", schedule.id).first();
317
+ if (existing) return;
318
+ await knex("schedules").insert(toInsertRow(schedule));
319
+ }
320
+ async get(id) {
321
+ const knex = this.getKnex();
322
+ const row = await knex("schedules").where("id", id).first();
323
+ return row ? fromDbRow(row) : void 0;
324
+ }
325
+ async update(id, patch) {
326
+ const knex = this.getKnex();
327
+ const existing = await knex("schedules").where("id", id).first();
328
+ if (!existing) return void 0;
329
+ const current = fromDbRow(existing);
330
+ const updated = { ...current, ...patch, id: current.id };
331
+ const row = toInsertRow(updated);
332
+ delete row.id;
333
+ await knex("schedules").where("id", id).update(row);
334
+ return updated;
335
+ }
336
+ async delete(id) {
337
+ const knex = this.getKnex();
338
+ const deleted = await knex("schedules").where("id", id).del();
339
+ if (deleted > 0) {
340
+ logger.info(`[KnexStore] Deleted schedule ${id}`);
341
+ return true;
342
+ }
343
+ return false;
344
+ }
345
+ // --- Queries ---
346
+ async getByCreator(creatorId) {
347
+ const knex = this.getKnex();
348
+ const rows = await knex("schedules").where("creator_id", creatorId);
349
+ return rows.map((r) => fromDbRow(r));
350
+ }
351
+ async getActiveSchedules() {
352
+ const knex = this.getKnex();
353
+ const rows = await knex("schedules").where("status", "active");
354
+ return rows.map((r) => fromDbRow(r));
355
+ }
356
+ async getDueSchedules(now) {
357
+ const ts = now ?? Date.now();
358
+ const knex = this.getKnex();
359
+ const bFalse = this.driver === "mssql" ? 0 : false;
360
+ const bTrue = this.driver === "mssql" ? 1 : true;
361
+ const rows = await knex("schedules").where("status", "active").andWhere(function() {
362
+ this.where(function() {
363
+ this.where("is_recurring", bFalse).whereNotNull("run_at").where("run_at", "<=", ts);
364
+ }).orWhere(function() {
365
+ this.where("is_recurring", bTrue).whereNotNull("next_run_at").where("next_run_at", "<=", ts);
366
+ });
367
+ });
368
+ return rows.map((r) => fromDbRow(r));
369
+ }
370
+ async findByWorkflow(creatorId, workflowName) {
371
+ const knex = this.getKnex();
372
+ const escaped = workflowName.toLowerCase().replace(/[%_\\]/g, "\\$&");
373
+ const pattern = `%${escaped}%`;
374
+ const rows = await knex("schedules").where("creator_id", creatorId).where("status", "active").whereRaw("LOWER(workflow) LIKE ? ESCAPE '\\'", [pattern]);
375
+ return rows.map((r) => fromDbRow(r));
376
+ }
377
+ async getAll() {
378
+ const knex = this.getKnex();
379
+ const rows = await knex("schedules");
380
+ return rows.map((r) => fromDbRow(r));
381
+ }
382
+ async getStats() {
383
+ const knex = this.getKnex();
384
+ const boolTrue = this.driver === "mssql" ? "1" : "true";
385
+ const boolFalse = this.driver === "mssql" ? "0" : "false";
386
+ const result = await knex("schedules").select(
387
+ knex.raw("COUNT(*) as total"),
388
+ knex.raw("SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active"),
389
+ knex.raw("SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused"),
390
+ knex.raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed"),
391
+ knex.raw("SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed"),
392
+ knex.raw(`SUM(CASE WHEN is_recurring = ${boolTrue} THEN 1 ELSE 0 END) as recurring`),
393
+ knex.raw(`SUM(CASE WHEN is_recurring = ${boolFalse} THEN 1 ELSE 0 END) as one_time`)
394
+ ).first();
395
+ return {
396
+ total: Number(result.total) || 0,
397
+ active: Number(result.active) || 0,
398
+ paused: Number(result.paused) || 0,
399
+ completed: Number(result.completed) || 0,
400
+ failed: Number(result.failed) || 0,
401
+ recurring: Number(result.recurring) || 0,
402
+ oneTime: Number(result.one_time) || 0
403
+ };
404
+ }
405
+ async validateLimits(creatorId, isRecurring, limits) {
406
+ const knex = this.getKnex();
407
+ if (limits.maxGlobal) {
408
+ const result = await knex("schedules").count("* as cnt").first();
409
+ if (Number(result?.cnt) >= limits.maxGlobal) {
410
+ throw new Error(`Global schedule limit reached (${limits.maxGlobal})`);
411
+ }
412
+ }
413
+ if (limits.maxPerUser) {
414
+ const result = await knex("schedules").where("creator_id", creatorId).count("* as cnt").first();
415
+ if (Number(result?.cnt) >= limits.maxPerUser) {
416
+ throw new Error(`You have reached the maximum number of schedules (${limits.maxPerUser})`);
417
+ }
418
+ }
419
+ if (isRecurring && limits.maxRecurringPerUser) {
420
+ const bTrue = this.driver === "mssql" ? 1 : true;
421
+ const result = await knex("schedules").where("creator_id", creatorId).where("is_recurring", bTrue).count("* as cnt").first();
422
+ if (Number(result?.cnt) >= limits.maxRecurringPerUser) {
423
+ throw new Error(
424
+ `You have reached the maximum number of recurring schedules (${limits.maxRecurringPerUser})`
425
+ );
426
+ }
427
+ }
428
+ }
429
+ // --- HA Distributed Locking (via scheduler_locks table) ---
430
+ async tryAcquireLock(lockId, nodeId, ttlSeconds) {
431
+ const knex = this.getKnex();
432
+ const now = Date.now();
433
+ const expiresAt = now + ttlSeconds * 1e3;
434
+ const token = uuidv4();
435
+ const updated = await knex("scheduler_locks").where("lock_id", lockId).where("expires_at", "<", now).update({
436
+ node_id: nodeId,
437
+ lock_token: token,
438
+ acquired_at: now,
439
+ expires_at: expiresAt
440
+ });
441
+ if (updated > 0) return token;
442
+ try {
443
+ await knex("scheduler_locks").insert({
444
+ lock_id: lockId,
445
+ node_id: nodeId,
446
+ lock_token: token,
447
+ acquired_at: now,
448
+ expires_at: expiresAt
449
+ });
450
+ return token;
451
+ } catch {
452
+ return null;
453
+ }
454
+ }
455
+ async releaseLock(lockId, lockToken) {
456
+ const knex = this.getKnex();
457
+ await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).del();
458
+ }
459
+ async renewLock(lockId, lockToken, ttlSeconds) {
460
+ const knex = this.getKnex();
461
+ const now = Date.now();
462
+ const expiresAt = now + ttlSeconds * 1e3;
463
+ const updated = await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).update({ acquired_at: now, expires_at: expiresAt });
464
+ return updated > 0;
465
+ }
466
+ async flush() {
467
+ }
468
+ // --- Message Trigger CRUD ---
469
+ async createTrigger(trigger) {
470
+ const knex = this.getKnex();
471
+ const newTrigger = {
472
+ ...trigger,
473
+ id: uuidv4(),
474
+ createdAt: Date.now()
475
+ };
476
+ await knex("message_triggers").insert(toTriggerInsertRow(newTrigger));
477
+ logger.info(`[KnexStore] Created trigger ${newTrigger.id} for user ${newTrigger.creatorId}`);
478
+ return newTrigger;
479
+ }
480
+ async getTrigger(id) {
481
+ const knex = this.getKnex();
482
+ const row = await knex("message_triggers").where("id", id).first();
483
+ return row ? fromTriggerRow(row) : void 0;
484
+ }
485
+ async updateTrigger(id, patch) {
486
+ const knex = this.getKnex();
487
+ const existing = await knex("message_triggers").where("id", id).first();
488
+ if (!existing) return void 0;
489
+ const current = fromTriggerRow(existing);
490
+ const updated = {
491
+ ...current,
492
+ ...patch,
493
+ id: current.id,
494
+ createdAt: current.createdAt
495
+ };
496
+ const row = toTriggerInsertRow(updated);
497
+ delete row.id;
498
+ await knex("message_triggers").where("id", id).update(row);
499
+ return updated;
500
+ }
501
+ async deleteTrigger(id) {
502
+ const knex = this.getKnex();
503
+ const deleted = await knex("message_triggers").where("id", id).del();
504
+ if (deleted > 0) {
505
+ logger.info(`[KnexStore] Deleted trigger ${id}`);
506
+ return true;
507
+ }
508
+ return false;
509
+ }
510
+ async getTriggersByCreator(creatorId) {
511
+ const knex = this.getKnex();
512
+ const rows = await knex("message_triggers").where("creator_id", creatorId);
513
+ return rows.map((r) => fromTriggerRow(r));
514
+ }
515
+ async getActiveTriggers() {
516
+ const knex = this.getKnex();
517
+ const rows = await knex("message_triggers").where("status", "active").where("enabled", this.driver === "mssql" ? 1 : true);
518
+ return rows.map((r) => fromTriggerRow(r));
519
+ }
520
+ };
521
+ }
522
+ });
523
+ init_knex_store();
524
+ export {
525
+ KnexStoreBackend
526
+ };
527
+ //# sourceMappingURL=knex-store-QCEW4I4R.mjs.map