Skip to content

Commit a770e87

Browse files
aksOpsclaude
andauthored
refactor(plugin): install via marketplace; skill bundle fetched lazily from Maven Central (#1)
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>
1 parent 5ff5db8 commit a770e87

11 files changed

Lines changed: 220 additions & 246 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "sonar-predict",
3+
"owner": {
4+
"name": "Amit Kumar",
5+
"url": "https://github.com/RandomCodeSpace"
6+
},
7+
"plugins": [
8+
{
9+
"name": "sonar-predictor",
10+
"source": "./plugin",
11+
"description": "Offline SonarSource quality gate — runs the genuine SonarSource analyzers locally (no network, no server) to catch bugs, code smells, vulnerabilities and security hotspots. The plugin itself is lightweight (kilobytes); the heavy analyzer bundle is fetched from Maven Central on first invocation and cached locally for every subsequent run.",
12+
"homepage": "https://github.com/RandomCodeSpace/sonar-predict",
13+
"license": "Apache-2.0",
14+
"keywords": [
15+
"code-quality",
16+
"static-analysis",
17+
"sonarsource",
18+
"linter",
19+
"quality-gate",
20+
"offline"
21+
]
22+
}
23+
]
24+
}

.github/workflows/publish.yml

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ name: Publish to Maven Central + GitHub Release
99
# 2. builds, tests, GPG-signs and deploys protocol/daemon/cli to Maven
1010
# Central via the Sonatype Central Portal (the dist module sets
1111
# maven.deploy.skip=true so it is built but never staged),
12-
# 3. creates a GitHub Release carrying three bundles: a whole-repo source
13-
# zip (git archive of HEAD), the assembled skill bundle zip, and the
14-
# assembled plugin bundle zip (the .claude-plugin format installable
15-
# on Claude Code and GitHub Copilot CLI).
12+
# 3. creates a GitHub Release carrying two bundles: a whole-repo source
13+
# zip (git archive of HEAD) and the assembled skill bundle zip. The
14+
# plugin itself is installed via the in-repo /plugin/ directory through
15+
# Claude Code's / Copilot CLI's marketplace (see /.claude-plugin/
16+
# marketplace.json); its skill launcher downloads the analyzer bundle
17+
# on first run from the Maven Central artifact this workflow publishes.
1618
#
1719
# Required repo secrets:
1820
# OSS_NEXUS_USER - Sonatype Central Portal token username
@@ -126,20 +128,6 @@ jobs:
126128
echo "skill_zip=${SKILL_ZIP}" >> "$GITHUB_OUTPUT"
127129
echo "Skill bundle: ${SKILL_ZIP}"
128130
129-
- name: Locate the plugin bundle zip
130-
id: plugin
131-
run: |
132-
set -euo pipefail
133-
VERSION="${{ steps.version.outputs.version }}"
134-
PLUGIN_ZIP="dist/target/sonar-predict-plugin-${VERSION}.zip"
135-
if [ ! -f "${PLUGIN_ZIP}" ]; then
136-
echo "::error::plugin bundle not found at ${PLUGIN_ZIP}"
137-
ls -la dist/target || true
138-
exit 1
139-
fi
140-
echo "plugin_zip=${PLUGIN_ZIP}" >> "$GITHUB_OUTPUT"
141-
echo "Plugin bundle: ${PLUGIN_ZIP}"
142-
143131
- name: Create the GitHub Release
144132
env:
145133
GH_TOKEN: ${{ github.token }}
@@ -148,7 +136,6 @@ jobs:
148136
VERSION="${{ steps.version.outputs.version }}"
149137
SRC_ZIP="sonar-predict-${VERSION}-src.zip"
150138
SKILL_ZIP="${{ steps.bundle.outputs.skill_zip }}"
151-
PLUGIN_ZIP="${{ steps.plugin.outputs.plugin_zip }}"
152139
if [ -n "${GITHUB_REF_NAME:-}" ] && [ "${GITHUB_REF_TYPE:-}" = "tag" ]; then
153140
TAG="${GITHUB_REF_NAME}"
154141
else
@@ -158,5 +145,4 @@ jobs:
158145
--title "sonar-predict ${VERSION}" \
159146
--generate-notes \
160147
"${SRC_ZIP}" \
161-
"${SKILL_ZIP}" \
162-
"${PLUGIN_ZIP}"
148+
"${SKILL_ZIP}"

dist/pom.xml

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -171,37 +171,6 @@
171171
</descriptors>
172172
</configuration>
173173
</execution>
174-
<!-- Exploded plugin bundle at target/plugin/sonar-predictor/.
175-
The .claude-plugin/plugin.json format is shared by
176-
Claude Code and GitHub Copilot CLI, so one bundle
177-
installs in both. Layout: .claude-plugin/, agents/,
178-
skills/sonar-predictor/. -->
179-
<execution>
180-
<id>build-plugin-dir</id>
181-
<phase>package</phase>
182-
<goals><goal>single</goal></goals>
183-
<configuration>
184-
<appendAssemblyId>false</appendAssemblyId>
185-
<finalName>plugin</finalName>
186-
<descriptors>
187-
<descriptor>src/assembly/plugin.xml</descriptor>
188-
</descriptors>
189-
</configuration>
190-
</execution>
191-
<!-- Matching plugin zip:
192-
target/sonar-predict-plugin-<version>.zip. -->
193-
<execution>
194-
<id>build-plugin-zip</id>
195-
<phase>package</phase>
196-
<goals><goal>single</goal></goals>
197-
<configuration>
198-
<appendAssemblyId>false</appendAssemblyId>
199-
<finalName>sonar-predict-plugin-${project.version}</finalName>
200-
<descriptors>
201-
<descriptor>src/assembly/plugin-zip.xml</descriptor>
202-
</descriptors>
203-
</configuration>
204-
</execution>
205174
</executions>
206175
</plugin>
207176
</plugins>

dist/src/assembly/plugin-zip.xml

Lines changed: 0 additions & 85 deletions
This file was deleted.

dist/src/assembly/plugin.xml

Lines changed: 0 additions & 107 deletions
This file was deleted.

dist/src/main/plugin/.claude-plugin/plugin.json renamed to plugin/.claude-plugin/plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sonar-predictor",
3-
"version": "0.1.1",
4-
"description": "Offline SonarSource quality gate — runs the genuine SonarSource analyzers locally (no network, no server) to catch bugs, code smells, vulnerabilities and security hotspots. Bundles the sonar-predictor scanner skill and two named agent variants — invoke `sonar-scanner-claude` on Claude Code (model: haiku) and `sonar-scanner-copilot` on GitHub Copilot CLI (model: gpt-5-mini). Selection is by agent name; neither is implicitly default.",
3+
"version": "0.1.3",
4+
"description": "Offline SonarSource quality gate — runs the genuine SonarSource analyzers locally (no network, no server) to catch bugs, code smells, vulnerabilities and security hotspots. Ships two named scanner agent variants (sonar-scanner-claude on Claude Code, sonar-scanner-copilot on GitHub Copilot CLI) and a thin sonar-predictor skill whose launcher fetches the analyzer bundle (~150 MB) from Maven Central on first invocation and caches it for every subsequent run.",
55
"author": {
66
"name": "Amit Kumar",
77
"url": "https://github.com/RandomCodeSpace"
File renamed without changes.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: sonar-predictor
3+
description: Use after writing or modifying source code, before committing or pushing — runs genuine SonarSource analyzers offline as a fast local quality gate to catch bugs, code smells, vulnerabilities and security hotspots. Also use when the user asks to check code quality, run sonar, or analyze a file or diff.
4+
---
5+
6+
# sonar-predictor
7+
8+
An offline SonarSource pre-push quality gate — runs the genuine analyzers locally, no network, no server.
9+
10+
**Scan-only.** This skill only *scans and reports* — it reads source and emits findings, and never modifies any file. Applying fixes is the calling agent's job, not this tool's; running it is a safe, read-only operation.
11+
12+
Run `./bin/sonar` from this skill's base directory (the folder with this `SKILL.md`), or by its absolute path — it is not on `PATH`. The first invocation downloads the analyzer bundle (~150 MB) from Maven Central into a user cache; every subsequent call runs from that cache with no network. **Read the tool's own help before invoking it:** `./bin/sonar --help` lists the commands and the global options, and `./bin/sonar <command> --help` gives a command's own options and exact argument order. The skill scans a git changeset or explicit files and directories and reports in a chosen format — the help states the precise flags and where each one goes. That generated help is the single source of truth; this `SKILL.md` deliberately does not restate command syntax, which would drift. Do not guess flag names or their placement — read the help.
13+
14+
Exit codes: `0` clean, `1` issues found, `2` tool error.
15+
16+
Acting on findings: fix `BUG`/`VULNERABILITY`/`SECURITY_HOTSPOT` and `CRITICAL`/`MAJOR` first. This is a fast first-pass gate, not the release gate — fix the real issues and move on.
17+
18+
**Air-gapped / pre-staged installs.** Set `SONAR_PREDICTOR_HOME=/path/to/extracted/sonar-predictor` to point the launcher at a pre-downloaded bundle and skip the first-run download.
19+
20+
**Plugin-bundled agent variants.** Two named scanner subagents ship with this plugin: invoke `sonar-scanner-claude` on Claude Code (model: haiku) or `sonar-scanner-copilot` on GitHub Copilot CLI (model: gpt-5-mini). Selection is by agent name — pick the one matching your platform.

0 commit comments

Comments
 (0)