Skip to content

Commit f20496c

Browse files
docs/add examples (#6)
* chore: add microservice architecture scaffolding Add Dockerfile, .dockerignore, .env.example, api/openapi.yaml, deploy/docker/docker-compose.yml, docs/architecture.md, and .github/workflows/docker.yml for GHCR build+push CI. * fix: exclude go.work from Docker build context go.work contains local replace directives that break Docker builds. Add go.work and go.work.sum to .dockerignore. * docs: add examples directory with basic usage Add examples/basic/main.go demonstrating how to use sight for code review. Co-authored-by: CommandCodeBot <noreply@commandcode.ai> --------- Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
1 parent 25a8931 commit f20496c

8 files changed

Lines changed: 389 additions & 0 deletions

File tree

.dockerignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.git
2+
.github
3+
.gitignore
4+
*.md
5+
.env
6+
.env.*
7+
Dockerfile
8+
.dockerignore
9+
coverage.out
10+
docs/
11+
deploy/
12+
api/
13+
go.work
14+
go.work.sum

.env.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# sight environment variables — copy to .env and fill in
2+
# LLM API key for code review (consumers provide their own via the Provider interface)
3+
# sight itself doesn't read this — configure your LLM client before passing it to sight.NewReviewer()
4+
SIGHT_PROVIDER=
5+
SIGHT_API_KEY=

.github/workflows/docker.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Docker
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ["v*"]
7+
pull_request:
8+
branches: [main]
9+
paths:
10+
- "Dockerfile"
11+
- "**.go"
12+
- "go.mod"
13+
- "go.sum"
14+
15+
permissions:
16+
contents: read
17+
packages: write
18+
19+
env:
20+
REGISTRY: ghcr.io
21+
IMAGE_NAME: graycodeai/sight
22+
23+
jobs:
24+
build-and-push:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
- name: Log in to GHCR
33+
if: github.event_name != 'pull_request'
34+
uses: docker/login-action@v3
35+
with:
36+
registry: ${{ env.REGISTRY }}
37+
username: ${{ github.actor }}
38+
password: ${{ secrets.GITHUB_TOKEN }}
39+
40+
- name: Docker metadata
41+
id: meta
42+
uses: docker/metadata-action@v5
43+
with:
44+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
45+
tags: |
46+
type=ref,event=branch
47+
type=semver,pattern={{version}}
48+
type=semver,pattern={{major}}.{{minor}}
49+
type=sha,prefix=sha-
50+
51+
- name: Build and push
52+
uses: docker/build-push-action@v6
53+
with:
54+
context: .
55+
push: ${{ github.event_name != 'pull_request' }}
56+
tags: ${{ steps.meta.outputs.tags }}
57+
labels: ${{ steps.meta.outputs.labels }}
58+
cache-from: type=gha
59+
cache-to: type=gha,mode=max
60+
build-args: |
61+
VERSION=${{ github.ref_name }}
62+
COMMIT=${{ github.sha }}
63+
BUILD_DATE=${{ github.event.head_commit.timestamp }}

Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FROM golang:1.26.3-alpine AS builder
2+
3+
RUN apk add --no-cache git ca-certificates tzdata
4+
5+
WORKDIR /build
6+
COPY go.mod go.sum ./
7+
RUN go mod download && go mod verify
8+
9+
COPY . .
10+
ARG VERSION=dev
11+
ARG COMMIT=none
12+
ARG BUILD_DATE=unknown
13+
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath \
14+
-ldflags="-s -w \
15+
-X main.Version=${VERSION} \
16+
-X main.Commit=${COMMIT} \
17+
-X main.BuildDate=${BUILD_DATE}" \
18+
-o sight ./cmd/sight
19+
20+
FROM alpine:3.21
21+
RUN apk add --no-cache ca-certificates tini && \
22+
adduser -D -u 1000 sight
23+
24+
COPY --from=builder /build/sight /usr/local/bin/sight
25+
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
26+
27+
USER sight
28+
ENTRYPOINT ["tini", "--", "sight"]
29+
CMD ["mcp"]

api/openapi.yaml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
openapi: "3.1.0"
2+
info:
3+
title: sight — Code Review Tool Reference
4+
description: |
5+
sight is an AI-powered code review library for diffs.
6+
It parses unified diffs, enriches with code context and git history,
7+
and runs parallel multi-concern reviews through an LLM provider.
8+
9+
sight operates as a Go library and MCP server (stdio or HTTP).
10+
This document describes the MCP tool surface as a machine-readable reference.
11+
version: "0.1.0"
12+
license:
13+
name: MIT
14+
url: https://github.com/GrayCodeAI/sight/blob/main/LICENSE
15+
contact:
16+
url: https://github.com/GrayCodeAI/sight
17+
18+
# No HTTP server by default — MCP uses stdio transport.
19+
# HTTP transport is available via: sight mcp --transport http --addr 127.0.0.1:8080
20+
21+
tags:
22+
- name: review
23+
description: Code review tools
24+
- name: taint
25+
description: Security taint analysis
26+
27+
x-mcp-server:
28+
transport: stdio
29+
binary: sight
30+
start_command: ["sight", "mcp"]
31+
http_transport_command: ["sight", "mcp", "--transport", "http", "--addr", "127.0.0.1:8080"]
32+
33+
x-mcp-tools:
34+
sight_review:
35+
description: AI code review on a unified diff — security, correctness, style, performance
36+
inputSchema:
37+
type: object
38+
required: [diff]
39+
properties:
40+
diff:
41+
type: string
42+
description: Unified diff text (output of `git diff`)
43+
preset:
44+
type: string
45+
enum: [Quick, Standard, Thorough, SecurityFocus, CI]
46+
default: Standard
47+
description: Review thoroughness preset
48+
exclude_files:
49+
type: array
50+
items:
51+
type: string
52+
description: File patterns to exclude from review (glob)
53+
max_tokens:
54+
type: integer
55+
description: Maximum tokens for the LLM review
56+
57+
sight_describe:
58+
description: Generate a pull request description from a unified diff
59+
inputSchema:
60+
type: object
61+
required: [diff]
62+
properties:
63+
diff:
64+
type: string
65+
description: Unified diff text
66+
67+
sight_improve:
68+
description: Suggest specific code improvements for a diff
69+
inputSchema:
70+
type: object
71+
required: [diff]
72+
properties:
73+
diff:
74+
type: string
75+
focus:
76+
type: string
77+
description: Focus area for improvements (e.g. "performance", "readability")
78+
79+
sight_taint:
80+
description: SSA-based cross-function taint analysis for security vulnerabilities
81+
inputSchema:
82+
type: object
83+
required: [path]
84+
properties:
85+
path:
86+
type: string
87+
description: Absolute path to the Go package or module root
88+
patterns:
89+
type: string
90+
default: "./..."
91+
description: Go package patterns to analyze
92+
json:
93+
type: boolean
94+
default: false
95+
description: Output results as JSON

deploy/docker/docker-compose.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: sight
2+
3+
services:
4+
sight:
5+
build:
6+
context: ../../
7+
dockerfile: Dockerfile
8+
image: ghcr.io/graycodeai/sight:dev
9+
env_file:
10+
- path: ../../.env.example
11+
required: false
12+
command: ["mcp"]

docs/architecture.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<div align="center">
2+
3+
# 👁️ sight Architecture
4+
5+
**AI-Powered Code Review on Diffs**
6+
7+
[![Go](https://img.shields.io/badge/Go-1.26+-00ADD8?logo=go)](https://go.dev/)
8+
[![Protocol](https://img.shields.io/badge/Protocol-MCP-purple)]()
9+
10+
</div>
11+
12+
---
13+
14+
## 🎯 Overview
15+
16+
sight is an AI-powered code review library for Go. It parses unified diffs, enriches with **code context** and **git history**, and runs **parallel multi-concern reviews** through an LLM provider.
17+
18+
> 💡 No LLM client bundled — consumers inject their own via the `Provider` interface.
19+
20+
---
21+
22+
## 🧱 Components
23+
24+
```
25+
sight/
26+
├── api/openapi.yaml 📜 MCP tool surface reference
27+
├── cmd/sight/main.go 🖥️ CLI entry (mcp, taint subcommands)
28+
├── sight.go 📤 Public API: Review(), Finding, Result, Stats
29+
├── reviewer.go 🔄 Reviewer: parallel concern orchestration
30+
├── options.go ⚙️ config, With* functions, presets
31+
├── provider.go 🔌 Provider interface (consumers implement)
32+
├── severity.go 📊 Re-exports from hawk/shared/types
33+
├── static_rules.go 🛡️ 30+ static analysis rules
34+
├── taint_analysis.go 🔗 SSA-based taint tracking
35+
├── sast_integration.go 🔒 SAST-LLM fusion
36+
├── autofix.go 🔧 Fix suggestion pipeline
37+
├── eval.go 📊 Evaluation harness
38+
├── mcp/ 🔌 MCP server (stdio + HTTP)
39+
└── internal/
40+
├── diff/ 📄 Unified diff parser
41+
├── review/ 🧠 Concerns, prompts, response parsing
42+
├── comment/ 💬 Inline comment formatting
43+
├── context/ 📖 Code context + git blame
44+
└── output/ 📊 SARIF and terminal formatters
45+
```
46+
47+
---
48+
49+
## 📤 Public API
50+
51+
```go
52+
// 🚀 One-shot review
53+
result, err := sight.Review(ctx, diffText,
54+
sight.WithProvider(myLLMProvider),
55+
sight.Thorough,
56+
)
57+
58+
// 🔄 Reusable reviewer
59+
reviewer := sight.NewReviewer(sight.WithProvider(myLLMProvider))
60+
result, err := reviewer.Review(ctx, diffText)
61+
62+
// ❌ Check if any findings are above threshold
63+
if result.Failed() {
64+
fmt.Printf("Review failed: %d findings\n", len(result.Findings))
65+
}
66+
```
67+
68+
---
69+
70+
## 🔌 Provider Interface
71+
72+
```go
73+
type Provider interface {
74+
Chat(ctx context.Context, messages []Message, opts ChatOpts) (*Response, error)
75+
}
76+
```
77+
78+
> Consumers implement this with their LLM client (e.g., using eyrie). hawk wires eyrie as the provider via `internal/bridge/sight/bridge.go`.
79+
80+
---
81+
82+
## ⚡ Presets
83+
84+
| Preset | Concerns | Speed |
85+
|--------|----------|:-----:|
86+
| 🏃 `Quick` | security, correctness | Fast |
87+
| 📊 `Standard` | security, correctness, style, docs | Medium |
88+
| 🔬 `Thorough` | all concerns | Slow |
89+
| 🔒 `SecurityFocus` | security, taint only | Fast |
90+
| 🤖 `CI` | Standard, fail on High+ | Medium |
91+
92+
---
93+
94+
## 🔌 MCP Server
95+
96+
```bash
97+
sight mcp # 📡 stdio transport
98+
sight mcp --transport http --addr :8080 # 🌐 HTTP transport
99+
```
100+
101+
**Tools:** `sight_review` · `sight_describe` · `sight_improve` · `sight_taint`
102+
103+
---
104+
105+
## 🔎 Findings
106+
107+
| Field | Description |
108+
|-------|-------------|
109+
| `Concern` | Review category (security, style, etc.) |
110+
| `Severity` | 🟢 Info · 🟡 Low · 🟠 Medium · 🔴 High · 🟥 Critical |
111+
| `File` / `Line` | Location in the diff |
112+
| `Message` | What was found and why |
113+
| `Fix` | Suggested fix |
114+
| `CWE` | CWE reference (security findings) |
115+
| `Confidence` | 0.0–1.0 score |
116+
| `InlineComment` | PR-ready inline comment |
117+
118+
---
119+
120+
## 🛡️ Static Rules + Taint Analysis
121+
122+
**30+ built-in rules** run without LLM overhead — hardcoded secret patterns, SQL injection sinks, unsafe deserialization, etc. Fused with LLM results.
123+
124+
**Taint analysis** (`sight taint --path .`) uses SSA-based cross-function tracking to detect source→sink data flows. Sources, sinks, and sanitizers are configurable.

examples/basic/main.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
8+
"github.com/GrayCodeAI/sight"
9+
)
10+
11+
type mockProvider struct{}
12+
13+
func (m *mockProvider) Complete(ctx context.Context, messages []sight.Message) (string, error) {
14+
return "Code looks good. Consider adding error handling for edge cases.", nil
15+
}
16+
17+
func main() {
18+
diff := `diff --git a/main.go b/main.go
19+
--- a/main.go
20+
+++ b/main.go
21+
@@ -10,6 +10,10 @@ func main() {
22+
if err != nil {
23+
log.Fatal(err)
24+
}
25+
+
26+
+ // Process the data
27+
+ processData(result)
28+
+
29+
fmt.Println("Done")
30+
}
31+
`
32+
33+
reviewer := sight.NewReviewer(
34+
sight.WithProvider(&mockProvider{}),
35+
sight.Thorough,
36+
)
37+
38+
result, err := reviewer.Review(context.Background(), diff)
39+
if err != nil {
40+
log.Fatal(err)
41+
}
42+
43+
fmt.Printf("Found %d findings:\n", len(result.Findings))
44+
for _, f := range result.Findings {
45+
fmt.Printf("[%s] %s:%d - %s\n", f.Severity, f.File, f.Line, f.Message)
46+
}
47+
}

0 commit comments

Comments
 (0)