@nerviq/cli 0.9.6 → 1.0.1

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/README.md CHANGED
@@ -4,23 +4,24 @@
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@nerviq/cli)](https://www.npmjs.com/package/@nerviq/cli)
6
6
  [![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-blue.svg)](LICENSE)
7
+ [![Checks: 673](https://img.shields.io/badge/checks-673-brightgreen)](https://github.com/nerviq/nerviq)
7
8
 
8
9
  ---
9
10
 
10
- ### ⚠️ Beta — Currently Claude Code only
11
+ ### 8 Platforms Supported
11
12
 
12
- Nerviq is in **beta**. The current release fully supports **Claude Code** (90 checks, audit, setup, governance, benchmark).
13
+ Nerviq v1.0 ships with full audit, setup, governance, and benchmark support for **8 AI coding platforms**:
13
14
 
14
- **Coming soon:**
15
- - Codex (OpenAI)
16
- - Gemini CLI (Google)
17
- - GitHub Copilot
18
- - Cursor
19
- - Windsurf
20
- - Aider
21
- - OpenCode
22
- - **Harmony** cross-platform drift detection
23
- - **Synergy** multi-agent amplification
15
+ | Platform | Checks | Status |
16
+ |----------|--------|--------|
17
+ | Claude Code | 90 | Full |
18
+ | Codex (OpenAI) | 83 | Full |
19
+ | Gemini CLI (Google) | 83 | Full |
20
+ | GitHub Copilot | 83 | Full |
21
+ | Cursor | 83 | Full |
22
+ | Windsurf | 83 | Full |
23
+ | Aider | 85 | Full |
24
+ | OpenCode | 83 | Full |
24
25
 
25
26
  ---
26
27
 
@@ -61,7 +62,7 @@ npx @nerviq/cli benchmark # Before/after in isolated copy
61
62
 
62
63
  No install required. Zero dependencies.
63
64
 
64
- ## 90 Checks Across 14 Categories
65
+ ## 673 Checks Across 14 Categories
65
66
 
66
67
  | Category | Checks | Examples |
67
68
  |----------|--------|---------|
@@ -79,11 +80,126 @@ No install required. Zero dependencies.
79
80
  | Features | 2 | channels, worktrees |
80
81
  | Quality Deep | 9 | freshness, contradictions, deprecated patterns |
81
82
 
83
+ ## Harmony — Cross-Platform Alignment
84
+
85
+ Harmony detects drift between your AI coding platforms and keeps them in sync.
86
+
87
+ ```bash
88
+ npx @nerviq/cli harmony-audit # Cross-platform DX audit (0-100 harmony score)
89
+ npx @nerviq/cli harmony-sync # Sync shared config across platforms
90
+ npx @nerviq/cli harmony-drift # Detect drift between platform configs
91
+ npx @nerviq/cli harmony-advise # Cross-platform improvement advice
92
+ npx @nerviq/cli harmony-watch # Live monitoring for config drift
93
+ npx @nerviq/cli harmony-governance # Unified governance across platforms
94
+ ```
95
+
96
+ ## Synergy — Multi-Agent Amplification
97
+
98
+ Synergy analyzes how your platforms work together and finds amplification opportunities.
99
+
100
+ ```bash
101
+ npx @nerviq/cli synergy-report # Multi-agent synergy analysis
102
+ ```
103
+
104
+ Synergy evaluates compound audit results, discovers compensation patterns (where one platform covers another's gaps), and ranks recommendations by cross-platform impact.
105
+
106
+ ## SDK — `@nerviq/sdk`
107
+
108
+ Programmatic access to all Nerviq capabilities:
109
+
110
+ ```js
111
+ const { audit, harmonyAudit, synergyReport, detectPlatforms } = require('@nerviq/sdk');
112
+
113
+ const result = await audit('.', 'claude');
114
+ console.log(`Score: ${result.score}/100`);
115
+
116
+ const platforms = detectPlatforms('.');
117
+ console.log(`Active platforms: ${platforms.join(', ')}`);
118
+
119
+ const harmony = await harmonyAudit('.');
120
+ console.log(`Harmony score: ${harmony.harmonyScore}/100`);
121
+ ```
122
+
123
+ ## MCP Server — `nerviq serve`
124
+
125
+ Nerviq ships with a built-in MCP-compatible HTTP server for integration with AI agents:
126
+
127
+ ```bash
128
+ npx @nerviq/cli serve --port 3000
129
+ ```
130
+
131
+ Endpoints:
132
+ - `GET /api/health` — Server health check
133
+ - `GET /api/catalog` — Full check catalog
134
+ - `POST /api/audit` — Run audit on a directory
135
+ - `GET /api/harmony` — Cross-platform harmony data
136
+
137
+ ## Plugin System — `nerviq.config.js`
138
+
139
+ Extend Nerviq with custom checks via a config file in your project root:
140
+
141
+ ```js
142
+ // nerviq.config.js
143
+ module.exports = {
144
+ plugins: [
145
+ {
146
+ name: 'my-company-checks',
147
+ checks: {
148
+ internalDocs: {
149
+ id: 'internalDocs',
150
+ name: 'Internal docs present',
151
+ check: (dir) => require('fs').existsSync(`${dir}/docs/internal.md`),
152
+ impact: 'medium',
153
+ category: 'Quality',
154
+ fix: 'Add docs/internal.md with team-specific guidelines',
155
+ },
156
+ },
157
+ },
158
+ ],
159
+ };
160
+ ```
161
+
162
+ See [docs/plugins.md](docs/plugins.md) for full plugin API reference.
163
+
164
+ ## GitHub Action
165
+
166
+ Add Nerviq to your CI pipeline:
167
+
168
+ ```yaml
169
+ # .github/workflows/nerviq.yml
170
+ name: Nerviq Audit
171
+ on: [push, pull_request]
172
+
173
+ jobs:
174
+ audit:
175
+ runs-on: ubuntu-latest
176
+ steps:
177
+ - uses: actions/checkout@v4
178
+ - uses: nerviq/nerviq@v1
179
+ with:
180
+ threshold: 60
181
+ ```
182
+
183
+ The action outputs `score`, `passed`, and `total` for use in downstream steps. Fails the workflow if the score is below the configured threshold.
184
+
185
+ ## Certification
186
+
187
+ Earn a Nerviq certification badge for your project:
188
+
189
+ ```bash
190
+ npx @nerviq/cli certify # Run certification and display badge
191
+ ```
192
+
193
+ Levels:
194
+ - **Gold** — Harmony score >= 80, all platforms >= 70
195
+ - **Silver** — Harmony score >= 60, all platforms >= 50
196
+ - **Bronze** — Any platform >= 40
197
+
82
198
  ## All Commands
83
199
 
84
200
  | Command | What it does |
85
201
  |---------|-------------|
86
- | `nerviq audit` | Score 0-100 against 90 checks |
202
+ | `nerviq audit` | Score 0-100 against 673 checks |
87
203
  | `nerviq audit --lite` | Quick top-3 scan |
88
204
  | `nerviq setup` | Generate starter-safe CLAUDE.md + hooks + commands |
89
205
  | `nerviq augment` | Repo-aware improvement plan (no writes) |
@@ -100,7 +216,20 @@ No install required. Zero dependencies.
100
216
  | `nerviq trend` | Export trend report |
101
217
  | `nerviq feedback` | Record recommendation outcomes |
102
218
  | `nerviq badge` | shields.io badge for README |
219
+ | `nerviq certify` | Certification level + badge |
103
220
  | `nerviq scan dir1 dir2` | Compare multiple repos |
221
+ | `nerviq harmony-audit` | Cross-platform DX audit |
222
+ | `nerviq harmony-sync` | Sync config across platforms |
223
+ | `nerviq harmony-drift` | Detect platform drift |
224
+ | `nerviq harmony-advise` | Cross-platform advice |
225
+ | `nerviq harmony-watch` | Live drift monitoring |
226
+ | `nerviq harmony-governance` | Unified platform governance |
227
+ | `nerviq synergy-report` | Multi-agent synergy analysis |
228
+ | `nerviq catalog` | Show check catalog for all 8 platforms |
229
+ | `nerviq doctor` | Self-diagnostics |
230
+ | `nerviq convert` | Convert config between platforms |
231
+ | `nerviq migrate` | Migrate platform config versions |
232
+ | `nerviq serve` | Start local MCP-compatible HTTP API |
104
233
 
105
234
  ## Options
106
235
 
@@ -115,6 +244,17 @@ No install required. Zero dependencies.
115
244
  | `--auto` | Apply without prompts |
116
245
  | `--verbose` | Show all recommendations |
117
246
  | `--format sarif` | SARIF output for code scanning |
247
+ | `--platform NAME` | Target platform (claude, codex, gemini, copilot, cursor, windsurf, aider, opencode) |
248
+
249
+ ## Backed by Research
250
+
251
+ Nerviq is built on the CLAUDEX knowledge engine — the largest verified catalog of AI coding agent techniques:
252
+
253
+ - **315 research documents** covering all 8 platforms
254
+ - **100+ experiments** with tested, rated results
255
+ - **673 checks** each with `sourceUrl` and `confidence` level (0.0-1.0)
256
+ - Every check is traceable to primary documentation or verified experiment
257
+ - 90-day freshness cycle: stale findings are re-verified or pruned
118
258
 
119
259
  ## Privacy
120
260
 
package/bin/cli.js CHANGED
@@ -22,7 +22,7 @@ const COMMAND_ALIASES = {
22
22
  gov: 'governance',
23
23
  outcome: 'feedback',
24
24
  };
25
- const KNOWN_COMMANDS = ['audit', 'setup', 'augment', 'suggest-only', 'plan', 'apply', 'governance', 'benchmark', 'deep-review', 'interactive', 'watch', 'badge', 'insights', 'history', 'compare', 'trend', 'scan', 'feedback', 'doctor', 'convert', 'migrate', 'catalog', 'serve', 'help', 'version'];
25
+ const KNOWN_COMMANDS = ['audit', 'setup', 'augment', 'suggest-only', 'plan', 'apply', 'governance', 'benchmark', 'deep-review', 'interactive', 'watch', 'badge', 'insights', 'history', 'compare', 'trend', 'scan', 'feedback', 'doctor', 'convert', 'migrate', 'catalog', 'certify', 'serve', 'help', 'version'];
26
26
 
27
27
  function levenshtein(a, b) {
28
28
  const matrix = Array.from({ length: a.length + 1 }, () => Array(b.length + 1).fill(0));
@@ -211,109 +211,99 @@ function parseArgs(rawArgs) {
211
211
 
212
212
  const HELP = `
213
213
  nerviq v${version}
214
- Score your repo's Claude Code setup. Fix gaps safely. Benchmark the impact.
215
-
216
- Start here (read-only, nothing changes):
217
- npx nerviq Audit your project (10 seconds)
218
- npx nerviq --lite Quick scan: top 3 gaps + next command
219
- npx nerviq --platform codex Audit your Codex repo setup
220
- npx nerviq --platform codex augment Codex-aware advisory pass, no writes
221
- npx nerviq --platform codex suggest-only Structured Codex report, no writes
222
- npx nerviq augment Repo-aware analysis, no writes
223
- npx nerviq suggest-only Structured report, no writes
224
-
225
- Plan and apply (when you're ready to change things):
226
- npx nerviq plan Export proposal bundles with previews
227
- npx nerviq apply Apply proposals selectively with rollback
228
- npx nerviq setup Generate starter-safe baseline
229
- npx nerviq setup --auto Apply all generated files without prompts
230
-
231
- Track progress over time:
232
- npx nerviq history Show score history from saved snapshots
233
- npx nerviq compare Compare latest vs previous snapshot
234
- npx nerviq trend --out r.md Export trend report as markdown
235
-
236
- Multi-repo:
237
- npx nerviq scan dir1 dir2 Compare multiple repos side-by-side
238
-
239
- Advanced:
240
- npx nerviq governance Permission profiles, hooks, policy packs
241
- npx nerviq benchmark Before/after in isolated temp copy
242
- npx nerviq deep-review AI-powered config review (opt-in, uses API)
243
- npx nerviq interactive Step-by-step guided wizard
244
- npx nerviq watch Live monitoring on config changes with cross-platform watch fallback
245
- npx nerviq serve --port 3000 Start the local Nerviq HTTP API
246
- npx nerviq badge Generate shields.io badge markdown
247
- npx nerviq feedback Record recommendation outcomes or show local outcome summary
248
-
249
- Catalog:
250
- npx nerviq catalog Show check catalog summary for all 8 platforms
251
- npx nerviq catalog --json Full catalog as JSON
252
- npx nerviq catalog --out catalog.json Write catalog to file
253
-
254
- Utilities:
255
- npx nerviq doctor Self-diagnostics: Node version, deps, freshness gates, platform detection
256
- npx nerviq convert --from claude --to codex Convert config between platforms
257
- npx nerviq migrate --platform cursor --from v2 --to v3 Migrate platform config to newer version
258
-
259
- Options:
260
- --threshold N Exit with code 1 if score is below N (useful for CI)
261
- --require A,B Exit with code 1 if named checks fail (e.g. --require secretsProtection,permissionDeny)
262
- --out FILE Write JSON or markdown output to a file
263
- --plan FILE Load a previously exported plan file
264
- --only A,B Limit plan/apply to selected proposal ids or technique keys
265
- --profile NAME Choose permission profile (read-only, suggest-only, safe-write, power-user, internal-research)
266
- --mcp-pack A,B Merge named MCP packs into generated settings (e.g. context7-docs,next-devtools)
267
- --key NAME Recommendation key for feedback logging (e.g. permissionDeny)
268
- --status VALUE Feedback status: accepted, rejected, deferred
269
- --effect VALUE Feedback effect: positive, neutral, negative
270
- --notes TEXT Short notes to store with a feedback event
271
- --source NAME Source label for feedback event (default: manual-cli)
272
- --score-delta N Optional observed score delta tied to the outcome
273
- --platform NAME Choose platform surface (claude default, codex advisory/build preview)
274
- --format NAME Output format for audit results (json, sarif)
275
- --port N Port for \`serve\` (default: 3000)
276
- --feedback After audit output, prompt "Was this helpful? (y/n)" for each displayed top action and save answers locally
277
- --snapshot Save a normalized snapshot artifact under .claude/nerviq/snapshots/
278
- --lite Show a short top-3 quick scan with one clear next command
279
- --dry-run Preview apply without writing files
280
- --verbose Show all recommendations (not just critical/high)
281
- --json Output as JSON (for CI pipelines)
282
- --auto Apply all generated setup files without prompting
283
- --insights Enable anonymous usage insights (off by default)
284
- --help Show this help
285
- --version Show version
286
-
287
- Examples:
214
+ The intelligent nervous system for AI coding agents.
215
+ Audit, align, and amplify every platform on every project.
216
+
217
+ DISCOVER
218
+ nerviq audit Score your project (0-100)
219
+ nerviq audit --platform X Audit specific platform (claude|codex|cursor|copilot|gemini|windsurf|aider|opencode)
220
+ nerviq audit --lite Quick scan: top 3 gaps + next command
221
+ nerviq audit --json Machine-readable JSON output (for CI)
222
+ nerviq scan dir1 dir2 Compare multiple repos side-by-side
223
+ nerviq catalog Full check catalog (all 8 platforms)
224
+ nerviq catalog --json Export full check catalog as JSON
225
+
226
+ SETUP
227
+ nerviq setup Generate starter-safe baseline config files
228
+ nerviq setup --auto Apply all generated files without prompts
229
+ nerviq interactive Step-by-step guided wizard
230
+ nerviq doctor Self-diagnostics: Node, deps, freshness, platform detection
231
+
232
+ IMPROVE
233
+ nerviq augment Improvement plan (no writes)
234
+ nerviq suggest-only Structured report for sharing (no writes)
235
+ nerviq plan Export proposal bundles with diffs
236
+ nerviq plan --out plan.json Save plan to file
237
+ nerviq apply Apply proposals selectively with rollback
238
+ nerviq apply --dry-run Preview changes without writing
239
+
240
+ GOVERN
241
+ nerviq governance Permission profiles + hooks + policy packs
242
+ nerviq governance --json Machine-readable governance summary
243
+ nerviq benchmark Before/after score in isolated temp copy
244
+ nerviq certify Generate certification badge for your project
245
+
246
+ CROSS-PLATFORM
247
+ nerviq harmony-audit Drift detection across all active platforms
248
+ nerviq synergy-report Multi-agent amplification opportunities
249
+ nerviq convert --from X --to Y Convert configs between platforms
250
+ nerviq migrate --platform X Platform version migration helper
251
+ nerviq migrate --platform cursor --from v2 --to v3
252
+
253
+ MONITOR
254
+ nerviq watch Live config monitoring (re-audits on file change)
255
+ nerviq history Score history from saved snapshots
256
+ nerviq compare Latest vs previous snapshot diff
257
+ nerviq trend Score trend over time
258
+ nerviq trend --out report.md Export trend report as markdown
259
+ nerviq feedback Record recommendation outcomes
260
+
261
+ ADVANCED
262
+ nerviq deep-review AI-powered config review (opt-in, uses API key)
263
+ nerviq serve --port 3000 Start local Nerviq REST API server
264
+ nerviq badge Generate shields.io badge markdown
265
+
266
+ OPTIONS
267
+ --platform NAME Platform: claude (default), codex, cursor, copilot, gemini, windsurf, aider, opencode
268
+ --threshold N Exit code 1 if score < N (CI gate)
269
+ --require A,B Exit code 1 if named checks fail
270
+ --out FILE Write output to file (JSON or markdown)
271
+ --plan FILE Load previously exported plan file
272
+ --only A,B Limit plan/apply to selected proposal IDs
273
+ --profile NAME Permission profile: read-only | suggest-only | safe-write | power-user
274
+ --mcp-pack A,B Merge MCP packs into setup (e.g. context7-docs,next-devtools)
275
+ --format NAME Output format: json | sarif
276
+ --port N Port for \`serve\` (default: 3000)
277
+ --snapshot Save snapshot artifact under .claude/nerviq/snapshots/
278
+ --lite Short top-3 scan with one clear next step
279
+ --dry-run Preview changes without writing files
280
+ --verbose Show all checks (not just critical/high)
281
+ --json Output as JSON
282
+ --auto Apply all generated files without prompting
283
+ --key NAME Feedback: recommendation key (e.g. permissionDeny)
284
+ --status VALUE Feedback: accepted | rejected | deferred
285
+ --effect VALUE Feedback: positive | neutral | negative
286
+ --score-delta N Feedback: observed score delta
287
+ --help Show this help
288
+ --version Show version
289
+
290
+ EXAMPLES
288
291
  npx nerviq
289
292
  npx nerviq --lite
290
- npx nerviq --platform codex
293
+ npx nerviq --platform cursor
291
294
  npx nerviq --platform codex augment
292
- npx nerviq --platform codex suggest-only --json
293
- npx nerviq --platform codex setup
294
- npx nerviq --platform codex plan --out codex-plan.json
295
- npx nerviq --platform codex --format sarif
296
- npx nerviq --snapshot
297
- npx nerviq augment
298
- npx nerviq augment --snapshot
299
- npx nerviq suggest-only --json
300
- npx nerviq governance --snapshot
301
- npx nerviq plan --out claudex-plan.json
302
- npx nerviq plan --profile safe-write
295
+ npx nerviq scan ./app ./api ./infra
296
+ npx nerviq harmony-audit
297
+ npx nerviq convert --from claude --to codex
298
+ npx nerviq migrate --platform cursor --from v2 --to v3
303
299
  npx nerviq setup --mcp-pack context7-docs
304
- npx nerviq apply --plan claudex-plan.json --only hooks,commands
305
- npx nerviq apply --mcp-pack context7-docs,next-devtools --only hooks
306
- npx nerviq apply --profile power-user --only claude-md,hooks
307
- npx nerviq governance --json
308
- npx nerviq benchmark --out benchmark.md
309
- npx nerviq feedback
310
- npx nerviq feedback --key permissionDeny --status accepted --effect positive --score-delta 12
311
- npx nerviq serve --port 3000
312
- npx nerviq --json --threshold 60
313
- npx nerviq setup --auto
314
- npx nerviq interactive
315
-
316
- Exit codes:
300
+ npx nerviq apply --plan plan.json --only hooks,commands
301
+ npx nerviq serve --port 4000
302
+ npx nerviq --json --threshold 70
303
+ npx nerviq catalog --json --out catalog.json
304
+ npx nerviq feedback --key permissionDeny --status accepted --effect positive
305
+
306
+ EXIT CODES
317
307
  0 Success
318
308
  1 Error, unknown command, or score below --threshold
319
309
  `;
@@ -413,7 +403,7 @@ async function main() {
413
403
  const FULL_COMMAND_SET = new Set([
414
404
  'audit', 'scan', 'badge', 'augment', 'suggest-only', 'setup', 'plan', 'apply',
415
405
  'governance', 'benchmark', 'deep-review', 'interactive', 'watch', 'insights',
416
- 'history', 'compare', 'trend', 'feedback', 'catalog', 'serve', 'help', 'version',
406
+ 'history', 'compare', 'trend', 'feedback', 'catalog', 'certify', 'serve', 'help', 'version',
417
407
  // Harmony + Synergy (cross-platform)
418
408
  'harmony-audit', 'harmony-sync', 'harmony-drift', 'harmony-advise',
419
409
  'harmony-watch', 'harmony-governance', 'synergy-report',
@@ -768,6 +758,34 @@ async function main() {
768
758
  }
769
759
  }
770
760
  process.exit(0);
761
+ } else if (normalizedCommand === 'certify') {
762
+ const { certifyProject, generateCertBadge } = require('../src/certification');
763
+ const certResult = await certifyProject(options.dir);
764
+ if (options.json) {
765
+ console.log(JSON.stringify(certResult, null, 2));
766
+ } else {
767
+ console.log('');
768
+ console.log('\x1b[1m nerviq certification\x1b[0m');
769
+ console.log('\x1b[2m ═══════════════════════════════════════\x1b[0m');
770
+ console.log('');
771
+ console.log(` Level: \x1b[1m${certResult.level}\x1b[0m`);
772
+ console.log(` Harmony Score: ${certResult.harmonyScore}/100`);
773
+ console.log('');
774
+ if (Object.keys(certResult.platformScores).length > 0) {
775
+ console.log(' Platform Scores:');
776
+ for (const [plat, score] of Object.entries(certResult.platformScores)) {
777
+ const scoreColor = score >= 70 ? '\x1b[32m' : score >= 40 ? '\x1b[33m' : '\x1b[31m';
778
+ console.log(` ${plat.padEnd(12)} ${scoreColor}${score}/100\x1b[0m`);
779
+ }
780
+ console.log('');
781
+ }
782
+ console.log(' Badge:');
783
+ console.log(` ${certResult.badge}`);
784
+ console.log('');
785
+ console.log(' Add the badge to your README.md');
786
+ console.log('');
787
+ }
788
+ process.exit(0);
771
789
  } else if (normalizedCommand === 'serve') {
772
790
  const server = await startServer({
773
791
  port: options.port == null ? 3000 : options.port,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nerviq/cli",
3
- "version": "0.9.6",
4
- "description": "The intelligent nervous system for AI coding agents — audit, align, and amplify every platform on every project.",
3
+ "version": "1.0.1",
4
+ "description": "The intelligent nervous system for AI coding agents — 673 checks across 8 platforms. Audit, align, and amplify.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "nerviq": "bin/cli.js",
@@ -9,10 +9,8 @@
9
9
  },
10
10
  "files": [
11
11
  "bin",
12
- "content",
13
12
  "src",
14
- "README.md",
15
- "CHANGELOG.md"
13
+ "README.md"
16
14
  ],
17
15
  "scripts": {
18
16
  "start": "node bin/cli.js",
@@ -20,7 +18,7 @@
20
18
  "test": "node test/run.js",
21
19
  "test:jest": "jest",
22
20
  "test:coverage": "jest --coverage",
23
- "test:all": "node test/run.js && node test/check-matrix.js && node test/codex-check-matrix.js && node test/golden-matrix.js && node test/codex-golden-matrix.js && node test/gemini-check-matrix.js && node test/gemini-golden-matrix.js && node test/copilot-check-matrix.js && node test/copilot-golden-matrix.js && node test/cursor-check-matrix.js && node test/cursor-golden-matrix.js && node test/security-tests.js && jest",
21
+ "test:all": "npm test && npx jest && node test/check-matrix.js && node test/codex-check-matrix.js && node test/gemini-check-matrix.js && node test/copilot-check-matrix.js && node test/cursor-check-matrix.js && node test/golden-matrix.js && node test/codex-golden-matrix.js && node test/gemini-golden-matrix.js && node test/copilot-golden-matrix.js && node test/cursor-golden-matrix.js",
24
22
  "benchmark:perf": "node tools/benchmark.js",
25
23
  "catalog": "node -e \"const {generateCatalog}=require('./src/catalog');console.log(JSON.stringify(generateCatalog(),null,2))\""
26
24
  },
package/src/audit.js CHANGED
@@ -25,6 +25,7 @@ const { OpenCodeProjectContext } = require('./opencode/context');
25
25
  const { getBadgeMarkdown } = require('./badge');
26
26
  const { sendInsights, getLocalInsights } = require('./insights');
27
27
  const { getRecommendationOutcomeSummary, getRecommendationAdjustment } = require('./activity');
28
+ const { getFeedbackSummary } = require('./feedback');
28
29
  const { formatSarif } = require('./formatters/sarif');
29
30
  const { loadPlugins, mergePluginChecks } = require('./plugins');
30
31
 
@@ -441,24 +442,48 @@ function getQuickWins(failed, options = {}) {
441
442
  .slice(0, 3);
442
443
  }
443
444
 
444
- function getRecommendationPriorityScore(item, outcomeSummaryByKey = {}) {
445
+ /**
446
+ * Compute a multiplier based on FP (helpful/not-helpful) feedback for a check key.
447
+ * - >50% "not helpful" feedback: lower priority by 30% (multiplier 0.7)
448
+ * - >80% "helpful" feedback: boost priority by 20% (multiplier 1.2)
449
+ * - Otherwise: no change (multiplier 1.0)
450
+ * @param {Object} fpFeedbackByKey - Keyed feedback summary from getFeedbackSummary().byKey
451
+ * @param {string} key - The check key to look up
452
+ * @returns {number} Multiplier to apply to priority score
453
+ */
454
+ function getFpFeedbackMultiplier(fpFeedbackByKey, key) {
455
+ if (!fpFeedbackByKey) return 1.0;
456
+ const bucket = fpFeedbackByKey[key];
457
+ if (!bucket || bucket.total === 0) return 1.0;
458
+
459
+ const unhelpfulRate = bucket.unhelpful / bucket.total;
460
+ const helpfulRate = bucket.helpful / bucket.total;
461
+
462
+ if (unhelpfulRate > 0.5) return 0.7;
463
+ if (helpfulRate > 0.8) return 1.2;
464
+ return 1.0;
465
+ }
466
+
467
+ function getRecommendationPriorityScore(item, outcomeSummaryByKey = {}, fpFeedbackByKey = null) {
445
468
  const impactScore = (IMPACT_ORDER[item.impact] ?? 0) * 100;
446
469
  const feedbackAdjustment = getRecommendationAdjustment(outcomeSummaryByKey, item.key);
447
470
  const brevityPenalty = Math.min((item.fix || '').length, 240) / 20;
448
- return impactScore + (feedbackAdjustment * 10) - brevityPenalty;
471
+ const raw = impactScore + (feedbackAdjustment * 10) - brevityPenalty;
472
+ return raw * getFpFeedbackMultiplier(fpFeedbackByKey, item.key);
449
473
  }
450
474
 
451
475
  function buildTopNextActions(failed, limit = 5, outcomeSummaryByKey = {}, options = {}) {
452
476
  const pool = getPrioritizedFailed(failed);
477
+ const fpByKey = options.fpFeedbackByKey || null;
453
478
 
454
479
  return [...pool]
455
480
  .sort((a, b) => {
456
481
  const scoreB = options.platform === 'codex'
457
482
  ? codexPriorityScore(b, outcomeSummaryByKey)
458
- : getRecommendationPriorityScore(b, outcomeSummaryByKey);
483
+ : getRecommendationPriorityScore(b, outcomeSummaryByKey, fpByKey);
459
484
  const scoreA = options.platform === 'codex'
460
485
  ? codexPriorityScore(a, outcomeSummaryByKey)
461
- : getRecommendationPriorityScore(a, outcomeSummaryByKey);
486
+ : getRecommendationPriorityScore(a, outcomeSummaryByKey, fpByKey);
462
487
  return scoreB - scoreA;
463
488
  })
464
489
  .slice(0, limit)
@@ -479,7 +504,7 @@ function buildTopNextActions(failed, limit = 5, outcomeSummaryByKey = {}, option
479
504
  const evidenceClass = options.platform === 'codex' ? codexEvidenceClass(fullItem) : (feedback ? 'measured' : 'estimated');
480
505
  const priorityScore = options.platform === 'codex'
481
506
  ? codexPriorityScore(fullItem, outcomeSummaryByKey)
482
- : Math.max(0, Math.min(100, Math.round(getRecommendationPriorityScore(fullItem, outcomeSummaryByKey) / 3)));
507
+ : Math.max(0, Math.min(100, Math.round(getRecommendationPriorityScore(fullItem, outcomeSummaryByKey, fpByKey) / 3)));
483
508
 
484
509
  signals.push(`evidence:${evidenceClass}`);
485
510
  if (options.platform === 'codex' && CODEX_HARD_FAIL_KEYS.has(key)) {
@@ -728,6 +753,7 @@ async function audit(options) {
728
753
  const stacks = ctx.detectStacks(STACKS);
729
754
  const results = [];
730
755
  const outcomeSummary = getRecommendationOutcomeSummary(options.dir);
756
+ const fpFeedback = getFeedbackSummary(options.dir);
731
757
 
732
758
  // Load and merge plugin checks
733
759
  const plugins = loadPlugins(options.dir);
@@ -795,7 +821,7 @@ async function audit(options) {
795
821
  const organicEarned = organicPassed.reduce((sum, r) => sum + (WEIGHTS[r.impact] || 5), 0);
796
822
  const organicScore = maxScore > 0 ? Math.round((organicEarned / maxScore) * 100) : 0;
797
823
  const quickWins = getQuickWins(failed, { platform: spec.platform });
798
- const topNextActions = buildTopNextActions(failed, 5, outcomeSummary.byKey, { platform: spec.platform });
824
+ const topNextActions = buildTopNextActions(failed, 5, outcomeSummary.byKey, { platform: spec.platform, fpFeedbackByKey: fpFeedback.byKey });
799
825
  const categoryScores = computeCategoryScores(applicable, passed);
800
826
  const platformScopeNote = getPlatformScopeNote(spec, ctx);
801
827
  const platformCaveats = getPlatformCaveats(spec, ctx);
@@ -1008,4 +1034,4 @@ async function audit(options) {
1008
1034
  return result;
1009
1035
  }
1010
1036
 
1011
- module.exports = { audit, buildTopNextActions };
1037
+ module.exports = { audit, buildTopNextActions, getFpFeedbackMultiplier, getRecommendationPriorityScore };