@probelabs/visor 0.1.149 → 0.1.150
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/README.md +52 -1
- package/dist/909.index.js +27117 -0
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/docs/assistant-workflows.md +805 -0
- package/dist/docs/event-triggers.md +25 -0
- package/dist/docs/scheduler.md +156 -0
- package/dist/docs/slack-integration.md +48 -0
- package/dist/enterprise/scheduler/knex-store.d.ts +7 -1
- package/dist/enterprise/scheduler/knex-store.d.ts.map +1 -1
- package/dist/examples/code-talk-as-tool.yaml +76 -0
- package/dist/examples/code-talk-workflow.yaml +68 -0
- package/dist/examples/intent-router-workflow.yaml +66 -0
- package/dist/examples/slack-message-triggers.yaml +270 -0
- package/dist/generated/config-schema.d.ts +102 -7
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +116 -7
- package/dist/git-repository-analyzer.d.ts +8 -0
- package/dist/git-repository-analyzer.d.ts.map +1 -1
- package/dist/index.js +4030 -4735
- package/dist/output/traces/{run-2026-03-03T07-19-07-543Z.ndjson → run-2026-03-03T20-21-24-501Z.ndjson} +84 -84
- package/dist/{traces/run-2026-03-03T07-19-50-933Z.ndjson → output/traces/run-2026-03-03T20-22-08-701Z.ndjson} +1806 -1730
- package/dist/scheduler/message-trigger.d.ts +47 -0
- package/dist/scheduler/message-trigger.d.ts.map +1 -0
- package/dist/scheduler/schedule-store.d.ts +31 -1
- package/dist/scheduler/schedule-store.d.ts.map +1 -1
- package/dist/scheduler/schedule-tool.d.ts +17 -1
- package/dist/scheduler/schedule-tool.d.ts.map +1 -1
- package/dist/scheduler/store/sqlite-store.d.ts +7 -1
- package/dist/scheduler/store/sqlite-store.d.ts.map +1 -1
- package/dist/scheduler/store/types.d.ts +45 -0
- package/dist/scheduler/store/types.d.ts.map +1 -1
- package/dist/sdk/{check-provider-registry-LVLC4EPF.mjs → check-provider-registry-6D5CAX44.mjs} +6 -6
- package/dist/sdk/{check-provider-registry-X4OZJWPK.mjs → check-provider-registry-RRYBG6AU.mjs} +6 -6
- package/dist/sdk/{check-provider-registry-IYSUDKPB.mjs → check-provider-registry-YFC5KSJY.mjs} +6 -6
- package/dist/sdk/{chunk-V6GI4U2M.mjs → chunk-AADKUA6L.mjs} +585 -29
- package/dist/sdk/{chunk-6EXCUX7Y.mjs.map → chunk-AADKUA6L.mjs.map} +1 -1
- package/dist/sdk/{chunk-6EXCUX7Y.mjs → chunk-CKDFGNF4.mjs} +585 -29
- package/dist/sdk/{chunk-GFNXX64M.mjs.map → chunk-CKDFGNF4.mjs.map} +1 -1
- package/dist/sdk/{chunk-YYZAN5NK.mjs → chunk-FYK2DJK6.mjs} +106 -9
- package/dist/sdk/chunk-FYK2DJK6.mjs.map +1 -0
- package/dist/sdk/{chunk-RJLJUTSU.mjs → chunk-FZEQ744M.mjs} +2 -2
- package/dist/sdk/{chunk-Q6EPAJ6Z.mjs → chunk-GIAN7HCT.mjs} +3 -3
- package/dist/sdk/{chunk-CISJ6DJW.mjs → chunk-GLROSEYJ.mjs} +3 -3
- package/dist/sdk/{chunk-VLUGLWLA.mjs → chunk-H4HFH7HH.mjs} +3 -3
- package/dist/sdk/{chunk-VLUGLWLA.mjs.map → chunk-H4HFH7HH.mjs.map} +1 -1
- package/dist/sdk/{chunk-62TNF5PJ.mjs → chunk-PETLPNRA.mjs} +2 -2
- package/dist/sdk/{chunk-62TNF5PJ.mjs.map → chunk-PETLPNRA.mjs.map} +1 -1
- package/dist/sdk/{chunk-BR7DYA3S.mjs → chunk-SWO4W57C.mjs} +2 -2
- package/dist/sdk/{chunk-GFNXX64M.mjs → chunk-YY3KADY2.mjs} +585 -29
- package/dist/sdk/{chunk-V6GI4U2M.mjs.map → chunk-YY3KADY2.mjs.map} +1 -1
- package/dist/sdk/{config-KQH254CA.mjs → config-MTEIGCOQ.mjs} +2 -2
- package/dist/sdk/{failure-condition-evaluator-IVCTD4BZ.mjs → failure-condition-evaluator-P6QUFLIN.mjs} +3 -3
- package/dist/sdk/{failure-condition-evaluator-LZ2AG5PY.mjs → failure-condition-evaluator-XV2ZMFFY.mjs} +3 -3
- package/dist/sdk/{git-repository-analyzer-QFMW6WIS.mjs → git-repository-analyzer-TWNJUN42.mjs} +34 -3
- package/dist/sdk/git-repository-analyzer-TWNJUN42.mjs.map +1 -0
- package/dist/sdk/{github-frontend-DFT5G32K.mjs → github-frontend-A2R7D4N6.mjs} +3 -3
- package/dist/sdk/{github-frontend-S523EEJB.mjs → github-frontend-GSB2P5PE.mjs} +3 -3
- package/dist/sdk/{host-7YKRMOUJ.mjs → host-CLPM2WVQ.mjs} +2 -2
- package/dist/sdk/{host-H7IX4GBK.mjs → host-MR7L57QI.mjs} +2 -2
- package/dist/sdk/{routing-LU5PAREW.mjs → routing-KLVK2MJZ.mjs} +4 -4
- package/dist/sdk/{routing-ZMBKWMVI.mjs → routing-V3MYZAOH.mjs} +4 -4
- package/dist/sdk/{schedule-tool-EOMZFICZ.mjs → schedule-tool-HYM55K3H.mjs} +6 -6
- package/dist/sdk/{schedule-tool-NX75VKGA.mjs → schedule-tool-NYLNJUEW.mjs} +6 -6
- package/dist/sdk/{schedule-tool-CDVUSZEG.mjs → schedule-tool-PRXFAV4K.mjs} +6 -6
- package/dist/sdk/{schedule-tool-handler-3FJHDIPG.mjs → schedule-tool-handler-EFQIYD3W.mjs} +6 -6
- package/dist/sdk/{schedule-tool-handler-KKN7XJYT.mjs → schedule-tool-handler-HVWCEGQ6.mjs} +6 -6
- package/dist/sdk/{schedule-tool-handler-QNZG55DX.mjs → schedule-tool-handler-M5YI573R.mjs} +6 -6
- package/dist/sdk/sdk.d.mts +38 -1
- package/dist/sdk/sdk.d.ts +38 -1
- package/dist/sdk/sdk.js +706 -22
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +5 -5
- package/dist/sdk/{trace-helpers-EJUIOP6L.mjs → trace-helpers-6NSZBC35.mjs} +2 -2
- package/dist/sdk/{trace-helpers-6ROJR7N3.mjs → trace-helpers-TORF3JD5.mjs} +2 -2
- package/dist/sdk/{workflow-check-provider-AGZ5JY2I.mjs → workflow-check-provider-3F6CBHVD.mjs} +6 -6
- package/dist/sdk/{workflow-check-provider-PTNUWM5W.mjs → workflow-check-provider-OXHMLICJ.mjs} +6 -6
- package/dist/sdk/{workflow-check-provider-6ERNNCNA.mjs → workflow-check-provider-XLH7N4FV.mjs} +6 -6
- package/dist/slack/socket-runner.d.ts +14 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/test-runner/core/flow-stage.d.ts.map +1 -1
- package/dist/test-runner/fixture-loader.d.ts +1 -1
- package/dist/test-runner/fixture-loader.d.ts.map +1 -1
- package/dist/test-runner/index.d.ts.map +1 -1
- package/dist/test-runner/validator.d.ts.map +1 -1
- package/dist/traces/{run-2026-03-03T07-19-07-543Z.ndjson → run-2026-03-03T20-21-24-501Z.ndjson} +84 -84
- package/dist/{output/traces/run-2026-03-03T07-19-50-933Z.ndjson → traces/run-2026-03-03T20-22-08-701Z.ndjson} +1806 -1730
- package/dist/types/config.d.ts +38 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/workspace-manager.d.ts +4 -0
- package/dist/utils/workspace-manager.d.ts.map +1 -1
- package/dist/utils/worktree-manager.d.ts +15 -1
- package/dist/utils/worktree-manager.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/sdk/chunk-YYZAN5NK.mjs.map +0 -1
- package/dist/sdk/git-repository-analyzer-QFMW6WIS.mjs.map +0 -1
- /package/dist/sdk/{check-provider-registry-IYSUDKPB.mjs.map → check-provider-registry-6D5CAX44.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-LVLC4EPF.mjs.map → check-provider-registry-RRYBG6AU.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-X4OZJWPK.mjs.map → check-provider-registry-YFC5KSJY.mjs.map} +0 -0
- /package/dist/sdk/{chunk-BR7DYA3S.mjs.map → chunk-FZEQ744M.mjs.map} +0 -0
- /package/dist/sdk/{chunk-CISJ6DJW.mjs.map → chunk-GIAN7HCT.mjs.map} +0 -0
- /package/dist/sdk/{chunk-Q6EPAJ6Z.mjs.map → chunk-GLROSEYJ.mjs.map} +0 -0
- /package/dist/sdk/{chunk-RJLJUTSU.mjs.map → chunk-SWO4W57C.mjs.map} +0 -0
- /package/dist/sdk/{config-KQH254CA.mjs.map → config-MTEIGCOQ.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-IVCTD4BZ.mjs.map → failure-condition-evaluator-P6QUFLIN.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-LZ2AG5PY.mjs.map → failure-condition-evaluator-XV2ZMFFY.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-DFT5G32K.mjs.map → github-frontend-A2R7D4N6.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-S523EEJB.mjs.map → github-frontend-GSB2P5PE.mjs.map} +0 -0
- /package/dist/sdk/{host-7YKRMOUJ.mjs.map → host-CLPM2WVQ.mjs.map} +0 -0
- /package/dist/sdk/{host-H7IX4GBK.mjs.map → host-MR7L57QI.mjs.map} +0 -0
- /package/dist/sdk/{routing-LU5PAREW.mjs.map → routing-KLVK2MJZ.mjs.map} +0 -0
- /package/dist/sdk/{routing-ZMBKWMVI.mjs.map → routing-V3MYZAOH.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-CDVUSZEG.mjs.map → schedule-tool-HYM55K3H.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-EOMZFICZ.mjs.map → schedule-tool-NYLNJUEW.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-NX75VKGA.mjs.map → schedule-tool-PRXFAV4K.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-3FJHDIPG.mjs.map → schedule-tool-handler-EFQIYD3W.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-KKN7XJYT.mjs.map → schedule-tool-handler-HVWCEGQ6.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-QNZG55DX.mjs.map → schedule-tool-handler-M5YI573R.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-6ROJR7N3.mjs.map → trace-helpers-6NSZBC35.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-EJUIOP6L.mjs.map → trace-helpers-TORF3JD5.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-6ERNNCNA.mjs.map → workflow-check-provider-3F6CBHVD.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-AGZ5JY2I.mjs.map → workflow-check-provider-OXHMLICJ.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-PTNUWM5W.mjs.map → workflow-check-provider-XLH7N4FV.mjs.map} +0 -0
package/dist/sdk/sdk.js
CHANGED
|
@@ -646,7 +646,7 @@ var require_package = __commonJS({
|
|
|
646
646
|
"package.json"(exports2, module2) {
|
|
647
647
|
module2.exports = {
|
|
648
648
|
name: "@probelabs/visor",
|
|
649
|
-
version: "0.1.
|
|
649
|
+
version: "0.1.150",
|
|
650
650
|
main: "dist/index.js",
|
|
651
651
|
bin: {
|
|
652
652
|
visor: "./dist/index.js"
|
|
@@ -760,7 +760,7 @@ var require_package = __commonJS({
|
|
|
760
760
|
"@opentelemetry/sdk-node": "^0.203.0",
|
|
761
761
|
"@opentelemetry/sdk-trace-base": "^1.30.1",
|
|
762
762
|
"@opentelemetry/semantic-conventions": "^1.30.1",
|
|
763
|
-
"@probelabs/probe": "^0.6.0-
|
|
763
|
+
"@probelabs/probe": "^0.6.0-rc266",
|
|
764
764
|
"@types/commander": "^2.12.0",
|
|
765
765
|
"@types/uuid": "^10.0.0",
|
|
766
766
|
acorn: "^8.16.0",
|
|
@@ -7192,6 +7192,23 @@ function createProbeTracerAdapter(fallbackTracer) {
|
|
|
7192
7192
|
}
|
|
7193
7193
|
}
|
|
7194
7194
|
},
|
|
7195
|
+
recordToolResult: (toolName, result, success, durationMs, metadata) => {
|
|
7196
|
+
const resultStr = typeof result === "string" ? result : JSON.stringify(result || "");
|
|
7197
|
+
emitEvent("tool.result", {
|
|
7198
|
+
"tool.name": toolName,
|
|
7199
|
+
"tool.result": resultStr.substring(0, 1e4),
|
|
7200
|
+
"tool.result.length": resultStr.length,
|
|
7201
|
+
"tool.duration_ms": durationMs,
|
|
7202
|
+
"tool.success": success,
|
|
7203
|
+
...metadata || {}
|
|
7204
|
+
});
|
|
7205
|
+
if (fallback && typeof fallback.recordToolResult === "function") {
|
|
7206
|
+
try {
|
|
7207
|
+
fallback.recordToolResult(toolName, result, success, durationMs, metadata);
|
|
7208
|
+
} catch {
|
|
7209
|
+
}
|
|
7210
|
+
}
|
|
7211
|
+
},
|
|
7195
7212
|
recordDelegationEvent: (phase, attrs) => {
|
|
7196
7213
|
emitEvent(`delegation.${phase}`, attrs);
|
|
7197
7214
|
if (fallback && typeof fallback.recordDelegationEvent === "function") {
|
|
@@ -13146,7 +13163,7 @@ var init_config_schema = __esm({
|
|
|
13146
13163
|
description: "Arguments/inputs for the workflow"
|
|
13147
13164
|
},
|
|
13148
13165
|
overrides: {
|
|
13149
|
-
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-
|
|
13166
|
+
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E%3E",
|
|
13150
13167
|
description: "Override specific step configurations in the workflow"
|
|
13151
13168
|
},
|
|
13152
13169
|
output_mapping: {
|
|
@@ -13162,7 +13179,7 @@ var init_config_schema = __esm({
|
|
|
13162
13179
|
description: "Config file path - alternative to workflow ID (loads a Visor config file as workflow)"
|
|
13163
13180
|
},
|
|
13164
13181
|
workflow_overrides: {
|
|
13165
|
-
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-
|
|
13182
|
+
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E%3E",
|
|
13166
13183
|
description: "Alias for overrides - workflow step overrides (backward compatibility)"
|
|
13167
13184
|
},
|
|
13168
13185
|
ref: {
|
|
@@ -13344,7 +13361,8 @@ var init_config_schema = __esm({
|
|
|
13344
13361
|
"issue_comment",
|
|
13345
13362
|
"manual",
|
|
13346
13363
|
"schedule",
|
|
13347
|
-
"webhook_received"
|
|
13364
|
+
"webhook_received",
|
|
13365
|
+
"slack_message"
|
|
13348
13366
|
],
|
|
13349
13367
|
description: "Valid event triggers for checks"
|
|
13350
13368
|
},
|
|
@@ -13850,7 +13868,7 @@ var init_config_schema = __esm({
|
|
|
13850
13868
|
description: "Custom output name (defaults to workflow name)"
|
|
13851
13869
|
},
|
|
13852
13870
|
overrides: {
|
|
13853
|
-
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-
|
|
13871
|
+
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E%3E",
|
|
13854
13872
|
description: "Step overrides"
|
|
13855
13873
|
},
|
|
13856
13874
|
output_mapping: {
|
|
@@ -13865,13 +13883,13 @@ var init_config_schema = __esm({
|
|
|
13865
13883
|
"^x-": {}
|
|
13866
13884
|
}
|
|
13867
13885
|
},
|
|
13868
|
-
"Record<string,Partial<interface-src_types_config.ts-
|
|
13886
|
+
"Record<string,Partial<interface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255>>": {
|
|
13869
13887
|
type: "object",
|
|
13870
13888
|
additionalProperties: {
|
|
13871
|
-
$ref: "#/definitions/Partial%3Cinterface-src_types_config.ts-
|
|
13889
|
+
$ref: "#/definitions/Partial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E"
|
|
13872
13890
|
}
|
|
13873
13891
|
},
|
|
13874
|
-
"Partial<interface-src_types_config.ts-
|
|
13892
|
+
"Partial<interface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255>": {
|
|
13875
13893
|
type: "object",
|
|
13876
13894
|
additionalProperties: false
|
|
13877
13895
|
},
|
|
@@ -14753,6 +14771,10 @@ var init_config_schema = __esm({
|
|
|
14753
14771
|
cron: {
|
|
14754
14772
|
$ref: "#/definitions/Record%3Cstring%2CStaticCronJob%3E",
|
|
14755
14773
|
description: "Static cron jobs defined in configuration (always executed)"
|
|
14774
|
+
},
|
|
14775
|
+
on_message: {
|
|
14776
|
+
$ref: "#/definitions/Record%3Cstring%2CSlackMessageTrigger%3E",
|
|
14777
|
+
description: "Slack message triggers for reactive workflow execution"
|
|
14756
14778
|
}
|
|
14757
14779
|
},
|
|
14758
14780
|
additionalProperties: false,
|
|
@@ -15005,6 +15027,97 @@ var init_config_schema = __esm({
|
|
|
15005
15027
|
"^x-": {}
|
|
15006
15028
|
}
|
|
15007
15029
|
},
|
|
15030
|
+
"Record<string,SlackMessageTrigger>": {
|
|
15031
|
+
type: "object",
|
|
15032
|
+
additionalProperties: {
|
|
15033
|
+
$ref: "#/definitions/SlackMessageTrigger"
|
|
15034
|
+
}
|
|
15035
|
+
},
|
|
15036
|
+
SlackMessageTrigger: {
|
|
15037
|
+
type: "object",
|
|
15038
|
+
properties: {
|
|
15039
|
+
channels: {
|
|
15040
|
+
type: "array",
|
|
15041
|
+
items: {
|
|
15042
|
+
type: "string"
|
|
15043
|
+
},
|
|
15044
|
+
description: 'Channel IDs to monitor (supports wildcard suffix, e.g., "CENG*")'
|
|
15045
|
+
},
|
|
15046
|
+
from: {
|
|
15047
|
+
type: "array",
|
|
15048
|
+
items: {
|
|
15049
|
+
type: "string"
|
|
15050
|
+
},
|
|
15051
|
+
description: "Only trigger on messages from these user IDs"
|
|
15052
|
+
},
|
|
15053
|
+
from_bots: {
|
|
15054
|
+
type: "boolean",
|
|
15055
|
+
description: "Allow bot messages to trigger (default: false)"
|
|
15056
|
+
},
|
|
15057
|
+
contains: {
|
|
15058
|
+
type: "array",
|
|
15059
|
+
items: {
|
|
15060
|
+
type: "string"
|
|
15061
|
+
},
|
|
15062
|
+
description: "Keyword match - any keyword triggers (case-insensitive OR)"
|
|
15063
|
+
},
|
|
15064
|
+
match: {
|
|
15065
|
+
type: "string",
|
|
15066
|
+
description: "Regex pattern to match against message text"
|
|
15067
|
+
},
|
|
15068
|
+
threads: {
|
|
15069
|
+
type: "string",
|
|
15070
|
+
enum: ["root_only", "thread_only", "any"],
|
|
15071
|
+
description: "Thread scope filter (default: 'any')"
|
|
15072
|
+
},
|
|
15073
|
+
workflow: {
|
|
15074
|
+
type: "string",
|
|
15075
|
+
description: "Workflow/check ID to execute"
|
|
15076
|
+
},
|
|
15077
|
+
inputs: {
|
|
15078
|
+
$ref: "#/definitions/Record%3Cstring%2Cunknown%3E",
|
|
15079
|
+
description: "Optional workflow inputs"
|
|
15080
|
+
},
|
|
15081
|
+
output: {
|
|
15082
|
+
type: "object",
|
|
15083
|
+
properties: {
|
|
15084
|
+
type: {
|
|
15085
|
+
type: "string",
|
|
15086
|
+
enum: ["slack", "github", "webhook", "none"],
|
|
15087
|
+
description: "Output type: slack, github, webhook, or none"
|
|
15088
|
+
},
|
|
15089
|
+
target: {
|
|
15090
|
+
type: "string",
|
|
15091
|
+
description: "Target (channel name, repo, URL)"
|
|
15092
|
+
},
|
|
15093
|
+
thread_id: {
|
|
15094
|
+
type: "string",
|
|
15095
|
+
description: "Thread ID for threaded outputs"
|
|
15096
|
+
}
|
|
15097
|
+
},
|
|
15098
|
+
required: ["type"],
|
|
15099
|
+
additionalProperties: false,
|
|
15100
|
+
description: "Output destination configuration",
|
|
15101
|
+
patternProperties: {
|
|
15102
|
+
"^x-": {}
|
|
15103
|
+
}
|
|
15104
|
+
},
|
|
15105
|
+
description: {
|
|
15106
|
+
type: "string",
|
|
15107
|
+
description: "Description for logging/display"
|
|
15108
|
+
},
|
|
15109
|
+
enabled: {
|
|
15110
|
+
type: "boolean",
|
|
15111
|
+
description: "Enable/disable this trigger (default: true)"
|
|
15112
|
+
}
|
|
15113
|
+
},
|
|
15114
|
+
required: ["workflow"],
|
|
15115
|
+
additionalProperties: false,
|
|
15116
|
+
description: "Slack message trigger for reactive workflow execution Triggers workflows based on Slack messages matching configured filters",
|
|
15117
|
+
patternProperties: {
|
|
15118
|
+
"^x-": {}
|
|
15119
|
+
}
|
|
15120
|
+
},
|
|
15008
15121
|
PolicyConfig: {
|
|
15009
15122
|
type: "object",
|
|
15010
15123
|
properties: {
|
|
@@ -15146,7 +15259,8 @@ var init_config = __esm({
|
|
|
15146
15259
|
"issue_comment",
|
|
15147
15260
|
"manual",
|
|
15148
15261
|
"schedule",
|
|
15149
|
-
"webhook_received"
|
|
15262
|
+
"webhook_received",
|
|
15263
|
+
"slack_message"
|
|
15150
15264
|
];
|
|
15151
15265
|
ConfigManager = class {
|
|
15152
15266
|
validCheckTypes = [
|
|
@@ -17713,6 +17827,48 @@ function fromDbRow(row) {
|
|
|
17713
17827
|
previousResponse: row.previous_response ?? void 0
|
|
17714
17828
|
};
|
|
17715
17829
|
}
|
|
17830
|
+
function toTriggerRow(trigger) {
|
|
17831
|
+
return {
|
|
17832
|
+
id: trigger.id,
|
|
17833
|
+
creator_id: trigger.creatorId,
|
|
17834
|
+
creator_context: trigger.creatorContext ?? null,
|
|
17835
|
+
creator_name: trigger.creatorName ?? null,
|
|
17836
|
+
description: trigger.description ?? null,
|
|
17837
|
+
channels: trigger.channels ? JSON.stringify(trigger.channels) : null,
|
|
17838
|
+
from_users: trigger.fromUsers ? JSON.stringify(trigger.fromUsers) : null,
|
|
17839
|
+
from_bots: trigger.fromBots ? 1 : 0,
|
|
17840
|
+
contains: trigger.contains ? JSON.stringify(trigger.contains) : null,
|
|
17841
|
+
match_pattern: trigger.matchPattern ?? null,
|
|
17842
|
+
threads: trigger.threads,
|
|
17843
|
+
workflow: trigger.workflow,
|
|
17844
|
+
inputs: trigger.inputs ? JSON.stringify(trigger.inputs) : null,
|
|
17845
|
+
output_context: trigger.outputContext ? JSON.stringify(trigger.outputContext) : null,
|
|
17846
|
+
status: trigger.status,
|
|
17847
|
+
enabled: trigger.enabled ? 1 : 0,
|
|
17848
|
+
created_at: trigger.createdAt
|
|
17849
|
+
};
|
|
17850
|
+
}
|
|
17851
|
+
function fromTriggerRow(row) {
|
|
17852
|
+
return {
|
|
17853
|
+
id: row.id,
|
|
17854
|
+
creatorId: row.creator_id,
|
|
17855
|
+
creatorContext: row.creator_context ?? void 0,
|
|
17856
|
+
creatorName: row.creator_name ?? void 0,
|
|
17857
|
+
description: row.description ?? void 0,
|
|
17858
|
+
channels: safeJsonParse(row.channels),
|
|
17859
|
+
fromUsers: safeJsonParse(row.from_users),
|
|
17860
|
+
fromBots: row.from_bots === 1,
|
|
17861
|
+
contains: safeJsonParse(row.contains),
|
|
17862
|
+
matchPattern: row.match_pattern ?? void 0,
|
|
17863
|
+
threads: row.threads,
|
|
17864
|
+
workflow: row.workflow,
|
|
17865
|
+
inputs: safeJsonParse(row.inputs),
|
|
17866
|
+
outputContext: safeJsonParse(row.output_context),
|
|
17867
|
+
status: row.status,
|
|
17868
|
+
enabled: row.enabled === 1,
|
|
17869
|
+
createdAt: row.created_at
|
|
17870
|
+
};
|
|
17871
|
+
}
|
|
17716
17872
|
var import_path5, import_fs4, import_uuid, SqliteStoreBackend;
|
|
17717
17873
|
var init_sqlite_store = __esm({
|
|
17718
17874
|
"src/scheduler/store/sqlite-store.ts"() {
|
|
@@ -17805,6 +17961,32 @@ var init_sqlite_store = __esm({
|
|
|
17805
17961
|
acquired_at BIGINT NOT NULL,
|
|
17806
17962
|
expires_at BIGINT NOT NULL
|
|
17807
17963
|
);
|
|
17964
|
+
|
|
17965
|
+
CREATE TABLE IF NOT EXISTS message_triggers (
|
|
17966
|
+
id VARCHAR(36) PRIMARY KEY,
|
|
17967
|
+
creator_id VARCHAR(255) NOT NULL,
|
|
17968
|
+
creator_context VARCHAR(255),
|
|
17969
|
+
creator_name VARCHAR(255),
|
|
17970
|
+
description TEXT,
|
|
17971
|
+
channels TEXT,
|
|
17972
|
+
from_users TEXT,
|
|
17973
|
+
from_bots BOOLEAN NOT NULL DEFAULT 0,
|
|
17974
|
+
contains TEXT,
|
|
17975
|
+
match_pattern TEXT,
|
|
17976
|
+
threads VARCHAR(20) NOT NULL DEFAULT 'any',
|
|
17977
|
+
workflow VARCHAR(255) NOT NULL,
|
|
17978
|
+
inputs TEXT,
|
|
17979
|
+
output_context TEXT,
|
|
17980
|
+
status VARCHAR(20) NOT NULL DEFAULT 'active',
|
|
17981
|
+
enabled BOOLEAN NOT NULL DEFAULT 1,
|
|
17982
|
+
created_at BIGINT NOT NULL
|
|
17983
|
+
);
|
|
17984
|
+
|
|
17985
|
+
CREATE INDEX IF NOT EXISTS idx_message_triggers_creator
|
|
17986
|
+
ON message_triggers(creator_id);
|
|
17987
|
+
|
|
17988
|
+
CREATE INDEX IF NOT EXISTS idx_message_triggers_status
|
|
17989
|
+
ON message_triggers(status);
|
|
17808
17990
|
`);
|
|
17809
17991
|
}
|
|
17810
17992
|
// --- Helpers ---
|
|
@@ -18086,6 +18268,114 @@ var init_sqlite_store = __esm({
|
|
|
18086
18268
|
}
|
|
18087
18269
|
async flush() {
|
|
18088
18270
|
}
|
|
18271
|
+
// --- Message Triggers ---
|
|
18272
|
+
async createTrigger(trigger) {
|
|
18273
|
+
const db = this.getDb();
|
|
18274
|
+
const newTrigger = {
|
|
18275
|
+
...trigger,
|
|
18276
|
+
id: (0, import_uuid.v4)(),
|
|
18277
|
+
createdAt: Date.now()
|
|
18278
|
+
};
|
|
18279
|
+
const row = toTriggerRow(newTrigger);
|
|
18280
|
+
db.prepare(
|
|
18281
|
+
`INSERT INTO message_triggers (
|
|
18282
|
+
id, creator_id, creator_context, creator_name, description,
|
|
18283
|
+
channels, from_users, from_bots, contains, match_pattern,
|
|
18284
|
+
threads, workflow, inputs, output_context,
|
|
18285
|
+
status, enabled, created_at
|
|
18286
|
+
) VALUES (
|
|
18287
|
+
?, ?, ?, ?, ?,
|
|
18288
|
+
?, ?, ?, ?, ?,
|
|
18289
|
+
?, ?, ?, ?,
|
|
18290
|
+
?, ?, ?
|
|
18291
|
+
)`
|
|
18292
|
+
).run(
|
|
18293
|
+
row.id,
|
|
18294
|
+
row.creator_id,
|
|
18295
|
+
row.creator_context,
|
|
18296
|
+
row.creator_name,
|
|
18297
|
+
row.description,
|
|
18298
|
+
row.channels,
|
|
18299
|
+
row.from_users,
|
|
18300
|
+
row.from_bots,
|
|
18301
|
+
row.contains,
|
|
18302
|
+
row.match_pattern,
|
|
18303
|
+
row.threads,
|
|
18304
|
+
row.workflow,
|
|
18305
|
+
row.inputs,
|
|
18306
|
+
row.output_context,
|
|
18307
|
+
row.status,
|
|
18308
|
+
row.enabled,
|
|
18309
|
+
row.created_at
|
|
18310
|
+
);
|
|
18311
|
+
logger.info(
|
|
18312
|
+
`[SqliteStore] Created message trigger ${newTrigger.id} for user ${newTrigger.creatorId}`
|
|
18313
|
+
);
|
|
18314
|
+
return newTrigger;
|
|
18315
|
+
}
|
|
18316
|
+
async getTrigger(id) {
|
|
18317
|
+
const db = this.getDb();
|
|
18318
|
+
const row = db.prepare("SELECT * FROM message_triggers WHERE id = ?").get(id);
|
|
18319
|
+
return row ? fromTriggerRow(row) : void 0;
|
|
18320
|
+
}
|
|
18321
|
+
async updateTrigger(id, patch) {
|
|
18322
|
+
const db = this.getDb();
|
|
18323
|
+
const existing = db.prepare("SELECT * FROM message_triggers WHERE id = ?").get(id);
|
|
18324
|
+
if (!existing) return void 0;
|
|
18325
|
+
const current = fromTriggerRow(existing);
|
|
18326
|
+
const updated = {
|
|
18327
|
+
...current,
|
|
18328
|
+
...patch,
|
|
18329
|
+
id: current.id,
|
|
18330
|
+
createdAt: current.createdAt
|
|
18331
|
+
};
|
|
18332
|
+
const row = toTriggerRow(updated);
|
|
18333
|
+
db.prepare(
|
|
18334
|
+
`UPDATE message_triggers SET
|
|
18335
|
+
creator_id = ?, creator_context = ?, creator_name = ?, description = ?,
|
|
18336
|
+
channels = ?, from_users = ?, from_bots = ?, contains = ?, match_pattern = ?,
|
|
18337
|
+
threads = ?, workflow = ?, inputs = ?, output_context = ?,
|
|
18338
|
+
status = ?, enabled = ?
|
|
18339
|
+
WHERE id = ?`
|
|
18340
|
+
).run(
|
|
18341
|
+
row.creator_id,
|
|
18342
|
+
row.creator_context,
|
|
18343
|
+
row.creator_name,
|
|
18344
|
+
row.description,
|
|
18345
|
+
row.channels,
|
|
18346
|
+
row.from_users,
|
|
18347
|
+
row.from_bots,
|
|
18348
|
+
row.contains,
|
|
18349
|
+
row.match_pattern,
|
|
18350
|
+
row.threads,
|
|
18351
|
+
row.workflow,
|
|
18352
|
+
row.inputs,
|
|
18353
|
+
row.output_context,
|
|
18354
|
+
row.status,
|
|
18355
|
+
row.enabled,
|
|
18356
|
+
row.id
|
|
18357
|
+
);
|
|
18358
|
+
return updated;
|
|
18359
|
+
}
|
|
18360
|
+
async deleteTrigger(id) {
|
|
18361
|
+
const db = this.getDb();
|
|
18362
|
+
const result = db.prepare("DELETE FROM message_triggers WHERE id = ?").run(id);
|
|
18363
|
+
if (result.changes > 0) {
|
|
18364
|
+
logger.info(`[SqliteStore] Deleted message trigger ${id}`);
|
|
18365
|
+
return true;
|
|
18366
|
+
}
|
|
18367
|
+
return false;
|
|
18368
|
+
}
|
|
18369
|
+
async getTriggersByCreator(creatorId) {
|
|
18370
|
+
const db = this.getDb();
|
|
18371
|
+
const rows = db.prepare("SELECT * FROM message_triggers WHERE creator_id = ?").all(creatorId);
|
|
18372
|
+
return rows.map(fromTriggerRow);
|
|
18373
|
+
}
|
|
18374
|
+
async getActiveTriggers() {
|
|
18375
|
+
const db = this.getDb();
|
|
18376
|
+
const rows = db.prepare("SELECT * FROM message_triggers WHERE status = 'active' AND enabled = 1").all();
|
|
18377
|
+
return rows.map(fromTriggerRow);
|
|
18378
|
+
}
|
|
18089
18379
|
};
|
|
18090
18380
|
}
|
|
18091
18381
|
});
|
|
@@ -18205,11 +18495,19 @@ var init_schedule_store = __esm({
|
|
|
18205
18495
|
init_json_migrator();
|
|
18206
18496
|
ScheduleStore = class _ScheduleStore {
|
|
18207
18497
|
static instance;
|
|
18498
|
+
static onTriggersChanged;
|
|
18208
18499
|
backend = null;
|
|
18209
18500
|
initialized = false;
|
|
18210
18501
|
limits;
|
|
18211
18502
|
config;
|
|
18212
18503
|
externalBackend = null;
|
|
18504
|
+
/**
|
|
18505
|
+
* Register a callback to be invoked when message triggers change (create/update/delete).
|
|
18506
|
+
* Used by SlackSocketRunner to rebuild its evaluator.
|
|
18507
|
+
*/
|
|
18508
|
+
static setTriggersChangedCallback(cb) {
|
|
18509
|
+
_ScheduleStore.onTriggersChanged = cb;
|
|
18510
|
+
}
|
|
18213
18511
|
constructor(config, limits, backend) {
|
|
18214
18512
|
this.config = config || {};
|
|
18215
18513
|
this.limits = {
|
|
@@ -18371,6 +18669,53 @@ var init_schedule_store = __esm({
|
|
|
18371
18669
|
}
|
|
18372
18670
|
return this.backend;
|
|
18373
18671
|
}
|
|
18672
|
+
// --- Message Trigger Methods ---
|
|
18673
|
+
/**
|
|
18674
|
+
* Create a new message trigger
|
|
18675
|
+
*/
|
|
18676
|
+
async createTriggerAsync(trigger) {
|
|
18677
|
+
const result = await this.getBackend().createTrigger(trigger);
|
|
18678
|
+
_ScheduleStore.onTriggersChanged?.();
|
|
18679
|
+
return result;
|
|
18680
|
+
}
|
|
18681
|
+
/**
|
|
18682
|
+
* Get a trigger by ID
|
|
18683
|
+
*/
|
|
18684
|
+
async getTriggerAsync(id) {
|
|
18685
|
+
return this.getBackend().getTrigger(id);
|
|
18686
|
+
}
|
|
18687
|
+
/**
|
|
18688
|
+
* Update a trigger
|
|
18689
|
+
*/
|
|
18690
|
+
async updateTriggerAsync(id, patch) {
|
|
18691
|
+
const result = await this.getBackend().updateTrigger(id, patch);
|
|
18692
|
+
if (result) {
|
|
18693
|
+
_ScheduleStore.onTriggersChanged?.();
|
|
18694
|
+
}
|
|
18695
|
+
return result;
|
|
18696
|
+
}
|
|
18697
|
+
/**
|
|
18698
|
+
* Delete a trigger
|
|
18699
|
+
*/
|
|
18700
|
+
async deleteTriggerAsync(id) {
|
|
18701
|
+
const result = await this.getBackend().deleteTrigger(id);
|
|
18702
|
+
if (result) {
|
|
18703
|
+
_ScheduleStore.onTriggersChanged?.();
|
|
18704
|
+
}
|
|
18705
|
+
return result;
|
|
18706
|
+
}
|
|
18707
|
+
/**
|
|
18708
|
+
* Get all triggers for a specific creator
|
|
18709
|
+
*/
|
|
18710
|
+
async getTriggersByCreatorAsync(creatorId) {
|
|
18711
|
+
return this.getBackend().getTriggersByCreator(creatorId);
|
|
18712
|
+
}
|
|
18713
|
+
/**
|
|
18714
|
+
* Get all active triggers
|
|
18715
|
+
*/
|
|
18716
|
+
async getActiveTriggersAsync() {
|
|
18717
|
+
return this.getBackend().getActiveTriggers();
|
|
18718
|
+
}
|
|
18374
18719
|
/**
|
|
18375
18720
|
* Shut down the backend cleanly
|
|
18376
18721
|
*/
|
|
@@ -19611,11 +19956,19 @@ async function handleScheduleAction(args, context2) {
|
|
|
19611
19956
|
return handlePauseResume(args, context2, store, "paused");
|
|
19612
19957
|
case "resume":
|
|
19613
19958
|
return handlePauseResume(args, context2, store, "active");
|
|
19959
|
+
case "create_trigger":
|
|
19960
|
+
return handleCreateTrigger(args, context2, store);
|
|
19961
|
+
case "list_triggers":
|
|
19962
|
+
return handleListTriggers(context2, store);
|
|
19963
|
+
case "delete_trigger":
|
|
19964
|
+
return handleDeleteTrigger(args, context2, store);
|
|
19965
|
+
case "update_trigger":
|
|
19966
|
+
return handleUpdateTrigger(args, context2, store);
|
|
19614
19967
|
default:
|
|
19615
19968
|
return {
|
|
19616
19969
|
success: false,
|
|
19617
19970
|
message: `Unknown action: ${args.action}`,
|
|
19618
|
-
error: `Supported actions: create, list, cancel, pause, resume`
|
|
19971
|
+
error: `Supported actions: create, list, cancel, pause, resume, create_trigger, list_triggers, delete_trigger, update_trigger`
|
|
19619
19972
|
};
|
|
19620
19973
|
}
|
|
19621
19974
|
}
|
|
@@ -19858,6 +20211,172 @@ async function handlePauseResume(args, context2, store, newStatus) {
|
|
|
19858
20211
|
schedule: updated
|
|
19859
20212
|
};
|
|
19860
20213
|
}
|
|
20214
|
+
function formatTrigger(trigger) {
|
|
20215
|
+
const channels = trigger.channels?.length ? trigger.channels.join(", ") : "all";
|
|
20216
|
+
const filters = [];
|
|
20217
|
+
if (trigger.contains?.length) filters.push(`contains: ${trigger.contains.join(", ")}`);
|
|
20218
|
+
if (trigger.matchPattern) filters.push(`match: /${trigger.matchPattern}/`);
|
|
20219
|
+
if (trigger.fromBots) filters.push("bots: yes");
|
|
20220
|
+
const filterStr = filters.length ? ` [${filters.join("; ")}]` : "";
|
|
20221
|
+
const status = trigger.enabled ? "" : " (disabled)";
|
|
20222
|
+
return `\`${trigger.id.substring(0, 8)}\` - channels: ${channels} \u2192 workflow: "${trigger.workflow}"${filterStr}${status}`;
|
|
20223
|
+
}
|
|
20224
|
+
async function handleCreateTrigger(args, context2, store) {
|
|
20225
|
+
if (!args.workflow) {
|
|
20226
|
+
return {
|
|
20227
|
+
success: false,
|
|
20228
|
+
message: "Missing workflow",
|
|
20229
|
+
error: "Please specify the workflow to run when the trigger fires."
|
|
20230
|
+
};
|
|
20231
|
+
}
|
|
20232
|
+
if (context2.availableWorkflows && !context2.availableWorkflows.includes(args.workflow)) {
|
|
20233
|
+
return {
|
|
20234
|
+
success: false,
|
|
20235
|
+
message: `Workflow "${args.workflow}" not found`,
|
|
20236
|
+
error: `Available workflows: ${context2.availableWorkflows.slice(0, 5).join(", ")}${context2.availableWorkflows.length > 5 ? "..." : ""}`
|
|
20237
|
+
};
|
|
20238
|
+
}
|
|
20239
|
+
if ((!args.trigger_channels || args.trigger_channels.length === 0) && (!args.trigger_contains || args.trigger_contains.length === 0) && !args.trigger_match) {
|
|
20240
|
+
return {
|
|
20241
|
+
success: false,
|
|
20242
|
+
message: "Missing trigger filters",
|
|
20243
|
+
error: "Please specify at least one filter: trigger_channels, trigger_contains, or trigger_match."
|
|
20244
|
+
};
|
|
20245
|
+
}
|
|
20246
|
+
const permissionCheck = checkSchedulePermissions(context2, args.workflow);
|
|
20247
|
+
if (!permissionCheck.allowed) {
|
|
20248
|
+
return {
|
|
20249
|
+
success: false,
|
|
20250
|
+
message: "Permission denied",
|
|
20251
|
+
error: permissionCheck.reason || "You do not have permission to create triggers for this workflow"
|
|
20252
|
+
};
|
|
20253
|
+
}
|
|
20254
|
+
try {
|
|
20255
|
+
const trigger = await store.createTriggerAsync({
|
|
20256
|
+
creatorId: context2.userId,
|
|
20257
|
+
creatorContext: context2.contextType,
|
|
20258
|
+
creatorName: context2.userName,
|
|
20259
|
+
description: args.trigger_description,
|
|
20260
|
+
channels: args.trigger_channels,
|
|
20261
|
+
fromBots: args.trigger_from_bots ?? false,
|
|
20262
|
+
contains: args.trigger_contains,
|
|
20263
|
+
matchPattern: args.trigger_match,
|
|
20264
|
+
threads: args.trigger_threads ?? "any",
|
|
20265
|
+
workflow: args.workflow,
|
|
20266
|
+
inputs: args.workflow_inputs,
|
|
20267
|
+
status: "active",
|
|
20268
|
+
enabled: true
|
|
20269
|
+
});
|
|
20270
|
+
logger.info(
|
|
20271
|
+
`[ScheduleTool] Created message trigger ${trigger.id} for user ${context2.userId}: workflow="${args.workflow}"`
|
|
20272
|
+
);
|
|
20273
|
+
return {
|
|
20274
|
+
success: true,
|
|
20275
|
+
message: `**Message trigger created!**
|
|
20276
|
+
|
|
20277
|
+
**Workflow**: ${trigger.workflow}
|
|
20278
|
+
**Channels**: ${trigger.channels?.join(", ") || "all"}
|
|
20279
|
+
${trigger.contains?.length ? `**Contains**: ${trigger.contains.join(", ")}
|
|
20280
|
+
` : ""}${trigger.matchPattern ? `**Pattern**: /${trigger.matchPattern}/
|
|
20281
|
+
` : ""}${trigger.description ? `**Description**: ${trigger.description}
|
|
20282
|
+
` : ""}
|
|
20283
|
+
ID: \`${trigger.id.substring(0, 8)}\``
|
|
20284
|
+
};
|
|
20285
|
+
} catch (error) {
|
|
20286
|
+
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
20287
|
+
logger.warn(`[ScheduleTool] Failed to create trigger: ${errorMsg}`);
|
|
20288
|
+
return {
|
|
20289
|
+
success: false,
|
|
20290
|
+
message: `Failed to create trigger: ${errorMsg}`,
|
|
20291
|
+
error: errorMsg
|
|
20292
|
+
};
|
|
20293
|
+
}
|
|
20294
|
+
}
|
|
20295
|
+
async function handleListTriggers(context2, store) {
|
|
20296
|
+
const triggers = await store.getTriggersByCreatorAsync(context2.userId);
|
|
20297
|
+
const active = triggers.filter((t) => t.status !== "deleted");
|
|
20298
|
+
if (active.length === 0) {
|
|
20299
|
+
return {
|
|
20300
|
+
success: true,
|
|
20301
|
+
message: `You don't have any message triggers.
|
|
20302
|
+
|
|
20303
|
+
To create one: "watch #channel for messages containing 'error' and run %my-workflow"`
|
|
20304
|
+
};
|
|
20305
|
+
}
|
|
20306
|
+
const lines = active.map((t, i) => `${i + 1}. ${formatTrigger(t)}`);
|
|
20307
|
+
return {
|
|
20308
|
+
success: true,
|
|
20309
|
+
message: `**Your message triggers:**
|
|
20310
|
+
|
|
20311
|
+
${lines.join("\n")}
|
|
20312
|
+
|
|
20313
|
+
To delete: "delete trigger <id>"
|
|
20314
|
+
To disable: "disable trigger <id>"`
|
|
20315
|
+
};
|
|
20316
|
+
}
|
|
20317
|
+
async function handleDeleteTrigger(args, context2, store) {
|
|
20318
|
+
if (!args.trigger_id) {
|
|
20319
|
+
return {
|
|
20320
|
+
success: false,
|
|
20321
|
+
message: "Missing trigger ID",
|
|
20322
|
+
error: "Please specify which trigger to delete."
|
|
20323
|
+
};
|
|
20324
|
+
}
|
|
20325
|
+
const userTriggers = await store.getTriggersByCreatorAsync(context2.userId);
|
|
20326
|
+
let trigger = userTriggers.find((t) => t.id === args.trigger_id);
|
|
20327
|
+
if (!trigger) {
|
|
20328
|
+
trigger = userTriggers.find((t) => t.id.startsWith(args.trigger_id));
|
|
20329
|
+
}
|
|
20330
|
+
if (!trigger) {
|
|
20331
|
+
return {
|
|
20332
|
+
success: false,
|
|
20333
|
+
message: "Trigger not found",
|
|
20334
|
+
error: `Could not find trigger with ID "${args.trigger_id}" in your triggers. Use "list my triggers" to see your triggers.`
|
|
20335
|
+
};
|
|
20336
|
+
}
|
|
20337
|
+
await store.deleteTriggerAsync(trigger.id);
|
|
20338
|
+
logger.info(`[ScheduleTool] Deleted trigger ${trigger.id} for user ${context2.userId}`);
|
|
20339
|
+
return {
|
|
20340
|
+
success: true,
|
|
20341
|
+
message: `**Trigger deleted!**
|
|
20342
|
+
|
|
20343
|
+
Was: watching for "${trigger.workflow}" ${trigger.channels?.length ? `in ${trigger.channels.join(", ")}` : ""}`
|
|
20344
|
+
};
|
|
20345
|
+
}
|
|
20346
|
+
async function handleUpdateTrigger(args, context2, store) {
|
|
20347
|
+
if (!args.trigger_id) {
|
|
20348
|
+
return {
|
|
20349
|
+
success: false,
|
|
20350
|
+
message: "Missing trigger ID",
|
|
20351
|
+
error: "Please specify which trigger to update."
|
|
20352
|
+
};
|
|
20353
|
+
}
|
|
20354
|
+
const userTriggers = await store.getTriggersByCreatorAsync(context2.userId);
|
|
20355
|
+
let trigger = userTriggers.find((t) => t.id === args.trigger_id);
|
|
20356
|
+
if (!trigger) {
|
|
20357
|
+
trigger = userTriggers.find((t) => t.id.startsWith(args.trigger_id));
|
|
20358
|
+
}
|
|
20359
|
+
if (!trigger) {
|
|
20360
|
+
return {
|
|
20361
|
+
success: false,
|
|
20362
|
+
message: "Trigger not found",
|
|
20363
|
+
error: `Could not find trigger with ID "${args.trigger_id}" in your triggers.`
|
|
20364
|
+
};
|
|
20365
|
+
}
|
|
20366
|
+
const patch = {};
|
|
20367
|
+
if (args.trigger_enabled !== void 0) {
|
|
20368
|
+
patch.enabled = args.trigger_enabled;
|
|
20369
|
+
}
|
|
20370
|
+
await store.updateTriggerAsync(trigger.id, patch);
|
|
20371
|
+
const action = args.trigger_enabled === false ? "disabled" : "enabled";
|
|
20372
|
+
logger.info(`[ScheduleTool] ${action} trigger ${trigger.id} for user ${context2.userId}`);
|
|
20373
|
+
return {
|
|
20374
|
+
success: true,
|
|
20375
|
+
message: `**Trigger ${action}!**
|
|
20376
|
+
|
|
20377
|
+
"${trigger.workflow}" ${trigger.channels?.length ? `in ${trigger.channels.join(", ")}` : ""}`
|
|
20378
|
+
};
|
|
20379
|
+
}
|
|
19861
20380
|
function getScheduleToolDefinition() {
|
|
19862
20381
|
return {
|
|
19863
20382
|
name: "schedule",
|
|
@@ -19877,6 +20396,17 @@ ACTIONS:
|
|
|
19877
20396
|
- cancel: Remove a schedule by ID
|
|
19878
20397
|
- pause/resume: Temporarily disable/enable a schedule
|
|
19879
20398
|
|
|
20399
|
+
MESSAGE-BASED TRIGGERS:
|
|
20400
|
+
In addition to time-based schedules, this tool can create/manage message-based triggers that react to
|
|
20401
|
+
Slack messages in specific channels. Use the create_trigger, list_triggers, delete_trigger, and update_trigger
|
|
20402
|
+
actions for this. Message triggers fire workflows based on message content, channel, sender, and thread scope.
|
|
20403
|
+
|
|
20404
|
+
TRIGGER ACTIONS:
|
|
20405
|
+
- create_trigger: Create a new message trigger (requires workflow + at least one filter)
|
|
20406
|
+
- list_triggers: Show user's message triggers
|
|
20407
|
+
- delete_trigger: Remove a trigger by ID
|
|
20408
|
+
- update_trigger: Enable/disable a trigger by ID
|
|
20409
|
+
|
|
19880
20410
|
FOR CREATE ACTION - Extract these from user's request:
|
|
19881
20411
|
1. WHAT:
|
|
19882
20412
|
- If user says "schedule %some-workflow ...", populate 'workflow' with "some-workflow".
|
|
@@ -19964,14 +20494,36 @@ User: "list my schedules"
|
|
|
19964
20494
|
\u2192 { "action": "list" }
|
|
19965
20495
|
|
|
19966
20496
|
User: "cancel schedule abc123"
|
|
19967
|
-
\u2192 { "action": "cancel", "schedule_id": "abc123" }
|
|
20497
|
+
\u2192 { "action": "cancel", "schedule_id": "abc123" }
|
|
20498
|
+
|
|
20499
|
+
User: "watch #cicd for messages containing 'failed' and run %handle-cicd"
|
|
20500
|
+
\u2192 { "action": "create_trigger", "trigger_channels": ["C0CICD"], "trigger_contains": ["failed"], "workflow": "handle-cicd" }
|
|
20501
|
+
|
|
20502
|
+
User: "list my message triggers"
|
|
20503
|
+
\u2192 { "action": "list_triggers" }
|
|
20504
|
+
|
|
20505
|
+
User: "delete trigger abc123"
|
|
20506
|
+
\u2192 { "action": "delete_trigger", "trigger_id": "abc123" }
|
|
20507
|
+
|
|
20508
|
+
User: "disable trigger abc123"
|
|
20509
|
+
\u2192 { "action": "update_trigger", "trigger_id": "abc123", "trigger_enabled": false }`,
|
|
19968
20510
|
inputSchema: {
|
|
19969
20511
|
type: "object",
|
|
19970
20512
|
properties: {
|
|
19971
20513
|
action: {
|
|
19972
20514
|
type: "string",
|
|
19973
|
-
enum: [
|
|
19974
|
-
|
|
20515
|
+
enum: [
|
|
20516
|
+
"create",
|
|
20517
|
+
"list",
|
|
20518
|
+
"cancel",
|
|
20519
|
+
"pause",
|
|
20520
|
+
"resume",
|
|
20521
|
+
"create_trigger",
|
|
20522
|
+
"list_triggers",
|
|
20523
|
+
"delete_trigger",
|
|
20524
|
+
"update_trigger"
|
|
20525
|
+
],
|
|
20526
|
+
description: "What to do: create/list/cancel/pause/resume for time-based schedules; create_trigger/list_triggers/delete_trigger/update_trigger for message-based triggers"
|
|
19975
20527
|
},
|
|
19976
20528
|
// WHAT to do
|
|
19977
20529
|
reminder_text: {
|
|
@@ -20021,6 +20573,42 @@ User: "cancel schedule abc123"
|
|
|
20021
20573
|
schedule_id: {
|
|
20022
20574
|
type: "string",
|
|
20023
20575
|
description: "For cancel/pause/resume: the schedule ID to act on (first 8 chars is enough)"
|
|
20576
|
+
},
|
|
20577
|
+
// For message trigger actions
|
|
20578
|
+
trigger_channels: {
|
|
20579
|
+
type: "array",
|
|
20580
|
+
items: { type: "string" },
|
|
20581
|
+
description: 'For create_trigger: Slack channel IDs to monitor (e.g., ["C0CICD"]). Supports wildcard suffix (e.g., "CENG*").'
|
|
20582
|
+
},
|
|
20583
|
+
trigger_from_bots: {
|
|
20584
|
+
type: "boolean",
|
|
20585
|
+
description: "For create_trigger: allow bot messages to trigger (default: false)"
|
|
20586
|
+
},
|
|
20587
|
+
trigger_contains: {
|
|
20588
|
+
type: "array",
|
|
20589
|
+
items: { type: "string" },
|
|
20590
|
+
description: 'For create_trigger: keywords to match (case-insensitive OR). E.g., ["failed", "error"].'
|
|
20591
|
+
},
|
|
20592
|
+
trigger_match: {
|
|
20593
|
+
type: "string",
|
|
20594
|
+
description: "For create_trigger: regex pattern to match against message text."
|
|
20595
|
+
},
|
|
20596
|
+
trigger_threads: {
|
|
20597
|
+
type: "string",
|
|
20598
|
+
enum: ["root_only", "thread_only", "any"],
|
|
20599
|
+
description: 'For create_trigger: thread scope filter (default: "any").'
|
|
20600
|
+
},
|
|
20601
|
+
trigger_description: {
|
|
20602
|
+
type: "string",
|
|
20603
|
+
description: "For create_trigger: human-readable description of the trigger."
|
|
20604
|
+
},
|
|
20605
|
+
trigger_id: {
|
|
20606
|
+
type: "string",
|
|
20607
|
+
description: "For delete_trigger/update_trigger: the trigger ID to act on (first 8 chars is enough)."
|
|
20608
|
+
},
|
|
20609
|
+
trigger_enabled: {
|
|
20610
|
+
type: "boolean",
|
|
20611
|
+
description: "For update_trigger: set to false to disable, true to enable."
|
|
20024
20612
|
}
|
|
20025
20613
|
},
|
|
20026
20614
|
required: ["action"]
|
|
@@ -46314,7 +46902,7 @@ var init_worktree_manager = __esm({
|
|
|
46314
46902
|
await this.saveMetadata(worktreePath, updatedMetadata);
|
|
46315
46903
|
if (options.clean) {
|
|
46316
46904
|
logger.debug(`Cleaning updated worktree`);
|
|
46317
|
-
await this.cleanWorktree(worktreePath);
|
|
46905
|
+
await this.cleanWorktree(worktreePath, latestCommit);
|
|
46318
46906
|
}
|
|
46319
46907
|
this.activeWorktrees.set(worktreeId, updatedMetadata);
|
|
46320
46908
|
return {
|
|
@@ -46333,7 +46921,7 @@ var init_worktree_manager = __esm({
|
|
|
46333
46921
|
}
|
|
46334
46922
|
if (options.clean) {
|
|
46335
46923
|
logger.debug(`Cleaning existing worktree`);
|
|
46336
|
-
await this.cleanWorktree(worktreePath);
|
|
46924
|
+
await this.cleanWorktree(worktreePath, metadata2.commit);
|
|
46337
46925
|
}
|
|
46338
46926
|
this.activeWorktrees.set(worktreeId, metadata2);
|
|
46339
46927
|
return {
|
|
@@ -46375,7 +46963,7 @@ var init_worktree_manager = __esm({
|
|
|
46375
46963
|
await this.saveMetadata(worktreePath, updatedMetadata);
|
|
46376
46964
|
if (options.clean) {
|
|
46377
46965
|
logger.debug(`Cleaning updated worktree`);
|
|
46378
|
-
await this.cleanWorktree(worktreePath);
|
|
46966
|
+
await this.cleanWorktree(worktreePath, newCommit);
|
|
46379
46967
|
}
|
|
46380
46968
|
this.activeWorktrees.set(worktreeId, updatedMetadata);
|
|
46381
46969
|
logger.info(`Successfully updated worktree to ${ref} (${newCommit})`);
|
|
@@ -46465,13 +47053,54 @@ var init_worktree_manager = __esm({
|
|
|
46465
47053
|
return true;
|
|
46466
47054
|
}
|
|
46467
47055
|
/**
|
|
46468
|
-
* Clean worktree (reset and remove untracked files)
|
|
46469
|
-
|
|
46470
|
-
|
|
47056
|
+
* Clean worktree (reset and remove untracked files).
|
|
47057
|
+
*
|
|
47058
|
+
* When `expectedCommit` is provided the worktree is first forced back to a
|
|
47059
|
+
* detached HEAD at that commit. This is essential because AI agents or user
|
|
47060
|
+
* commands may have created local branches inside the worktree, switching
|
|
47061
|
+
* HEAD away from the detached state. A plain `reset --hard HEAD` would
|
|
47062
|
+
* then reset to the *wrong* commit. After resetting, any local branches
|
|
47063
|
+
* that were created inside the worktree are deleted so they cannot leak
|
|
47064
|
+
* into future runs or PRs.
|
|
47065
|
+
*/
|
|
47066
|
+
async cleanWorktree(worktreePath, expectedCommit) {
|
|
47067
|
+
if (expectedCommit) {
|
|
47068
|
+
const detachCmd = `git -C ${this.escapeShellArg(worktreePath)} checkout --detach ${this.escapeShellArg(expectedCommit)}`;
|
|
47069
|
+
const detachResult = await this.executeGitCommand(detachCmd, { timeout: 3e4 });
|
|
47070
|
+
if (detachResult.exitCode !== 0) {
|
|
47071
|
+
await this.executeGitCommand(`git -C ${this.escapeShellArg(worktreePath)} reset --hard`, {
|
|
47072
|
+
timeout: 1e4
|
|
47073
|
+
});
|
|
47074
|
+
await this.executeGitCommand(detachCmd, { timeout: 3e4 });
|
|
47075
|
+
}
|
|
47076
|
+
}
|
|
46471
47077
|
const resetCmd = `git -C ${this.escapeShellArg(worktreePath)} reset --hard HEAD`;
|
|
46472
47078
|
await this.executeGitCommand(resetCmd);
|
|
46473
47079
|
const cleanCmd = `git -C ${this.escapeShellArg(worktreePath)} clean -fdx`;
|
|
46474
47080
|
await this.executeGitCommand(cleanCmd);
|
|
47081
|
+
await this.deleteLocalBranches(worktreePath);
|
|
47082
|
+
}
|
|
47083
|
+
/**
|
|
47084
|
+
* Delete all local branches in a worktree.
|
|
47085
|
+
* Worktrees are always used in detached HEAD state, so any local branches
|
|
47086
|
+
* were unintentionally created and should be cleaned up.
|
|
47087
|
+
*/
|
|
47088
|
+
async deleteLocalBranches(worktreePath) {
|
|
47089
|
+
const listCmd = `git -C ${this.escapeShellArg(worktreePath)} branch --list --format='%(refname:short)'`;
|
|
47090
|
+
const listResult = await this.executeGitCommand(listCmd, { timeout: 1e4 });
|
|
47091
|
+
if (listResult.exitCode !== 0 || !listResult.stdout.trim()) {
|
|
47092
|
+
return;
|
|
47093
|
+
}
|
|
47094
|
+
const branches = listResult.stdout.trim().split("\n").map((b) => b.trim()).filter((b) => b.length > 0);
|
|
47095
|
+
for (const branch of branches) {
|
|
47096
|
+
const deleteCmd = `git -C ${this.escapeShellArg(worktreePath)} branch -D ${this.escapeShellArg(branch)}`;
|
|
47097
|
+
const deleteResult = await this.executeGitCommand(deleteCmd, { timeout: 1e4 });
|
|
47098
|
+
if (deleteResult.exitCode === 0) {
|
|
47099
|
+
logger.debug(`Deleted local branch '${branch}' from worktree`);
|
|
47100
|
+
} else {
|
|
47101
|
+
logger.warn(`Failed to delete branch '${branch}': ${deleteResult.stderr}`);
|
|
47102
|
+
}
|
|
47103
|
+
}
|
|
46475
47104
|
}
|
|
46476
47105
|
/**
|
|
46477
47106
|
* Get commit SHA for a given ref inside a bare repository.
|
|
@@ -53022,9 +53651,40 @@ ${file.patch}`).join("\n\n");
|
|
|
53022
53651
|
/**
|
|
53023
53652
|
* Get diff between current branch and base branch (for feature branch analysis)
|
|
53024
53653
|
*/
|
|
53654
|
+
/**
|
|
53655
|
+
* Resolve the base branch ref to a revision that exists locally.
|
|
53656
|
+
* In CI (shallow clones), the local branch may not exist, so we try:
|
|
53657
|
+
* 1. The branch name as-is (e.g. "main")
|
|
53658
|
+
* 2. The remote-tracking ref (e.g. "origin/main")
|
|
53659
|
+
* 3. Fetch from origin then retry
|
|
53660
|
+
*/
|
|
53661
|
+
async resolveBaseBranchRef(baseBranch) {
|
|
53662
|
+
try {
|
|
53663
|
+
await this.git.revparse([baseBranch]);
|
|
53664
|
+
return baseBranch;
|
|
53665
|
+
} catch {
|
|
53666
|
+
}
|
|
53667
|
+
const remoteBranch = `origin/${baseBranch}`;
|
|
53668
|
+
try {
|
|
53669
|
+
await this.git.revparse([remoteBranch]);
|
|
53670
|
+
return remoteBranch;
|
|
53671
|
+
} catch {
|
|
53672
|
+
}
|
|
53673
|
+
try {
|
|
53674
|
+
await this.git.fetch(["origin", baseBranch]);
|
|
53675
|
+
await this.git.revparse([remoteBranch]);
|
|
53676
|
+
return remoteBranch;
|
|
53677
|
+
} catch {
|
|
53678
|
+
return baseBranch;
|
|
53679
|
+
}
|
|
53680
|
+
}
|
|
53025
53681
|
async getBranchDiff(baseBranch, includeContext = true) {
|
|
53026
53682
|
try {
|
|
53027
|
-
const
|
|
53683
|
+
const resolvedBase = await this.resolveBaseBranchRef(baseBranch);
|
|
53684
|
+
if (resolvedBase !== baseBranch) {
|
|
53685
|
+
console.error(`\u{1F4CE} Resolved base branch: ${baseBranch} \u2192 ${resolvedBase}`);
|
|
53686
|
+
}
|
|
53687
|
+
const diffSummary = await this.git.diffSummary([resolvedBase]);
|
|
53028
53688
|
const changes = [];
|
|
53029
53689
|
if (!diffSummary || !diffSummary.files) {
|
|
53030
53690
|
return [];
|
|
@@ -53052,7 +53712,7 @@ ${file.patch}`).join("\n\n");
|
|
|
53052
53712
|
let truncated = false;
|
|
53053
53713
|
if (includeContext && !isBinary) {
|
|
53054
53714
|
try {
|
|
53055
|
-
const rawPatch = await this.git.diff([
|
|
53715
|
+
const rawPatch = await this.git.diff([resolvedBase, "--", file.file]);
|
|
53056
53716
|
if (rawPatch) {
|
|
53057
53717
|
const result = this.truncatePatch(rawPatch, file.file);
|
|
53058
53718
|
patch = result.patch;
|
|
@@ -53648,6 +54308,30 @@ var init_workspace_manager = __esm({
|
|
|
53648
54308
|
if (cleanResult.exitCode !== 0) {
|
|
53649
54309
|
logger.warn(`[Workspace] clean -fdx failed: ${cleanResult.stderr}`);
|
|
53650
54310
|
}
|
|
54311
|
+
await this.deleteLocalBranches(worktreePath);
|
|
54312
|
+
}
|
|
54313
|
+
/**
|
|
54314
|
+
* Delete all local branches in a worktree.
|
|
54315
|
+
*/
|
|
54316
|
+
async deleteLocalBranches(worktreePath) {
|
|
54317
|
+
const escapedPath = shellEscape(worktreePath);
|
|
54318
|
+
const listResult = await commandExecutor.execute(
|
|
54319
|
+
`git -C ${escapedPath} branch --list --format='%(refname:short)'`,
|
|
54320
|
+
{ timeout: 1e4 }
|
|
54321
|
+
);
|
|
54322
|
+
if (listResult.exitCode !== 0 || !listResult.stdout.trim()) {
|
|
54323
|
+
return;
|
|
54324
|
+
}
|
|
54325
|
+
const branches = listResult.stdout.trim().split("\n").map((b) => b.trim()).filter((b) => b.length > 0);
|
|
54326
|
+
for (const branch of branches) {
|
|
54327
|
+
const deleteResult = await commandExecutor.execute(
|
|
54328
|
+
`git -C ${escapedPath} branch -D ${shellEscape(branch)}`,
|
|
54329
|
+
{ timeout: 1e4 }
|
|
54330
|
+
);
|
|
54331
|
+
if (deleteResult.exitCode === 0) {
|
|
54332
|
+
logger.debug(`[Workspace] Deleted local branch '${branch}' from worktree`);
|
|
54333
|
+
}
|
|
54334
|
+
}
|
|
53651
54335
|
}
|
|
53652
54336
|
/**
|
|
53653
54337
|
* Refresh an existing worktree to the latest upstream default branch
|