@nerviq/cli 0.9.2 → 0.9.4
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/bin/cli.js +64 -3
- package/package.json +3 -2
- package/src/aider/techniques.js +85 -11
- package/src/audit.js +3 -2
- package/src/codex/techniques.js +3 -0
- package/src/convert.js +336 -0
- package/src/copilot/techniques.js +125 -11
- package/src/cursor/techniques.js +93 -10
- package/src/doctor.js +253 -0
- package/src/feedback.js +173 -0
- package/src/freshness.js +177 -0
- package/src/gemini/techniques.js +177 -23
- package/src/mcp-server.js +373 -0
- package/src/migrate.js +354 -0
- package/src/opencode/techniques.js +73 -99
- package/src/source-urls.js +219 -0
- package/src/techniques.js +3 -0
- package/src/windsurf/techniques.js +214 -138
package/bin/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ const { buildProposalBundle, printProposalBundle, writePlanFile, applyProposalBu
|
|
|
7
7
|
const { getGovernanceSummary, printGovernanceSummary, ensureWritableProfile, renderGovernanceMarkdown } = require('../src/governance');
|
|
8
8
|
const { runBenchmark, printBenchmark, writeBenchmarkReport } = require('../src/benchmark');
|
|
9
9
|
const { writeSnapshotArtifact, recordRecommendationOutcome, formatRecommendationOutcomeSummary, getRecommendationOutcomeSummary } = require('../src/activity');
|
|
10
|
+
const { collectFeedback } = require('../src/feedback');
|
|
10
11
|
const { version } = require('../package.json');
|
|
11
12
|
|
|
12
13
|
const args = process.argv.slice(2);
|
|
@@ -20,7 +21,7 @@ const COMMAND_ALIASES = {
|
|
|
20
21
|
gov: 'governance',
|
|
21
22
|
outcome: 'feedback',
|
|
22
23
|
};
|
|
23
|
-
const KNOWN_COMMANDS = ['audit', 'setup', 'augment', 'suggest-only', 'plan', 'apply', 'governance', 'benchmark', 'deep-review', 'interactive', 'watch', 'badge', 'insights', 'history', 'compare', 'trend', 'scan', 'feedback', 'help', 'version'];
|
|
24
|
+
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', 'help', 'version'];
|
|
24
25
|
|
|
25
26
|
function levenshtein(a, b) {
|
|
26
27
|
const matrix = Array.from({ length: a.length + 1 }, () => Array(b.length + 1).fill(0));
|
|
@@ -73,11 +74,15 @@ function parseArgs(rawArgs) {
|
|
|
73
74
|
let format = null;
|
|
74
75
|
let commandSet = false;
|
|
75
76
|
let extraArgs = [];
|
|
77
|
+
let convertFrom = null;
|
|
78
|
+
let convertTo = null;
|
|
79
|
+
let migrateFrom = null;
|
|
80
|
+
let migrateTo = null;
|
|
76
81
|
|
|
77
82
|
for (let i = 0; i < rawArgs.length; i++) {
|
|
78
83
|
const arg = rawArgs[i];
|
|
79
84
|
|
|
80
|
-
if (arg === '--threshold' || arg === '--out' || arg === '--plan' || arg === '--only' || arg === '--profile' || arg === '--mcp-pack' || arg === '--require' || arg === '--key' || arg === '--status' || arg === '--effect' || arg === '--notes' || arg === '--source' || arg === '--score-delta' || arg === '--platform' || arg === '--format') {
|
|
85
|
+
if (arg === '--threshold' || arg === '--out' || arg === '--plan' || arg === '--only' || arg === '--profile' || arg === '--mcp-pack' || arg === '--require' || arg === '--key' || arg === '--status' || arg === '--effect' || arg === '--notes' || arg === '--source' || arg === '--score-delta' || arg === '--platform' || arg === '--format' || arg === '--from' || arg === '--to') {
|
|
81
86
|
const value = rawArgs[i + 1];
|
|
82
87
|
if (!value || value.startsWith('--')) {
|
|
83
88
|
throw new Error(`${arg} requires a value`);
|
|
@@ -97,6 +102,8 @@ function parseArgs(rawArgs) {
|
|
|
97
102
|
if (arg === '--score-delta') feedbackScoreDelta = value.trim();
|
|
98
103
|
if (arg === '--platform') platform = value.trim().toLowerCase();
|
|
99
104
|
if (arg === '--format') format = value.trim().toLowerCase();
|
|
105
|
+
if (arg === '--from') { convertFrom = value.trim(); migrateFrom = value.trim(); }
|
|
106
|
+
if (arg === '--to') { convertTo = value.trim(); migrateTo = value.trim(); }
|
|
100
107
|
i++;
|
|
101
108
|
continue;
|
|
102
109
|
}
|
|
@@ -191,7 +198,7 @@ function parseArgs(rawArgs) {
|
|
|
191
198
|
|
|
192
199
|
const normalizedCommand = COMMAND_ALIASES[command] || command;
|
|
193
200
|
|
|
194
|
-
return { flags, command, normalizedCommand, threshold, out, planFile, only, profile, mcpPacks, requireChecks, feedbackKey, feedbackStatus, feedbackEffect, feedbackNotes, feedbackSource, feedbackScoreDelta, platform, format, extraArgs };
|
|
201
|
+
return { flags, command, normalizedCommand, threshold, out, planFile, only, profile, mcpPacks, requireChecks, feedbackKey, feedbackStatus, feedbackEffect, feedbackNotes, feedbackSource, feedbackScoreDelta, platform, format, extraArgs, convertFrom, convertTo, migrateFrom, migrateTo };
|
|
195
202
|
}
|
|
196
203
|
|
|
197
204
|
const HELP = `
|
|
@@ -230,6 +237,11 @@ const HELP = `
|
|
|
230
237
|
npx nerviq badge Generate shields.io badge markdown
|
|
231
238
|
npx nerviq feedback Record recommendation outcomes or show local outcome summary
|
|
232
239
|
|
|
240
|
+
Utilities:
|
|
241
|
+
npx nerviq doctor Self-diagnostics: Node version, deps, freshness gates, platform detection
|
|
242
|
+
npx nerviq convert --from claude --to codex Convert config between platforms
|
|
243
|
+
npx nerviq migrate --platform cursor --from v2 --to v3 Migrate platform config to newer version
|
|
244
|
+
|
|
233
245
|
Options:
|
|
234
246
|
--threshold N Exit with code 1 if score is below N (useful for CI)
|
|
235
247
|
--require A,B Exit with code 1 if named checks fail (e.g. --require secretsProtection,permissionDeny)
|
|
@@ -246,6 +258,7 @@ const HELP = `
|
|
|
246
258
|
--score-delta N Optional observed score delta tied to the outcome
|
|
247
259
|
--platform NAME Choose platform surface (claude default, codex advisory/build preview)
|
|
248
260
|
--format NAME Output format for audit results (json, sarif)
|
|
261
|
+
--feedback After audit output, prompt "Was this helpful? (y/n)" for each displayed top action and save answers locally
|
|
249
262
|
--snapshot Save a normalized snapshot artifact under .claude/nerviq/snapshots/
|
|
250
263
|
--lite Show a short top-3 quick scan with one clear next command
|
|
251
264
|
--dry-run Preview apply without writing files
|
|
@@ -316,6 +329,7 @@ async function main() {
|
|
|
316
329
|
auto: flags.includes('--auto'),
|
|
317
330
|
lite: flags.includes('--lite'),
|
|
318
331
|
snapshot: flags.includes('--snapshot'),
|
|
332
|
+
feedback: flags.includes('--feedback'),
|
|
319
333
|
dryRun: flags.includes('--dry-run'),
|
|
320
334
|
threshold: parsed.threshold !== null ? Number(parsed.threshold) : null,
|
|
321
335
|
out: parsed.out,
|
|
@@ -699,6 +713,34 @@ async function main() {
|
|
|
699
713
|
} else if (normalizedCommand === 'watch') {
|
|
700
714
|
const { watch } = require('../src/watch');
|
|
701
715
|
await watch(options);
|
|
716
|
+
} else if (normalizedCommand === 'doctor') {
|
|
717
|
+
const { runDoctor } = require('../src/doctor');
|
|
718
|
+
const output = await runDoctor({ dir: options.dir, json: options.json, verbose: options.verbose });
|
|
719
|
+
console.log(output);
|
|
720
|
+
process.exit(0);
|
|
721
|
+
} else if (normalizedCommand === 'convert') {
|
|
722
|
+
const { runConvert } = require('../src/convert');
|
|
723
|
+
const output = await runConvert({
|
|
724
|
+
dir: options.dir,
|
|
725
|
+
from: parsed.convertFrom,
|
|
726
|
+
to: parsed.convertTo,
|
|
727
|
+
dryRun: options.dryRun,
|
|
728
|
+
json: options.json,
|
|
729
|
+
});
|
|
730
|
+
console.log(output);
|
|
731
|
+
process.exit(0);
|
|
732
|
+
} else if (normalizedCommand === 'migrate') {
|
|
733
|
+
const { runMigrate } = require('../src/migrate');
|
|
734
|
+
const output = await runMigrate({
|
|
735
|
+
dir: options.dir,
|
|
736
|
+
platform: options.platform || parsed.platform || 'claude',
|
|
737
|
+
from: parsed.migrateFrom,
|
|
738
|
+
to: parsed.migrateTo,
|
|
739
|
+
dryRun: options.dryRun,
|
|
740
|
+
json: options.json,
|
|
741
|
+
});
|
|
742
|
+
console.log(output);
|
|
743
|
+
process.exit(0);
|
|
702
744
|
} else if (normalizedCommand === 'setup') {
|
|
703
745
|
await setup(options);
|
|
704
746
|
if (options.snapshot) {
|
|
@@ -712,6 +754,25 @@ async function main() {
|
|
|
712
754
|
}
|
|
713
755
|
} else {
|
|
714
756
|
const result = await audit(options);
|
|
757
|
+
if (options.feedback && !options.json && options.format === null) {
|
|
758
|
+
const feedbackTargets = options.lite
|
|
759
|
+
? (result.liteSummary?.topNextActions || [])
|
|
760
|
+
: (result.topNextActions || []);
|
|
761
|
+
const feedbackResult = await collectFeedback(options.dir, {
|
|
762
|
+
findings: feedbackTargets,
|
|
763
|
+
platform: result.platform,
|
|
764
|
+
sourceCommand: normalizedCommand,
|
|
765
|
+
score: result.score,
|
|
766
|
+
});
|
|
767
|
+
if (feedbackResult.mode === 'skipped-noninteractive') {
|
|
768
|
+
console.log(' Feedback prompt skipped: interactive terminal required.');
|
|
769
|
+
console.log('');
|
|
770
|
+
} else if (feedbackResult.saved > 0) {
|
|
771
|
+
console.log(` Feedback saved: ${feedbackResult.relativeDir}`);
|
|
772
|
+
console.log(` Helpful: ${feedbackResult.helpful} | Not helpful: ${feedbackResult.unhelpful}`);
|
|
773
|
+
console.log('');
|
|
774
|
+
}
|
|
775
|
+
}
|
|
715
776
|
const snapshot = options.snapshot ? writeSnapshotArtifact(options.dir, 'audit', result, {
|
|
716
777
|
sourceCommand: normalizedCommand,
|
|
717
778
|
}) : null;
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nerviq/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "The intelligent nervous system for AI coding agents — audit, align, and amplify every platform on every project.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"nerviq": "bin/cli.js"
|
|
7
|
+
"nerviq": "bin/cli.js",
|
|
8
|
+
"nerviq-mcp": "src/mcp-server.js"
|
|
8
9
|
},
|
|
9
10
|
"files": [
|
|
10
11
|
"bin",
|
package/src/aider/techniques.js
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Aider Technique Database —
|
|
2
|
+
* Aider Technique Database — 71 checks (AD-A01 through AD-P06)
|
|
3
3
|
*
|
|
4
4
|
* Aider is fundamentally different from IDE platforms:
|
|
5
5
|
* - Git-first CLI tool: git is the ONLY safety mechanism
|
|
6
6
|
* - No hooks, no MCP, no skills, no agents
|
|
7
7
|
* - Config: .aider.conf.yml (YAML), .aider.model.settings.yml, .env
|
|
8
8
|
* - 3 model roles: main (coding), editor (applying), weak (commit messages)
|
|
9
|
-
* - Architect mode (2-model workflow)
|
|
10
|
-
* - Convention files must be
|
|
9
|
+
* - Architect mode (2-model workflow, ~1.73x cost vs standard)
|
|
10
|
+
* - Convention files must be EXPLICITLY passed AND referenced in prompts (no auto-discovery)
|
|
11
11
|
* - 4-level config precedence: env vars > CLI args > .aider.conf.yml > defaults
|
|
12
|
+
* - Key gotcha: default auto-commit bypasses pre-commit hooks (use --git-commit-verify)
|
|
13
|
+
* - Key gotcha: exit code 0 returned even on auth failure in headless mode
|
|
14
|
+
* - Key gotcha: Playwright auto-scrapes URLs in messages (unexpected side effect)
|
|
12
15
|
*
|
|
13
|
-
* Categories: Config(8), Git Safety(
|
|
14
|
-
* Architecture(4), Security(6), CI(4), Quality(6) + M/N/O/P expansion (
|
|
16
|
+
* Categories: Config(8), Git Safety(10), Model Config(8), Conventions(6),
|
|
17
|
+
* Architecture(4), Security(6), CI(4), Quality(6) + M/N/O/P expansion (19)
|
|
15
18
|
*
|
|
16
19
|
* Check ID prefix: AD-
|
|
17
20
|
*/
|
|
18
21
|
|
|
19
22
|
const { containsEmbeddedSecret } = require('../secret-patterns');
|
|
23
|
+
const { attachSourceUrls } = require('../source-urls');
|
|
20
24
|
|
|
21
25
|
const FILLER_PATTERNS = [
|
|
22
26
|
/\bbe helpful\b/i,
|
|
@@ -421,7 +425,7 @@ const AIDER_TECHNIQUES = {
|
|
|
421
425
|
impact: 'high',
|
|
422
426
|
rating: 4,
|
|
423
427
|
category: 'model-config',
|
|
424
|
-
fix: 'Set `architect: true` to use a 2-model workflow (architect plans, editor applies).',
|
|
428
|
+
fix: 'Set `architect: true` to use a 2-model workflow (architect plans, editor applies). NOTE: architect mode costs ~1.73x standard mode per edit ($0.00026 vs $0.00015 measured in live experiment). auto_accept_architect is on by default — no confirmation between steps.',
|
|
425
429
|
template: 'aider-conf-yml',
|
|
426
430
|
file: () => '.aider.conf.yml',
|
|
427
431
|
line: (ctx) => firstLineMatching(configContent(ctx), /architect\s*:/i),
|
|
@@ -540,7 +544,7 @@ const AIDER_TECHNIQUES = {
|
|
|
540
544
|
impact: 'high',
|
|
541
545
|
rating: 4,
|
|
542
546
|
category: 'conventions',
|
|
543
|
-
fix: 'Add `read: [CONVENTIONS.md]` to .aider.conf.yml — Aider has NO auto-discovery.',
|
|
547
|
+
fix: 'Add `read: [CONVENTIONS.md]` to .aider.conf.yml — Aider has NO auto-discovery. Additionally, convention files are only followed when EXPLICITLY referenced in the prompt itself (confirmed by live experiment with gpt-4o-mini). Just loading them via --read is not enough; your prompts must say "follow the conventions in CONVENTIONS.md".',
|
|
544
548
|
template: 'aider-conf-yml',
|
|
545
549
|
file: () => '.aider.conf.yml',
|
|
546
550
|
line: (ctx) => firstLineMatching(configContent(ctx), /read\s*:/i),
|
|
@@ -867,15 +871,64 @@ const AIDER_TECHNIQUES = {
|
|
|
867
871
|
Boolean(ctx.fileContent('.husky/pre-commit')) ||
|
|
868
872
|
Boolean(ctx.fileContent('.lefthook.yml'));
|
|
869
873
|
},
|
|
870
|
-
impact: '
|
|
871
|
-
rating:
|
|
874
|
+
impact: 'high',
|
|
875
|
+
rating: 4,
|
|
872
876
|
category: 'ci',
|
|
873
|
-
fix: 'Add pre-commit hooks (pre-commit, husky, lefthook) to
|
|
877
|
+
fix: 'Add pre-commit hooks (pre-commit, husky, lefthook). IMPORTANT: Aider default auto-commit BYPASSES pre-commit hooks (confirmed by live experiment). If hooks are critical, pass --git-commit-verify to Aider to restore hook enforcement.',
|
|
874
878
|
template: null,
|
|
875
879
|
file: () => null,
|
|
876
880
|
line: () => null,
|
|
877
881
|
},
|
|
878
882
|
|
|
883
|
+
aiderGitCommitVerify: {
|
|
884
|
+
id: 'AD-G05',
|
|
885
|
+
name: '--git-commit-verify recommended when pre-commit hooks exist',
|
|
886
|
+
check: (ctx) => {
|
|
887
|
+
// Only relevant if pre-commit hooks exist
|
|
888
|
+
const hasHooks = Boolean(ctx.fileContent('.pre-commit-config.yaml')) ||
|
|
889
|
+
Boolean(ctx.fileContent('.husky/pre-commit')) ||
|
|
890
|
+
Boolean(ctx.fileContent('.lefthook.yml'));
|
|
891
|
+
if (!hasHooks) return null;
|
|
892
|
+
const config = configContent(ctx);
|
|
893
|
+
if (!config) return false;
|
|
894
|
+
// Check if git-commit-verify is set in config or documented in conventions
|
|
895
|
+
return /git-commit-verify/i.test(config) ||
|
|
896
|
+
/git-commit-verify/i.test(conventionContent(ctx));
|
|
897
|
+
},
|
|
898
|
+
impact: 'high',
|
|
899
|
+
rating: 4,
|
|
900
|
+
category: 'ci',
|
|
901
|
+
fix: 'When pre-commit hooks exist, add --git-commit-verify to Aider invocations. Default Aider auto-commits SKIP pre-commit hooks entirely (experimentally confirmed). Without this flag, hooks that enforce security or quality checks are silently bypassed.',
|
|
902
|
+
template: 'aider-conf-yml',
|
|
903
|
+
file: () => '.aider.conf.yml',
|
|
904
|
+
line: (ctx) => firstLineMatching(configContent(ctx), /git-commit-verify/i),
|
|
905
|
+
},
|
|
906
|
+
|
|
907
|
+
aiderCiExitCodeUnreliable: {
|
|
908
|
+
id: 'AD-G06',
|
|
909
|
+
name: 'CI scripts handle exit code 0 on auth failure (unreliable exit code)',
|
|
910
|
+
check: (ctx) => {
|
|
911
|
+
const workflows = ctx.workflowFiles ? ctx.workflowFiles() : [];
|
|
912
|
+
if (workflows.length === 0) return null;
|
|
913
|
+
// Check if any workflow mentions aider and has output checking
|
|
914
|
+
for (const wf of workflows) {
|
|
915
|
+
const content = ctx.fileContent(wf) || '';
|
|
916
|
+
if (/aider/i.test(content)) {
|
|
917
|
+
// Good if it checks output, not just exit code
|
|
918
|
+
return /grep|check.*output|--json|error.*detect/i.test(content);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
return null;
|
|
922
|
+
},
|
|
923
|
+
impact: 'high',
|
|
924
|
+
rating: 4,
|
|
925
|
+
category: 'ci',
|
|
926
|
+
fix: 'Aider returns exit code 0 even on auth failure (experimentally confirmed). CI scripts that use Aider MUST NOT rely solely on exit codes to detect failure. Check Aider output for error strings or use output parsing to detect real failures.',
|
|
927
|
+
template: null,
|
|
928
|
+
file: () => '.github/workflows/',
|
|
929
|
+
line: () => null,
|
|
930
|
+
},
|
|
931
|
+
|
|
879
932
|
// =========================================================================
|
|
880
933
|
// H — Quality (6 checks: AD-H01 .. AD-H06)
|
|
881
934
|
// =========================================================================
|
|
@@ -1128,6 +1181,25 @@ const AIDER_TECHNIQUES = {
|
|
|
1128
1181
|
line: (ctx) => firstLineMatching(configContent(ctx), /voice-language\s*:/i),
|
|
1129
1182
|
},
|
|
1130
1183
|
|
|
1184
|
+
aiderPlaywrightUrlScraping: {
|
|
1185
|
+
id: 'AD-N05',
|
|
1186
|
+
name: 'Playwright URL auto-scraping side effect is expected',
|
|
1187
|
+
check: (ctx) => {
|
|
1188
|
+
const conventions = conventionContent(ctx);
|
|
1189
|
+
const config = configContent(ctx);
|
|
1190
|
+
// Check if team is aware of the Playwright auto-scraping behavior
|
|
1191
|
+
return /playwright|url.*scrap|scrape.*url|auto.*fetch|web.*fetch/i.test(conventions) ||
|
|
1192
|
+
/playwright|url.*scrap/i.test(config);
|
|
1193
|
+
},
|
|
1194
|
+
impact: 'medium',
|
|
1195
|
+
rating: 3,
|
|
1196
|
+
category: 'workflow-patterns',
|
|
1197
|
+
fix: 'Aider automatically scrapes URLs found in messages using Playwright (experimentally confirmed side effect). This causes unexpected network requests and delays. Document this in conventions, and avoid putting real URLs in messages unless scraping is intentional.',
|
|
1198
|
+
template: 'aider-conventions',
|
|
1199
|
+
file: () => 'CONVENTIONS.md',
|
|
1200
|
+
line: () => null,
|
|
1201
|
+
},
|
|
1202
|
+
|
|
1131
1203
|
// =========================================================================
|
|
1132
1204
|
// O — Editor Integration (4 checks: AD-O01 .. AD-O04)
|
|
1133
1205
|
// =========================================================================
|
|
@@ -1294,7 +1366,7 @@ const AIDER_TECHNIQUES = {
|
|
|
1294
1366
|
impact: 'medium',
|
|
1295
1367
|
rating: 3,
|
|
1296
1368
|
category: 'release-readiness',
|
|
1297
|
-
fix: 'Enable prompt caching or configure separate weak/editor models for cost optimization.',
|
|
1369
|
+
fix: 'Enable prompt caching or configure separate weak/editor models for cost optimization. Cost reference (measured): standard edit ~$0.00015, architect mode edit ~$0.00026 (~1.73x). Set cache-prompts: true for repeated context, and weak-model for commit messages to reduce costs.',
|
|
1298
1370
|
template: 'aider-conf-yml',
|
|
1299
1371
|
file: () => '.aider.conf.yml',
|
|
1300
1372
|
line: (ctx) => firstLineMatching(configContent(ctx), /cache-prompts\s*:|weak-model\s*:|editor-model\s*:/i),
|
|
@@ -1318,6 +1390,8 @@ const AIDER_TECHNIQUES = {
|
|
|
1318
1390
|
},
|
|
1319
1391
|
};
|
|
1320
1392
|
|
|
1393
|
+
attachSourceUrls('aider', AIDER_TECHNIQUES);
|
|
1394
|
+
|
|
1321
1395
|
module.exports = {
|
|
1322
1396
|
AIDER_TECHNIQUES,
|
|
1323
1397
|
};
|
package/src/audit.js
CHANGED
|
@@ -461,7 +461,7 @@ function buildTopNextActions(failed, limit = 5, outcomeSummaryByKey = {}, option
|
|
|
461
461
|
return scoreB - scoreA;
|
|
462
462
|
})
|
|
463
463
|
.slice(0, limit)
|
|
464
|
-
.map(({ key, id, name, impact, fix, category }) => {
|
|
464
|
+
.map(({ key, id, name, impact, fix, category, sourceUrl }) => {
|
|
465
465
|
const feedback = outcomeSummaryByKey[key] || null;
|
|
466
466
|
const rankingAdjustment = getRecommendationAdjustment(outcomeSummaryByKey, key);
|
|
467
467
|
const signals = [
|
|
@@ -491,6 +491,7 @@ function buildTopNextActions(failed, limit = 5, outcomeSummaryByKey = {}, option
|
|
|
491
491
|
name,
|
|
492
492
|
impact,
|
|
493
493
|
category,
|
|
494
|
+
sourceUrl,
|
|
494
495
|
module: CATEGORY_MODULES[category] || category,
|
|
495
496
|
fix,
|
|
496
497
|
priorityScore,
|
|
@@ -810,7 +811,7 @@ async function audit(options) {
|
|
|
810
811
|
stacks,
|
|
811
812
|
results,
|
|
812
813
|
categoryScores,
|
|
813
|
-
quickWins: quickWins.map(({ key, name, impact, fix, category }) => ({ key, name, impact, category, fix })),
|
|
814
|
+
quickWins: quickWins.map(({ key, name, impact, fix, category, sourceUrl }) => ({ key, name, impact, category, fix, sourceUrl })),
|
|
814
815
|
topNextActions,
|
|
815
816
|
recommendationOutcomes: {
|
|
816
817
|
totalEntries: outcomeSummary.totalEntries,
|
package/src/codex/techniques.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const os = require('os');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { EMBEDDED_SECRET_PATTERNS, containsEmbeddedSecret } = require('../secret-patterns');
|
|
4
|
+
const { attachSourceUrls } = require('../source-urls');
|
|
4
5
|
|
|
5
6
|
const DEFAULT_PROJECT_DOC_MAX_BYTES = 32768;
|
|
6
7
|
const SUPPORTED_HOOK_EVENTS = new Set(['SessionStart', 'PreToolUse', 'PostToolUse', 'UserPromptSubmit', 'Stop']);
|
|
@@ -3249,6 +3250,8 @@ const CODEX_TECHNIQUES = {
|
|
|
3249
3250
|
},
|
|
3250
3251
|
};
|
|
3251
3252
|
|
|
3253
|
+
attachSourceUrls('codex', CODEX_TECHNIQUES);
|
|
3254
|
+
|
|
3252
3255
|
module.exports = {
|
|
3253
3256
|
CODEX_TECHNIQUES,
|
|
3254
3257
|
};
|