@northbridge-security/secureai 0.1.13

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.
Files changed (50) hide show
  1. package/.claude/README.md +122 -0
  2. package/.claude/commands/architect/clean.md +978 -0
  3. package/.claude/commands/architect/kiss.md +762 -0
  4. package/.claude/commands/architect/review.md +704 -0
  5. package/.claude/commands/catchup.md +90 -0
  6. package/.claude/commands/code.md +115 -0
  7. package/.claude/commands/commit.md +1218 -0
  8. package/.claude/commands/cover.md +1298 -0
  9. package/.claude/commands/fmea.md +275 -0
  10. package/.claude/commands/kaizen.md +312 -0
  11. package/.claude/commands/pr.md +503 -0
  12. package/.claude/commands/todo.md +99 -0
  13. package/.claude/commands/worktree.md +738 -0
  14. package/.claude/commands/wrapup.md +103 -0
  15. package/LICENSE +183 -0
  16. package/README.md +108 -0
  17. package/dist/cli.js +75634 -0
  18. package/docs/agents/devops-reviewer.md +889 -0
  19. package/docs/agents/kiss-simplifier.md +1088 -0
  20. package/docs/agents/typescript.md +8 -0
  21. package/docs/guides/README.md +109 -0
  22. package/docs/guides/agents.clean.arch.md +244 -0
  23. package/docs/guides/agents.clean.arch.ts.md +1314 -0
  24. package/docs/guides/agents.gotask.md +1037 -0
  25. package/docs/guides/agents.markdown.md +1209 -0
  26. package/docs/guides/agents.onepassword.md +285 -0
  27. package/docs/guides/agents.sonar.md +857 -0
  28. package/docs/guides/agents.tdd.md +838 -0
  29. package/docs/guides/agents.tdd.ts.md +1062 -0
  30. package/docs/guides/agents.typesript.md +1389 -0
  31. package/docs/guides/github-mcp.md +1075 -0
  32. package/package.json +130 -0
  33. package/packages/secureai-cli/src/cli.ts +21 -0
  34. package/tasks/README.md +880 -0
  35. package/tasks/aws.yml +64 -0
  36. package/tasks/bash.yml +118 -0
  37. package/tasks/bun.yml +738 -0
  38. package/tasks/claude.yml +183 -0
  39. package/tasks/docker.yml +420 -0
  40. package/tasks/docs.yml +127 -0
  41. package/tasks/git.yml +1336 -0
  42. package/tasks/gotask.yml +132 -0
  43. package/tasks/json.yml +77 -0
  44. package/tasks/markdown.yml +95 -0
  45. package/tasks/onepassword.yml +350 -0
  46. package/tasks/security.yml +102 -0
  47. package/tasks/sonar.yml +437 -0
  48. package/tasks/template.yml +74 -0
  49. package/tasks/vscode.yml +103 -0
  50. package/tasks/yaml.yml +121 -0
@@ -0,0 +1,857 @@
1
+ # SonarQube Integration Guide for AI Agents
2
+
3
+ This guide explains how AI agents can integrate with SonarQube/SonarCloud for automated code quality analysis, security scanning, and PR review workflows. Target audience: AI code assistants working with repositories that use SonarQube for quality gates.
4
+
5
+ ## Overview
6
+
7
+ SonarQube provides automated code quality and security analysis integrated into CI/CD workflows. AI agents can download analysis results programmatically, review findings, and fix issues automatically without requiring manual SonarCloud UI access.
8
+
9
+ **Key capabilities:**
10
+
11
+ - Download complete analysis results via GoTask commands
12
+ - Parse issues and security hotspots from downloaded reports
13
+ - Address findings programmatically (fix real issues, suppress false positives)
14
+ - Integrate with `/pr:fix` workflow for automated PR remediation
15
+ - Track quality gate status and blocking issues
16
+
17
+ **Supported workflows:**
18
+
19
+ - **PR-based analysis**: Get issues specific to a pull request
20
+ - **Branch analysis**: Get issues for default branch
21
+ - **Local scanning**: Run sonar-scanner locally before pushing
22
+ - **Automated fixes**: Bulk remediation of security hotspots and code smells
23
+
24
+ ## Prerequisites
25
+
26
+ ### Repository Requirements
27
+
28
+ **Minimum setup** (may not exist in all repositories):
29
+
30
+ - `sonar-project.properties` file in repository root
31
+ - `SONAR_TOKEN` environment variable or secret
32
+ - GitHub Actions workflow with SonarQube step (optional)
33
+
34
+ **Typical structure:**
35
+
36
+ ```text
37
+ repository/
38
+ ├── sonar-project.properties # SonarQube configuration
39
+ ├── .github/
40
+ │ ├── workflows/
41
+ │ │ └── ci.yml # CI workflow with SonarQube job
42
+ │ └── actions/
43
+ │ └── sonar/
44
+ │ └── action.yml # Reusable SonarQube action
45
+ ├── .env # Local secrets (gitignored)
46
+ └── tasks/
47
+ └── sonar.yml # GoTask automation (if using GoTask)
48
+ ```
49
+
50
+ **If repository lacks SonarQube setup:**
51
+
52
+ The repository may not have SonarQube configured. Check for these files before attempting analysis:
53
+
54
+ ```bash
55
+ # Check for sonar-project.properties
56
+ [ -f sonar-project.properties ] && echo "SonarQube configured" || echo "No SonarQube"
57
+
58
+ # Check for SonarQube GitHub Action
59
+ grep -r "sonar" .github/workflows/ 2>/dev/null
60
+ ```
61
+
62
+ If not configured, skip SonarQube analysis or suggest setup (see [Setting Up SonarQube](#setting-up-sonarqube)).
63
+
64
+ ### Token Setup
65
+
66
+ **For local analysis:**
67
+
68
+ Add to `.env` file (gitignored):
69
+
70
+ ```bash
71
+ # SonarQube/SonarCloud authentication token
72
+ SONAR_TOKEN=your-token-here
73
+
74
+ # Or use 1Password reference
75
+ SONAR_TOKEN=op://Private/SonarCloud/API Token/token
76
+ ```
77
+
78
+ **For CI/CD:**
79
+
80
+ Token should be configured as GitHub secret:
81
+
82
+ - **Secret name**: `SONAR_TOKEN`
83
+ - **Where**: Repository Settings → Secrets and variables → Actions
84
+
85
+ ## GoTask Integration
86
+
87
+ ### Available Commands
88
+
89
+ **Analysis commands:**
90
+
91
+ ```bash
92
+ # Download complete analysis results (recommended)
93
+ task sonar:download
94
+
95
+ # View most recent downloaded report
96
+ task sonar:issues
97
+
98
+ # Run local scan (requires sonar-scanner installed)
99
+ task sonar:scan
100
+ ```
101
+
102
+ **Setup commands:**
103
+
104
+ ```bash
105
+ # Install sonar-scanner CLI (macOS/Linux)
106
+ task sonar:setup
107
+
108
+ # Show all available commands
109
+ task sonar:help
110
+ ```
111
+
112
+ ### Download Analysis Results
113
+
114
+ The `sonar:download` command fetches complete analysis results from SonarQube API and generates a human-readable report.
115
+
116
+ **What it does:**
117
+
118
+ 1. Detects PR context (or default branch if no PR)
119
+ 2. Fetches issues, security hotspots, and quality gate status
120
+ 3. Generates timestamped report in `.logs/sonar/`
121
+ 4. Opens report in VSCode (if available)
122
+
123
+ **Example output:**
124
+
125
+ ```bash
126
+ $ task sonar:download
127
+
128
+ ℹ Analyzing PR #4: feat(installer): Phase 2 - Agent installation
129
+ ℹ Project: northbridge-security_ai-toolkit
130
+ ℹ Branch: feat/installer-ph2 → main
131
+
132
+ ❌ Quality Gate: ERROR
133
+ ℹ Downloaded 237 issues + 49 hotspots → .logs/sonar/issues-20251118-115543.txt
134
+ ```
135
+
136
+ **Report structure:**
137
+
138
+ ```text
139
+ SonarQube Analysis Report
140
+ =========================
141
+ Project: northbridge-security_ai-toolkit
142
+ Analysis: PR #4
143
+ Date: 2025-11-18 11:55:43
144
+
145
+ Quality Gate: ERROR
146
+ Failed Conditions:
147
+ - coverage: 65.2% (threshold: 80%)
148
+ - duplicated_lines_density: 9.1% (threshold: 3%)
149
+
150
+ Issues: 237
151
+ By Severity:
152
+ Blocker: 4
153
+ Critical: 73
154
+ Major: 76
155
+ Minor: 78
156
+
157
+ Security Hotspots: 49
158
+ To Review: 49
159
+ Reviewed: 0
160
+
161
+ ═══════════════════════════════════════════════════════════════
162
+ DETAILED ISSUES
163
+ ═══════════════════════════════════════════════════════════════
164
+
165
+ [BLOCKER] .github/workflows/approve.yml:24
166
+ Type: CODE_SMELL
167
+ Rule: javascript:S2076
168
+ Message: Make sure that executing this OS command is safe here.
169
+ ───────────────────────────────────────────────────────────────
170
+ ...
171
+ ```
172
+
173
+ ### Programmatic Analysis
174
+
175
+ **Read downloaded reports:**
176
+
177
+ ```bash
178
+ # Most recent report
179
+ REPORT=$(ls -t .logs/sonar/issues-*.txt 2>/dev/null | head -1)
180
+
181
+ # Count issues by severity
182
+ BLOCKER=$(grep "^\[BLOCKER\]" "$REPORT" | wc -l)
183
+ CRITICAL=$(grep "^\[CRITICAL\]" "$REPORT" | wc -l)
184
+
185
+ # Extract specific file issues
186
+ grep "src/tasks/bash/utils.ts" "$REPORT"
187
+ ```
188
+
189
+ **Parse raw JSON data:**
190
+
191
+ ```bash
192
+ # Raw API responses are also saved
193
+ RAW_JSON=$(ls -t .logs/sonar/issues-*-raw.json 2>/dev/null | head -1)
194
+
195
+ # Extract high-severity issues
196
+ jq '.issues[] | select(.severity == "BLOCKER" or .severity == "CRITICAL")' "$RAW_JSON"
197
+
198
+ # Group by file
199
+ jq -r '.issues[] | "\(.component | split(":")[1]):\(.line)"' "$RAW_JSON" | sort | uniq -c
200
+ ```
201
+
202
+ ## Analyzing Findings
203
+
204
+ ### Issue Categories
205
+
206
+ **By severity:**
207
+
208
+ - **BLOCKER**: Breaks core functionality, must fix immediately
209
+ - **CRITICAL**: High-impact bugs or security vulnerabilities
210
+ - **MAJOR**: Moderate-impact issues (complexity, maintainability)
211
+ - **MINOR**: Low-impact code smells (style, minor improvements)
212
+
213
+ **By type:**
214
+
215
+ - **BUG**: Logic errors, incorrect behavior
216
+ - **VULNERABILITY**: Security weaknesses
217
+ - **CODE_SMELL**: Maintainability issues
218
+ - **SECURITY_HOTSPOT**: Code requiring security review
219
+
220
+ ### Security Hotspots
221
+
222
+ Security hotspots require manual review to determine if they're real vulnerabilities or false positives.
223
+
224
+ **Hotspot workflow:**
225
+
226
+ 1. **Download report**: `task sonar:download`
227
+ 2. **Review each hotspot**: Check the code context
228
+ 3. **Determine action**:
229
+ - **Real issue**: Fix the vulnerability
230
+ - **False positive**: Add suppression comment with justification
231
+ 4. **Document decision**: Add inline comments explaining why
232
+
233
+ **Hotspot severity levels:**
234
+
235
+ - **HIGH**: Likely security vulnerability, immediate attention
236
+ - **MEDIUM**: Potential security issue, review carefully
237
+ - **LOW**: Minor security concern, low risk
238
+
239
+ **Example hotspot review:**
240
+
241
+ ```typescript
242
+ // Security hotspot: Command injection warning
243
+ // Line 37: execSync('shfmt -d "' + file + '"')
244
+
245
+ // Analysis:
246
+ // - file variable comes from discoverFiles() function
247
+ // - discoverFiles() returns file paths from filesystem
248
+ // - Filenames could contain special characters like quotes, semicolons
249
+ // - This creates a command injection vulnerability
250
+
251
+ // FIX: Use proper shell escaping
252
+ import { escapeShellArg } from "./utils";
253
+ execSync("shfmt -d " + escapeShellArg(file));
254
+ ```
255
+
256
+ **Example false positive:**
257
+
258
+ ```typescript
259
+ // Security hotspot: Hard-coded password
260
+ // Line 76: const token = 'github_pat_1234567890abcd';
261
+
262
+ // Analysis:
263
+ // - This is a test file (tests/integration/github-mcp.test.ts)
264
+ // - Token is clearly a fake placeholder (sequential characters)
265
+ // - Not a real secret
266
+
267
+ // SUPPRESSION: Document false positive
268
+ // nosemgrep: generic.secrets.security.detected-generic-secret.detected-generic-secret
269
+ const token = "github_pat_1234567890abcd"; // Test fixture, not real secret
270
+ ```
271
+
272
+ ### Suppression Patterns
273
+
274
+ **When to suppress:**
275
+
276
+ - Test fixtures with fake credentials
277
+ - Hardcoded commands with no user input
278
+ - Simple regex patterns flagged as ReDoS
279
+ - Permission checks in test cleanup code
280
+ - Math.random() used for non-security purposes
281
+
282
+ **Suppression format:**
283
+
284
+ ```typescript
285
+ // SECURITY: [Explanation of why this is safe]
286
+ // nosemgrep: [rule-id]
287
+ [code that triggered warning]
288
+ ```
289
+
290
+ **Common suppression rules:**
291
+
292
+ | Issue Type | Semgrep Rule ID |
293
+ | ------------------ | ------------------------------------------------------------------------------------ |
294
+ | Generic secrets | `generic.secrets.security.detected-generic-secret.detected-generic-secret` |
295
+ | Command injection | `javascript.lang.security.audit.unsafe-exec.unsafe-exec` |
296
+ | ReDoS | `javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp` |
297
+ | Weak crypto | `javascript.lang.security.audit.detect-pseudorandom-usage.detect-pseudorandom-usage` |
298
+ | Unsafe permissions | `javascript.lang.security.audit.unsafe-permissions.unsafe-permissions` |
299
+
300
+ ## The /pr:fix Workflow
301
+
302
+ The `/pr:fix` slash command integrates SonarQube analysis into automated PR remediation.
303
+
304
+ **Workflow overview:**
305
+
306
+ 1. **Detect PR context** - Identifies current branch and PR number
307
+ 2. **Download PR comments** - Fetches GitHub PR review comments
308
+ 3. **Download workflow logs** - Gets CI/CD failure details
309
+ 4. **Download SonarQube analysis** - Runs `task sonar:download`
310
+ 5. **Analyze findings** - Categorizes issues by priority
311
+ 6. **Fix blocking issues** - Addresses critical/blocker issues automatically
312
+ 7. **Update PR review documentation** - Tracks progress in `.pr.review.local.md`
313
+
314
+ **Usage:**
315
+
316
+ ```bash
317
+ # Run in repository with open PR
318
+ /pr:fix
319
+ ```
320
+
321
+ **What it does with SonarQube:**
322
+
323
+ ```typescript
324
+ // Phase 3: Download SonarQube analysis
325
+ await bash("task sonar:download");
326
+
327
+ // Read downloaded report
328
+ const report = readFile(".logs/sonar/issues-*.txt");
329
+
330
+ // Parse findings
331
+ const blockers = parseIssues(report, "BLOCKER");
332
+ const criticals = parseIssues(report, "CRITICAL");
333
+ const hotspots = parseSecurityHotspots(report);
334
+
335
+ // Prioritize fixes
336
+ const mustFix = [...blockers, ...hotspots.filter((h) => h.severity === "HIGH")];
337
+
338
+ // Fix each issue programmatically
339
+ for (const issue of mustFix) {
340
+ await fixIssue(issue);
341
+ }
342
+
343
+ // Update documentation
344
+ await updatePRReview({ fixed: mustFix.length, remaining: criticals.length });
345
+ ```
346
+
347
+ **Example `/pr:fix` output:**
348
+
349
+ ```text
350
+ Phase 3: Downloading SonarQube analysis...
351
+ ✓ Downloaded 237 issues + 49 hotspots
352
+
353
+ Analyzing findings:
354
+ - 4 BLOCKER issues (immediate fix required)
355
+ - 73 CRITICAL issues (high priority)
356
+ - 49 security hotspots (11 HIGH, 8 MEDIUM, 30 LOW)
357
+
358
+ Fixing BLOCKER issues:
359
+ ✓ Fixed: .github/workflows/approve.yml:24 (command injection)
360
+ ✓ Fixed: .github/actions/sonar/action.yml:92 (command injection)
361
+ ✓ Fixed: src/tasks/bash/utils.ts:24 (command injection)
362
+ ✓ Fixed: src/tasks/json/utils.ts:208 (incomplete escaping)
363
+
364
+ Addressing HIGH priority security hotspots:
365
+ ✓ Fixed: src/tasks/bash/format-check.ts:37 (added escapeShellArg)
366
+ ✓ Fixed: src/tasks/bash/format.ts:44 (added escapeShellArg)
367
+ ✓ Fixed: src/tasks/bash/lint.ts:34 (added escapeShellArg)
368
+ ✓ Documented: tests/integration/github-mcp.test.ts:76 (test fixture)
369
+
370
+ Updated: .pr.review.local.md
371
+ ```
372
+
373
+ **Result:**
374
+
375
+ - All blocking issues fixed
376
+ - Progress tracked in `.pr.review.local.md`
377
+ - PR ready for review with clean quality gate
378
+
379
+ ## Setting Up SonarQube
380
+
381
+ If repository doesn't have SonarQube configured, here's how to set it up.
382
+
383
+ ### SonarCloud Project Setup
384
+
385
+ **1. Create SonarCloud project:**
386
+
387
+ - Go to https://sonarcloud.io
388
+ - Log in with GitHub account
389
+ - Click "+ " → "Analyze new project"
390
+ - Select repository
391
+ - Choose "With GitHub Actions" setup method
392
+
393
+ **2. Configure GitHub secret:**
394
+
395
+ - Copy SonarCloud token from setup page
396
+ - Go to GitHub repo → Settings → Secrets and variables → Actions
397
+ - Create new secret:
398
+ - **Name**: `SONAR_TOKEN`
399
+ - **Value**: [paste token]
400
+
401
+ ### Configuration File
402
+
403
+ Create `sonar-project.properties` in repository root:
404
+
405
+ ```properties
406
+ # SonarCloud Configuration
407
+ sonar.projectKey=organization_repository-name
408
+ sonar.organization=organization-name
409
+
410
+ # Project metadata
411
+ sonar.projectName=Repository Name
412
+ sonar.projectVersion=1.0
413
+
414
+ # Source code
415
+ sonar.sources=src
416
+ sonar.tests=tests
417
+ sonar.sourceEncoding=UTF-8
418
+
419
+ # Language-specific settings
420
+ sonar.javascript.lcov.reportPaths=.logs/coverage/lcov.info
421
+ sonar.testExecutionReportPaths=.logs/test-results/junit.xml
422
+
423
+ # Exclusions
424
+ sonar.exclusions=\
425
+ **/node_modules/**,\
426
+ **/dist/**,\
427
+ **/coverage/**,\
428
+ **/.logs/**,\
429
+ **/tests/**/*.test.ts
430
+
431
+ sonar.test.inclusions=\
432
+ tests/**/*.test.ts,\
433
+ **/*.test.ts
434
+
435
+ # Coverage exclusions
436
+ sonar.coverage.exclusions=\
437
+ tests/**,\
438
+ **/*.test.ts,\
439
+ **/types/**
440
+
441
+ # Quality gate
442
+ sonar.qualitygate.wait=false
443
+ ```
444
+
445
+ **Key settings:**
446
+
447
+ | Property | Purpose | Example |
448
+ | ----------------------------------- | ----------------------- | -------------------------- |
449
+ | `sonar.projectKey` | Unique identifier | `org_repo-name` |
450
+ | `sonar.organization` | SonarCloud organization | `your-org` |
451
+ | `sonar.sources` | Source code directory | `src` |
452
+ | `sonar.tests` | Test directory | `tests` |
453
+ | `sonar.javascript.lcov.reportPaths` | Coverage report path | `.logs/coverage/lcov.info` |
454
+
455
+ ### GitHub Actions Integration
456
+
457
+ **Create reusable action** (`.github/actions/sonar/action.yml`):
458
+
459
+ ```yaml
460
+ name: "SonarQube Analysis"
461
+ description: "Runs SonarQube/SonarCloud analysis with sonar-scanner CLI"
462
+
463
+ inputs:
464
+ github-token:
465
+ description: "GitHub token for authentication"
466
+ required: true
467
+ sonar-token:
468
+ description: "SonarQube/SonarCloud token for authentication"
469
+ required: true
470
+ sonar-host-url:
471
+ description: "SonarQube/SonarCloud host URL"
472
+ required: false
473
+ default: "https://sonarcloud.io"
474
+
475
+ runs:
476
+ using: "composite"
477
+ steps:
478
+ - name: Install sonar-scanner
479
+ shell: bash
480
+ run: |
481
+ curl -sSL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.8.0.2856-linux.zip -o /tmp/sonar-scanner.zip
482
+ unzip -q /tmp/sonar-scanner.zip -d /tmp/
483
+ echo "/tmp/sonar-scanner-4.8.0.2856-linux/bin" >> $GITHUB_PATH
484
+
485
+ - name: Run SonarQube analysis
486
+ shell: bash
487
+ env:
488
+ GITHUB_TOKEN: ${{ inputs.github-token }}
489
+ SONAR_TOKEN: ${{ inputs.sonar-token }}
490
+ HEAD_REF: ${{ github.head_ref }}
491
+ BASE_REF: ${{ github.base_ref }}
492
+ PR_NUMBER: ${{ github.event.pull_request.number }}
493
+ run: |
494
+ SCANNER_ARGS="-Dsonar.host.url=${{ inputs.sonar-host-url }}"
495
+
496
+ # Add PR-specific parameters
497
+ if [ -n "$PR_NUMBER" ]; then
498
+ SCANNER_ARGS="$SCANNER_ARGS \
499
+ -Dsonar.pullrequest.key=${PR_NUMBER} \
500
+ -Dsonar.pullrequest.branch=${HEAD_REF} \
501
+ -Dsonar.pullrequest.base=${BASE_REF}"
502
+ fi
503
+
504
+ sonar-scanner $SCANNER_ARGS
505
+ ```
506
+
507
+ **Add to CI workflow** (`.github/workflows/ci.yml`):
508
+
509
+ ```yaml
510
+ jobs:
511
+ # Run SonarQube code quality analysis
512
+ sonarqube:
513
+ name: SonarQube Analysis
514
+ runs-on: ubuntu-latest
515
+ needs: [lint, typecheck, test]
516
+ if: github.event_name == 'pull_request' && secrets.SONAR_TOKEN != ''
517
+ steps:
518
+ - name: Checkout code
519
+ uses: actions/checkout@v4
520
+ with:
521
+ fetch-depth: 0 # Full history for better analysis
522
+
523
+ - name: Setup Bun
524
+ uses: oven-sh/setup-bun@v2
525
+ with:
526
+ bun-version: latest
527
+
528
+ - name: Install dependencies
529
+ run: bun install --frozen-lockfile
530
+
531
+ - name: Run tests with coverage
532
+ run: bun test --coverage
533
+
534
+ - name: Run SonarQube analysis
535
+ uses: ./.github/actions/sonar
536
+ with:
537
+ github-token: ${{ secrets.GITHUB_TOKEN }}
538
+ sonar-token: ${{ secrets.SONAR_TOKEN }}
539
+ ```
540
+
541
+ ### GoTask Integration
542
+
543
+ **Create task file** (`tasks/sonar.yml`):
544
+
545
+ ```yaml
546
+ version: "3"
547
+
548
+ vars:
549
+ SONAR_HOST: '{{.SONAR_HOST | default "https://sonarcloud.io"}}'
550
+
551
+ tasks:
552
+ download:
553
+ desc: Download SonarQube analysis results
554
+ dotenv: [".env"]
555
+ cmds:
556
+ - |
557
+ # Read project key from sonar-project.properties
558
+ PROJECT_KEY=$(grep "^sonar.projectKey=" sonar-project.properties | cut -d'=' -f2)
559
+
560
+ # Detect PR context
561
+ PR_NUMBER=$(gh pr list --head "$(git branch --show-current)" --json number --jq '.[0].number' 2>/dev/null || echo "")
562
+
563
+ # Fetch issues from SonarQube API
564
+ if [ -n "$PR_NUMBER" ]; then
565
+ ISSUES_API="{{.SONAR_HOST}}/api/issues/search?pullRequest=$PR_NUMBER&componentKeys=$PROJECT_KEY&ps=500"
566
+ else
567
+ ISSUES_API="{{.SONAR_HOST}}/api/issues/search?componentKeys=$PROJECT_KEY&ps=500"
568
+ fi
569
+
570
+ curl -s -X GET "$ISSUES_API" -H "Authorization: Bearer $SONAR_TOKEN" > .logs/sonar/issues.json
571
+ ```
572
+
573
+ ## Best Practices
574
+
575
+ ### For AI Agents
576
+
577
+ **Always use task commands:**
578
+
579
+ ```bash
580
+ # ✓ GOOD - Use task commands (logged, cached, consistent)
581
+ task sonar:download
582
+
583
+ # ✗ BAD - Direct API calls (no caching, harder to debug)
584
+ curl -X GET "https://sonarcloud.io/api/issues/search?..." -H "Authorization: Bearer $SONAR_TOKEN"
585
+ ```
586
+
587
+ **Check for SonarQube setup before using:**
588
+
589
+ ```typescript
590
+ // Check if sonar-project.properties exists
591
+ const hasSonar = existsSync("sonar-project.properties");
592
+
593
+ if (!hasSonar) {
594
+ console.log("⚠️ SonarQube not configured in this repository");
595
+ return; // Skip SonarQube analysis
596
+ }
597
+
598
+ // Proceed with analysis
599
+ await bash("task sonar:download");
600
+ ```
601
+
602
+ **Parse reports programmatically:**
603
+
604
+ ```typescript
605
+ // Read downloaded report
606
+ const report = readFileSync(".logs/sonar/issues-20251118-115543.txt", "utf-8");
607
+
608
+ // Extract issues by pattern matching
609
+ const blockers = report
610
+ .split("\n")
611
+ .filter((line) => line.startsWith("[BLOCKER]"))
612
+ .map((line) => parseIssueLine(line));
613
+
614
+ // Fix each issue
615
+ for (const issue of blockers) {
616
+ await fixIssue(issue);
617
+ }
618
+ ```
619
+
620
+ **Document all suppressions:**
621
+
622
+ ```typescript
623
+ // ALWAYS add explanation for suppressions
624
+ // ✓ GOOD
625
+ // SECURITY: Test fixture with fake GitHub token format, not a real secret
626
+ // nosemgrep: generic.secrets.security.detected-generic-secret.detected-generic-secret
627
+ const token = "github_pat_test123";
628
+
629
+ // ✗ BAD
630
+ // nosemgrep: generic.secrets.security.detected-generic-secret.detected-generic-secret
631
+ const token = "github_pat_test123";
632
+ ```
633
+
634
+ **Prioritize fixes:**
635
+
636
+ 1. **BLOCKER**: Fix immediately (breaks core functionality)
637
+ 2. **HIGH security hotspots**: Review and fix real vulnerabilities
638
+ 3. **CRITICAL**: Fix after blockers
639
+ 4. **MEDIUM/LOW hotspots**: Document false positives, defer real issues
640
+ 5. **MAJOR/MINOR**: Address in follow-up PRs
641
+
642
+ ### For Repository Maintainers
643
+
644
+ **Quality gate targets:**
645
+
646
+ - **Coverage**: ≥80% code coverage
647
+ - **Duplication**: ≤3% duplicated code
648
+ - **Security**: 0 vulnerabilities, 0 HIGH hotspots
649
+ - **Maintainability**: No BLOCKER/CRITICAL code smells
650
+
651
+ **Custom quality gates:**
652
+
653
+ Edit in SonarCloud UI → Project → Administration → Quality Gate
654
+
655
+ **Branch protection:**
656
+
657
+ Require SonarQube check to pass before merging:
658
+
659
+ 1. GitHub → Settings → Branches
660
+ 2. Add rule for `main` branch
661
+ 3. Check "Require status checks to pass"
662
+ 4. Select "SonarQube Analysis"
663
+
664
+ ## Troubleshooting
665
+
666
+ ### Token Not Set
667
+
668
+ **Error:**
669
+
670
+ ```text
671
+ ❌ SONAR_TOKEN not set
672
+ Add to .env: SONAR_TOKEN=your-token
673
+ ```
674
+
675
+ **Solution:**
676
+
677
+ ```bash
678
+ # Add to .env file (gitignored)
679
+ echo "SONAR_TOKEN=your-token-here" >> .env
680
+
681
+ # Or use 1Password
682
+ echo "SONAR_TOKEN=op://Private/SonarCloud/API Token/token" >> .env
683
+ ```
684
+
685
+ ### No Reports Found
686
+
687
+ **Error:**
688
+
689
+ ```text
690
+ ❌ No reports found
691
+ Run: task sonar:download
692
+ ```
693
+
694
+ **Solution:**
695
+
696
+ ```bash
697
+ # Download analysis first
698
+ task sonar:download
699
+
700
+ # Then view results
701
+ task sonar:issues
702
+ ```
703
+
704
+ ### PR Analysis Not Found
705
+
706
+ **Warning:**
707
+
708
+ ```text
709
+ ⚠️ PR analysis not found, showing default branch analysis
710
+ ```
711
+
712
+ **Why:** SonarQube PR analysis only runs after CI completes. If viewing results before CI finishes, default branch analysis is shown instead.
713
+
714
+ **Solution:** Wait for CI to complete, then run `task sonar:download` again.
715
+
716
+ ### Quality Gate Failed
717
+
718
+ **Error:**
719
+
720
+ ```text
721
+ ❌ Quality Gate: ERROR
722
+ Failed Conditions:
723
+ - coverage: 65.2% (threshold: 80%)
724
+ ```
725
+
726
+ **Solution:**
727
+
728
+ ```bash
729
+ # Check what needs to be fixed
730
+ task sonar:download
731
+
732
+ # Fix coverage
733
+ bun test --coverage
734
+
735
+ # Fix duplication
736
+ # (Refactor duplicated code blocks)
737
+
738
+ # Re-run analysis
739
+ task sonar:scan
740
+ ```
741
+
742
+ ### sonar-scanner Not Found
743
+
744
+ **Error:**
745
+
746
+ ```text
747
+ sonar-scanner: command not found
748
+ ```
749
+
750
+ **Solution:**
751
+
752
+ ```bash
753
+ # Install sonar-scanner
754
+ task sonar:setup
755
+
756
+ # Verify installation
757
+ sonar-scanner --version
758
+ ```
759
+
760
+ ## Examples
761
+
762
+ ### Example 1: Fix All Blocker Issues
763
+
764
+ ```bash
765
+ # Download analysis
766
+ task sonar:download
767
+
768
+ # Read report
769
+ REPORT=$(ls -t .logs/sonar/issues-*.txt | head -1)
770
+
771
+ # Extract blocker issues
772
+ grep "^\[BLOCKER\]" "$REPORT" | while read -r line; do
773
+ # Parse file and line number
774
+ FILE=$(echo "$line" | sed 's/\[BLOCKER\] \(.*\):.*/\1/')
775
+ LINE=$(echo "$line" | sed 's/.*:\([0-9]*\).*/\1/')
776
+
777
+ echo "Fixing $FILE:$LINE"
778
+
779
+ # Open in editor or apply automated fix
780
+ # ... implementation ...
781
+ done
782
+ ```
783
+
784
+ ### Example 2: Review Security Hotspots by Priority
785
+
786
+ ```bash
787
+ # Download analysis
788
+ task sonar:download
789
+
790
+ # Find HIGH priority hotspots in report
791
+ REPORT=$(ls -t .logs/sonar/issues-*.txt | head -1)
792
+
793
+ # Extract HIGH severity hotspots
794
+ grep -A3 "^\[HIGH\]" "$REPORT" | while read -r line; do
795
+ case "$line" in
796
+ \[HIGH\]*)
797
+ FILE=$(echo "$line" | sed 's/\[HIGH\] \(.*\):.*/\1/')
798
+ echo "Review: $FILE"
799
+ ;;
800
+ Message:*)
801
+ echo " → ${line#Message: }"
802
+ ;;
803
+ esac
804
+ done
805
+ ```
806
+
807
+ ### Example 3: Track Fix Progress
808
+
809
+ ```typescript
810
+ // Track fixes in PR review documentation
811
+ interface FixProgress {
812
+ total: number;
813
+ fixed: number;
814
+ remaining: number;
815
+ categories: {
816
+ blocker: number;
817
+ critical: number;
818
+ hotspots: { high: number; medium: number; low: number };
819
+ };
820
+ }
821
+
822
+ async function trackProgress(): Promise<FixProgress> {
823
+ // Download latest analysis
824
+ await bash("task sonar:download");
825
+
826
+ // Read report
827
+ const report = readFileSync(".logs/sonar/issues-latest.txt", "utf-8");
828
+
829
+ // Count by severity
830
+ const blockers = (report.match(/^\[BLOCKER\]/gm) || []).length;
831
+ const criticals = (report.match(/^\[CRITICAL\]/gm) || []).length;
832
+ const highHotspots = (report.match(/^\[HIGH\].*hotspot/gim) || []).length;
833
+
834
+ return {
835
+ total: blockers + criticals + highHotspots,
836
+ fixed: 0, // Updated as fixes are applied
837
+ remaining: blockers + criticals + highHotspots,
838
+ categories: {
839
+ blocker: blockers,
840
+ critical: criticals,
841
+ hotspots: { high: highHotspots, medium: 0, low: 0 },
842
+ },
843
+ };
844
+ }
845
+ ```
846
+
847
+ ## Related Documentation
848
+
849
+ - [GoTask Usage Guide](./agents.gotask.md) - Task automation patterns
850
+ - [Markdown Standards](./agents.markdown.md) - Documentation formatting
851
+ - [GitHub MCP Integration](./github-mcp.md) - PR and issue management
852
+ - [QA Standards](../QA.md) - Quality assurance guidelines
853
+ - [SonarCloud Documentation](https://docs.sonarcloud.io) - Official docs
854
+
855
+ ---
856
+
857
+ **For AI Agents**: Always use `task sonar:download` to fetch analysis results programmatically. Never require manual UI access. Parse downloaded reports to address findings automatically.