@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,737 @@
1
+ # Contributing to Visor
2
+
3
+ Thank you for your interest in contributing to Visor! This guide provides
4
+ everything you need to get started with development, understand the codebase,
5
+ and submit high-quality contributions.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Getting Started](#getting-started)
10
+ - [Development Workflow](#development-workflow)
11
+ - [Code Standards](#code-standards)
12
+ - [Testing](#testing)
13
+ - [Adding New Features](#adding-new-features)
14
+ - [Pull Request Process](#pull-request-process)
15
+ - [Architecture Overview](#architecture-overview)
16
+ - [Common Tasks](#common-tasks)
17
+ - [Getting Help](#getting-help)
18
+
19
+ ---
20
+
21
+ ## Getting Started
22
+
23
+ ### Prerequisites
24
+
25
+ - **Node.js**: Version 18 or higher (20 recommended)
26
+ - **npm**: Comes with Node.js
27
+ - **Git**: For version control
28
+
29
+ Verify your setup:
30
+
31
+ ```bash
32
+ node --version # Should be v18.x or higher
33
+ npm --version # Should be v9.x or higher
34
+ git --version
35
+ ```
36
+
37
+ ### Cloning the Repository
38
+
39
+ ```bash
40
+ git clone https://github.com/probelabs/visor.git
41
+ cd visor
42
+ ```
43
+
44
+ ### Installing Dependencies
45
+
46
+ ```bash
47
+ npm install
48
+ ```
49
+
50
+ This will also run the `prepare` script which sets up Husky for Git hooks.
51
+
52
+ ### Building the Project
53
+
54
+ ```bash
55
+ npm run build
56
+ ```
57
+
58
+ This command:
59
+
60
+ 1. Cleans the dist directory
61
+ 2. Runs `patch-package` for any dependency patches
62
+ 3. Generates the configuration schema
63
+ 4. Builds the CLI bundle with `@vercel/ncc`
64
+ 5. Builds the SDK with `tsup`
65
+
66
+ ### Verifying Your Setup
67
+
68
+ ```bash
69
+ # Run the test suite
70
+ npm test
71
+
72
+ # Run the CLI
73
+ ./dist/index.js --help
74
+
75
+ # Check linting
76
+ npm run lint
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Development Workflow
82
+
83
+ ### Development Commands
84
+
85
+ | Command | Description |
86
+ | ---------------------------- | ---------------------------------------------- |
87
+ | `npm run build` | Build CLI and SDK |
88
+ | `npm run build:cli` | Build CLI only |
89
+ | `npm run build:sdk` | Build SDK only |
90
+ | `npm run clean` | Clean dist directory |
91
+ | `npm test` | Run all tests (Jest + YAML tests) |
92
+ | `npm run test:watch` | Run tests in watch mode |
93
+ | `npm run test:coverage` | Generate coverage report |
94
+ | `npm run test:yaml` | Run YAML-based tests only |
95
+ | `npm run test:yaml:parallel` | Run YAML tests with parallelism |
96
+ | `npm run lint` | Lint TypeScript files |
97
+ | `npm run lint:fix` | Auto-fix linting issues |
98
+ | `npm run format` | Format code with Prettier |
99
+ | `npm run format:check` | Check code formatting |
100
+ | `npm run docs:validate` | Validate README links |
101
+
102
+ ### Running the CLI Locally
103
+
104
+ After building, you can run the CLI directly:
105
+
106
+ ```bash
107
+ # Show help
108
+ ./dist/index.js --help
109
+
110
+ # Run all checks
111
+ ./dist/index.js --check all
112
+
113
+ # Run specific checks with debug output
114
+ ./dist/index.js --check security,performance --debug
115
+
116
+ # Run with custom config
117
+ ./dist/index.js --config my-config.yaml --check all
118
+
119
+ # Output in different formats
120
+ ./dist/index.js --check all --output json
121
+ ./dist/index.js --check all --output markdown
122
+ ./dist/index.js --check all --output sarif
123
+ ```
124
+
125
+ ### Watch Mode Development
126
+
127
+ For rapid development, use watch mode for tests:
128
+
129
+ ```bash
130
+ npm run test:watch
131
+ ```
132
+
133
+ Note: There is no hot-reload for the CLI itself. You need to run `npm run build`
134
+ after making changes to source files.
135
+
136
+ ### Debugging Techniques
137
+
138
+ 1. **Enable debug mode**:
139
+
140
+ ```bash
141
+ ./dist/index.js --debug --config .visor.yaml
142
+ ```
143
+
144
+ 2. **Use the `log()` function** in JavaScript expressions (`if`, `fail_if`,
145
+ `transform_js`):
146
+
147
+ ```yaml
148
+ if: |
149
+ log("Debug:", outputs);
150
+ return outputs.length > 0;
151
+ ```
152
+
153
+ 3. **Use the `json` filter** in Liquid templates:
154
+
155
+ ```yaml
156
+ prompt: |
157
+ Debug: {{ outputs | json }}
158
+ ```
159
+
160
+ 4. **Use the logger check type**:
161
+
162
+ ```yaml
163
+ checks:
164
+ debug-flow:
165
+ type: logger
166
+ message: |
167
+ Outputs: {{ outputs | json }}
168
+ ```
169
+
170
+ 5. **Enable OpenTelemetry tracing**:
171
+ ```bash
172
+ VISOR_TELEMETRY_ENABLED=true \
173
+ VISOR_TELEMETRY_SINK=otlp \
174
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces \
175
+ ./dist/index.js --config .visor.yaml
176
+ ```
177
+
178
+ For more debugging techniques, see [docs/debugging.md](./debugging.md).
179
+
180
+ ---
181
+
182
+ ## Code Standards
183
+
184
+ ### TypeScript Conventions
185
+
186
+ - **Target**: ES2022
187
+ - **Module**: CommonJS
188
+ - **Strict mode**: Enabled
189
+ - All source code is in the `src/` directory
190
+ - Tests are in the `tests/` directory
191
+
192
+ ### ESLint Rules
193
+
194
+ Key ESLint rules enforced:
195
+
196
+ - `prefer-const`: Use `const` when variables are not reassigned
197
+ - `no-var`: Use `let` or `const` instead of `var`
198
+ - `@typescript-eslint/no-unused-vars`: No unused variables (allows `_` prefix
199
+ for intentionally unused)
200
+ - Import `liquidjs` through `createExtendedLiquid()` from
201
+ `src/liquid-extensions`
202
+
203
+ ### Prettier Configuration
204
+
205
+ The project uses Prettier with these settings:
206
+
207
+ | Setting | Value |
208
+ | ---------------- | ------- |
209
+ | `semi` | `true` |
210
+ | `trailingComma` | `es5` |
211
+ | `singleQuote` | `true` |
212
+ | `printWidth` | `100` |
213
+ | `tabWidth` | `2` |
214
+ | `useTabs` | `false` |
215
+ | `bracketSpacing` | `true` |
216
+ | `arrowParens` | `avoid` |
217
+ | `endOfLine` | `lf` |
218
+
219
+ For markdown files, `printWidth` is `80` with `proseWrap: always`.
220
+
221
+ ### Naming Conventions
222
+
223
+ - **Files**: Use kebab-case for file names (`check-provider.interface.ts`)
224
+ - **Classes**: Use PascalCase (`CheckProvider`, `ConfigManager`)
225
+ - **Functions/Methods**: Use camelCase (`executeCheck`, `validateConfig`)
226
+ - **Constants**: Use UPPER_SNAKE_CASE for true constants
227
+ - **Interfaces**: Use PascalCase, prefix with `I` only if needed for clarity
228
+
229
+ ### File Organization
230
+
231
+ ```
232
+ src/
233
+ index.ts # GitHub Action entry point
234
+ cli-main.ts # CLI entry point
235
+ config.ts # Configuration loading
236
+
237
+ types/
238
+ config.ts # Configuration types
239
+ engine.ts # Engine state types
240
+ execution.ts # Execution result types
241
+ cli.ts # CLI option types
242
+
243
+ providers/
244
+ check-provider.interface.ts # Provider base class
245
+ check-provider-registry.ts # Provider registry
246
+ ai-check-provider.ts # AI provider
247
+ command-check-provider.ts # Command provider
248
+ ... # Other providers
249
+
250
+ state-machine/
251
+ runner.ts # State machine runner
252
+ states/ # State handlers
253
+
254
+ utils/ # Utility functions
255
+ telemetry/ # OpenTelemetry integration
256
+ debug-visualizer/ # Debug UI server
257
+ ```
258
+
259
+ ### Pre-commit Hooks
260
+
261
+ The project uses Husky with lint-staged to run checks before commits:
262
+
263
+ - ESLint with auto-fix on `src/**/*.ts` and `tests/**/*.ts`
264
+ - Prettier formatting on all staged files
265
+
266
+ ---
267
+
268
+ ## Testing
269
+
270
+ ### Test Structure
271
+
272
+ Tests are organized by type:
273
+
274
+ ```
275
+ tests/
276
+ unit/ # Unit tests for individual components
277
+ integration/ # Integration tests with mocked APIs
278
+ e2e/ # End-to-end tests
279
+ scenarios/ # Complex workflow scenarios
280
+ performance/ # Performance and stress tests
281
+ fixtures/ # Test data and mock responses
282
+ errors/ # Error handling tests
283
+ edge-cases/ # Edge case tests
284
+ setup.ts # Global test setup
285
+ ```
286
+
287
+ ### Writing Tests with Jest
288
+
289
+ Tests use Jest with SWC for TypeScript transformation. Example test:
290
+
291
+ ```typescript
292
+ import { ConfigManager } from '../../src/config';
293
+
294
+ describe('ConfigManager', () => {
295
+ beforeEach(() => {
296
+ // Setup for each test
297
+ });
298
+
299
+ afterEach(() => {
300
+ // Cleanup
301
+ });
302
+
303
+ it('should load configuration from file', async () => {
304
+ const manager = new ConfigManager();
305
+ const config = await manager.loadConfig('path/to/config.yaml');
306
+
307
+ expect(config).toBeDefined();
308
+ expect(config.checks).toBeDefined();
309
+ });
310
+
311
+ it('should throw on invalid configuration', async () => {
312
+ const manager = new ConfigManager();
313
+
314
+ await expect(manager.loadConfig('invalid.yaml')).rejects.toThrow();
315
+ });
316
+ });
317
+ ```
318
+
319
+ ### Test Fixtures
320
+
321
+ Place test fixtures in `tests/fixtures/`:
322
+
323
+ ```typescript
324
+ // tests/fixtures/sample-pr.ts
325
+ export const samplePR = {
326
+ number: 123,
327
+ title: 'Test PR',
328
+ body: 'Test description',
329
+ author: 'test-user',
330
+ // ...
331
+ };
332
+ ```
333
+
334
+ ### Running Specific Tests
335
+
336
+ ```bash
337
+ # Run a specific test file
338
+ npm test -- tests/unit/config.test.ts
339
+
340
+ # Run tests matching a pattern
341
+ npm test -- --testNamePattern="ConfigManager"
342
+
343
+ # Run tests in a specific directory
344
+ npm test -- tests/unit/
345
+
346
+ # Run with verbose output
347
+ npm test -- --verbose
348
+
349
+ # Update snapshots
350
+ npm test -- --updateSnapshot
351
+ ```
352
+
353
+ ### Test Configuration
354
+
355
+ Key Jest settings (from `jest.config.js`):
356
+
357
+ - **testTimeout**: 10 seconds (increased from default)
358
+ - **forceExit**: true (prevents hanging on async operations)
359
+ - **logHeapUsage**: Enabled in CI for memory monitoring
360
+ - **maxWorkers**: 1 in CI, 50% locally
361
+
362
+ ### Coverage Requirements
363
+
364
+ Generate coverage reports:
365
+
366
+ ```bash
367
+ npm run test:coverage
368
+ ```
369
+
370
+ Coverage reports are generated in the `coverage/` directory. While there are no
371
+ strict coverage requirements, aim to maintain or improve coverage when adding
372
+ new code.
373
+
374
+ ---
375
+
376
+ ## Adding New Features
377
+
378
+ ### Adding a New Provider
379
+
380
+ Providers are pluggable components that implement check types. To add a new
381
+ provider:
382
+
383
+ 1. **Create the provider file** in `src/providers/`:
384
+
385
+ ```typescript
386
+ // src/providers/my-custom-provider.ts
387
+ import { CheckProvider, CheckProviderConfig, ExecutionContext } from './check-provider.interface';
388
+ import { PRInfo } from '../pr-analyzer';
389
+ import { ReviewSummary } from '../reviewer';
390
+
391
+ export class MyCustomProvider extends CheckProvider {
392
+ getName(): string {
393
+ return 'my-custom';
394
+ }
395
+
396
+ getDescription(): string {
397
+ return 'My custom check provider';
398
+ }
399
+
400
+ async validateConfig(config: unknown): Promise<boolean> {
401
+ // Validate provider-specific configuration
402
+ const cfg = config as CheckProviderConfig;
403
+ return cfg.type === 'my-custom' && !!cfg.myRequiredField;
404
+ }
405
+
406
+ async execute(
407
+ prInfo: PRInfo,
408
+ config: CheckProviderConfig,
409
+ dependencyResults?: Map<string, ReviewSummary>,
410
+ context?: ExecutionContext
411
+ ): Promise<ReviewSummary> {
412
+ // Implement your check logic here
413
+ return {
414
+ issues: [],
415
+ summary: 'Check completed successfully',
416
+ };
417
+ }
418
+
419
+ getSupportedConfigKeys(): string[] {
420
+ return ['type', 'myRequiredField', 'optionalField'];
421
+ }
422
+
423
+ async isAvailable(): Promise<boolean> {
424
+ // Check if required dependencies are available
425
+ return true;
426
+ }
427
+
428
+ getRequirements(): string[] {
429
+ return ['MY_API_KEY environment variable'];
430
+ }
431
+ }
432
+ ```
433
+
434
+ 2. **Register the provider** in `src/providers/check-provider-registry.ts`:
435
+
436
+ ```typescript
437
+ import { MyCustomProvider } from './my-custom-provider';
438
+
439
+ // In the registry initialization
440
+ registry.register(new MyCustomProvider());
441
+ ```
442
+
443
+ 3. **Add TypeScript types** if needed in `src/types/config.ts`
444
+
445
+ 4. **Write tests** in `tests/unit/providers/my-custom-provider.test.ts`
446
+
447
+ 5. **Add documentation** in `docs/providers/my-custom.md`
448
+
449
+ ### Adding New Configuration Options
450
+
451
+ 1. **Update the types** in `src/types/config.ts`:
452
+
453
+ ```typescript
454
+ export interface CheckConfig {
455
+ // ... existing fields
456
+ myNewOption?: string;
457
+ }
458
+ ```
459
+
460
+ 2. **Update the schema generator** by running:
461
+
462
+ ```bash
463
+ npm run prebuild
464
+ ```
465
+
466
+ 3. **Update documentation** in `docs/configuration.md`
467
+
468
+ 4. **Add tests** for the new option
469
+
470
+ ### Adding New CLI Commands
471
+
472
+ CLI commands are defined in `src/cli-main.ts` using Commander:
473
+
474
+ ```typescript
475
+ program
476
+ .command('my-command')
477
+ .description('Description of my command')
478
+ .option('-f, --flag <value>', 'Option description')
479
+ .action(async (options) => {
480
+ // Command implementation
481
+ });
482
+ ```
483
+
484
+ ### Documentation Requirements
485
+
486
+ When adding new features:
487
+
488
+ 1. Update relevant documentation in `docs/`
489
+ 2. Add examples in `examples/` if appropriate
490
+ 3. Update `CLAUDE.md` if the feature affects development workflow
491
+ 4. Keep README examples accurate
492
+
493
+ ---
494
+
495
+ ## Pull Request Process
496
+
497
+ ### Branch Naming Conventions
498
+
499
+ Use descriptive branch names:
500
+
501
+ - `feature/add-new-provider` - New features
502
+ - `fix/config-loading-error` - Bug fixes
503
+ - `docs/update-contributing` - Documentation updates
504
+ - `refactor/simplify-engine` - Code refactoring
505
+ - `test/add-provider-tests` - Test additions
506
+
507
+ ### Commit Message Format
508
+
509
+ Write clear, descriptive commit messages:
510
+
511
+ ```
512
+ <type>: <short description>
513
+
514
+ <optional longer description>
515
+
516
+ <optional footer with issue references>
517
+ ```
518
+
519
+ Types:
520
+
521
+ - `feat`: New feature
522
+ - `fix`: Bug fix
523
+ - `docs`: Documentation changes
524
+ - `refactor`: Code refactoring
525
+ - `test`: Test additions or changes
526
+ - `chore`: Build process or auxiliary tool changes
527
+
528
+ Examples:
529
+
530
+ ```
531
+ feat: add HTTP client provider for external API calls
532
+
533
+ Implements a new provider type that can make HTTP requests
534
+ to external APIs and process the responses.
535
+
536
+ Closes #123
537
+ ```
538
+
539
+ ```
540
+ fix: resolve config loading race condition
541
+
542
+ The configuration loader was not awaiting async operations
543
+ properly, causing intermittent failures.
544
+ ```
545
+
546
+ ### Before Submitting
547
+
548
+ 1. **Run the test suite**:
549
+
550
+ ```bash
551
+ npm test
552
+ ```
553
+
554
+ 2. **Run linting and formatting**:
555
+
556
+ ```bash
557
+ npm run lint
558
+ npm run format
559
+ ```
560
+
561
+ 3. **Build the project**:
562
+
563
+ ```bash
564
+ npm run build
565
+ ```
566
+
567
+ 4. **Test your changes manually**:
568
+ ```bash
569
+ ./dist/index.js --check all --debug
570
+ ```
571
+
572
+ ### PR Description Template
573
+
574
+ When creating a PR, include:
575
+
576
+ ```markdown
577
+ ## Summary
578
+
579
+ Brief description of what this PR does.
580
+
581
+ ## Changes
582
+
583
+ - List of specific changes
584
+ - Include any breaking changes
585
+
586
+ ## Testing
587
+
588
+ How the changes were tested:
589
+
590
+ - [ ] Unit tests added/updated
591
+ - [ ] Integration tests added/updated
592
+ - [ ] Manual testing performed
593
+
594
+ ## Related Issues
595
+
596
+ Closes #123
597
+ ```
598
+
599
+ ### Review Process
600
+
601
+ 1. PRs require at least one approval before merging
602
+ 2. All CI checks must pass
603
+ 3. Address review comments or explain why changes are not needed
604
+ 4. Keep PRs focused - prefer smaller, incremental changes
605
+
606
+ ### CI Checks
607
+
608
+ The following checks run on PRs:
609
+
610
+ - **Lint**: ESLint checks
611
+ - **Format**: Prettier format check
612
+ - **Test**: Full test suite
613
+ - **Build**: Verify the project builds successfully
614
+
615
+ ---
616
+
617
+ ## Architecture Overview
618
+
619
+ For a detailed architecture overview, see [docs/architecture.md](./architecture.md).
620
+
621
+ ### Key Files to Understand
622
+
623
+ | File | Description |
624
+ | -------------------------------------- | ------------------------------------ |
625
+ | `src/index.ts` | GitHub Action entry point |
626
+ | `src/cli-main.ts` | CLI entry point |
627
+ | `src/config.ts` | Configuration loading and validation |
628
+ | `src/check-execution-engine.ts` | Main orchestration engine |
629
+ | `src/state-machine-execution-engine.ts`| State machine runner |
630
+ | `src/providers/check-provider.interface.ts` | Provider base class |
631
+ | `src/types/config.ts` | Configuration TypeScript types |
632
+
633
+ ### How the Codebase is Organized
634
+
635
+ 1. **Entry Points**: `src/index.ts` (GitHub Action) and `src/cli-main.ts` (CLI)
636
+ 2. **Configuration**: `src/config.ts` loads and validates YAML configuration
637
+ 3. **Execution Engine**: `src/state-machine-execution-engine.ts` orchestrates
638
+ check execution using a state machine
639
+ 4. **Providers**: `src/providers/` contains pluggable check implementations
640
+ 5. **Types**: `src/types/` contains TypeScript type definitions
641
+ 6. **Utilities**: `src/utils/` contains helper functions
642
+
643
+ ---
644
+
645
+ ## Common Tasks
646
+
647
+ ### Updating Dependencies
648
+
649
+ ```bash
650
+ # Update a specific dependency
651
+ npm update <package-name>
652
+
653
+ # Update all dependencies (be careful)
654
+ npm update
655
+
656
+ # Check for outdated packages
657
+ npm outdated
658
+ ```
659
+
660
+ After updating dependencies:
661
+
662
+ 1. Run the full test suite
663
+ 2. Build the project
664
+ 3. Test the CLI manually
665
+
666
+ ### Regenerating Types
667
+
668
+ The configuration schema is auto-generated from TypeScript types:
669
+
670
+ ```bash
671
+ npm run prebuild
672
+ ```
673
+
674
+ This runs `scripts/generate-config-schema.js` which generates the JSON schema
675
+ from `src/types/config.ts`.
676
+
677
+ ### Updating Documentation
678
+
679
+ 1. Edit files in `docs/`
680
+ 2. Validate links: `npm run docs:validate`
681
+ 3. Keep examples in `examples/` synchronized with documentation
682
+
683
+ ### Running Simulations
684
+
685
+ Test GitHub event handling locally:
686
+
687
+ ```bash
688
+ # Simulate issue event
689
+ npm run simulate:issue
690
+
691
+ # Simulate comment event
692
+ npm run simulate:comment
693
+ ```
694
+
695
+ ### Release Process
696
+
697
+ Releases are managed through npm scripts:
698
+
699
+ ```bash
700
+ # Interactive release
701
+ npm run release
702
+
703
+ # Specific version bumps
704
+ npm run release:patch # 0.1.42 -> 0.1.43
705
+ npm run release:minor # 0.1.42 -> 0.2.0
706
+ npm run release:major # 0.1.42 -> 1.0.0
707
+ ```
708
+
709
+ The release script handles:
710
+
711
+ 1. Version bumping in `package.json`
712
+ 2. Building the project
713
+ 3. Creating a git tag
714
+ 4. Pushing to the repository
715
+ 5. Publishing to npm
716
+
717
+ ---
718
+
719
+ ## Getting Help
720
+
721
+ - **Documentation**: Check the `docs/` directory
722
+ - **Issues**: Search or create issues on GitHub
723
+ - **Debugging**: See [docs/debugging.md](./debugging.md)
724
+ - **Troubleshooting**: See [docs/troubleshooting.md](./troubleshooting.md)
725
+
726
+ ### Related Documentation
727
+
728
+ - [Configuration Reference](./configuration.md)
729
+ - [Architecture Overview](./architecture.md)
730
+ - [Debugging Guide](./debugging.md)
731
+ - [Troubleshooting](./troubleshooting.md)
732
+ - [Dev Playbook](./dev-playbook.md)
733
+ - [CI/CLI Mode](./ci-cli-mode.md)
734
+
735
+ ---
736
+
737
+ Thank you for contributing to Visor!