tryassay 0.1.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/LICENSE +21 -0
- package/README.md +553 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +80 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/assess.d.ts +6 -0
- package/dist/commands/assess.js +267 -0
- package/dist/commands/assess.js.map +1 -0
- package/dist/commands/describe.d.ts +3 -0
- package/dist/commands/describe.js +114 -0
- package/dist/commands/describe.js.map +1 -0
- package/dist/commands/extract.d.ts +4 -0
- package/dist/commands/extract.js +144 -0
- package/dist/commands/extract.js.map +1 -0
- package/dist/commands/hallucinate.d.ts +3 -0
- package/dist/commands/hallucinate.js +100 -0
- package/dist/commands/hallucinate.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +39 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/regenerate.d.ts +3 -0
- package/dist/commands/regenerate.js +158 -0
- package/dist/commands/regenerate.js.map +1 -0
- package/dist/commands/remediate.d.ts +5 -0
- package/dist/commands/remediate.js +155 -0
- package/dist/commands/remediate.js.map +1 -0
- package/dist/commands/report.d.ts +3 -0
- package/dist/commands/report.js +84 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/reverse.d.ts +9 -0
- package/dist/commands/reverse.js +115 -0
- package/dist/commands/reverse.js.map +1 -0
- package/dist/commands/verify.d.ts +4 -0
- package/dist/commands/verify.js +112 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/lib/anthropic.d.ts +13 -0
- package/dist/lib/anthropic.js +60 -0
- package/dist/lib/anthropic.js.map +1 -0
- package/dist/lib/assessment-reporter.d.ts +5 -0
- package/dist/lib/assessment-reporter.js +266 -0
- package/dist/lib/assessment-reporter.js.map +1 -0
- package/dist/lib/claim-extractor.d.ts +6 -0
- package/dist/lib/claim-extractor.js +138 -0
- package/dist/lib/claim-extractor.js.map +1 -0
- package/dist/lib/code-verifier.d.ts +7 -0
- package/dist/lib/code-verifier.js +265 -0
- package/dist/lib/code-verifier.js.map +1 -0
- package/dist/lib/codebase-indexer.d.ts +15 -0
- package/dist/lib/codebase-indexer.js +156 -0
- package/dist/lib/codebase-indexer.js.map +1 -0
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.js +38 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constraint-engine.d.ts +2 -0
- package/dist/lib/constraint-engine.js +337 -0
- package/dist/lib/constraint-engine.js.map +1 -0
- package/dist/lib/fs-utils.d.ts +1 -0
- package/dist/lib/fs-utils.js +11 -0
- package/dist/lib/fs-utils.js.map +1 -0
- package/dist/lib/guided-generator.d.ts +2 -0
- package/dist/lib/guided-generator.js +195 -0
- package/dist/lib/guided-generator.js.map +1 -0
- package/dist/lib/inventory-extractor.d.ts +7 -0
- package/dist/lib/inventory-extractor.js +238 -0
- package/dist/lib/inventory-extractor.js.map +1 -0
- package/dist/lib/prompts.d.ts +3 -0
- package/dist/lib/prompts.js +50 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/publisher.d.ts +2 -0
- package/dist/lib/publisher.js +71 -0
- package/dist/lib/publisher.js.map +1 -0
- package/dist/lib/remediation-generator.d.ts +2 -0
- package/dist/lib/remediation-generator.js +136 -0
- package/dist/lib/remediation-generator.js.map +1 -0
- package/dist/lib/remediator.d.ts +7 -0
- package/dist/lib/remediator.js +209 -0
- package/dist/lib/remediator.js.map +1 -0
- package/dist/lib/report-generator.d.ts +8 -0
- package/dist/lib/report-generator.js +190 -0
- package/dist/lib/report-generator.js.map +1 -0
- package/dist/lib/requirements-generator.d.ts +14 -0
- package/dist/lib/requirements-generator.js +311 -0
- package/dist/lib/requirements-generator.js.map +1 -0
- package/dist/lib/spec-synthesizer.d.ts +2 -0
- package/dist/lib/spec-synthesizer.js +136 -0
- package/dist/lib/spec-synthesizer.js.map +1 -0
- package/dist/lib/system-prompts.d.ts +12 -0
- package/dist/lib/system-prompts.js +254 -0
- package/dist/lib/system-prompts.js.map +1 -0
- package/dist/types.d.ts +243 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { synthesizeSpecs } from '../lib/spec-synthesizer.js';
|
|
4
|
+
import { generateConstraints } from '../lib/constraint-engine.js';
|
|
5
|
+
import { generateWithConstraints } from '../lib/guided-generator.js';
|
|
6
|
+
export async function reverseCommand(options) {
|
|
7
|
+
const startTime = Date.now();
|
|
8
|
+
// Resolve task description
|
|
9
|
+
let task;
|
|
10
|
+
if (options.task) {
|
|
11
|
+
task = options.task;
|
|
12
|
+
}
|
|
13
|
+
else if (options.taskFile) {
|
|
14
|
+
try {
|
|
15
|
+
task = (await readFile(options.taskFile, 'utf-8')).trim();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
console.error(`Error: Cannot read task file: ${options.taskFile}`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
console.error('Error: Provide --task or --task-file');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
if (!task) {
|
|
27
|
+
console.error('Error: Task description is empty');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const language = options.lang;
|
|
31
|
+
const verbose = options.verbose ?? false;
|
|
32
|
+
const progress = (msg) => {
|
|
33
|
+
if (verbose) {
|
|
34
|
+
console.error(` ${msg}`);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
// ── Phase 1: Spec Synthesis ──────────────────────────────
|
|
38
|
+
console.error('\n┌─ REVERSE ASSAY ─────────────────────────────────┐');
|
|
39
|
+
console.error(`│ Task: ${task.slice(0, 45)}${task.length > 45 ? '...' : ''}`);
|
|
40
|
+
console.error(`│ Language: ${language}`);
|
|
41
|
+
console.error('└─────────────────────────────────────────────────┘\n');
|
|
42
|
+
console.error('▸ Phase 1/3: Synthesizing specifications...');
|
|
43
|
+
const specResult = await synthesizeSpecs(task, language, progress);
|
|
44
|
+
console.error(` ✓ ${specResult.totalSpecs} specs generated`);
|
|
45
|
+
if (verbose) {
|
|
46
|
+
for (const spec of specResult.specs) {
|
|
47
|
+
console.error(` [${spec.id}] (${spec.severity}/${spec.category}) ${spec.description}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// ── Phase 2: Constraint Generation ───────────────────────
|
|
51
|
+
console.error('\n▸ Phase 2/3: Generating constraints...');
|
|
52
|
+
const constraintResult = await generateConstraints(task, language, specResult.specs, progress);
|
|
53
|
+
console.error(` ✓ ${constraintResult.totalConstraints} constraints generated`);
|
|
54
|
+
if (verbose) {
|
|
55
|
+
const musts = constraintResult.constraints.filter(c => c.type === 'must');
|
|
56
|
+
const mustNots = constraintResult.constraints.filter(c => c.type === 'must-not');
|
|
57
|
+
const prefers = constraintResult.constraints.filter(c => c.type === 'prefer');
|
|
58
|
+
console.error(` MUST: ${musts.length} | MUST-NOT: ${mustNots.length} | PREFER: ${prefers.length}`);
|
|
59
|
+
}
|
|
60
|
+
// ── Phase 3: Guided Generation ───────────────────────────
|
|
61
|
+
console.error('\n▸ Phase 3/3: Generating code with constraints...');
|
|
62
|
+
const codeResult = await generateWithConstraints(task, language, specResult.specs, constraintResult.constraints, progress);
|
|
63
|
+
const satisfiedPct = codeResult.totalSpecs > 0
|
|
64
|
+
? ((codeResult.satisfiedCount / codeResult.totalSpecs) * 100).toFixed(1)
|
|
65
|
+
: '0.0';
|
|
66
|
+
console.error(` ✓ Code generated — ${codeResult.satisfiedCount}/${codeResult.totalSpecs} specs satisfied (${satisfiedPct}%)`);
|
|
67
|
+
if (verbose) {
|
|
68
|
+
for (const sv of codeResult.selfVerification) {
|
|
69
|
+
const icon = sv.status === 'satisfied' ? '✓'
|
|
70
|
+
: sv.status === 'partial' ? '◐'
|
|
71
|
+
: sv.status === 'unsatisfied' ? '✗'
|
|
72
|
+
: '?';
|
|
73
|
+
console.error(` ${icon} ${sv.specId}: ${sv.reasoning.slice(0, 80)}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// ── Output ───────────────────────────────────────────────
|
|
77
|
+
const totalDurationMs = Date.now() - startTime;
|
|
78
|
+
const totalInputTokens = specResult.inputTokens + constraintResult.inputTokens + codeResult.inputTokens;
|
|
79
|
+
const totalOutputTokens = specResult.outputTokens + constraintResult.outputTokens + codeResult.outputTokens;
|
|
80
|
+
if (options.output) {
|
|
81
|
+
// Ensure output directory exists
|
|
82
|
+
await mkdir(dirname(options.output), { recursive: true });
|
|
83
|
+
await writeFile(options.output, codeResult.code, 'utf-8');
|
|
84
|
+
console.error(`\n✓ Code written to: ${options.output}`);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// Write code to stdout
|
|
88
|
+
process.stdout.write(codeResult.code);
|
|
89
|
+
}
|
|
90
|
+
// ── Summary ──────────────────────────────────────────────
|
|
91
|
+
console.error('\n┌─ SUMMARY ───────────────────────────────────────┐');
|
|
92
|
+
console.error(`│ Specs: ${specResult.totalSpecs} synthesized`);
|
|
93
|
+
console.error(`│ Constraints: ${constraintResult.totalConstraints} generated`);
|
|
94
|
+
console.error(`│ Satisfied: ${codeResult.satisfiedCount}/${codeResult.totalSpecs} (${satisfiedPct}%)`);
|
|
95
|
+
console.error(`│ Tokens: ${totalInputTokens.toLocaleString()} in / ${totalOutputTokens.toLocaleString()} out`);
|
|
96
|
+
console.error(`│ Duration: ${(totalDurationMs / 1000).toFixed(1)}s`);
|
|
97
|
+
console.error('└─────────────────────────────────────────────────┘');
|
|
98
|
+
// ── Write full result as JSON sidecar ────────────────────
|
|
99
|
+
if (options.output) {
|
|
100
|
+
const result = {
|
|
101
|
+
task,
|
|
102
|
+
language,
|
|
103
|
+
specSynthesis: specResult,
|
|
104
|
+
constraintSet: constraintResult,
|
|
105
|
+
generatedCode: codeResult,
|
|
106
|
+
totalInputTokens,
|
|
107
|
+
totalOutputTokens,
|
|
108
|
+
totalDurationMs,
|
|
109
|
+
};
|
|
110
|
+
const sidecarPath = options.output.replace(/\.[^.]+$/, '.reverse-assay.json');
|
|
111
|
+
await writeFile(sidecarPath, JSON.stringify(result, null, 2), 'utf-8');
|
|
112
|
+
console.error(`✓ Full result written to: ${sidecarPath}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=reverse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reverse.js","sourceRoot":"","sources":["../../src/commands/reverse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { readdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
import { getIterationsDir } from '../lib/config.js';
|
|
4
|
+
import { exists } from '../lib/fs-utils.js';
|
|
5
|
+
import { indexCodebase } from '../lib/codebase-indexer.js';
|
|
6
|
+
import { verifyClaims } from '../lib/code-verifier.js';
|
|
7
|
+
async function findLatestIteration(iterDir) {
|
|
8
|
+
if (!(await exists(iterDir)))
|
|
9
|
+
return null;
|
|
10
|
+
const entries = await readdir(iterDir, { withFileTypes: true });
|
|
11
|
+
const nums = entries
|
|
12
|
+
.filter((e) => e.isDirectory())
|
|
13
|
+
.map((e) => parseInt(e.name, 10))
|
|
14
|
+
.filter((n) => !isNaN(n));
|
|
15
|
+
return nums.length === 0 ? null : Math.max(...nums);
|
|
16
|
+
}
|
|
17
|
+
export async function verifyCommand(options) {
|
|
18
|
+
const iterDir = getIterationsDir();
|
|
19
|
+
const repoPath = resolve(options.repo || '.');
|
|
20
|
+
// Determine iteration
|
|
21
|
+
let iteration;
|
|
22
|
+
if (options.iteration) {
|
|
23
|
+
iteration = parseInt(options.iteration, 10);
|
|
24
|
+
if (isNaN(iteration)) {
|
|
25
|
+
console.error(` Error: Invalid iteration "${options.iteration}".`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const latest = await findLatestIteration(iterDir);
|
|
31
|
+
if (latest === null) {
|
|
32
|
+
console.error(' Error: No iterations found. Run `assay extract` first.');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
iteration = latest;
|
|
36
|
+
}
|
|
37
|
+
const iterPath = join(iterDir, String(iteration));
|
|
38
|
+
const claimsPath = join(iterPath, 'claims.json');
|
|
39
|
+
if (!(await exists(claimsPath))) {
|
|
40
|
+
console.error(` Error: No claims.json found for iteration ${iteration}.`);
|
|
41
|
+
console.error(' Run `assay extract` first.');
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
const extraction = JSON.parse(await readFile(claimsPath, 'utf-8'));
|
|
45
|
+
console.log(`\n Assay — Verifying claims against codebase (iteration ${iteration})`);
|
|
46
|
+
console.log(` Codebase: ${repoPath}`);
|
|
47
|
+
console.log(` Claims: ${extraction.totalClaims} (${extraction.testableClaims} testable)`);
|
|
48
|
+
console.log(` ─────────────────────────────────────\n`);
|
|
49
|
+
// Index the codebase
|
|
50
|
+
console.log(` Indexing codebase...`);
|
|
51
|
+
const index = await indexCodebase(repoPath);
|
|
52
|
+
console.log(` ${index.summary.split('\n').join('\n ')}\n`);
|
|
53
|
+
// Run verification
|
|
54
|
+
const startTime = Date.now();
|
|
55
|
+
const { verifications, inputTokens, outputTokens } = await verifyClaims(extraction.claims, index, (msg) => console.log(` ${msg}`));
|
|
56
|
+
const durationMs = Date.now() - startTime;
|
|
57
|
+
// Count verdicts
|
|
58
|
+
const verdicts = { pass: 0, partial: 0, fail: 0, na: 0 };
|
|
59
|
+
for (const v of verifications) {
|
|
60
|
+
const key = v.verdict.toLowerCase().replace('/', '');
|
|
61
|
+
if (key in verdicts) {
|
|
62
|
+
verdicts[key]++;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Build report
|
|
66
|
+
const report = {
|
|
67
|
+
iteration,
|
|
68
|
+
codebasePath: repoPath,
|
|
69
|
+
verdicts,
|
|
70
|
+
verifications,
|
|
71
|
+
generatedAt: new Date().toISOString(),
|
|
72
|
+
};
|
|
73
|
+
const reportPath = join(iterPath, 'verification.json');
|
|
74
|
+
await writeFile(reportPath, JSON.stringify(report, null, 2) + '\n', 'utf-8');
|
|
75
|
+
// Print verdict table
|
|
76
|
+
const total = verifications.length;
|
|
77
|
+
const passRate = total > 0
|
|
78
|
+
? (((verdicts.pass + verdicts.partial * 0.5) / (total - verdicts.na)) * 100).toFixed(1)
|
|
79
|
+
: '0.0';
|
|
80
|
+
console.log(`\n ─────────────────────────────────────`);
|
|
81
|
+
console.log(` Saved: .assay/iterations/${iteration}/verification.json`);
|
|
82
|
+
console.log(`\n Verdict Distribution:`);
|
|
83
|
+
console.log(` PASS ${String(verdicts.pass).padStart(4)} ${bar(verdicts.pass, total)}`);
|
|
84
|
+
console.log(` PARTIAL ${String(verdicts.partial).padStart(4)} ${bar(verdicts.partial, total)}`);
|
|
85
|
+
console.log(` FAIL ${String(verdicts.fail).padStart(4)} ${bar(verdicts.fail, total)}`);
|
|
86
|
+
console.log(` N/A ${String(verdicts.na).padStart(4)} ${bar(verdicts.na, total)}`);
|
|
87
|
+
console.log(` ─────────────────`);
|
|
88
|
+
console.log(` Total ${String(total).padStart(4)}`);
|
|
89
|
+
console.log(`\n Compliance score: ${passRate}%`);
|
|
90
|
+
// Print critical failures
|
|
91
|
+
const criticalFails = verifications.filter((v) => v.verdict === 'FAIL' &&
|
|
92
|
+
extraction.claims.find((c) => c.id === v.claimId)?.severity === 'critical');
|
|
93
|
+
if (criticalFails.length > 0) {
|
|
94
|
+
console.log(`\n CRITICAL FAILURES (${criticalFails.length}):`);
|
|
95
|
+
for (const f of criticalFails) {
|
|
96
|
+
console.log(` ${f.claimId}: ${f.claim}`);
|
|
97
|
+
console.log(` Reason: ${f.reasoning}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
console.log(`\n Input tokens: ${inputTokens.toLocaleString()}`);
|
|
101
|
+
console.log(` Output tokens: ${outputTokens.toLocaleString()}`);
|
|
102
|
+
console.log(` Duration: ${(durationMs / 1000).toFixed(1)}s`);
|
|
103
|
+
console.log(`\n Next: Run \`assay report\` to generate the gap report.\n`);
|
|
104
|
+
}
|
|
105
|
+
function bar(value, total) {
|
|
106
|
+
if (total === 0)
|
|
107
|
+
return '';
|
|
108
|
+
const width = 20;
|
|
109
|
+
const filled = Math.round((value / total) * width);
|
|
110
|
+
return '#'.repeat(filled) + '-'.repeat(width - filled);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import type { HallucinationType } from '../types.js';
|
|
3
|
+
import type { AssayConfig } from '../types.js';
|
|
4
|
+
import type { RegenerationContext } from './system-prompts.js';
|
|
5
|
+
export declare const MODEL = "claude-sonnet-4-5-20250929";
|
|
6
|
+
export declare function getClient(): Anthropic;
|
|
7
|
+
export interface StreamResult {
|
|
8
|
+
content: string;
|
|
9
|
+
inputTokens: number;
|
|
10
|
+
outputTokens: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function streamHallucination(config: AssayConfig, type: HallucinationType): Promise<StreamResult>;
|
|
13
|
+
export declare function streamRegeneration(ctx: RegenerationContext): Promise<StreamResult>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import { getSystemPrompt, getUserPrompt, getRegenerationSystemPrompt, getRegenerationUserPrompt } from './system-prompts.js';
|
|
3
|
+
export const MODEL = 'claude-sonnet-4-5-20250929';
|
|
4
|
+
const MAX_TOKENS = 12_000;
|
|
5
|
+
export function getClient() {
|
|
6
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
throw new Error('ANTHROPIC_API_KEY environment variable is not set.\n' +
|
|
9
|
+
'Export it before running: export ANTHROPIC_API_KEY=sk-ant-...');
|
|
10
|
+
}
|
|
11
|
+
return new Anthropic({ apiKey, timeout: 15 * 60 * 1000 });
|
|
12
|
+
}
|
|
13
|
+
export async function streamHallucination(config, type) {
|
|
14
|
+
const client = getClient();
|
|
15
|
+
const systemPrompt = getSystemPrompt(type, config);
|
|
16
|
+
const userPrompt = getUserPrompt(type, config);
|
|
17
|
+
let content = '';
|
|
18
|
+
let inputTokens = 0;
|
|
19
|
+
let outputTokens = 0;
|
|
20
|
+
const stream = client.messages.stream({
|
|
21
|
+
model: MODEL,
|
|
22
|
+
max_tokens: MAX_TOKENS,
|
|
23
|
+
system: systemPrompt,
|
|
24
|
+
messages: [{ role: 'user', content: userPrompt }],
|
|
25
|
+
});
|
|
26
|
+
stream.on('text', (text) => {
|
|
27
|
+
process.stdout.write(text);
|
|
28
|
+
content += text;
|
|
29
|
+
});
|
|
30
|
+
const finalMessage = await stream.finalMessage();
|
|
31
|
+
inputTokens = finalMessage.usage.input_tokens;
|
|
32
|
+
outputTokens = finalMessage.usage.output_tokens;
|
|
33
|
+
// Newline after streamed content
|
|
34
|
+
console.log();
|
|
35
|
+
return { content, inputTokens, outputTokens };
|
|
36
|
+
}
|
|
37
|
+
export async function streamRegeneration(ctx) {
|
|
38
|
+
const client = getClient();
|
|
39
|
+
const systemPrompt = getRegenerationSystemPrompt(ctx);
|
|
40
|
+
const userPrompt = getRegenerationUserPrompt(ctx);
|
|
41
|
+
let content = '';
|
|
42
|
+
let inputTokens = 0;
|
|
43
|
+
let outputTokens = 0;
|
|
44
|
+
const stream = client.messages.stream({
|
|
45
|
+
model: MODEL,
|
|
46
|
+
max_tokens: MAX_TOKENS,
|
|
47
|
+
system: systemPrompt,
|
|
48
|
+
messages: [{ role: 'user', content: userPrompt }],
|
|
49
|
+
});
|
|
50
|
+
stream.on('text', (text) => {
|
|
51
|
+
process.stdout.write(text);
|
|
52
|
+
content += text;
|
|
53
|
+
});
|
|
54
|
+
const finalMessage = await stream.finalMessage();
|
|
55
|
+
inputTokens = finalMessage.usage.input_tokens;
|
|
56
|
+
outputTokens = finalMessage.usage.output_tokens;
|
|
57
|
+
console.log();
|
|
58
|
+
return { content, inputTokens, outputTokens };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/lib/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AssessmentResult, RouteAssessmentResult } from '../types.js';
|
|
2
|
+
export declare function generateAssessmentReport(routeResults: RouteAssessmentResult[], repoName: string, repoUrl: string, frameworks: string[], totalTokens: {
|
|
3
|
+
input: number;
|
|
4
|
+
output: number;
|
|
5
|
+
}, outputDir: string, onProgress?: (msg: string) => void): Promise<AssessmentResult>;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { getClient, MODEL } from './anthropic.js';
|
|
5
|
+
// ── Severity ordering for sort ──────────────────────────────────────
|
|
6
|
+
const SEVERITY_ORDER = {
|
|
7
|
+
critical: 0,
|
|
8
|
+
high: 1,
|
|
9
|
+
medium: 2,
|
|
10
|
+
low: 3,
|
|
11
|
+
};
|
|
12
|
+
// ── Bug severity lookup ─────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Build a map from claimId -> severity, using the original Claim objects.
|
|
15
|
+
* ClaimVerification only has claimId/claim text, not severity,
|
|
16
|
+
* so we need the claims array to look it up.
|
|
17
|
+
*/
|
|
18
|
+
function buildSeverityMap(routeResults) {
|
|
19
|
+
const map = new Map();
|
|
20
|
+
for (const route of routeResults) {
|
|
21
|
+
for (const claim of route.claims) {
|
|
22
|
+
map.set(claim.id, claim.severity);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return map;
|
|
26
|
+
}
|
|
27
|
+
function getBugSeverity(bug, severityMap) {
|
|
28
|
+
return severityMap.get(bug.claimId) ?? 'medium';
|
|
29
|
+
}
|
|
30
|
+
function collectBugEntries(routeResults, severityMap) {
|
|
31
|
+
const entries = [];
|
|
32
|
+
for (const route of routeResults) {
|
|
33
|
+
// Find the original claim for category lookup
|
|
34
|
+
const claimMap = new Map(route.claims.map((c) => [c.id, c]));
|
|
35
|
+
for (const bug of route.bugs) {
|
|
36
|
+
const claim = claimMap.get(bug.claimId);
|
|
37
|
+
entries.push({
|
|
38
|
+
bug,
|
|
39
|
+
severity: getBugSeverity(bug, severityMap),
|
|
40
|
+
route: route.requirement.route,
|
|
41
|
+
domain: route.requirement.domain,
|
|
42
|
+
category: claim?.category ?? 'functionality',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Sort by severity order (critical first), then by route
|
|
47
|
+
entries.sort((a, b) => {
|
|
48
|
+
const sevDiff = SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity];
|
|
49
|
+
if (sevDiff !== 0)
|
|
50
|
+
return sevDiff;
|
|
51
|
+
return a.route.localeCompare(b.route);
|
|
52
|
+
});
|
|
53
|
+
return entries;
|
|
54
|
+
}
|
|
55
|
+
function countBugsBySeverity(entries) {
|
|
56
|
+
const counts = { critical: 0, high: 0, medium: 0, low: 0 };
|
|
57
|
+
for (const e of entries) {
|
|
58
|
+
counts[e.severity]++;
|
|
59
|
+
}
|
|
60
|
+
return counts;
|
|
61
|
+
}
|
|
62
|
+
function generateBugReport(entries, repoName, bugCounts) {
|
|
63
|
+
const lines = [
|
|
64
|
+
`# Bug Report -- ${repoName}`,
|
|
65
|
+
``,
|
|
66
|
+
`**Assessment Date:** ${new Date().toISOString().split('T')[0]}`,
|
|
67
|
+
`**Total Bugs:** ${entries.length} (Critical: ${bugCounts.critical}, High: ${bugCounts.high}, Medium: ${bugCounts.medium}, Low: ${bugCounts.low})`,
|
|
68
|
+
``,
|
|
69
|
+
`---`,
|
|
70
|
+
];
|
|
71
|
+
let bugNumber = 0;
|
|
72
|
+
const severities = ['critical', 'high', 'medium', 'low'];
|
|
73
|
+
for (const sev of severities) {
|
|
74
|
+
const sevEntries = entries.filter((e) => e.severity === sev);
|
|
75
|
+
if (sevEntries.length === 0)
|
|
76
|
+
continue;
|
|
77
|
+
lines.push(``, `## ${sev.charAt(0).toUpperCase() + sev.slice(1)}`, ``);
|
|
78
|
+
for (const entry of sevEntries) {
|
|
79
|
+
bugNumber++;
|
|
80
|
+
const bugId = `BUG-${String(bugNumber).padStart(3, '0')}`;
|
|
81
|
+
const evidenceLines = entry.bug.evidence.length > 0
|
|
82
|
+
? entry.bug.evidence.map((e) => ` - \`${e.file}${e.lineNumber ? ':' + e.lineNumber : ''}\` -- ${e.snippet}`)
|
|
83
|
+
: [' - No specific file evidence'];
|
|
84
|
+
lines.push(`### ${bugId}: ${entry.bug.claim}`, `- **Route:** ${entry.route}`, `- **Domain:** ${entry.domain}`, `- **Category:** ${entry.category}`, `- **Verdict:** ${entry.bug.verdict}`, `- **Evidence:**`, ...evidenceLines, `- **Reasoning:** ${entry.bug.reasoning}`, ``);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (entries.length === 0) {
|
|
88
|
+
lines.push(``, `No bugs found. All claims passed verification.`);
|
|
89
|
+
}
|
|
90
|
+
return lines.join('\n');
|
|
91
|
+
}
|
|
92
|
+
// ── Coverage matrix generation ──────────────────────────────────────
|
|
93
|
+
function generateCoverageMatrix(routeResults, repoName) {
|
|
94
|
+
// Group routes by domain
|
|
95
|
+
const domainMap = new Map();
|
|
96
|
+
for (const r of routeResults) {
|
|
97
|
+
const domain = r.requirement.domain;
|
|
98
|
+
if (!domainMap.has(domain)) {
|
|
99
|
+
domainMap.set(domain, []);
|
|
100
|
+
}
|
|
101
|
+
domainMap.get(domain).push(r);
|
|
102
|
+
}
|
|
103
|
+
// Sort domains alphabetically
|
|
104
|
+
const sortedDomains = [...domainMap.keys()].sort();
|
|
105
|
+
const lines = [
|
|
106
|
+
`# Coverage Matrix -- ${repoName}`,
|
|
107
|
+
``,
|
|
108
|
+
`| Domain | Route | Pass | Partial | Fail | Total | Score |`,
|
|
109
|
+
`|--------|-------|------|---------|------|-------|-------|`,
|
|
110
|
+
];
|
|
111
|
+
for (const domain of sortedDomains) {
|
|
112
|
+
const routes = domainMap.get(domain);
|
|
113
|
+
// Sort routes by path within domain
|
|
114
|
+
routes.sort((a, b) => a.requirement.route.localeCompare(b.requirement.route));
|
|
115
|
+
// Domain header row
|
|
116
|
+
lines.push(`| **${domain}** | | | | | | |`);
|
|
117
|
+
for (const r of routes) {
|
|
118
|
+
const pass = r.verifications.filter((v) => v.verdict === 'PASS').length;
|
|
119
|
+
const partial = r.verifications.filter((v) => v.verdict === 'PARTIAL').length;
|
|
120
|
+
const fail = r.verifications.filter((v) => v.verdict === 'FAIL').length;
|
|
121
|
+
const testable = pass + partial + fail;
|
|
122
|
+
const score = testable > 0 ? Math.round((pass / testable) * 100) : 0;
|
|
123
|
+
lines.push(`| | ${r.requirement.route} | ${pass} | ${partial} | ${fail} | ${testable} | ${score}% |`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
lines.push('');
|
|
127
|
+
return lines.join('\n');
|
|
128
|
+
}
|
|
129
|
+
// ── Executive summary (Claude-generated) ────────────────────────────
|
|
130
|
+
async function generateExecutiveSummary(repoName, totalClaims, verdicts, bugCounts, totalRoutes, domainSummaries, topBugs, score) {
|
|
131
|
+
const client = getClient();
|
|
132
|
+
const totalBugs = bugCounts.critical + bugCounts.high + bugCounts.medium + bugCounts.low;
|
|
133
|
+
const topBugDescriptions = topBugs
|
|
134
|
+
.slice(0, 10)
|
|
135
|
+
.map((b, i) => `${i + 1}. [${b.severity.toUpperCase()}] ${b.bug.claim} (${b.route})`)
|
|
136
|
+
.join('\n');
|
|
137
|
+
const domainTable = domainSummaries
|
|
138
|
+
.map((d) => `- ${d.domain}: ${d.routes} routes, ${d.score}% compliance`)
|
|
139
|
+
.join('\n');
|
|
140
|
+
const prompt = `You are writing an executive summary for a codebase compliance assessment report. Write 3-4 paragraphs for a CTO or VP Engineering audience. Focus on business risk, not code details.
|
|
141
|
+
|
|
142
|
+
ASSESSMENT DATA:
|
|
143
|
+
- Repository: ${repoName}
|
|
144
|
+
- Total routes assessed: ${totalRoutes}
|
|
145
|
+
- Total claims verified: ${totalClaims}
|
|
146
|
+
- Compliance score: ${score}/100
|
|
147
|
+
- Verdicts: ${verdicts.pass} PASS, ${verdicts.partial} PARTIAL, ${verdicts.fail} FAIL, ${verdicts.na} N/A
|
|
148
|
+
- Bugs found: ${totalBugs} total (${bugCounts.critical} critical, ${bugCounts.high} high, ${bugCounts.medium} medium, ${bugCounts.low} low)
|
|
149
|
+
|
|
150
|
+
DOMAIN COVERAGE:
|
|
151
|
+
${domainTable}
|
|
152
|
+
|
|
153
|
+
TOP BUGS:
|
|
154
|
+
${topBugDescriptions || 'None found.'}
|
|
155
|
+
|
|
156
|
+
GUIDELINES:
|
|
157
|
+
- Paragraph 1: Overall assessment and score interpretation
|
|
158
|
+
- Paragraph 2: Key risk areas and critical/high bugs
|
|
159
|
+
- Paragraph 3: Domain-by-domain coverage highlights
|
|
160
|
+
- Paragraph 4: Recommendations and next steps
|
|
161
|
+
- Write for a non-technical executive
|
|
162
|
+
- Be direct about risks without being alarmist
|
|
163
|
+
- Do NOT use markdown headers or bullet points -- write prose paragraphs only`;
|
|
164
|
+
const stream = client.messages.stream({
|
|
165
|
+
model: MODEL,
|
|
166
|
+
max_tokens: 2000,
|
|
167
|
+
messages: [{ role: 'user', content: prompt }],
|
|
168
|
+
});
|
|
169
|
+
let summary = '';
|
|
170
|
+
stream.on('text', (text) => {
|
|
171
|
+
summary += text;
|
|
172
|
+
});
|
|
173
|
+
const finalMessage = await stream.finalMessage();
|
|
174
|
+
return {
|
|
175
|
+
summary: summary.trim(),
|
|
176
|
+
inputTokens: finalMessage.usage.input_tokens,
|
|
177
|
+
outputTokens: finalMessage.usage.output_tokens,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// ── Main report generator ───────────────────────────────────────────
|
|
181
|
+
export async function generateAssessmentReport(routeResults, repoName, repoUrl, frameworks, totalTokens, outputDir, onProgress) {
|
|
182
|
+
const createdAt = new Date().toISOString();
|
|
183
|
+
// Build severity map from claims
|
|
184
|
+
const severityMap = buildSeverityMap(routeResults);
|
|
185
|
+
// Aggregate verdicts
|
|
186
|
+
const allVerifications = routeResults.flatMap((r) => r.verifications);
|
|
187
|
+
const verdicts = {
|
|
188
|
+
pass: allVerifications.filter((v) => v.verdict === 'PASS').length,
|
|
189
|
+
partial: allVerifications.filter((v) => v.verdict === 'PARTIAL').length,
|
|
190
|
+
fail: allVerifications.filter((v) => v.verdict === 'FAIL').length,
|
|
191
|
+
na: allVerifications.filter((v) => v.verdict === 'N/A').length,
|
|
192
|
+
};
|
|
193
|
+
// Collect and count bugs
|
|
194
|
+
const bugEntries = collectBugEntries(routeResults, severityMap);
|
|
195
|
+
const bugCounts = countBugsBySeverity(bugEntries);
|
|
196
|
+
// Compliance score
|
|
197
|
+
const totalClaims = routeResults.reduce((sum, r) => sum + r.claims.length, 0);
|
|
198
|
+
const testable = verdicts.pass + verdicts.partial + verdicts.fail;
|
|
199
|
+
const score = testable > 0 ? Math.round((verdicts.pass / testable) * 100) : 0;
|
|
200
|
+
// Domain summaries for executive summary
|
|
201
|
+
const domainMap = new Map();
|
|
202
|
+
for (const r of routeResults) {
|
|
203
|
+
const domain = r.requirement.domain;
|
|
204
|
+
if (!domainMap.has(domain))
|
|
205
|
+
domainMap.set(domain, []);
|
|
206
|
+
domainMap.get(domain).push(r);
|
|
207
|
+
}
|
|
208
|
+
const domainSummaries = [...domainMap.entries()].map(([domain, routes]) => {
|
|
209
|
+
const domainVerifications = routes.flatMap((r) => r.verifications);
|
|
210
|
+
const domainPass = domainVerifications.filter((v) => v.verdict === 'PASS').length;
|
|
211
|
+
const domainTestable = domainPass +
|
|
212
|
+
domainVerifications.filter((v) => v.verdict === 'PARTIAL').length +
|
|
213
|
+
domainVerifications.filter((v) => v.verdict === 'FAIL').length;
|
|
214
|
+
return {
|
|
215
|
+
domain,
|
|
216
|
+
routes: routes.length,
|
|
217
|
+
score: domainTestable > 0 ? Math.round((domainPass / domainTestable) * 100) : 0,
|
|
218
|
+
};
|
|
219
|
+
});
|
|
220
|
+
// 1. Bug report
|
|
221
|
+
onProgress?.(' Generating bug report...');
|
|
222
|
+
const bugReportMd = generateBugReport(bugEntries, repoName, bugCounts);
|
|
223
|
+
await writeFile(resolve(outputDir, 'bug-report.md'), bugReportMd);
|
|
224
|
+
// 2. Coverage matrix
|
|
225
|
+
onProgress?.(' Generating coverage matrix...');
|
|
226
|
+
const coverageMatrixMd = generateCoverageMatrix(routeResults, repoName);
|
|
227
|
+
await writeFile(resolve(outputDir, 'coverage-matrix.md'), coverageMatrixMd);
|
|
228
|
+
// 3. Executive summary (Claude-generated)
|
|
229
|
+
onProgress?.(' Generating executive summary...');
|
|
230
|
+
const { summary: executiveSummary, inputTokens: execIn, outputTokens: execOut, } = await generateExecutiveSummary(repoName, totalClaims, verdicts, bugCounts, routeResults.length, domainSummaries, bugEntries, score);
|
|
231
|
+
const execSummaryMd = [
|
|
232
|
+
`# Executive Summary -- ${repoName}`,
|
|
233
|
+
``,
|
|
234
|
+
`**Assessment Date:** ${createdAt.split('T')[0]}`,
|
|
235
|
+
`**Compliance Score:** ${score}/100`,
|
|
236
|
+
``,
|
|
237
|
+
`---`,
|
|
238
|
+
``,
|
|
239
|
+
executiveSummary,
|
|
240
|
+
].join('\n');
|
|
241
|
+
await writeFile(resolve(outputDir, 'executive-summary.md'), execSummaryMd);
|
|
242
|
+
const completedAt = new Date().toISOString();
|
|
243
|
+
// 4. Build full AssessmentResult
|
|
244
|
+
const result = {
|
|
245
|
+
id: randomUUID(),
|
|
246
|
+
repoName,
|
|
247
|
+
repoUrl,
|
|
248
|
+
frameworks,
|
|
249
|
+
totalRoutes: routeResults.length,
|
|
250
|
+
totalClaims,
|
|
251
|
+
verdicts,
|
|
252
|
+
bugs: bugCounts,
|
|
253
|
+
score,
|
|
254
|
+
executiveSummary,
|
|
255
|
+
routeResults,
|
|
256
|
+
createdAt,
|
|
257
|
+
completedAt,
|
|
258
|
+
inputTokens: totalTokens.input + execIn,
|
|
259
|
+
outputTokens: totalTokens.output + execOut,
|
|
260
|
+
};
|
|
261
|
+
// 5. Machine-readable JSON
|
|
262
|
+
onProgress?.(' Writing assessment.json...');
|
|
263
|
+
await writeFile(resolve(outputDir, 'assessment.json'), JSON.stringify(result, null, 2));
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=assessment-reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assessment-reporter.js","sourceRoot":"","sources":["../../src/lib/assessment-reporter.ts"],"names":[],"mappings":"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"}
|