@probelabs/visor 0.1.124 → 0.1.126

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 (195) hide show
  1. package/dist/config.d.ts.map +1 -1
  2. package/dist/docs/DEPLOYMENT.md +117 -11
  3. package/dist/docs/GITHUB_CHECKS.md +18 -4
  4. package/dist/docs/NPM_USAGE.md +112 -39
  5. package/dist/docs/action-reference.md +63 -9
  6. package/dist/docs/advanced-ai.md +58 -51
  7. package/dist/docs/ai-configuration.md +99 -11
  8. package/dist/docs/ai-custom-tools-usage.md +70 -33
  9. package/dist/docs/ai-custom-tools.md +50 -27
  10. package/dist/docs/architecture.md +1232 -0
  11. package/dist/docs/bot-transports-rfc.md +13 -3
  12. package/dist/docs/ci-cli-mode.md +116 -8
  13. package/dist/docs/claude-code.md +111 -41
  14. package/dist/docs/command-provider.md +37 -15
  15. package/dist/docs/commands.md +252 -6
  16. package/dist/docs/configuration.md +138 -4
  17. package/dist/docs/contributing.md +737 -0
  18. package/dist/docs/custom-tools.md +39 -8
  19. package/dist/docs/dashboards/README.md +33 -19
  20. package/dist/docs/debug-visualizer-progress.md +14 -13
  21. package/dist/docs/debug-visualizer-rfc.md +14 -13
  22. package/dist/docs/debug-visualizer.md +30 -5
  23. package/dist/docs/debugging.md +73 -8
  24. package/dist/docs/default-output-schema.md +24 -20
  25. package/dist/docs/dependencies.md +75 -21
  26. package/dist/docs/dev-playbook.md +85 -9
  27. package/dist/docs/engine-pause-resume-rfc.md +11 -11
  28. package/dist/docs/engine-state-machine-plan.md +10 -3
  29. package/dist/docs/event-driven-github-integration-rfc.md +20 -11
  30. package/dist/docs/event-triggers.md +95 -6
  31. package/dist/docs/execution-statistics-rfc.md +16 -4
  32. package/dist/docs/fact-validator-gap-analysis.md +12 -1
  33. package/dist/docs/fact-validator-implementation-plan.md +19 -11
  34. package/dist/docs/fail-if.md +116 -11
  35. package/dist/docs/failure-conditions-implementation.md +40 -6
  36. package/dist/docs/failure-conditions-schema.md +243 -87
  37. package/dist/docs/failure-routing-rfc.md +43 -18
  38. package/dist/docs/failure-routing.md +80 -23
  39. package/dist/docs/faq.md +836 -0
  40. package/dist/docs/foreach-dependency-propagation.md +32 -15
  41. package/dist/docs/github-ops.md +6 -5
  42. package/dist/docs/glossary.md +322 -0
  43. package/dist/docs/goto-forward-run-plan.md +23 -10
  44. package/dist/docs/guides/criticality-modes.md +15 -13
  45. package/dist/docs/guides/fault-management-and-contracts.md +8 -5
  46. package/dist/docs/guides/workflow-style-guide.md +17 -8
  47. package/dist/docs/http.md +102 -3
  48. package/dist/docs/human-input-provider.md +20 -36
  49. package/dist/docs/index.md +206 -0
  50. package/dist/docs/lifecycle-hooks.md +322 -2
  51. package/dist/docs/limits.md +20 -5
  52. package/dist/docs/liquid-templates.md +86 -14
  53. package/dist/docs/loop-routing-refactor.md +4 -2
  54. package/dist/docs/mcp-provider.md +53 -19
  55. package/dist/docs/mcp.md +27 -1
  56. package/dist/docs/memory.md +7 -2
  57. package/dist/docs/migration.md +596 -0
  58. package/dist/docs/observability.md +227 -6
  59. package/dist/docs/output-formats.md +388 -9
  60. package/dist/docs/output-history.md +36 -6
  61. package/dist/docs/performance.md +510 -4
  62. package/dist/docs/pluggable.md +95 -4
  63. package/dist/docs/proposals/snapshot-scope-execution.md +6 -5
  64. package/dist/docs/providers/git-checkout.md +16 -14
  65. package/dist/docs/providers/noop.md +696 -0
  66. package/dist/docs/recipes.md +8 -9
  67. package/dist/docs/rfc/git-checkout-step.md +3 -1
  68. package/dist/docs/rfc/on_init-hook.md +18 -5
  69. package/dist/docs/rfc/workspace-isolation.md +16 -0
  70. package/dist/docs/roadmap/criticality-implementation-tasks.md +27 -27
  71. package/dist/docs/router-patterns.md +155 -43
  72. package/dist/docs/schema-templates.md +51 -15
  73. package/dist/docs/script.md +162 -13
  74. package/dist/docs/sdk.md +46 -12
  75. package/dist/docs/security.md +464 -5
  76. package/dist/docs/slack-integration.md +481 -0
  77. package/dist/docs/tag-filtering.md +60 -20
  78. package/dist/docs/telemetry-setup.md +157 -46
  79. package/dist/docs/test-framework-rfc.md +37 -36
  80. package/dist/docs/testing/assertions.md +92 -4
  81. package/dist/docs/testing/ci.md +56 -7
  82. package/dist/docs/testing/cli.md +57 -15
  83. package/dist/docs/testing/cookbook.md +53 -20
  84. package/dist/docs/testing/dsl-reference.md +110 -9
  85. package/dist/docs/testing/fixtures-and-mocks.md +28 -3
  86. package/dist/docs/testing/flows.md +59 -4
  87. package/dist/docs/testing/getting-started.md +14 -13
  88. package/dist/docs/testing/troubleshooting.md +39 -2
  89. package/dist/docs/timeouts.md +174 -18
  90. package/dist/docs/troubleshooting.md +176 -6
  91. package/dist/docs/workflow-creation-guide.md +101 -3
  92. package/dist/docs/workflows.md +138 -41
  93. package/dist/examples/README.md +169 -4
  94. package/dist/examples/ai-custom-tools-simple.yaml +2 -3
  95. package/dist/examples/cron-webhook-config.yaml +15 -0
  96. package/dist/examples/forEach-example.yaml +6 -0
  97. package/dist/examples/git-checkout-basic.yaml +4 -0
  98. package/dist/examples/git-checkout-compare.yaml +6 -0
  99. package/dist/examples/git-checkout-cross-repo.yaml +7 -0
  100. package/dist/examples/http-integration-config.yaml +30 -0
  101. package/dist/examples/https-server-config.yaml +15 -0
  102. package/dist/examples/mcp-provider-example.yaml +10 -10
  103. package/dist/examples/transform-example.yaml +3 -0
  104. package/dist/examples/webhook-pipeline-config.yaml +18 -0
  105. package/dist/examples/workflows/workflow-composition-example.yaml +4 -0
  106. package/dist/frontends/slack-frontend.d.ts +2 -0
  107. package/dist/frontends/slack-frontend.d.ts.map +1 -1
  108. package/dist/generated/config-schema.d.ts +11 -7
  109. package/dist/generated/config-schema.d.ts.map +1 -1
  110. package/dist/generated/config-schema.json +11 -7
  111. package/dist/index.js +3127 -974
  112. package/dist/output/traces/{run-2026-01-28T16-15-24-569Z.ndjson → run-2026-01-31T16-37-22-321Z.ndjson} +84 -84
  113. package/dist/output/traces/{run-2026-01-28T16-16-09-757Z.ndjson → run-2026-01-31T16-38-06-031Z.ndjson} +1013 -1013
  114. package/dist/providers/ai-check-provider.d.ts +9 -2
  115. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  116. package/dist/providers/command-check-provider.d.ts.map +1 -1
  117. package/dist/providers/mcp-custom-sse-server.d.ts +17 -1
  118. package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
  119. package/dist/providers/workflow-check-provider.d.ts.map +1 -1
  120. package/dist/providers/workflow-tool-executor.d.ts +68 -0
  121. package/dist/providers/workflow-tool-executor.d.ts.map +1 -0
  122. package/dist/sdk/{check-provider-registry-AQ3JETBG.mjs → check-provider-registry-3KI5RKXT.mjs} +6 -5
  123. package/dist/sdk/check-provider-registry-IYILYY35.mjs +28 -0
  124. package/dist/sdk/chunk-2CPMMNIX.mjs +1459 -0
  125. package/dist/sdk/chunk-2CPMMNIX.mjs.map +1 -0
  126. package/dist/sdk/chunk-5LI6T4O3.mjs +3600 -0
  127. package/dist/sdk/chunk-5LI6T4O3.mjs.map +1 -0
  128. package/dist/sdk/{chunk-YLQ4UN62.mjs → chunk-A4PGHURG.mjs} +6838 -6257
  129. package/dist/sdk/chunk-A4PGHURG.mjs.map +1 -0
  130. package/dist/sdk/chunk-EXFGO4FX.mjs +147 -0
  131. package/dist/sdk/chunk-EXFGO4FX.mjs.map +1 -0
  132. package/dist/sdk/chunk-PJ7K5UFC.mjs +17732 -0
  133. package/dist/sdk/chunk-PJ7K5UFC.mjs.map +1 -0
  134. package/dist/sdk/{chunk-BHZ4CKUS.mjs → chunk-PXFIALUH.mjs} +77 -8
  135. package/dist/sdk/chunk-PXFIALUH.mjs.map +1 -0
  136. package/dist/sdk/{chunk-PVITVJ6J.mjs → chunk-RTKJXNZS.mjs} +32 -9
  137. package/dist/sdk/chunk-RTKJXNZS.mjs.map +1 -0
  138. package/dist/sdk/chunk-VW2GBXQT.mjs +606 -0
  139. package/dist/sdk/chunk-VW2GBXQT.mjs.map +1 -0
  140. package/dist/sdk/{config-RQQPMLRD.mjs → config-5AUYQFHE.mjs} +2 -2
  141. package/dist/sdk/config-6CUVEH7H.mjs +16 -0
  142. package/dist/sdk/config-6CUVEH7H.mjs.map +1 -0
  143. package/dist/sdk/{github-frontend-6Q4BISZX.mjs → github-frontend-BZ4N3BFZ.mjs} +7 -3
  144. package/dist/sdk/github-frontend-BZ4N3BFZ.mjs.map +1 -0
  145. package/dist/sdk/host-4MT3EW2I.mjs +52 -0
  146. package/dist/sdk/{host-P5NQICP7.mjs → host-NYWXLIFC.mjs} +2 -2
  147. package/dist/sdk/host-NYWXLIFC.mjs.map +1 -0
  148. package/dist/sdk/{routing-DEY2AIXM.mjs → routing-6R42GXUO.mjs} +2 -2
  149. package/dist/sdk/routing-6R42GXUO.mjs.map +1 -0
  150. package/dist/sdk/routing-7FXPULTO.mjs +24 -0
  151. package/dist/sdk/routing-7FXPULTO.mjs.map +1 -0
  152. package/dist/sdk/sdk.d.mts +3 -1
  153. package/dist/sdk/sdk.d.ts +3 -1
  154. package/dist/sdk/sdk.js +12163 -11204
  155. package/dist/sdk/sdk.js.map +1 -1
  156. package/dist/sdk/sdk.mjs +14 -10
  157. package/dist/sdk/sdk.mjs.map +1 -1
  158. package/dist/sdk/slack-frontend-JUT3TYVC.mjs +821 -0
  159. package/dist/sdk/slack-frontend-JUT3TYVC.mjs.map +1 -0
  160. package/dist/sdk/workflow-check-provider-H3CUOLUD.mjs +28 -0
  161. package/dist/sdk/workflow-check-provider-H3CUOLUD.mjs.map +1 -0
  162. package/dist/sdk/workflow-check-provider-YUNNF4KC.mjs +28 -0
  163. package/dist/sdk/workflow-check-provider-YUNNF4KC.mjs.map +1 -0
  164. package/dist/sdk/workflow-registry-KFWSDSLM.mjs +12 -0
  165. package/dist/sdk/workflow-registry-KFWSDSLM.mjs.map +1 -0
  166. package/dist/slack/socket-runner.d.ts +2 -0
  167. package/dist/slack/socket-runner.d.ts.map +1 -1
  168. package/dist/state-machine/context/workflow-inputs.d.ts +20 -0
  169. package/dist/state-machine/context/workflow-inputs.d.ts.map +1 -0
  170. package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
  171. package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -1
  172. package/dist/state-machine/dispatch/stats-manager.d.ts.map +1 -1
  173. package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
  174. package/dist/state-machine/states/routing.d.ts +2 -1
  175. package/dist/state-machine/states/routing.d.ts.map +1 -1
  176. package/dist/traces/{run-2026-01-28T16-15-24-569Z.ndjson → run-2026-01-31T16-37-22-321Z.ndjson} +84 -84
  177. package/dist/traces/{run-2026-01-28T16-16-09-757Z.ndjson → run-2026-01-31T16-38-06-031Z.ndjson} +1013 -1013
  178. package/dist/types/config.d.ts +3 -1
  179. package/dist/types/config.d.ts.map +1 -1
  180. package/dist/utils/human-id.d.ts +12 -0
  181. package/dist/utils/human-id.d.ts.map +1 -0
  182. package/dist/utils/worktree-manager.d.ts +3 -0
  183. package/dist/utils/worktree-manager.d.ts.map +1 -1
  184. package/dist/workflow-executor.d.ts.map +1 -1
  185. package/dist/workflow-registry.d.ts +1 -0
  186. package/dist/workflow-registry.d.ts.map +1 -1
  187. package/package.json +2 -2
  188. package/dist/sdk/chunk-BHZ4CKUS.mjs.map +0 -1
  189. package/dist/sdk/chunk-PVITVJ6J.mjs.map +0 -1
  190. package/dist/sdk/chunk-YLQ4UN62.mjs.map +0 -1
  191. package/dist/sdk/github-frontend-6Q4BISZX.mjs.map +0 -1
  192. /package/dist/sdk/{check-provider-registry-AQ3JETBG.mjs.map → check-provider-registry-3KI5RKXT.mjs.map} +0 -0
  193. /package/dist/sdk/{config-RQQPMLRD.mjs.map → check-provider-registry-IYILYY35.mjs.map} +0 -0
  194. /package/dist/sdk/{routing-DEY2AIXM.mjs.map → config-5AUYQFHE.mjs.map} +0 -0
  195. /package/dist/sdk/{host-P5NQICP7.mjs.map → host-4MT3EW2I.mjs.map} +0 -0
@@ -0,0 +1,836 @@
1
+ # Frequently Asked Questions (FAQ)
2
+
3
+ This document answers common questions about Visor, the AI-powered workflow orchestration tool for code review, automation, and CI/CD pipelines.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ - [General Questions](#general-questions)
10
+ - [Configuration Questions](#configuration-questions)
11
+ - [GitHub Actions Questions](#github-actions-questions)
12
+ - [Provider Questions](#provider-questions)
13
+ - [Troubleshooting](#troubleshooting)
14
+ - [Advanced Topics](#advanced-topics)
15
+
16
+ ---
17
+
18
+ ## General Questions
19
+
20
+ ### What is Visor?
21
+
22
+ Visor is an AI-powered workflow orchestration tool that can perform intelligent code review, automate CI/CD tasks, and integrate with various services. It supports multiple AI providers (Google Gemini, Anthropic Claude, OpenAI GPT, AWS Bedrock) and can run as both a GitHub Action and a CLI tool.
23
+
24
+ Key capabilities:
25
+ - Automated code review for pull requests
26
+ - Security, performance, and style analysis
27
+ - Custom workflow automation with 15+ provider types
28
+ - MCP (Model Context Protocol) tool integration
29
+ - Slack and HTTP webhook integrations
30
+
31
+ ### How is Visor different from other code review tools?
32
+
33
+ Unlike traditional linters that rely on static rules, Visor uses AI to understand context and provide nuanced feedback. Key differentiators:
34
+
35
+ 1. **AI-powered analysis**: Uses LLMs to understand code intent and provide contextual suggestions
36
+ 2. **Workflow orchestration**: Not just code review - supports complex multi-step workflows with routing, retries, and state management
37
+ 3. **Pluggable architecture**: 15+ provider types (AI, command, MCP, HTTP, memory, etc.) that can be combined
38
+ 4. **Configuration-driven**: Define workflows in YAML without writing code
39
+ 5. **Multiple transports**: Works as GitHub Action, CLI tool, or Slack bot
40
+
41
+ ### Can Visor run without AI? What happens then?
42
+
43
+ Yes. If no AI API key is configured, Visor falls back to fast, heuristic-based checks using simple pattern matching for basic style and performance issues.
44
+
45
+ To use AI-powered features, set one of these environment variables:
46
+ - `GOOGLE_API_KEY` for Google Gemini
47
+ - `ANTHROPIC_API_KEY` for Anthropic Claude
48
+ - `OPENAI_API_KEY` for OpenAI GPT
49
+ - AWS credentials for AWS Bedrock
50
+
51
+ ### What are the supported AI providers?
52
+
53
+ | Provider | Environment Variable | Example Models |
54
+ |----------|---------------------|----------------|
55
+ | Google Gemini | `GOOGLE_API_KEY` | `gemini-2.0-flash-exp`, `gemini-1.5-pro` |
56
+ | Anthropic Claude | `ANTHROPIC_API_KEY` | `claude-3-5-sonnet-latest`, `claude-3-opus-latest` |
57
+ | OpenAI GPT | `OPENAI_API_KEY` | `gpt-4o`, `gpt-4-turbo` |
58
+ | AWS Bedrock | AWS credentials | `anthropic.claude-sonnet-4-20250514-v1:0` |
59
+
60
+ See [AI Configuration](./ai-configuration.md) for complete setup instructions.
61
+
62
+ ### How do I install Visor?
63
+
64
+ **Quick start (no installation required):**
65
+ ```bash
66
+ npx -y @probelabs/visor@latest --help
67
+ ```
68
+
69
+ **Global installation:**
70
+ ```bash
71
+ npm install -g @probelabs/visor
72
+ ```
73
+
74
+ **Project dependency:**
75
+ ```bash
76
+ npm install --save-dev @probelabs/visor
77
+ ```
78
+
79
+ See [NPM Usage](./NPM_USAGE.md) for detailed installation options.
80
+
81
+ ---
82
+
83
+ ## Configuration Questions
84
+
85
+ ### Where should I put my configuration file?
86
+
87
+ Visor looks for configuration in this order:
88
+ 1. CLI `--config` parameter
89
+ 2. `.visor.yaml` in the project root (note the leading dot)
90
+ 3. Default configuration
91
+
92
+ **Example:**
93
+ ```bash
94
+ # Use default location (.visor.yaml)
95
+ visor --check all
96
+
97
+ # Use custom config file
98
+ visor --config path/to/my-config.yaml
99
+ ```
100
+
101
+ ### How do I validate my configuration?
102
+
103
+ Use the `validate` command to check for errors before running:
104
+
105
+ ```bash
106
+ # Validate default config
107
+ visor validate
108
+
109
+ # Validate specific file
110
+ visor validate --config .visor.yaml
111
+ ```
112
+
113
+ The validator checks for:
114
+ - Missing required fields
115
+ - Invalid check types
116
+ - Incorrect event triggers
117
+ - Schema compliance
118
+
119
+ See [Configuration](./configuration.md#validating-configuration) for details.
120
+
121
+ ### How do I configure multiple AI providers?
122
+
123
+ You can set a global default and override per-check:
124
+
125
+ ```yaml
126
+ # Global default
127
+ ai_provider: anthropic
128
+ ai_model: claude-3-5-sonnet-latest
129
+
130
+ steps:
131
+ # This uses the global default (Anthropic)
132
+ security-review:
133
+ type: ai
134
+ prompt: "Analyze security vulnerabilities"
135
+
136
+ # This overrides to use Google
137
+ performance-review:
138
+ type: ai
139
+ ai_provider: google
140
+ ai_model: gemini-2.0-flash-exp
141
+ prompt: "Analyze performance issues"
142
+
143
+ # Alternative syntax using nested 'ai' block
144
+ style-review:
145
+ type: ai
146
+ ai:
147
+ provider: openai
148
+ model: gpt-4o
149
+ prompt: "Review code style"
150
+ ```
151
+
152
+ ### How do I enable or disable specific checks?
153
+
154
+ Use the `on` field to control when checks run:
155
+
156
+ ```yaml
157
+ steps:
158
+ # Runs on PR open and update
159
+ security-check:
160
+ type: ai
161
+ on: [pr_opened, pr_updated]
162
+ prompt: "Check for security issues"
163
+
164
+ # Disable a check by setting on to empty
165
+ disabled-check:
166
+ type: ai
167
+ on: [] # Never runs
168
+ ```
169
+
170
+ You can also use tags and the CLI to filter checks:
171
+
172
+ ```bash
173
+ # Run only checks tagged 'security'
174
+ visor --tags security
175
+
176
+ # Exclude checks tagged 'experimental'
177
+ visor --exclude-tags experimental
178
+ ```
179
+
180
+ See [Tag Filtering](./tag-filtering.md) for more options.
181
+
182
+ ### How do I configure custom tools?
183
+
184
+ Define tools in the `tools` section and reference them in checks:
185
+
186
+ ```yaml
187
+ tools:
188
+ my-lint-tool:
189
+ name: my-lint-tool
190
+ description: Run custom linter
191
+ inputSchema:
192
+ type: object
193
+ properties:
194
+ files:
195
+ type: array
196
+ items:
197
+ type: string
198
+ required: [files]
199
+ exec: 'eslint {{ args.files | join: " " }}'
200
+
201
+ steps:
202
+ run-linter:
203
+ type: mcp
204
+ transport: custom
205
+ method: my-lint-tool
206
+ methodArgs:
207
+ files: ["src/**/*.ts"]
208
+ ```
209
+
210
+ See [Custom Tools](./custom-tools.md) for complete documentation.
211
+
212
+ ### How do I share configuration across projects?
213
+
214
+ Use the `extends` field to inherit from base configurations:
215
+
216
+ ```yaml
217
+ # .visor.yaml
218
+ extends:
219
+ - ./team-standards.yaml # Local file
220
+ - default # Built-in defaults
221
+
222
+ steps:
223
+ my-custom-check:
224
+ type: ai
225
+ prompt: "Project-specific analysis"
226
+ ```
227
+
228
+ You can also extend remote configurations:
229
+ ```bash
230
+ visor --allowed-remote-patterns "https://github.com/myorg/"
231
+ ```
232
+
233
+ See [Configuration Inheritance](./configuration.md#configuration-inheritance-with-extends).
234
+
235
+ ---
236
+
237
+ ## GitHub Actions Questions
238
+
239
+ ### How do I set up Visor as a GitHub Action?
240
+
241
+ Create `.github/workflows/visor.yml`:
242
+
243
+ ```yaml
244
+ name: Visor Code Review
245
+ on:
246
+ pull_request:
247
+ types: [opened, synchronize]
248
+
249
+ permissions:
250
+ contents: read
251
+ pull-requests: write
252
+ issues: write
253
+ checks: write
254
+
255
+ jobs:
256
+ review:
257
+ runs-on: ubuntu-latest
258
+ steps:
259
+ - uses: actions/checkout@v4
260
+ - uses: buger/visor@main
261
+ with:
262
+ github-token: ${{ secrets.GITHUB_TOKEN }}
263
+ env:
264
+ GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
265
+ ```
266
+
267
+ See [Action Reference](./action-reference.md) for all available inputs and outputs.
268
+
269
+ ### What GitHub events trigger Visor?
270
+
271
+ | Event | Trigger | Use Case |
272
+ |-------|---------|----------|
273
+ | `pull_request` (opened) | `pr_opened` | New PR review |
274
+ | `pull_request` (synchronize) | `pr_updated` | Updated PR review |
275
+ | `pull_request` (closed) | `pr_closed` | PR close handling |
276
+ | `issues` (opened) | `issue_opened` | Issue assistants |
277
+ | `issue_comment` | `issue_comment` | Comment commands |
278
+ | `schedule` | `schedule` | Cron jobs |
279
+ | `workflow_dispatch` | `schedule` | Manual triggers |
280
+
281
+ See [Event Triggers](./event-triggers.md) for complete documentation.
282
+
283
+ ### How do I customize what gets reviewed?
284
+
285
+ Use the `on` field and conditions:
286
+
287
+ ```yaml
288
+ steps:
289
+ # Only review TypeScript files
290
+ ts-review:
291
+ type: ai
292
+ on: [pr_opened, pr_updated]
293
+ if: "files.some(f => f.filename.endsWith('.ts'))"
294
+ prompt: "Review TypeScript code"
295
+
296
+ # Only review on main branch PRs
297
+ main-review:
298
+ type: ai
299
+ on: [pr_opened]
300
+ if: "pr.base === 'main'"
301
+ prompt: "Review changes to main"
302
+ ```
303
+
304
+ ### How do I handle large PRs?
305
+
306
+ For large PRs, consider:
307
+
308
+ 1. **Increase timeout:**
309
+ ```yaml
310
+ steps:
311
+ review:
312
+ type: ai
313
+ timeout: 300000 # 5 minutes
314
+ ```
315
+
316
+ 2. **Run checks in parallel:**
317
+ ```yaml
318
+ max_parallelism: 5
319
+ ```
320
+
321
+ 3. **Split into focused checks:**
322
+ ```yaml
323
+ steps:
324
+ security-review:
325
+ type: ai
326
+ prompt: "Focus only on security"
327
+
328
+ style-review:
329
+ type: ai
330
+ prompt: "Focus only on style"
331
+ ```
332
+
333
+ 4. **Filter by file type:**
334
+ ```yaml
335
+ steps:
336
+ js-review:
337
+ type: ai
338
+ if: "files.some(f => f.filename.endsWith('.js'))"
339
+ ```
340
+
341
+ ### Why am I getting permission errors on fork PRs?
342
+
343
+ Fork PRs have restricted permissions by default. Solutions:
344
+
345
+ 1. **Accept comment-only mode**: Visor falls back to PR comments automatically
346
+ 2. **Use `pull_request_target`**: For full check run support (requires careful security review)
347
+
348
+ See [GitHub Checks - Fork PR Support](./GITHUB_CHECKS.md#fork-pr-support).
349
+
350
+ ---
351
+
352
+ ## Provider Questions
353
+
354
+ ### Which AI provider should I use?
355
+
356
+ | Provider | Best For | Notes |
357
+ |----------|----------|-------|
358
+ | **Anthropic Claude** | Complex code analysis, security review | Strong reasoning, good context handling |
359
+ | **Google Gemini** | Fast analysis, cost-effective | Good for high-volume reviews |
360
+ | **OpenAI GPT-4** | General-purpose analysis | Wide model availability |
361
+ | **AWS Bedrock** | Enterprise environments | IAM integration, private endpoints |
362
+
363
+ For most use cases, start with whichever provider you already have API access to.
364
+
365
+ ### How do I add custom checks?
366
+
367
+ Several provider types support custom logic:
368
+
369
+ **Command provider (shell commands):**
370
+ ```yaml
371
+ steps:
372
+ custom-lint:
373
+ type: command
374
+ exec: "npm run lint"
375
+ ```
376
+
377
+ **Script provider (JavaScript):**
378
+ ```yaml
379
+ steps:
380
+ custom-analysis:
381
+ type: script
382
+ content: |
383
+ const largeFiles = pr.files.filter(f => f.additions > 100);
384
+ return {
385
+ hasLargeChanges: largeFiles.length > 0,
386
+ files: largeFiles.map(f => f.filename)
387
+ };
388
+ ```
389
+
390
+ **AI provider (custom prompts):**
391
+ ```yaml
392
+ steps:
393
+ domain-review:
394
+ type: ai
395
+ prompt: |
396
+ You are an expert in our domain. Review this code for:
397
+ - Business logic correctness
398
+ - Domain model violations
399
+ - API contract adherence
400
+ ```
401
+
402
+ ### How do I use MCP tools?
403
+
404
+ The MCP provider supports direct tool execution via multiple transports:
405
+
406
+ **stdio transport (local command):**
407
+ ```yaml
408
+ steps:
409
+ probe-search:
410
+ type: mcp
411
+ transport: stdio
412
+ command: npx
413
+ command_args: ["-y", "@probelabs/probe@latest", "mcp"]
414
+ method: search_code
415
+ methodArgs:
416
+ query: "TODO"
417
+ ```
418
+
419
+ **HTTP transport (remote server):**
420
+ ```yaml
421
+ steps:
422
+ remote-tool:
423
+ type: mcp
424
+ transport: http
425
+ url: https://mcp-server.example.com/mcp
426
+ method: analyze
427
+ methodArgs:
428
+ data: "{{ pr.title }}"
429
+ ```
430
+
431
+ **Custom transport (YAML-defined tools):**
432
+ ```yaml
433
+ tools:
434
+ grep-tool:
435
+ exec: 'grep -rn "{{ args.pattern }}" src/'
436
+
437
+ steps:
438
+ search:
439
+ type: mcp
440
+ transport: custom
441
+ method: grep-tool
442
+ methodArgs:
443
+ pattern: "FIXME"
444
+ ```
445
+
446
+ See [MCP Provider](./mcp-provider.md) for complete documentation.
447
+
448
+ ### What's the difference between command and script providers?
449
+
450
+ | Feature | `command` | `script` |
451
+ |---------|-----------|----------|
452
+ | Execution | Shell commands | JavaScript sandbox |
453
+ | Use case | External tools, shell scripts | Logic, data processing |
454
+ | Access | File system, external commands | PR context, memory, outputs |
455
+ | Security | Runs with process permissions | Sandboxed environment |
456
+
457
+ **Use `command` for:**
458
+ ```yaml
459
+ steps:
460
+ run-tests:
461
+ type: command
462
+ exec: "npm test -- --json"
463
+ ```
464
+
465
+ **Use `script` for:**
466
+ ```yaml
467
+ steps:
468
+ process-results:
469
+ type: script
470
+ depends_on: [run-tests]
471
+ content: |
472
+ const results = outputs['run-tests'];
473
+ return {
474
+ passed: results.tests.filter(t => t.passed).length,
475
+ failed: results.tests.filter(t => !t.passed).length
476
+ };
477
+ ```
478
+
479
+ ---
480
+
481
+ ## Troubleshooting
482
+
483
+ ### Why isn't my check running?
484
+
485
+ Common causes:
486
+
487
+ 1. **Event filter mismatch**: Check if the `on` field matches the current event
488
+ ```yaml
489
+ steps:
490
+ my-check:
491
+ on: [pr_opened] # Won't run on pr_updated
492
+ ```
493
+
494
+ 2. **Condition evaluated to false**: Check your `if` expression
495
+ ```yaml
496
+ steps:
497
+ my-check:
498
+ if: "files.length > 0" # Won't run if no files changed
499
+ ```
500
+
501
+ 3. **Tag filter exclusion**: Check if tags are filtering out the check
502
+ ```bash
503
+ visor --tags github # Only runs checks tagged 'github'
504
+ ```
505
+
506
+ 4. **Missing dependencies**: Ensure `depends_on` targets exist
507
+ ```yaml
508
+ steps:
509
+ my-check:
510
+ depends_on: [nonexistent-check] # Will fail
511
+ ```
512
+
513
+ Debug with:
514
+ ```bash
515
+ visor --check all --debug
516
+ ```
517
+
518
+ ### Why is routing not working?
519
+
520
+ Common issues with `goto`, `retry`, and `run`:
521
+
522
+ 1. **goto must target ancestors only**: You can only jump back to previously executed checks
523
+ ```yaml
524
+ steps:
525
+ step-a:
526
+ type: command
527
+ step-b:
528
+ depends_on: [step-a]
529
+ on_fail:
530
+ goto: step-a # Valid (ancestor)
531
+ # goto: step-c # Invalid (not an ancestor)
532
+ ```
533
+
534
+ 2. **Loop limit reached**: Check `max_loops` setting
535
+ ```yaml
536
+ routing:
537
+ max_loops: 10 # Increase if needed
538
+ ```
539
+
540
+ 3. **JS expression errors**: Use `log()` to debug
541
+ ```yaml
542
+ on_fail:
543
+ goto_js: |
544
+ log("Current outputs:", outputs);
545
+ log("History:", outputs.history);
546
+ return null;
547
+ ```
548
+
549
+ See [Failure Routing](./failure-routing.md) for complete documentation.
550
+
551
+ ### How do I debug my configuration?
552
+
553
+ **Enable debug mode:**
554
+ ```bash
555
+ visor --check all --debug
556
+ ```
557
+
558
+ **Use the logger check type:**
559
+ ```yaml
560
+ steps:
561
+ debug-flow:
562
+ type: logger
563
+ depends_on: [previous-check]
564
+ message: |
565
+ Outputs: {{ outputs | json }}
566
+ PR: {{ pr | json }}
567
+ ```
568
+
569
+ **Use `log()` in JavaScript expressions:**
570
+ ```yaml
571
+ steps:
572
+ my-check:
573
+ type: command
574
+ if: |
575
+ log("Files:", filesChanged);
576
+ log("Event:", event);
577
+ return filesChanged.length > 0;
578
+ ```
579
+
580
+ **Enable tracing with OpenTelemetry:**
581
+ ```bash
582
+ VISOR_TELEMETRY_ENABLED=true \
583
+ VISOR_TELEMETRY_SINK=otlp \
584
+ visor --check all
585
+ ```
586
+
587
+ See [Debugging Guide](./debugging.md) for comprehensive techniques.
588
+
589
+ ### What do the different error messages mean?
590
+
591
+ | Error | Meaning | Solution |
592
+ |-------|---------|----------|
593
+ | `Configuration not found` | No `.visor.yaml` found | Create config or use `--config` |
594
+ | `Invalid check type` | Unknown provider type | Use valid type: ai, command, script, etc. |
595
+ | `outputs is undefined` | Missing `depends_on` | Add dependency to access outputs |
596
+ | `Rate limit exceeded` | API quota reached | Reduce parallelism or add delays |
597
+ | `Command execution failed` | Shell command error | Check command syntax and permissions |
598
+ | `Transform error` | Invalid Liquid/JS | Debug with `log()` function |
599
+
600
+ See [Troubleshooting](./troubleshooting.md) for more error resolutions.
601
+
602
+ ### Why are my AI responses incomplete or truncated?
603
+
604
+ Possible causes:
605
+
606
+ 1. **Timeout too short**: Increase step timeout
607
+ ```yaml
608
+ steps:
609
+ analysis:
610
+ type: ai
611
+ timeout: 120000 # 2 minutes
612
+ ```
613
+
614
+ 2. **Model token limits**: Switch to a model with larger context
615
+ ```yaml
616
+ steps:
617
+ analysis:
618
+ type: ai
619
+ ai_model: gpt-4-turbo # 128k context
620
+ ```
621
+
622
+ 3. **Prompt too complex**: Split into smaller, focused prompts
623
+
624
+ ---
625
+
626
+ ## Advanced Topics
627
+
628
+ ### How do I implement retry logic?
629
+
630
+ Use `on_fail.retry` with optional backoff:
631
+
632
+ ```yaml
633
+ steps:
634
+ api-call:
635
+ type: http_client
636
+ url: https://api.example.com/data
637
+ on_fail:
638
+ retry:
639
+ max: 3
640
+ backoff:
641
+ mode: exponential
642
+ delay_ms: 1000 # 1s, 2s, 4s
643
+ ```
644
+
645
+ You can also configure retries at the AI provider level:
646
+
647
+ ```yaml
648
+ steps:
649
+ analysis:
650
+ type: ai
651
+ ai:
652
+ retry:
653
+ maxRetries: 3
654
+ initialDelay: 1000
655
+ backoffFactor: 2
656
+ ```
657
+
658
+ See [Failure Routing](./failure-routing.md) for complete retry options.
659
+
660
+ ### How do I share state between checks?
661
+
662
+ Use the memory provider for persistent key-value storage:
663
+
664
+ ```yaml
665
+ steps:
666
+ store-value:
667
+ type: memory
668
+ operation: set
669
+ key: my-key
670
+ value: "{{ outputs['previous-check'].result }}"
671
+ namespace: my-workflow
672
+
673
+ read-value:
674
+ type: script
675
+ content: |
676
+ const value = memory.get('my-key', 'my-workflow');
677
+ return { retrieved: value };
678
+ ```
679
+
680
+ In script and routing expressions, use the `memory` object:
681
+ ```javascript
682
+ // Read
683
+ const value = memory.get('key', 'namespace');
684
+
685
+ // Write
686
+ memory.set('key', 'value', 'namespace');
687
+
688
+ // Increment
689
+ memory.increment('counter', 1, 'namespace');
690
+ ```
691
+
692
+ See [Memory Provider](./memory.md) for complete documentation.
693
+
694
+ ### How do I create conditional workflows?
695
+
696
+ Use `if` conditions and routing:
697
+
698
+ **Simple conditions:**
699
+ ```yaml
700
+ steps:
701
+ security-scan:
702
+ type: ai
703
+ if: "files.some(f => f.filename.includes('security'))"
704
+ ```
705
+
706
+ **Branch by output:**
707
+ ```yaml
708
+ steps:
709
+ check-type:
710
+ type: script
711
+ content: |
712
+ return { type: pr.title.startsWith('fix:') ? 'bugfix' : 'feature' };
713
+
714
+ bugfix-review:
715
+ type: ai
716
+ depends_on: [check-type]
717
+ if: "outputs['check-type'].type === 'bugfix'"
718
+ prompt: "Review this bug fix"
719
+
720
+ feature-review:
721
+ type: ai
722
+ depends_on: [check-type]
723
+ if: "outputs['check-type'].type === 'feature'"
724
+ prompt: "Review this feature"
725
+ ```
726
+
727
+ **Declarative routing with transitions:**
728
+ ```yaml
729
+ steps:
730
+ validate:
731
+ type: ai
732
+ on_success:
733
+ transitions:
734
+ - when: "outputs['validate'].score >= 90"
735
+ to: publish
736
+ - when: "outputs['validate'].score >= 70"
737
+ to: review
738
+ - when: "true"
739
+ to: reject
740
+ ```
741
+
742
+ See [Router Patterns](./router-patterns.md) for best practices.
743
+
744
+ ### How do I test my Visor configuration?
745
+
746
+ Use the built-in test framework with YAML test files:
747
+
748
+ ```yaml
749
+ # visor.tests.yaml
750
+ version: "1.0"
751
+ extends: ".visor.yaml"
752
+
753
+ tests:
754
+ defaults:
755
+ strict: true
756
+ ai_provider: mock
757
+
758
+ cases:
759
+ - name: security-check-runs
760
+ event: pr_opened
761
+ fixture: gh.pr_open.minimal
762
+ mocks:
763
+ security-review:
764
+ text: "No security issues found"
765
+ expect:
766
+ calls:
767
+ - step: security-review
768
+ exactly: 1
769
+ ```
770
+
771
+ Run tests:
772
+ ```bash
773
+ # Run all tests
774
+ visor test
775
+
776
+ # Run specific test case
777
+ visor test --only security-check-runs
778
+
779
+ # Validate test file only
780
+ visor test --validate
781
+ ```
782
+
783
+ See [Testing Guide](./testing/getting-started.md) for complete documentation.
784
+
785
+ ### How do I use workflows for reusable components?
786
+
787
+ Define reusable workflows in separate files:
788
+
789
+ ```yaml
790
+ # workflows/security-scan.yaml
791
+ id: security-scan
792
+ name: Security Scanner
793
+ inputs:
794
+ - name: severity_threshold
795
+ schema:
796
+ type: string
797
+ enum: [low, medium, high]
798
+ default: medium
799
+
800
+ steps:
801
+ scan:
802
+ type: ai
803
+ prompt: |
804
+ Scan for security issues with threshold: {{ inputs.severity_threshold }}
805
+
806
+ outputs:
807
+ - name: vulnerabilities
808
+ value_js: steps.scan.output.issues
809
+ ```
810
+
811
+ Import and use in your main config:
812
+
813
+ ```yaml
814
+ # .visor.yaml
815
+ imports:
816
+ - ./workflows/security-scan.yaml
817
+
818
+ steps:
819
+ run-security:
820
+ type: workflow
821
+ workflow: security-scan
822
+ args:
823
+ severity_threshold: high
824
+ ```
825
+
826
+ See [Reusable Workflows](./workflows.md) for complete documentation.
827
+
828
+ ---
829
+
830
+ ## Further Reading
831
+
832
+ - [Configuration Reference](./configuration.md) - Complete configuration options
833
+ - [Provider Documentation](./pluggable.md) - All 15+ provider types
834
+ - [Debugging Guide](./debugging.md) - Troubleshooting techniques
835
+ - [Recipes](./recipes.md) - Copy-paste workflow examples
836
+ - [Workflow Style Guide](./guides/workflow-style-guide.md) - Best practices