Show HN: Farol – a risk map of a pull request for the person who approves it
Show HN: Farol – a risk map of a pull request for the person who approves it (github.com)
要約
Farolは、AIレビュー後にプルリクエストの承認者がマージのリスクとその発生箇所を把握できる、オープンソースのCLIおよびGitHubアクションです。静的解析に基づき、変更が及ぼす影響範囲、リスクスコア、そして最もリスクの高いファイルを特定し、レビューの効率化と品質向上を目指します。
全文翻訳
farol AIレビューの後で
[画像: farol]
プルリクエストのマージリスクと、それがどこに潜むかを把握する。
無料のオープンソースCLIおよびGitHub Action。AIレビューの後、farolは承認者にマージのリスクとリスクを伴うファイルを示し、最もリスクの高い変更に最も注意が払われるようにします。
ウェブサイト · ライブデモ · はじめに · リファレンス
[画像: ライセンス: MIT] [画像: Node.js 22+] [画像: TypeScript · Go · Python] [画像: シャドウモード]
エージェントがコードを書き、エージェントがそれをレビューします。最後の判断は依然として人間が行います:マージを承認するかしないか。その承認が希少な部分であり、すべてのプルリクエストに均等に分散されると、それは読み飛ばしとなり、共有フックへの1行の変更が40ページをダウンさせる原因となります。
farolはAIレビューの代わりではなく、その後に機能します。 レビューエージェントは差分内の行にコメントします。farolは、エージェントが確実に提供できないものを提供します:変更を受け入れるリスク、そしてそれがどこに潜むか。目標はレビューを速くするだけではありません。低リスクのプルリクエストは速く進められ、リスクの高いものは、リスクを伴うファイルから始めて、行ごとに読まれます。これは静的解析(モデルの推測ではなく、コンパイラ自身のコードビュー)から機能するため、同じプルリクエストは常に同じ結果を得ます。
Claude Codeチームは、How the Claude Code team does code reviewで同様の原則を説明しています:レビューの労力は変更のリスクに従います。彼らが言うように、「変更がティアを設定するのであり、作成者ではない」のです。
farol(ポルトガル語で灯台の意味)は、レビューアが差分を開く前にトリアージを行います:
- この変更は何に影響しますか? 変更されたコードを実行する既存のすべてのページ、API操作、RPCメソッド、ジョブ、スクリプト、およびそれらへの呼び出しチェーン。
- マージのリスクはどれくらいですか? 影響範囲、差分カバレッジ、セキュリティ検出、契約違反、依存関係の変更から得られる判定(ファストトラック、クイックレビュー、慎重なレビュー)と0〜100のリスクスコア。
- どこから始めればよいですか? 最もリスクの高いファイルから始め、インライン差分、テストされていない行のマーク、手動で試すことのチェックリスト付き。
無料かつオープンソース(MIT)。 npx @winninjs/farolとしてCLIで実行するか、GitHub Action winnin/farol/actionで各プルリクエストで実行します。アカウント不要、ホストサービスなし:お使いのマシンまたはCIランナーで実行され、各PRにコメントしますが、マージをブロックすることはありません。コードを実行せず、どこにも送信しません。
[画像: プルリクエストのfarolレポート:74/100の慎重なレビュー、開始すべき2つのファイル、3つの契約変更]
ライブデモ
このデモには、FastAPIフルスタックテンプレートのプルリクエストに対してCIで生成されたfarolレポートが含まれています。このプルリクエストは、FastAPIバックエンドとTanStack Routerを備えたReactフロントエンドを使用しています。プルリクエストはアイテムにステータスとインサイトページを追加し、レビューアがキャッチすべき問題(APIの破壊的変更、f-stringで構築されたSQL、テストのない共有コンポーネントなど)を特定します。
- バックエンドレポート:⚠ 慎重なレビュー、APIの破壊的変更、および高深刻度のセキュリティ検出。
- フロントエンドレポート:⚠ 慎重なレビュー、新しいページ、および共有コンポーネントが影響する既存のページ。
レポートはインタラクティブです:ファイルをレビュー済みとしてマークする、ページをフィーチャーフラグで隠されているとマークする、インライン差分を開く、テストプランに従う、結果タブからレビュー記録をコピーする。これらはプルリクエストのコメントがリンクしているファイルと同じです(プルリクエスト);コピーはdocs/demo/にあります。
| AIレビューエージェント | farol | |
|---|---|---|
| 読み取るもの | 差分と、プロンプトに収まるコンテキスト | ベースとヘッドの全プログラム、およびコンパイラ(TypeScript型チェッカー、go/types、Python ast) |
| 伝えること | これらの行に何があるか | これらの行が何に影響するか、マージのリスクはどれくらいか、どこから見ればよいか |
| 結果は | 確率的:実行ごとに異なる言葉遣い | 決定的:同じPRは同じレポートを生成し、すべての主張には呼び出しチェーンが付随する |
| 不確かな場合 | 自信があるように聞こえるかもしれない | unknownと表示し、慎重なレビューを求める |
| 実行 | モデル、通常はホストサービス | ローカルまたはCIで:コードを実行せず、どこにも送信しない |
両方を使用してください、その順序で。エージェントはまず行をレビューします。次にfarolは承認者に、マージにどれだけ注意が必要か、どのファイルがそれに値するか、どのページとエンドポイントを手動でテストすべきか、どの契約変更がクライアントのチェックを必要とするかを示します。エージェントのレビューは、小さな変更が大きな影響を持つ場合に不十分であり、それがfarolが示すものです。
なぜfarolなのか
- レビューの注意はリスクのある場所に向かう。 40ファイルあるPRでも、実際に問題を起こしうるファイルは2〜3個であることがほとんどです。farolはそれらをランク付けするので、レビューアはそれらを注意深く読み、残りは安心してスキップできます。
- ファイル名ではなく、コードに従う。 farolは実際のコンパイラ(TypeScript型チェッカー、
go/types、Pythonのast)を使用して宣言グラフを構築します。「1ファイル変更」ではなく、「formatPriceの変更が12ページに影響する」とリストアップします。 - クライアントが対応する前に契約違反を検出する。 レスポンスフィールドの削除、新しい必須パラメータ、GraphQL、FastAPI、Goハンドラ、gRPCでの型の変更、および各エンドポイントを呼び出すサービス。
- PR全体をレビューするか、前回見たものから変更された部分だけをレビューするか。 各プッシュには2つのレポートが生成されます:プルリクエスト全体、および前回のプッシュ以降のコミットのみ。修正のラウンドの後、レビューアは最初からやり直すのではなく、新しいコミットをチェックします。
- CIが既に持っているものを使用する。 カバレッジ、リンター、セキュリティ、監査レポートが、変更された行の差分カバレッジと検出事項になります。何も二度実行されません。
- クローズドで失敗する。 farolが変更の一部を読み取れない場合、
unknownと表示し、慎重なレビューを求めます。理解できなかったからといって、安全だと呼ぶことはありません。 - 人間のループのために構築されている。 ファイルをレビュー済みとしてマークする、ページをフィーチャーフラグで隠されているとマークする、検出事項をチェックオフする、結果をPRに貼り付けてレビューの記録とする。
内容
- ライブデモ
- farol AIレビューの後で
- はじめに
- レシピ集:React Router · Next.js · TanStack Router · TypeScript API · Go · Python · Datadog
- サポートされているもの
- レビューの読み方
- 仕組み · セキュリティ · 制限事項 · FAQ
- リファレンス(すべてのコマンド、オプション、設定キー)
はじめに
Node.js 22+ と git(Goプロジェクトの場合はgo、Pythonプロジェクトの場合はpython3 3.11+)が必要です。インストール不要:npx @winninjs/farolでfarolを実行します。
1. プロジェクトを記述します。ルートにfarol.config.jsonを作成します。スタックを選択するだけで開始できます:
| プロジェクト | farol.config.json | 完全なレシピ |
|---|---|---|
| React Router を使用した React アプリ | { "routes": { "file": "src/routes.tsx" } }(ルートテーブルを構築するファイル) | React Router |
| Next.js アプリ(Pages または App Router) | { "routes": { "adapter": "next" } } | Next.js |
| TanStack Router を使用した React アプリ | { "routes": { "adapter": "tanstack-router", "dir": "src/routes" } } | TanStack Router |
| TypeScript API(GraphQL、REST) | { "surface": "backend" } | TypeScript API |
| Go サービス | { "language": "go", "surface": "backend" } | Go |
| Python サービス(FastAPI、Flask、Django、Celery…) | { "language": "python", "surface": "backend" } | Python |
2. farolが検出するものを確認します:見つかったページ、エンドポイント、ジョブ、スクリプト。
npx @winninjs/farol routes
3. ブランチを分析し、レポートを開きます。
npx @winninjs/farol analyze --base origin/main --head HEAD --out farol.json
npx @winninjs/farol html --in farol.json --out farol.html && open farol.html # Linuxでは xdg-open
例:React Router を使用した React アプリ
cd path/to/your/react-app
echo '{ "routes": { "file": "src/routes.tsx" } }' > farol.config.json
npx @winninjs/farol routes # ページをリスト表示:"/", "/products", "/settings"…
git checkout my-feature-branch
npx @winninjs/farol analyze --base origin/main --head HEAD --out farol.json
npx @winninjs/farol html --in farol.json --out farol.html && open farol.html
レポートには、判定、スコア、開始すべきファイル、変更が影響するページ、手動でテストすべき項目が既に表示されています。次のステップ: カバレッジ、リンター、監査レポートを追加し、スタックのレシピを使用して各PRでfarolを実行します。すべてのオプションはリファレンスにあり、スタックごとにexamples/README.mdにあります。
頻繁に実行しますか?
npm install --global @winninjs/farolを実行すると、通常のfarolコマンドが利用できます。
レシピ集
各レシピには3つの部分があります:コミットする farol.config.json、生成するレポート、およびGitHub Actionsワークフロー。examples/ のワークフローは完全で、1つの形状を共有しています:
tests:テスト、リンター、監査を実行し、レポートを保持します。PRのコードを実行するため、機密情報や書き込み権限のあるトークンは使用しません。既にテストジョブがある場合は、それを保持し、そのアップロードステップを追加してください。farol:その後に実行され(成功または失敗)、gitとレポートを読み取り、ブラウザでHTMLレポートへのリンクを含む各プッシュに新しいコメントを投稿します。さらに、前回のプッシュ以降のコミットのみを含む2番目のレポートも生成します。PRのコードは実行しません。- ドラフトはスキップされ、フォークPRはコメントを受け取りません(トークンは読み取り専用です)。すべてのfarolステップは
continue-on-errorです。
動作したらアクションをコミットにピン留めしてください:winnin/farol/action@<sha> # main (YYYY-MM-DD 現在)。
examples/README.md は各スタックについて詳しく説明しています:すべての設定キー、CLIパラメータ、アクション入力、およびセットアップの確認方法。
Reactフロントエンド(React Router)
React Routerのルートテーブル(オブジェクト形式およびJSX形式、遅延ロードルート、分割ルートモジュール)、宣言ごとの到達範囲。
{
"routes": { "file": "src/routes.tsx" },
"roles": { "global": ["src/main.tsx", "src/App.tsx", "src/styles/global.css", "package.json", "vite.config.ts"] }
}
npx vitest run --coverage.enabled --coverage.reporter=json --coverage.reportsDirectory=reports/coverage
npx eslint -f json -o reports/eslint.json <変更されたファイル>
npm audit --json > reports/audit.json # または pnpm audit --json
npx @winninjs/farol analyze --base origin/main --head HEAD \
--coverage reports/coverage/coverage-final.json --eslint reports/eslint.json --audit reports/audit.json --out farol.json
CI: examples/workflow.ymlを.github/workflows/farol.ymlにコピーしてください。
Vitest設定でcoverage.include: ['src/**/*.{ts,tsx}']を設定して、テストでロードされないファイルがテストされていないと報告されるようにします。分割されたルートツリーはroutes.extraFilesに格納されます。より完全な設定はexamples/farol.config.jsonにあります。
Next.js
Pages RouterとApp Router:すべてのページ、APIルート、レイアウト、_app/_document、ミドルウェア。ファイル名から読み取られます。動的セグメント([id])、キャッチオール、ルートグループ、並列スロットが理解されます。
{
"routes": { "adapter": "next" },
"roles": { "global": ["next.config.*", "package.json"]
}
pages/とapp/はプロジェクト内またはそのsrc/内で検出されます。それらが別の場所にある場合は"dir"を設定してください。レポートとCIはReact Routerと同じです(JestまたはVitestカバレッジ、ESLint、監査)。tsconfigがワークスペースパッケージを拡張するモノレポの場合("extends": "tsconfig/nextjs.json")、分析前に依存関係をインストールしてください。これにより、パッケージがnode_modulesに配置されます。
TanStack Router
ファイルベースルーティング:ルートディレクトリ下のcreateFileRoute('<id>')を呼び出すすべてのモジュール、ルートルート、パスレスレイアウト(_app)、および親ルートを子レイアウトとして扱います。
{ "routes": { "adapter": "tanstack-router", "dir": "src/routes" } }
レポートとCIはReact Routerと同じです。
TypeScript API(GraphQLまたはREST)
GraphQLルート操作(スキーマファイルとgqlテンプレート、リゾルバごと)およびFastify/ExpressスタイルのRESTエンドポイント。
{
"surface": "backend",
"backend": { "graphql": true, "rest": true },
"roles": { "global": ["package.json", "src/app.ts"]
}
レポートとCIはReact Routerと同じです:examples/workflow.yml。リゾルバがインジェクトされたコンテキスト(ctx.loaders.Brand.byId())を介してデータに到達する場合、プロバイダーの場所をfarolに伝えます:"backend": { "context": { "loaders": ["src/modules/*/loaders/index.ts"] } }。
Goサービス
chi、gin、echo、net/httpルート、gRPCサービスメソッド、mainバイナリ。宣言ごとの到達範囲と、実装に解決されたインターフェース呼び出し。
{ "language": "go", "surface": "backend" }
go test -coverpkg=./... -coverprofile=reports/cover.out ./...
golangci-lint run --output.json.path=reports/golangci.json --issues-exit-code=0 ./... # gosecを有効にする
govulncheck -json ./... > reports/govulncheck.json
npx @winninjs/farol analyze --base origin/main --head HEAD \
--coverage reports/cover.out --eslint reports/golangci.json --audit reports/govulncheck.json --out farol.json
CI: examples/workflow-go.ymlをコピーしてください(uvを使用;インストーラーは適宜変更してください)。farolはモジュールをオフラインで読み取るため、ワークフローは最初にベースとヘッドの両方に対してgo mod downloadを実行します。
Pythonサービス
FastAPIおよびFlaskルート(ルーター、ブループリント、プレフィックス)、Django URL、MCPツール/リソース/プロンプト、Celeryタスク、Temporalワークフローとアクティビティ、Prefectフロー、および__main__スクリプト。farolはコードを解析しますが、インポートしません。
{ "language": "python", "surface": "backend", "python": { "roots": ["src", "."] } }
pytest --cov=src --cov-report=json:reports/coverage.json
ruff check --output-format json --extend-select S --exit-zero . > reports/ruff.json # S = flake8-bandit
pip-audit --format json -o reports/pip-audit.json
npx @winninjs/farol analyze --base origin/main --head HEAD \
--coverage reports/coverage.json --eslint reports/ruff.json --audit reports/pip-audit.json --out farol.json
CI: examples/workflow-python.ymlをコピーします(uvを使用;インストーラーは適宜変更してください)。
Datadogのトラフィックとエラーを追加
オプションであり、情報提供のみです。スコアを変更することはありません。これにより、レポートは各影響を受けるページまたは操作のトラフィック量、その個別の本番エラー(Datadogにリンク)、既にエラーを発生させている変更されたファイル、および各変更されたエンドポイントを呼び出すサービスを示します。
{
"datadog": {
"env": "prod",
"rum": { "applicationId": "<RUM application id>" },
"apm": { "service": "orders-api", "operations": ["fastapi.request"] }
}
}
DD_API_KEY=… DD_APP_KEY=… npx @winninjs/farol usage --out usage.json # 過去14日間
npx @winninjs/farol analyze … --usage usage.json
CI: サンプルワークフローにはfarol-usageジョブがあります:DD_API_KEYとDD_APP_KEYのシークレット、およびリポジトリ変数FAROL_DATADOG=trueを設定します。Datadogを1日1回読み取り、PRのコードを見ることはありません。キー、スコープ、および一致ルールはリファレンスにあります。
サポートされているもの
| TypeScript / Reactフロントエンド | TypeScript / JavaScriptバックエンド | Go | Python | |
|---|---|---|---|---|
| エントリーポイント | React Routerのルートテーブル(オブジェクト形式およびJSX形式、遅延ロードルート、分割ルートモジュール);Next.jsのPagesおよびApp Router(ページ、APIルート、レイアウト、ミドルウェア);TanStack Routerのファイルベースルート | GraphQLルート操作(スキーマファイルとgqlテンプレート)およびRESTエンドポイント(Fastify/Expressスタイル) | chi、gin、echo、net/httpルート;gRPCサービスメソッド;mainバイナリ | FastAPIおよびFlaskルート(ルーター、ブループリント、プレフィックス);Django URL;MCPツール、リソース、プロンプト;Celeryタスク;Temporalワークフローとアクティビティ;Prefectフロー;__main__スクリプト |
| 到達精度 | 宣言ごと(TypeScript型チェッカー) | モジュールごと、GraphQLのリゾルバごと | 宣言ごと(go/types、実装に解決されたインターフェース呼び出し) | 宣言ごと(ローカル型推論を備えたPython ast) |
| 契約変更 | — | GraphQLスキーマ(破壊的/危険/安全) | ハンドラのリクエストおよびレスポンス型(net/http、chi、gin、echo);gRPCメッセージ | FastAPIパラメータ、ボディ、レスポンス、Pydanticモデル |
| 依存関係 | package.json + npm/pnpm/yarn/bunロックファイル | 同上 | go.mod + go.sum | pyproject.toml(PEP 621、extras、groups、uv、Poetry)、requirements.txt + uv.lock/poetry.lock/Pipfile.lock |
| 差分カバレッジ | Istanbul coverage-final.json(Vitest、Jest) | 同上 | go test -coverprofile | coverage.py JSON(pytest --cov) |
| リンター | eslint -f json | 同上 | golangci-lint JSON | ruff JSON |
| セキュリティ | 内蔵ルール(XSSシンク、eval、ハードコードされたシークレット、javascript: URL…) | 同上 | gosec(golangci-lint経由) | flake8-bandit(ruff Sルール) |
| 脆弱性 | npm audit --json、pnpm audit --json | 同上 | govulncheck -json | pip-audit --format json |
| 抑制 | eslint-disable、@ts-ignore、@ts-expect-error、as any… | 同上 | //nolint、//lint:ignore、#nosec | # noqa、# type: ignore、# nosec、# pragma: no cover… |
| トラフィックとエラー(オプション) | Datadog RUMページビューとエラー | Datadog APMリクエスト、エラーイベント、および呼び出し元 | 同上 | 同上 |
すべての言語で:環境、インフラストラクチャ、CIファイル(.env*、Dockerfile、compose、CIパイプライン、helm、k8s、terraform…)は独自のセクションに;任意のコミット以降の増分分析(--since);git blameとCODEOWNERSからの推奨レビューア;GitHubコメント、Markdown、または単一ファイルHTMLページとしてのレポート。
レビューの読み方
farolは2つのものを生成します:判定、トップファイル、テストチェックリストを含むPRコメントと、レビューが行われる単一ファイルHTMLレポート(コメントからリンク)。各部分の目的と使用方法を以下に示します。
判定とマージリスクスコア
PRにどれだけの時間を費やすべきかを示します。
| 判定 | 意味 | やること |
|---|---|---|
| ✓ ファストトラック | 新規コード、テスト、または低リスクの変更のみ。 | 差分をスキップして承認する。 |
| ◐ クイックレビュー | 範囲が限定された既存コードの変更、または弱いシグナル(低カバレッジ、リンターエラー、設定ファイル)。 | ここから始めるファイルをチェックしてから承認する。 |
| ⚠ 慎重なレビュー | 広範囲またはサイレントな破壊の可能性:スコア60以上、契約の破壊的変更、高深刻度の検出、テストされていない中心的なファイル、またはfarolが読み取れなかったコード。 | ここから始めるファイルを一行ずつ読み、それらが影響するものをテストする。 |
スコア(0〜100)は、少なくとも1つのリスク項目が何かを破壊する可能性です。スコアの内訳を展開して、各項目とそのポイントを表示します:影響範囲×テストされていない割合によるファイル、検出事項、契約変更、依存関係。判定には常にその理由が付随します。差分を読む前にそれらを読んでください。
ここから始める
変更されたコードファイル、リスクの高い順。各行は、そのファイルを実行する既存のページまたは操作の数、差分カバレッジ、検出事項、およびそれ自体のリスクポイントを示します。Datadogを使用すると、トラフィックと本番エラーも表示されます。インライン差分を開きます:テストが実行されない追加行は○、検出事項がある行は⚠とマークされます。
使い方: 上から順にレビューし、各ファイルをレビュー済みとしてマークします。進むにつれてスコアが下がるため、残りのリスクがどれだけあるかを常に把握できます。その下に、低リスクのファイル(スキップ用)、環境/インフラ/CIファイル(環境ごとの値を確認)、レビュー不要なファイル(ドキュメント、ロックファイル、テスト)が続きます。
フィーチャーフラグの下
各ページまたは操作の行、および上部のパネルに:完全にフラグの下にあるエントリーポイントをマークします。フラグ付きエントリーポイントのみを使用するファイルはレビューから除外され、レビュー済みではなくフラグの下とラベル付けされます。これは、ダークでリリースされた作業中の機能に使用し、残りのスコアがユーザーが実際にヒットするものを反映するようにします。
ページ / 操作
新しいエントリーポイントと影響を受けるエントリーポイントすべてを、リストまたはモジュールごとのツリーとして表示します。いずれかを開くと、変更がファイルごとにどのようにエントリーポイントに到達するかを示します。Datadogを使用すると、各エントリーポイントはトラフィックシェアと個別のエラー(最も多いものから順)を表示します。使い方: ブラスト半径を判断します。ほとんど使用されない3つの管理ページに影響する変更は、チェックアウトページに影響する変更とは異なります。
契約(バックエンド)
リクエストまたはレスポンスの形状が変更された各エンドポイント。破壊的(ベース用に構築されたクライアントが失敗する可能性)、危険(誤動作する可能性)、または安全(互換性のある追加)として表示され、正確なフィールドとDatadogからの呼び出し元サービスが示されます。使い方: すべての破壊的変更が意図されており、そのクライアントが更新されていることを確認し、クライアントとチェック済みをマークします。
[画像: 破壊的な契約変更:GET /brands が response[].name を返さなくなった]
セキュリティ、依存関係、カバレッジ
スコアの根拠:変更された行のセキュリティ検出事項(各項目にチェックボックス付き)、既知の脆弱性を持つ追加または更新された依存関係、およびファイルごとの差分カバレッジ。レポートが提供されなかった場合は検証されていませんと表示され、合格とは表示されません。
テストプラン
手動で試す新しいページまたは操作、新しいものから順に、次にそれらに到達するファイルの危険度順。PRコメントにはタスクリストとして表示されます。使い方: ローカルまたはプレビュー環境でブランチを実行するときに使用します。レビューに従います:アイテムの背後にある変更されたファイルがすべてレビュー済みとしてマークされると、アイテムもマークされます(✓ ファイルレビュー済み)、または🚩フラグの下。手動テスト用の独自のチェックボックスは、あなたがチェックするために残されます。
レビュアー
誰がレビューすべきか:PRのコードを変更した人(git blame、各ファイルの危険度で重み付け)、およびCODEOWNERS。PRの作成者自身やボットは除外され、非アクティブな人はラベル付けされます。使い方: 誰か空いている人ではなく、最もリスクの高いファイルを最もよく知っている人に依頼するために使用します。
結果
レビューのMarkdown記録:最初の判定とスコア、現在のスコア、フラグ付きエントリーポイント、レビュー済みファイル、チェックされた検出事項と契約変更。MarkdownとしてコピーしてPRにレビューコメントとして貼り付け、次の人が何が確認されたかを知れるようにします。
前回のプッシュ以降
開いているPRへのプッシュ後、コメントには前回のプッシュ以降のコミットのみを含む2番目のレポートが添付されます(analyze --since <sha>;フォースプッシュ後は、そのマージベースから)。その判定、スコア、およびここから始めるは、それらの変更のみをカバーします。使い方: レビューの2回目のラウンドに使用します:修正が要求されたことを行い、他に何も影響しないことを確認し、新しいコミットがどこかに到達した場合にのみ、完全なレポートに戻ります。
クラスと理由
詳細とコメントの折りたたまれたブロックに保持されるため、レビューアはまず自分の意見を形成します:isolated(追加のみ)、touches-existing(既存コードが変更された)、global(グローバルファイル、マニフェスト、または重要な依存関係)、unknown(変更の一部が読み取れなかった:決して安全ではない)。すべての理由コードはdocs/reasons.mdにあります。
仕組み
- 差分:マージベースとヘッドの差分を取り、リネームを検出し、空白のみの行と末尾のカンマの行を無視します。
- 両方のツリーを何も実行せずに読み取る:TypeScriptコンパイラAPI、
go list+go/types(オフライン)、Pythonast。そこから、エントリーポイントと、どの宣言がどれを使用するかを示すグラフを作成します。 - 宣言を比較:コードのハッシュによって比較するため、コメントやフォーマットはカウントされません。新しい宣言とエントリーポイントは追加されます。
- 到達範囲:各変更された宣言から、それを実行するすべてエントリーポイントまでの最短チェーンを保持します。
- 分類、重み付け、計画:クラス、スコア、判定、開始すべきファイル、テストチェックリスト。
662の過去の4つのリポジトリのコミットで、ファストトラックは56コミットで問題なし、スコアのAUCは0.72〜0.83でした。あなた自身の履歴でfarol calibrateを実行してください。言語ごとの詳細はdocs/how-it-works.mdにあり、すべての選択の背後にある理由はdocs/DECISIONS.mdにあります。
セキュリティとプライバシー
analyzeは分析対象リポジトリのコードを実行せず、ネットワークを使用しません。GoおよびPythonヘルパーは標準ライブラリのみを使用し、解析のみを行います。- ネットワークと通信するのは
comment(GitHub API)とusage(Datadog API)のみです。エラーメッセージはDatadogからコピーされず、エラータイプのみがコピーされます。 - CIでは、コードを実行するジョブはシークレットや書き込みトークンを持たず、コメントするジョブはコードを実行しません。
- シャドウモード:farolは情報提供のみを行い、承認、変更要求、チェック失敗は行いません。
制限事項
- 静的読み取り:実行時に構築される値は不可視です(計算されたルートパス、
getattr、importlib、DIコンテナ、ループで埋められたレジストリ)。エントリーポイントが読み取れない場合、PRはunknownとなります。呼び出しが解決できない場合、farolはそれがより多く到達すると仮定し、少なくないと仮定します。 - TypeScriptフロントエンド:React Router、Next.js、TanStack Router(ファイルベース)のみ:コードベースのTanStackルートツリー、Remix/React Routerのファイル規約、VueまたはSvelteはありません。JavaScriptファイル、リネームされたファイル、TypeScriptバックエンドはモジュールレベルの到達範囲を使用します。
- Go:chi/gin/echoグループ以外のミドルウェアスタックからのルートプレフィックスは適用されません。ルーターを独自の登録APIでラップするプロジェクトタイプ(Giteaの
web.Router)は読み取られません。Python:Django REST Frameworkルーターは読み取られません。 - スコアと判定のしきい値は、いくつかのリポジトリでチェックされたヒューリスティックです。あなた自身の履歴でそれらを調整してください。
FAQ
既にAIレビュアーがいますが、なぜfarolを追加するのですか? それらは異なる質問に答えます。エージェントは差分内の行にコメントします。その後、farolは承認者に、マージのリスクはどれくらいか、そしてリスクを伴うファイルはどれかを示します。これはプログラム全体の静的解析に基づいています。両方実行してください:farolのコメントとレポートはエージェントの隣に配置され、どちらもマージをブロックしません。
無料ですか? はい。farolはMITライセンスの下でオープンソースであり、アカウント、ホストサービス、有料ティアはありません。npx @winninjs/farolまたはGitHub Action winnin/farol/actionで実行できます。
CIを遅くしますか? いいえ。farolはテストの後に実行され、それらのレポートを再利用します。分析には、300ファイルのPythonサービスで約3秒、大規模なTypeScriptモノレポまたはコールドキャッシュのGoサービスで8〜10秒、ヘルパー出力がキャッシュされている場合はベースで1秒未満かかります。
GitHub以外で使用できますか? はい。analyze、html、reportはどこでも動作します。commentのみがGitHub固有です。npx @winninjs/farol reportの出力をプラットフォームのAPIで投稿してください。
レポートに「検証されていません」と表示されます。 そのレポートは提供されなかったか、パスが間違っています。analyzeに提供されたパスは現在のディレクトリからの相対パスです。farol.config.jsonのパスはプロジェクトからの相対パスです。
変更したページがリストにありません。 npx @winninjs/farol routesを実行してfarolが読み取るエントリーポイントを確認し、npx @winninjs/farol impact <ファイル>を実行してファイルに到達するものを確認してください。読み取れないルート構造は診断の下にリストされます。
Go:「farolはGoモジュールをオフラインで読み取ります:go mod download を実行してください」。 モジュールキャッシュにベースまたはヘッドの依存関係がありません。分析する前に両方に対してgo mod downloadを実行してください。
モノレポ? --cwdをアプリにポイントしてください。パスはリポジトリルートからの相対パスのままですが、プロジェクトが使用しないアプリの変更は、その外部にあるものとしてリストされます。
貢献
貢献を歓迎します:ルートアダプター、フレームワーク、言語、レポート形式、およびより良いヒューリスティック。セットアップ、アーキテクチャ、規約についてはCONTRIBUTING.mdを参照してください。脆弱性を報告するにはSECURITY.mdを参照してください。
ライセンス
MIT © 2026 Winnin