browser_review_gate 0.1.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +74 -0
- data/exe/browser-review-gate +5 -0
- data/lib/browser_review_gate/assessment.rb +97 -0
- data/lib/browser_review_gate/assessor.rb +141 -0
- data/lib/browser_review_gate/cli.rb +144 -0
- data/lib/browser_review_gate/config.rb +57 -0
- data/lib/browser_review_gate/gate.rb +62 -0
- data/lib/browser_review_gate/github.rb +81 -0
- data/lib/browser_review_gate/hook.rb +36 -0
- data/lib/browser_review_gate/installer.rb +171 -0
- data/lib/browser_review_gate/markdown.rb +8 -0
- data/lib/browser_review_gate/model_client.rb +70 -0
- data/lib/browser_review_gate/publisher.rb +136 -0
- data/lib/browser_review_gate/report.rb +154 -0
- data/lib/browser_review_gate/saved_report.rb +26 -0
- data/lib/browser_review_gate/shell.rb +15 -0
- data/lib/browser_review_gate/status.rb +40 -0
- data/lib/browser_review_gate/templates/agents_block.md.erb +5 -0
- data/lib/browser_review_gate/templates/claude_skill.md.erb +10 -0
- data/lib/browser_review_gate/templates/config.yml.erb +24 -0
- data/lib/browser_review_gate/templates/cursor_command.md.erb +4 -0
- data/lib/browser_review_gate/templates/playbook.md.erb +48 -0
- data/lib/browser_review_gate/templates/workflow.yml.erb +64 -0
- data/lib/browser_review_gate/version.rb +3 -0
- data/lib/browser_review_gate.rb +38 -0
- data/lib/generators/browser_review_gate/install/install_generator.rb +22 -0
- metadata +70 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require "json"
|
|
3
|
+
|
|
4
|
+
module BrowserReviewGate
|
|
5
|
+
# Results of a browser run made before the PR exists, kept inside the git directory for one commit.
|
|
6
|
+
# They are published once a PR for that commit is opened.
|
|
7
|
+
class SavedReport
|
|
8
|
+
def initialize(sha:, shell: Shell.new)
|
|
9
|
+
@sha = sha
|
|
10
|
+
@shell = shell
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def path
|
|
14
|
+
@path ||= @shell.call("git", "rev-parse", "--git-path", "browser-verification/#{@sha}.json").strip
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def exist? = File.exist?(path)
|
|
18
|
+
def read = JSON.parse(File.read(path))
|
|
19
|
+
def delete = FileUtils.rm_f(path)
|
|
20
|
+
|
|
21
|
+
def write(data)
|
|
22
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
23
|
+
File.write(path, JSON.pretty_generate(data))
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "open3"
|
|
2
|
+
|
|
3
|
+
module BrowserReviewGate
|
|
4
|
+
# Runs a command and returns its stdout; raises Error with stderr when it fails.
|
|
5
|
+
class Shell
|
|
6
|
+
def call(*argv, stdin_data: nil)
|
|
7
|
+
stdout, stderr, status = Open3.capture3(*argv, stdin_data: stdin_data)
|
|
8
|
+
return stdout if status.success?
|
|
9
|
+
|
|
10
|
+
raise Error, "#{argv.join(" ")} failed: #{stderr.strip}"
|
|
11
|
+
rescue Errno::ENOENT
|
|
12
|
+
raise Error, "#{argv.first} is not installed"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module BrowserReviewGate
|
|
2
|
+
# What an agent needs to know before a browser run: the decision for the PR head and the next step.
|
|
3
|
+
class Status
|
|
4
|
+
def initialize(github:, config: Config.new, shell: Shell.new)
|
|
5
|
+
@github = github
|
|
6
|
+
@config = config
|
|
7
|
+
@shell = shell
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def to_h(number = nil)
|
|
11
|
+
local_sha = @shell.call("git", "rev-parse", "HEAD").strip
|
|
12
|
+
saved = SavedReport.new(sha: local_sha, shell: @shell).exist?
|
|
13
|
+
number ||= @github.pull_request_number_for_branch
|
|
14
|
+
return { "pull_request" => nil, "local_head" => local_sha, "saved_run" => saved, "next" => saved ? "open_pull_request" : "run_and_save", "app" => @config.app } unless number
|
|
15
|
+
|
|
16
|
+
pull_request = @github.pull_request(number)
|
|
17
|
+
comments = @github.comments(number)
|
|
18
|
+
head_sha = pull_request.fetch("head").fetch("sha")
|
|
19
|
+
assessment = Assessment.latest(comments)
|
|
20
|
+
assessment = nil unless assessment&.for?(head_sha)
|
|
21
|
+
verified = pull_request.fetch("labels").any? { |label| label["name"] == @config.label } && !Report.latest_passing(comments).nil?
|
|
22
|
+
|
|
23
|
+
{ "pull_request" => number, "pr_head" => head_sha, "local_head" => local_sha,
|
|
24
|
+
"decision" => assessment&.decision, "reason" => assessment&.reason, "verified" => verified,
|
|
25
|
+
"saved_run" => saved, "next" => next_step(assessment, verified, saved, head_sha == local_sha),
|
|
26
|
+
"app" => @config.app }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def next_step(assessment, verified, saved, on_pr_head)
|
|
32
|
+
return "nothing" if verified || (assessment && !assessment.required?)
|
|
33
|
+
return "check_out_pr_head" unless on_pr_head
|
|
34
|
+
return "publish_saved" if saved
|
|
35
|
+
return "request_assessment" unless assessment
|
|
36
|
+
|
|
37
|
+
"run_and_publish"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<!-- browser_review_gate:start -->
|
|
2
|
+
## Browser verification before human review
|
|
3
|
+
|
|
4
|
+
A PR that changes browser-visible behavior needs a browser run before a human reviews it; CI takes back reviewer requests until one is published. When asked to run `<%= command %>` (with or without a PR number), or to verify a branch or PR in the browser, read `<%= playbook_path %>` and follow it exactly. Right after opening a PR with `gh pr create`, run `browser-review-gate publish` if `browser-review-gate status` says `publish_saved`.
|
|
5
|
+
<!-- browser_review_gate:end -->
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-pr-verification
|
|
3
|
+
description: Use when a branch or an open pull request needs browser verification before human review - before the PR is opened, or after the PR comment asks for it.
|
|
4
|
+
argument-hint: "[PR number] [optional reviewer]"
|
|
5
|
+
---
|
|
6
|
+
<!-- browser_review_gate:managed <%= BrowserReviewGate::VERSION %> -->
|
|
7
|
+
|
|
8
|
+
# Verify a PR in the browser
|
|
9
|
+
|
|
10
|
+
Read `<%= playbook_path %>` and follow it exactly. The arguments are: `$ARGUMENTS` (a PR number, optionally followed by a reviewer login; empty means the current branch).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Settings for browser_review_gate. Every key is optional.
|
|
2
|
+
|
|
3
|
+
# How an AI coding agent starts and reaches the app for a browser run.
|
|
4
|
+
start_command:<%= start_command ? " #{start_command.inspect}" : "" %>
|
|
5
|
+
url:<%= url ? " #{url.inspect}" : "" %>
|
|
6
|
+
# How to sign in locally, e.g. "use the seed account from db/seeds.rb". No real credentials here.
|
|
7
|
+
sign_in:
|
|
8
|
+
|
|
9
|
+
# Workflow file name under .github/workflows, used to request an assessment by hand.
|
|
10
|
+
workflow: <%= workflow %>
|
|
11
|
+
|
|
12
|
+
# PRs that are never gated.
|
|
13
|
+
skip_authors:
|
|
14
|
+
- "dependabot[bot]"
|
|
15
|
+
- "github-actions[bot]"
|
|
16
|
+
skip_branch_prefixes: []
|
|
17
|
+
|
|
18
|
+
# A PR that only touches these paths cannot change browser behavior; no model call is made.
|
|
19
|
+
ignore_paths:
|
|
20
|
+
- "docs/**"
|
|
21
|
+
- "test/**"
|
|
22
|
+
- "spec/**"
|
|
23
|
+
- "**/*.md"
|
|
24
|
+
- ".github/**"
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<!-- browser_review_gate:managed <%= BrowserReviewGate::VERSION %> -->
|
|
2
|
+
# Verify a PR in the browser
|
|
3
|
+
|
|
4
|
+
Read `<%= playbook_path %>` and follow it exactly. Whatever follows this command is the argument: a PR number, optionally followed by a reviewer login. No argument means the current branch.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<!-- browser_review_gate:managed <%= BrowserReviewGate::VERSION %> — re-run `browser-review-gate install` to update. -->
|
|
2
|
+
# Browser verification before human review
|
|
3
|
+
|
|
4
|
+
A pull request that changes what a person sees or does in a browser must be exercised in a browser before a human reviews it. CI decides whether a PR needs that and writes the decision in one "Browser verification" comment. Until a passing run is published, reviewer requests on such a PR are taken back.
|
|
5
|
+
|
|
6
|
+
This file is the playbook for the AI coding agent that does the run. The person starts it with `<%= command %> NUMBER` for an open PR, or `<%= command %>` on a branch that has no PR yet.
|
|
7
|
+
|
|
8
|
+
## Steps
|
|
9
|
+
|
|
10
|
+
1. Run `browser-review-gate status` (add `--pr NUMBER` when a number was given). It prints JSON; follow `next`:
|
|
11
|
+
- `nothing`: no run is needed, or the PR is already verified. Say that review can be requested.
|
|
12
|
+
- `check_out_pr_head`: check out the PR head with a clean worktree, then start again.
|
|
13
|
+
- `request_assessment`: run `browser-review-gate request-assessment NUMBER`, wait about a minute, then start again.
|
|
14
|
+
- `publish_saved`: a run saved for this commit exists. Run `browser-review-gate publish` and stop; nothing runs again.
|
|
15
|
+
- `open_pull_request`: a run is saved and waits for the PR. Tell the person to open it.
|
|
16
|
+
- `run_and_publish` or `run_and_save`: continue with step 2.
|
|
17
|
+
2. Read the diff against the base branch and the earlier report in the PR, if any. List the scenarios for the browser-visible behavior that changed. Do not re-run behavior an earlier passing case still covers.
|
|
18
|
+
3. Start the app and open it in a browser tool. `app` in the status output says how: start command, URL, sign-in hint. Use local test data and do not destroy existing data. If the app, the data, or a browser tool is missing, report the blocker. Reading code and running unit tests does not replace a browser run.
|
|
19
|
+
4. Run every scenario end to end. After key actions check the page state, console errors, and failed requests. Record what you observed. A skipped or blocked scenario is not a pass.
|
|
20
|
+
5. Write the report as JSON outside the repository (see the shape below). Set `coverage_complete` to true only when every scenario from step 2 ran.
|
|
21
|
+
6. Publish or save, from the checkout that was tested, with everything committed and pushed:
|
|
22
|
+
- PR exists: `browser-review-gate publish --report PATH` (add `--pr NUMBER` when the branch has several). It posts the cases with their outcomes. Only a complete all-pass report adds the `<%= label %>` label.
|
|
23
|
+
- No PR yet: `browser-review-gate save --report PATH`. The run is published when the PR for this commit is opened. A new commit makes it stale.
|
|
24
|
+
7. Check the command result and the PR. A non-zero exit can still mean a report was posted: a failing or incomplete report is visible in the PR and review stays closed.
|
|
25
|
+
8. Request a reviewer only when the person named one and only after the run passed. Otherwise say that review can be requested.
|
|
26
|
+
|
|
27
|
+
## Report shape
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"tested_sha": "<full commit SHA that was tested>",
|
|
32
|
+
"coverage_complete": true,
|
|
33
|
+
"cases": [
|
|
34
|
+
{ "id": "BROWSER-1", "name": "The changed interaction completes", "result": "pass", "details": "What was observed." }
|
|
35
|
+
],
|
|
36
|
+
"excluded": [
|
|
37
|
+
{ "name": "Sign-in through an external provider", "reason": "Needs a real provider account; covered by integration tests." }
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`result` is `pass` or `fail`. `excluded` is optional: list a scenario there only when the person decided it stays outside the local run. Never exclude a scenario on your own to make the run complete. Keep customer and real company names out of the report.
|
|
43
|
+
|
|
44
|
+
## Rules
|
|
45
|
+
|
|
46
|
+
- Run the awkward path in the browser, or mark coverage incomplete and leave review closed. Do not declare a run done from tests and code reading.
|
|
47
|
+
- Keep the report file and browser artifacts outside the repository. The publisher refuses a checkout with modified or untracked files and lists them.
|
|
48
|
+
- After an unrelated commit, do not run everything again: use the PR comment and the earlier report to pick only what is new.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# browser_review_gate:managed <%= BrowserReviewGate::VERSION %> — re-run `browser-review-gate install` to update.
|
|
2
|
+
#
|
|
3
|
+
# Decides whether a PR needs a browser run and keeps human review requests behind it.
|
|
4
|
+
# A tool-free model call proposes the decision; the gem validates it and does every write.
|
|
5
|
+
# pull_request_target runs this file from the base branch. PR code is never checked out or
|
|
6
|
+
# executed; the diff is read through the API as data.
|
|
7
|
+
#
|
|
8
|
+
# Setup: a CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY secret. Settings: .github/browser-review-gate.yml
|
|
9
|
+
# A PR opened before this workflow existed is assessed on its next event; dispatch with pr_number
|
|
10
|
+
# to assess it now.
|
|
11
|
+
|
|
12
|
+
name: Browser review gate
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
pull_request_target:
|
|
16
|
+
types: [opened, reopened, synchronize, review_requested]
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
inputs:
|
|
19
|
+
pr_number:
|
|
20
|
+
description: "Pull request to assess"
|
|
21
|
+
type: number
|
|
22
|
+
required: true
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
issues: write
|
|
27
|
+
pull-requests: write
|
|
28
|
+
|
|
29
|
+
concurrency:
|
|
30
|
+
group: browser-review-gate-${{ github.event.pull_request.number || inputs.pr_number }}
|
|
31
|
+
cancel-in-progress: false
|
|
32
|
+
|
|
33
|
+
jobs:
|
|
34
|
+
gate:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
timeout-minutes: 10
|
|
37
|
+
steps:
|
|
38
|
+
- name: Checkout base branch
|
|
39
|
+
uses: actions/checkout@v4
|
|
40
|
+
with:
|
|
41
|
+
fetch-depth: 1
|
|
42
|
+
persist-credentials: false
|
|
43
|
+
|
|
44
|
+
- name: Set up Ruby
|
|
45
|
+
uses: ruby/setup-ruby@v1
|
|
46
|
+
with:
|
|
47
|
+
<% if ruby_version -%>
|
|
48
|
+
ruby-version: "<%= ruby_version %>"
|
|
49
|
+
<% end -%>
|
|
50
|
+
bundler-cache: false
|
|
51
|
+
|
|
52
|
+
- name: Install browser_review_gate
|
|
53
|
+
run: |
|
|
54
|
+
<%= install_command %>
|
|
55
|
+
|
|
56
|
+
# PR text is never interpolated into the shell: only the number reaches it.
|
|
57
|
+
- name: Assess the change and keep review requests behind browser verification
|
|
58
|
+
env:
|
|
59
|
+
GH_TOKEN: ${{ github.token }}
|
|
60
|
+
GH_REPO: ${{ github.repository }}
|
|
61
|
+
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
62
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
63
|
+
PR_NUMBER: ${{ github.event.pull_request.number || inputs.pr_number }}
|
|
64
|
+
run: browser-review-gate ci "$PR_NUMBER"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require_relative "browser_review_gate/version"
|
|
2
|
+
|
|
3
|
+
# Keeps human review of a pull request behind a browser run of its browser-visible changes.
|
|
4
|
+
#
|
|
5
|
+
# CI side (`browser-review-gate ci`): decide whether the PR needs a browser run, record the decision in
|
|
6
|
+
# one PR comment, and remove reviewer requests until a passing run is published.
|
|
7
|
+
# Local side (`save`, `publish`, `status`, `hook`): an AI coding agent runs the scenarios in a browser
|
|
8
|
+
# and publishes what it observed.
|
|
9
|
+
module BrowserReviewGate
|
|
10
|
+
Error = Class.new(StandardError)
|
|
11
|
+
|
|
12
|
+
# URL-safe Base64 without padding, for the data kept in PR comment markers. Uses nothing outside the
|
|
13
|
+
# core, so the executable also runs from a plain copy of this directory.
|
|
14
|
+
module Marker
|
|
15
|
+
def self.encode(text) = [ text ].pack("m0").tr("+/", "-_").delete("=")
|
|
16
|
+
|
|
17
|
+
def self.decode(payload)
|
|
18
|
+
padded = payload.tr("-_", "+/")
|
|
19
|
+
"#{padded}#{"=" * ((4 - padded.length % 4) % 4)}".unpack1("m0")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
autoload :Assessment, File.join(__dir__, "browser_review_gate/assessment")
|
|
24
|
+
autoload :Assessor, File.join(__dir__, "browser_review_gate/assessor")
|
|
25
|
+
autoload :CLI, File.join(__dir__, "browser_review_gate/cli")
|
|
26
|
+
autoload :Config, File.join(__dir__, "browser_review_gate/config")
|
|
27
|
+
autoload :Gate, File.join(__dir__, "browser_review_gate/gate")
|
|
28
|
+
autoload :GitHub, File.join(__dir__, "browser_review_gate/github")
|
|
29
|
+
autoload :Hook, File.join(__dir__, "browser_review_gate/hook")
|
|
30
|
+
autoload :Installer, File.join(__dir__, "browser_review_gate/installer")
|
|
31
|
+
autoload :Markdown, File.join(__dir__, "browser_review_gate/markdown")
|
|
32
|
+
autoload :ModelClient, File.join(__dir__, "browser_review_gate/model_client")
|
|
33
|
+
autoload :Publisher, File.join(__dir__, "browser_review_gate/publisher")
|
|
34
|
+
autoload :Report, File.join(__dir__, "browser_review_gate/report")
|
|
35
|
+
autoload :SavedReport, File.join(__dir__, "browser_review_gate/saved_report")
|
|
36
|
+
autoload :Shell, File.join(__dir__, "browser_review_gate/shell")
|
|
37
|
+
autoload :Status, File.join(__dir__, "browser_review_gate/status")
|
|
38
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
require "browser_review_gate"
|
|
3
|
+
|
|
4
|
+
module BrowserReviewGate
|
|
5
|
+
module Generators
|
|
6
|
+
# bin/rails generate browser_review_gate:install
|
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
|
8
|
+
desc "Set up the browser review gate: CI workflow, settings, playbook, and AI agent entry points."
|
|
9
|
+
|
|
10
|
+
class_option :agents, type: :array, desc: "claude, cursor, codex (default: detected from the project)"
|
|
11
|
+
class_option :gem_source, type: :string, desc: "How CI gets the gem: rubygems (default), git:URL[#REF] or path:DIR"
|
|
12
|
+
class_option :workflow, type: :string, desc: "Workflow file name under .github/workflows"
|
|
13
|
+
|
|
14
|
+
def install
|
|
15
|
+
BrowserReviewGate::Installer.new(
|
|
16
|
+
root: destination_root, agents: options[:agents], gem_source: options[:gem_source],
|
|
17
|
+
workflow: options[:workflow], force: options[:force], dry_run: options[:pretend]
|
|
18
|
+
).install
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: browser_review_gate
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- JetRockets
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: CI decides whether a pull request needs a browser run and takes back
|
|
13
|
+
reviewer requests until an AI coding agent (Claude Code, Cursor, Codex) has exercised
|
|
14
|
+
the change in a browser and published what it observed. One command sets a project
|
|
15
|
+
up.
|
|
16
|
+
executables:
|
|
17
|
+
- browser-review-gate
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- CHANGELOG.md
|
|
22
|
+
- LICENSE.txt
|
|
23
|
+
- README.md
|
|
24
|
+
- exe/browser-review-gate
|
|
25
|
+
- lib/browser_review_gate.rb
|
|
26
|
+
- lib/browser_review_gate/assessment.rb
|
|
27
|
+
- lib/browser_review_gate/assessor.rb
|
|
28
|
+
- lib/browser_review_gate/cli.rb
|
|
29
|
+
- lib/browser_review_gate/config.rb
|
|
30
|
+
- lib/browser_review_gate/gate.rb
|
|
31
|
+
- lib/browser_review_gate/github.rb
|
|
32
|
+
- lib/browser_review_gate/hook.rb
|
|
33
|
+
- lib/browser_review_gate/installer.rb
|
|
34
|
+
- lib/browser_review_gate/markdown.rb
|
|
35
|
+
- lib/browser_review_gate/model_client.rb
|
|
36
|
+
- lib/browser_review_gate/publisher.rb
|
|
37
|
+
- lib/browser_review_gate/report.rb
|
|
38
|
+
- lib/browser_review_gate/saved_report.rb
|
|
39
|
+
- lib/browser_review_gate/shell.rb
|
|
40
|
+
- lib/browser_review_gate/status.rb
|
|
41
|
+
- lib/browser_review_gate/templates/agents_block.md.erb
|
|
42
|
+
- lib/browser_review_gate/templates/claude_skill.md.erb
|
|
43
|
+
- lib/browser_review_gate/templates/config.yml.erb
|
|
44
|
+
- lib/browser_review_gate/templates/cursor_command.md.erb
|
|
45
|
+
- lib/browser_review_gate/templates/playbook.md.erb
|
|
46
|
+
- lib/browser_review_gate/templates/workflow.yml.erb
|
|
47
|
+
- lib/browser_review_gate/version.rb
|
|
48
|
+
- lib/generators/browser_review_gate/install/install_generator.rb
|
|
49
|
+
licenses:
|
|
50
|
+
- MIT
|
|
51
|
+
metadata: {}
|
|
52
|
+
rdoc_options: []
|
|
53
|
+
require_paths:
|
|
54
|
+
- lib
|
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '3.2'
|
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
61
|
+
requirements:
|
|
62
|
+
- - ">="
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
version: '0'
|
|
65
|
+
requirements: []
|
|
66
|
+
rubygems_version: 4.0.10
|
|
67
|
+
specification_version: 4
|
|
68
|
+
summary: Keeps human review of a pull request behind a browser run of its browser-visible
|
|
69
|
+
changes.
|
|
70
|
+
test_files: []
|