@codyswann/lisa 2.296.0 → 2.297.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.
- package/dist/cli/doctor-sonar.d.ts +15 -0
- package/dist/cli/doctor-sonar.d.ts.map +1 -0
- package/dist/cli/doctor-sonar.js +28 -0
- package/dist/cli/doctor-sonar.js.map +1 -0
- package/dist/cli/doctor.d.ts +2 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +4 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/core/learnings-contract.d.ts +23 -1
- package/dist/core/learnings-contract.d.ts.map +1 -1
- package/dist/core/learnings-contract.js +26 -2
- package/dist/core/learnings-contract.js.map +1 -1
- package/dist/core/lisa.d.ts +13 -0
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +44 -0
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/project-config-kane.d.ts +9 -0
- package/dist/core/project-config-kane.d.ts.map +1 -1
- package/dist/core/project-config-kane.js +35 -3
- package/dist/core/project-config-kane.js.map +1 -1
- package/dist/core/sonar-integration.d.ts +30 -0
- package/dist/core/sonar-integration.d.ts.map +1 -0
- package/dist/core/sonar-integration.js +55 -0
- package/dist/core/sonar-integration.js.map +1 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +26 -5
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/sonar/sonar-installer.d.ts +19 -0
- package/dist/sonar/sonar-installer.d.ts.map +1 -0
- package/dist/sonar/sonar-installer.js +69 -0
- package/dist/sonar/sonar-installer.js.map +1 -0
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-analyze-claude-remote/SKILL.md +6 -6
- package/plugins/lisa/.codex-plugin/skills/lisa-generate-claude-remote-build-script/SKILL.md +14 -6
- package/plugins/lisa/.codex-plugin/skills/lisa-persist-learning/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-sonar/SKILL.md +108 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-sonar/agents/openai.yaml +4 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-sonarcloud-access/SKILL.md +51 -46
- package/plugins/lisa/commands/setup/sonar.md +7 -0
- package/plugins/lisa/rules/reference/integration-access-layer.md +10 -2
- package/plugins/lisa/skills/lisa-analyze-claude-remote/SKILL.md +6 -6
- package/plugins/lisa/skills/lisa-generate-claude-remote-build-script/SKILL.md +14 -6
- package/plugins/lisa/skills/lisa-persist-learning/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-setup-sonar/SKILL.md +108 -0
- package/plugins/lisa/skills/lisa-setup-sonar/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/lisa-sonarcloud-access/SKILL.md +52 -47
- package/plugins/lisa/skills/lisa-sonarcloud-access/agents/openai.yaml +2 -2
- package/plugins/lisa-agy/commands/lisa/setup/sonar.md +7 -0
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-analyze-claude-remote/SKILL.md +6 -6
- package/plugins/lisa-agy/skills/lisa-generate-claude-remote-build-script/SKILL.md +14 -6
- package/plugins/lisa-agy/skills/lisa-persist-learning/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-setup-sonar/SKILL.md +108 -0
- package/plugins/lisa-agy/skills/lisa-sonarcloud-access/SKILL.md +52 -47
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/commands/lisa/setup/sonar.md +7 -0
- package/plugins/lisa-copilot/rules/reference/integration-access-layer.md +10 -2
- package/plugins/lisa-copilot/skills/lisa-analyze-claude-remote/SKILL.md +6 -6
- package/plugins/lisa-copilot/skills/lisa-generate-claude-remote-build-script/SKILL.md +14 -6
- package/plugins/lisa-copilot/skills/lisa-persist-learning/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-setup-sonar/SKILL.md +108 -0
- package/plugins/lisa-copilot/skills/lisa-sonarcloud-access/SKILL.md +52 -47
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/commands/lisa/setup/sonar.md +7 -0
- package/plugins/lisa-cursor/rules/integration-access-layer-reference.mdc +10 -2
- package/plugins/lisa-cursor/skills/lisa-analyze-claude-remote/SKILL.md +6 -6
- package/plugins/lisa-cursor/skills/lisa-generate-claude-remote-build-script/SKILL.md +14 -6
- package/plugins/lisa-cursor/skills/lisa-persist-learning/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-setup-sonar/SKILL.md +108 -0
- package/plugins/lisa-cursor/skills/lisa-sonarcloud-access/SKILL.md +52 -47
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/commands/setup/sonar.md +7 -0
- package/plugins/src/base/rules/reference/integration-access-layer.md +10 -2
- package/plugins/src/base/skills/lisa-analyze-claude-remote/SKILL.md +6 -6
- package/plugins/src/base/skills/lisa-generate-claude-remote-build-script/SKILL.md +14 -6
- package/plugins/src/base/skills/lisa-persist-learning/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-setup-sonar/SKILL.md +108 -0
- package/plugins/src/base/skills/lisa-sonarcloud-access/SKILL.md +52 -47
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lisa-setup-sonar
|
|
3
|
+
description: "Configure the official SonarQube plugin + MCP as Lisa's single Sonar substrate across every supported coding agent. Installs/updates the SonarQube CLI, authenticates (browser login on a dev machine, or SONARQUBE_TOKEN headless), selects the Test Manager target, runs `sonar integrate <agent>` for each supported agent (Claude, Codex, Cursor, Copilot, Antigravity) and wires the MCP for OpenCode, then writes only non-secret policy to .lisa.config.json. Separate from the CI SonarCloud scan gate, which is unchanged."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Write", "Edit", "AskUserQuestion", "Skill"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Set up SonarQube (official plugin + MCP)
|
|
8
|
+
|
|
9
|
+
This is an explicit exterior setup gate. Run it **outside** any active Build, QA,
|
|
10
|
+
Monitor, or Verify factory — authentication and MCP wiring must be complete before
|
|
11
|
+
unattended factories run. It replaces Lisa's former hand-rolled SonarCloud REST
|
|
12
|
+
access with the vendor's official token-authed MCP, which is Lisa's single Sonar
|
|
13
|
+
substrate on both developer machines and headless cloud routines.
|
|
14
|
+
|
|
15
|
+
This does **not** touch the CI SonarCloud SAST job in `quality.yml` or its
|
|
16
|
+
`SONAR_TOKEN` secret — that enforcement gate is separate and stays as-is.
|
|
17
|
+
|
|
18
|
+
## Supported agents
|
|
19
|
+
|
|
20
|
+
Wire only Lisa's supported agents: **Claude Code, Codex, Cursor, GitHub Copilot,
|
|
21
|
+
Antigravity (agy)** via `sonar integrate <agent>`, and **OpenCode** via its MCP
|
|
22
|
+
config. **Never** wire Kiro or Gemini CLI even though the vendor supports them —
|
|
23
|
+
they are not Lisa-supported agents.
|
|
24
|
+
|
|
25
|
+
## 1. Install or update the SonarQube CLI
|
|
26
|
+
|
|
27
|
+
Check `sonar` on PATH (`command -v sonar`). If present, update it (`sonar
|
|
28
|
+
self-update`, or the package manager that owns it); if absent, install it and ask
|
|
29
|
+
for confirmation before running the install:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# macOS/Linux (script) — default, works everywhere
|
|
33
|
+
curl -o- https://raw.githubusercontent.com/SonarSource/sonarqube-cli/refs/heads/master/user-scripts/install.sh | bash
|
|
34
|
+
# or Homebrew: brew install --cask sonarqube-cli
|
|
35
|
+
# or mise: mise use -g aqua:SonarSource/sonarqube-cli
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
A container runtime (Docker/Podman/Nerdctl) must be installed and running — the
|
|
39
|
+
MCP runs as a container via `sonar run mcp`. Probe with `docker ps` (falling back
|
|
40
|
+
to `podman ps` / `nerdctl ps`). If none succeed, tell the operator to start it and
|
|
41
|
+
note the agent session must restart afterward for the MCP tools to load.
|
|
42
|
+
|
|
43
|
+
## 2. Authenticate — token for factories, login for dev machines
|
|
44
|
+
|
|
45
|
+
The MCP authenticates from environment variables — this is the headless path and
|
|
46
|
+
the one factories use. **Never** write credentials to `.lisa.config.json` or
|
|
47
|
+
`.lisa.config.local.json`; provide them as environment variables / CI secrets:
|
|
48
|
+
|
|
49
|
+
- `SONARQUBE_TOKEN` — required.
|
|
50
|
+
- `SONARQUBE_ORG` — for SonarQube Cloud.
|
|
51
|
+
- `SONARQUBE_URL` — for a self-hosted SonarQube Server.
|
|
52
|
+
|
|
53
|
+
On an interactive developer machine you may instead run `sonar auth login`
|
|
54
|
+
(browser flow; token stored in the OS keychain). Do **not** use the keychain flow
|
|
55
|
+
for headless/cloud-routine environments — provision the env token there instead
|
|
56
|
+
(see `/lisa:generate-claude-remote-build-script`, which now installs the CLI,
|
|
57
|
+
pre-pulls the MCP image, and sets `SONARQUBE_TOKEN`). Verify with `sonar auth
|
|
58
|
+
status`; record the identity label only, never token material.
|
|
59
|
+
|
|
60
|
+
## 3. Select the Test Manager target
|
|
61
|
+
|
|
62
|
+
Use `sonar config project` (and optional `sonar config folder`), then `sonar
|
|
63
|
+
config show`. Capture the non-secret project/organization identifiers.
|
|
64
|
+
|
|
65
|
+
## 4. Integrate per supported agent
|
|
66
|
+
|
|
67
|
+
Confirm the target scope (single-choice: current project / global), then for each
|
|
68
|
+
supported agent detected on PATH run its non-interactive integrate:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
sonar integrate claude --non-interactive
|
|
72
|
+
sonar integrate codex --non-interactive
|
|
73
|
+
sonar integrate cursor --non-interactive
|
|
74
|
+
sonar integrate copilot --non-interactive
|
|
75
|
+
sonar integrate antigravity --non-interactive
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For **OpenCode** (no vendor integrate path), wire the MCP through OpenCode's own
|
|
79
|
+
MCP config so it launches `sonar run mcp`, authenticated from the same env token.
|
|
80
|
+
|
|
81
|
+
Skip any agent whose CLI is not installed; never wire Kiro or Gemini.
|
|
82
|
+
|
|
83
|
+
## 5. Write non-secret policy config
|
|
84
|
+
|
|
85
|
+
Merge only non-secret identifiers into committed `.lisa.config.json`, preserving
|
|
86
|
+
every unrelated key (never credentials):
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"verification": {
|
|
91
|
+
"sonar": {
|
|
92
|
+
"enabled": true,
|
|
93
|
+
"edition": "cloud",
|
|
94
|
+
"organization": "<org-key>",
|
|
95
|
+
"projectKey": "<project-key>"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Use `"edition": "server"` with a `"serverUrl"` for a self-hosted Server.
|
|
102
|
+
|
|
103
|
+
## 6. Prove readiness
|
|
104
|
+
|
|
105
|
+
Run the `lisa-sonarcloud-access` probe (an `mcp__sonarqube__*` project search) and
|
|
106
|
+
confirm a `mcp__sonarqube__*` tool answers. Then run `lisa doctor` and confirm the
|
|
107
|
+
Sonar provider check is green. If the MCP tools do not appear, verify the container
|
|
108
|
+
runtime is running and restart the agent session.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
display_name: "Setup Sonar"
|
|
2
|
+
short_description: "Configure the official SonarQube plugin + MCP as Lisa's single Sonar substrate across every supported coding agent"
|
|
3
|
+
default_prompt:
|
|
4
|
+
- "Use $lisa-setup-sonar: Configure the official SonarQube plugin + MCP as Lisa's single Sonar substrate across every supported coding agent."
|
|
@@ -1,71 +1,76 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lisa-sonarcloud-access
|
|
3
|
-
description: "Vendor-neutral access layer for
|
|
3
|
+
description: "Vendor-neutral access layer for SonarQube Cloud/Server. Sonar triage skills MUST delegate through this skill rather than calling the SonarQube MCP tools directly. Single substrate: the official SonarQube MCP server (mcp__sonarqube__*), authenticated headlessly from SONARQUBE_TOKEN (+ SONARQUBE_ORG for Cloud, SONARQUBE_URL for Server)."
|
|
4
4
|
allowed-tools: ["Bash", "Read", "Skill"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# SonarCloud Access: $ARGUMENTS
|
|
8
8
|
|
|
9
|
-
Single chokepoint for
|
|
10
|
-
`mcp__sonarqube__*` tools directly
|
|
11
|
-
|
|
9
|
+
Single chokepoint for Sonar quality and security data. Caller skills MUST NOT
|
|
10
|
+
invoke `mcp__sonarqube__*` tools directly; they ask for data by operation name and
|
|
11
|
+
this skill owns the tool selection.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Substrate
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
operation: rule-detail key:<RULE_KEY>
|
|
20
|
-
operation: source-snippet component:<COMPONENT_KEY> from:<N> to:<N>
|
|
21
|
-
```
|
|
15
|
+
There is exactly one substrate: the **official SonarQube MCP server**, provided by
|
|
16
|
+
the `sonarqube` plugin and launched by the `sonar` CLI (`sonar run mcp`). It
|
|
17
|
+
authenticates headlessly from environment variables — no browser, no OS keychain —
|
|
18
|
+
so it is the same substrate on a developer machine and in a headless cloud routine:
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
- `SONARQUBE_TOKEN` — required (Sonar user/analysis token).
|
|
21
|
+
- `SONARQUBE_ORG` — required for SonarQube Cloud.
|
|
22
|
+
- `SONARQUBE_URL` — required for a self-hosted SonarQube Server.
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
Wiring is performed once by `/lisa:setup:sonar` (which drives `sonar integrate
|
|
25
|
+
<agent>`); this access layer assumes the MCP is already wired. This is distinct
|
|
26
|
+
from the CI `SONAR_TOKEN` secret that authenticates the SonarCloud scan job in
|
|
27
|
+
`quality.yml` — that gate is separate and unchanged.
|
|
26
28
|
|
|
27
|
-
Probe
|
|
29
|
+
## Probe (tool-access-gate)
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
Prove access with a cheap read-only MCP call before relying on it — the `sonar` CLI
|
|
32
|
+
being on PATH is not access. Probe by searching projects (the `projects` toolset is
|
|
33
|
+
always enabled):
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
- If a `mcp__sonarqube__*` project-search tool returns, access is proven.
|
|
36
|
+
- If no `mcp__sonarqube__*` tool is present, or the call fails authentication, fail
|
|
37
|
+
loudly and do not improvise a substitute:
|
|
33
38
|
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
local path="$1"
|
|
37
|
-
[ -n "$SONAR_TOKEN" ] || {
|
|
38
|
-
echo "Error: SONAR_TOKEN is not set." >&2
|
|
39
|
-
return 1
|
|
40
|
-
}
|
|
41
|
-
curl -sS "https://sonarcloud.io/api${path}" \
|
|
42
|
-
-H "Authorization: Bearer $SONAR_TOKEN"
|
|
43
|
-
}
|
|
39
|
+
```text
|
|
40
|
+
Error: no SonarQube access. Run /lisa:setup:sonar (or `sonar integrate <agent>`), and set SONARQUBE_TOKEN (+ SONARQUBE_ORG for Cloud / SONARQUBE_URL for Server).
|
|
44
41
|
```
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
There is no hand-rolled REST fallback: the official MCP is headless-capable via the
|
|
44
|
+
token env vars, so it is the only sanctioned substrate. A missing MCP is a
|
|
45
|
+
tool-access-gate failure to surface, not a reason to curl the Web API.
|
|
48
46
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```text
|
|
52
|
-
Error: no SonarCloud access substrate available. Authenticate the Sonar MCP or set SONAR_TOKEN.
|
|
53
|
-
```
|
|
47
|
+
## Operation → toolset map
|
|
54
48
|
|
|
55
|
-
|
|
49
|
+
Consumers pass a coarse, vendor-native operation; resolve it with the matching
|
|
50
|
+
`mcp__sonarqube__*` tool from the named toolset and return parsed JSON in a
|
|
51
|
+
`<result>` block.
|
|
56
52
|
|
|
57
|
-
| Operation |
|
|
53
|
+
| Operation | SonarQube MCP toolset |
|
|
58
54
|
|---|---|
|
|
59
|
-
| `gate-status` |
|
|
60
|
-
| `issues` |
|
|
61
|
-
| `hotspots` |
|
|
62
|
-
| `rule-detail` |
|
|
63
|
-
| `source-snippet` |
|
|
55
|
+
| `gate-status` | `quality-gates` |
|
|
56
|
+
| `issues` | `issues` |
|
|
57
|
+
| `hotspots` | `security-hotspots` |
|
|
58
|
+
| `rule-detail` | `rules` |
|
|
59
|
+
| `source-snippet` | `cag` (context augmentation) / component source |
|
|
60
|
+
| `coverage` | `coverage` |
|
|
61
|
+
| `duplication` | `duplications` |
|
|
62
|
+
| `dependency-risks` | `dependency-risks` |
|
|
63
|
+
| `projects` | `projects` |
|
|
64
|
+
|
|
65
|
+
Pass the project key through the tool's `projectKey` argument (or rely on a
|
|
66
|
+
server-configured `SONARQUBE_PROJECT_KEY`); pass `branch` / `pullRequest` where the
|
|
67
|
+
tool accepts them.
|
|
64
68
|
|
|
65
69
|
## Invariants
|
|
66
70
|
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
-
|
|
71
|
-
|
|
71
|
+
- The official SonarQube MCP is the only substrate; there is no REST fallback.
|
|
72
|
+
- Auth is env-var only (`SONARQUBE_TOKEN` [+ `SONARQUBE_ORG` | `SONARQUBE_URL`]);
|
|
73
|
+
never the interactive `sonar auth login` keychain flow inside a factory.
|
|
74
|
+
- Sonar host access requires the host (`sonarcloud.io`, `sonarqube.us`, or the
|
|
75
|
+
Server URL) in any custom remote-network allowlist.
|
|
76
|
+
- Consumers ask for data by operation name; this skill owns tool selection.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
display_name: "SonarCloud Access"
|
|
2
|
-
short_description: "Vendor-neutral access layer for
|
|
2
|
+
short_description: "Vendor-neutral access layer for SonarQube Cloud/Server"
|
|
3
3
|
default_prompt:
|
|
4
|
-
- "Use $lisa-sonarcloud-access: Vendor-neutral access layer for
|
|
4
|
+
- "Use $lisa-sonarcloud-access: Vendor-neutral access layer for SonarQube Cloud/Server."
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Wire the official SonarQube plugin + MCP into this project across every supported coding agent. Installs/updates the SonarQube CLI, authenticates (browser login on a dev machine, or SONARQUBE_TOKEN headless), selects the Test Manager target, runs `sonar integrate <agent>` for each supported agent, and writes only non-secret policy to `.lisa.config.json`. Does not touch the separate CI SonarCloud scan gate."
|
|
3
|
+
allowed-tools: ["Skill"]
|
|
4
|
+
argument-hint: "[--org=<org-key>] [--server-url=<url>] [--global]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Use the /lisa-setup-sonar skill to wire the official SonarQube MCP for this project across every supported agent. $ARGUMENTS
|
|
@@ -195,7 +195,7 @@ Group the findings as:
|
|
|
195
195
|
| Match | Substrate | Env | Setup / wiring | Domains |
|
|
196
196
|
|---|---|---|---|---|
|
|
197
197
|
| `mcp.jam.dev`, `jam`, or Jam MCP entries | Jam CLI (`jam`) authenticated by PAT | `JAM_PAT` | install with `curl -fsSL https://native.jam.dev/install | bash`; export `~/.local/bin`; run `printf '%s' "$JAM_PAT" | jam auth login --token`; optionally `jam skills install` | `native.jam.dev`, `api.jam.dev` |
|
|
198
|
-
| `mcp/sonarqube`, `sonarqube`, or SonarCloud
|
|
198
|
+
| `mcp/sonarqube`, `sonarqube`, or SonarQube/SonarCloud MCP entries | Official SonarQube MCP (`sonar run mcp`), token-authed — runs headless as-is, no REST substitute | `SONARQUBE_TOKEN` (+ `SONARQUBE_ORG` for Cloud / `SONARQUBE_URL` for Server) | install the SonarQube CLI (`curl -o- https://raw.githubusercontent.com/SonarSource/sonarqube-cli/refs/heads/master/user-scripts/install.sh \| bash`) and `sonar integrate <agent>`; pre-pull the MCP container image in the setup script so it fits the cache budget; the MCP authenticates from the env token — never `sonar auth login` | `sonarcloud.io`, `sonarqube.us` (or the Server URL) |
|
|
199
199
|
|
|
200
200
|
For PAT-bearer MCP substrates that really use the same MCP transport, include `mcpHeaders` in
|
|
201
201
|
the inventory with a snippet such as `headers: { "Authorization": "Bearer ${VAR}" }` so the
|
|
@@ -353,17 +353,17 @@ so the generator can render acquisition comments into its template:
|
|
|
353
353
|
"setupSnippet": "curl -fsSL https://native.jam.dev/install | bash; export PATH=\"$HOME/.local/bin:$PATH\"; printf '%s' \"$JAM_PAT\" | jam auth login --token; jam skills install"
|
|
354
354
|
},
|
|
355
355
|
{
|
|
356
|
-
"name": "
|
|
357
|
-
"reason": "
|
|
358
|
-
"headlessSubstrate": "
|
|
356
|
+
"name": "SONARQUBE_TOKEN", "required": false, "secret": true, "integration": "sonarcloud",
|
|
357
|
+
"reason": "authenticates the official SonarQube MCP headlessly; the MCP runs as-is in a cloud routine (Docker is preinstalled), so no REST substitute is needed",
|
|
358
|
+
"headlessSubstrate": "Official SonarQube MCP (token-authed)",
|
|
359
359
|
"acquireUrl": "https://docs.sonarsource.com/sonarqube-cloud/managing-your-account/managing-tokens",
|
|
360
|
-
"accessScope": "token must be able to read the target
|
|
360
|
+
"accessScope": "token must be able to read the target Sonar organization/project quality gate, issues, hotspots, rules, coverage, duplications, and dependency risks; add SONARQUBE_ORG (Cloud) or SONARQUBE_URL (Server)"
|
|
361
361
|
}
|
|
362
362
|
],
|
|
363
363
|
"mcp": [
|
|
364
364
|
{ "name": "linear-server", "transport": "http", "auth": "oauth", "headlessUsable": false, "replacedBy": "LINEAR_API_KEY + Linear GraphQL", "dormant": true },
|
|
365
365
|
{ "name": "jam", "transport": "http", "auth": "oauth", "headlessUsable": true, "replacedBy": "jam CLI + JAM_PAT", "dormant": true },
|
|
366
|
-
{ "name": "sonarqube", "transport": "stdio", "auth": "
|
|
366
|
+
{ "name": "sonarqube", "transport": "stdio", "auth": "env-token", "headlessUsable": true, "replacedBy": null, "dormant": true }
|
|
367
367
|
],
|
|
368
368
|
"awsProfiles": [
|
|
369
369
|
{
|
|
@@ -69,9 +69,9 @@ tracker/source, plus the host project's own package manager and tooling — not
|
|
|
69
69
|
sibling repos reachable through the routine's GitHub proxy.
|
|
70
70
|
For OPTIONAL non-tracker MCP recovery entries discovered by
|
|
71
71
|
`/lisa:analyze-claude-remote`, preserve the same names-only behavior:
|
|
72
|
-
include `JAM_PAT`, `
|
|
73
|
-
only as optional secrets, with their
|
|
74
|
-
supplied them. Never invent values or promote dormant substrates to required.
|
|
72
|
+
include `JAM_PAT`, `SONARQUBE_TOKEN` (+ `SONARQUBE_ORG`/`SONARQUBE_URL`), or
|
|
73
|
+
similar documented substrate env vars only as optional secrets, with their
|
|
74
|
+
acquire/scope comments when the analysis supplied them. Never invent values or promote dormant substrates to required.
|
|
75
75
|
When AWS entries are present, list only `LISA_AWS_BOOTSTRAP_JSON` as the
|
|
76
76
|
required secret and `LISA_REMOTE_AGENT=claude` as plain configuration. Never
|
|
77
77
|
emit standard `AWS_ACCESS_KEY_ID` variables and never recommend `aws sso login`.
|
|
@@ -84,9 +84,17 @@ tracker/source, plus the host project's own package manager and tooling — not
|
|
|
84
84
|
`export PATH="$HOME/.local/bin:$PATH"`, `printf '%s' "$JAM_PAT" | jam auth login --token`,
|
|
85
85
|
and `jam skills install`, all inside `[ -n "${JAM_PAT:-}" ] && ...` guards so missing
|
|
86
86
|
optional secrets do not fail the environment build.
|
|
87
|
-
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
- Container-backed MCP substrates (e.g. the official SonarQube MCP): the MCP
|
|
88
|
+
runs headless as-is in a cloud routine — Docker is preinstalled — so wire the
|
|
89
|
+
real MCP rather than substituting REST. Emit, guarded on the optional env
|
|
90
|
+
token, the vendor CLI install (`curl -o- https://raw.githubusercontent.com/SonarSource/sonarqube-cli/refs/heads/master/user-scripts/install.sh | bash`),
|
|
91
|
+
`sonar integrate <agent>`, and a `sonar run mcp`-image pre-pull so the first
|
|
92
|
+
run fits the ~5-min cache budget. Provide `SONARQUBE_TOKEN`
|
|
93
|
+
(+ `SONARQUBE_ORG`/`SONARQUBE_URL`); never emit `sonar auth login` (keychain
|
|
94
|
+
does not exist headless).
|
|
95
|
+
- REST-only substitute substrates: for a vendor whose MCP genuinely cannot run
|
|
96
|
+
headless, do not install an MCP — emit comments naming the REST host and env
|
|
97
|
+
var, and rely on the access skill or generated consumer to call the API.
|
|
90
98
|
- PAT-bearer MCP substrates: print a commented `.mcp.json` `headers` snippet from the
|
|
91
99
|
inventory's `mcpHeaders`. Use this only when the analysis explicitly says the same MCP
|
|
92
100
|
transport supports static-token auth. Do not print a Jam `.mcp.json` header snippet because
|
|
@@ -174,6 +174,20 @@ No learning content is ever committed without a PR — there is no other write p
|
|
|
174
174
|
- **Related entry found** → consolidate via `persistConsolidatedLearning(projectRoot, entry, { supersede: [<related ids>] })`, merging the old entry's still-true content into the new rule. Never append a near-duplicate sibling — a sibling is a bug that fails review.
|
|
175
175
|
- **No related entry** → append via `persistLearningEntry(projectRoot, entry)` and state in the PR body why appending was correct.
|
|
176
176
|
- Entry mapping: `id` = the fingerprint; `rule`/`why`/`provenance` from the candidate; `first_learned` = `last_confirmed` = today (ISO date; on consolidation keep the superseded entry's earliest `first_learned`); `confidence` = the judge's `high`/`low`. The writer re-asserts the entry and token budgets — an over-budget failure means consolidate harder or drop, never truncate by hand.
|
|
177
|
+
- **On a budget-forced drop, signal saturation once (never silent).** When the writer's budget re-assertion cannot fit the entry even after consolidating harder — a durable capture has to be DROPPED for budget — the ledger is saturated, and that pressure must be visible to an operator instead of swallowed. Emit **exactly one** tracker signal via `lisa-tracker-write` (`issue_type: Task`; GitHub trackers carry the `type:Task` label), then continue — dropping the capture never blocks the build. Follow the same marker-dedupe discipline as every other comment here (match on the **marker, never the title**; **exactly one marker per body**; the eventual-consistency guard when the search index is stale), with **one deliberate difference: dedupe against OPEN signals only.** A *closed* saturation ticket means room was already reclaimed, so a fresh saturation is a new actionable event — searching closed tickets too (as the drop/upstream markers do) would permanently suppress every later saturation.
|
|
178
|
+
|
|
179
|
+
The saturation fingerprint keys on the **ledger, not the candidate**, so the signal fires once per saturation episode — never once per capture:
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
saturation-fingerprint = "sat-" + first 12 hex chars of sha1(<resolved learnings-file path>)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
```markdown
|
|
186
|
+
<!-- [lisa-ledger-saturated] key=<saturation-fingerprint> -->
|
|
187
|
+
Learnings ledger saturated — a durable capture was dropped for budget. The projection is now omitting entries; promote or retire a learning to reclaim room. This is an operator-visible budget-pressure signal, not itself a new learning.
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The `[lisa-ledger-saturated]` marker sits **outside the `[lisa-learning-*]` namespace** that the gardener (`lisa-learnings-audit`) auto-excludes from candidacy. The gardener already derives budget pressure independently — it measures the entries its `projectLearnings` projection has to omit — so this ticket does not feed that measurement mechanically; its job is an idempotent, operator-visible notification that saturation happened. Keeping it outside `[lisa-learning-*]` matters so the audit tooling does not silently filter it as learning-machinery noise before an operator sees it. **Do not reuse a `[lisa-learning-*]` marker here.** The candidate itself is still dropped; this signal records the saturation, it does not persist the rule.
|
|
177
191
|
4. **Branch + commit.** Work on branch `learning/<fingerprint>`. Commit only the learnings file; verify with `git diff --name-only` that the diff touches nothing else.
|
|
178
192
|
5. **PR body.** Exactly one marker line plus the reviewable story:
|
|
179
193
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lisa-setup-sonar
|
|
3
|
+
description: "Configure the official SonarQube plugin + MCP as Lisa's single Sonar substrate across every supported coding agent. Installs/updates the SonarQube CLI, authenticates (browser login on a dev machine, or SONARQUBE_TOKEN headless), selects the Test Manager target, runs `sonar integrate <agent>` for each supported agent (Claude, Codex, Cursor, Copilot, Antigravity) and wires the MCP for OpenCode, then writes only non-secret policy to .lisa.config.json. Separate from the CI SonarCloud scan gate, which is unchanged."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Write", "Edit", "AskUserQuestion", "Skill"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Set up SonarQube (official plugin + MCP)
|
|
8
|
+
|
|
9
|
+
This is an explicit exterior setup gate. Run it **outside** any active Build, QA,
|
|
10
|
+
Monitor, or Verify factory — authentication and MCP wiring must be complete before
|
|
11
|
+
unattended factories run. It replaces Lisa's former hand-rolled SonarCloud REST
|
|
12
|
+
access with the vendor's official token-authed MCP, which is Lisa's single Sonar
|
|
13
|
+
substrate on both developer machines and headless cloud routines.
|
|
14
|
+
|
|
15
|
+
This does **not** touch the CI SonarCloud SAST job in `quality.yml` or its
|
|
16
|
+
`SONAR_TOKEN` secret — that enforcement gate is separate and stays as-is.
|
|
17
|
+
|
|
18
|
+
## Supported agents
|
|
19
|
+
|
|
20
|
+
Wire only Lisa's supported agents: **Claude Code, Codex, Cursor, GitHub Copilot,
|
|
21
|
+
Antigravity (agy)** via `sonar integrate <agent>`, and **OpenCode** via its MCP
|
|
22
|
+
config. **Never** wire Kiro or Gemini CLI even though the vendor supports them —
|
|
23
|
+
they are not Lisa-supported agents.
|
|
24
|
+
|
|
25
|
+
## 1. Install or update the SonarQube CLI
|
|
26
|
+
|
|
27
|
+
Check `sonar` on PATH (`command -v sonar`). If present, update it (`sonar
|
|
28
|
+
self-update`, or the package manager that owns it); if absent, install it and ask
|
|
29
|
+
for confirmation before running the install:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# macOS/Linux (script) — default, works everywhere
|
|
33
|
+
curl -o- https://raw.githubusercontent.com/SonarSource/sonarqube-cli/refs/heads/master/user-scripts/install.sh | bash
|
|
34
|
+
# or Homebrew: brew install --cask sonarqube-cli
|
|
35
|
+
# or mise: mise use -g aqua:SonarSource/sonarqube-cli
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
A container runtime (Docker/Podman/Nerdctl) must be installed and running — the
|
|
39
|
+
MCP runs as a container via `sonar run mcp`. Probe with `docker ps` (falling back
|
|
40
|
+
to `podman ps` / `nerdctl ps`). If none succeed, tell the operator to start it and
|
|
41
|
+
note the agent session must restart afterward for the MCP tools to load.
|
|
42
|
+
|
|
43
|
+
## 2. Authenticate — token for factories, login for dev machines
|
|
44
|
+
|
|
45
|
+
The MCP authenticates from environment variables — this is the headless path and
|
|
46
|
+
the one factories use. **Never** write credentials to `.lisa.config.json` or
|
|
47
|
+
`.lisa.config.local.json`; provide them as environment variables / CI secrets:
|
|
48
|
+
|
|
49
|
+
- `SONARQUBE_TOKEN` — required.
|
|
50
|
+
- `SONARQUBE_ORG` — for SonarQube Cloud.
|
|
51
|
+
- `SONARQUBE_URL` — for a self-hosted SonarQube Server.
|
|
52
|
+
|
|
53
|
+
On an interactive developer machine you may instead run `sonar auth login`
|
|
54
|
+
(browser flow; token stored in the OS keychain). Do **not** use the keychain flow
|
|
55
|
+
for headless/cloud-routine environments — provision the env token there instead
|
|
56
|
+
(see `/lisa:generate-claude-remote-build-script`, which now installs the CLI,
|
|
57
|
+
pre-pulls the MCP image, and sets `SONARQUBE_TOKEN`). Verify with `sonar auth
|
|
58
|
+
status`; record the identity label only, never token material.
|
|
59
|
+
|
|
60
|
+
## 3. Select the Test Manager target
|
|
61
|
+
|
|
62
|
+
Use `sonar config project` (and optional `sonar config folder`), then `sonar
|
|
63
|
+
config show`. Capture the non-secret project/organization identifiers.
|
|
64
|
+
|
|
65
|
+
## 4. Integrate per supported agent
|
|
66
|
+
|
|
67
|
+
Confirm the target scope (single-choice: current project / global), then for each
|
|
68
|
+
supported agent detected on PATH run its non-interactive integrate:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
sonar integrate claude --non-interactive
|
|
72
|
+
sonar integrate codex --non-interactive
|
|
73
|
+
sonar integrate cursor --non-interactive
|
|
74
|
+
sonar integrate copilot --non-interactive
|
|
75
|
+
sonar integrate antigravity --non-interactive
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For **OpenCode** (no vendor integrate path), wire the MCP through OpenCode's own
|
|
79
|
+
MCP config so it launches `sonar run mcp`, authenticated from the same env token.
|
|
80
|
+
|
|
81
|
+
Skip any agent whose CLI is not installed; never wire Kiro or Gemini.
|
|
82
|
+
|
|
83
|
+
## 5. Write non-secret policy config
|
|
84
|
+
|
|
85
|
+
Merge only non-secret identifiers into committed `.lisa.config.json`, preserving
|
|
86
|
+
every unrelated key (never credentials):
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"verification": {
|
|
91
|
+
"sonar": {
|
|
92
|
+
"enabled": true,
|
|
93
|
+
"edition": "cloud",
|
|
94
|
+
"organization": "<org-key>",
|
|
95
|
+
"projectKey": "<project-key>"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Use `"edition": "server"` with a `"serverUrl"` for a self-hosted Server.
|
|
102
|
+
|
|
103
|
+
## 6. Prove readiness
|
|
104
|
+
|
|
105
|
+
Run the `lisa-sonarcloud-access` probe (an `mcp__sonarqube__*` project search) and
|
|
106
|
+
confirm a `mcp__sonarqube__*` tool answers. Then run `lisa doctor` and confirm the
|
|
107
|
+
Sonar provider check is green. If the MCP tools do not appear, verify the container
|
|
108
|
+
runtime is running and restart the agent session.
|
|
@@ -1,71 +1,76 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lisa-sonarcloud-access
|
|
3
|
-
description: "Vendor-neutral access layer for
|
|
3
|
+
description: "Vendor-neutral access layer for SonarQube Cloud/Server. Sonar triage skills MUST delegate through this skill rather than calling the SonarQube MCP tools directly. Single substrate: the official SonarQube MCP server (mcp__sonarqube__*), authenticated headlessly from SONARQUBE_TOKEN (+ SONARQUBE_ORG for Cloud, SONARQUBE_URL for Server)."
|
|
4
4
|
allowed-tools: ["Bash", "Read", "Skill"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# SonarCloud Access: $ARGUMENTS
|
|
8
8
|
|
|
9
|
-
Single chokepoint for
|
|
10
|
-
`mcp__sonarqube__*` tools directly
|
|
11
|
-
|
|
9
|
+
Single chokepoint for Sonar quality and security data. Caller skills MUST NOT
|
|
10
|
+
invoke `mcp__sonarqube__*` tools directly; they ask for data by operation name and
|
|
11
|
+
this skill owns the tool selection.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Substrate
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
operation: rule-detail key:<RULE_KEY>
|
|
20
|
-
operation: source-snippet component:<COMPONENT_KEY> from:<N> to:<N>
|
|
21
|
-
```
|
|
15
|
+
There is exactly one substrate: the **official SonarQube MCP server**, provided by
|
|
16
|
+
the `sonarqube` plugin and launched by the `sonar` CLI (`sonar run mcp`). It
|
|
17
|
+
authenticates headlessly from environment variables — no browser, no OS keychain —
|
|
18
|
+
so it is the same substrate on a developer machine and in a headless cloud routine:
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
- `SONARQUBE_TOKEN` — required (Sonar user/analysis token).
|
|
21
|
+
- `SONARQUBE_ORG` — required for SonarQube Cloud.
|
|
22
|
+
- `SONARQUBE_URL` — required for a self-hosted SonarQube Server.
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
Wiring is performed once by `/lisa:setup:sonar` (which drives `sonar integrate
|
|
25
|
+
<agent>`); this access layer assumes the MCP is already wired. This is distinct
|
|
26
|
+
from the CI `SONAR_TOKEN` secret that authenticates the SonarCloud scan job in
|
|
27
|
+
`quality.yml` — that gate is separate and unchanged.
|
|
26
28
|
|
|
27
|
-
Probe
|
|
29
|
+
## Probe (tool-access-gate)
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
Prove access with a cheap read-only MCP call before relying on it — the `sonar` CLI
|
|
32
|
+
being on PATH is not access. Probe by searching projects (the `projects` toolset is
|
|
33
|
+
always enabled):
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
- If a `mcp__sonarqube__*` project-search tool returns, access is proven.
|
|
36
|
+
- If no `mcp__sonarqube__*` tool is present, or the call fails authentication, fail
|
|
37
|
+
loudly and do not improvise a substitute:
|
|
33
38
|
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
local path="$1"
|
|
37
|
-
[ -n "$SONAR_TOKEN" ] || {
|
|
38
|
-
echo "Error: SONAR_TOKEN is not set." >&2
|
|
39
|
-
return 1
|
|
40
|
-
}
|
|
41
|
-
curl -sS "https://sonarcloud.io/api${path}" \
|
|
42
|
-
-H "Authorization: Bearer $SONAR_TOKEN"
|
|
43
|
-
}
|
|
39
|
+
```text
|
|
40
|
+
Error: no SonarQube access. Run /lisa:setup:sonar (or `sonar integrate <agent>`), and set SONARQUBE_TOKEN (+ SONARQUBE_ORG for Cloud / SONARQUBE_URL for Server).
|
|
44
41
|
```
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
There is no hand-rolled REST fallback: the official MCP is headless-capable via the
|
|
44
|
+
token env vars, so it is the only sanctioned substrate. A missing MCP is a
|
|
45
|
+
tool-access-gate failure to surface, not a reason to curl the Web API.
|
|
48
46
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```text
|
|
52
|
-
Error: no SonarCloud access substrate available. Authenticate the Sonar MCP or set SONAR_TOKEN.
|
|
53
|
-
```
|
|
47
|
+
## Operation → toolset map
|
|
54
48
|
|
|
55
|
-
|
|
49
|
+
Consumers pass a coarse, vendor-native operation; resolve it with the matching
|
|
50
|
+
`mcp__sonarqube__*` tool from the named toolset and return parsed JSON in a
|
|
51
|
+
`<result>` block.
|
|
56
52
|
|
|
57
|
-
| Operation |
|
|
53
|
+
| Operation | SonarQube MCP toolset |
|
|
58
54
|
|---|---|
|
|
59
|
-
| `gate-status` |
|
|
60
|
-
| `issues` |
|
|
61
|
-
| `hotspots` |
|
|
62
|
-
| `rule-detail` |
|
|
63
|
-
| `source-snippet` |
|
|
55
|
+
| `gate-status` | `quality-gates` |
|
|
56
|
+
| `issues` | `issues` |
|
|
57
|
+
| `hotspots` | `security-hotspots` |
|
|
58
|
+
| `rule-detail` | `rules` |
|
|
59
|
+
| `source-snippet` | `cag` (context augmentation) / component source |
|
|
60
|
+
| `coverage` | `coverage` |
|
|
61
|
+
| `duplication` | `duplications` |
|
|
62
|
+
| `dependency-risks` | `dependency-risks` |
|
|
63
|
+
| `projects` | `projects` |
|
|
64
|
+
|
|
65
|
+
Pass the project key through the tool's `projectKey` argument (or rely on a
|
|
66
|
+
server-configured `SONARQUBE_PROJECT_KEY`); pass `branch` / `pullRequest` where the
|
|
67
|
+
tool accepts them.
|
|
64
68
|
|
|
65
69
|
## Invariants
|
|
66
70
|
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
-
|
|
71
|
-
|
|
71
|
+
- The official SonarQube MCP is the only substrate; there is no REST fallback.
|
|
72
|
+
- Auth is env-var only (`SONARQUBE_TOKEN` [+ `SONARQUBE_ORG` | `SONARQUBE_URL`]);
|
|
73
|
+
never the interactive `sonar auth login` keychain flow inside a factory.
|
|
74
|
+
- Sonar host access requires the host (`sonarcloud.io`, `sonarqube.us`, or the
|
|
75
|
+
Server URL) in any custom remote-network allowlist.
|
|
76
|
+
- Consumers ask for data by operation name; this skill owns tool selection.
|