@probelabs/visor 0.1.38 → 0.1.39
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/LICENSE +22 -0
- package/README.md +232 -2431
- package/defaults/.visor.yaml +1 -1
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/check-execution-engine.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/defaults/.visor.yaml +1 -1
- package/dist/failure-condition-evaluator.d.ts.map +1 -1
- package/dist/index.js +64 -158
- package/dist/output-formatters.d.ts.map +1 -1
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/claude-code-check-provider.d.ts.map +1 -1
- package/dist/providers/http-check-provider.d.ts.map +1 -1
- package/dist/providers/http-client-provider.d.ts.map +1 -1
- package/dist/providers/http-input-provider.d.ts.map +1 -1
- package/dist/providers/log-check-provider.d.ts.map +1 -1
- package/dist/providers/noop-check-provider.d.ts.map +1 -1
- package/dist/providers/tool-check-provider.d.ts +0 -1
- package/dist/providers/tool-check-provider.d.ts.map +1 -1
- package/dist/reviewer.d.ts +0 -1
- package/dist/reviewer.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,2599 +1,400 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<img src="site/visor.png" alt="Visor Logo" width="500" />
|
|
3
3
|
|
|
4
|
-
# Visor
|
|
4
|
+
# Visor — Open‑source SDLC automation & code review orchestration
|
|
5
5
|
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
7
7
|
[](https://nodejs.org/)
|
|
8
8
|
[]()
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Config‑driven checks and automations with native GitHub checks/annotations.
|
|
11
|
+
PR reviews, issue assistants, release notes, scheduled audits, and webhooks.
|
|
12
|
+
AI‑assisted when you want it, fully predictable when you don’t.
|
|
11
13
|
</div>
|
|
12
14
|
|
|
13
15
|
---
|
|
14
16
|
|
|
15
17
|
Visor ships with a ready-to-run configuration at `defaults/.visor.yaml`, so you immediately get:
|
|
16
|
-
- A staged review pipeline (`overview → security → performance → quality → style`)
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- A manual release-notes generator
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
### Table of Contents
|
|
24
|
-
- [Quick Start](#-quick-start)
|
|
25
|
-
- [Features](#-features)
|
|
26
|
-
- [Developer Experience Playbook](#-developer-experience-playbook)
|
|
27
|
-
- [Tag-Based Filtering](#-tag-based-check-filtering)
|
|
28
|
-
- [PR Comment Commands](#-pr-comment-commands)
|
|
29
|
-
- [Suppress Warnings](#-suppressing-warnings)
|
|
30
|
-
- [CLI Usage](#-cli-usage)
|
|
31
|
-
- [AI Configuration](#-ai-configuration)
|
|
32
|
-
- [MCP Support](#-mcp-model-context-protocol-support-for-ai-providers)
|
|
33
|
-
- [Step Dependencies](#-step-dependencies--intelligent-execution)
|
|
34
|
-
- [Troubleshooting](#-troubleshooting)
|
|
35
|
-
- [Security Defaults](#-security-defaults)
|
|
36
|
-
- [Performance & Cost](#-performance--cost-controls)
|
|
37
|
-
- [Observability](#-observability)
|
|
38
|
-
- [Examples & Recipes](#-examples--recipes)
|
|
39
|
-
- [Contributing](#-contributing)
|
|
40
|
-
|
|
41
|
-
### As GitHub Action (Recommended)
|
|
42
|
-
|
|
43
|
-
Create `.github/workflows/code-review.yml`:
|
|
18
|
+
- A staged review pipeline (`overview → security → performance → quality → style`).
|
|
19
|
+
- Native GitHub integration: check runs, annotations, and PR comments out of the box.
|
|
20
|
+
- Built‑in code answering assistant: trigger from any issue or PR comment, e.g. `/visor how it works?`.
|
|
21
|
+
- A manual release-notes generator for tagged release workflows.
|
|
22
|
+
- No magic: everything is config‑driven in `.visor.yaml`; prompts/context are visible and templatable.
|
|
23
|
+
- Built for scale: composable checks, tag-based profiles, and flexible `extends` for shared policies.
|
|
44
24
|
|
|
45
|
-
|
|
46
|
-
name: Code Review
|
|
47
|
-
on:
|
|
48
|
-
pull_request:
|
|
49
|
-
|
|
50
|
-
jobs:
|
|
51
|
-
review:
|
|
52
|
-
runs-on: ubuntu-latest
|
|
53
|
-
permissions:
|
|
54
|
-
pull-requests: write
|
|
55
|
-
contents: read
|
|
56
|
-
steps:
|
|
57
|
-
- uses: actions/checkout@v4
|
|
58
|
-
- uses: actions/setup-node@v4
|
|
59
|
-
with:
|
|
60
|
-
node-version: 20
|
|
61
|
-
cache: npm
|
|
62
|
-
- uses: ./ # or: gates-ai/visor-action@v1
|
|
63
|
-
# Optional: run Visor as a GitHub App instead of the workflow token identity
|
|
64
|
-
# with:
|
|
65
|
-
# app-id: ${{ secrets.VISOR_APP_ID }}
|
|
66
|
-
# private-key: ${{ secrets.VISOR_APP_PRIVATE_KEY }}
|
|
67
|
-
# installation-id: ${{ secrets.VISOR_APP_INSTALLATION_ID }}
|
|
68
|
-
env:
|
|
69
|
-
# Choose one AI provider (see AI Configuration below)
|
|
70
|
-
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
|
71
|
-
# ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
72
|
-
# OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
The default `GITHUB_TOKEN` already exists in every workflow run, so you do **not** need to create a secret for it. Switch to a GitHub App when you want a dedicated bot identity, granular repo access, or org-wide deployment.
|
|
76
|
-
|
|
77
|
-
If you don't commit a `.visor.yaml` yet, Visor automatically loads `defaults/.visor.yaml`, giving your team the full overview → security → performance → quality → style pipeline, critical/error failure stop, `/review` orchestration, and the optional release-notes check out of the box.
|
|
78
|
-
|
|
79
|
-
**Optional GitHub App setup:**
|
|
80
|
-
1. [Create a GitHub App](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app) with:
|
|
81
|
-
- **Pull requests**: Read & Write
|
|
82
|
-
- **Issues**: Write
|
|
83
|
-
- **Metadata**: Read
|
|
84
|
-
2. Generate and store the private key securely.
|
|
85
|
-
3. Install the app on the repositories (or org) you want Visor to review.
|
|
86
|
-
4. Add secrets for `VISOR_APP_ID`, `VISOR_APP_PRIVATE_KEY`, and optionally `VISOR_APP_INSTALLATION_ID` if you don't want auto-detection.
|
|
25
|
+
## 🚀 90‑second Quick Start
|
|
87
26
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
#### Advanced Configuration Options
|
|
91
|
-
|
|
92
|
-
For more control over execution behavior:
|
|
27
|
+
### Add the Action
|
|
93
28
|
|
|
94
29
|
```yaml
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
30
|
+
# .github/workflows/visor.yml
|
|
31
|
+
name: Visor
|
|
32
|
+
on:
|
|
33
|
+
pull_request: { types: [opened, synchronize] }
|
|
34
|
+
issues: { types: [opened] }
|
|
35
|
+
issue_comment: { types: [created] }
|
|
36
|
+
permissions:
|
|
37
|
+
contents: read
|
|
38
|
+
pull-requests: write
|
|
39
|
+
issues: write
|
|
40
|
+
checks: write
|
|
98
41
|
jobs:
|
|
99
|
-
|
|
42
|
+
visor:
|
|
100
43
|
runs-on: ubuntu-latest
|
|
101
44
|
steps:
|
|
102
45
|
- uses: actions/checkout@v4
|
|
103
|
-
- uses:
|
|
104
|
-
with:
|
|
105
|
-
max-parallelism: '5' # Run up to 5 checks in parallel
|
|
106
|
-
fail-fast: 'true' # Stop on first failure
|
|
107
|
-
checks: 'security,performance' # Run specific checks only
|
|
46
|
+
- uses: probelabs/visor@v1
|
|
108
47
|
env:
|
|
109
|
-
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
|
48
|
+
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} # or ANTHROPIC/OPENAI
|
|
110
49
|
```
|
|
111
50
|
|
|
112
|
-
###
|
|
51
|
+
### Open a PR
|
|
52
|
+
- Visor posts a PR summary, creates GitHub Check runs, and annotates lines.
|
|
113
53
|
|
|
114
|
-
|
|
115
|
-
# Install dependencies
|
|
116
|
-
npm install
|
|
117
|
-
|
|
118
|
-
# Build TypeScript sources (required when running from a clone)
|
|
119
|
-
npm run build
|
|
120
|
-
|
|
121
|
-
# Run analysis from the compiled dist bundle
|
|
122
|
-
node dist/index.js --cli --check all
|
|
123
|
-
|
|
124
|
-
# Or use the published package without building
|
|
125
|
-
npx @probelabs/visor --check security --output json
|
|
126
|
-
|
|
127
|
-
# Point to a custom config file
|
|
128
|
-
npx @probelabs/visor --config custom.yaml --check all
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
> Tip: `node dist/index.js --cli` forces CLI mode even inside GitHub Action environments. Install the package globally (`npm install --global @probelabs/visor`) if you prefer calling the `visor` binary directly.
|
|
132
|
-
|
|
133
|
-
## ✨ Features
|
|
134
|
-
|
|
135
|
-
- **Automated PR Reviews** - Analyzes code changes and posts review comments
|
|
136
|
-
- **Schema-Template System** - Flexible data validation with JSON Schema and Liquid templating
|
|
137
|
-
- **Group-Based Comments** - Multiple GitHub comments organized by check groups
|
|
138
|
-
- **Multiple Check Types** - Security, performance, style, and architecture analysis
|
|
139
|
-
- **Flexible Output** - Table, JSON, Markdown, or SARIF format (SARIF emits standard 2.1.0)
|
|
140
|
-
- **Step Dependencies** - Define execution order with `depends_on` relationships
|
|
141
|
-
- **PR Commands** - Trigger reviews with `/review` comments
|
|
142
|
-
- **GitHub Integration** - Creates check runs, adds labels, posts comments
|
|
143
|
-
- **Warning Suppression** - Suppress false positives with `visor-disable` comments
|
|
144
|
-
- **Tag-Based Filtering** - Run subsets of checks based on tags for different execution profiles
|
|
145
|
-
|
|
146
|
-
## 🧭 Developer Experience Playbook
|
|
54
|
+
### Optional: Add `.visor.yaml`
|
|
147
55
|
|
|
148
|
-
- **Start with the shipping defaults** – Copy `dist/defaults/.visor.yaml` (after `npm run build`) or `examples/quick-start-tags.yaml` into your repo as `.visor.yaml`, run `npx @probelabs/visor --check all --debug`, and commit both the config and observed baseline so every contributor shares the same playbook.
|
|
149
|
-
- **Treat configuration as code** – Review config edits in PRs, version Liquid prompt templates under `prompts/`, and pin AI provider/model in config to keep reviews reproducible.
|
|
150
|
-
- **Roll out checks gradually** – Use tag filters (`local`, `fast`, `critical`) to gate heavier analysis behind branch rules and to stage new checks on a subset of teams before rolling out widely.
|
|
151
|
-
- **Secure your credentials** – Prefer GitHub App auth in production for clearer audit trails; fall back to repo `GITHUB_TOKEN` only for sandboxes. Scope AI API keys to review-only projects and rotate them with GitHub secret scanning alerts enabled.
|
|
152
|
-
- **Make feedback actionable** – Group related checks, enable `reuse_ai_session` for multi-turn follow-ups, and add `/review --check performance` comment triggers so reviewers can pull deeper insights on demand.
|
|
153
|
-
- **Keep suppressions intentional** – Use `visor-disable` sparingly, add context in the adjacent comment, and review `visor-disable-file` entries during quarterly hygiene passes to avoid silencing real regressions.
|
|
154
|
-
- **Validate locally before CI** – Reproduce findings with `node dist/index.js --cli --check security --output markdown`, run `npm test` for guardrails, and enable `--fail-fast` in fast lanes to surface blocking issues instantly.
|
|
155
|
-
|
|
156
|
-
## 📚 Examples & Recipes
|
|
157
|
-
|
|
158
|
-
- Minimal `.visor.yaml` starter
|
|
159
56
|
```yaml
|
|
160
57
|
version: "1.0"
|
|
161
58
|
checks:
|
|
162
59
|
security:
|
|
163
60
|
type: ai
|
|
164
61
|
schema: code-review
|
|
165
|
-
prompt: "Identify security
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
62
|
+
prompt: "Identify security issues in changed files"
|
|
63
|
+
tags: ["fast", "security"]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Tip: Pin releases for stability, e.g. `uses: probelabs/visor@v1`.
|
|
67
|
+
|
|
68
|
+
## 🧩 Core Concepts (1 minute)
|
|
69
|
+
|
|
70
|
+
- Check – unit of work (`security`, `performance`).
|
|
71
|
+
- Schema – JSON shape checks return (e.g., `code-review`).
|
|
72
|
+
- Template – renders results (tables/markdown).
|
|
73
|
+
- Group – which comment a check is posted into.
|
|
74
|
+
- Provider – how a check runs (`ai`, `http`, `tool`, `script`, `claude-code`).
|
|
75
|
+
- Dependencies – `depends_on` controls order; independents run in parallel.
|
|
76
|
+
- Tags – label checks (`fast`, `local`, `comprehensive`) and filter with `--tags`.
|
|
77
|
+
- Events – PRs, issues, `/review` comments, webhooks, or cron schedules.
|
|
78
|
+
|
|
79
|
+
## Beyond Code Review
|
|
80
|
+
|
|
81
|
+
Visor is a general SDLC automation framework:
|
|
82
|
+
- PR Reviews – security/perf/style findings with native annotations
|
|
83
|
+
- Issue Assistant – `/visor …` for code Q&A and triage
|
|
84
|
+
- Release Notes – manual or tagged release workflows
|
|
85
|
+
- Scheduled Audits – cron‑driven checks against main
|
|
86
|
+
- Webhooks & HTTP – receive events, call APIs, and post results
|
|
87
|
+
- Policy‑as‑Code – schemas + templates for predictable, auditable outputs
|
|
88
|
+
|
|
89
|
+
## Table of Contents
|
|
90
|
+
|
|
91
|
+
- [90‑second Quick Start](#90-second-quick-start)
|
|
92
|
+
- [Core Concepts](#core-concepts-1-minute)
|
|
93
|
+
- [Beyond Code Review](#beyond-code-review)
|
|
94
|
+
- [Features](#features)
|
|
95
|
+
- [When to pick Visor](#when-to-pick-visor)
|
|
96
|
+
- [Developer Experience Playbook](#developer-experience-playbook)
|
|
97
|
+
- [Tag-Based Filtering](#tag-based-check-filtering)
|
|
98
|
+
- [PR Comment Commands](#pr-comment-commands)
|
|
99
|
+
- [Suppress Warnings](#suppressing-warnings)
|
|
100
|
+
- [CLI Usage](#cli-usage)
|
|
101
|
+
- [Troubleshooting](#troubleshooting)
|
|
102
|
+
- [Security Defaults](#security-defaults)
|
|
103
|
+
- [Performance & Cost Controls](#performance--cost-controls)
|
|
104
|
+
- [Observability](#observability)
|
|
105
|
+
- [AI Configuration](#ai-configuration)
|
|
106
|
+
- [Step Dependencies](#step-dependencies--intelligent-execution)
|
|
107
|
+
- [Claude Code Provider](#claude-code-provider)
|
|
108
|
+
- [AI Session Reuse](#ai-session-reuse)
|
|
109
|
+
- [Schema-Template System](#schema-template-system)
|
|
110
|
+
- [Enhanced Prompts](#enhanced-prompts)
|
|
111
|
+
- [Advanced Configuration](#advanced-configuration)
|
|
112
|
+
- [HTTP Integration & Scheduling](#http-integration--scheduling)
|
|
113
|
+
- [Pluggable Architecture](#pluggable-architecture)
|
|
114
|
+
- [GitHub Action Reference](#github-action-reference)
|
|
115
|
+
- [Output Formats](#output-formats)
|
|
172
116
|
|
|
173
|
-
|
|
174
|
-
- docs/NPM_USAGE.md – CLI usage and flags
|
|
175
|
-
- GITHUB_CHECKS.md – Checks, outputs, and workflow integration
|
|
176
|
-
- examples/ – MCP, Jira, and advanced configs
|
|
177
|
-
|
|
178
|
-
## 🤝 Contributing
|
|
117
|
+
## ✨ Features
|
|
179
118
|
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
119
|
+
- Native GitHub reviews: Check runs, inline annotations, and status reporting wired into PRs.
|
|
120
|
+
- Config‑first: One `.visor.yaml` defines checks, prompts, schemas, and templates — no hidden logic.
|
|
121
|
+
- Structured outputs: JSON Schema validation drives deterministic rendering, annotations, and SARIF.
|
|
122
|
+
- Orchestrated pipelines: Dependencies, parallelism, and tag‑based profiles; run in Actions or any CI.
|
|
123
|
+
- Multi‑provider AI: Google Gemini, Anthropic Claude, OpenAI — plus MCP tools and Claude Code SDK.
|
|
124
|
+
- Assistants & commands: `/review` to rerun checks, `/visor …` for Q&A, predictable comment groups.
|
|
125
|
+
- HTTP & schedules: Receive webhooks, call external APIs, and run cron‑scheduled audits and reports.
|
|
126
|
+
- Extensible providers: `ai`, `http`, `http_client`, `log`, `tool`, `script`, `claude-code` — or add your own.
|
|
127
|
+
- Security by default: GitHub App support, scoped tokens, remote‑extends allowlist, opt‑in network usage.
|
|
128
|
+
- Observability & control: JSON/SARIF outputs, fail‑fast and timeouts, parallelism and cost control.
|
|
129
|
+
|
|
130
|
+
## When to pick Visor
|
|
131
|
+
|
|
132
|
+
- You want native GitHub checks/annotations and config‑driven behavior
|
|
133
|
+
- You need structured outputs (schemas) and predictable templates
|
|
134
|
+
- You care about dependency‑aware execution and tag‑based profiles
|
|
135
|
+
- You want PR reviews + assistants + scheduled audits from one tool
|
|
136
|
+
- You prefer open‑source with no hidden rules
|
|
185
137
|
|
|
186
|
-
|
|
138
|
+
## 🧭 Developer Experience Playbook
|
|
187
139
|
|
|
188
|
-
|
|
140
|
+
Start with the defaults, iterate locally, and commit a shared `.visor.yaml` for your team.
|
|
189
141
|
|
|
190
|
-
|
|
142
|
+
Example:
|
|
143
|
+
```bash
|
|
144
|
+
npx @probelabs/visor --check all --debug
|
|
145
|
+
```
|
|
191
146
|
|
|
192
|
-
|
|
147
|
+
Learn more: [docs/dev-playbook.md](docs/dev-playbook.md)
|
|
193
148
|
|
|
194
|
-
|
|
195
|
-
2. **Filter execution** using `--tags` and `--exclude-tags` parameters
|
|
196
|
-
3. **Dependencies work intelligently** - they use what's available after filtering
|
|
149
|
+
## 🏷️ Tag-Based Check Filtering
|
|
197
150
|
|
|
198
|
-
|
|
151
|
+
Run subsets of checks (e.g., `local`, `fast`, `security`) and select them per environment with `--tags`/`--exclude-tags`.
|
|
199
152
|
|
|
153
|
+
Example:
|
|
200
154
|
```yaml
|
|
201
|
-
# .visor.yaml
|
|
202
|
-
version: "1.0"
|
|
203
|
-
|
|
204
155
|
checks:
|
|
205
|
-
# Fast, local security check
|
|
206
156
|
security-quick:
|
|
207
157
|
type: ai
|
|
208
|
-
prompt: "Quick security scan
|
|
158
|
+
prompt: "Quick security scan"
|
|
209
159
|
tags: ["local", "fast", "security"]
|
|
210
|
-
on: [pr_opened, pr_updated]
|
|
211
|
-
|
|
212
|
-
# Comprehensive security analysis (for CI)
|
|
213
|
-
security-comprehensive:
|
|
214
|
-
type: ai
|
|
215
|
-
prompt: "Deep security analysis with full vulnerability scanning"
|
|
216
|
-
tags: ["remote", "comprehensive", "security", "slow"]
|
|
217
|
-
on: [pr_opened]
|
|
218
|
-
|
|
219
|
-
# Performance check that runs everywhere
|
|
220
|
-
performance:
|
|
221
|
-
type: ai
|
|
222
|
-
prompt: "Analyze performance issues"
|
|
223
|
-
tags: ["local", "remote", "performance", "fast"]
|
|
224
|
-
on: [pr_opened, pr_updated]
|
|
225
|
-
|
|
226
|
-
# Experimental new check
|
|
227
|
-
ai-architecture:
|
|
228
|
-
type: ai
|
|
229
|
-
prompt: "AI-powered architecture review"
|
|
230
|
-
tags: ["experimental", "architecture", "slow"]
|
|
231
|
-
on: [manual]
|
|
232
|
-
|
|
233
|
-
# Report that depends on security checks
|
|
234
|
-
security-report:
|
|
235
|
-
type: noop
|
|
236
|
-
tags: ["reporting", "local", "remote"]
|
|
237
|
-
depends_on: [security-quick, security-comprehensive]
|
|
238
|
-
on: [pr_opened, pr_updated]
|
|
239
160
|
```
|
|
240
161
|
|
|
241
|
-
|
|
242
|
-
|
|
162
|
+
CLI:
|
|
243
163
|
```bash
|
|
244
|
-
# Run only fast, local checks (great for pre-commit hooks)
|
|
245
164
|
visor --tags local,fast
|
|
246
|
-
|
|
247
|
-
# Run comprehensive remote checks (for CI/CD)
|
|
248
|
-
visor --tags remote,comprehensive
|
|
249
|
-
|
|
250
|
-
# Run all security-related checks
|
|
251
|
-
visor --tags security
|
|
252
|
-
|
|
253
|
-
# Run everything except slow checks
|
|
254
|
-
visor --exclude-tags slow
|
|
255
|
-
|
|
256
|
-
# Run everything except experimental features
|
|
257
|
-
visor --exclude-tags experimental
|
|
258
|
-
|
|
259
|
-
# Combine filters: Run fast security checks only
|
|
260
|
-
visor --tags security,fast
|
|
261
|
-
|
|
262
|
-
# Run local checks but skip experimental ones
|
|
263
|
-
visor --tags local --exclude-tags experimental
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### GitHub Action Usage
|
|
267
|
-
|
|
268
|
-
```yaml
|
|
269
|
-
name: Code Review with Tags
|
|
270
|
-
on: pull_request
|
|
271
|
-
|
|
272
|
-
jobs:
|
|
273
|
-
# Fast checks on every push
|
|
274
|
-
fast-review:
|
|
275
|
-
runs-on: ubuntu-latest
|
|
276
|
-
steps:
|
|
277
|
-
- uses: actions/checkout@v4
|
|
278
|
-
- uses: gates-ai/visor-action@v1
|
|
279
|
-
with:
|
|
280
|
-
tags: "local,fast"
|
|
281
|
-
exclude-tags: "experimental"
|
|
282
|
-
env:
|
|
283
|
-
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
|
284
|
-
|
|
285
|
-
# Comprehensive checks only on main branch PRs
|
|
286
|
-
comprehensive-review:
|
|
287
|
-
if: github.base_ref == 'main'
|
|
288
|
-
runs-on: ubuntu-latest
|
|
289
|
-
steps:
|
|
290
|
-
- uses: actions/checkout@v4
|
|
291
|
-
- uses: gates-ai/visor-action@v1
|
|
292
|
-
with:
|
|
293
|
-
tags: "remote,comprehensive"
|
|
294
|
-
env:
|
|
295
|
-
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
|
296
165
|
```
|
|
297
166
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
| Tag | Purpose | Example Use |
|
|
301
|
-
|-----|---------|-------------|
|
|
302
|
-
| `local` | Checks suitable for local development | Pre-commit hooks, developer testing |
|
|
303
|
-
| `remote` | Checks designed for CI/CD environments | GitHub Actions, Jenkins |
|
|
304
|
-
| `fast` | Quick checks (< 30 seconds) | Rapid feedback loops |
|
|
305
|
-
| `slow` | Time-consuming checks | Nightly builds, release validation |
|
|
306
|
-
| `security` | Security-related checks | Security audits |
|
|
307
|
-
| `performance` | Performance analysis | Performance testing |
|
|
308
|
-
| `style` | Code style and formatting | Linting, formatting |
|
|
309
|
-
| `experimental` | Beta/testing features | Opt-in testing |
|
|
310
|
-
| `critical` | Must-pass checks | Release gates |
|
|
311
|
-
| `comprehensive` | Thorough analysis | Full PR reviews |
|
|
312
|
-
|
|
313
|
-
### Advanced Examples
|
|
314
|
-
|
|
315
|
-
#### Environment-Specific Execution
|
|
316
|
-
|
|
317
|
-
```yaml
|
|
318
|
-
# Development environment - fast feedback
|
|
319
|
-
development:
|
|
320
|
-
extends: .visor.yaml
|
|
321
|
-
tag_filter:
|
|
322
|
-
include: ["local", "fast"]
|
|
323
|
-
exclude: ["experimental"]
|
|
324
|
-
|
|
325
|
-
# Staging environment - balanced
|
|
326
|
-
staging:
|
|
327
|
-
extends: .visor.yaml
|
|
328
|
-
tag_filter:
|
|
329
|
-
include: ["remote", "security", "performance"]
|
|
330
|
-
exclude: ["experimental"]
|
|
331
|
-
|
|
332
|
-
# Production environment - comprehensive
|
|
333
|
-
production:
|
|
334
|
-
extends: .visor.yaml
|
|
335
|
-
tag_filter:
|
|
336
|
-
include: ["remote", "comprehensive", "critical"]
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
#### Multi-Stage Pipeline
|
|
340
|
-
|
|
341
|
-
```yaml
|
|
342
|
-
# GitHub Actions workflow with progressive checks
|
|
343
|
-
name: Progressive Code Review
|
|
344
|
-
on: pull_request
|
|
167
|
+
Learn more: [docs/tag-filtering.md](docs/tag-filtering.md)
|
|
345
168
|
|
|
346
|
-
|
|
347
|
-
stage-1-fast:
|
|
348
|
-
runs-on: ubuntu-latest
|
|
349
|
-
steps:
|
|
350
|
-
- uses: actions/checkout@v4
|
|
351
|
-
- uses: gates-ai/visor-action@v1
|
|
352
|
-
with:
|
|
353
|
-
tags: "fast,critical"
|
|
354
|
-
fail-fast: "true" # Stop if critical issues found
|
|
169
|
+
## 💬 PR Comment Commands
|
|
355
170
|
|
|
356
|
-
|
|
357
|
-
needs: stage-1-fast
|
|
358
|
-
runs-on: ubuntu-latest
|
|
359
|
-
steps:
|
|
360
|
-
- uses: actions/checkout@v4
|
|
361
|
-
- uses: gates-ai/visor-action@v1
|
|
362
|
-
with:
|
|
363
|
-
tags: "security"
|
|
364
|
-
exclude-tags: "fast" # Run deeper security checks
|
|
171
|
+
Trigger reviews and assistant actions via comments on PRs/issues.
|
|
365
172
|
|
|
366
|
-
|
|
367
|
-
needs: [stage-1-fast, stage-2-security]
|
|
368
|
-
runs-on: ubuntu-latest
|
|
369
|
-
steps:
|
|
370
|
-
- uses: actions/checkout@v4
|
|
371
|
-
- uses: gates-ai/visor-action@v1
|
|
372
|
-
with:
|
|
373
|
-
tags: "comprehensive"
|
|
374
|
-
exclude-tags: "fast,security" # Run remaining checks
|
|
173
|
+
Examples:
|
|
375
174
|
```
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
When using tags with dependencies, Visor intelligently handles missing dependencies:
|
|
380
|
-
|
|
381
|
-
```yaml
|
|
382
|
-
checks:
|
|
383
|
-
data-validation:
|
|
384
|
-
type: ai
|
|
385
|
-
prompt: "Validate data structures"
|
|
386
|
-
tags: ["local", "data"]
|
|
387
|
-
|
|
388
|
-
api-validation:
|
|
389
|
-
type: ai
|
|
390
|
-
prompt: "Validate API contracts"
|
|
391
|
-
tags: ["remote", "api"]
|
|
392
|
-
|
|
393
|
-
integration-report:
|
|
394
|
-
type: noop
|
|
395
|
-
tags: ["reporting"]
|
|
396
|
-
depends_on: [data-validation, api-validation]
|
|
397
|
-
# When filtered by "local" tag, only uses data-validation
|
|
398
|
-
# When filtered by "remote" tag, only uses api-validation
|
|
399
|
-
# With no filter, uses both dependencies
|
|
175
|
+
/review
|
|
176
|
+
/review --check security
|
|
177
|
+
/visor how does caching work?
|
|
400
178
|
```
|
|
401
179
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
- Tags must start with an alphanumeric character
|
|
405
|
-
- Can contain letters, numbers, hyphens, and underscores
|
|
406
|
-
- Examples: `local`, `test-env`, `feature_flag`, `v2`
|
|
407
|
-
- Invalid: `-invalid`, `@special`, `tag with spaces`
|
|
408
|
-
|
|
409
|
-
### Best Practices
|
|
410
|
-
|
|
411
|
-
1. **Use consistent naming conventions** across your organization
|
|
412
|
-
2. **Document your tag taxonomy** in your team's documentation
|
|
413
|
-
3. **Start simple** - begin with `local`/`remote` or `fast`/`slow`
|
|
414
|
-
4. **Avoid over-tagging** - too many tags can be confusing
|
|
415
|
-
5. **Use tag combinations** for fine-grained control
|
|
416
|
-
6. **Test your tag filters** before deploying to production
|
|
417
|
-
|
|
418
|
-
## 💬 PR Comment Commands
|
|
419
|
-
|
|
420
|
-
Add comments to your PR to trigger Visor:
|
|
421
|
-
|
|
422
|
-
- `/review` - Run all checks
|
|
423
|
-
- `/review --check security` - Run security checks only
|
|
424
|
-
- `/review --check performance` - Run performance checks only
|
|
425
|
-
- `/review --help` - Show available commands
|
|
180
|
+
Learn more: [docs/commands.md](docs/commands.md)
|
|
426
181
|
|
|
427
182
|
## 🔇 Suppressing Warnings
|
|
428
183
|
|
|
429
|
-
|
|
184
|
+
Suppress a specific issue by adding a nearby `visor-disable` comment.
|
|
430
185
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
```javascript
|
|
436
|
-
// Example: Suppress a specific warning
|
|
437
|
-
function authenticate() {
|
|
438
|
-
const testPassword = "demo123"; // visor-disable
|
|
439
|
-
// This hardcoded password warning will be suppressed
|
|
440
|
-
}
|
|
186
|
+
Example (JS):
|
|
187
|
+
```js
|
|
188
|
+
const testPassword = "demo123"; // visor-disable
|
|
441
189
|
```
|
|
442
190
|
|
|
443
|
-
|
|
444
|
-
- `// visor-disable` (JavaScript, TypeScript, C++, etc.)
|
|
445
|
-
- `# visor-disable` (Python, Ruby, Shell, etc.)
|
|
446
|
-
- `/* visor-disable */` (Multi-line comments)
|
|
447
|
-
- `<!-- visor-disable -->` (HTML, XML)
|
|
448
|
-
|
|
449
|
-
### File-Level Suppression
|
|
450
|
-
|
|
451
|
-
To suppress all warnings in an entire file, add `visor-disable-file` in the first 5 lines:
|
|
191
|
+
Learn more: [docs/suppressions.md](docs/suppressions.md)
|
|
452
192
|
|
|
453
|
-
|
|
454
|
-
// visor-disable-file
|
|
455
|
-
// All warnings in this file will be suppressed
|
|
456
|
-
|
|
457
|
-
function insecureCode() {
|
|
458
|
-
eval("user input"); // No warning
|
|
459
|
-
const password = "hardcoded"; // No warning
|
|
460
|
-
}
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
### Configuration
|
|
193
|
+
## 📋 CLI Usage
|
|
464
194
|
|
|
465
|
-
|
|
195
|
+
Run locally in any CI or dev machine.
|
|
466
196
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
output:
|
|
471
|
-
suppressionEnabled: false # Disable suppression comments
|
|
472
|
-
pr_comment:
|
|
473
|
-
format: markdown
|
|
474
|
-
group_by: check
|
|
197
|
+
Example:
|
|
198
|
+
```bash
|
|
199
|
+
npx @probelabs/visor --check all --output table
|
|
475
200
|
```
|
|
476
201
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
- Suppression comments are **case-insensitive** (`visor-disable`, `VISOR-DISABLE`, `Visor-Disable` all work)
|
|
480
|
-
- The comment just needs to contain the suppression keyword as a substring
|
|
481
|
-
- When issues are suppressed, Visor logs a summary showing which files had suppressed issues
|
|
482
|
-
- Use suppression judiciously - it's better to fix issues than suppress them
|
|
202
|
+
See [docs/NPM_USAGE.md](docs/NPM_USAGE.md) for full options and examples.
|
|
483
203
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
```python
|
|
487
|
-
# Python example
|
|
488
|
-
def process_data():
|
|
489
|
-
api_key = "sk-12345" # visor-disable
|
|
490
|
-
return api_key
|
|
491
|
-
```
|
|
204
|
+
## 🛠️ Troubleshooting
|
|
492
205
|
|
|
493
|
-
|
|
494
|
-
// TypeScript example - suppress within range
|
|
495
|
-
function riskyOperation() {
|
|
496
|
-
// visor-disable
|
|
497
|
-
const unsafe = eval(userInput); // Suppressed (within 2 lines)
|
|
498
|
-
processData(unsafe); // Suppressed (within 2 lines)
|
|
206
|
+
If comments/annotations don’t appear, verify workflow permissions and run with `--debug`.
|
|
499
207
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
208
|
+
Example:
|
|
209
|
+
```bash
|
|
210
|
+
node dist/index.js --cli --check all --debug
|
|
503
211
|
```
|
|
504
212
|
|
|
505
|
-
|
|
506
|
-
// Go example - file-level suppression
|
|
507
|
-
// visor-disable-file
|
|
508
|
-
package main
|
|
213
|
+
Learn more: [docs/troubleshooting.md](docs/troubleshooting.md)
|
|
509
214
|
|
|
510
|
-
|
|
511
|
-
password := "hardcoded" // All issues suppressed
|
|
512
|
-
fmt.Println(password)
|
|
513
|
-
}
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
## 📋 CLI Usage
|
|
215
|
+
## 🔐 Security Defaults
|
|
517
216
|
|
|
518
|
-
|
|
519
|
-
visor [options]
|
|
520
|
-
|
|
521
|
-
Options:
|
|
522
|
-
-c, --check <type> Check type: security, performance, style, architecture, all
|
|
523
|
-
Can be used multiple times: --check security --check style
|
|
524
|
-
-o, --output <format> Output format: table, json, markdown, sarif
|
|
525
|
-
Default: table
|
|
526
|
-
--config <path> Path to configuration file
|
|
527
|
-
Default search: ./.visor.yaml or ./.visor.yml
|
|
528
|
-
--max-parallelism <count> Maximum number of checks to run in parallel
|
|
529
|
-
Default: 3
|
|
530
|
-
--fail-fast Stop execution when any check fails
|
|
531
|
-
Default: false
|
|
532
|
-
--timeout <ms> Timeout for check operations in milliseconds
|
|
533
|
-
Default: 600000ms (10 minutes)
|
|
534
|
-
--debug Enable debug mode for detailed output
|
|
535
|
-
--allowed-remote-patterns Comma-separated list of allowed URL prefixes for remote configs
|
|
536
|
-
Example: "https://github.com/myorg/,https://raw.githubusercontent.com/"
|
|
537
|
-
--no-remote-extends Disable remote configuration extends for security
|
|
538
|
-
--version Show version
|
|
539
|
-
--help Show help
|
|
217
|
+
Prefer a GitHub App for production, and restrict remote extends unless explicitly allowed.
|
|
540
218
|
|
|
541
219
|
Examples:
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
visor --check all --max-parallelism 5 # Run up to 5 checks in parallel
|
|
546
|
-
visor --check all --fail-fast # Stop on first failure
|
|
547
|
-
visor --check all --timeout 300000 --debug # 5 minute timeout with debug output
|
|
548
|
-
|
|
549
|
-
# Using remote configs with security allowlist
|
|
550
|
-
visor --check all --allowed-remote-patterns "https://github.com/myorg/"
|
|
220
|
+
```bash
|
|
221
|
+
visor --no-remote-extends
|
|
222
|
+
visor --allowed-remote-patterns "https://raw.githubusercontent.com/myorg/"
|
|
551
223
|
```
|
|
552
224
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
- Not a git repository or no changes: run inside a Git repo with a diff (PR or local changes), or supply a config that doesn’t require PR context.
|
|
556
|
-
- No AI keys configured: Visor falls back to pattern checks. Set `GOOGLE_API_KEY`, `ANTHROPIC_API_KEY`, or `OPENAI_API_KEY` and optionally `MODEL_NAME`.
|
|
557
|
-
- Claude Code provider errors: install optional peers `@anthropic/claude-code-sdk` and `@modelcontextprotocol/sdk`, then set `CLAUDE_CODE_API_KEY` or `ANTHROPIC_API_KEY`.
|
|
558
|
-
- No PR comments posted: ensure workflow `permissions` include `pull-requests: write`; set `debug: true` (action input) or run `--debug` locally and inspect logs.
|
|
559
|
-
- Remote extends blocked: confirm `--no-remote-extends` or `VISOR_NO_REMOTE_EXTENDS=true` is intended; otherwise remove.
|
|
560
|
-
|
|
561
|
-
## 🔐 Security Defaults
|
|
562
|
-
|
|
563
|
-
- Use the workflow token by default; prefer a GitHub App for production (bot identity, least-privilege scopes).
|
|
564
|
-
- Lock remote configuration: set `VISOR_NO_REMOTE_EXTENDS=true` in CI or pass `--no-remote-extends` to avoid loading external configs.
|
|
565
|
-
- Scope AI API keys to a review-only project; rotate regularly and enable GitHub secret scanning alerts.
|
|
225
|
+
Learn more: [docs/security.md](docs/security.md)
|
|
566
226
|
|
|
567
227
|
## ⚡ Performance & Cost Controls
|
|
568
228
|
|
|
569
|
-
|
|
570
|
-
- Separate fast vs. deep checks via tags: run `local,fast` in PRs, `remote,comprehensive` nightly.
|
|
571
|
-
- Increase `max_parallelism` only when not using `reuse_ai_session` between dependent checks.
|
|
572
|
-
|
|
573
|
-
## 👀 Observability
|
|
574
|
-
|
|
575
|
-
- Machine-readable output: use `--output json` for pipelines; redirect SARIF for code scanning: `npx @probelabs/visor --check security --output sarif > visor-results.sarif`.
|
|
576
|
-
- Verbose logs: set `--debug` (CLI) or `debug: true` in the action input.
|
|
577
|
-
|
|
578
|
-
## 🤖 AI Configuration
|
|
229
|
+
Use tags for fast lanes and raise parallelism cautiously.
|
|
579
230
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
231
|
+
Example:
|
|
232
|
+
```bash
|
|
233
|
+
visor --tags local,fast --max-parallelism 5
|
|
234
|
+
```
|
|
583
235
|
|
|
584
|
-
|
|
585
|
-
|----------|---------------------|-------------------|
|
|
586
|
-
| Google Gemini | `GOOGLE_API_KEY` | `gemini-2.0-flash-exp` (default), `gemini-1.5-pro` |
|
|
587
|
-
| Anthropic Claude | `ANTHROPIC_API_KEY` | `claude-3-opus`, `claude-3-sonnet` |
|
|
588
|
-
| OpenAI GPT | `OPENAI_API_KEY` | `gpt-4`, `gpt-4-turbo`, `gpt-3.5-turbo` |
|
|
236
|
+
Learn more: [docs/performance.md](docs/performance.md)
|
|
589
237
|
|
|
590
|
-
|
|
238
|
+
## 👀 Observability
|
|
591
239
|
|
|
592
|
-
|
|
593
|
-
Add your API key as a repository secret:
|
|
594
|
-
1. Go to Settings → Secrets and variables → Actions
|
|
595
|
-
2. Click "New repository secret"
|
|
596
|
-
3. Add one of: `GOOGLE_API_KEY`, `ANTHROPIC_API_KEY`, or `OPENAI_API_KEY`
|
|
597
|
-
4. (Optional) Add `MODEL_NAME` to specify a model
|
|
240
|
+
Use JSON for pipelines or SARIF for code scanning.
|
|
598
241
|
|
|
599
|
-
|
|
600
|
-
Set environment variables:
|
|
242
|
+
Examples:
|
|
601
243
|
```bash
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
export MODEL_NAME="gemini-2.0-flash-exp"
|
|
605
|
-
|
|
606
|
-
# Using Anthropic Claude
|
|
607
|
-
export ANTHROPIC_API_KEY="your-api-key"
|
|
608
|
-
export MODEL_NAME="claude-3-sonnet"
|
|
609
|
-
|
|
610
|
-
# Using OpenAI GPT
|
|
611
|
-
export OPENAI_API_KEY="your-api-key"
|
|
612
|
-
export MODEL_NAME="gpt-4"
|
|
244
|
+
visor --check security --output json
|
|
245
|
+
visor --check security --output sarif > visor-results.sarif
|
|
613
246
|
```
|
|
614
247
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
- **Google Gemini**: [Get API Key](https://makersuite.google.com/app/apikey) (Free tier available)
|
|
618
|
-
- **Anthropic Claude**: [Get API Key](https://console.anthropic.com/)
|
|
619
|
-
- **OpenAI GPT**: [Get API Key](https://platform.openai.com/api-keys)
|
|
248
|
+
Learn more: [docs/observability.md](docs/observability.md)
|
|
620
249
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
If no API key is configured, Visor will fall back to basic pattern-matching analysis:
|
|
624
|
-
- Keyword detection for security issues (e.g., `eval`, `innerHTML`)
|
|
625
|
-
- Simple performance checks (nested loops, large files)
|
|
626
|
-
- Basic style validation
|
|
627
|
-
|
|
628
|
-
For best results, configure an AI provider for intelligent, context-aware code review.
|
|
250
|
+
## 🤖 AI Configuration
|
|
629
251
|
|
|
630
|
-
|
|
252
|
+
Set one provider key (Google/Anthropic/OpenAI) via env.
|
|
631
253
|
|
|
632
|
-
|
|
254
|
+
Example (Action):
|
|
255
|
+
```yaml
|
|
256
|
+
- uses: probelabs/visor@v1
|
|
257
|
+
env:
|
|
258
|
+
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
|
259
|
+
```
|
|
633
260
|
|
|
634
|
-
|
|
261
|
+
Learn more: [docs/ai-configuration.md](docs/ai-configuration.md)
|
|
635
262
|
|
|
636
|
-
|
|
263
|
+
## 📊 Step Dependencies & Intelligent Execution
|
|
637
264
|
|
|
638
|
-
|
|
265
|
+
Define `depends_on` to enforce order; independent checks run in parallel.
|
|
639
266
|
|
|
267
|
+
Example:
|
|
640
268
|
```yaml
|
|
641
|
-
# Global configuration
|
|
642
|
-
ai_provider: anthropic
|
|
643
|
-
ai_model: claude-3-sonnet
|
|
644
|
-
ai_mcp_servers:
|
|
645
|
-
probe:
|
|
646
|
-
command: "npx"
|
|
647
|
-
args: ["-y", "@probelabs/probe@latest", "mcp"]
|
|
648
|
-
filesystem:
|
|
649
|
-
command: "npx"
|
|
650
|
-
args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"]
|
|
651
|
-
|
|
652
269
|
checks:
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
prompt: "Review code using available MCP tools"
|
|
656
|
-
# Inherits global MCP servers automatically
|
|
270
|
+
security: { type: ai }
|
|
271
|
+
performance:{ type: ai, depends_on: [security] }
|
|
657
272
|
```
|
|
658
273
|
|
|
659
|
-
|
|
274
|
+
Learn more: [docs/dependencies.md](docs/dependencies.md)
|
|
660
275
|
|
|
661
|
-
|
|
276
|
+
## 🤖 Claude Code Provider
|
|
277
|
+
|
|
278
|
+
Use the Claude Code SDK as a provider for deeper analysis.
|
|
662
279
|
|
|
280
|
+
Example:
|
|
663
281
|
```yaml
|
|
664
282
|
checks:
|
|
665
|
-
|
|
666
|
-
type:
|
|
667
|
-
prompt: "Analyze
|
|
668
|
-
ai_mcp_servers: # Overrides global servers
|
|
669
|
-
probe:
|
|
670
|
-
command: "npx"
|
|
671
|
-
args: ["-y", "@probelabs/probe@latest", "mcp"]
|
|
672
|
-
custom_profiler:
|
|
673
|
-
command: "python3"
|
|
674
|
-
args: ["./tools/performance-analyzer.py"]
|
|
283
|
+
claude-review:
|
|
284
|
+
type: claude-code
|
|
285
|
+
prompt: "Analyze code complexity"
|
|
675
286
|
```
|
|
676
287
|
|
|
677
|
-
|
|
288
|
+
Learn more: [docs/claude-code.md](docs/claude-code.md)
|
|
678
289
|
|
|
679
|
-
|
|
290
|
+
## 🔄 AI Session Reuse
|
|
291
|
+
|
|
292
|
+
Reuse context between dependent AI checks for smarter follow‑ups.
|
|
680
293
|
|
|
294
|
+
Example:
|
|
681
295
|
```yaml
|
|
682
296
|
checks:
|
|
683
|
-
|
|
297
|
+
security: { type: ai }
|
|
298
|
+
remediation:
|
|
684
299
|
type: ai
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
provider: anthropic
|
|
688
|
-
mcpServers: # Overrides everything else
|
|
689
|
-
probe:
|
|
690
|
-
command: "npx"
|
|
691
|
-
args: ["-y", "@probelabs/probe@latest", "mcp"]
|
|
692
|
-
github:
|
|
693
|
-
command: "npx"
|
|
694
|
-
args: ["-y", "@modelcontextprotocol/server-github"]
|
|
300
|
+
depends_on: [security]
|
|
301
|
+
reuse_ai_session: true
|
|
695
302
|
```
|
|
696
303
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
- **Probe**: Advanced code search and analysis (`@probelabs/probe`)
|
|
700
|
-
- **Jira**: Jira Cloud integration for issue management (`@orengrinker/jira-mcp-server`)
|
|
701
|
-
- **Filesystem**: File system access (`@modelcontextprotocol/server-filesystem`)
|
|
702
|
-
- **GitHub**: GitHub API access (coming soon)
|
|
703
|
-
- **Custom**: Your own MCP servers
|
|
704
|
-
|
|
705
|
-
#### Example Configurations
|
|
706
|
-
|
|
707
|
-
- [Basic MCP with Probe](examples/ai-with-mcp.yaml) - Code analysis with multiple MCP servers
|
|
708
|
-
- [Jira Workflow Automation](examples/jira-workflow-mcp.yaml) - Complete Jira integration examples
|
|
709
|
-
- [Simple Jira Analysis](examples/jira-simple-example.yaml) - Basic JQL → analyze → label workflow
|
|
710
|
-
- [Setup Guide](examples/JIRA_MCP_SETUP.md) - Detailed Jira MCP configuration instructions
|
|
711
|
-
|
|
712
|
-
## 📊 Step Dependencies & Intelligent Execution
|
|
713
|
-
|
|
714
|
-
### Dependency-Aware Check Execution
|
|
715
|
-
|
|
716
|
-
Visor supports defining dependencies between checks using the `depends_on` field. This enables:
|
|
304
|
+
Learn more: [docs/advanced-ai.md](docs/advanced-ai.md)
|
|
717
305
|
|
|
718
|
-
|
|
719
|
-
- **Parallel Optimization**: Independent checks run simultaneously for faster execution
|
|
720
|
-
- **Smart Scheduling**: Automatic topological sorting ensures correct execution order
|
|
306
|
+
## 📋 Schema-Template System
|
|
721
307
|
|
|
722
|
-
|
|
308
|
+
Schemas validate outputs; templates render GitHub‑friendly comments.
|
|
723
309
|
|
|
310
|
+
Example:
|
|
724
311
|
```yaml
|
|
725
|
-
version: "1.0"
|
|
726
312
|
checks:
|
|
727
313
|
security:
|
|
728
314
|
type: ai
|
|
729
|
-
group: code-review
|
|
730
|
-
schema: code-review
|
|
731
|
-
prompt: "Comprehensive security analysis..."
|
|
732
|
-
tags: ["security", "critical", "comprehensive"]
|
|
733
|
-
on: [pr_opened, pr_updated]
|
|
734
|
-
# No dependencies - runs first
|
|
735
|
-
|
|
736
|
-
performance:
|
|
737
|
-
type: ai
|
|
738
|
-
group: code-review
|
|
739
|
-
schema: code-review
|
|
740
|
-
prompt: "Performance analysis..."
|
|
741
|
-
tags: ["performance", "fast", "local", "remote"]
|
|
742
|
-
on: [pr_opened, pr_updated]
|
|
743
|
-
# No dependencies - runs parallel with security
|
|
744
|
-
|
|
745
|
-
style:
|
|
746
|
-
type: ai
|
|
747
|
-
group: code-review
|
|
748
|
-
schema: code-review
|
|
749
|
-
prompt: "Style analysis based on security findings..."
|
|
750
|
-
tags: ["style", "fast", "local"]
|
|
751
|
-
on: [pr_opened]
|
|
752
|
-
depends_on: [security] # Waits for security to complete
|
|
753
|
-
|
|
754
|
-
architecture:
|
|
755
|
-
type: ai
|
|
756
|
-
group: code-review
|
|
757
315
|
schema: code-review
|
|
758
|
-
prompt: "
|
|
759
|
-
on: [pr_opened, pr_updated]
|
|
760
|
-
depends_on: [security, performance] # Waits for both to complete
|
|
316
|
+
prompt: "Return JSON matching code-review schema"
|
|
761
317
|
```
|
|
762
318
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
With the above configuration:
|
|
766
|
-
1. **Level 0**: `security` and `performance` run in parallel
|
|
767
|
-
2. **Level 1**: `style` runs after `security` completes
|
|
768
|
-
3. **Level 2**: `architecture` runs after both `security` and `performance` complete
|
|
769
|
-
|
|
770
|
-
### Benefits
|
|
319
|
+
Learn more: [docs/schema-templates.md](docs/schema-templates.md)
|
|
771
320
|
|
|
772
|
-
|
|
773
|
-
- **Better Context**: Later checks can reference findings from dependencies
|
|
774
|
-
- **Logical Flow**: Ensures foundational checks (like security) complete before specialized ones
|
|
775
|
-
- **Error Handling**: Failed dependencies don't prevent other independent checks from running
|
|
776
|
-
|
|
777
|
-
### Advanced Patterns
|
|
321
|
+
## 🎯 Enhanced Prompts
|
|
778
322
|
|
|
779
|
-
|
|
780
|
-
```yaml
|
|
781
|
-
version: "1.0"
|
|
782
|
-
checks:
|
|
783
|
-
foundation:
|
|
784
|
-
type: ai
|
|
785
|
-
group: base
|
|
786
|
-
schema: code-review
|
|
787
|
-
prompt: "Base analysis"
|
|
788
|
-
|
|
789
|
-
branch_a:
|
|
790
|
-
type: ai
|
|
791
|
-
group: code-review
|
|
792
|
-
schema: code-review
|
|
793
|
-
depends_on: [foundation]
|
|
794
|
-
|
|
795
|
-
branch_b:
|
|
796
|
-
type: ai
|
|
797
|
-
group: code-review
|
|
798
|
-
schema: code-review
|
|
799
|
-
depends_on: [foundation]
|
|
800
|
-
|
|
801
|
-
final:
|
|
802
|
-
type: ai
|
|
803
|
-
group: summary
|
|
804
|
-
schema: markdown
|
|
805
|
-
depends_on: [branch_a, branch_b]
|
|
806
|
-
```
|
|
323
|
+
Write prompts inline or in files; Liquid variables provide PR context.
|
|
807
324
|
|
|
808
|
-
|
|
325
|
+
Example:
|
|
809
326
|
```yaml
|
|
810
|
-
version: "1.0"
|
|
811
327
|
checks:
|
|
812
|
-
|
|
813
|
-
security_basic:
|
|
814
|
-
type: ai
|
|
815
|
-
group: security
|
|
816
|
-
schema: code-review
|
|
817
|
-
prompt: "Basic security scan"
|
|
818
|
-
|
|
819
|
-
security_advanced:
|
|
820
|
-
type: ai
|
|
821
|
-
group: security
|
|
822
|
-
schema: code-review
|
|
823
|
-
depends_on: [security_basic]
|
|
824
|
-
|
|
825
|
-
# Performance chain
|
|
826
|
-
performance_basic:
|
|
827
|
-
type: ai
|
|
828
|
-
group: performance
|
|
829
|
-
schema: code-review
|
|
830
|
-
prompt: "Basic performance scan"
|
|
831
|
-
|
|
832
|
-
performance_advanced:
|
|
833
|
-
type: ai
|
|
834
|
-
group: performance
|
|
835
|
-
schema: code-review
|
|
836
|
-
depends_on: [performance_basic]
|
|
837
|
-
|
|
838
|
-
# Final integration (waits for both chains)
|
|
839
|
-
integration:
|
|
328
|
+
overview:
|
|
840
329
|
type: ai
|
|
841
|
-
|
|
842
|
-
schema: markdown
|
|
843
|
-
depends_on: [security_advanced, performance_advanced]
|
|
330
|
+
prompt: ./prompts/overview.liquid
|
|
844
331
|
```
|
|
845
332
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
- **Cycle Detection**: Circular dependencies are detected and reported
|
|
849
|
-
- **Missing Dependencies**: References to non-existent checks are validated
|
|
850
|
-
- **Graceful Failures**: Failed checks don't prevent independent checks from running
|
|
851
|
-
- **Dependency Results**: Results from dependency checks are available to dependent checks
|
|
333
|
+
Learn more: [docs/schema-templates.md](docs/schema-templates.md)
|
|
852
334
|
|
|
853
|
-
##
|
|
854
|
-
|
|
855
|
-
Visor includes advanced integration with Claude Code SDK, providing powerful AI-driven code analysis with MCP (Model Context Protocol) tools and subagent support.
|
|
856
|
-
|
|
857
|
-
### Features
|
|
858
|
-
|
|
859
|
-
- **Advanced AI Analysis**: Leverages Claude Code's sophisticated understanding
|
|
860
|
-
- **MCP Tools**: Built-in and custom tools for specialized analysis
|
|
861
|
-
- **Subagents**: Delegate specific tasks to specialized agents
|
|
862
|
-
- **Streaming Responses**: Real-time feedback during analysis
|
|
863
|
-
- **Flexible Permissions**: Granular control over tool usage
|
|
335
|
+
## 🔧 Advanced Configuration
|
|
864
336
|
|
|
865
|
-
|
|
337
|
+
Extend shared configs and override per‑repo settings.
|
|
866
338
|
|
|
339
|
+
Example:
|
|
867
340
|
```yaml
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
prompt: "Perform a comprehensive security and performance review"
|
|
872
|
-
tags: ["comprehensive", "security", "performance", "slow", "remote"]
|
|
873
|
-
claude_code:
|
|
874
|
-
allowedTools: ['Grep', 'Read', 'WebSearch']
|
|
875
|
-
maxTurns: 5
|
|
876
|
-
systemPrompt: "You are an expert security auditor"
|
|
877
|
-
|
|
878
|
-
claude_with_mcp:
|
|
879
|
-
type: claude-code
|
|
880
|
-
prompt: "Analyze code complexity and architecture"
|
|
881
|
-
tags: ["architecture", "complexity", "comprehensive", "remote"]
|
|
882
|
-
claude_code:
|
|
883
|
-
allowedTools: ['analyze_file_structure', 'calculate_complexity']
|
|
884
|
-
mcpServers:
|
|
885
|
-
custom_analyzer:
|
|
886
|
-
command: "node"
|
|
887
|
-
args: ["./mcp-servers/analyzer.js"]
|
|
888
|
-
env:
|
|
889
|
-
ANALYSIS_MODE: "deep"
|
|
890
|
-
```
|
|
891
|
-
|
|
892
|
-
### Built-in MCP Tools
|
|
893
|
-
|
|
894
|
-
- `analyze_file_structure`: Analyzes project organization
|
|
895
|
-
- `detect_patterns`: Identifies code patterns and anti-patterns
|
|
896
|
-
- `calculate_complexity`: Computes complexity metrics
|
|
897
|
-
- `suggest_improvements`: Provides improvement recommendations
|
|
898
|
-
|
|
899
|
-
### Custom MCP Servers
|
|
900
|
-
|
|
901
|
-
Create `.mcp.json` in your project root:
|
|
902
|
-
|
|
903
|
-
```json
|
|
904
|
-
{
|
|
905
|
-
"mcpServers": {
|
|
906
|
-
"security_scanner": {
|
|
907
|
-
"command": "python",
|
|
908
|
-
"args": ["./tools/security_scanner.py"],
|
|
909
|
-
"env": {
|
|
910
|
-
"SCAN_DEPTH": "full"
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
```
|
|
916
|
-
|
|
917
|
-
### Environment Setup
|
|
918
|
-
|
|
919
|
-
```bash
|
|
920
|
-
# Install Claude Code CLI (required)
|
|
921
|
-
npm install -g @anthropic-ai/claude-code
|
|
922
|
-
|
|
923
|
-
# Set API key (optional - uses local Claude Code if available)
|
|
924
|
-
export CLAUDE_CODE_API_KEY=your-api-key
|
|
341
|
+
extends:
|
|
342
|
+
- default
|
|
343
|
+
- ./team-standards.yaml
|
|
925
344
|
```
|
|
926
345
|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
Visor supports AI session reuse for dependent checks, allowing follow-up analysis to maintain conversation context with the AI. This creates more intelligent, contextual analysis workflows.
|
|
346
|
+
Learn more: [docs/configuration.md](docs/configuration.md)
|
|
930
347
|
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
When `reuse_ai_session: true` is set on a dependent check, Visor:
|
|
934
|
-
1. **Reuses the ProbeAgent session** from the parent check
|
|
935
|
-
2. **Maintains conversation context** - the AI remembers the previous discussion
|
|
936
|
-
3. **Forces sequential execution** - dependent checks with session reuse run sequentially to preserve context
|
|
937
|
-
4. **Provides intelligent follow-ups** - the AI can reference previous findings
|
|
348
|
+
## 🌐 HTTP Integration & Scheduling
|
|
938
349
|
|
|
939
|
-
|
|
350
|
+
Receive webhooks, call APIs, and schedule checks.
|
|
940
351
|
|
|
352
|
+
Examples:
|
|
941
353
|
```yaml
|
|
942
|
-
|
|
943
|
-
|
|
354
|
+
http_server: { enabled: true, port: 8080 }
|
|
944
355
|
checks:
|
|
945
|
-
|
|
946
|
-
type: ai
|
|
947
|
-
group: review
|
|
948
|
-
schema: code-review
|
|
949
|
-
prompt: "Analyze code for security vulnerabilities..."
|
|
950
|
-
on: [pr_opened, pr_updated]
|
|
951
|
-
|
|
952
|
-
security-remediation:
|
|
953
|
-
type: ai
|
|
954
|
-
group: review
|
|
955
|
-
schema: code-review
|
|
956
|
-
prompt: |
|
|
957
|
-
Based on our previous security analysis discussion,
|
|
958
|
-
provide detailed remediation guidance for the issues we identified.
|
|
959
|
-
depends_on: [security]
|
|
960
|
-
reuse_ai_session: true # 🔄 Reuses security check's AI session
|
|
961
|
-
on: [pr_opened, pr_updated]
|
|
356
|
+
nightly: { type: ai, schedule: "0 2 * * *" }
|
|
962
357
|
```
|
|
963
358
|
|
|
964
|
-
|
|
359
|
+
Learn more: [docs/http.md](docs/http.md)
|
|
965
360
|
|
|
966
|
-
|
|
967
|
-
- **Cost Efficiency**: Reuses existing AI sessions instead of creating new ones
|
|
968
|
-
- **Better Analysis**: Follow-up prompts build on previous discussion
|
|
969
|
-
- **Natural Conversation Flow**: Creates multi-turn conversations with AI
|
|
970
|
-
|
|
971
|
-
### Validation Rules
|
|
361
|
+
## 🔧 Pluggable Architecture
|
|
972
362
|
|
|
973
|
-
|
|
974
|
-
- **Sequential Execution**: Checks with session reuse are automatically scheduled sequentially
|
|
975
|
-
- **AI Checks Only**: Only works with `type: ai` checks
|
|
976
|
-
- **Clear Error Messages**: Invalid configurations provide helpful guidance
|
|
363
|
+
Mix providers (`ai`, `http`, `http_client`, `log`, `tool`, `script`, `claude-code`) or add your own.
|
|
977
364
|
|
|
978
|
-
|
|
365
|
+
Learn more: [docs/pluggable.md](docs/pluggable.md)
|
|
979
366
|
|
|
980
|
-
|
|
981
|
-
```yaml
|
|
982
|
-
security:
|
|
983
|
-
type: ai
|
|
984
|
-
prompt: "Identify security vulnerabilities..."
|
|
985
|
-
|
|
986
|
-
security-fixes:
|
|
987
|
-
type: ai
|
|
988
|
-
prompt: "Based on our security discussion, provide step-by-step fix instructions..."
|
|
989
|
-
depends_on: [security]
|
|
990
|
-
reuse_ai_session: true
|
|
991
|
-
```
|
|
367
|
+
## 🎯 GitHub Action Reference
|
|
992
368
|
|
|
993
|
-
|
|
994
|
-
```yaml
|
|
995
|
-
performance:
|
|
996
|
-
type: ai
|
|
997
|
-
prompt: "Analyze performance issues..."
|
|
998
|
-
|
|
999
|
-
performance-optimization:
|
|
1000
|
-
type: ai
|
|
1001
|
-
prompt: "Building on our performance analysis, create an optimization roadmap..."
|
|
1002
|
-
depends_on: [performance]
|
|
1003
|
-
reuse_ai_session: true
|
|
1004
|
-
```
|
|
369
|
+
Common inputs include `max-parallelism`, `fail-fast`, and `config-path`.
|
|
1005
370
|
|
|
1006
|
-
|
|
371
|
+
Example:
|
|
1007
372
|
```yaml
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
clarification:
|
|
1013
|
-
type: ai
|
|
1014
|
-
prompt: "Let's dive deeper into the most critical issues we identified..."
|
|
1015
|
-
depends_on: [initial-review]
|
|
1016
|
-
reuse_ai_session: true
|
|
1017
|
-
|
|
1018
|
-
final-recommendations:
|
|
1019
|
-
type: ai
|
|
1020
|
-
prompt: "Summarize our discussion with prioritized action items..."
|
|
1021
|
-
depends_on: [clarification]
|
|
1022
|
-
reuse_ai_session: true
|
|
373
|
+
- uses: probelabs/visor@v1
|
|
374
|
+
with:
|
|
375
|
+
max-parallelism: 5
|
|
1023
376
|
```
|
|
1024
377
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
Visor's new schema-template system provides structured output validation and customizable rendering, replacing the previous category-based approach with a more flexible, configuration-driven system.
|
|
1028
|
-
|
|
1029
|
-
### Overview
|
|
378
|
+
Learn more: [docs/action-reference.md](docs/action-reference.md)
|
|
1030
379
|
|
|
1031
|
-
|
|
380
|
+
## 📊 Output Formats
|
|
1032
381
|
|
|
1033
|
-
|
|
1034
|
-
- **Liquid Templates**: Dynamic content rendering with conditional logic and loops
|
|
1035
|
-
- **Multiple Output Formats**: Support for structured tables, free-form markdown, and custom formats
|
|
1036
|
-
- **Group-Based Comments**: Create separate GitHub comments based on `group` configuration
|
|
1037
|
-
- **Check-Focused Organization**: Group issues by check name rather than artificial categories
|
|
1038
|
-
- **Extensible Design**: Easy to add new schemas and output formats
|
|
382
|
+
Emit `table`, `json`, `markdown`, or `sarif`.
|
|
1039
383
|
|
|
1040
|
-
|
|
384
|
+
Example:
|
|
385
|
+
```bash
|
|
386
|
+
visor --check security --output json
|
|
387
|
+
```
|
|
1041
388
|
|
|
1042
|
-
|
|
1043
|
-
version: "1.0"
|
|
1044
|
-
|
|
1045
|
-
checks:
|
|
1046
|
-
security:
|
|
1047
|
-
type: ai
|
|
1048
|
-
group: code-review # Groups this check with others for commenting
|
|
1049
|
-
schema: code-review # Uses built-in code-review schema
|
|
1050
|
-
prompt: |
|
|
1051
|
-
Perform comprehensive security analysis focusing on:
|
|
1052
|
-
- SQL injection vulnerabilities
|
|
1053
|
-
- XSS attack vectors
|
|
1054
|
-
- Authentication/authorization issues
|
|
1055
|
-
|
|
1056
|
-
Return results in JSON format matching the code-review schema.
|
|
1057
|
-
on: [pr_opened, pr_updated]
|
|
1058
|
-
|
|
1059
|
-
performance:
|
|
1060
|
-
type: ai
|
|
1061
|
-
group: code-review # Same group = combined in one comment
|
|
1062
|
-
schema: code-review # Same schema = same table format
|
|
1063
|
-
prompt: |
|
|
1064
|
-
Analyze performance issues including:
|
|
1065
|
-
- Algorithm complexity
|
|
1066
|
-
- Memory usage patterns
|
|
1067
|
-
- Database query optimization
|
|
1068
|
-
on: [pr_opened, pr_updated]
|
|
1069
|
-
|
|
1070
|
-
full-review:
|
|
1071
|
-
type: ai
|
|
1072
|
-
group: pr-overview # Different group = separate comment
|
|
1073
|
-
schema: text # Uses built-in text schema for markdown
|
|
1074
|
-
prompt: |
|
|
1075
|
-
Create a comprehensive pull request overview in markdown format with:
|
|
1076
|
-
|
|
1077
|
-
## 📋 Pull Request Overview
|
|
1078
|
-
1. **Summary**: Brief description of changes
|
|
1079
|
-
2. **Files Changed**: Table of modified files
|
|
1080
|
-
3. **Architecture Impact**: Key architectural considerations
|
|
1081
|
-
on: [pr_opened]
|
|
1082
|
-
```
|
|
1083
|
-
|
|
1084
|
-
## 🎯 Enhanced Prompts
|
|
1085
|
-
|
|
1086
|
-
Visor supports advanced prompt features including Liquid templates, file-based prompts, and access to event context and previous check results.
|
|
1087
|
-
|
|
1088
|
-
### Smart Auto-Detection
|
|
1089
|
-
|
|
1090
|
-
Visor automatically detects whether your prompt is a file path or inline content:
|
|
1091
|
-
|
|
1092
|
-
```yaml
|
|
1093
|
-
checks:
|
|
1094
|
-
security:
|
|
1095
|
-
type: ai
|
|
1096
|
-
# File path - automatically detected
|
|
1097
|
-
prompt: ./templates/security-analysis.liquid
|
|
1098
|
-
|
|
1099
|
-
performance:
|
|
1100
|
-
type: ai
|
|
1101
|
-
# Inline string - automatically detected
|
|
1102
|
-
prompt: "Analyze this code for performance issues"
|
|
1103
|
-
|
|
1104
|
-
quality:
|
|
1105
|
-
type: ai
|
|
1106
|
-
# Multi-line string - automatically detected
|
|
1107
|
-
prompt: |
|
|
1108
|
-
Review this code for:
|
|
1109
|
-
- Code quality issues
|
|
1110
|
-
- Best practices violations
|
|
1111
|
-
- Maintainability concerns
|
|
1112
|
-
```
|
|
1113
|
-
|
|
1114
|
-
**Auto-detection rules:**
|
|
1115
|
-
- ✅ **File paths**: `./file.liquid`, `../templates/prompt.md`, `/absolute/path/file.txt`
|
|
1116
|
-
- ✅ **Inline content**: `Analyze this code`, `Review for security issues`
|
|
1117
|
-
- ✅ **Multi-line**: Uses YAML `|` or `>` syntax for longer prompts
|
|
1118
|
-
|
|
1119
|
-
### Liquid Template Support
|
|
1120
|
-
|
|
1121
|
-
Prompts can use [Liquid templating](https://shopify.github.io/liquid/) with rich context data:
|
|
1122
|
-
|
|
1123
|
-
```yaml
|
|
1124
|
-
checks:
|
|
1125
|
-
context-aware-review:
|
|
1126
|
-
type: ai
|
|
1127
|
-
prompt: |
|
|
1128
|
-
# Review for PR {{ pr.number }}: {{ pr.title }}
|
|
1129
|
-
|
|
1130
|
-
## PR Details
|
|
1131
|
-
- Author: {{ pr.author }}
|
|
1132
|
-
- Branch: {{ pr.headBranch }} → {{ pr.baseBranch }}
|
|
1133
|
-
- Files changed: {{ files.size }}
|
|
1134
|
-
- Total changes: +{{ pr.totalAdditions }}/-{{ pr.totalDeletions }}
|
|
1135
|
-
|
|
1136
|
-
## File Analysis
|
|
1137
|
-
{% if utils.filesByExtension.ts %}
|
|
1138
|
-
### TypeScript Files ({{ utils.filesByExtension.ts.size }})
|
|
1139
|
-
{% for file in utils.filesByExtension.ts %}
|
|
1140
|
-
- {{ file.filename }} (+{{ file.additions }}/-{{ file.deletions }})
|
|
1141
|
-
{% endfor %}
|
|
1142
|
-
{% endif %}
|
|
1143
|
-
|
|
1144
|
-
{% if utils.hasLargeChanges %}
|
|
1145
|
-
⚠️ **Warning**: This PR contains large changes requiring careful review.
|
|
1146
|
-
{% endif %}
|
|
1147
|
-
|
|
1148
|
-
## Previous Results
|
|
1149
|
-
{% if outputs.security %}
|
|
1150
|
-
Security check found {{ outputs.security.totalIssues }} issues:
|
|
1151
|
-
{% for issue in outputs.security.securityIssues %}
|
|
1152
|
-
- **{{ issue.severity | upcase }}**: {{ issue.message }} in {{ issue.file }}:{{ issue.line }}
|
|
1153
|
-
{% endfor %}
|
|
1154
|
-
{% endif %}
|
|
1155
|
-
on: [pr_opened, pr_updated]
|
|
1156
|
-
```
|
|
1157
|
-
|
|
1158
|
-
### File-Based Prompts
|
|
1159
|
-
|
|
1160
|
-
Store prompts in external files for better organization:
|
|
1161
|
-
|
|
1162
|
-
```yaml
|
|
1163
|
-
checks:
|
|
1164
|
-
security-review:
|
|
1165
|
-
type: ai
|
|
1166
|
-
prompt: ./prompts/security-detailed.liquid # Auto-detects file path
|
|
1167
|
-
on: [pr_opened, pr_updated]
|
|
1168
|
-
|
|
1169
|
-
architecture-check:
|
|
1170
|
-
type: ai
|
|
1171
|
-
prompt: /absolute/path/to/architecture-prompt.liquid # Auto-detects file path
|
|
1172
|
-
on: [pr_opened]
|
|
1173
|
-
```
|
|
1174
|
-
|
|
1175
|
-
### Template Context Variables
|
|
1176
|
-
|
|
1177
|
-
#### PR Information (`pr`)
|
|
1178
|
-
```liquid
|
|
1179
|
-
{{ pr.number }} <!-- PR number -->
|
|
1180
|
-
{{ pr.title }} <!-- PR title -->
|
|
1181
|
-
{{ pr.author }} <!-- PR author -->
|
|
1182
|
-
{{ pr.baseBranch }} <!-- Base branch name -->
|
|
1183
|
-
{{ pr.headBranch }} <!-- Head branch name -->
|
|
1184
|
-
{{ pr.totalAdditions }} <!-- Total lines added -->
|
|
1185
|
-
{{ pr.totalDeletions }} <!-- Total lines deleted -->
|
|
1186
|
-
{{ pr.isIncremental }} <!-- Boolean: incremental analysis -->
|
|
1187
|
-
```
|
|
1188
|
-
|
|
1189
|
-
#### File Information (`files` and `utils`)
|
|
1190
|
-
```liquid
|
|
1191
|
-
{{ files.size }} <!-- Number of files changed -->
|
|
1192
|
-
{{ utils.filesByExtension.ts.size }} <!-- TypeScript files count -->
|
|
1193
|
-
{{ utils.filesByExtension.js.size }} <!-- JavaScript files count -->
|
|
1194
|
-
{{ utils.addedFiles.size }} <!-- Newly added files -->
|
|
1195
|
-
{{ utils.modifiedFiles.size }} <!-- Modified files -->
|
|
1196
|
-
{{ utils.hasLargeChanges }} <!-- Boolean: large changes detected -->
|
|
1197
|
-
{{ utils.totalFiles }} <!-- Total files changed -->
|
|
1198
|
-
```
|
|
1199
|
-
|
|
1200
|
-
#### GitHub Event Context (`event`)
|
|
1201
|
-
```liquid
|
|
1202
|
-
{{ event.name }} <!-- Event name (pull_request, issue_comment, etc.) -->
|
|
1203
|
-
{{ event.action }} <!-- Event action (opened, updated, etc.) -->
|
|
1204
|
-
{{ event.repository.fullName }} <!-- Repository owner/name -->
|
|
1205
|
-
|
|
1206
|
-
<!-- For comment-triggered events -->
|
|
1207
|
-
{% if event.comment %}
|
|
1208
|
-
{{ event.comment.body }} <!-- Comment text -->
|
|
1209
|
-
{{ event.comment.author }} <!-- Comment author -->
|
|
1210
|
-
{% endif %}
|
|
1211
|
-
```
|
|
1212
|
-
|
|
1213
|
-
#### Previous Check Results (`outputs`)
|
|
1214
|
-
```liquid
|
|
1215
|
-
{% if outputs.security %}
|
|
1216
|
-
Security Results:
|
|
1217
|
-
- Total issues: {{ outputs.security.totalIssues }}
|
|
1218
|
-
- Critical: {{ outputs.security.criticalIssues }}
|
|
1219
|
-
- Errors: {{ outputs.security.errorIssues }}
|
|
1220
|
-
- Warnings: {{ outputs.security.warningIssues }}
|
|
1221
|
-
|
|
1222
|
-
Security Issues:
|
|
1223
|
-
{% for issue in outputs.security.securityIssues %}
|
|
1224
|
-
- {{ issue.severity | upcase }}: {{ issue.message }}
|
|
1225
|
-
{% endfor %}
|
|
1226
|
-
|
|
1227
|
-
Suggestions:
|
|
1228
|
-
{% for suggestion in outputs.security.suggestions %}
|
|
1229
|
-
- {{ suggestion }}
|
|
1230
|
-
{% endfor %}
|
|
1231
|
-
{% endif %}
|
|
1232
|
-
```
|
|
1233
|
-
|
|
1234
|
-
### Custom Templates
|
|
1235
|
-
|
|
1236
|
-
Customize output rendering with custom templates:
|
|
1237
|
-
|
|
1238
|
-
```yaml
|
|
1239
|
-
checks:
|
|
1240
|
-
security-with-custom-output:
|
|
1241
|
-
type: ai
|
|
1242
|
-
prompt: "Analyze security vulnerabilities..."
|
|
1243
|
-
template:
|
|
1244
|
-
file: ./templates/security-report.liquid
|
|
1245
|
-
# OR inline content:
|
|
1246
|
-
# content: |
|
|
1247
|
-
# # 🔒 Security Report
|
|
1248
|
-
# {% for issue in issues %}
|
|
1249
|
-
# - **{{ issue.severity }}**: {{ issue.message }}
|
|
1250
|
-
# {% endfor %}
|
|
1251
|
-
on: [pr_opened]
|
|
1252
|
-
```
|
|
1253
|
-
|
|
1254
|
-
### Advanced Example: Multi-Context Review
|
|
1255
|
-
|
|
1256
|
-
```yaml
|
|
1257
|
-
checks:
|
|
1258
|
-
comprehensive-review:
|
|
1259
|
-
type: ai
|
|
1260
|
-
depends_on: [security, performance] # Run after these checks
|
|
1261
|
-
prompt:
|
|
1262
|
-
content: |
|
|
1263
|
-
# Comprehensive Review for {{ event.repository.fullName }}#{{ pr.number }}
|
|
1264
|
-
|
|
1265
|
-
{% if event.comment %}
|
|
1266
|
-
Triggered by comment: "{{ event.comment.body }}" from {{ event.comment.author }}
|
|
1267
|
-
{% endif %}
|
|
1268
|
-
|
|
1269
|
-
## Previous Analysis Summary
|
|
1270
|
-
{% if outputs.security %}
|
|
1271
|
-
- **Security**: {{ outputs.security.totalIssues }} issues found
|
|
1272
|
-
{% for issue in outputs.security.criticalIssues %}
|
|
1273
|
-
- 🔴 **CRITICAL**: {{ issue.message }}
|
|
1274
|
-
{% endfor %}
|
|
1275
|
-
{% endif %}
|
|
1276
|
-
|
|
1277
|
-
{% if outputs.performance %}
|
|
1278
|
-
- **Performance**: {{ outputs.performance.totalIssues }} issues found
|
|
1279
|
-
{% endif %}
|
|
1280
|
-
|
|
1281
|
-
## New Focus Areas
|
|
1282
|
-
Based on file changes in this PR:
|
|
1283
|
-
{% for ext, files in utils.filesByExtension %}
|
|
1284
|
-
- {{ ext | upcase }} files: {{ files.size }}
|
|
1285
|
-
{% endfor %}
|
|
1286
|
-
|
|
1287
|
-
Please provide an architectural review focusing on:
|
|
1288
|
-
1. Integration between modified components
|
|
1289
|
-
2. Impact on existing security measures
|
|
1290
|
-
3. Performance implications of changes
|
|
1291
|
-
4. Maintainability and technical debt
|
|
1292
|
-
on: [pr_opened, pr_updated]
|
|
1293
|
-
```
|
|
1294
|
-
|
|
1295
|
-
## 🔧 Advanced Configuration
|
|
1296
|
-
|
|
1297
|
-
### Check-Level AI Configuration
|
|
1298
|
-
|
|
1299
|
-
Override global AI settings for specific checks:
|
|
1300
|
-
|
|
1301
|
-
```yaml
|
|
1302
|
-
# Global AI settings (optional)
|
|
1303
|
-
ai_model: gpt-3.5-turbo
|
|
1304
|
-
ai_provider: openai
|
|
1305
|
-
|
|
1306
|
-
checks:
|
|
1307
|
-
security-advanced:
|
|
1308
|
-
type: ai
|
|
1309
|
-
prompt: "Perform advanced security analysis..."
|
|
1310
|
-
# Override global settings for this check
|
|
1311
|
-
ai_model: claude-3-opus
|
|
1312
|
-
ai_provider: anthropic
|
|
1313
|
-
on: [pr_opened]
|
|
1314
|
-
|
|
1315
|
-
performance-quick:
|
|
1316
|
-
type: ai
|
|
1317
|
-
prompt: "Quick performance check..."
|
|
1318
|
-
# Use different model for performance checks
|
|
1319
|
-
ai_model: gpt-4-turbo
|
|
1320
|
-
# ai_provider will inherit global setting (openai)
|
|
1321
|
-
on: [pr_updated]
|
|
1322
|
-
|
|
1323
|
-
quality-standard:
|
|
1324
|
-
type: ai
|
|
1325
|
-
prompt: "Standard quality review..."
|
|
1326
|
-
# No overrides - uses global settings
|
|
1327
|
-
on: [pr_opened]
|
|
1328
|
-
```
|
|
1329
|
-
|
|
1330
|
-
### Environment Variable Configuration
|
|
1331
|
-
|
|
1332
|
-
Use environment variables with GitHub Actions-like syntax:
|
|
1333
|
-
|
|
1334
|
-
```yaml
|
|
1335
|
-
# Global environment variables
|
|
1336
|
-
env:
|
|
1337
|
-
DEFAULT_TIMEOUT: "30000"
|
|
1338
|
-
LOG_LEVEL: "info"
|
|
1339
|
-
SHARED_SECRET: "${{ env.GITHUB_TOKEN }}"
|
|
1340
|
-
|
|
1341
|
-
checks:
|
|
1342
|
-
security-with-env:
|
|
1343
|
-
type: ai
|
|
1344
|
-
prompt: |
|
|
1345
|
-
Security analysis using timeout: ${{ env.SECURITY_TIMEOUT }}ms
|
|
1346
|
-
API endpoint: ${{ env.SECURITY_API_ENDPOINT }}
|
|
1347
|
-
|
|
1348
|
-
Analyze these files for security issues...
|
|
1349
|
-
# Check-specific environment variables
|
|
1350
|
-
env:
|
|
1351
|
-
SECURITY_API_KEY: "${{ env.ANTHROPIC_API_KEY }}"
|
|
1352
|
-
SECURITY_TIMEOUT: "${DEFAULT_TIMEOUT}" # Reference global env
|
|
1353
|
-
ANALYSIS_MODE: "comprehensive"
|
|
1354
|
-
CUSTOM_RULES: "security,auth,crypto"
|
|
1355
|
-
# Use environment variable for AI model
|
|
1356
|
-
ai_model: "${{ env.SECURITY_MODEL }}"
|
|
1357
|
-
ai_provider: "${{ env.PREFERRED_AI_PROVIDER }}"
|
|
1358
|
-
on: [pr_opened, pr_updated]
|
|
1359
|
-
```
|
|
1360
|
-
|
|
1361
|
-
#### Environment Variable Syntax
|
|
1362
|
-
|
|
1363
|
-
Visor supports multiple environment variable syntaxes:
|
|
1364
|
-
|
|
1365
|
-
```yaml
|
|
1366
|
-
env:
|
|
1367
|
-
# GitHub Actions style (recommended)
|
|
1368
|
-
API_KEY: "${{ env.OPENAI_API_KEY }}"
|
|
1369
|
-
|
|
1370
|
-
# Shell style
|
|
1371
|
-
MODEL_NAME: "${CUSTOM_MODEL}"
|
|
1372
|
-
|
|
1373
|
-
# Simple shell style
|
|
1374
|
-
PROVIDER: "$AI_PROVIDER"
|
|
1375
|
-
|
|
1376
|
-
# Mixed usage
|
|
1377
|
-
ENDPOINT: "https://${{ env.API_HOST }}/v1/${API_VERSION}"
|
|
1378
|
-
|
|
1379
|
-
# Static values
|
|
1380
|
-
TIMEOUT: 45000
|
|
1381
|
-
DEBUG_MODE: true
|
|
1382
|
-
FEATURES: "security,performance"
|
|
1383
|
-
```
|
|
1384
|
-
|
|
1385
|
-
### Configuration Inheritance with Extends
|
|
1386
|
-
|
|
1387
|
-
Visor supports configuration inheritance through the `extends` directive, allowing you to build upon existing configurations. This is useful for:
|
|
1388
|
-
- Sharing common configurations across projects
|
|
1389
|
-
- Building team/organization standards
|
|
1390
|
-
- Creating environment-specific configs (dev, staging, prod)
|
|
1391
|
-
|
|
1392
|
-
#### Using the Extends Directive
|
|
1393
|
-
|
|
1394
|
-
The `extends` field can reference:
|
|
1395
|
-
- **Local files**: Relative or absolute paths to YAML files
|
|
1396
|
-
- **Remote URLs**: HTTPS URLs to configuration files (requires allowlist for security)
|
|
1397
|
-
- **Default**: Built-in default configuration (`extends: default`)
|
|
1398
|
-
|
|
1399
|
-
```yaml
|
|
1400
|
-
# .visor.yaml - Your project config
|
|
1401
|
-
extends: ./base-config.yaml # Single extend
|
|
1402
|
-
# OR multiple extends (merged left-to-right)
|
|
1403
|
-
extends:
|
|
1404
|
-
- default # Start with defaults
|
|
1405
|
-
- ./team-standards.yaml # Apply team standards
|
|
1406
|
-
- ./project-specific.yaml # Project overrides
|
|
1407
|
-
|
|
1408
|
-
checks:
|
|
1409
|
-
my-custom-check:
|
|
1410
|
-
type: ai
|
|
1411
|
-
prompt: "Project-specific analysis..."
|
|
1412
|
-
```
|
|
1413
|
-
|
|
1414
|
-
#### Example: Team Configuration
|
|
1415
|
-
|
|
1416
|
-
**team-config.yaml** (shared team configuration):
|
|
1417
|
-
```yaml
|
|
1418
|
-
version: "1.0"
|
|
1419
|
-
ai_provider: openai
|
|
1420
|
-
ai_model: gpt-4
|
|
1421
|
-
|
|
1422
|
-
checks:
|
|
1423
|
-
security-scan:
|
|
1424
|
-
type: ai
|
|
1425
|
-
prompt: "Perform security analysis following OWASP guidelines"
|
|
1426
|
-
on: [pr_opened, pr_updated]
|
|
1427
|
-
|
|
1428
|
-
code-quality:
|
|
1429
|
-
type: ai
|
|
1430
|
-
prompt: "Check code quality and best practices"
|
|
1431
|
-
on: [pr_opened, pr_updated]
|
|
1432
|
-
```
|
|
1433
|
-
|
|
1434
|
-
**project-config.yaml** (project extends team config):
|
|
1435
|
-
```yaml
|
|
1436
|
-
extends: ./team-config.yaml
|
|
1437
|
-
|
|
1438
|
-
# Override team defaults
|
|
1439
|
-
ai_model: gpt-4-turbo # Use newer model
|
|
1440
|
-
|
|
1441
|
-
checks:
|
|
1442
|
-
# Disable code-quality by setting empty 'on' array
|
|
1443
|
-
code-quality:
|
|
1444
|
-
on: []
|
|
1445
|
-
|
|
1446
|
-
# Add project-specific check
|
|
1447
|
-
performance-check:
|
|
1448
|
-
type: ai
|
|
1449
|
-
prompt: "Analyze performance implications"
|
|
1450
|
-
on: [pr_opened]
|
|
1451
|
-
```
|
|
1452
|
-
|
|
1453
|
-
#### Remote Configuration (with Security)
|
|
1454
|
-
|
|
1455
|
-
For security, remote URLs must be explicitly allowed via CLI:
|
|
1456
|
-
|
|
1457
|
-
```bash
|
|
1458
|
-
# Allow specific URL prefixes
|
|
1459
|
-
visor --check all \
|
|
1460
|
-
--allowed-remote-patterns "https://github.com/myorg/,https://raw.githubusercontent.com/myorg/"
|
|
1461
|
-
```
|
|
1462
|
-
|
|
1463
|
-
Then use in your config:
|
|
1464
|
-
```yaml
|
|
1465
|
-
extends: https://raw.githubusercontent.com/myorg/configs/main/base.yaml
|
|
1466
|
-
|
|
1467
|
-
checks:
|
|
1468
|
-
# Your project-specific checks...
|
|
1469
|
-
```
|
|
1470
|
-
|
|
1471
|
-
#### Security Features
|
|
1472
|
-
|
|
1473
|
-
1. **Path Traversal Protection**: Local file paths are restricted to the project root
|
|
1474
|
-
2. **URL Allowlist**: Remote URLs must match allowed patterns (empty by default)
|
|
1475
|
-
3. **No Remote by Default**: Use `--no-remote-extends` to completely disable remote configs
|
|
1476
|
-
|
|
1477
|
-
#### Merge Behavior
|
|
1478
|
-
|
|
1479
|
-
When extending configurations:
|
|
1480
|
-
- **Simple values**: Child overrides parent
|
|
1481
|
-
- **Objects**: Deep merge (child properties override parent)
|
|
1482
|
-
- **Arrays**: Replaced entirely (not concatenated)
|
|
1483
|
-
- **Checks**: Can be disabled by setting `on: []`
|
|
1484
|
-
|
|
1485
|
-
#### Appending to Prompts with `appendPrompt`
|
|
1486
|
-
|
|
1487
|
-
When extending configurations, you can append additional instructions to existing prompts using the `appendPrompt` field. This is useful for adding project-specific requirements without completely replacing the base prompt.
|
|
1488
|
-
|
|
1489
|
-
**base-config.yaml**:
|
|
1490
|
-
```yaml
|
|
1491
|
-
checks:
|
|
1492
|
-
security-review:
|
|
1493
|
-
type: ai
|
|
1494
|
-
prompt: "Perform basic security analysis"
|
|
1495
|
-
on: [pr_opened]
|
|
1496
|
-
```
|
|
1497
|
-
|
|
1498
|
-
**project-config.yaml**:
|
|
1499
|
-
```yaml
|
|
1500
|
-
extends: ./base-config.yaml
|
|
1501
|
-
|
|
1502
|
-
checks:
|
|
1503
|
-
security-review:
|
|
1504
|
-
# Appends to the parent prompt instead of replacing it
|
|
1505
|
-
appendPrompt: "Also check for SQL injection vulnerabilities and hardcoded secrets"
|
|
1506
|
-
# Result: "Perform basic security analysis\n\nAlso check for SQL injection vulnerabilities and hardcoded secrets"
|
|
1507
|
-
```
|
|
1508
|
-
|
|
1509
|
-
Notes:
|
|
1510
|
-
- `appendPrompt` is combined with parent `prompt` using a double newline separator
|
|
1511
|
-
- If no parent prompt exists, `appendPrompt` becomes the prompt
|
|
1512
|
-
- Use `prompt` field to completely replace the parent prompt instead of appending
|
|
1513
|
-
|
|
1514
|
-
### Configuration Priority Order
|
|
1515
|
-
|
|
1516
|
-
With extends, the full priority order becomes:
|
|
1517
|
-
|
|
1518
|
-
1. **Check-level settings** (highest priority)
|
|
1519
|
-
2. **Current file configuration**
|
|
1520
|
-
3. **Extended configurations** (merged in order)
|
|
1521
|
-
4. **Global configuration**
|
|
1522
|
-
5. **Environment variables**
|
|
1523
|
-
6. **Default values** (lowest priority)
|
|
1524
|
-
|
|
1525
|
-
```yaml
|
|
1526
|
-
# Global defaults
|
|
1527
|
-
ai_model: gpt-3.5-turbo
|
|
1528
|
-
ai_provider: openai
|
|
1529
|
-
env:
|
|
1530
|
-
GLOBAL_TIMEOUT: "30000"
|
|
1531
|
-
|
|
1532
|
-
checks:
|
|
1533
|
-
example-check:
|
|
1534
|
-
type: ai
|
|
1535
|
-
prompt: "Example analysis"
|
|
1536
|
-
# These override global settings
|
|
1537
|
-
ai_model: claude-3-opus # Overrides global ai_model
|
|
1538
|
-
# ai_provider: inherits openai from global
|
|
1539
|
-
|
|
1540
|
-
env:
|
|
1541
|
-
# Inherits GLOBAL_TIMEOUT from global env
|
|
1542
|
-
CHECK_TIMEOUT: "45000" # Check-specific setting
|
|
1543
|
-
API_KEY: "${{ env.ANTHROPIC_API_KEY }}" # From process env
|
|
1544
|
-
```
|
|
1545
|
-
|
|
1546
|
-
### Production Environment Setup
|
|
1547
|
-
|
|
1548
|
-
For production deployments, set up environment variables:
|
|
1549
|
-
|
|
1550
|
-
```bash
|
|
1551
|
-
# AI Provider API Keys
|
|
1552
|
-
export OPENAI_API_KEY="sk-your-openai-key"
|
|
1553
|
-
export ANTHROPIC_API_KEY="sk-ant-your-anthropic-key"
|
|
1554
|
-
export GOOGLE_API_KEY="your-google-api-key"
|
|
1555
|
-
|
|
1556
|
-
# GitHub Integration
|
|
1557
|
-
export GITHUB_TOKEN="ghp_your-github-token"
|
|
1558
|
-
|
|
1559
|
-
# Custom Configuration
|
|
1560
|
-
export SECURITY_MODEL="claude-3-opus"
|
|
1561
|
-
export PERFORMANCE_MODEL="gpt-4-turbo"
|
|
1562
|
-
export PREFERRED_AI_PROVIDER="anthropic"
|
|
1563
|
-
export ANALYSIS_TIMEOUT="60000"
|
|
1564
|
-
```
|
|
1565
|
-
|
|
1566
|
-
Then reference them in your configuration:
|
|
1567
|
-
|
|
1568
|
-
```yaml
|
|
1569
|
-
env:
|
|
1570
|
-
# Production environment references
|
|
1571
|
-
OPENAI_KEY: "${{ env.OPENAI_API_KEY }}"
|
|
1572
|
-
ANTHROPIC_KEY: "${{ env.ANTHROPIC_API_KEY }}"
|
|
1573
|
-
GITHUB_ACCESS_TOKEN: "${{ env.GITHUB_TOKEN }}"
|
|
1574
|
-
|
|
1575
|
-
checks:
|
|
1576
|
-
production-security:
|
|
1577
|
-
type: ai
|
|
1578
|
-
ai_model: "${{ env.SECURITY_MODEL }}"
|
|
1579
|
-
ai_provider: "${{ env.PREFERRED_AI_PROVIDER }}"
|
|
1580
|
-
env:
|
|
1581
|
-
API_KEY: "${{ env.ANTHROPIC_KEY }}"
|
|
1582
|
-
TIMEOUT: "${{ env.ANALYSIS_TIMEOUT }}"
|
|
1583
|
-
prompt: |
|
|
1584
|
-
Production security analysis with ${{ env.ANALYSIS_TIMEOUT }}ms timeout
|
|
1585
|
-
Using provider: ${{ env.PREFERRED_AI_PROVIDER }}
|
|
1586
|
-
Model: ${{ env.SECURITY_MODEL }}
|
|
1587
|
-
|
|
1588
|
-
Perform comprehensive security analysis...
|
|
1589
|
-
```
|
|
1590
|
-
|
|
1591
|
-
### Built-in Schemas
|
|
1592
|
-
|
|
1593
|
-
#### Code Review Schema (`code-review`)
|
|
1594
|
-
Structured format for code analysis results:
|
|
1595
|
-
```json
|
|
1596
|
-
{
|
|
1597
|
-
"issues": [
|
|
1598
|
-
{
|
|
1599
|
-
"file": "src/auth.ts",
|
|
1600
|
-
"line": 15,
|
|
1601
|
-
"ruleId": "security/hardcoded-secret",
|
|
1602
|
-
"message": "Hardcoded API key detected",
|
|
1603
|
-
"severity": "critical",
|
|
1604
|
-
"category": "security",
|
|
1605
|
-
"suggestion": "Use environment variables"
|
|
1606
|
-
}
|
|
1607
|
-
]
|
|
1608
|
-
}
|
|
1609
|
-
```
|
|
1610
|
-
|
|
1611
|
-
#### Text Schema (`text`)
|
|
1612
|
-
Free-form text/markdown content:
|
|
1613
|
-
```json
|
|
1614
|
-
{
|
|
1615
|
-
"content": "# PR Overview\n\nThis PR adds authentication features..."
|
|
1616
|
-
}
|
|
1617
|
-
```
|
|
1618
|
-
|
|
1619
|
-
### Output Templates
|
|
1620
|
-
|
|
1621
|
-
#### Code Review Template
|
|
1622
|
-
Renders structured data as HTML tables with:
|
|
1623
|
-
- Grouping by check name
|
|
1624
|
-
- Severity indicators with emojis (🔴 🟠 🟡 🟢)
|
|
1625
|
-
- Collapsible suggestion details
|
|
1626
|
-
- File and line information
|
|
1627
|
-
|
|
1628
|
-
#### Text Template
|
|
1629
|
-
Renders text/markdown content as-is for:
|
|
1630
|
-
- PR overviews and summaries
|
|
1631
|
-
- Architecture diagrams
|
|
1632
|
-
- Custom formatted content
|
|
1633
|
-
|
|
1634
|
-
### Comment Grouping
|
|
1635
|
-
|
|
1636
|
-
The `group` property controls GitHub comment generation:
|
|
1637
|
-
|
|
1638
|
-
```yaml
|
|
1639
|
-
checks:
|
|
1640
|
-
security:
|
|
1641
|
-
group: code-review # \
|
|
1642
|
-
performance: # } All grouped in one comment
|
|
1643
|
-
group: code-review # /
|
|
1644
|
-
|
|
1645
|
-
overview:
|
|
1646
|
-
group: summary # Separate comment
|
|
1647
|
-
|
|
1648
|
-
issue-assistant:
|
|
1649
|
-
group: dynamic # Special group: creates NEW comment each time (never updates)
|
|
1650
|
-
```
|
|
1651
|
-
|
|
1652
|
-
**Special "dynamic" group**: When a check uses `group: dynamic`, it creates a new comment for each execution instead of updating an existing comment. This is perfect for:
|
|
1653
|
-
- Issue assistants that respond to user questions
|
|
1654
|
-
- Release notes generation
|
|
1655
|
-
- Changelog updates
|
|
1656
|
-
- Any check where you want to preserve the history of responses
|
|
1657
|
-
|
|
1658
|
-
### Custom Schemas and Templates
|
|
1659
|
-
|
|
1660
|
-
Add custom schemas in your config:
|
|
1661
|
-
|
|
1662
|
-
```yaml
|
|
1663
|
-
schemas:
|
|
1664
|
-
custom-metrics:
|
|
1665
|
-
file: ./schemas/metrics.json # Local file
|
|
1666
|
-
compliance:
|
|
1667
|
-
url: https://example.com/compliance.json # Remote URL
|
|
1668
|
-
|
|
1669
|
-
checks:
|
|
1670
|
-
metrics:
|
|
1671
|
-
schema: custom-metrics # References custom schema
|
|
1672
|
-
group: metrics # Separate comment group
|
|
1673
|
-
```
|
|
1674
|
-
|
|
1675
|
-
### Key Features Implemented
|
|
1676
|
-
|
|
1677
|
-
- ✅ **Check-Based Organization**: Issues grouped by check name, not artificial categories
|
|
1678
|
-
- ✅ **Group-Based Comments**: Multiple GitHub comments based on `group` property
|
|
1679
|
-
- ✅ **JSON Schema Validation**: Runtime validation with AJV library
|
|
1680
|
-
- ✅ **Liquid Templates**: Dynamic rendering with conditional logic
|
|
1681
|
-
- ✅ **Multiple Output Formats**: Structured tables vs free-form markdown
|
|
1682
|
-
- ✅ **Backwards Compatibility**: Existing configurations continue to work
|
|
1683
|
-
- ✅ **No False Categories**: Eliminates "logic" issues when no logic checks configured
|
|
1684
|
-
- ✅ **Type Safety**: Structured data validation prevents malformed output
|
|
1685
|
-
- ✅ **Extensible Design**: Easy to add custom schemas and templates
|
|
1686
|
-
|
|
1687
|
-
### Schema and Template Properties
|
|
1688
|
-
|
|
1689
|
-
The schema-template system introduces two new configuration properties:
|
|
1690
|
-
|
|
1691
|
-
#### Group Property
|
|
1692
|
-
Controls GitHub comment organization:
|
|
1693
|
-
```yaml
|
|
1694
|
-
checks:
|
|
1695
|
-
security:
|
|
1696
|
-
group: code-review # Groups with other code-review checks
|
|
1697
|
-
performance:
|
|
1698
|
-
group: code-review # Same group = combined in one comment
|
|
1699
|
-
overview:
|
|
1700
|
-
group: pr-summary # Different group = separate comment
|
|
1701
|
-
changelog:
|
|
1702
|
-
group: dynamic # Special: creates NEW comment each time
|
|
1703
|
-
```
|
|
1704
|
-
|
|
1705
|
-
The special `group: dynamic` creates a new comment for each execution instead of updating existing comments. Use this for checks where you want to preserve history (issue assistants, release notes, etc.)
|
|
1706
|
-
|
|
1707
|
-
#### Schema Property
|
|
1708
|
-
Enforces structured output format:
|
|
1709
|
-
```yaml
|
|
1710
|
-
checks:
|
|
1711
|
-
security:
|
|
1712
|
-
schema: code-review # Structured table format
|
|
1713
|
-
prompt: "Return JSON matching code-review schema"
|
|
1714
|
-
overview:
|
|
1715
|
-
schema: text # Free-form markdown
|
|
1716
|
-
prompt: "Return markdown content"
|
|
1717
|
-
```
|
|
1718
|
-
|
|
1719
|
-
#### Benefits
|
|
1720
|
-
- **Check-Based Organization**: Only configured checks appear in results
|
|
1721
|
-
- **Multiple Comments**: Separate GitHub comments based on `group` property
|
|
1722
|
-
- **Structured Output**: JSON Schema validation ensures consistent data
|
|
1723
|
-
- **Flexible Rendering**: Different templates for different output types
|
|
1724
|
-
|
|
1725
|
-
### GitHub Integration Schema Requirements
|
|
1726
|
-
|
|
1727
|
-
Visor is **fully schema-agnostic** - checks can return any structure and templates handle all formatting logic. However, for GitHub Checks API integration (status checks, outputs), specific structure may be required:
|
|
1728
|
-
|
|
1729
|
-
#### Unstructured Checks (No Schema / Plain Schema)
|
|
1730
|
-
```yaml
|
|
1731
|
-
# ✅ No-schema and plain schema behave identically
|
|
1732
|
-
overview:
|
|
1733
|
-
type: ai
|
|
1734
|
-
# No schema - returns raw markdown directly to PR comments
|
|
1735
|
-
prompt: "Analyze this PR and provide an overview"
|
|
1736
|
-
|
|
1737
|
-
documentation:
|
|
1738
|
-
type: ai
|
|
1739
|
-
schema: plain # Equivalent to no schema
|
|
1740
|
-
prompt: "Generate documentation for these changes"
|
|
1741
|
-
```
|
|
1742
|
-
|
|
1743
|
-
**Behavior**: AI returns raw text/markdown → Posted as-is to PR comments → GitHub integration reports 0 issues
|
|
1744
|
-
|
|
1745
|
-
#### Structured Checks (GitHub Checks API Compatible)
|
|
1746
|
-
```yaml
|
|
1747
|
-
security:
|
|
1748
|
-
type: ai
|
|
1749
|
-
schema: code-review # Built-in schema, works out of the box
|
|
1750
|
-
prompt: "Review for security issues and return findings as JSON"
|
|
1751
|
-
|
|
1752
|
-
# Custom schema example
|
|
1753
|
-
custom-check:
|
|
1754
|
-
type: ai
|
|
1755
|
-
schema: |
|
|
1756
|
-
{
|
|
1757
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
1758
|
-
"type": "object",
|
|
1759
|
-
"required": ["issues"],
|
|
1760
|
-
"properties": {
|
|
1761
|
-
"issues": {
|
|
1762
|
-
"type": "array",
|
|
1763
|
-
"items": {
|
|
1764
|
-
"type": "object",
|
|
1765
|
-
"required": ["file", "line", "message", "severity"],
|
|
1766
|
-
"properties": {
|
|
1767
|
-
"file": { "type": "string" },
|
|
1768
|
-
"line": { "type": "integer" },
|
|
1769
|
-
"ruleId": { "type": "string" },
|
|
1770
|
-
"message": { "type": "string" },
|
|
1771
|
-
"severity": { "enum": ["critical", "error", "warning", "info"] },
|
|
1772
|
-
"category": { "type": "string" }
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
prompt: "Review the code and return JSON matching the schema"
|
|
1779
|
-
```
|
|
1780
|
-
|
|
1781
|
-
**Required Structure for GitHub Checks API Integration**:
|
|
1782
|
-
- `issues`: Array of issue objects (required for GitHub status checks)
|
|
1783
|
-
- `issues[].severity`: Must be `"critical"`, `"error"`, `"warning"`, or `"info"`
|
|
1784
|
-
- `issues[].file`: File path (required for GitHub annotations)
|
|
1785
|
-
- `issues[].line`: Line number (required for GitHub annotations)
|
|
1786
|
-
- `issues[].message`: Issue description (required for GitHub annotations)
|
|
1787
|
-
|
|
1788
|
-
#### GitHub Checks API Features
|
|
1789
|
-
When checks return the structured format above:
|
|
1790
|
-
- ✅ **GitHub Status Checks**: Pass/fail based on severity thresholds
|
|
1791
|
-
- ✅ **GitHub Annotations**: Issues appear as file annotations in PR
|
|
1792
|
-
- ✅ **Action Outputs**: `issues-found`, `critical-issues-found` outputs
|
|
1793
|
-
- ✅ **PR Comments**: Structured table format with issue details
|
|
1794
|
-
|
|
1795
|
-
#### Schema Behavior Summary
|
|
1796
|
-
| Schema Type | AI Output | Comment Rendering | GitHub Checks API |
|
|
1797
|
-
|-------------|-----------|-------------------|-------------------|
|
|
1798
|
-
| **None/Plain** | Raw text/markdown | ✅ Posted as-is | ❌ No status checks, 0 issues |
|
|
1799
|
-
| **Structured** | JSON with `issues[]` | ✅ Table format | ✅ Full GitHub integration |
|
|
1800
|
-
|
|
1801
|
-
**Key Design**: Use unstructured (none/plain) for narrative content like overviews and documentation. Use structured schemas for actionable code review findings that integrate with GitHub's checking system.
|
|
1802
|
-
|
|
1803
|
-
## 🧠 Advanced AI Features
|
|
1804
|
-
|
|
1805
|
-
### XML-Formatted Analysis
|
|
1806
|
-
Visor uses structured XML formatting when sending data to AI providers, enabling precise and context-aware analysis for both pull requests and issues.
|
|
1807
|
-
|
|
1808
|
-
#### Pull Request Context
|
|
1809
|
-
For PR events, Visor provides comprehensive code review context:
|
|
1810
|
-
|
|
1811
|
-
```xml
|
|
1812
|
-
<pull_request>
|
|
1813
|
-
<metadata>
|
|
1814
|
-
<number>123</number> <!-- PR number -->
|
|
1815
|
-
<title>Add user authentication</title> <!-- PR title -->
|
|
1816
|
-
<author>developer</author> <!-- PR author username -->
|
|
1817
|
-
<base_branch>main</base_branch> <!-- Target branch (where changes will be merged) -->
|
|
1818
|
-
<target_branch>feature-auth</target_branch> <!-- Source branch (contains the changes) -->
|
|
1819
|
-
<total_additions>250</total_additions> <!-- Total lines added across all files -->
|
|
1820
|
-
<total_deletions>50</total_deletions> <!-- Total lines removed across all files -->
|
|
1821
|
-
<files_changed_count>3</files_changed_count> <!-- Number of files modified -->
|
|
1822
|
-
</metadata>
|
|
1823
|
-
|
|
1824
|
-
<description>
|
|
1825
|
-
<!-- PR description/body text provided by the author -->
|
|
1826
|
-
This PR implements JWT-based authentication with refresh token support
|
|
1827
|
-
</description>
|
|
1828
|
-
|
|
1829
|
-
<full_diff>
|
|
1830
|
-
<!-- Complete unified diff of all changes (present for all PR analyses) -->
|
|
1831
|
-
--- src/auth.ts
|
|
1832
|
-
+++ src/auth.ts
|
|
1833
|
-
@@ -1,3 +1,10 @@
|
|
1834
|
-
+import jwt from 'jsonwebtoken';
|
|
1835
|
-
...
|
|
1836
|
-
</full_diff>
|
|
1837
|
-
|
|
1838
|
-
<commit_diff>
|
|
1839
|
-
<!-- Only present for incremental analysis (pr_updated events) -->
|
|
1840
|
-
<!-- Contains diff of just the latest commit pushed -->
|
|
1841
|
-
</commit_diff>
|
|
1842
|
-
|
|
1843
|
-
<files_summary>
|
|
1844
|
-
<!-- List of all modified files with change statistics -->
|
|
1845
|
-
<file index="1">
|
|
1846
|
-
<filename>src/auth.ts</filename>
|
|
1847
|
-
<status>modified</status> <!-- added/modified/removed/renamed -->
|
|
1848
|
-
<additions>120</additions> <!-- Lines added in this file -->
|
|
1849
|
-
<deletions>10</deletions> <!-- Lines removed from this file -->
|
|
1850
|
-
</file>
|
|
1851
|
-
</files_summary>
|
|
1852
|
-
|
|
1853
|
-
<!-- Only present for issue_comment events on PRs -->
|
|
1854
|
-
<triggering_comment>
|
|
1855
|
-
<author>reviewer1</author>
|
|
1856
|
-
<created_at>2024-01-16T15:30:00Z</created_at>
|
|
1857
|
-
<body>/review --check security</body>
|
|
1858
|
-
</triggering_comment>
|
|
1859
|
-
|
|
1860
|
-
<!-- Historical comments on the PR (excludes triggering comment) -->
|
|
1861
|
-
<comment_history>
|
|
1862
|
-
<comment index="1">
|
|
1863
|
-
<author>reviewer2</author>
|
|
1864
|
-
<created_at>2024-01-15T11:00:00Z</created_at>
|
|
1865
|
-
<body>Please add unit tests for the authentication logic</body>
|
|
1866
|
-
</comment>
|
|
1867
|
-
<comment index="2">
|
|
1868
|
-
<author>developer</author>
|
|
1869
|
-
<created_at>2024-01-15T14:30:00Z</created_at>
|
|
1870
|
-
<body>Tests added in latest commit</body>
|
|
1871
|
-
</comment>
|
|
1872
|
-
</comment_history>
|
|
1873
|
-
</pull_request>
|
|
1874
|
-
```
|
|
1875
|
-
|
|
1876
|
-
#### Issue Context
|
|
1877
|
-
For issue events, Visor provides issue-specific context for intelligent assistance:
|
|
1878
|
-
|
|
1879
|
-
```xml
|
|
1880
|
-
<issue>
|
|
1881
|
-
<metadata>
|
|
1882
|
-
<number>456</number> <!-- Issue number -->
|
|
1883
|
-
<title>Feature request: Add dark mode</title> <!-- Issue title -->
|
|
1884
|
-
<author>user123</author> <!-- Issue author username -->
|
|
1885
|
-
<state>open</state> <!-- Issue state: open/closed -->
|
|
1886
|
-
<created_at>2024-01-15T10:30:00Z</created_at> <!-- When issue was created -->
|
|
1887
|
-
<updated_at>2024-01-16T14:20:00Z</updated_at> <!-- Last update timestamp -->
|
|
1888
|
-
<comments_count>5</comments_count> <!-- Total number of comments -->
|
|
1889
|
-
</metadata>
|
|
1890
|
-
|
|
1891
|
-
<description>
|
|
1892
|
-
<!-- Issue body/description text provided by the author -->
|
|
1893
|
-
I would like to request a dark mode feature for better accessibility...
|
|
1894
|
-
</description>
|
|
1895
|
-
|
|
1896
|
-
<labels>
|
|
1897
|
-
<!-- GitHub labels applied to categorize the issue -->
|
|
1898
|
-
<label>enhancement</label>
|
|
1899
|
-
<label>good first issue</label>
|
|
1900
|
-
<label>ui/ux</label>
|
|
1901
|
-
</labels>
|
|
1902
|
-
|
|
1903
|
-
<assignees>
|
|
1904
|
-
<!-- Users assigned to work on this issue -->
|
|
1905
|
-
<assignee>developer1</assignee>
|
|
1906
|
-
<assignee>developer2</assignee>
|
|
1907
|
-
</assignees>
|
|
1908
|
-
|
|
1909
|
-
<milestone>
|
|
1910
|
-
<!-- Project milestone this issue is part of (if any) -->
|
|
1911
|
-
<title>v2.0 Release</title>
|
|
1912
|
-
<state>open</state> <!-- Milestone state: open/closed -->
|
|
1913
|
-
<due_on>2024-03-01T00:00:00Z</due_on> <!-- Milestone due date -->
|
|
1914
|
-
</milestone>
|
|
1915
|
-
|
|
1916
|
-
<!-- Only present for issue_comment events -->
|
|
1917
|
-
<triggering_comment>
|
|
1918
|
-
<author>user456</author> <!-- User who posted the triggering comment -->
|
|
1919
|
-
<created_at>2024-01-16T15:30:00Z</created_at> <!-- When comment was posted -->
|
|
1920
|
-
<body>/review security --focus authentication</body> <!-- The comment text -->
|
|
1921
|
-
</triggering_comment>
|
|
1922
|
-
|
|
1923
|
-
<!-- Historical comments on the issue (excludes triggering comment) -->
|
|
1924
|
-
<comment_history>
|
|
1925
|
-
<comment index="1"> <!-- Comments ordered by creation time -->
|
|
1926
|
-
<author>developer1</author>
|
|
1927
|
-
<created_at>2024-01-15T11:00:00Z</created_at>
|
|
1928
|
-
<body>This is a great idea! I'll start working on it.</body>
|
|
1929
|
-
</comment>
|
|
1930
|
-
<comment index="2">
|
|
1931
|
-
<author>user123</author>
|
|
1932
|
-
<created_at>2024-01-15T14:30:00Z</created_at>
|
|
1933
|
-
<body>Thanks! Please consider accessibility standards.</body>
|
|
1934
|
-
</comment>
|
|
1935
|
-
</comment_history>
|
|
1936
|
-
</issue>
|
|
1937
|
-
```
|
|
1938
|
-
|
|
1939
|
-
### Incremental Commit Analysis
|
|
1940
|
-
When new commits are pushed to a PR, Visor performs incremental analysis:
|
|
1941
|
-
- **Full Analysis**: Reviews the entire PR on initial creation
|
|
1942
|
-
- **Incremental Analysis**: On new commits, focuses only on the latest changes
|
|
1943
|
-
- **Smart Updates**: Updates existing review comments instead of creating duplicates
|
|
1944
|
-
|
|
1945
|
-
### Intelligent Comment Management
|
|
1946
|
-
- **Unique Comment IDs**: Each PR gets a unique review comment that persists across updates
|
|
1947
|
-
- **Collision Detection**: Prevents conflicts when multiple reviews run simultaneously
|
|
1948
|
-
- **Context-Aware Updates**: Comments are updated with relevant context (PR opened, updated, synchronized)
|
|
1949
|
-
|
|
1950
|
-
## 🌐 HTTP Integration & Scheduling
|
|
1951
|
-
|
|
1952
|
-
Visor provides comprehensive HTTP integration capabilities including webhook reception, HTTP outputs, scheduled executions via cron, and TLS/HTTPS support.
|
|
1953
|
-
|
|
1954
|
-
### HTTP Server for Webhook Reception
|
|
1955
|
-
|
|
1956
|
-
Configure an HTTP/HTTPS server to receive webhooks and trigger checks:
|
|
1957
|
-
|
|
1958
|
-
```yaml
|
|
1959
|
-
version: "1.0"
|
|
1960
|
-
|
|
1961
|
-
http_server:
|
|
1962
|
-
enabled: true
|
|
1963
|
-
port: 8080
|
|
1964
|
-
host: "0.0.0.0"
|
|
1965
|
-
|
|
1966
|
-
# Optional TLS/HTTPS configuration
|
|
1967
|
-
tls:
|
|
1968
|
-
enabled: true
|
|
1969
|
-
cert: "${TLS_CERT}" # From environment variable
|
|
1970
|
-
key: "${TLS_KEY}"
|
|
1971
|
-
ca: "${TLS_CA}" # Optional CA certificate
|
|
1972
|
-
rejectUnauthorized: true
|
|
1973
|
-
|
|
1974
|
-
# Authentication
|
|
1975
|
-
auth:
|
|
1976
|
-
type: bearer_token
|
|
1977
|
-
secret: "${WEBHOOK_SECRET}"
|
|
1978
|
-
|
|
1979
|
-
# Webhook endpoints
|
|
1980
|
-
endpoints:
|
|
1981
|
-
- path: "/webhook/github"
|
|
1982
|
-
name: "github-events"
|
|
1983
|
-
- path: "/webhook/jenkins"
|
|
1984
|
-
name: "jenkins-builds"
|
|
1985
|
-
```
|
|
1986
|
-
|
|
1987
|
-
**Note**: The HTTP server is automatically disabled when running in GitHub Actions to avoid conflicts.
|
|
1988
|
-
|
|
1989
|
-
### Check Types for HTTP Integration
|
|
1990
|
-
|
|
1991
|
-
#### 1. HTTP Input (Webhook Receiver)
|
|
1992
|
-
Receive data from configured webhook endpoints:
|
|
1993
|
-
|
|
1994
|
-
```yaml
|
|
1995
|
-
checks:
|
|
1996
|
-
github-webhook:
|
|
1997
|
-
type: http_input
|
|
1998
|
-
endpoint: "/webhook/github"
|
|
1999
|
-
on: [webhook_received]
|
|
2000
|
-
transform: |
|
|
2001
|
-
{
|
|
2002
|
-
"event": "{{ webhook.action }}",
|
|
2003
|
-
"repository": "{{ webhook.repository.full_name }}"
|
|
2004
|
-
}
|
|
2005
|
-
```
|
|
2006
|
-
|
|
2007
|
-
#### 2. HTTP Output (Send Data)
|
|
2008
|
-
Send check results to external services:
|
|
2009
|
-
|
|
2010
|
-
```yaml
|
|
2011
|
-
checks:
|
|
2012
|
-
notify-external:
|
|
2013
|
-
type: http
|
|
2014
|
-
depends_on: [security-check]
|
|
2015
|
-
url: "https://api.example.com/notify"
|
|
2016
|
-
method: POST
|
|
2017
|
-
headers:
|
|
2018
|
-
Content-Type: "application/json"
|
|
2019
|
-
Authorization: "Bearer ${API_TOKEN}"
|
|
2020
|
-
body: |
|
|
2021
|
-
{
|
|
2022
|
-
"results": {{ outputs['security-check'] | json }},
|
|
2023
|
-
"timestamp": "{{ 'now' | date: '%Y-%m-%d %H:%M:%S' }}"
|
|
2024
|
-
}
|
|
2025
|
-
```
|
|
2026
|
-
|
|
2027
|
-
#### 3. HTTP Client (Fetch Data)
|
|
2028
|
-
Fetch data from external APIs:
|
|
2029
|
-
|
|
2030
|
-
```yaml
|
|
2031
|
-
checks:
|
|
2032
|
-
fetch-config:
|
|
2033
|
-
type: http_client
|
|
2034
|
-
url: "https://api.example.com/config"
|
|
2035
|
-
method: GET
|
|
2036
|
-
headers:
|
|
2037
|
-
Authorization: "Bearer ${API_TOKEN}"
|
|
2038
|
-
transform: |
|
|
2039
|
-
{
|
|
2040
|
-
"settings": {{ response.data | json }},
|
|
2041
|
-
"fetched_at": "{{ 'now' | date: '%Y-%m-%d' }}"
|
|
2042
|
-
}
|
|
2043
|
-
```
|
|
2044
|
-
|
|
2045
|
-
#### 4. Log Provider (Debugging & Monitoring)
|
|
2046
|
-
Output debugging information and monitor workflow execution:
|
|
2047
|
-
|
|
2048
|
-
```yaml
|
|
2049
|
-
checks:
|
|
2050
|
-
debug-start:
|
|
2051
|
-
type: log
|
|
2052
|
-
group: debugging
|
|
2053
|
-
level: info
|
|
2054
|
-
message: "🚀 Starting code review for PR #{{ pr.number }} by {{ pr.author }}"
|
|
2055
|
-
include_pr_context: true
|
|
2056
|
-
include_dependencies: false
|
|
2057
|
-
include_metadata: true
|
|
2058
|
-
|
|
2059
|
-
debug-dependencies:
|
|
2060
|
-
type: log
|
|
2061
|
-
group: debugging
|
|
2062
|
-
level: debug
|
|
2063
|
-
depends_on: [security-check]
|
|
2064
|
-
message: |
|
|
2065
|
-
📊 Dependency results summary:
|
|
2066
|
-
{% if dependencies %}
|
|
2067
|
-
- Security check found {{ dependencies['security-check'].issueCount }} issues
|
|
2068
|
-
{% else %}
|
|
2069
|
-
- No dependencies processed
|
|
2070
|
-
{% endif %}
|
|
2071
|
-
include_dependencies: true
|
|
2072
|
-
|
|
2073
|
-
performance-monitor:
|
|
2074
|
-
type: log
|
|
2075
|
-
group: monitoring
|
|
2076
|
-
level: warn
|
|
2077
|
-
message: "⚠️ Large PR detected: {{ pr.totalAdditions }} lines added"
|
|
2078
|
-
include_pr_context: true
|
|
2079
|
-
```
|
|
2080
|
-
|
|
2081
|
-
**Configuration Options:**
|
|
2082
|
-
- `message` - Log message (required, supports Liquid templates)
|
|
2083
|
-
- `level` - Log level: `debug`, `info`, `warn`, `error` (default: `info`)
|
|
2084
|
-
- `include_pr_context` - Include PR information (default: `true`)
|
|
2085
|
-
- `include_dependencies` - Include dependency results (default: `true`)
|
|
2086
|
-
- `include_metadata` - Include execution metadata (default: `true`)
|
|
2087
|
-
- `group` - Output group for organization
|
|
2088
|
-
|
|
2089
|
-
**Use Cases:**
|
|
2090
|
-
- Debug complex check workflows and execution order
|
|
2091
|
-
- Monitor check performance and resource usage
|
|
2092
|
-
- Create audit trails for review processes
|
|
2093
|
-
- Troubleshoot configuration issues
|
|
2094
|
-
- Track dependency execution flow
|
|
2095
|
-
|
|
2096
|
-
### Cron Scheduling
|
|
2097
|
-
|
|
2098
|
-
Schedule any check type to run at specific intervals:
|
|
2099
|
-
|
|
2100
|
-
```yaml
|
|
2101
|
-
checks:
|
|
2102
|
-
daily-security-scan:
|
|
2103
|
-
type: ai
|
|
2104
|
-
prompt: "Perform comprehensive security audit"
|
|
2105
|
-
schedule: "0 2 * * *" # Run at 2 AM daily
|
|
2106
|
-
|
|
2107
|
-
hourly-metrics:
|
|
2108
|
-
type: http_client
|
|
2109
|
-
url: "https://metrics.example.com/latest"
|
|
2110
|
-
schedule: "0 * * * *" # Every hour
|
|
2111
|
-
|
|
2112
|
-
weekly-report:
|
|
2113
|
-
type: ai
|
|
2114
|
-
prompt: "Generate weekly summary"
|
|
2115
|
-
schedule: "0 9 * * MON" # Every Monday at 9 AM
|
|
2116
|
-
```
|
|
2117
|
-
|
|
2118
|
-
**Cron Expression Format**:
|
|
2119
|
-
```
|
|
2120
|
-
┌────────────── minute (0-59)
|
|
2121
|
-
│ ┌──────────── hour (0-23)
|
|
2122
|
-
│ │ ┌────────── day of month (1-31)
|
|
2123
|
-
│ │ │ ┌──────── month (1-12)
|
|
2124
|
-
│ │ │ │ ┌────── day of week (0-6, Sunday=0)
|
|
2125
|
-
│ │ │ │ │
|
|
2126
|
-
* * * * *
|
|
2127
|
-
```
|
|
2128
|
-
|
|
2129
|
-
### TLS/HTTPS Configuration
|
|
2130
|
-
|
|
2131
|
-
Support for various TLS certificate configurations:
|
|
2132
|
-
|
|
2133
|
-
#### Environment Variables
|
|
2134
|
-
```yaml
|
|
2135
|
-
tls:
|
|
2136
|
-
enabled: true
|
|
2137
|
-
cert: "${TLS_CERT}" # Certificate from env var
|
|
2138
|
-
key: "${TLS_KEY}" # Private key from env var
|
|
2139
|
-
```
|
|
2140
|
-
|
|
2141
|
-
#### File Paths
|
|
2142
|
-
```yaml
|
|
2143
|
-
tls:
|
|
2144
|
-
enabled: true
|
|
2145
|
-
cert: "/etc/ssl/certs/server.crt"
|
|
2146
|
-
key: "/etc/ssl/private/server.key"
|
|
2147
|
-
ca: "/etc/ssl/certs/ca-bundle.crt"
|
|
2148
|
-
```
|
|
2149
|
-
|
|
2150
|
-
#### Let's Encrypt
|
|
2151
|
-
```yaml
|
|
2152
|
-
tls:
|
|
2153
|
-
enabled: true
|
|
2154
|
-
cert: "/etc/letsencrypt/live/example.com/fullchain.pem"
|
|
2155
|
-
key: "/etc/letsencrypt/live/example.com/privkey.pem"
|
|
2156
|
-
```
|
|
2157
|
-
|
|
2158
|
-
### HTTP Security Features
|
|
2159
|
-
|
|
2160
|
-
Visor's HTTP server includes comprehensive security protections:
|
|
2161
|
-
|
|
2162
|
-
#### Authentication Methods
|
|
2163
|
-
```yaml
|
|
2164
|
-
# Bearer Token Authentication
|
|
2165
|
-
auth:
|
|
2166
|
-
type: bearer_token
|
|
2167
|
-
secret: "${WEBHOOK_SECRET}"
|
|
2168
|
-
|
|
2169
|
-
# HMAC-SHA256 Signature Verification
|
|
2170
|
-
auth:
|
|
2171
|
-
type: hmac
|
|
2172
|
-
secret: "${WEBHOOK_SECRET}"
|
|
2173
|
-
|
|
2174
|
-
# Basic Authentication
|
|
2175
|
-
auth:
|
|
2176
|
-
type: basic
|
|
2177
|
-
username: "${HTTP_USERNAME}"
|
|
2178
|
-
password: "${HTTP_PASSWORD}"
|
|
2179
|
-
```
|
|
2180
|
-
|
|
2181
|
-
#### HMAC Authentication Details
|
|
2182
|
-
For `hmac` authentication, webhooks must include the `x-webhook-signature` header:
|
|
2183
|
-
- Signature format: `sha256={hash}`
|
|
2184
|
-
- Uses HMAC-SHA256 with the configured secret
|
|
2185
|
-
- Implements timing-safe comparison to prevent timing attacks
|
|
2186
|
-
- Compatible with GitHub webhook signatures
|
|
2187
|
-
|
|
2188
|
-
#### DoS Protection
|
|
2189
|
-
- **Request size limits**: Maximum 1MB request body size
|
|
2190
|
-
- **Early rejection**: Validates `Content-Length` header before processing
|
|
2191
|
-
- **Graceful error handling**: Returns proper HTTP status codes (413 Payload Too Large)
|
|
2192
|
-
|
|
2193
|
-
#### Security Best Practices
|
|
2194
|
-
- **Environment detection**: Automatically disables in GitHub Actions
|
|
2195
|
-
- **TLS support**: Full HTTPS configuration with custom certificates
|
|
2196
|
-
- **Input validation**: Validates all webhook payloads before processing
|
|
2197
|
-
- **Error isolation**: Security failures don't affect independent checks
|
|
2198
|
-
|
|
2199
|
-
### Complete HTTP Pipeline Example
|
|
2200
|
-
|
|
2201
|
-
```yaml
|
|
2202
|
-
version: "1.0"
|
|
2203
|
-
|
|
2204
|
-
# HTTP server configuration
|
|
2205
|
-
http_server:
|
|
2206
|
-
enabled: true
|
|
2207
|
-
port: 8443
|
|
2208
|
-
tls:
|
|
2209
|
-
enabled: true
|
|
2210
|
-
cert: "${TLS_CERT}"
|
|
2211
|
-
key: "${TLS_KEY}"
|
|
2212
|
-
auth:
|
|
2213
|
-
type: bearer_token
|
|
2214
|
-
secret: "${WEBHOOK_SECRET}"
|
|
2215
|
-
endpoints:
|
|
2216
|
-
- path: "/webhook/deployment"
|
|
2217
|
-
name: "deployment-trigger"
|
|
2218
|
-
|
|
2219
|
-
checks:
|
|
2220
|
-
# 1. Receive webhook
|
|
2221
|
-
deployment-webhook:
|
|
2222
|
-
type: http_input
|
|
2223
|
-
endpoint: "/webhook/deployment"
|
|
2224
|
-
on: [webhook_received]
|
|
2225
|
-
transform: |
|
|
2226
|
-
{
|
|
2227
|
-
"version": "{{ webhook.version }}",
|
|
2228
|
-
"environment": "{{ webhook.environment }}"
|
|
2229
|
-
}
|
|
2230
|
-
|
|
2231
|
-
# 2. Analyze deployment
|
|
2232
|
-
deployment-analysis:
|
|
2233
|
-
type: ai
|
|
2234
|
-
depends_on: [deployment-webhook]
|
|
2235
|
-
prompt: |
|
|
2236
|
-
Analyze deployment for version {{ outputs['deployment-webhook'].suggestions | first }}
|
|
2237
|
-
Check for potential issues and risks
|
|
2238
|
-
|
|
2239
|
-
# 3. Fetch current status
|
|
2240
|
-
current-status:
|
|
2241
|
-
type: http_client
|
|
2242
|
-
depends_on: [deployment-webhook]
|
|
2243
|
-
url: "https://api.example.com/status"
|
|
2244
|
-
method: GET
|
|
2245
|
-
|
|
2246
|
-
# 4. Send results
|
|
2247
|
-
notify-team:
|
|
2248
|
-
type: http
|
|
2249
|
-
depends_on: [deployment-analysis, current-status]
|
|
2250
|
-
url: "https://slack.example.com/webhook"
|
|
2251
|
-
body: |
|
|
2252
|
-
{
|
|
2253
|
-
"text": "Deployment Analysis Complete",
|
|
2254
|
-
"analysis": {{ outputs['deployment-analysis'] | json }},
|
|
2255
|
-
"current_status": {{ outputs['current-status'] | json }}
|
|
2256
|
-
}
|
|
2257
|
-
|
|
2258
|
-
# 5. Scheduled health check
|
|
2259
|
-
health-check:
|
|
2260
|
-
type: http_client
|
|
2261
|
-
url: "https://api.example.com/health"
|
|
2262
|
-
schedule: "*/5 * * * *" # Every 5 minutes
|
|
2263
|
-
transform: |
|
|
2264
|
-
{
|
|
2265
|
-
"status": "{{ response.status }}",
|
|
2266
|
-
"checked_at": "{{ 'now' | date: '%Y-%m-%d %H:%M:%S' }}"
|
|
2267
|
-
}
|
|
2268
|
-
```
|
|
2269
|
-
|
|
2270
|
-
### Liquid Template Support
|
|
2271
|
-
|
|
2272
|
-
All HTTP configurations support Liquid templating for dynamic content:
|
|
2273
|
-
|
|
2274
|
-
- Access webhook data: `{{ webhook.field }}`
|
|
2275
|
-
- Access headers: `{{ headers['x-custom-header'] }}`
|
|
2276
|
-
- Access previous outputs: `{{ outputs['check-name'].suggestions | first }}`
|
|
2277
|
-
- Date formatting: `{{ 'now' | date: '%Y-%m-%d' }}`
|
|
2278
|
-
- JSON encoding: `{{ data | json }}`
|
|
2279
|
-
|
|
2280
|
-
## 🔧 Pluggable Architecture
|
|
2281
|
-
|
|
2282
|
-
Visor features a pluggable provider system for extensibility:
|
|
2283
|
-
|
|
2284
|
-
### Supported Check Types
|
|
2285
|
-
- **AI Provider**: Intelligent analysis using LLMs (Google Gemini, Anthropic Claude, OpenAI GPT) with MCP (Model Context Protocol) tools support
|
|
2286
|
-
- **Claude Code Provider**: Advanced AI analysis using Claude Code SDK with MCP tools and subagents
|
|
2287
|
-
- **Tool Provider**: Integration with external tools (ESLint, Prettier, SonarQube)
|
|
2288
|
-
- **HTTP Provider**: Send data to external HTTP endpoints
|
|
2289
|
-
- **HTTP Input Provider**: Receive data from webhooks
|
|
2290
|
-
- **HTTP Client Provider**: Fetch data from external APIs
|
|
2291
|
-
- **Script Provider**: Custom shell scripts and commands
|
|
2292
|
-
|
|
2293
|
-
### Adding Custom Providers
|
|
2294
|
-
```typescript
|
|
2295
|
-
// Custom provider implementation
|
|
2296
|
-
export class CustomCheckProvider extends CheckProvider {
|
|
2297
|
-
getName(): string {
|
|
2298
|
-
return 'custom-security-scan';
|
|
2299
|
-
}
|
|
2300
|
-
|
|
2301
|
-
async execute(prInfo: PRInfo, config: CheckProviderConfig): Promise<ReviewSummary> {
|
|
2302
|
-
// Your custom analysis logic
|
|
2303
|
-
return {
|
|
2304
|
-
issues: [...],
|
|
2305
|
-
suggestions: [...]
|
|
2306
|
-
};
|
|
2307
|
-
}
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
// Register your provider
|
|
2311
|
-
CheckProviderRegistry.getInstance().registerProvider(new CustomCheckProvider());
|
|
2312
|
-
```
|
|
2313
|
-
|
|
2314
|
-
## ⚙️ Configuration
|
|
2315
|
-
|
|
2316
|
-
Create `.visor.yaml` in your project root:
|
|
2317
|
-
|
|
2318
|
-
```yaml
|
|
2319
|
-
# .visor.yaml
|
|
2320
|
-
version: "1.0"
|
|
2321
|
-
|
|
2322
|
-
# Project metadata
|
|
2323
|
-
project:
|
|
2324
|
-
name: "My Project"
|
|
2325
|
-
description: "My awesome project"
|
|
2326
|
-
language: "typescript" # primary language
|
|
2327
|
-
frameworks: # frameworks in use
|
|
2328
|
-
- "react"
|
|
2329
|
-
- "nodejs"
|
|
2330
|
-
|
|
2331
|
-
# Analysis configuration
|
|
2332
|
-
analysis:
|
|
2333
|
-
# File patterns to include/exclude
|
|
2334
|
-
include:
|
|
2335
|
-
- "src/**/*" # Include all files in src
|
|
2336
|
-
- "lib/**/*" # Include all files in lib
|
|
2337
|
-
exclude:
|
|
2338
|
-
- "node_modules/**" # Exclude node_modules
|
|
2339
|
-
- "dist/**" # Exclude build output
|
|
2340
|
-
- "**/*.test.ts" # Exclude test files
|
|
2341
|
-
|
|
2342
|
-
# Limits
|
|
2343
|
-
maxFileSize: 500000 # Max file size in bytes (500KB)
|
|
2344
|
-
maxFiles: 1000 # Max number of files to analyze
|
|
2345
|
-
|
|
2346
|
-
# Check-specific settings
|
|
2347
|
-
checks:
|
|
2348
|
-
security:
|
|
2349
|
-
enabled: true # Enable/disable this check
|
|
2350
|
-
severity: warning # Minimum severity: info, warning, error, critical
|
|
2351
|
-
rules: # Specific rules to apply
|
|
2352
|
-
- detect-secrets
|
|
2353
|
-
- xss-prevention
|
|
2354
|
-
- sql-injection
|
|
2355
|
-
|
|
2356
|
-
performance:
|
|
2357
|
-
enabled: true
|
|
2358
|
-
severity: info
|
|
2359
|
-
rules:
|
|
2360
|
-
- complexity-analysis
|
|
2361
|
-
- memory-leaks
|
|
2362
|
-
- algorithm-efficiency
|
|
2363
|
-
depends_on: [security] # Run after security check completes
|
|
2364
|
-
|
|
2365
|
-
style:
|
|
2366
|
-
enabled: true
|
|
2367
|
-
severity: info
|
|
2368
|
-
extends: "eslint:recommended" # Extend from ESLint config
|
|
2369
|
-
rules:
|
|
2370
|
-
- naming-conventions
|
|
2371
|
-
- formatting
|
|
2372
|
-
depends_on: [security] # Ensure secure coding style
|
|
2373
|
-
|
|
2374
|
-
architecture:
|
|
2375
|
-
enabled: true
|
|
2376
|
-
severity: warning
|
|
2377
|
-
rules:
|
|
2378
|
-
- circular-dependencies
|
|
2379
|
-
- design-patterns
|
|
2380
|
-
depends_on: [security, performance] # Build on foundational checks
|
|
2381
|
-
|
|
2382
|
-
# Thresholds for pass/fail
|
|
2383
|
-
thresholds:
|
|
2384
|
-
minScore: 70 # Minimum overall score (0-100)
|
|
2385
|
-
maxIssues: 100 # Maximum total issues
|
|
2386
|
-
maxCriticalIssues: 0 # Maximum critical issues
|
|
2387
|
-
|
|
2388
|
-
# Output settings
|
|
2389
|
-
reporting:
|
|
2390
|
-
format: markdown # Default output format
|
|
2391
|
-
verbose: false # Show detailed output
|
|
2392
|
-
includeFixSuggestions: true # Include fix suggestions
|
|
2393
|
-
groupByFile: true # Group issues by file
|
|
2394
|
-
```
|
|
2395
|
-
|
|
2396
|
-
## 🎯 GitHub Action Reference
|
|
2397
|
-
|
|
2398
|
-
### Inputs
|
|
2399
|
-
|
|
2400
|
-
| Input | Description | Default | Required |
|
|
2401
|
-
|-------|-------------|---------|----------|
|
|
2402
|
-
| `github-token` | GitHub token for API access (auto-provided) | `${{ github.token }}` | No (defaults to workflow token) |
|
|
2403
|
-
| `auto-review` | Auto-review on PR open/update | `true` | No |
|
|
2404
|
-
| `checks` | Checks to run (comma-separated) | `all` | No |
|
|
2405
|
-
| `output-format` | Output format | `markdown` | No |
|
|
2406
|
-
| `config-path` | Path to config file | `.visor.yaml` | No |
|
|
2407
|
-
| `max-parallelism` | Maximum number of checks to run in parallel | `3` | No |
|
|
2408
|
-
| `fail-fast` | Stop execution when any check fails | `false` | No |
|
|
2409
|
-
| `comment-on-pr` | Post review as PR comment | `true` | No |
|
|
2410
|
-
| `create-check` | Create GitHub check run | `true` | No |
|
|
2411
|
-
| `add-labels` | Add quality labels to PR | `true` | No |
|
|
2412
|
-
| `fail-on-critical` | Fail if critical issues found | `false` | No |
|
|
2413
|
-
| `min-score` | Minimum score to pass (0-100) | `0` | No |
|
|
2414
|
-
|
|
2415
|
-
### Outputs
|
|
2416
|
-
|
|
2417
|
-
| Output | Description |
|
|
2418
|
-
|--------|-------------|
|
|
2419
|
-
| `review-score` | Overall code quality score (0-100) |
|
|
2420
|
-
| `total-issues` | Total number of issues found |
|
|
2421
|
-
| `critical-issues` | Number of critical issues |
|
|
2422
|
-
| `auto-review-completed` | Whether auto-review was completed (true/false) |
|
|
2423
|
-
| `pr-action` | The PR action that triggered the review (opened/synchronize/edited) |
|
|
2424
|
-
| `incremental-analysis` | Whether incremental analysis was used (true/false) |
|
|
2425
|
-
| `issues-found` | Total number of issues found (alias for total-issues) |
|
|
2426
|
-
| `review-url` | URL to the review comment |
|
|
2427
|
-
|
|
2428
|
-
### Example Workflows
|
|
2429
|
-
|
|
2430
|
-
#### Basic Review with Incremental Analysis
|
|
2431
|
-
```yaml
|
|
2432
|
-
name: PR Review
|
|
2433
|
-
on:
|
|
2434
|
-
pull_request:
|
|
2435
|
-
types: [opened, synchronize, edited] # Enable incremental analysis on new commits
|
|
2436
|
-
|
|
2437
|
-
jobs:
|
|
2438
|
-
review:
|
|
2439
|
-
runs-on: ubuntu-latest
|
|
2440
|
-
steps:
|
|
2441
|
-
- uses: actions/checkout@v4
|
|
2442
|
-
- uses: ./
|
|
2443
|
-
with:
|
|
2444
|
-
auto-review: true # Enable automatic review
|
|
2445
|
-
env:
|
|
2446
|
-
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
|
2447
|
-
MODEL_NAME: gemini-2.0-flash-exp
|
|
2448
|
-
```
|
|
2449
|
-
|
|
2450
|
-
#### Security Focus with SARIF Upload
|
|
2451
|
-
```yaml
|
|
2452
|
-
name: Security Scan
|
|
2453
|
-
on: [push, pull_request]
|
|
2454
|
-
|
|
2455
|
-
jobs:
|
|
2456
|
-
security:
|
|
2457
|
-
runs-on: ubuntu-latest
|
|
2458
|
-
steps:
|
|
2459
|
-
- uses: actions/checkout@v4
|
|
2460
|
-
- name: Run Visor Security Scan
|
|
2461
|
-
uses: ./
|
|
2462
|
-
with:
|
|
2463
|
-
checks: security
|
|
2464
|
-
output-format: sarif
|
|
2465
|
-
|
|
2466
|
-
- name: Upload SARIF
|
|
2467
|
-
uses: github/codeql-action/upload-sarif@v2
|
|
2468
|
-
if: always()
|
|
2469
|
-
with:
|
|
2470
|
-
sarif_file: visor-results.sarif
|
|
2471
|
-
```
|
|
2472
|
-
|
|
2473
|
-
#### Quality Gate
|
|
2474
|
-
```yaml
|
|
2475
|
-
name: Quality Gate
|
|
2476
|
-
on: pull_request
|
|
2477
|
-
|
|
2478
|
-
jobs:
|
|
2479
|
-
quality:
|
|
2480
|
-
runs-on: ubuntu-latest
|
|
2481
|
-
steps:
|
|
2482
|
-
- uses: actions/checkout@v4
|
|
2483
|
-
- uses: ./
|
|
2484
|
-
with:
|
|
2485
|
-
min-score: 80
|
|
2486
|
-
fail-on-critical: true
|
|
2487
|
-
```
|
|
2488
|
-
|
|
2489
|
-
#### Command-Triggered Review
|
|
2490
|
-
```yaml
|
|
2491
|
-
name: Manual Review
|
|
2492
|
-
on:
|
|
2493
|
-
issue_comment:
|
|
2494
|
-
types: [created]
|
|
2495
|
-
|
|
2496
|
-
jobs:
|
|
2497
|
-
review:
|
|
2498
|
-
if: |
|
|
2499
|
-
github.event.issue.pull_request &&
|
|
2500
|
-
startsWith(github.event.comment.body, '/review')
|
|
2501
|
-
runs-on: ubuntu-latest
|
|
2502
|
-
steps:
|
|
2503
|
-
- uses: actions/checkout@v4
|
|
2504
|
-
- uses: ./
|
|
2505
|
-
# Optional: configure inputs (e.g., tag filters, custom configs) with a `with:` block
|
|
2506
|
-
```
|
|
2507
|
-
|
|
2508
|
-
## 📊 Output Formats
|
|
2509
|
-
|
|
2510
|
-
### Table (Default)
|
|
2511
|
-
```
|
|
2512
|
-
╔════════════════════════════════════════════════════════════════╗
|
|
2513
|
-
║ Analysis Summary ║
|
|
2514
|
-
╠════════════════════════════════════════════════════════════════╣
|
|
2515
|
-
║ Overall Score: 85/100 Issues Found: 12 ║
|
|
2516
|
-
╟────────────────────────────────────────────────────────────────╢
|
|
2517
|
-
║ ✓ Security: 92/100 ⚠ Performance: 78/100 ║
|
|
2518
|
-
║ ✓ Style: 88/100 ✓ Architecture: 82/100 ║
|
|
2519
|
-
╚════════════════════════════════════════════════════════════════╝
|
|
2520
|
-
```
|
|
2521
|
-
|
|
2522
|
-
### JSON
|
|
2523
|
-
```json
|
|
2524
|
-
{
|
|
2525
|
-
"summary": {
|
|
2526
|
-
"overallScore": 85,
|
|
2527
|
-
"totalIssues": 12,
|
|
2528
|
-
"criticalIssues": 1
|
|
2529
|
-
},
|
|
2530
|
-
"issues": [
|
|
2531
|
-
{
|
|
2532
|
-
"file": "src/api.ts",
|
|
2533
|
-
"line": 45,
|
|
2534
|
-
"severity": "critical",
|
|
2535
|
-
"category": "security",
|
|
2536
|
-
"message": "Potential SQL injection"
|
|
2537
|
-
}
|
|
2538
|
-
]
|
|
2539
|
-
}
|
|
2540
|
-
```
|
|
2541
|
-
|
|
2542
|
-
### SARIF
|
|
2543
|
-
Compatible with GitHub Security tab and other SARIF consumers.
|
|
2544
|
-
|
|
2545
|
-
## 🛠️ Development
|
|
2546
|
-
|
|
2547
|
-
### Setup
|
|
2548
|
-
```bash
|
|
2549
|
-
# Clone and install
|
|
2550
|
-
git clone https://github.com/your-org/visor.git
|
|
2551
|
-
cd visor
|
|
2552
|
-
npm install
|
|
2553
|
-
|
|
2554
|
-
# Build
|
|
2555
|
-
npm run build
|
|
2556
|
-
|
|
2557
|
-
# Test
|
|
2558
|
-
npm test
|
|
2559
|
-
```
|
|
2560
|
-
|
|
2561
|
-
### Project Structure
|
|
2562
|
-
```
|
|
2563
|
-
visor/
|
|
2564
|
-
├── src/
|
|
2565
|
-
│ ├── cli-main.ts # CLI entry point
|
|
2566
|
-
│ ├── index.ts # GitHub Action entry
|
|
2567
|
-
│ ├── reviewer.ts # Core review logic
|
|
2568
|
-
│ └── output-formatters.ts # Output formatting
|
|
2569
|
-
├── tests/ # Test suites
|
|
2570
|
-
├── .github/workflows/ # GitHub workflows
|
|
2571
|
-
├── action.yml # Action metadata
|
|
2572
|
-
└── .visor.yaml # Project config (overrides defaults/.visor.yaml)
|
|
2573
|
-
```
|
|
2574
|
-
|
|
2575
|
-
### Available Scripts
|
|
2576
|
-
|
|
2577
|
-
| Command | Description |
|
|
2578
|
-
|---------|-------------|
|
|
2579
|
-
| `npm run build` | Build TypeScript |
|
|
2580
|
-
| `npm test` | Run tests |
|
|
2581
|
-
| `npm run test:watch` | Test watch mode |
|
|
2582
|
-
| `npm run test:coverage` | Coverage report |
|
|
389
|
+
Learn more: [docs/output-formats.md](docs/output-formats.md)
|
|
2583
390
|
|
|
2584
391
|
## 🤝 Contributing
|
|
2585
392
|
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
1. Fork the repository
|
|
2589
|
-
2. Create a feature branch
|
|
2590
|
-
3. Make your changes
|
|
2591
|
-
4. Add tests
|
|
2592
|
-
5. Submit a PR
|
|
393
|
+
Learn more: [docs/contributing.md](docs/contributing.md)
|
|
2593
394
|
|
|
2594
395
|
## 📄 License
|
|
2595
396
|
|
|
2596
|
-
MIT License
|
|
397
|
+
MIT License — see [LICENSE](LICENSE)
|
|
2597
398
|
|
|
2598
399
|
---
|
|
2599
400
|
|