Skip to content

refactor(plugin): install via marketplace; skill bundle fetched lazily from Maven Central#1

Merged
aksOps merged 1 commit into
mainfrom
feat/plugin-as-marketplace
May 23, 2026
Merged

refactor(plugin): install via marketplace; skill bundle fetched lazily from Maven Central#1
aksOps merged 1 commit into
mainfrom
feat/plugin-as-marketplace

Conversation

@aksOps
Copy link
Copy Markdown
Contributor

@aksOps aksOps commented May 23, 2026

Restructures the plugin from a 142 MB build-artifact zip into a git-installed marketplace plugin whose launcher downloads the analyzer bundle from Maven Central on first run.

Install

/plugin marketplace add RandomCodeSpace/sonar-predict
/plugin install sonar-predictor@sonar-predict

Same command on GitHub Copilot CLI; the .claude-plugin format is shared.

Layout

  • /.claude-plugin/marketplace.json — marketplace manifest at repo root
  • /plugin/.claude-plugin/plugin.json — plugin manifest
  • /plugin/agents/sonar-scanner-{claude,copilot}.md — two named scanner variants
  • /plugin/skills/sonar-predictor/SKILL.md — thin; still defers all syntax to --help
  • /plugin/skills/sonar-predictor/bin/sonar{,.bat} — bootstrap that downloads + caches + execs

How the bootstrap works

  1. Resolves cache dir: ${XDG_CACHE_HOME:-~/.cache}/sonar-predictor/<VERSION>/ (or SONAR_PREDICTOR_HOME if set for air-gap).
  2. If cache empty: curl the zip + SHA-1 sidecar from https://repo1.maven.org/maven2/io/github/randomcodespace/sonarpredict/sonar-predictor-dist/<VERSION>/, verify, unzip.
  3. exec the cached bin/sonar with the user's args.

Subsequent invocations skip steps 1-2.

Removed

  • dist/src/assembly/plugin.xml, dist/src/assembly/plugin-zip.xml (the 142 MB plugin assembly).
  • The build-plugin-{dir,zip} executions in dist/pom.xml.
  • The "Locate the plugin bundle zip" step + plugin-zip attach in publish.yml.

The skill bundle assembly stays — that is what Maven Central serves to the bootstrap.

Verified

  • Bootstrap first-run: ./plugin/skills/sonar-predictor/bin/sonar --help downloads v0.1.1 from Maven Central, verifies SHA-1, extracts, and execs --help cleanly.
  • Cache reuse: second run completes in 0.24s with no network.
  • Air-gap override: SONAR_PREDICTOR_HOME=… skips download entirely.

Known issue this release does NOT fix

v0.1.2 on Maven Central is shaped as the now-removed plugin-bundle because the appendAssemblyId=false collision made the plugin-zip become the attached artifact in that build. The bootstrap pins VERSION=0.1.1 — the last good skill bundle. v0.1.3 onward will be skill-shaped again (only the skill assembly remains).

🤖 Generated with Claude Code

…y from Maven Central

The plugin is now installed from git via Claude Code's / GitHub Copilot
CLI's marketplace, not as a Maven-built zip. Its source lives under
/plugin/ in the repo and ships only what is small and immutable per
release: the manifest, two named agent variants, and a thin sonar-predictor
skill whose launcher fetches the heavy analyzer bundle (~150 MB) from
Maven Central on first invocation.

Install
  /plugin marketplace add RandomCodeSpace/sonar-predict
  /plugin install sonar-predictor@sonar-predict

Layout
  /.claude-plugin/marketplace.json         marketplace manifest at repo root
  /plugin/.claude-plugin/plugin.json       plugin manifest
  /plugin/agents/                          two named scanner variants
  /plugin/skills/sonar-predictor/SKILL.md
  /plugin/skills/sonar-predictor/bin/sonar       bootstrap (bash)
  /plugin/skills/sonar-predictor/bin/sonar.bat   bootstrap (Windows)

The bootstrap downloads sonar-predictor-dist-<VERSION>.zip from Maven
Central into ${XDG_CACHE_HOME:-~/.cache}/sonar-predictor/<VERSION>/,
verifies its SHA-1 sidecar, unpacks it, and exec's the cached launcher.
Every subsequent call runs from cache with no network. Air-gapped or
pre-staged installs override the cache location with SONAR_PREDICTOR_HOME.
The pinned VERSION is bumped in lockstep with each plugin release.

Removed: the dist module's plugin assembly (dist/src/assembly/plugin*.xml
and the build-plugin-{dir,zip} executions) plus the publish workflow's
plugin-bundle attach step. The skill bundle assembly stays; it is what
Maven Central serves to the bootstrap.

Currently the bootstrap pins VERSION=0.1.1, the last bundle on Maven
Central that was actually shaped as a skill. v0.1.2's dist artifact on
Central is the (now-removed) plugin-bundle shape because the assembly's
appendAssemblyId=false collision made the plugin-zip become the attached
artifact in that release. v0.1.3 onward will be skill-shaped again.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@aksOps aksOps merged commit a770e87 into main May 23, 2026
9 checks passed
aksOps added a commit that referenced this pull request May 23, 2026
…y licenses

Builds on the marketplace restructure (#1). Changes:

1. Externalize launcher knobs into plugin/skills/sonar-predictor/config.env
   - SONAR_MAVEN_REPO_URL    Maven proxy where the analyzer bundle is fetched
   - SONAR_BUNDLE_VERSION    Bundle version pin (default: 0.1.1)
   - SONAR_MIN_JAVA_VERSION  Minimum Java major required (default: 17)
   - SONAR_JRE_URL_TEMPLATE  JRE source for auto-download; tokens {os} {arch}
                             {version} are substituted (default: Adoptium API)
   - SONAR_JRE_VERSION       JRE version to fetch (default: 17)
   - SONAR_DISABLE_JRE_AUTODOWNLOAD  Set to 1 to refuse the JRE auto-download

   Plain KEY=VALUE format parsed by both bash and Windows launchers. Env vars
   of the same name take precedence over the file (one-off override without
   editing). Forking workflow: clone, edit config.env, push, install.

2. Bash launcher gains a 'no Java anywhere -> download a JRE' step that runs
   after the bundle is cached. Searches $JAVA_HOME, PATH, and the same common
   install dirs the bundle's own launcher probes; if nothing meets the
   minimum, substitutes {os}/{arch}/{version} into SONAR_JRE_URL_TEMPLATE,
   downloads, extracts to ~/.cache/sonar-predictor/jre/<VERSION>/, and exports
   JAVA_HOME for the bundle launcher to pick up.

   Windows launcher reads the same config.env but still requires Java 17+ on
   the system (or in JAVA_HOME). Auto-install on Windows is deferred.

3. Refresh README.md and dist/README.md for the marketplace install path:
   - Quick-start is now the two-command marketplace install (Claude + Copilot)
   - Add a 'Corporate / air-gapped setup' section documenting config.env
     and SONAR_PREDICTOR_HOME for fully pre-staged installs
   - Expand the License section into 'License & third-party components' with
     the SonarSource analyzer license situation called out honestly

4. Add NOTICE listing third-party components and their licenses:
   - sonarlint-analysis-engine — LGPL v3
   - SonarSource language analyzers — SONAR Source-Available License v1.0
     (SSALv1) since SonarSource's 2024 relicense
   - Apache 2.0 build / runtime dependencies (picocli, jackson, maven plugins)
   - Adoptium Temurin JRE — GPL-2.0 WITH Classpath-exception-2.0

   NOTICE also documents the future direction: have the bootstrap fetch each
   analyzer JAR individually from Maven Central instead of bundling them into
   the dist artifact. That eliminates any SSALv1 redistribution question
   (SonarSource's own Maven Central distribution becomes the sole channel).
   The plugin's config.env already isolates the Maven URL, so the transition
   is transparent to corporate proxies.

Smoke-tested end to end:
  - default config: bundle from Maven Central, system Java used.
  - SONAR_MAVEN_REPO_URL=bogus env override correctly steered the download
    (failed at DNS as expected) — env-var precedence confirmed.
  - SONAR_MIN_JAVA_VERSION=99 forced the JRE auto-install path; Adoptium
    Temurin 17.0.19 downloaded and ran.
  - SONAR_DISABLE_JRE_AUTODOWNLOAD=1 blocked the install with the right error.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
aksOps added a commit that referenced this pull request May 23, 2026
…onfig.env (#2)

* feat(plugin): config-driven launcher; refresh docs; NOTICE third-party licenses

Builds on the marketplace restructure (#1). Changes:

1. Externalize launcher knobs into plugin/skills/sonar-predictor/config.env
   - SONAR_MAVEN_REPO_URL    Maven proxy where the analyzer bundle is fetched
   - SONAR_BUNDLE_VERSION    Bundle version pin (default: 0.1.1)
   - SONAR_MIN_JAVA_VERSION  Minimum Java major required (default: 17)
   - SONAR_JRE_URL_TEMPLATE  JRE source for auto-download; tokens {os} {arch}
                             {version} are substituted (default: Adoptium API)
   - SONAR_JRE_VERSION       JRE version to fetch (default: 17)
   - SONAR_DISABLE_JRE_AUTODOWNLOAD  Set to 1 to refuse the JRE auto-download

   Plain KEY=VALUE format parsed by both bash and Windows launchers. Env vars
   of the same name take precedence over the file (one-off override without
   editing). Forking workflow: clone, edit config.env, push, install.

2. Bash launcher gains a 'no Java anywhere -> download a JRE' step that runs
   after the bundle is cached. Searches $JAVA_HOME, PATH, and the same common
   install dirs the bundle's own launcher probes; if nothing meets the
   minimum, substitutes {os}/{arch}/{version} into SONAR_JRE_URL_TEMPLATE,
   downloads, extracts to ~/.cache/sonar-predictor/jre/<VERSION>/, and exports
   JAVA_HOME for the bundle launcher to pick up.

   Windows launcher reads the same config.env but still requires Java 17+ on
   the system (or in JAVA_HOME). Auto-install on Windows is deferred.

3. Refresh README.md and dist/README.md for the marketplace install path:
   - Quick-start is now the two-command marketplace install (Claude + Copilot)
   - Add a 'Corporate / air-gapped setup' section documenting config.env
     and SONAR_PREDICTOR_HOME for fully pre-staged installs
   - Expand the License section into 'License & third-party components' with
     the SonarSource analyzer license situation called out honestly

4. Add NOTICE listing third-party components and their licenses:
   - sonarlint-analysis-engine — LGPL v3
   - SonarSource language analyzers — SONAR Source-Available License v1.0
     (SSALv1) since SonarSource's 2024 relicense
   - Apache 2.0 build / runtime dependencies (picocli, jackson, maven plugins)
   - Adoptium Temurin JRE — GPL-2.0 WITH Classpath-exception-2.0

   NOTICE also documents the future direction: have the bootstrap fetch each
   analyzer JAR individually from Maven Central instead of bundling them into
   the dist artifact. That eliminates any SSALv1 redistribution question
   (SonarSource's own Maven Central distribution becomes the sole channel).
   The plugin's config.env already isolates the Maven URL, so the transition
   is transparent to corporate proxies.

Smoke-tested end to end:
  - default config: bundle from Maven Central, system Java used.
  - SONAR_MAVEN_REPO_URL=bogus env override correctly steered the download
    (failed at DNS as expected) — env-var precedence confirmed.
  - SONAR_MIN_JAVA_VERSION=99 forced the JRE auto-install path; Adoptium
    Temurin 17.0.19 downloaded and ran.
  - SONAR_DISABLE_JRE_AUTODOWNLOAD=1 blocked the install with the right error.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(plugin): add agent-scan subcommand that writes JSON to a file and returns a pointer

A new `./bin/sonar agent-scan [scope]` wrapper in the plugin's bootstrap
that bakes the out-of-context discipline into the tool, replacing the
"agent must remember to redirect to a temp file + jq" pattern.

  ./bin/sonar agent-scan                          -> git changeset (default)
  ./bin/sonar agent-scan check src/Main.java      -> specific files
  ./bin/sonar agent-scan analyze src/             -> whole directory

On invocation:
  1. Ensures .sonar-predictor/ exists at the project root.
  2. If inside a git repo, appends .sonar-predictor/ to .gitignore on first
     use (with a comment header). Idempotent — re-runs do nothing.
  3. Runs `sonar --format json <scope>`, redirecting stdout+stderr to
     .sonar-predictor/scan.json.
  4. Prints a compact summary on stdout: total issue count, severity
     breakdown, and the file path. Example:

       sonar-predictor: 47 issues written to .sonar-predictor/scan.json
         severity: BLOCKER=3 CRITICAL=12 MAJOR=22 MINOR=8 INFO=2
         query: jq '...' .sonar-predictor/scan.json

  5. Propagates the underlying CLI's exit code (0 clean, 1 issues, 2 error).

The summary uses jq when available; if not, falls back to a plain pointer.

Both agent variants (sonar-scanner-claude, sonar-scanner-copilot) now invoke
`agent-scan` instead of the manual redirect+jq dance. Their prompts retain
the jq drill-down recipe for when the orchestrator asks for specifics — the
file is right there, the recipe stays cheap.

SKILL.md declares the agent-scan contract as the canonical agent invocation
pattern. The repo's own .gitignore gains a .sonar-predictor/ entry so
dogfooding scans against this repo never get committed.

Windows .bat gets parity for the subcommand: writes the file, gitignores the
path, prints a pointer. No jq-based summary on Windows (jq isn't typically
on PATH); just the pointer.

Smoke-tested: agent-scan in this git repo wrote a 0-issue scan.json (116
bytes), exit 0, stdout summary correct, .gitignore unchanged because the
line was already present (the idempotent guard works).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant