@probelabs/visor 0.1.149 → 0.1.150-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.
- 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 +5868 -4756
- 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-RRYBG6AU.mjs} +6 -6
- package/dist/sdk/{check-provider-registry-X4OZJWPK.mjs → check-provider-registry-VHM53BTI.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-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-GLROSEYJ.mjs} +3 -3
- package/dist/sdk/{chunk-6EXCUX7Y.mjs → chunk-O4H5KZ7Y.mjs} +586 -30
- package/dist/sdk/{chunk-GFNXX64M.mjs.map → chunk-O4H5KZ7Y.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/{config-KQH254CA.mjs → config-MTEIGCOQ.mjs} +2 -2
- package/dist/sdk/{failure-condition-evaluator-IVCTD4BZ.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/{host-7YKRMOUJ.mjs → host-BRZQLVCH.mjs} +2 -2
- package/dist/sdk/{host-H7IX4GBK.mjs → host-MR7L57QI.mjs} +2 -2
- package/dist/sdk/knex-store-CRORFJE6.mjs +527 -0
- package/dist/sdk/knex-store-CRORFJE6.mjs.map +1 -0
- package/dist/sdk/loader-NJCF7DUS.mjs +89 -0
- package/dist/sdk/loader-NJCF7DUS.mjs.map +1 -0
- package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs +655 -0
- package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs.map +1 -0
- package/dist/sdk/{routing-LU5PAREW.mjs → routing-V3MYZAOH.mjs} +4 -4
- package/dist/sdk/{schedule-tool-EOMZFICZ.mjs → schedule-tool-4QDBJV74.mjs} +6 -6
- package/dist/sdk/{schedule-tool-NX75VKGA.mjs → schedule-tool-NYLNJUEW.mjs} +6 -6
- package/dist/sdk/{schedule-tool-handler-3FJHDIPG.mjs → schedule-tool-handler-27XEVLSY.mjs} +6 -6
- package/dist/sdk/{schedule-tool-handler-KKN7XJYT.mjs → schedule-tool-handler-EFQIYD3W.mjs} +6 -6
- package/dist/sdk/sdk.d.mts +38 -1
- package/dist/sdk/sdk.d.ts +38 -1
- package/dist/sdk/sdk.js +2338 -280
- 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/validator-XTZJZZJH.mjs +134 -0
- package/dist/sdk/validator-XTZJZZJH.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-AGZ5JY2I.mjs → workflow-check-provider-3MVUCEJR.mjs} +6 -6
- package/dist/sdk/{workflow-check-provider-PTNUWM5W.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/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/output/traces/run-2026-03-03T07-19-07-543Z.ndjson +0 -138
- package/dist/output/traces/run-2026-03-03T07-19-50-933Z.ndjson +0 -2121
- package/dist/sdk/check-provider-registry-IYSUDKPB.mjs +0 -29
- package/dist/sdk/chunk-BR7DYA3S.mjs +0 -739
- package/dist/sdk/chunk-CISJ6DJW.mjs +0 -1502
- package/dist/sdk/chunk-GFNXX64M.mjs +0 -43159
- package/dist/sdk/chunk-Q6EPAJ6Z.mjs.map +0 -1
- package/dist/sdk/chunk-RJLJUTSU.mjs.map +0 -1
- package/dist/sdk/chunk-V6GI4U2M.mjs.map +0 -1
- package/dist/sdk/chunk-VLUGLWLA.mjs +0 -443
- package/dist/sdk/chunk-VLUGLWLA.mjs.map +0 -1
- package/dist/sdk/chunk-YYZAN5NK.mjs.map +0 -1
- package/dist/sdk/failure-condition-evaluator-LZ2AG5PY.mjs +0 -17
- package/dist/sdk/git-repository-analyzer-QFMW6WIS.mjs.map +0 -1
- package/dist/sdk/github-frontend-S523EEJB.mjs +0 -1368
- package/dist/sdk/github-frontend-S523EEJB.mjs.map +0 -1
- package/dist/sdk/routing-ZMBKWMVI.mjs +0 -25
- package/dist/sdk/schedule-tool-CDVUSZEG.mjs +0 -35
- package/dist/sdk/schedule-tool-handler-KKN7XJYT.mjs.map +0 -1
- package/dist/sdk/schedule-tool-handler-QNZG55DX.mjs +0 -39
- package/dist/sdk/schedule-tool-handler-QNZG55DX.mjs.map +0 -1
- package/dist/sdk/trace-helpers-6ROJR7N3.mjs +0 -25
- package/dist/sdk/trace-helpers-6ROJR7N3.mjs.map +0 -1
- package/dist/sdk/trace-helpers-EJUIOP6L.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-6ERNNCNA.mjs +0 -29
- package/dist/sdk/workflow-check-provider-6ERNNCNA.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-AGZ5JY2I.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-PTNUWM5W.mjs.map +0 -1
- package/dist/traces/run-2026-03-03T07-19-07-543Z.ndjson +0 -138
- package/dist/traces/run-2026-03-03T07-19-50-933Z.ndjson +0 -2121
- /package/dist/sdk/{check-provider-registry-IYSUDKPB.mjs.map → check-provider-registry-RRYBG6AU.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-LVLC4EPF.mjs.map → check-provider-registry-VHM53BTI.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-GLROSEYJ.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-X4OZJWPK.mjs.map → config-MTEIGCOQ.mjs.map} +0 -0
- /package/dist/sdk/{config-KQH254CA.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/{host-7YKRMOUJ.mjs.map → host-BRZQLVCH.mjs.map} +0 -0
- /package/dist/sdk/{host-H7IX4GBK.mjs.map → host-MR7L57QI.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-IVCTD4BZ.mjs.map → routing-V3MYZAOH.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-LZ2AG5PY.mjs.map → schedule-tool-4QDBJV74.mjs.map} +0 -0
- /package/dist/sdk/{routing-LU5PAREW.mjs.map → schedule-tool-NYLNJUEW.mjs.map} +0 -0
- /package/dist/sdk/{routing-ZMBKWMVI.mjs.map → schedule-tool-handler-27XEVLSY.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-CDVUSZEG.mjs.map → schedule-tool-handler-EFQIYD3W.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-EOMZFICZ.mjs.map → trace-helpers-6NSZBC35.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-NX75VKGA.mjs.map → workflow-check-provider-3MVUCEJR.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-3FJHDIPG.mjs.map → workflow-check-provider-XLH7N4FV.mjs.map} +0 -0
|
@@ -185,6 +185,29 @@ The complete list of event triggers that can be used in the `on` field:
|
|
|
185
185
|
| `manual` | Manual CLI invocation |
|
|
186
186
|
| `schedule` | Scheduled execution (cron or workflow_dispatch) |
|
|
187
187
|
| `webhook_received` | HTTP webhook was received (via http_input provider) |
|
|
188
|
+
| `slack_message` | Slack message matched an `on_message` trigger (see [Scheduler - Message Triggers](./scheduler.md#message-triggers-on_message)) |
|
|
189
|
+
|
|
190
|
+
### Slack Message Trigger Events (`slack_message`)
|
|
191
|
+
|
|
192
|
+
When a Slack message matches a configured `on_message` trigger (defined in `scheduler.on_message`), the specified workflow is dispatched with event type `slack_message`. This allows reactive workflows based on message content in specific channels, without requiring an @mention.
|
|
193
|
+
|
|
194
|
+
- **Trigger mapping**: `slack_message`
|
|
195
|
+
- **Source**: `scheduler.on_message` filter match in Slack Socket Mode
|
|
196
|
+
- **Log format**:
|
|
197
|
+
```
|
|
198
|
+
[SlackSocket] Message trigger 'cicd-watcher' matched → workflow="handle-cicd" channel=C0CICD ts=1700.001
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Steps can filter on this event type:
|
|
202
|
+
```yaml
|
|
203
|
+
steps:
|
|
204
|
+
handle-cicd-failure:
|
|
205
|
+
on: [slack_message] # Only runs when triggered by on_message
|
|
206
|
+
type: ai
|
|
207
|
+
prompt: "Analyze the CI/CD failure."
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
See [Scheduler - Message Triggers](./scheduler.md#message-triggers-on_message) for configuration details.
|
|
188
211
|
|
|
189
212
|
## Configuration
|
|
190
213
|
|
|
@@ -241,6 +264,7 @@ The `goto_event` field accepts any valid `EventTrigger` value:
|
|
|
241
264
|
- `pr_opened`, `pr_updated`, `pr_closed`
|
|
242
265
|
- `issue_opened`, `issue_comment`
|
|
243
266
|
- `manual`, `schedule`, `webhook_received`
|
|
267
|
+
- `slack_message`
|
|
244
268
|
|
|
245
269
|
For complete documentation on failure routing, retry policies, and loop control, see [Failure Routing](./failure-routing.md).
|
|
246
270
|
|
|
@@ -300,6 +324,7 @@ visor --check security --event pr_updated
|
|
|
300
324
|
| `--event issue_comment` | Only runs checks with `on: [issue_comment]` | Test comment assistant |
|
|
301
325
|
| `--event manual` | Only runs checks with `on: [manual]` | Test manual-triggered checks |
|
|
302
326
|
| `--event schedule` | Only runs checks with `on: [schedule]` | Test scheduled/cron checks |
|
|
327
|
+
| `--event slack_message` | Only runs checks with `on: [slack_message]` | Test message trigger workflows |
|
|
303
328
|
| `--event all` | Runs all checks (except manual-only) | Default behavior, ignores `on:` filters |
|
|
304
329
|
| (no flag) | Auto-detects based on schema | Smart default |
|
|
305
330
|
|
package/dist/docs/scheduler.md
CHANGED
|
@@ -63,6 +63,160 @@ scheduler:
|
|
|
63
63
|
target: "#platform-team"
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
## Message Triggers (`on_message`)
|
|
67
|
+
|
|
68
|
+
Message triggers allow workflows to be executed reactively based on Slack messages, without requiring an @mention. This is useful for monitoring channels (e.g., CI/CD failure notifications) and automatically triggering workflows in response.
|
|
69
|
+
|
|
70
|
+
### Configuration
|
|
71
|
+
|
|
72
|
+
Add `on_message` alongside `cron` in the `scheduler` section:
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
scheduler:
|
|
76
|
+
enabled: true
|
|
77
|
+
|
|
78
|
+
on_message:
|
|
79
|
+
cicd-watcher:
|
|
80
|
+
description: "React to CI/CD failure notifications"
|
|
81
|
+
channels: ["C0CICD"] # Channel IDs (wildcard suffix supported, e.g., "CENG*")
|
|
82
|
+
from: ["U123BOT"] # Optional: only from these user IDs
|
|
83
|
+
from_bots: true # Allow bot messages (default: false)
|
|
84
|
+
contains: ["failed", "error"] # Any keyword match, case-insensitive (OR)
|
|
85
|
+
match: "build.*failed" # Regex pattern (optional)
|
|
86
|
+
threads: root_only # root_only | thread_only | any (default: any)
|
|
87
|
+
workflow: handle-cicd-failure
|
|
88
|
+
inputs:
|
|
89
|
+
source: slack
|
|
90
|
+
output:
|
|
91
|
+
type: slack
|
|
92
|
+
enabled: true
|
|
93
|
+
|
|
94
|
+
thread-responder:
|
|
95
|
+
description: "Respond in threads about deployments"
|
|
96
|
+
channels: ["C0DEPLOY"]
|
|
97
|
+
threads: thread_only # Only react to thread replies
|
|
98
|
+
contains: ["help", "stuck"]
|
|
99
|
+
workflow: deploy-help
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Filter Options
|
|
103
|
+
|
|
104
|
+
| Option | Type | Default | Description |
|
|
105
|
+
|--------|------|---------|-------------|
|
|
106
|
+
| `channels` | string[] | (all) | Channel IDs to monitor. Supports wildcard suffix (e.g., `CENG*`) |
|
|
107
|
+
| `from` | string[] | (all) | Only trigger on messages from these Slack user IDs |
|
|
108
|
+
| `from_bots` | boolean | `false` | Allow bot messages to trigger. When false, bot messages are ignored |
|
|
109
|
+
| `contains` | string[] | (all) | Keyword match — any keyword triggers (case-insensitive, OR logic) |
|
|
110
|
+
| `match` | string | (none) | Regex pattern to match against message text (case-insensitive) |
|
|
111
|
+
| `threads` | string | `any` | Thread scope: `root_only`, `thread_only`, or `any` |
|
|
112
|
+
| `workflow` | string | **(required)** | Workflow/check ID to execute when triggered |
|
|
113
|
+
| `inputs` | object | `{}` | Workflow inputs passed to the execution |
|
|
114
|
+
| `output` | object | (none) | Output destination (`type`, `target`, `thread_id`) |
|
|
115
|
+
| `description` | string | (none) | Description for logging |
|
|
116
|
+
| `enabled` | boolean | `true` | Enable/disable this trigger |
|
|
117
|
+
|
|
118
|
+
### Filter Logic
|
|
119
|
+
|
|
120
|
+
- All specified filters must pass (**AND** logic between filters)
|
|
121
|
+
- Within `contains`, any keyword match suffices (**OR** logic)
|
|
122
|
+
- Omitted filters are not checked (they match everything)
|
|
123
|
+
|
|
124
|
+
### Thread Scope
|
|
125
|
+
|
|
126
|
+
| Value | Behavior |
|
|
127
|
+
|-------|----------|
|
|
128
|
+
| `root_only` | Only react to root channel messages (no `thread_ts` or `thread_ts === ts`) |
|
|
129
|
+
| `thread_only` | Only react to thread replies (`thread_ts` exists and differs from `ts`) |
|
|
130
|
+
| `any` | React to both root messages and thread replies (default) |
|
|
131
|
+
|
|
132
|
+
When a triggered message is a thread reply, full thread conversation context is fetched via `SlackAdapter` and passed to the workflow as `slack_conversation`. When the message is a root channel message, only the single message is available.
|
|
133
|
+
|
|
134
|
+
### Message Flow
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
Slack WebSocket Event
|
|
138
|
+
→ Parse JSON, ACK
|
|
139
|
+
→ Filter subtypes (edited, etc.)
|
|
140
|
+
→ Filter self-bot messages
|
|
141
|
+
→ Filter guests
|
|
142
|
+
→ Evaluate message triggers ← NEW
|
|
143
|
+
→ For each match: dispatch workflow async
|
|
144
|
+
→ Mention gate (existing @mention path)
|
|
145
|
+
→ Thread/allowlist/dedup gates
|
|
146
|
+
→ Dispatch all checks (existing mention-based path)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Both paths can fire for the same message. A message that matches a trigger AND contains an @mention will dispatch the triggered workflow AND go through the normal mention-based dispatch. Each triggered workflow gets its own engine instance.
|
|
150
|
+
|
|
151
|
+
### Webhook Context
|
|
152
|
+
|
|
153
|
+
The triggered workflow receives via `webhookData`:
|
|
154
|
+
|
|
155
|
+
| Field | Description |
|
|
156
|
+
|-------|-------------|
|
|
157
|
+
| `event.text` | Message text |
|
|
158
|
+
| `event.user` | Sender user ID |
|
|
159
|
+
| `event.channel` | Channel ID |
|
|
160
|
+
| `event.ts` / `event.thread_ts` | Message timestamps |
|
|
161
|
+
| `trigger.id` | Which trigger matched |
|
|
162
|
+
| `trigger.type` | `on_message` |
|
|
163
|
+
| `slack_conversation` | Full thread context (if thread reply) |
|
|
164
|
+
|
|
165
|
+
The event type is `slack_message`, which can be used in step `on:` filters:
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
steps:
|
|
169
|
+
handle-cicd-failure:
|
|
170
|
+
type: ai
|
|
171
|
+
on: [slack_message]
|
|
172
|
+
prompt: "Analyze this CI/CD failure and suggest fixes."
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Deduplication
|
|
176
|
+
|
|
177
|
+
Each trigger match is deduplicated using the key `trigger:${triggerId}:${channel}:${ts}`. This prevents the same trigger from firing multiple times for duplicate Slack events.
|
|
178
|
+
|
|
179
|
+
### Hot Reload
|
|
180
|
+
|
|
181
|
+
Message triggers are rebuilt when configuration is hot-reloaded via `updateConfig()`. Adding, removing, or modifying triggers in `.visor.yaml` takes effect on the next config reload without restarting the bot.
|
|
182
|
+
|
|
183
|
+
### Example: CI/CD Failure Monitor
|
|
184
|
+
|
|
185
|
+
```yaml
|
|
186
|
+
scheduler:
|
|
187
|
+
on_message:
|
|
188
|
+
cicd-failures:
|
|
189
|
+
channels: ["C0CICD"]
|
|
190
|
+
from_bots: true
|
|
191
|
+
contains: ["failed", "error", "broken"]
|
|
192
|
+
match: "build.*#\\d+.*(failed|error)"
|
|
193
|
+
threads: root_only
|
|
194
|
+
workflow: analyze-failure
|
|
195
|
+
inputs:
|
|
196
|
+
notify_team: true
|
|
197
|
+
|
|
198
|
+
steps:
|
|
199
|
+
analyze-failure:
|
|
200
|
+
type: ai
|
|
201
|
+
on: [slack_message]
|
|
202
|
+
schema:
|
|
203
|
+
type: object
|
|
204
|
+
properties:
|
|
205
|
+
text:
|
|
206
|
+
type: string
|
|
207
|
+
severity:
|
|
208
|
+
type: string
|
|
209
|
+
enum: [low, medium, high, critical]
|
|
210
|
+
required: [text, severity]
|
|
211
|
+
prompt: |
|
|
212
|
+
A CI/CD failure was detected. Analyze the failure message and provide:
|
|
213
|
+
1. Root cause analysis
|
|
214
|
+
2. Suggested fix
|
|
215
|
+
3. Severity assessment
|
|
216
|
+
|
|
217
|
+
Failure message: {{ event.text }}
|
|
218
|
+
```
|
|
219
|
+
|
|
66
220
|
## Static Cron Jobs
|
|
67
221
|
|
|
68
222
|
Static cron jobs are defined in your configuration file and always run regardless of permission settings. They're ideal for recurring organizational tasks:
|
|
@@ -398,6 +552,7 @@ src/
|
|
|
398
552
|
│ ├── schedule-parser.ts # Natural language parsing utilities
|
|
399
553
|
│ ├── scheduler.ts # Generic scheduler daemon
|
|
400
554
|
│ ├── schedule-tool.ts # AI tool for schedule management
|
|
555
|
+
│ ├── message-trigger.ts # Slack message trigger evaluator
|
|
401
556
|
│ ├── cli-handler.ts # CLI command handlers
|
|
402
557
|
│ └── store/ # Storage backends
|
|
403
558
|
│ ├── index.ts # Backend factory
|
|
@@ -418,6 +573,7 @@ src/
|
|
|
418
573
|
|-----------|---------|
|
|
419
574
|
| `Scheduler` | Main daemon that checks for due schedules and executes them |
|
|
420
575
|
| `ScheduleStore` | Singleton for persisting schedules to JSON |
|
|
576
|
+
| `MessageTriggerEvaluator` | Evaluates Slack messages against `on_message` triggers |
|
|
421
577
|
| `ScheduleOutputAdapter` | Interface for output destinations |
|
|
422
578
|
| `SlackOutputAdapter` | Implements output posting for Slack |
|
|
423
579
|
| `schedule-tool` | AI tool definition and handler |
|
|
@@ -9,6 +9,7 @@ Visor provides bidirectional Slack integration through Socket Mode, enabling int
|
|
|
9
9
|
- [Configuration](#configuration)
|
|
10
10
|
- [Features](#features)
|
|
11
11
|
- [Example Workflows](#example-workflows)
|
|
12
|
+
- [Message Triggers](#message-triggers)
|
|
12
13
|
- [Troubleshooting](#troubleshooting)
|
|
13
14
|
- [Related Documentation](#related-documentation)
|
|
14
15
|
|
|
@@ -474,6 +475,53 @@ Log messages include:
|
|
|
474
475
|
- `[slack-frontend]` - Message posting and reactions
|
|
475
476
|
- `[prompt-state]` - Human input state management
|
|
476
477
|
|
|
478
|
+
## Message Triggers
|
|
479
|
+
|
|
480
|
+
Message triggers allow Visor to react to Slack messages in specific channels without requiring an @mention. This is configured via `scheduler.on_message` and is ideal for monitoring bot notifications (e.g., CI/CD failures, deployment alerts).
|
|
481
|
+
|
|
482
|
+
### Quick Example
|
|
483
|
+
|
|
484
|
+
```yaml
|
|
485
|
+
scheduler:
|
|
486
|
+
on_message:
|
|
487
|
+
cicd-watcher:
|
|
488
|
+
channels: ["C0CICD"]
|
|
489
|
+
from_bots: true
|
|
490
|
+
contains: ["failed", "error"]
|
|
491
|
+
workflow: handle-cicd-failure
|
|
492
|
+
|
|
493
|
+
steps:
|
|
494
|
+
handle-cicd-failure:
|
|
495
|
+
type: ai
|
|
496
|
+
on: [slack_message]
|
|
497
|
+
prompt: "Analyze this CI/CD failure and suggest a fix."
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
When a message matching the filters appears in the specified channel, Visor dispatches the configured workflow asynchronously. The workflow receives the full Slack event context including message text, sender, channel, and thread conversation history (for thread replies).
|
|
501
|
+
|
|
502
|
+
### Key Features
|
|
503
|
+
|
|
504
|
+
- **No @mention required**: Triggers fire based on message content, channel, user, and thread scope
|
|
505
|
+
- **Bot message support**: Set `from_bots: true` to react to messages from other bots (CI systems, monitoring tools)
|
|
506
|
+
- **Coexists with @mention path**: A message can trigger both a message trigger workflow and the normal @mention-based dispatch
|
|
507
|
+
- **Hot reload**: Trigger configuration is rebuilt on config hot-reload without restarting the bot
|
|
508
|
+
- **Deduplication**: Built-in dedup prevents duplicate workflow dispatches for the same Slack event
|
|
509
|
+
|
|
510
|
+
### Filter Options
|
|
511
|
+
|
|
512
|
+
| Filter | Description |
|
|
513
|
+
|--------|-------------|
|
|
514
|
+
| `channels` | Channel IDs (wildcard suffix supported, e.g., `CENG*`) |
|
|
515
|
+
| `from` | Specific user IDs |
|
|
516
|
+
| `from_bots` | Allow bot messages (default: false) |
|
|
517
|
+
| `contains` | Keyword match (case-insensitive, any = match) |
|
|
518
|
+
| `match` | Regex pattern |
|
|
519
|
+
| `threads` | `root_only`, `thread_only`, or `any` (default) |
|
|
520
|
+
|
|
521
|
+
All specified filters must pass (AND). Within `contains`, any keyword suffices (OR). Omitted filters match everything.
|
|
522
|
+
|
|
523
|
+
See [Scheduler - Message Triggers](./scheduler.md#message-triggers-on_message) for complete configuration reference.
|
|
524
|
+
|
|
477
525
|
## Scheduled Reminders
|
|
478
526
|
|
|
479
527
|
The scheduler integrates with Slack to deliver scheduled reminders and workflow results. See [Scheduler](./scheduler.md) for full documentation.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* in compliance with the Elastic License 2.0.
|
|
5
5
|
*/
|
|
6
6
|
import type { Schedule, ScheduleLimits } from '../../scheduler/schedule-store';
|
|
7
|
-
import type { ScheduleStoreBackend, ScheduleStoreStats, StorageConfig, HAConfig } from '../../scheduler/store/types';
|
|
7
|
+
import type { ScheduleStoreBackend, ScheduleStoreStats, StorageConfig, HAConfig, MessageTrigger } from '../../scheduler/store/types';
|
|
8
8
|
/**
|
|
9
9
|
* Enterprise Knex-backed store for PostgreSQL, MySQL, and MSSQL
|
|
10
10
|
*/
|
|
@@ -37,5 +37,11 @@ export declare class KnexStoreBackend implements ScheduleStoreBackend {
|
|
|
37
37
|
releaseLock(lockId: string, lockToken: string): Promise<void>;
|
|
38
38
|
renewLock(lockId: string, lockToken: string, ttlSeconds: number): Promise<boolean>;
|
|
39
39
|
flush(): Promise<void>;
|
|
40
|
+
createTrigger(trigger: Omit<MessageTrigger, 'id' | 'createdAt'>): Promise<MessageTrigger>;
|
|
41
|
+
getTrigger(id: string): Promise<MessageTrigger | undefined>;
|
|
42
|
+
updateTrigger(id: string, patch: Partial<MessageTrigger>): Promise<MessageTrigger | undefined>;
|
|
43
|
+
deleteTrigger(id: string): Promise<boolean>;
|
|
44
|
+
getTriggersByCreator(creatorId: string): Promise<MessageTrigger[]>;
|
|
45
|
+
getActiveTriggers(): Promise<MessageTrigger[]>;
|
|
40
46
|
}
|
|
41
47
|
//# sourceMappingURL=knex-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knex-store.d.ts","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/enterprise/scheduler/knex-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,QAAQ,
|
|
1
|
+
{"version":3,"file":"knex-store.d.ts","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/enterprise/scheduler/knex-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# Example: Using code-talk as an AI Custom Tool
|
|
3
|
+
# =============================================================================
|
|
4
|
+
#
|
|
5
|
+
# This example shows how to use the code-talk workflow as an AI tool,
|
|
6
|
+
# allowing an AI assistant to explore your codebase on demand.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# visor --config examples/code-talk-as-tool.yaml --message "Help me understand the codebase"
|
|
10
|
+
#
|
|
11
|
+
# =============================================================================
|
|
12
|
+
|
|
13
|
+
version: "1.0"
|
|
14
|
+
|
|
15
|
+
imports:
|
|
16
|
+
- visor://code-talk.yaml
|
|
17
|
+
|
|
18
|
+
# Define a project-specific wrapper that can be used as a tool
|
|
19
|
+
checks:
|
|
20
|
+
# Get user request
|
|
21
|
+
get-request:
|
|
22
|
+
type: human-input
|
|
23
|
+
prompt: "What would you like help with?"
|
|
24
|
+
placeholder: "e.g., Help me understand how the API endpoints work"
|
|
25
|
+
|
|
26
|
+
# AI assistant with code exploration tool
|
|
27
|
+
assistant:
|
|
28
|
+
type: ai
|
|
29
|
+
depends_on: [get-request]
|
|
30
|
+
ai:
|
|
31
|
+
skip_code_context: true
|
|
32
|
+
prompt_type: general
|
|
33
|
+
prompt: |
|
|
34
|
+
You are a helpful assistant for this project.
|
|
35
|
+
|
|
36
|
+
The user asked: {{ outputs['get-request'].text }}
|
|
37
|
+
|
|
38
|
+
You have access to the code-talk tool which can explore the codebase
|
|
39
|
+
and answer technical questions with code references.
|
|
40
|
+
|
|
41
|
+
Use the code-talk tool when you need to:
|
|
42
|
+
- Find specific implementations
|
|
43
|
+
- Understand how components work
|
|
44
|
+
- Locate relevant code files
|
|
45
|
+
- Answer technical questions about the codebase
|
|
46
|
+
|
|
47
|
+
After getting information from the tool, provide a clear and helpful response.
|
|
48
|
+
|
|
49
|
+
ai_custom_tools:
|
|
50
|
+
# Use code-talk directly as a tool
|
|
51
|
+
- workflow: code-talk
|
|
52
|
+
args:
|
|
53
|
+
# Pre-configure with your project settings
|
|
54
|
+
architecture: |
|
|
55
|
+
# Project Architecture
|
|
56
|
+
Describe your project here.
|
|
57
|
+
|
|
58
|
+
projects:
|
|
59
|
+
- id: my-project
|
|
60
|
+
repo: your-org/your-repo
|
|
61
|
+
description: Main project codebase
|
|
62
|
+
|
|
63
|
+
max_projects: 1
|
|
64
|
+
|
|
65
|
+
# Show the result
|
|
66
|
+
show-result:
|
|
67
|
+
type: log
|
|
68
|
+
depends_on: [assistant]
|
|
69
|
+
message: |
|
|
70
|
+
===============================================================
|
|
71
|
+
Assistant Response
|
|
72
|
+
===============================================================
|
|
73
|
+
|
|
74
|
+
{{ outputs['assistant'].content }}
|
|
75
|
+
|
|
76
|
+
===============================================================
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# Example: Using code-talk as a Standard Workflow
|
|
3
|
+
# =============================================================================
|
|
4
|
+
#
|
|
5
|
+
# This example shows how to use the code-talk workflow for interactive
|
|
6
|
+
# code exploration in your project.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# visor --config examples/code-talk-workflow.yaml --message "How does auth work?"
|
|
10
|
+
#
|
|
11
|
+
# =============================================================================
|
|
12
|
+
|
|
13
|
+
version: "1.0"
|
|
14
|
+
|
|
15
|
+
imports:
|
|
16
|
+
- visor://code-talk.yaml
|
|
17
|
+
|
|
18
|
+
checks:
|
|
19
|
+
# Get the user's question
|
|
20
|
+
get-question:
|
|
21
|
+
type: human-input
|
|
22
|
+
prompt: "What would you like to know about the codebase?"
|
|
23
|
+
placeholder: "e.g., How does the authentication system work?"
|
|
24
|
+
|
|
25
|
+
# Call code-talk with your project configuration
|
|
26
|
+
explore:
|
|
27
|
+
type: workflow
|
|
28
|
+
workflow: code-talk
|
|
29
|
+
criticality: internal
|
|
30
|
+
depends_on: [get-question]
|
|
31
|
+
args:
|
|
32
|
+
question: "{{ outputs['get-question'].text }}"
|
|
33
|
+
|
|
34
|
+
# Customize this for your project
|
|
35
|
+
architecture: |
|
|
36
|
+
# Project Architecture
|
|
37
|
+
|
|
38
|
+
## Overview
|
|
39
|
+
Describe your project architecture here.
|
|
40
|
+
|
|
41
|
+
## Key Components
|
|
42
|
+
- Component A: Description
|
|
43
|
+
- Component B: Description
|
|
44
|
+
|
|
45
|
+
## Project IDs
|
|
46
|
+
| ID | Description |
|
|
47
|
+
|----|-------------|
|
|
48
|
+
| `my-project` | Main project codebase |
|
|
49
|
+
|
|
50
|
+
## Key Directories
|
|
51
|
+
- `src/` - Source code
|
|
52
|
+
- `tests/` - Test files
|
|
53
|
+
|
|
54
|
+
# GitHub repository for docs (optional)
|
|
55
|
+
docs_repo: your-org/your-repo
|
|
56
|
+
docs_ref: main
|
|
57
|
+
|
|
58
|
+
# Define your projects
|
|
59
|
+
projects:
|
|
60
|
+
- id: my-project
|
|
61
|
+
repo: your-org/your-repo
|
|
62
|
+
description: |
|
|
63
|
+
Main project codebase:
|
|
64
|
+
- src/ - Source code
|
|
65
|
+
- tests/ - Test files
|
|
66
|
+
|
|
67
|
+
# Limit to single project for focused analysis
|
|
68
|
+
max_projects: 1
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# Example: Using intent-router for Assistant Routing
|
|
3
|
+
# =============================================================================
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# visor --config examples/intent-router-workflow.yaml --message "Summarize this thread"
|
|
7
|
+
#
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
version: "1.0"
|
|
11
|
+
|
|
12
|
+
imports:
|
|
13
|
+
- visor://intent-router.yaml
|
|
14
|
+
|
|
15
|
+
checks:
|
|
16
|
+
ask:
|
|
17
|
+
type: human-input
|
|
18
|
+
prompt: "What should I do with this message?"
|
|
19
|
+
placeholder: "e.g., Summarize the thread and list action items"
|
|
20
|
+
|
|
21
|
+
route-intent:
|
|
22
|
+
type: workflow
|
|
23
|
+
workflow: intent-router
|
|
24
|
+
criticality: internal
|
|
25
|
+
depends_on: [ask]
|
|
26
|
+
args:
|
|
27
|
+
question: "{{ outputs['ask'].text }}"
|
|
28
|
+
intents:
|
|
29
|
+
- id: chat
|
|
30
|
+
description: general Q&A or small talk
|
|
31
|
+
- id: thread_summary
|
|
32
|
+
description: user explicitly asks for a summary of the thread
|
|
33
|
+
- id: code_help
|
|
34
|
+
description: questions about code, debugging, or implementation details
|
|
35
|
+
tags:
|
|
36
|
+
- id: jira
|
|
37
|
+
description: request references Jira tickets or needs Jira data
|
|
38
|
+
- id: confluence
|
|
39
|
+
description: request references Confluence pages or needs Confluence data
|
|
40
|
+
- id: codebase
|
|
41
|
+
description: request needs codebase or implementation details
|
|
42
|
+
routing_instructions: |
|
|
43
|
+
Prefer thread_summary when the user asks to summarize or extract action items.
|
|
44
|
+
|
|
45
|
+
chat-answer:
|
|
46
|
+
type: ai
|
|
47
|
+
depends_on: [route-intent]
|
|
48
|
+
if: "outputs['route-intent']?.intent === 'chat'"
|
|
49
|
+
prompt: |
|
|
50
|
+
Answer the user's question:
|
|
51
|
+
{{ outputs['route-intent'].topic }}
|
|
52
|
+
|
|
53
|
+
summarize-thread:
|
|
54
|
+
type: ai
|
|
55
|
+
depends_on: [route-intent]
|
|
56
|
+
if: "outputs['route-intent']?.intent === 'thread_summary'"
|
|
57
|
+
prompt: |
|
|
58
|
+
Summarize the thread and list action items.
|
|
59
|
+
|
|
60
|
+
code-help:
|
|
61
|
+
type: ai
|
|
62
|
+
depends_on: [route-intent]
|
|
63
|
+
if: "outputs['route-intent']?.intent === 'code_help'"
|
|
64
|
+
prompt: |
|
|
65
|
+
Provide a short technical explanation for:
|
|
66
|
+
{{ outputs['route-intent'].topic }}
|