tryassay 0.33.1 → 0.34.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/dist/cli.js +20 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/hunt.d.ts +2 -0
- package/dist/commands/hunt.js +58 -7
- package/dist/commands/hunt.js.map +1 -1
- package/dist/commands/mcp.d.ts +14 -0
- package/dist/commands/mcp.js +18 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/watch.d.ts +19 -0
- package/dist/commands/watch.js +158 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/hunt/__tests__/finding-to-template.test.d.ts +1 -0
- package/dist/hunt/__tests__/finding-to-template.test.js +213 -0
- package/dist/hunt/__tests__/finding-to-template.test.js.map +1 -0
- package/dist/hunt/__tests__/parse-utils.test.js +28 -1
- package/dist/hunt/__tests__/parse-utils.test.js.map +1 -1
- package/dist/hunt/__tests__/taint-analysis.test.d.ts +1 -0
- package/dist/hunt/__tests__/taint-analysis.test.js +556 -0
- package/dist/hunt/__tests__/taint-analysis.test.js.map +1 -0
- package/dist/hunt/__tests__/templates.test.js +2 -2
- package/dist/hunt/__tests__/templates.test.js.map +1 -1
- package/dist/hunt/deep-dive.d.ts +2 -2
- package/dist/hunt/deep-dive.js +4 -4
- package/dist/hunt/deep-dive.js.map +1 -1
- package/dist/hunt/discovery.js +2 -2
- package/dist/hunt/discovery.js.map +1 -1
- package/dist/hunt/finding-to-template.d.ts +47 -0
- package/dist/hunt/finding-to-template.js +288 -0
- package/dist/hunt/finding-to-template.js.map +1 -0
- package/dist/hunt/orchestrator.d.ts +3 -0
- package/dist/hunt/orchestrator.js +20 -5
- package/dist/hunt/orchestrator.js.map +1 -1
- package/dist/hunt/taint-analysis.d.ts +49 -0
- package/dist/hunt/taint-analysis.js +429 -0
- package/dist/hunt/taint-analysis.js.map +1 -0
- package/dist/hunt/templates/csv-injection.d.ts +2 -0
- package/dist/hunt/templates/csv-injection.js +148 -0
- package/dist/hunt/templates/csv-injection.js.map +1 -0
- package/dist/hunt/templates/django-misconfig.d.ts +2 -0
- package/dist/hunt/templates/django-misconfig.js +172 -0
- package/dist/hunt/templates/django-misconfig.js.map +1 -0
- package/dist/hunt/templates/express-misconfig.d.ts +2 -0
- package/dist/hunt/templates/express-misconfig.js +156 -0
- package/dist/hunt/templates/express-misconfig.js.map +1 -0
- package/dist/hunt/templates/file-upload.d.ts +2 -0
- package/dist/hunt/templates/file-upload.js +131 -0
- package/dist/hunt/templates/file-upload.js.map +1 -0
- package/dist/hunt/templates/graphql-abuse.d.ts +2 -0
- package/dist/hunt/templates/graphql-abuse.js +161 -0
- package/dist/hunt/templates/graphql-abuse.js.map +1 -0
- package/dist/hunt/templates/hardcoded-credentials.d.ts +2 -0
- package/dist/hunt/templates/hardcoded-credentials.js +109 -0
- package/dist/hunt/templates/hardcoded-credentials.js.map +1 -0
- package/dist/hunt/templates/idor.d.ts +2 -0
- package/dist/hunt/templates/idor.js +102 -0
- package/dist/hunt/templates/idor.js.map +1 -0
- package/dist/hunt/templates/index.d.ts +2 -2
- package/dist/hunt/templates/index.js +38 -5
- package/dist/hunt/templates/index.js.map +1 -1
- package/dist/hunt/templates/insecure-deserialization.d.ts +2 -0
- package/dist/hunt/templates/insecure-deserialization.js +131 -0
- package/dist/hunt/templates/insecure-deserialization.js.map +1 -0
- package/dist/hunt/templates/mass-assignment.d.ts +2 -0
- package/dist/hunt/templates/mass-assignment.js +101 -0
- package/dist/hunt/templates/mass-assignment.js.map +1 -0
- package/dist/hunt/templates/nextjs-misconfig.d.ts +2 -0
- package/dist/hunt/templates/nextjs-misconfig.js +127 -0
- package/dist/hunt/templates/nextjs-misconfig.js.map +1 -0
- package/dist/hunt/templates/postmessage.d.ts +2 -0
- package/dist/hunt/templates/postmessage.js +180 -0
- package/dist/hunt/templates/postmessage.js.map +1 -0
- package/dist/hunt/templates/race-condition.d.ts +2 -0
- package/dist/hunt/templates/race-condition.js +138 -0
- package/dist/hunt/templates/race-condition.js.map +1 -0
- package/dist/hunt/templates/spring-misconfig.d.ts +2 -0
- package/dist/hunt/templates/spring-misconfig.js +177 -0
- package/dist/hunt/templates/spring-misconfig.js.map +1 -0
- package/dist/hunt/templates/xxe.d.ts +2 -0
- package/dist/hunt/templates/xxe.js +187 -0
- package/dist/hunt/templates/xxe.js.map +1 -0
- package/dist/hunt/triage.d.ts +2 -2
- package/dist/hunt/triage.js +4 -4
- package/dist/hunt/triage.js.map +1 -1
- package/dist/realtime/__tests__/catch-real-bugs.test.d.ts +9 -0
- package/dist/realtime/__tests__/catch-real-bugs.test.js +205 -0
- package/dist/realtime/__tests__/catch-real-bugs.test.js.map +1 -0
- package/dist/realtime/__tests__/code-buffer.test.d.ts +1 -0
- package/dist/realtime/__tests__/code-buffer.test.js +202 -0
- package/dist/realtime/__tests__/code-buffer.test.js.map +1 -0
- package/dist/realtime/__tests__/correction-injector.test.d.ts +1 -0
- package/dist/realtime/__tests__/correction-injector.test.js +168 -0
- package/dist/realtime/__tests__/correction-injector.test.js.map +1 -0
- package/dist/realtime/__tests__/stream-interceptor.test.d.ts +1 -0
- package/dist/realtime/__tests__/stream-interceptor.test.js +193 -0
- package/dist/realtime/__tests__/stream-interceptor.test.js.map +1 -0
- package/dist/realtime/__tests__/streaming-checks.test.d.ts +1 -0
- package/dist/realtime/__tests__/streaming-checks.test.js +479 -0
- package/dist/realtime/__tests__/streaming-checks.test.js.map +1 -0
- package/dist/realtime/__tests__/streaming-verifier.test.d.ts +1 -0
- package/dist/realtime/__tests__/streaming-verifier.test.js +157 -0
- package/dist/realtime/__tests__/streaming-verifier.test.js.map +1 -0
- package/dist/realtime/code-buffer.d.ts +52 -0
- package/dist/realtime/code-buffer.js +276 -0
- package/dist/realtime/code-buffer.js.map +1 -0
- package/dist/realtime/correction-injector.d.ts +56 -0
- package/dist/realtime/correction-injector.js +96 -0
- package/dist/realtime/correction-injector.js.map +1 -0
- package/dist/realtime/index.d.ts +14 -0
- package/dist/realtime/index.js +11 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/realtime/mcp-server.d.ts +14 -0
- package/dist/realtime/mcp-server.js +200 -0
- package/dist/realtime/mcp-server.js.map +1 -0
- package/dist/realtime/stream-interceptor.d.ts +65 -0
- package/dist/realtime/stream-interceptor.js +174 -0
- package/dist/realtime/stream-interceptor.js.map +1 -0
- package/dist/realtime/streaming-checks.d.ts +55 -0
- package/dist/realtime/streaming-checks.js +452 -0
- package/dist/realtime/streaming-checks.js.map +1 -0
- package/dist/realtime/streaming-verifier.d.ts +57 -0
- package/dist/realtime/streaming-verifier.js +134 -0
- package/dist/realtime/streaming-verifier.js.map +1 -0
- package/dist/realtime/types.d.ts +99 -0
- package/dist/realtime/types.js +8 -0
- package/dist/realtime/types.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correction-injector.js","sourceRoot":"","sources":["../../src/realtime/correction-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,8EAA8E;AAC9E,iDAAiD;AACjD,8EAA8E;AAE9E,MAAM,aAAa,GAAkC;IACnD,GAAG,EAAE,CAAC;IACN,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,QAAQ,EAAE,CAAC;CACZ,CAAC;AAsBF,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,MAAM,OAAO,kBAAkB;IACZ,WAAW,CAAgB;IAC3B,cAAc,CAAS;IAChC,eAAe,GAAG,CAAC,CAAC;IAE5B,YAAY,OAAmC;QAC7C,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,MAAM,CAAC;QAClD,IAAI,CAAC,cAAc,GAAG,OAAO,EAAE,cAAc,IAAI,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAwB;QACpC,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM;YAAE,OAAO,KAAK,CAAC;QAC3C,IAAI,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC;YAAE,OAAO,KAAK,CAAC;QAClF,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,cAAc;YAAE,OAAO,KAAK,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;OASG;IACH,uBAAuB,CACrB,cAAsB,EACtB,KAAwB,EACxB,qBAA6B,EAC7B,kBAA0B;QAE1B,MAAM,cAAc,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAElD,OAAO;YACL,EAAE,IAAI,EAAE,MAAe,EAAE,OAAO,EAAE,kBAAkB,EAAE;YACtD,EAAE,IAAI,EAAE,WAAoB,EAAE,OAAO,EAAE,cAAc,EAAE;YACvD,EAAE,IAAI,EAAE,MAAe,EAAE,OAAO,EAAE,cAAc,EAAE;SACnD,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,gBAAgB,CAAC,MAAyB;QACxC,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,6CAA6C;IAC7C,kBAAkB;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,wDAAwD;IACxD,KAAK;QACH,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,mBAAmB,CAAC,KAAwB;IACnD,MAAM,KAAK,GAAa;QACtB,uCAAuC;QACvC,GAAG,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,QAAQ,EAAE;KACxC,CAAC;IAEF,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,IAAI,CACR,EAAE,EACF,4JAA4J,CAC7J,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,wBAAwB;AACxB,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real-time verification pipeline — verify code as it streams from the LLM.
|
|
3
|
+
*
|
|
4
|
+
* Phase 2 of the 10x roadmap.
|
|
5
|
+
*/
|
|
6
|
+
export { CodeBuffer } from './code-buffer.js';
|
|
7
|
+
export { getFormalChecks, loadLearnedChecks, compileCheckSet, runChecks, } from './streaming-checks.js';
|
|
8
|
+
export { StreamingVerifier } from './streaming-verifier.js';
|
|
9
|
+
export type { StreamingVerifierOptions } from './streaming-verifier.js';
|
|
10
|
+
export { CorrectionInjector } from './correction-injector.js';
|
|
11
|
+
export type { CorrectionInjectorOptions, CorrectionMessage } from './correction-injector.js';
|
|
12
|
+
export { createVerifiedStream, createVerifiedStreamFromTokens, } from './stream-interceptor.js';
|
|
13
|
+
export type { VerifiedStreamOptions, VerifiedStreamResult, } from './stream-interceptor.js';
|
|
14
|
+
export type { CheckSeverity, CodeUnit, CodeUnitKind, CompiledCheckSet, CorrectionResult, StreamingCheck, StreamingVerifierStats, VerificationEvent, } from './types.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real-time verification pipeline — verify code as it streams from the LLM.
|
|
3
|
+
*
|
|
4
|
+
* Phase 2 of the 10x roadmap.
|
|
5
|
+
*/
|
|
6
|
+
export { CodeBuffer } from './code-buffer.js';
|
|
7
|
+
export { getFormalChecks, loadLearnedChecks, compileCheckSet, runChecks, } from './streaming-checks.js';
|
|
8
|
+
export { StreamingVerifier } from './streaming-verifier.js';
|
|
9
|
+
export { CorrectionInjector } from './correction-injector.js';
|
|
10
|
+
export { createVerifiedStream, createVerifiedStreamFromTokens, } from './stream-interceptor.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,SAAS,GACV,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EACL,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server for Assay real-time verification.
|
|
3
|
+
*
|
|
4
|
+
* Exposes two tools over stdio transport:
|
|
5
|
+
* - verify_code: One-shot verification of a code snippet
|
|
6
|
+
* - verify_and_fix: Verify code and return fix suggestions
|
|
7
|
+
*
|
|
8
|
+
* Usage with Claude Code:
|
|
9
|
+
* npx tryassay mcp
|
|
10
|
+
*
|
|
11
|
+
* Claude Code config (~/.claude.json):
|
|
12
|
+
* { "mcpServers": { "assay": { "command": "npx", "args": ["tryassay", "mcp"] } } }
|
|
13
|
+
*/
|
|
14
|
+
export declare function startMcpServer(): Promise<void>;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server for Assay real-time verification.
|
|
3
|
+
*
|
|
4
|
+
* Exposes two tools over stdio transport:
|
|
5
|
+
* - verify_code: One-shot verification of a code snippet
|
|
6
|
+
* - verify_and_fix: Verify code and return fix suggestions
|
|
7
|
+
*
|
|
8
|
+
* Usage with Claude Code:
|
|
9
|
+
* npx tryassay mcp
|
|
10
|
+
*
|
|
11
|
+
* Claude Code config (~/.claude.json):
|
|
12
|
+
* { "mcpServers": { "assay": { "command": "npx", "args": ["tryassay", "mcp"] } } }
|
|
13
|
+
*/
|
|
14
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
15
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
16
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
17
|
+
import { StreamingVerifier } from './streaming-verifier.js';
|
|
18
|
+
// ── Core verification logic ─────────────────────────────────
|
|
19
|
+
function verifyCode(code, language, projectPath) {
|
|
20
|
+
const verifier = new StreamingVerifier({
|
|
21
|
+
language,
|
|
22
|
+
projectPath: projectPath || undefined,
|
|
23
|
+
});
|
|
24
|
+
verifier.push(code);
|
|
25
|
+
verifier.flush();
|
|
26
|
+
const rawFindings = verifier.getFindings();
|
|
27
|
+
const stats = verifier.getStats();
|
|
28
|
+
const findings = rawFindings.map((f) => ({
|
|
29
|
+
checkName: f.checkName,
|
|
30
|
+
severity: f.severity,
|
|
31
|
+
evidence: f.evidence,
|
|
32
|
+
suggestion: f.suggestion,
|
|
33
|
+
}));
|
|
34
|
+
return {
|
|
35
|
+
findings,
|
|
36
|
+
stats: {
|
|
37
|
+
unitsProcessed: stats.unitsProcessed,
|
|
38
|
+
checksRun: stats.checksRun,
|
|
39
|
+
findings: stats.findings,
|
|
40
|
+
avgLatencyMs: Math.round(stats.avgLatencyMs * 100) / 100,
|
|
41
|
+
},
|
|
42
|
+
clean: findings.length === 0,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function buildFixInstructions(findings) {
|
|
46
|
+
if (findings.length === 0) {
|
|
47
|
+
return 'No issues found. Code is clean.';
|
|
48
|
+
}
|
|
49
|
+
const lines = [
|
|
50
|
+
`Found ${findings.length} issue${findings.length > 1 ? 's' : ''} to fix:`,
|
|
51
|
+
'',
|
|
52
|
+
];
|
|
53
|
+
for (let i = 0; i < findings.length; i++) {
|
|
54
|
+
const f = findings[i];
|
|
55
|
+
lines.push(`${i + 1}. [${f.severity.toUpperCase()}] ${f.checkName}`);
|
|
56
|
+
lines.push(` Problem: ${f.evidence}`);
|
|
57
|
+
if (f.suggestion) {
|
|
58
|
+
lines.push(` Fix: ${f.suggestion}`);
|
|
59
|
+
}
|
|
60
|
+
lines.push('');
|
|
61
|
+
}
|
|
62
|
+
lines.push('Apply the fixes above and re-verify to confirm resolution.');
|
|
63
|
+
return lines.join('\n');
|
|
64
|
+
}
|
|
65
|
+
// ── MCP Server ──────────────────────────────────────────────
|
|
66
|
+
export async function startMcpServer() {
|
|
67
|
+
const server = new Server({
|
|
68
|
+
name: 'assay',
|
|
69
|
+
version: '0.33.2',
|
|
70
|
+
}, {
|
|
71
|
+
capabilities: {
|
|
72
|
+
tools: {},
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
// List available tools
|
|
76
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
77
|
+
tools: [
|
|
78
|
+
{
|
|
79
|
+
name: 'verify_code',
|
|
80
|
+
description: 'Verify a code snippet for security vulnerabilities, error handling gaps, and common bugs. Returns structured findings with severity levels. Use this after generating code to catch issues before they ship.',
|
|
81
|
+
inputSchema: {
|
|
82
|
+
type: 'object',
|
|
83
|
+
properties: {
|
|
84
|
+
code: {
|
|
85
|
+
type: 'string',
|
|
86
|
+
description: 'The code to verify',
|
|
87
|
+
},
|
|
88
|
+
language: {
|
|
89
|
+
type: 'string',
|
|
90
|
+
description: 'Language of the code (typescript, javascript, python, etc.)',
|
|
91
|
+
},
|
|
92
|
+
projectPath: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
description: 'Optional project path for loading learned verification rules',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
required: ['code', 'language'],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'verify_and_fix',
|
|
102
|
+
description: 'Verify a code snippet and return actionable fix instructions. Use this to self-correct generated code. Returns findings plus step-by-step fix instructions.',
|
|
103
|
+
inputSchema: {
|
|
104
|
+
type: 'object',
|
|
105
|
+
properties: {
|
|
106
|
+
code: {
|
|
107
|
+
type: 'string',
|
|
108
|
+
description: 'The code to verify',
|
|
109
|
+
},
|
|
110
|
+
language: {
|
|
111
|
+
type: 'string',
|
|
112
|
+
description: 'Language of the code (typescript, javascript, python, etc.)',
|
|
113
|
+
},
|
|
114
|
+
projectPath: {
|
|
115
|
+
type: 'string',
|
|
116
|
+
description: 'Optional project path for loading learned verification rules',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
required: ['code', 'language'],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
}));
|
|
124
|
+
// Handle tool calls
|
|
125
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
126
|
+
const { name, arguments: args } = request.params;
|
|
127
|
+
if (name === 'verify_code') {
|
|
128
|
+
const code = args?.code;
|
|
129
|
+
const language = args?.language;
|
|
130
|
+
const projectPath = args?.projectPath;
|
|
131
|
+
if (!code || !language) {
|
|
132
|
+
return {
|
|
133
|
+
content: [
|
|
134
|
+
{
|
|
135
|
+
type: 'text',
|
|
136
|
+
text: JSON.stringify({
|
|
137
|
+
error: 'Both "code" and "language" are required',
|
|
138
|
+
}),
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
isError: true,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const result = verifyCode(code, language, projectPath);
|
|
145
|
+
return {
|
|
146
|
+
content: [
|
|
147
|
+
{
|
|
148
|
+
type: 'text',
|
|
149
|
+
text: JSON.stringify(result, null, 2),
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (name === 'verify_and_fix') {
|
|
155
|
+
const code = args?.code;
|
|
156
|
+
const language = args?.language;
|
|
157
|
+
const projectPath = args?.projectPath;
|
|
158
|
+
if (!code || !language) {
|
|
159
|
+
return {
|
|
160
|
+
content: [
|
|
161
|
+
{
|
|
162
|
+
type: 'text',
|
|
163
|
+
text: JSON.stringify({
|
|
164
|
+
error: 'Both "code" and "language" are required',
|
|
165
|
+
}),
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
isError: true,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
const verifyResult = verifyCode(code, language, projectPath);
|
|
172
|
+
const fixInstructions = buildFixInstructions(verifyResult.findings);
|
|
173
|
+
const result = {
|
|
174
|
+
...verifyResult,
|
|
175
|
+
fixInstructions,
|
|
176
|
+
};
|
|
177
|
+
return {
|
|
178
|
+
content: [
|
|
179
|
+
{
|
|
180
|
+
type: 'text',
|
|
181
|
+
text: JSON.stringify(result, null, 2),
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
content: [
|
|
188
|
+
{
|
|
189
|
+
type: 'text',
|
|
190
|
+
text: JSON.stringify({ error: `Unknown tool: ${name}` }),
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
isError: true,
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
// Connect via stdio
|
|
197
|
+
const transport = new StdioServerTransport();
|
|
198
|
+
await server.connect(transport);
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../../src/realtime/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamInterceptor — wraps the Anthropic streaming API to pipe tokens
|
|
3
|
+
* through the real-time verification pipeline transparently.
|
|
4
|
+
*
|
|
5
|
+
* Consumers get a verified text stream: code with bugs gets flagged
|
|
6
|
+
* (and optionally corrected) mid-generation.
|
|
7
|
+
*
|
|
8
|
+
* Phase 2, Milestone 3 of the 10x roadmap.
|
|
9
|
+
*/
|
|
10
|
+
import type { CheckSeverity, StreamingVerifierStats, VerificationEvent } from './types.js';
|
|
11
|
+
export interface VerifiedStreamOptions {
|
|
12
|
+
/** Anthropic API key (falls back to ANTHROPIC_API_KEY env) */
|
|
13
|
+
apiKey?: string;
|
|
14
|
+
/** Model to use. Default: 'claude-sonnet-4-20250514' */
|
|
15
|
+
model?: string;
|
|
16
|
+
/** System prompt for code generation */
|
|
17
|
+
systemPrompt?: string;
|
|
18
|
+
/** User prompt (the code request) */
|
|
19
|
+
userPrompt: string;
|
|
20
|
+
/** Language of the code being generated */
|
|
21
|
+
language: string;
|
|
22
|
+
/** Max tokens. Default: 4096 */
|
|
23
|
+
maxTokens?: number;
|
|
24
|
+
/** Project path for loading learned rules */
|
|
25
|
+
projectPath?: string;
|
|
26
|
+
/** Callback for each text chunk */
|
|
27
|
+
onText?: (text: string) => void;
|
|
28
|
+
/** Callback for each verification event */
|
|
29
|
+
onVerification?: (event: VerificationEvent) => void;
|
|
30
|
+
/** Callback when a correction is triggered */
|
|
31
|
+
onCorrection?: (info: {
|
|
32
|
+
finding: VerificationEvent;
|
|
33
|
+
generatedSoFar: string;
|
|
34
|
+
}) => void;
|
|
35
|
+
/** Enable auto-correction. Default: false for MVP */
|
|
36
|
+
autoCorrect?: boolean;
|
|
37
|
+
/** Min severity for auto-correction. Default: 'high' */
|
|
38
|
+
minCorrectionSeverity?: CheckSeverity;
|
|
39
|
+
}
|
|
40
|
+
export interface VerifiedStreamResult {
|
|
41
|
+
/** The full generated text */
|
|
42
|
+
text: string;
|
|
43
|
+
/** All verification events */
|
|
44
|
+
events: VerificationEvent[];
|
|
45
|
+
/** Only the findings (FAIL events) */
|
|
46
|
+
findings: VerificationEvent[];
|
|
47
|
+
/** Verifier statistics */
|
|
48
|
+
stats: StreamingVerifierStats;
|
|
49
|
+
/** API usage */
|
|
50
|
+
inputTokens: number;
|
|
51
|
+
outputTokens: number;
|
|
52
|
+
/** Total wall time */
|
|
53
|
+
durationMs: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create and run a verified stream using the Anthropic API.
|
|
57
|
+
* Returns when generation is complete.
|
|
58
|
+
*/
|
|
59
|
+
export declare function createVerifiedStream(options: VerifiedStreamOptions): Promise<VerifiedStreamResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Simulate a verified stream by pushing an array of token strings through
|
|
62
|
+
* the verification pipeline. Same logic as createVerifiedStream but without
|
|
63
|
+
* the Anthropic client. Useful for deterministic testing.
|
|
64
|
+
*/
|
|
65
|
+
export declare function createVerifiedStreamFromTokens(tokens: string[], options: Omit<VerifiedStreamOptions, 'userPrompt' | 'apiKey' | 'model' | 'systemPrompt' | 'maxTokens'>): VerifiedStreamResult;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamInterceptor — wraps the Anthropic streaming API to pipe tokens
|
|
3
|
+
* through the real-time verification pipeline transparently.
|
|
4
|
+
*
|
|
5
|
+
* Consumers get a verified text stream: code with bugs gets flagged
|
|
6
|
+
* (and optionally corrected) mid-generation.
|
|
7
|
+
*
|
|
8
|
+
* Phase 2, Milestone 3 of the 10x roadmap.
|
|
9
|
+
*/
|
|
10
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
11
|
+
import { StreamingVerifier } from './streaming-verifier.js';
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Severity ordering for comparison
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
const SEVERITY_RANK = {
|
|
16
|
+
critical: 4,
|
|
17
|
+
high: 3,
|
|
18
|
+
medium: 2,
|
|
19
|
+
low: 1,
|
|
20
|
+
};
|
|
21
|
+
function meetsMinSeverity(severity, minSeverity) {
|
|
22
|
+
return SEVERITY_RANK[severity] >= SEVERITY_RANK[minSeverity];
|
|
23
|
+
}
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Core pipeline logic (shared between real and test entrypoints)
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
/**
|
|
28
|
+
* Process a sequence of text chunks through the verification pipeline.
|
|
29
|
+
* This is the shared core used by both createVerifiedStream (real API)
|
|
30
|
+
* and createVerifiedStreamFromTokens (test helper).
|
|
31
|
+
*/
|
|
32
|
+
function processTokensThroughPipeline(tokens, verifier, options) {
|
|
33
|
+
const allEvents = [];
|
|
34
|
+
const autoCorrect = options.autoCorrect ?? false;
|
|
35
|
+
const minCorrectionSeverity = options.minCorrectionSeverity ?? 'high';
|
|
36
|
+
for (const chunk of tokens) {
|
|
37
|
+
// Fire text callback
|
|
38
|
+
options.onText?.(chunk);
|
|
39
|
+
// Push through verifier
|
|
40
|
+
const events = verifier.push(chunk);
|
|
41
|
+
for (const event of events) {
|
|
42
|
+
allEvents.push(event);
|
|
43
|
+
options.onVerification?.(event);
|
|
44
|
+
// Auto-correction callback for critical/high findings
|
|
45
|
+
if (autoCorrect &&
|
|
46
|
+
event.verdict === 'FAIL' &&
|
|
47
|
+
meetsMinSeverity(event.severity, minCorrectionSeverity)) {
|
|
48
|
+
options.onCorrection?.({
|
|
49
|
+
finding: event,
|
|
50
|
+
generatedSoFar: verifier.getGeneratedCode(),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Flush trailing code that never hit a structural boundary
|
|
56
|
+
const flushEvents = verifier.flush();
|
|
57
|
+
for (const event of flushEvents) {
|
|
58
|
+
allEvents.push(event);
|
|
59
|
+
options.onVerification?.(event);
|
|
60
|
+
if (autoCorrect &&
|
|
61
|
+
event.verdict === 'FAIL' &&
|
|
62
|
+
meetsMinSeverity(event.severity, minCorrectionSeverity)) {
|
|
63
|
+
options.onCorrection?.({
|
|
64
|
+
finding: event,
|
|
65
|
+
generatedSoFar: verifier.getGeneratedCode(),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return { allEvents };
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// createVerifiedStream — real Anthropic API
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
/**
|
|
75
|
+
* Create and run a verified stream using the Anthropic API.
|
|
76
|
+
* Returns when generation is complete.
|
|
77
|
+
*/
|
|
78
|
+
export async function createVerifiedStream(options) {
|
|
79
|
+
const start = Date.now();
|
|
80
|
+
const model = options.model ?? 'claude-sonnet-4-20250514';
|
|
81
|
+
const maxTokens = options.maxTokens ?? 4096;
|
|
82
|
+
// Create verifier
|
|
83
|
+
const verifier = new StreamingVerifier({
|
|
84
|
+
language: options.language,
|
|
85
|
+
projectPath: options.projectPath,
|
|
86
|
+
});
|
|
87
|
+
// Create Anthropic client
|
|
88
|
+
const apiKey = options.apiKey ?? process.env.ANTHROPIC_API_KEY;
|
|
89
|
+
if (!apiKey) {
|
|
90
|
+
throw new Error('ANTHROPIC_API_KEY is required for createVerifiedStream.\n' +
|
|
91
|
+
'Set it via the apiKey option or ANTHROPIC_API_KEY env var.');
|
|
92
|
+
}
|
|
93
|
+
const client = new Anthropic({ apiKey });
|
|
94
|
+
// Start streaming
|
|
95
|
+
const stream = client.messages.stream({
|
|
96
|
+
model,
|
|
97
|
+
max_tokens: maxTokens,
|
|
98
|
+
...(options.systemPrompt ? { system: options.systemPrompt } : {}),
|
|
99
|
+
messages: [{ role: 'user', content: options.userPrompt }],
|
|
100
|
+
});
|
|
101
|
+
// Collect text events into an array, then process them
|
|
102
|
+
const allEvents = [];
|
|
103
|
+
const autoCorrect = options.autoCorrect ?? false;
|
|
104
|
+
const minCorrectionSeverity = options.minCorrectionSeverity ?? 'high';
|
|
105
|
+
stream.on('text', (text) => {
|
|
106
|
+
options.onText?.(text);
|
|
107
|
+
const events = verifier.push(text);
|
|
108
|
+
for (const event of events) {
|
|
109
|
+
allEvents.push(event);
|
|
110
|
+
options.onVerification?.(event);
|
|
111
|
+
if (autoCorrect &&
|
|
112
|
+
event.verdict === 'FAIL' &&
|
|
113
|
+
meetsMinSeverity(event.severity, minCorrectionSeverity)) {
|
|
114
|
+
options.onCorrection?.({
|
|
115
|
+
finding: event,
|
|
116
|
+
generatedSoFar: verifier.getGeneratedCode(),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// Wait for stream to complete
|
|
122
|
+
const finalMessage = await stream.finalMessage();
|
|
123
|
+
// Flush trailing code
|
|
124
|
+
const flushEvents = verifier.flush();
|
|
125
|
+
for (const event of flushEvents) {
|
|
126
|
+
allEvents.push(event);
|
|
127
|
+
options.onVerification?.(event);
|
|
128
|
+
if (autoCorrect &&
|
|
129
|
+
event.verdict === 'FAIL' &&
|
|
130
|
+
meetsMinSeverity(event.severity, minCorrectionSeverity)) {
|
|
131
|
+
options.onCorrection?.({
|
|
132
|
+
finding: event,
|
|
133
|
+
generatedSoFar: verifier.getGeneratedCode(),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const findings = allEvents.filter(e => e.verdict === 'FAIL');
|
|
138
|
+
return {
|
|
139
|
+
text: verifier.getGeneratedCode(),
|
|
140
|
+
events: allEvents,
|
|
141
|
+
findings,
|
|
142
|
+
stats: verifier.getStats(),
|
|
143
|
+
inputTokens: finalMessage.usage.input_tokens,
|
|
144
|
+
outputTokens: finalMessage.usage.output_tokens,
|
|
145
|
+
durationMs: Date.now() - start,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// createVerifiedStreamFromTokens — test helper (no API calls)
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
/**
|
|
152
|
+
* Simulate a verified stream by pushing an array of token strings through
|
|
153
|
+
* the verification pipeline. Same logic as createVerifiedStream but without
|
|
154
|
+
* the Anthropic client. Useful for deterministic testing.
|
|
155
|
+
*/
|
|
156
|
+
export function createVerifiedStreamFromTokens(tokens, options) {
|
|
157
|
+
const start = Date.now();
|
|
158
|
+
const verifier = new StreamingVerifier({
|
|
159
|
+
language: options.language,
|
|
160
|
+
projectPath: options.projectPath,
|
|
161
|
+
});
|
|
162
|
+
const { allEvents } = processTokensThroughPipeline(tokens, verifier, options);
|
|
163
|
+
const findings = allEvents.filter(e => e.verdict === 'FAIL');
|
|
164
|
+
return {
|
|
165
|
+
text: verifier.getGeneratedCode(),
|
|
166
|
+
events: allEvents,
|
|
167
|
+
findings,
|
|
168
|
+
stats: verifier.getStats(),
|
|
169
|
+
inputTokens: 0,
|
|
170
|
+
outputTokens: 0,
|
|
171
|
+
durationMs: Date.now() - start,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=stream-interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-interceptor.js","sourceRoot":"","sources":["../../src/realtime/stream-interceptor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AA0D5D,8EAA8E;AAC9E,mCAAmC;AACnC,8EAA8E;AAE9E,MAAM,aAAa,GAAkC;IACnD,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;CACP,CAAC;AAEF,SAAS,gBAAgB,CACvB,QAAuB,EACvB,WAA0B;IAE1B,OAAO,aAAa,CAAC,QAAQ,CAAC,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;AAC/D,CAAC;AAED,8EAA8E;AAC9E,iEAAiE;AACjE,8EAA8E;AAE9E;;;;GAIG;AACH,SAAS,4BAA4B,CACnC,MAAwB,EACxB,QAA2B,EAC3B,OAGC;IAED,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC;IACjD,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,IAAI,MAAM,CAAC;IAEtE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,qBAAqB;QACrB,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;QAExB,wBAAwB;QACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC;YAEhC,sDAAsD;YACtD,IACE,WAAW;gBACX,KAAK,CAAC,OAAO,KAAK,MAAM;gBACxB,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EACvD,CAAC;gBACD,OAAO,CAAC,YAAY,EAAE,CAAC;oBACrB,OAAO,EAAE,KAAK;oBACd,cAAc,EAAE,QAAQ,CAAC,gBAAgB,EAAE;iBAC5C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC;QAEhC,IACE,WAAW;YACX,KAAK,CAAC,OAAO,KAAK,MAAM;YACxB,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EACvD,CAAC;YACD,OAAO,CAAC,YAAY,EAAE,CAAC;gBACrB,OAAO,EAAE,KAAK;gBACd,cAAc,EAAE,QAAQ,CAAC,gBAAgB,EAAE;aAC5C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,CAAC;AACvB,CAAC;AAED,8EAA8E;AAC9E,4CAA4C;AAC5C,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAA8B;IAE9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,0BAA0B,CAAC;IAC1D,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;IAE5C,kBAAkB;IAClB,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC;QACrC,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC/D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,2DAA2D;YAC3D,4DAA4D,CAC7D,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAEzC,kBAAkB;IAClB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QACpC,KAAK;QACL,UAAU,EAAE,SAAS;QACrB,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;KAC1D,CAAC,CAAC;IAEH,uDAAuD;IACvD,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC;IACjD,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,IAAI,MAAM,CAAC;IAEtE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACzB,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QAEvB,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC;YAEhC,IACE,WAAW;gBACX,KAAK,CAAC,OAAO,KAAK,MAAM;gBACxB,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EACvD,CAAC;gBACD,OAAO,CAAC,YAAY,EAAE,CAAC;oBACrB,OAAO,EAAE,KAAK;oBACd,cAAc,EAAE,QAAQ,CAAC,gBAAgB,EAAE;iBAC5C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,8BAA8B;IAC9B,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;IAEjD,sBAAsB;IACtB,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC;QAEhC,IACE,WAAW;YACX,KAAK,CAAC,OAAO,KAAK,MAAM;YACxB,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EACvD,CAAC;YACD,OAAO,CAAC,YAAY,EAAE,CAAC;gBACrB,OAAO,EAAE,KAAK;gBACd,cAAc,EAAE,QAAQ,CAAC,gBAAgB,EAAE;aAC5C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;IAE7D,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAAE;QACjC,MAAM,EAAE,SAAS;QACjB,QAAQ;QACR,KAAK,EAAE,QAAQ,CAAC,QAAQ,EAAE;QAC1B,WAAW,EAAE,YAAY,CAAC,KAAK,CAAC,YAAY;QAC5C,YAAY,EAAE,YAAY,CAAC,KAAK,CAAC,aAAa;QAC9C,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;KAC/B,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,8DAA8D;AAC9D,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAC5C,MAAgB,EAChB,OAAsG;IAEtG,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC;QACrC,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IAEH,MAAM,EAAE,SAAS,EAAE,GAAG,4BAA4B,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;IAE7D,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAAE;QACjC,MAAM,EAAE,SAAS;QACjB,QAAQ;QACR,KAAK,EAAE,QAAQ,CAAC,QAAQ,EAAE;QAC1B,WAAW,EAAE,CAAC;QACd,YAAY,EAAE,CAAC;QACf,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;KAC/B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming Checks — stateless, pre-compiled pattern matchers for real-time verification.
|
|
3
|
+
*
|
|
4
|
+
* Extracts the regex-based formal verification checks from the existing
|
|
5
|
+
* formal-verifier.ts into standalone StreamingCheck objects. Also loads
|
|
6
|
+
* learned rules from the catalog and compiles them into the same format.
|
|
7
|
+
*
|
|
8
|
+
* All regex patterns are created once at module load time and reused across
|
|
9
|
+
* invocations. The `runChecks` function targets <10ms for the full check set
|
|
10
|
+
* against a single code unit.
|
|
11
|
+
*/
|
|
12
|
+
import type { StreamingCheck, CompiledCheckSet, CodeUnit, VerificationEvent } from './types.js';
|
|
13
|
+
import type { LearnedRule } from '../lib/learned-rules/types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Returns all hand-crafted formal checks as StreamingCheck objects.
|
|
16
|
+
*
|
|
17
|
+
* These cover the key vulnerability patterns from formal-verifier.ts,
|
|
18
|
+
* adapted for streaming (line/statement-level) detection during generation.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getFormalChecks(): StreamingCheck[];
|
|
21
|
+
/**
|
|
22
|
+
* Derive context keywords for a learned rule based on its name, description,
|
|
23
|
+
* and category. Returns undefined if no specific context can be inferred
|
|
24
|
+
* (the rule will run against all code units).
|
|
25
|
+
*/
|
|
26
|
+
declare function deriveContextKeywords(rule: LearnedRule): string[] | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Extract literal substrings (4+ alphanumeric chars) from a regex pattern.
|
|
29
|
+
* These are likely the actual identifiers the rule is looking for.
|
|
30
|
+
*/
|
|
31
|
+
declare function extractRegexLiterals(regexStr: string): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Load learned rules from the catalog and convert them to StreamingCheck format.
|
|
34
|
+
*
|
|
35
|
+
* Default path: `.assay/learned/rules.json` relative to process.cwd().
|
|
36
|
+
* Falls back to an empty set if the file doesn't exist (starter rules
|
|
37
|
+
* are loaded separately by getFormalChecks equivalent in the catalog).
|
|
38
|
+
*
|
|
39
|
+
* Each rule is assigned contextKeywords for relevance filtering — the check
|
|
40
|
+
* only runs on code units that contain at least one keyword.
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadLearnedChecks(catalogPath?: string): StreamingCheck[];
|
|
43
|
+
export { deriveContextKeywords as _deriveContextKeywords, extractRegexLiterals as _extractRegexLiterals };
|
|
44
|
+
/**
|
|
45
|
+
* Filter checks by language and return a pre-compiled set ready for fast execution.
|
|
46
|
+
*
|
|
47
|
+
* If no checks are provided, uses the built-in formal checks.
|
|
48
|
+
*/
|
|
49
|
+
export declare function compileCheckSet(language: string, checks?: StreamingCheck[]): CompiledCheckSet;
|
|
50
|
+
/**
|
|
51
|
+
* Run all checks in the set against a code unit. Returns verification events.
|
|
52
|
+
*
|
|
53
|
+
* Designed to complete in <10ms for the full check set against a typical code unit.
|
|
54
|
+
*/
|
|
55
|
+
export declare function runChecks(unit: CodeUnit, checkSet: CompiledCheckSet): VerificationEvent[];
|