Doctor

June 17, 2026 · View on GitHub

Run @geoql/doctor in CI: quality score, structured findings, SARIF, and dashboard push.

Marketplace License: MIT

What is this?

A GitHub Action that runs @geoql/vue-doctor or @geoql/nuxt-doctor against your codebase. It surfaces a 0-100 quality score, structured findings, and a SARIF report for GitHub Code Scanning, and can push results to your the-doctor.report dashboard. It audits Vue 3 and Nuxt 4 code for AI-generated anti-patterns, reactivity traps, performance issues, and correctness mistakes. It does not scaffold or rewrite. It critiques.

Listed on the Marketplace as doctor-vue-nuxt-code-audit.

Ecosystem

RepoWhatLink
geoql/doctorOSS CLIs + oxlint rule pluginsgithub.com/geoql/doctor
geoql/doctor-action (this repo)GitHub Action wrappergithub.com/geoql/doctor-action
the-doctor.reportHosted SaaS dashboard (private)app.the-doctor.report
DocsRules, CLI, scoring referencedocs.the-doctor.report

Quick start

Vue 3 project

- uses: geoql/doctor-action@v2
  with:
    framework: vue
    preset: recommended
    fail-on: warn

Nuxt 4 project

- uses: geoql/doctor-action@v2
  with:
    framework: nuxt
    preset: strict
    threshold: '80'

PR review + SARIF upload

On a pull request, the action posts inline review comments on the changed lines that have findings and keeps one sticky summary comment up to date. pull-requests: write is required for both. Use comment-mode to choose summary, review, or both (the default).

permissions:
  contents: read
  pull-requests: write
  security-events: write

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - id: doctor
        uses: geoql/doctor-action@v2
        with:
          framework: vue
          pr-comment: 'true'
          comment-mode: both # summary | review | both
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: doctor.sarif
      - run: echo "Score: ${{ steps.doctor.outputs.score }}"

Inline comments only land on lines added or changed in the PR diff (a GitHub constraint); findings elsewhere are rolled into the summary instead. The step degrades to summary-only — never failing the build — when it is not a pull request, when token is absent, or when a comment cannot be placed.

Push findings to your dashboard

Generate an API key in your the-doctor.report dashboard, store it as a repo secret (DOCTOR_API_KEY), and the action pushes every run.

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: geoql/doctor-action@v2
        with:
          framework: nuxt
          api-key: ${{ secrets.DOCTOR_API_KEY }}
          # project defaults to owner/repo; override if your slug differs
          # project: my-team/my-app

The push runs even when the gate fails, so a regression still lands on your trend chart.

Inputs

InputDefaultDescription
frameworkvueWhich doctor to run: vue or nuxt.
presetrecommendedBase rule preset: minimal | recommended | strict | all.
threshold0Minimum passing score (0-100). The job fails below this value.
fail-onerrorExit non-zero on this severity or worse: error | warn | none.
difffalseOnly report findings in files changed vs HEAD.
pr-commentfalseOn a PR, post inline review comments + a sticky summary comment.
comment-modebothWhat to post when pr-comment is on: summary | review | both.
token${{ github.token }}Token used to post PR comments. Needs pull-requests: write.
working-directory.Directory to run the audit in (the project root).
api-key''the-doctor.report API key (doc_…). When set, results push to your dashboard. Pass via secrets, never inline.
project${{ github.repository }}Project slug for the dashboard. Defaults to the GitHub owner/repo.
push-modefullHow to push: full (CLI streams privacy-stripped findings in one call) or score (action posts only the score via curl).
push-urlhttps://app.the-doctor.report/api/v1/findingsFindings endpoint, used when push-mode is full. Override for self-hosted.

Outputs

OutputDescription
scoreThe integer quality score (0-100).
findings-countThe total number of diagnostics reported.

How it works

The action resolves the exact CLI version from the npm registry, installs @geoql/vue-doctor or @geoql/nuxt-doctor globally, then runs the audit once to JSON (driving the outputs and the gate exit code) and again to SARIF for Code Scanning. When pr-comment is true on a pull request, it maps each finding to its position in the PR diff and posts the findings as one batched review (inline comments on changed lines) plus a single sticky summary comment that it creates once and updates in place on every later run, located via a hidden <!-- geoql-doctor-report --> marker.

When api-key is set, results flow to the-doctor.report. With push-mode: full (the default), the CLI streams privacy-stripped findings to https://app.the-doctor.report/api/v1/findings in a single call. The payload carries rule IDs, severities, file paths, line and column numbers, and message templates only. No source code, no file contents, no secrets. With push-mode: score, the action falls back to a curl-based score-only POST to https://app.the-doctor.report/api/v1/score.

The gate (threshold and fail-on) is enforced last, so the findings push and PR comment always run first, even on a failing score.

License

MIT © geoql