projscan 4.10.0 → 4.11.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/README.md +27 -8
- package/dist/cli/commands/assess.d.ts +3 -0
- package/dist/cli/commands/assess.js +143 -0
- package/dist/cli/commands/assess.js.map +1 -0
- package/dist/cli/commands/simulate.d.ts +3 -0
- package/dist/cli/commands/simulate.js +125 -0
- package/dist/cli/commands/simulate.js.map +1 -0
- package/dist/cli/registerCommands.js +4 -0
- package/dist/cli/registerCommands.js.map +1 -1
- package/dist/core/assess.d.ts +9 -0
- package/dist/core/assess.js +119 -0
- package/dist/core/assess.js.map +1 -0
- package/dist/core/proofCards.d.ts +10 -0
- package/dist/core/proofCards.js +222 -0
- package/dist/core/proofCards.js.map +1 -0
- package/dist/core/riskDelta.d.ts +19 -0
- package/dist/core/riskDelta.js +77 -0
- package/dist/core/riskDelta.js.map +1 -0
- package/dist/core/simulate.d.ts +6 -0
- package/dist/core/simulate.js +298 -0
- package/dist/core/simulate.js.map +1 -0
- package/dist/mcp/toolCatalog.js +4 -0
- package/dist/mcp/toolCatalog.js.map +1 -1
- package/dist/mcp/tools/assess.d.ts +2 -0
- package/dist/mcp/tools/assess.js +42 -0
- package/dist/mcp/tools/assess.js.map +1 -0
- package/dist/mcp/tools/simulate.d.ts +2 -0
- package/dist/mcp/tools/simulate.js +32 -0
- package/dist/mcp/tools/simulate.js.map +1 -0
- package/dist/projscan-sbom.cdx.json +6 -6
- package/dist/publicCore.d.ts +2 -0
- package/dist/publicCore.js +2 -0
- package/dist/publicCore.js.map +1 -1
- package/dist/tool-manifest.json +52 -3
- package/dist/types/assess.d.ts +91 -0
- package/dist/types/assess.js +2 -0
- package/dist/types/assess.js.map +1 -0
- package/dist/types/simulate.d.ts +41 -0
- package/dist/types/simulate.js +2 -0
- package/dist/types/simulate.js.map +1 -0
- package/dist/types/workplan.d.ts +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/utils/formatSupport.d.ts +2 -0
- package/dist/utils/formatSupport.js +2 -0
- package/dist/utils/formatSupport.js.map +1 -1
- package/docs/GUIDE.md +19 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,8 +24,9 @@ Use projscan when an agent asks one of these questions:
|
|
|
24
24
|
- Which files should I read before changing this feature?
|
|
25
25
|
- Which proof commands should I run before handoff?
|
|
26
26
|
- Which risks need fixes, reviewer attention, or release sign-off?
|
|
27
|
+
- What is actually risky, and what should I fix first?
|
|
27
28
|
|
|
28
|
-
projscan runs core scans on your machine. It respects `.gitignore`, keeps `.env` values out of scans unless you opt in, and exposes the same evidence through a CLI and a
|
|
29
|
+
projscan runs core scans on your machine. It respects `.gitignore`, keeps `.env` values out of scans unless you opt in, and exposes the same evidence through a CLI and a 47-tool MCP server. The language layer uses 11 AST adapters covering 12 named languages.
|
|
29
30
|
|
|
30
31
|
## Install
|
|
31
32
|
|
|
@@ -89,6 +90,20 @@ You get read-only readiness evidence. projscan reports fixes and sign-off gates;
|
|
|
89
90
|
|
|
90
91
|
Success criteria: release review separates concrete defects from human approval gates before anyone tags or publishes.
|
|
91
92
|
|
|
93
|
+
### Weekly proof-first assessment
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
projscan assess --goal "make this repo safer to ship this week"
|
|
97
|
+
projscan assess --mode fix-first --format markdown
|
|
98
|
+
projscan simulate --plan "split bugHunt.ts into ranking, evidence, and output modules"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
You get Proof Cards: each recommendation carries local evidence, impact, a safe change shape, verification commands, feedback or suppression guidance, and a risk delta. Add `--baseline previous-assess.json` to compare the current risk delta against a prior run. `assess` composes existing quality, bug-hunt, and preflight evidence; it does not release, tag, publish, or deploy.
|
|
102
|
+
|
|
103
|
+
Use the risk delta simulator before a refactor or extraction. It predicts likely touched files, affected tests, contract surfaces, rollout steps, proof commands, and before/after risk from local evidence. It is read-only: it does not edit files, run the plan, release, tag, publish, or deploy.
|
|
104
|
+
|
|
105
|
+
Success criteria: the team sees the one or two highest-value fixes, why they matter, how to prove them, and whether ship-readiness still needs caution or review.
|
|
106
|
+
|
|
92
107
|
## Mission Control
|
|
93
108
|
|
|
94
109
|
`projscan start --intent "<goal>"` turns a plain-language goal into an execution plan:
|
|
@@ -128,13 +143,13 @@ npm run docs:screenshots
|
|
|
128
143
|
npm run docs:demos
|
|
129
144
|
```
|
|
130
145
|
|
|
131
|
-
## 4.
|
|
146
|
+
## 4.11.0 Notes
|
|
132
147
|
|
|
133
|
-
4.
|
|
148
|
+
4.11.0 is the proof-first engineering command center release:
|
|
134
149
|
|
|
135
|
-
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
150
|
+
- `projscan assess` turns quality, bug-hunt, and preflight evidence into Proof Cards with fix-first guidance and risk delta.
|
|
151
|
+
- `projscan simulate --plan "<change plan>"` predicts likely files, tests, contracts, rollout, proof commands, and before/after risk before editing.
|
|
152
|
+
- MCP now exposes 47 tools, including `projscan_assess` and `projscan_simulate`.
|
|
138
153
|
|
|
139
154
|
## MCP Setup
|
|
140
155
|
|
|
@@ -174,6 +189,8 @@ npx -y projscan mcp --watch
|
|
|
174
189
|
| Who imports this file? | `projscan semantic-graph --query importers --file src/auth/jwt.ts --format json` |
|
|
175
190
|
| What breaks if I rename this symbol? | `projscan impact --symbol buildCodeGraph --format json` |
|
|
176
191
|
| What should I fix first? | `projscan bug-hunt --format json` |
|
|
192
|
+
| What is risky and worth fixing this week? | `projscan assess --goal "make this repo safer to ship this week"` |
|
|
193
|
+
| Is this refactor worth doing? | `projscan simulate --plan "split bugHunt.ts into ranking, evidence, and output modules"` |
|
|
177
194
|
| Which files have high risk and low coverage? | `projscan coverage --format json` |
|
|
178
195
|
| What should my agent do next? | `projscan workplan --format json` |
|
|
179
196
|
| Which proof belongs in this PR? | `projscan evidence-pack --pr-comment` |
|
|
@@ -186,6 +203,8 @@ npx -y projscan mcp --watch
|
|
|
186
203
|
| `projscan start` | first-60-seconds orientation, routing, and Mission Control |
|
|
187
204
|
| `projscan understand` | cited repo map, runtime flows, public contracts, and change readiness |
|
|
188
205
|
| `projscan preflight` | proceed, caution, or block gate for edit, commit, or merge |
|
|
206
|
+
| `projscan assess` | proof-first assessment with Proof Cards, risk delta, and fix-first guidance |
|
|
207
|
+
| `projscan simulate` | risk delta simulator for a proposed change plan before editing |
|
|
189
208
|
| `projscan evidence-pack` | PR-ready proof with risks, owners, and next commands |
|
|
190
209
|
| `projscan bug-hunt` | ranked fix queue from health, hotspots, session, and preflight evidence |
|
|
191
210
|
| `projscan workplan` | ordered agent tasks with proof and handoff text |
|
|
@@ -375,7 +394,7 @@ Supply-chain scanners may flag package strings or APIs used by `git`, `npm audit
|
|
|
375
394
|
|
|
376
395
|
## Install Notes
|
|
377
396
|
|
|
378
|
-
`projscan@4.
|
|
397
|
+
`projscan@4.11.0` has seven direct runtime dependencies:
|
|
379
398
|
|
|
380
399
|
- `@babel/parser`
|
|
381
400
|
- `@babel/types`
|
|
@@ -385,7 +404,7 @@ Supply-chain scanners may flag package strings or APIs used by `git`, `npm audit
|
|
|
385
404
|
- `ora`
|
|
386
405
|
- `web-tree-sitter`
|
|
387
406
|
|
|
388
|
-
If npm prints `allow-scripts` warnings during a global install, check which package names it lists. projscan core does not need `node-gyp` grammar builds at runtime in 4.
|
|
407
|
+
If npm prints `allow-scripts` warnings during a global install, check which package names it lists. projscan core does not need `node-gyp` grammar builds at runtime in 4.11.0. Open an issue with the warning text if npm reports install scripts from `projscan@latest`, or run `projscan feedback intake --text "<warning text>" --format json` to turn it into a focused setup-trust task.
|
|
389
408
|
|
|
390
409
|
The grammar packages are build-time sources, not global-install dependencies. Published grammar assets include `tree-sitter-python.wasm` and `tree-sitter-c_sharp.wasm`.
|
|
391
410
|
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { assertFormatSupported, getRootPath, maybeCompactBanner, program, setupLogLevel, } from '../_shared.js';
|
|
4
|
+
import { computeAssess } from '../../core/assess.js';
|
|
5
|
+
const ASSESS_MODES = ['standard', 'fix-first', 'ship-readiness'];
|
|
6
|
+
export function registerAssess() {
|
|
7
|
+
program
|
|
8
|
+
.command('assess')
|
|
9
|
+
.description('Run a proof-first codebase assessment with evidence-backed Proof Cards')
|
|
10
|
+
.option('--goal <text>', 'plain-language assessment goal')
|
|
11
|
+
.option('--mode <mode>', 'assessment mode: standard, fix-first, ship-readiness', parseMode)
|
|
12
|
+
.option('--max-cards <count>', 'maximum Proof Cards to return', parsePositiveInt)
|
|
13
|
+
.option('--baseline <path>', 'prior assess JSON file to compare risk delta against')
|
|
14
|
+
.action(async (cmdOpts) => {
|
|
15
|
+
setupLogLevel();
|
|
16
|
+
maybeCompactBanner();
|
|
17
|
+
const format = assertFormatSupported('assess');
|
|
18
|
+
try {
|
|
19
|
+
const report = await computeAssess(getRootPath(), {
|
|
20
|
+
goal: cmdOpts.goal,
|
|
21
|
+
mode: cmdOpts.mode,
|
|
22
|
+
maxCards: cmdOpts.maxCards,
|
|
23
|
+
...(cmdOpts.baseline
|
|
24
|
+
? {
|
|
25
|
+
baselineReport: await readAssessBaseline(cmdOpts.baseline),
|
|
26
|
+
baselinePath: cmdOpts.baseline,
|
|
27
|
+
}
|
|
28
|
+
: {}),
|
|
29
|
+
});
|
|
30
|
+
if (format === 'json') {
|
|
31
|
+
console.log(JSON.stringify(report, null, 2));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (format === 'markdown') {
|
|
35
|
+
console.log(renderAssessMarkdown(report));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
printAssessConsole(report);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
console.error(chalk.red(err instanceof Error ? err.message : String(err)));
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function printAssessConsole(report) {
|
|
47
|
+
const color = report.verdict === 'blocked' ? chalk.red : report.verdict === 'watch' ? chalk.yellow : chalk.green;
|
|
48
|
+
console.log(color(`Projscan Assess: ${report.verdict}`));
|
|
49
|
+
console.log(report.summary);
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(chalk.bold('Fix First'));
|
|
52
|
+
console.log(report.fixFirst ? `- ${report.fixFirst.finding}` : '- Preserve the baseline');
|
|
53
|
+
console.log('');
|
|
54
|
+
console.log(chalk.bold('Verification'));
|
|
55
|
+
for (const command of report.answers.testsThatProveIt)
|
|
56
|
+
console.log(`- ${command}`);
|
|
57
|
+
}
|
|
58
|
+
export function renderAssessMarkdown(report) {
|
|
59
|
+
const lines = [];
|
|
60
|
+
lines.push('# Projscan Assess');
|
|
61
|
+
lines.push('');
|
|
62
|
+
lines.push(`- **Verdict:** ${report.verdict}`);
|
|
63
|
+
lines.push(`- **Mode:** ${report.mode}`);
|
|
64
|
+
lines.push(`- **Goal:** ${report.goal}`);
|
|
65
|
+
lines.push(`- **Summary:** ${report.summary}`);
|
|
66
|
+
if (report.baselineComparison)
|
|
67
|
+
lines.push(`- **Baseline:** ${report.baselineComparison.summary}`);
|
|
68
|
+
lines.push('');
|
|
69
|
+
lines.push('## Answers');
|
|
70
|
+
lines.push('');
|
|
71
|
+
lines.push(`- **Actually risky:** ${report.answers.actuallyRisky}`);
|
|
72
|
+
lines.push(`- **Why risky:** ${report.answers.whyRisky}`);
|
|
73
|
+
lines.push(`- **Fix first:** ${report.answers.fixFirst}`);
|
|
74
|
+
lines.push(`- **Safest change:** ${report.answers.safestChange}`);
|
|
75
|
+
lines.push(`- **Risk removed:** ${report.answers.riskRemoved}`);
|
|
76
|
+
lines.push(`- **Ship now:** ${report.answers.shipNow}`);
|
|
77
|
+
lines.push('');
|
|
78
|
+
lines.push('## Proof Cards');
|
|
79
|
+
lines.push('');
|
|
80
|
+
for (const card of report.proofCards)
|
|
81
|
+
renderProofCard(lines, card);
|
|
82
|
+
if (report.proofCards.length === 0)
|
|
83
|
+
lines.push('- No proof-backed actions outrank baseline verification.');
|
|
84
|
+
lines.push('');
|
|
85
|
+
lines.push('## Verification');
|
|
86
|
+
lines.push('');
|
|
87
|
+
for (const command of report.answers.testsThatProveIt)
|
|
88
|
+
lines.push(`- \`${command}\``);
|
|
89
|
+
lines.push('');
|
|
90
|
+
lines.push('## Next Commands');
|
|
91
|
+
lines.push('');
|
|
92
|
+
for (const command of report.commands)
|
|
93
|
+
lines.push(`- \`${command}\``);
|
|
94
|
+
return lines.join('\n');
|
|
95
|
+
}
|
|
96
|
+
function renderProofCard(lines, card) {
|
|
97
|
+
lines.push(`### ${card.finding}`);
|
|
98
|
+
lines.push('');
|
|
99
|
+
lines.push(`- **Priority:** ${card.priority}`);
|
|
100
|
+
lines.push(`- **Confidence:** ${card.confidence}`);
|
|
101
|
+
lines.push(`- **Why it matters:** ${card.whyItMatters}`);
|
|
102
|
+
if (card.files.length > 0)
|
|
103
|
+
lines.push(`- **Files:** ${card.files.join(', ')}`);
|
|
104
|
+
lines.push(`- **Recommended fix:** ${card.recommendedFix.summary}`);
|
|
105
|
+
lines.push(`- **Safe change:** ${card.recommendedFix.safeChangeShape}`);
|
|
106
|
+
lines.push(`- **Risk delta:** ${card.riskDelta.delta}`);
|
|
107
|
+
lines.push('- **Evidence:**');
|
|
108
|
+
for (const evidence of card.evidence) {
|
|
109
|
+
const file = evidence.file ? ` (${evidence.file})` : '';
|
|
110
|
+
lines.push(` - ${evidence.source}: ${evidence.detail}${file}`);
|
|
111
|
+
}
|
|
112
|
+
lines.push('- **Commands:**');
|
|
113
|
+
for (const command of card.verification.commands)
|
|
114
|
+
lines.push(` - \`${command}\``);
|
|
115
|
+
lines.push('');
|
|
116
|
+
}
|
|
117
|
+
function parseMode(value) {
|
|
118
|
+
if (ASSESS_MODES.includes(value))
|
|
119
|
+
return value;
|
|
120
|
+
throw new Error(`mode must be one of: ${ASSESS_MODES.join(', ')}`);
|
|
121
|
+
}
|
|
122
|
+
function parsePositiveInt(value) {
|
|
123
|
+
const parsed = Number.parseInt(value, 10);
|
|
124
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
125
|
+
throw new Error('value must be a positive integer');
|
|
126
|
+
}
|
|
127
|
+
return parsed;
|
|
128
|
+
}
|
|
129
|
+
async function readAssessBaseline(filePath) {
|
|
130
|
+
try {
|
|
131
|
+
const parsed = JSON.parse(await fs.readFile(filePath, 'utf-8'));
|
|
132
|
+
if (parsed.schemaVersion !== 1 ||
|
|
133
|
+
!parsed.riskDelta ||
|
|
134
|
+
typeof parsed.riskDelta.projectedScore !== 'number') {
|
|
135
|
+
throw new Error('invalid assess baseline shape');
|
|
136
|
+
}
|
|
137
|
+
return parsed;
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
throw new Error(`Could not read assess baseline ${filePath}: ${err instanceof Error ? err.message : 'invalid JSON'}`, { cause: err });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=assess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assess.js","sourceRoot":"","sources":["../../../src/cli/commands/assess.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { assertFormatSupported, getRootPath, maybeCompactBanner, program, setupLogLevel, } from '../_shared.js';
|
|
3
|
+
import { computeSimulation } from '../../core/simulate.js';
|
|
4
|
+
export function registerSimulate() {
|
|
5
|
+
program
|
|
6
|
+
.command('simulate')
|
|
7
|
+
.description('Simulate a proposed change plan with local evidence and projected risk delta')
|
|
8
|
+
.requiredOption('--plan <text>', 'plain-language change plan to simulate')
|
|
9
|
+
.option('--max-files <count>', 'maximum likely touched files to return', parsePositiveInt)
|
|
10
|
+
.action(async (cmdOpts) => {
|
|
11
|
+
setupLogLevel();
|
|
12
|
+
maybeCompactBanner();
|
|
13
|
+
const format = assertFormatSupported('simulate');
|
|
14
|
+
try {
|
|
15
|
+
const report = await computeSimulation(getRootPath(), {
|
|
16
|
+
plan: cmdOpts.plan,
|
|
17
|
+
maxFiles: cmdOpts.maxFiles,
|
|
18
|
+
});
|
|
19
|
+
if (format === 'json') {
|
|
20
|
+
console.log(JSON.stringify(report, null, 2));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (format === 'markdown') {
|
|
24
|
+
console.log(renderSimulateMarkdown(report));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
printSimulateConsole(report);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
console.error(chalk.red(err instanceof Error ? err.message : String(err)));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function printSimulateConsole(report) {
|
|
36
|
+
const color = report.verdict === 'worth-doing'
|
|
37
|
+
? chalk.green
|
|
38
|
+
: report.verdict === 'needs-more-evidence'
|
|
39
|
+
? chalk.yellow
|
|
40
|
+
: chalk.gray;
|
|
41
|
+
console.log(color(`Projscan Simulate: ${report.verdict}`));
|
|
42
|
+
console.log(report.summary);
|
|
43
|
+
console.log('');
|
|
44
|
+
console.log(chalk.bold('Files Likely Touched'));
|
|
45
|
+
if (report.filesLikelyTouched.length === 0)
|
|
46
|
+
console.log('- No concrete file matched the plan');
|
|
47
|
+
for (const file of report.filesLikelyTouched)
|
|
48
|
+
console.log(renderCandidateConsole(file));
|
|
49
|
+
console.log('');
|
|
50
|
+
console.log(chalk.bold('Proof Commands'));
|
|
51
|
+
for (const command of report.proofCommands.slice(0, 6))
|
|
52
|
+
console.log(`- ${command}`);
|
|
53
|
+
}
|
|
54
|
+
export function renderSimulateMarkdown(report) {
|
|
55
|
+
const lines = [];
|
|
56
|
+
lines.push('# Projscan Simulate');
|
|
57
|
+
lines.push('');
|
|
58
|
+
lines.push(`- **Verdict:** ${report.verdict}`);
|
|
59
|
+
lines.push(`- **Confidence:** ${report.confidence}`);
|
|
60
|
+
lines.push(`- **Plan:** ${report.plan}`);
|
|
61
|
+
lines.push(`- **Summary:** ${report.summary}`);
|
|
62
|
+
lines.push(`- **Risk delta:** +${report.riskDelta.delta}`);
|
|
63
|
+
lines.push('');
|
|
64
|
+
lines.push('## Files Likely Touched');
|
|
65
|
+
lines.push('');
|
|
66
|
+
if (report.filesLikelyTouched.length === 0) {
|
|
67
|
+
lines.push('- No concrete file matched the plan.');
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
for (const file of report.filesLikelyTouched) {
|
|
71
|
+
lines.push(`- **${file.path}** (${file.score})`);
|
|
72
|
+
for (const reason of file.reasons)
|
|
73
|
+
lines.push(` - ${reason}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
lines.push('');
|
|
77
|
+
lines.push('## Tests Likely Affected');
|
|
78
|
+
lines.push('');
|
|
79
|
+
if (report.testsLikelyAffected.length === 0)
|
|
80
|
+
lines.push('- Add or identify a regression test first.');
|
|
81
|
+
for (const test of report.testsLikelyAffected)
|
|
82
|
+
lines.push(`- \`${test}\``);
|
|
83
|
+
lines.push('');
|
|
84
|
+
lines.push('## Contracts Likely Affected');
|
|
85
|
+
lines.push('');
|
|
86
|
+
if (report.contractsLikelyAffected.length === 0)
|
|
87
|
+
lines.push('- No public contract inferred.');
|
|
88
|
+
for (const contract of report.contractsLikelyAffected)
|
|
89
|
+
lines.push(`- ${contract}`);
|
|
90
|
+
lines.push('');
|
|
91
|
+
lines.push('## Rollout Plan');
|
|
92
|
+
lines.push('');
|
|
93
|
+
for (const step of report.rolloutPlan) {
|
|
94
|
+
lines.push(`### ${step.title}`);
|
|
95
|
+
lines.push('');
|
|
96
|
+
lines.push(step.detail);
|
|
97
|
+
lines.push('');
|
|
98
|
+
for (const command of step.commands)
|
|
99
|
+
lines.push(`- \`${command}\``);
|
|
100
|
+
lines.push('');
|
|
101
|
+
}
|
|
102
|
+
lines.push('## Proof Commands');
|
|
103
|
+
lines.push('');
|
|
104
|
+
for (const command of report.proofCommands)
|
|
105
|
+
lines.push(`- \`${command}\``);
|
|
106
|
+
if (report.warnings.length > 0) {
|
|
107
|
+
lines.push('');
|
|
108
|
+
lines.push('## Warnings');
|
|
109
|
+
lines.push('');
|
|
110
|
+
for (const warning of report.warnings)
|
|
111
|
+
lines.push(`- ${warning}`);
|
|
112
|
+
}
|
|
113
|
+
return lines.join('\n');
|
|
114
|
+
}
|
|
115
|
+
function renderCandidateConsole(file) {
|
|
116
|
+
return `- ${file.path} (${file.score}): ${file.reasons[0] ?? 'local evidence'}`;
|
|
117
|
+
}
|
|
118
|
+
function parsePositiveInt(value) {
|
|
119
|
+
const parsed = Number.parseInt(value, 10);
|
|
120
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
121
|
+
throw new Error('value must be a positive integer');
|
|
122
|
+
}
|
|
123
|
+
return parsed;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=simulate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulate.js","sourceRoot":"","sources":["../../../src/cli/commands/simulate.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,6 +48,8 @@ import { registerFeedback } from './commands/feedback.js';
|
|
|
48
48
|
import { registerRegressionPlan } from './commands/regressionPlan.js';
|
|
49
49
|
import { registerAgentBrief } from './commands/agentBrief.js';
|
|
50
50
|
import { registerQualityScorecard } from './commands/qualityScorecard.js';
|
|
51
|
+
import { registerAssess } from './commands/assess.js';
|
|
52
|
+
import { registerSimulate } from './commands/simulate.js';
|
|
51
53
|
import { registerFirstRun, registerRecipes } from './commands/recipes.js';
|
|
52
54
|
import { registerStart } from './commands/start.js';
|
|
53
55
|
import { registerTrial } from './commands/trial.js';
|
|
@@ -107,6 +109,8 @@ export const CLI_COMMAND_REGISTRARS = [
|
|
|
107
109
|
registerRegressionPlan,
|
|
108
110
|
registerAgentBrief,
|
|
109
111
|
registerQualityScorecard,
|
|
112
|
+
registerAssess,
|
|
113
|
+
registerSimulate,
|
|
110
114
|
registerStart,
|
|
111
115
|
registerTrial,
|
|
112
116
|
registerTelemetry,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerCommands.js","sourceRoot":"","sources":["../../src/cli/registerCommands.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"registerCommands.js","sourceRoot":"","sources":["../../src/cli/registerCommands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AssessMode, AssessReport } from '../types/assess.js';
|
|
2
|
+
export interface ComputeAssessOptions {
|
|
3
|
+
goal?: string;
|
|
4
|
+
mode?: AssessMode;
|
|
5
|
+
maxCards?: number;
|
|
6
|
+
baselineReport?: AssessReport;
|
|
7
|
+
baselinePath?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function computeAssess(rootPath: string, options?: ComputeAssessOptions): Promise<AssessReport>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { computeBugHunt } from './bugHunt.js';
|
|
2
|
+
import { computePreflight } from './preflight.js';
|
|
3
|
+
import { buildProofCards } from './proofCards.js';
|
|
4
|
+
import { computeQualityScorecard } from './qualityScorecard.js';
|
|
5
|
+
import { compareRiskDeltaSnapshots, computeRiskDelta } from './riskDelta.js';
|
|
6
|
+
const DEFAULT_GOAL = 'assess codebase risk and next proof-backed action';
|
|
7
|
+
export async function computeAssess(rootPath, options = {}) {
|
|
8
|
+
const mode = normalizeMode(options.mode);
|
|
9
|
+
const maxCards = mode === 'fix-first' ? Math.min(options.maxCards ?? 2, 2) : options.maxCards;
|
|
10
|
+
const goal = normalizeGoal(options.goal);
|
|
11
|
+
const [quality, bugHunt, preflight] = await Promise.all([
|
|
12
|
+
computeQualityScorecard(rootPath, { maxRisks: maxCards ?? 5 }),
|
|
13
|
+
computeBugHunt(rootPath, { maxFindings: maxCards ?? 5 }),
|
|
14
|
+
computePreflight(rootPath, { mode: 'before_commit' }),
|
|
15
|
+
]);
|
|
16
|
+
const initialCards = buildProofCards({
|
|
17
|
+
goal,
|
|
18
|
+
qualityRisks: quality.topRisks,
|
|
19
|
+
bugHuntFindings: bugHunt.fixQueue.length > 0 ? bugHunt.fixQueue : bugHunt.topSuspects,
|
|
20
|
+
maxCards,
|
|
21
|
+
});
|
|
22
|
+
const selectedCards = mode === 'fix-first' ? initialCards.slice(0, 2) : initialCards;
|
|
23
|
+
const riskDelta = computeRiskDelta({
|
|
24
|
+
healthScore: quality.health.score,
|
|
25
|
+
qualityVerdict: quality.verdict,
|
|
26
|
+
preflightVerdict: preflight.verdict,
|
|
27
|
+
proofCards: selectedCards.map((card) => ({
|
|
28
|
+
id: card.id,
|
|
29
|
+
priority: card.priority,
|
|
30
|
+
source: card.source,
|
|
31
|
+
})),
|
|
32
|
+
selectedCardIds: selectedCards.slice(0, mode === 'fix-first' ? 2 : 1).map((card) => card.id),
|
|
33
|
+
});
|
|
34
|
+
const proofCards = selectedCards.map((card) => ({ ...card, riskDelta }));
|
|
35
|
+
const verdict = assessVerdict(quality.verdict, preflight.verdict);
|
|
36
|
+
const answers = buildAnswers({
|
|
37
|
+
proofCards,
|
|
38
|
+
riskDelta,
|
|
39
|
+
preflightVerdict: preflight.verdict,
|
|
40
|
+
});
|
|
41
|
+
const report = {
|
|
42
|
+
schemaVersion: 1,
|
|
43
|
+
goal,
|
|
44
|
+
mode,
|
|
45
|
+
verdict,
|
|
46
|
+
summary: summarize(verdict, proofCards, riskDelta),
|
|
47
|
+
answers,
|
|
48
|
+
proofCards,
|
|
49
|
+
...(proofCards[0] ? { fixFirst: proofCards[0] } : {}),
|
|
50
|
+
riskDelta,
|
|
51
|
+
commands: commandsFor(mode),
|
|
52
|
+
feedback: proofCards.map((card) => card.feedback.command),
|
|
53
|
+
sourceVerdicts: {
|
|
54
|
+
quality: quality.verdict,
|
|
55
|
+
preflight: preflight.verdict,
|
|
56
|
+
},
|
|
57
|
+
...(initialCards.length > proofCards.length ? { truncated: true } : {}),
|
|
58
|
+
};
|
|
59
|
+
if (options.baselineReport) {
|
|
60
|
+
report.baselineComparison = compareRiskDeltaSnapshots({
|
|
61
|
+
previous: options.baselineReport,
|
|
62
|
+
current: report,
|
|
63
|
+
baselinePath: options.baselinePath,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return report;
|
|
67
|
+
}
|
|
68
|
+
function buildAnswers(input) {
|
|
69
|
+
const first = input.proofCards[0];
|
|
70
|
+
const evidenceSources = first?.evidence.map((entry) => entry.source).join(', ');
|
|
71
|
+
const proofCommands = first?.verification.commands ?? ['projscan doctor --format json'];
|
|
72
|
+
return {
|
|
73
|
+
actuallyRisky: first
|
|
74
|
+
? `${first.finding} is the top proof-backed risk.`
|
|
75
|
+
: 'No proof-backed risk is currently ranked above baseline verification.',
|
|
76
|
+
whyRisky: first
|
|
77
|
+
? `Evidence comes from ${evidenceSources || 'local projscan analysis'}.`
|
|
78
|
+
: 'The current assessment did not find a higher-priority local signal.',
|
|
79
|
+
fixFirst: first ? `${first.finding}: ${first.recommendedFix.summary}` : 'Preserve the baseline.',
|
|
80
|
+
safestChange: first
|
|
81
|
+
? `Use a small bounded change: ${first.recommendedFix.safeChangeShape}`
|
|
82
|
+
: 'Run the listed verification commands before taking larger changes.',
|
|
83
|
+
testsThatProveIt: proofCommands,
|
|
84
|
+
riskRemoved: `Projected risk score improves by ${input.riskDelta.delta} to ${input.riskDelta.projectedScore}.`,
|
|
85
|
+
shipNow: input.preflightVerdict === 'block'
|
|
86
|
+
? 'Do not ship until preflight blockers are resolved.'
|
|
87
|
+
: `Ship only after preflight and proof commands pass; current preflight verdict is ${input.preflightVerdict}.`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function assessVerdict(qualityVerdict, preflightVerdict) {
|
|
91
|
+
if (preflightVerdict === 'block' || qualityVerdict === 'blocked')
|
|
92
|
+
return 'blocked';
|
|
93
|
+
if (preflightVerdict === 'caution' || qualityVerdict === 'needs_attention')
|
|
94
|
+
return 'watch';
|
|
95
|
+
return 'ready';
|
|
96
|
+
}
|
|
97
|
+
function commandsFor(mode) {
|
|
98
|
+
const commands = [
|
|
99
|
+
'projscan assess --mode fix-first --format json',
|
|
100
|
+
'projscan preflight --mode before_commit --format json',
|
|
101
|
+
'projscan quality-scorecard --format json',
|
|
102
|
+
];
|
|
103
|
+
if (mode === 'ship-readiness')
|
|
104
|
+
commands.unshift('projscan preflight --mode before_merge --format json');
|
|
105
|
+
return [...new Set(commands)];
|
|
106
|
+
}
|
|
107
|
+
function summarize(verdict, proofCards, riskDelta) {
|
|
108
|
+
if (proofCards.length === 0)
|
|
109
|
+
return `${verdict}: no proof-backed action outranks baseline verification`;
|
|
110
|
+
return `${verdict}: ${proofCards.length} proof-backed action(s), projected risk delta +${riskDelta.delta}`;
|
|
111
|
+
}
|
|
112
|
+
function normalizeMode(value) {
|
|
113
|
+
return value ?? 'standard';
|
|
114
|
+
}
|
|
115
|
+
function normalizeGoal(value) {
|
|
116
|
+
const trimmed = value?.trim();
|
|
117
|
+
return trimmed && trimmed.length > 0 ? trimmed : DEFAULT_GOAL;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=assess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assess.js","sourceRoot":"","sources":["../../src/core/assess.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AssessProofCard, RiskDeltaSnapshot } from '../types/assess.js';
|
|
2
|
+
import type { BugHuntFinding, QualityScorecardRisk } from '../types.js';
|
|
3
|
+
export interface BuildProofCardsInput {
|
|
4
|
+
goal?: string;
|
|
5
|
+
qualityRisks: QualityScorecardRisk[];
|
|
6
|
+
bugHuntFindings: BugHuntFinding[];
|
|
7
|
+
maxCards?: number;
|
|
8
|
+
riskDelta?: RiskDeltaSnapshot;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildProofCards(input: BuildProofCardsInput): AssessProofCard[];
|