compose-doctor

agent
Guvenlik Denetimi
Uyari
Health Uyari
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Uyari
  • process.env — Environment variable access in .github/workflows/compose-doctor.yml
  • fs module — File system access in .github/workflows/compose-doctor.yml
  • process.env — Environment variable access in action.yml
  • fs module — File system access in action.yml
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

Deterministic 0-100 health score and agent fix-loop for Android Jetpack Compose. Wraps detekt + compose-rules

README.md

compose-doctor

Gradle Plugin Portal
Claude Code Plugin
Gemini CLI Extension
ci
License: MIT
Website

A deterministic health check for Android Jetpack Compose — the React Doctor idea, for Compose.

Your agent writes Compose; this scores it. compose-doctor runs detekt +
compose-rules under the hood, then turns the findings
into a single 0–100 health score, a structured report an agent can fix against, and a CI/PR gate.

Published. The plugin is live on the Gradle Plugin Portal
as dev.composedoctor — apply it with plugins { id("dev.composedoctor") version "0.1.0" }
(see Use it in your project).

Why

The pieces exist in the Compose world but are unbundled — compose-rules/compose-lints for the
rules, scattered agent guides, and no shared score. compose-doctor's value isn't the rules (those
are battle-tested upstream); it's the bundle: one score, an agent fix-loop, and a CI gate.

The score

score = 100 − (uniqueErrorRules × 1.5) − (uniqueWarningRules × 0.75)      // clamped to [0, 100]

Translated directly from React Doctor: the unit is unique rule IDs triggered, not instance
count and not normalized by code size. Fixing 49 of 50 violations of a rule does not move the
score; clearing the last one removes that rule's penalty. That makes the score deterministic
without calibration — and makes the agent loop ("clear one rule at a time") effective.

Labels: 75+ Great · 50–74 Needs work · <50 Critical.

Findings are grouped into display dimensions (State/Correctness, Performance, Architecture,
Security, Accessibility) for the report — dimensions do not weight the overall score.

compose-doctor applies a curated policy on top of detekt + compose-rules — Compose health plus
genuine bugs, with a two-tier severity (errors −1.5, warnings −0.75) and style noise disabled. See
docs/RULES.md.

Try it

The repo ships a deliberately-flawed playground/ feed app, wired to the plugin from
source via a composite build. With JDK 21:

git clone [email protected]:rotemmiz/compose-doctor.git && cd compose-doctor
./gradlew -p playground composeDoctor

📖 docs/TRY-IT-PLAYGROUND.md is a guided walkthrough — run it, read
the report, fix a rule, and watch the score move.

compose-doctor — health score: 72/100  [NEEDS_WORK]
  unique error rules:   9
  unique warning rules: 19
  total findings:       34

  by dimension:
    ARCHITECTURE       82/100
    STATE_CORRECTNESS  94/100
    ...

Outputs:

  • build/reports/compose-doctor/score.json — machine-readable score + findings (for agents/CI). Excerpt:

    {
      "schemaVersion": 1, "status": "ok", "score": 72, "label": "NEEDS_WORK",
      "uniqueErrorRules": 9, "uniqueWarningRules": 19, "totalFindings": 34,
      "dimensions": { "ARCHITECTURE": 82, "PERFORMANCE": 96, "STATE_CORRECTNESS": 94 },
      "byRule": [
        { "ruleId": "CompositionLocalAllowlist", "severity": "ERROR", "count": 1,
          "scoreImpactIfCleared": 1.5, "fixHint": "Avoid this CompositionLocal or add it to the allowlist." }
      ]
    }
    
  • build/reports/detekt/detekt.sarif — findings in SARIF, with precise locations.

Use it in your project

The plugin is on the Gradle Plugin Portal
apply it by id and pin the version (pinning keeps scores comparable across runs):

// build.gradle.kts of a module with Compose source
plugins {
    id("dev.composedoctor") version "0.1.0"
}

composeDoctor {
    failBelow.set(75)          // fail the build below this score (optional)
    // per-engine strictness — see docs/RULES.md (needs: import dev.composedoctor.plugin.EngineLevel)
    // detekt  = EngineLevel.ERRORS              // count only detekt's genuine bugs
    // compose = EngineLevel.ERRORS_AND_WARNINGS // count all Compose issues (default)
    // autoConfigureDetekt.set(false)            // if you already configure detekt yourself
}

Then ./gradlew composeDoctor. The plugin applies detekt, attaches the compose-rules ruleset
(config bundled), enables SARIF, and scores it. Existing detekt machinery — baseline.xml,
detekt.yml, @Suppress — applies as usual.

Repositories: your build needs gradlePluginPortal(), mavenCentral(), and google()
available — the plugin pulls detekt and the io.nlopez.compose.rules ruleset from them.

JDK: run Gradle on JDK 17–21. detekt (1.23.x) can't analyze under a JDK newer than 22, so
a daemon on JDK 22+ fails the :detekt task — pin Gradle's JVM (org.gradle.java.home) if your
default JDK is newer.

CI

A reusable workflow posts the score on every PR, uploads SARIF for code-scanning annotations, and
gates on a threshold:

# .github/workflows/health.yml
jobs:
  health:
    uses: rotemmiz/compose-doctor/.github/workflows/compose-doctor.yml@main
    with:
      gradle-args: composeDoctor
      fail-below: 75

It posts a sticky score comment on the PR — a health badge, the headline score, the top outstanding
findings (with file:line and a fix hint), and a per-dimension breakdown:

compose-doctor's sticky PR score comment

Repo Health Badge

Showcase your project's Compose health score in your README:

[![Compose Doctor](https://img.shields.io/badge/Compose%20Doctor-75%2B%20Great-10b981?logo=android)](https://github.com/rotemmiz/compose-doctor)

Agent skill

skills/compose-doctor/SKILL.md teaches a coding agent to run the
task, read the SARIF, and fix the highest-value rule iteratively — plus Compose best-practices to
avoid the findings up front. It's the single source of truth; the per-agent packaging below wraps it.

Claude Code — install as a plugin (bundles the skill + a /compose-doctor command):

/plugin marketplace add rotemmiz/compose-doctor
/plugin install compose-doctor@compose-doctor

Codex · OpenCode · Google Antigravity · Cursor — zero install: all auto-read the root
AGENTS.md, the neutral mirror of the skill. OpenCode also ships the /compose-doctor
command in-repo at .opencode/commands/.

Gemini CLI — install as an extension (bundles the command + AGENTS.md context):

gemini extensions install https://github.com/rotemmiz/compose-doctor

See skills/README.md for all install paths. The skill is self-bootstrapping:
if a module has no composeDoctor task yet, it runs the bundled
init/compose-doctor.init.gradle.kts to apply the plugin
without editing any build file.

The full agent loop, the score.json contract, and the memory/integrity model are specified in
docs/AGENT-HARNESS.md.

How it works

A single self-contained Gradle plugin orchestrates the engines and aggregates their SARIF — it does
not embed detekt-core or reimplement rules. Internally: the scoring package is a pure,
deterministic function; rulemap maps rule IDs to dimensions; the plugin does the wiring, scoring,
and reporting.

Roadmap

  • Publish to the Gradle Plugin Portal. ✅ live as dev.composedoctor.
  • Wire android-lint to populate the Security/Accessibility dimensions.
  • composeDoctorBaseline task to seed detekt's baseline.xml.

License

MIT © 2026 Rotem Meidan

Yorumlar (0)

Sonuc bulunamadi