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 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGvC,MAAM,SAAS,GAAG,QAAQ,CAAC;AAC3B,MAAM,WAAW,GAAG,aAAa,CAAC;AAClC,MAAM,cAAc,GAAG,YAAY,CAAC;AAEpC,MAAM,UAAU,WAAW,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACrD,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACvD,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC1D,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC5D,OAAO,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC1D,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,sDAAsD,CACvD,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAmB,EAAE,MAAc,OAAO,CAAC,GAAG,EAAE;IAChF,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAEtC,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACvF,CAAC"}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { getClient, MODEL } from './anthropic.js';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Domain patterns — embedded knowledge from Assay benchmark findings
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
const DOMAIN_PATTERNS = [
|
|
6
|
+
{
|
|
7
|
+
triggers: ['sql', 'query', 'database', 'db'],
|
|
8
|
+
constraints: [
|
|
9
|
+
{ type: 'must', description: 'Use parameterized queries, never string concatenation for SQL' },
|
|
10
|
+
{ type: 'must-not', description: 'Never build SQL with template literals or string concatenation', pattern: '`SELECT * FROM ${table} WHERE id = ${id}`' },
|
|
11
|
+
],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
triggers: ['password', 'auth', 'login', 'credentials'],
|
|
15
|
+
constraints: [
|
|
16
|
+
{ type: 'must', description: 'Use bcrypt or argon2 for password hashing, never MD5/SHA1' },
|
|
17
|
+
{ type: 'must-not', description: 'Never store passwords in plaintext or use weak hashing' },
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
triggers: ['counter', 'increment', 'shared', 'concurrent'],
|
|
22
|
+
constraints: [
|
|
23
|
+
{ type: 'must', description: 'Use atomic operations or transactions for shared state updates' },
|
|
24
|
+
{ type: 'must-not', description: 'Never use read-then-write pattern for counters without locking', pattern: 'const count = await getCount(); await setCount(count + 1);' },
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
triggers: ['api', 'fetch', 'request', 'http'],
|
|
29
|
+
constraints: [
|
|
30
|
+
{ type: 'must', description: 'Handle HTTP errors explicitly (check response.ok or status code)' },
|
|
31
|
+
{ type: 'must-not', description: 'Never ignore HTTP error responses or assume success' },
|
|
32
|
+
{ type: 'prefer', description: 'Include timeout configuration for HTTP requests' },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
triggers: ['array', 'list', 'collection', 'filter', 'map', 'reduce'],
|
|
37
|
+
constraints: [
|
|
38
|
+
{ type: 'must', description: 'Handle empty array/collection edge case' },
|
|
39
|
+
{ type: 'prefer', description: 'Use Set for O(1) lookups instead of nested array iterations' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
triggers: ['parse', 'json', 'input', 'user input', 'form'],
|
|
44
|
+
constraints: [
|
|
45
|
+
{ type: 'must', description: 'Validate and sanitize all external input before processing' },
|
|
46
|
+
{ type: 'must', description: 'Wrap JSON.parse in try-catch' },
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
triggers: ['file', 'path', 'directory', 'fs'],
|
|
51
|
+
constraints: [
|
|
52
|
+
{ type: 'must', description: 'Check file/directory existence before operations' },
|
|
53
|
+
{ type: 'must', description: 'Handle file operation errors (ENOENT, EACCES, etc.)' },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
triggers: ['regex', 'pattern', 'match'],
|
|
58
|
+
constraints: [
|
|
59
|
+
{ type: 'must-not', description: 'Never use regex with /g flag in repeated calls without resetting lastIndex (JavaScript)' },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
triggers: ['float', 'decimal', 'money', 'price', 'calculation'],
|
|
64
|
+
constraints: [
|
|
65
|
+
{ type: 'must-not', description: 'Never compare floating point numbers with strict equality', pattern: 'if (a === 0.3)' },
|
|
66
|
+
{ type: 'prefer', description: 'Use epsilon comparison for floating point: Math.abs(a - b) < Number.EPSILON' },
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
triggers: ['sort', 'order', 'rank', 'compare'],
|
|
71
|
+
constraints: [
|
|
72
|
+
{ type: 'must', description: 'Provide an explicit comparator for numeric sorts (JavaScript default sort is lexicographic)', pattern: 'array.sort()' },
|
|
73
|
+
{ type: 'must', description: 'Ensure sort comparator is consistent (if a < b then b > a)' },
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
triggers: ['async', 'await', 'promise', 'callback'],
|
|
78
|
+
constraints: [
|
|
79
|
+
{ type: 'must', description: 'Handle promise rejections with try-catch or .catch()' },
|
|
80
|
+
{ type: 'must-not', description: 'Never fire-and-forget promises without error handling' },
|
|
81
|
+
{ type: 'prefer', description: 'Use Promise.allSettled instead of Promise.all when partial failures are acceptable' },
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
triggers: ['cache', 'memo', 'memoize', 'store'],
|
|
86
|
+
constraints: [
|
|
87
|
+
{ type: 'must', description: 'Include cache invalidation or TTL mechanism' },
|
|
88
|
+
{ type: 'must-not', description: 'Never allow unbounded cache growth without eviction policy' },
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
triggers: ['recursive', 'recursion', 'tree', 'graph', 'traverse'],
|
|
93
|
+
constraints: [
|
|
94
|
+
{ type: 'must', description: 'Include a base case that terminates recursion' },
|
|
95
|
+
{ type: 'prefer', description: 'Guard against circular references in graph/tree traversal' },
|
|
96
|
+
{ type: 'prefer', description: 'Consider stack depth limits for deep recursion; use iteration if depth is unbounded' },
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
triggers: ['string', 'text', 'substring', 'split', 'join'],
|
|
101
|
+
constraints: [
|
|
102
|
+
{ type: 'must', description: 'Handle empty string edge case' },
|
|
103
|
+
{ type: 'prefer', description: 'Consider Unicode/multi-byte characters when indexing strings' },
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
triggers: ['date', 'time', 'timestamp', 'schedule', 'cron'],
|
|
108
|
+
constraints: [
|
|
109
|
+
{ type: 'must', description: 'Handle timezone conversions explicitly, do not assume UTC' },
|
|
110
|
+
{ type: 'must-not', description: 'Never construct dates from string concatenation without validation' },
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
triggers: ['divide', 'division', 'ratio', 'percentage', 'average'],
|
|
115
|
+
constraints: [
|
|
116
|
+
{ type: 'must', description: 'Check for division by zero before dividing' },
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
triggers: ['env', 'environment', 'config', 'secret', 'token'],
|
|
121
|
+
constraints: [
|
|
122
|
+
{ type: 'must', description: 'Validate that required environment variables are set before using them' },
|
|
123
|
+
{ type: 'must-not', description: 'Never log or expose secrets/tokens in error messages or console output' },
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
triggers: ['stream', 'pipe', 'buffer', 'socket', 'websocket'],
|
|
128
|
+
constraints: [
|
|
129
|
+
{ type: 'must', description: 'Handle stream error events to prevent unhandled exceptions' },
|
|
130
|
+
{ type: 'must', description: 'Clean up resources (close streams/sockets) in error and completion paths' },
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// LLM-based constraint derivation from specs
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
const CONSTRAINT_SYSTEM_PROMPT = `You are a constraint generator for code generation. Given a set of formal specifications that code must satisfy, produce generation constraints that PREVENT common failures.
|
|
138
|
+
|
|
139
|
+
CONSTRAINT RULES:
|
|
140
|
+
|
|
141
|
+
1. For each specification, produce 1-2 constraints that guide the code generator:
|
|
142
|
+
- correctness spec → "must" constraint with specific implementation guidance
|
|
143
|
+
- security spec → "must-not" constraint with anti-pattern example
|
|
144
|
+
- edge-case spec → "must" constraint for boundary handling
|
|
145
|
+
- error-handling spec → "must" constraint for explicit error paths
|
|
146
|
+
- type-safety spec → "must-not" constraint against unsafe coercions
|
|
147
|
+
- performance spec → "prefer" constraint with recommended approach
|
|
148
|
+
|
|
149
|
+
2. Each constraint must have:
|
|
150
|
+
- type: "must" | "must-not" | "prefer"
|
|
151
|
+
- description: Clear guidance for the code generator (1-2 sentences)
|
|
152
|
+
- pattern: (optional) A short code snippet showing the anti-pattern (for must-not) or expected pattern (for must)
|
|
153
|
+
|
|
154
|
+
3. Be SPECIFIC and ACTIONABLE:
|
|
155
|
+
- GOOD: "Must handle the case where input array is empty by returning an empty array"
|
|
156
|
+
- GOOD: "Must-not use indexOf for existence checks on large arrays; use Set or Map"
|
|
157
|
+
- BAD: "Must be correct" (too vague)
|
|
158
|
+
- BAD: "Must handle errors" (not actionable)
|
|
159
|
+
|
|
160
|
+
4. Do NOT duplicate: If two specs would produce the same constraint, only include it once.
|
|
161
|
+
|
|
162
|
+
OUTPUT FORMAT:
|
|
163
|
+
Return ONLY a JSON array of constraint objects. No markdown fences, no commentary.
|
|
164
|
+
[
|
|
165
|
+
{
|
|
166
|
+
"type": "must",
|
|
167
|
+
"description": "...",
|
|
168
|
+
"pattern": "..."
|
|
169
|
+
}
|
|
170
|
+
]`;
|
|
171
|
+
const VALID_TYPES = ['must', 'must-not', 'prefer'];
|
|
172
|
+
function validateConstraint(raw) {
|
|
173
|
+
if (!raw.description || typeof raw.description !== 'string')
|
|
174
|
+
return null;
|
|
175
|
+
const type = VALID_TYPES.includes(raw.type)
|
|
176
|
+
? raw.type
|
|
177
|
+
: 'must';
|
|
178
|
+
return {
|
|
179
|
+
type,
|
|
180
|
+
description: raw.description.trim(),
|
|
181
|
+
pattern: typeof raw.pattern === 'string' ? raw.pattern.trim() : undefined,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// Domain pattern matching
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
function matchDomainPatterns(task) {
|
|
188
|
+
const taskLower = task.toLowerCase();
|
|
189
|
+
const matched = [];
|
|
190
|
+
const seen = new Set();
|
|
191
|
+
for (const pattern of DOMAIN_PATTERNS) {
|
|
192
|
+
const triggered = pattern.triggers.some((t) => taskLower.includes(t));
|
|
193
|
+
if (!triggered)
|
|
194
|
+
continue;
|
|
195
|
+
for (const c of pattern.constraints) {
|
|
196
|
+
// Deduplicate by description
|
|
197
|
+
if (seen.has(c.description))
|
|
198
|
+
continue;
|
|
199
|
+
seen.add(c.description);
|
|
200
|
+
matched.push({
|
|
201
|
+
type: c.type,
|
|
202
|
+
description: c.description,
|
|
203
|
+
pattern: c.pattern,
|
|
204
|
+
source: 'domain',
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return matched;
|
|
209
|
+
}
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
// JSON parsing helpers (same pattern as claim-extractor / spec-synthesizer)
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
function stripCodeFences(text) {
|
|
214
|
+
let jsonText = text.trim();
|
|
215
|
+
// Remove opening code fence
|
|
216
|
+
if (jsonText.startsWith('```')) {
|
|
217
|
+
const firstNewline = jsonText.indexOf('\n');
|
|
218
|
+
if (firstNewline !== -1) {
|
|
219
|
+
jsonText = jsonText.slice(firstNewline + 1);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Remove closing code fence
|
|
223
|
+
const lastFence = jsonText.lastIndexOf('```');
|
|
224
|
+
if (lastFence !== -1) {
|
|
225
|
+
jsonText = jsonText.slice(0, lastFence);
|
|
226
|
+
}
|
|
227
|
+
return jsonText.trim();
|
|
228
|
+
}
|
|
229
|
+
function repairTruncatedArray(jsonText, onProgress) {
|
|
230
|
+
if (jsonText.endsWith(']'))
|
|
231
|
+
return jsonText;
|
|
232
|
+
const lastCloseBrace = jsonText.lastIndexOf('}');
|
|
233
|
+
if (lastCloseBrace !== -1) {
|
|
234
|
+
onProgress?.('Note: Response was truncated. Recovered partial constraints.');
|
|
235
|
+
return jsonText.slice(0, lastCloseBrace + 1) + '\n]';
|
|
236
|
+
}
|
|
237
|
+
return jsonText;
|
|
238
|
+
}
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
// Spec-derived constraints via LLM
|
|
241
|
+
// ---------------------------------------------------------------------------
|
|
242
|
+
async function deriveSpecConstraints(specs, task, language, onProgress) {
|
|
243
|
+
if (specs.length === 0) {
|
|
244
|
+
return { constraints: [], inputTokens: 0, outputTokens: 0 };
|
|
245
|
+
}
|
|
246
|
+
const client = getClient();
|
|
247
|
+
onProgress?.('Deriving spec constraints via Claude (streaming)...');
|
|
248
|
+
const specsText = specs
|
|
249
|
+
.map((s) => `[${s.id}] (${s.category}, ${s.severity}) ${s.description}\n Assertion: ${s.assertion}`)
|
|
250
|
+
.join('\n\n');
|
|
251
|
+
const stream = client.messages.stream({
|
|
252
|
+
model: MODEL,
|
|
253
|
+
max_tokens: 8_000,
|
|
254
|
+
system: CONSTRAINT_SYSTEM_PROMPT,
|
|
255
|
+
messages: [
|
|
256
|
+
{
|
|
257
|
+
role: 'user',
|
|
258
|
+
content: `Generate constraints for the following coding task and specifications.\n\nLanguage: ${language}\nTask: ${task}\n\nSpecifications:\n${specsText}`,
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
});
|
|
262
|
+
let rawText = '';
|
|
263
|
+
stream.on('text', (text) => {
|
|
264
|
+
rawText += text;
|
|
265
|
+
});
|
|
266
|
+
const finalMessage = await stream.finalMessage();
|
|
267
|
+
onProgress?.('Parsing constraint results...');
|
|
268
|
+
let jsonText = stripCodeFences(rawText);
|
|
269
|
+
jsonText = repairTruncatedArray(jsonText, onProgress);
|
|
270
|
+
let parsed;
|
|
271
|
+
try {
|
|
272
|
+
parsed = JSON.parse(jsonText);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
throw new Error(`Failed to parse Claude's constraint response as JSON.\n` +
|
|
276
|
+
`First 200 chars: ${jsonText.slice(0, 200)}`);
|
|
277
|
+
}
|
|
278
|
+
if (!Array.isArray(parsed)) {
|
|
279
|
+
throw new Error('Expected a JSON array of constraints from Claude.');
|
|
280
|
+
}
|
|
281
|
+
const constraints = [];
|
|
282
|
+
for (const raw of parsed) {
|
|
283
|
+
const validated = validateConstraint(raw);
|
|
284
|
+
if (validated) {
|
|
285
|
+
constraints.push({
|
|
286
|
+
...validated,
|
|
287
|
+
source: 'spec',
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
constraints,
|
|
293
|
+
inputTokens: finalMessage.usage.input_tokens,
|
|
294
|
+
outputTokens: finalMessage.usage.output_tokens,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
// ---------------------------------------------------------------------------
|
|
298
|
+
// Main export
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
300
|
+
export async function generateConstraints(task, language, specs, onProgress) {
|
|
301
|
+
// 1. Match domain patterns
|
|
302
|
+
onProgress?.('Matching domain patterns...');
|
|
303
|
+
const domainConstraints = matchDomainPatterns(task);
|
|
304
|
+
onProgress?.(`Matched ${domainConstraints.length} domain constraint(s).`);
|
|
305
|
+
// 2. Derive spec constraints via LLM
|
|
306
|
+
const { constraints: specConstraints, inputTokens, outputTokens } = await deriveSpecConstraints(specs, task, language, onProgress);
|
|
307
|
+
onProgress?.(`Derived ${specConstraints.length} spec constraint(s).`);
|
|
308
|
+
// 3. Merge and deduplicate (domain first, then spec-derived)
|
|
309
|
+
const allConstraints = [...domainConstraints, ...specConstraints];
|
|
310
|
+
const seen = new Set();
|
|
311
|
+
const deduped = [];
|
|
312
|
+
for (const c of allConstraints) {
|
|
313
|
+
const key = c.description.toLowerCase();
|
|
314
|
+
if (seen.has(key))
|
|
315
|
+
continue;
|
|
316
|
+
seen.add(key);
|
|
317
|
+
deduped.push(c);
|
|
318
|
+
}
|
|
319
|
+
// 4. Number all constraints CON-001, CON-002, etc.
|
|
320
|
+
const numbered = deduped.map((c, i) => ({
|
|
321
|
+
id: `CON-${String(i + 1).padStart(3, '0')}`,
|
|
322
|
+
type: c.type,
|
|
323
|
+
description: c.description,
|
|
324
|
+
pattern: c.pattern,
|
|
325
|
+
source: c.source,
|
|
326
|
+
}));
|
|
327
|
+
onProgress?.(`Total: ${numbered.length} constraint(s) after deduplication.`);
|
|
328
|
+
return {
|
|
329
|
+
task,
|
|
330
|
+
constraints: numbered,
|
|
331
|
+
totalConstraints: numbered.length,
|
|
332
|
+
generatedAt: new Date().toISOString(),
|
|
333
|
+
inputTokens,
|
|
334
|
+
outputTokens,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=constraint-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraint-engine.js","sourceRoot":"","sources":["../../src/lib/constraint-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function exists(path: string): Promise<boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-utils.js","sourceRoot":"","sources":["../../src/lib/fs-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { CodeSpec, GenerationConstraint, GeneratedCode } from '../types.js';
|
|
2
|
+
export declare function generateWithConstraints(task: string, language: string, specs: CodeSpec[], constraints: GenerationConstraint[], onProgress?: (msg: string) => void): Promise<GeneratedCode>;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { getClient, MODEL } from './anthropic.js';
|
|
2
|
+
const MAX_TOKENS = 16_000;
|
|
3
|
+
function buildGenerationSystemPrompt(language, specs, constraints) {
|
|
4
|
+
const specLines = specs.map((s) => {
|
|
5
|
+
return `[${s.id}] (${s.severity}/${s.category}): ${s.description}\n Assertion: ${s.assertion}`;
|
|
6
|
+
});
|
|
7
|
+
const musts = constraints.filter((c) => c.type === 'must');
|
|
8
|
+
const mustNots = constraints.filter((c) => c.type === 'must-not');
|
|
9
|
+
const prefers = constraints.filter((c) => c.type === 'prefer');
|
|
10
|
+
let constraintBlock = '';
|
|
11
|
+
if (musts.length > 0) {
|
|
12
|
+
constraintBlock += 'MUST DO:\n';
|
|
13
|
+
constraintBlock += musts
|
|
14
|
+
.map((c) => `- ${c.id}: ${c.description}${c.pattern ? `\n Example: ${c.pattern}` : ''}`)
|
|
15
|
+
.join('\n');
|
|
16
|
+
constraintBlock += '\n\n';
|
|
17
|
+
}
|
|
18
|
+
if (mustNots.length > 0) {
|
|
19
|
+
constraintBlock += 'MUST NOT DO:\n';
|
|
20
|
+
constraintBlock += mustNots
|
|
21
|
+
.map((c) => `- ${c.id}: ${c.description}${c.pattern ? `\n Bad example: ${c.pattern}` : ''}`)
|
|
22
|
+
.join('\n');
|
|
23
|
+
constraintBlock += '\n\n';
|
|
24
|
+
}
|
|
25
|
+
if (prefers.length > 0) {
|
|
26
|
+
constraintBlock += 'PREFER:\n';
|
|
27
|
+
constraintBlock += prefers
|
|
28
|
+
.map((c) => `- ${c.id}: ${c.description}${c.pattern ? `\n Example: ${c.pattern}` : ''}`)
|
|
29
|
+
.join('\n');
|
|
30
|
+
constraintBlock += '\n';
|
|
31
|
+
}
|
|
32
|
+
return `You are an expert programmer. Generate production-quality ${language} code.
|
|
33
|
+
|
|
34
|
+
SPECIFICATIONS — Your code MUST satisfy ALL of these:
|
|
35
|
+
${specLines.join('\n')}
|
|
36
|
+
|
|
37
|
+
CONSTRAINTS:
|
|
38
|
+
${constraintBlock}
|
|
39
|
+
OUTPUT RULES:
|
|
40
|
+
- Return ONLY the code
|
|
41
|
+
- No markdown code fences
|
|
42
|
+
- No explanations before or after the code
|
|
43
|
+
- Include all necessary imports
|
|
44
|
+
- Include type annotations
|
|
45
|
+
- The code should be complete and runnable`;
|
|
46
|
+
}
|
|
47
|
+
const VERIFICATION_SYSTEM_PROMPT = `You are a code reviewer verifying generated code against specifications. For each specification, determine whether the code satisfies it.
|
|
48
|
+
|
|
49
|
+
OUTPUT FORMAT:
|
|
50
|
+
Return ONLY a JSON array. No markdown fences, no commentary. Each element:
|
|
51
|
+
{
|
|
52
|
+
"specId": "SPEC-001",
|
|
53
|
+
"status": "satisfied" | "partial" | "unsatisfied" | "unknown",
|
|
54
|
+
"reasoning": "Brief explanation of why the code does or does not satisfy this spec"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
STATUS MEANINGS:
|
|
58
|
+
- satisfied: The code clearly and correctly implements this specification
|
|
59
|
+
- partial: The code addresses this specification but incompletely or with caveats
|
|
60
|
+
- unsatisfied: The code does not implement this specification or violates it
|
|
61
|
+
- unknown: Cannot determine from static analysis alone (e.g., runtime/performance specs)`;
|
|
62
|
+
function stripCodeFences(text) {
|
|
63
|
+
let result = text.trim();
|
|
64
|
+
// Remove opening code fence (```language or just ```)
|
|
65
|
+
if (result.startsWith('```')) {
|
|
66
|
+
const firstNewline = result.indexOf('\n');
|
|
67
|
+
if (firstNewline !== -1) {
|
|
68
|
+
result = result.slice(firstNewline + 1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Remove closing code fence
|
|
72
|
+
const lastFence = result.lastIndexOf('```');
|
|
73
|
+
if (lastFence !== -1) {
|
|
74
|
+
result = result.slice(0, lastFence);
|
|
75
|
+
}
|
|
76
|
+
return result.trim();
|
|
77
|
+
}
|
|
78
|
+
const VALID_STATUSES = [
|
|
79
|
+
'satisfied', 'partial', 'unsatisfied', 'unknown',
|
|
80
|
+
];
|
|
81
|
+
function validateVerification(raw, specs) {
|
|
82
|
+
if (!raw.specId || typeof raw.specId !== 'string')
|
|
83
|
+
return null;
|
|
84
|
+
if (!raw.reasoning || typeof raw.reasoning !== 'string')
|
|
85
|
+
return null;
|
|
86
|
+
// Verify the specId references a real spec
|
|
87
|
+
const matchesSpec = specs.some((s) => s.id === raw.specId);
|
|
88
|
+
if (!matchesSpec)
|
|
89
|
+
return null;
|
|
90
|
+
const status = VALID_STATUSES.includes(raw.status)
|
|
91
|
+
? raw.status
|
|
92
|
+
: 'unknown';
|
|
93
|
+
return {
|
|
94
|
+
specId: raw.specId,
|
|
95
|
+
status,
|
|
96
|
+
reasoning: raw.reasoning.trim(),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function parseVerificationJson(rawText, specs, onProgress) {
|
|
100
|
+
let jsonText = stripCodeFences(rawText);
|
|
101
|
+
// If response was truncated (no closing ]), try to repair
|
|
102
|
+
if (!jsonText.endsWith(']')) {
|
|
103
|
+
const lastCloseBrace = jsonText.lastIndexOf('}');
|
|
104
|
+
if (lastCloseBrace !== -1) {
|
|
105
|
+
jsonText = jsonText.slice(0, lastCloseBrace + 1) + '\n]';
|
|
106
|
+
onProgress?.('Note: Verification response was truncated. Recovered partial results.');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
let parsed;
|
|
110
|
+
try {
|
|
111
|
+
parsed = JSON.parse(jsonText);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
onProgress?.('Warning: Failed to parse self-verification JSON. Returning empty results.');
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
if (!Array.isArray(parsed)) {
|
|
118
|
+
onProgress?.('Warning: Self-verification response was not an array. Returning empty results.');
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
const results = [];
|
|
122
|
+
for (const item of parsed) {
|
|
123
|
+
const validated = validateVerification(item, specs);
|
|
124
|
+
if (validated) {
|
|
125
|
+
results.push(validated);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return results;
|
|
129
|
+
}
|
|
130
|
+
export async function generateWithConstraints(task, language, specs, constraints, onProgress) {
|
|
131
|
+
const client = getClient();
|
|
132
|
+
let totalInputTokens = 0;
|
|
133
|
+
let totalOutputTokens = 0;
|
|
134
|
+
// ── Step 1: Guided code generation (streaming) ──
|
|
135
|
+
onProgress?.('Generating code with spec-aware constraints (streaming)...');
|
|
136
|
+
const systemPrompt = buildGenerationSystemPrompt(language, specs, constraints);
|
|
137
|
+
const stream = client.messages.stream({
|
|
138
|
+
model: MODEL,
|
|
139
|
+
max_tokens: MAX_TOKENS,
|
|
140
|
+
system: systemPrompt,
|
|
141
|
+
messages: [
|
|
142
|
+
{
|
|
143
|
+
role: 'user',
|
|
144
|
+
content: `Generate ${language} code for the following task:\n\n${task}`,
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
});
|
|
148
|
+
let rawCode = '';
|
|
149
|
+
stream.on('text', (text) => {
|
|
150
|
+
rawCode += text;
|
|
151
|
+
});
|
|
152
|
+
const genMessage = await stream.finalMessage();
|
|
153
|
+
totalInputTokens += genMessage.usage.input_tokens;
|
|
154
|
+
totalOutputTokens += genMessage.usage.output_tokens;
|
|
155
|
+
const code = stripCodeFences(rawCode);
|
|
156
|
+
onProgress?.(`Code generated (${totalOutputTokens} tokens). Running self-verification...`);
|
|
157
|
+
// ── Step 2: Self-verification (non-streaming) ──
|
|
158
|
+
const specList = specs
|
|
159
|
+
.map((s) => `[${s.id}] (${s.severity}/${s.category}): ${s.description}\n Assertion: ${s.assertion}`)
|
|
160
|
+
.join('\n');
|
|
161
|
+
const verifyResponse = await client.messages.create({
|
|
162
|
+
model: MODEL,
|
|
163
|
+
max_tokens: 8_000,
|
|
164
|
+
system: VERIFICATION_SYSTEM_PROMPT,
|
|
165
|
+
messages: [
|
|
166
|
+
{
|
|
167
|
+
role: 'user',
|
|
168
|
+
content: `Verify the following code against the specifications below.\n\nCODE:\n${code}\n\nSPECIFICATIONS:\n${specList}`,
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
});
|
|
172
|
+
totalInputTokens += verifyResponse.usage.input_tokens;
|
|
173
|
+
totalOutputTokens += verifyResponse.usage.output_tokens;
|
|
174
|
+
const verifyText = verifyResponse.content
|
|
175
|
+
.filter((block) => block.type === 'text')
|
|
176
|
+
.map((block) => block.text)
|
|
177
|
+
.join('');
|
|
178
|
+
const selfVerification = parseVerificationJson(verifyText, specs, onProgress);
|
|
179
|
+
const satisfiedCount = selfVerification.filter((v) => v.status === 'satisfied').length;
|
|
180
|
+
onProgress?.(`Self-verification complete: ${satisfiedCount}/${specs.length} specs satisfied.`);
|
|
181
|
+
return {
|
|
182
|
+
task,
|
|
183
|
+
code,
|
|
184
|
+
language,
|
|
185
|
+
specs,
|
|
186
|
+
constraints,
|
|
187
|
+
selfVerification,
|
|
188
|
+
satisfiedCount,
|
|
189
|
+
totalSpecs: specs.length,
|
|
190
|
+
generatedAt: new Date().toISOString(),
|
|
191
|
+
inputTokens: totalInputTokens,
|
|
192
|
+
outputTokens: totalOutputTokens,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=guided-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guided-generator.js","sourceRoot":"","sources":["../../src/lib/guided-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CodebaseIndex } from './codebase-indexer.js';
|
|
2
|
+
import type { AssessmentInventory } from '../types.js';
|
|
3
|
+
export declare function extractInventory(index: CodebaseIndex, onProgress?: (msg: string) => void): Promise<{
|
|
4
|
+
inventory: AssessmentInventory;
|
|
5
|
+
inputTokens: number;
|
|
6
|
+
outputTokens: number;
|
|
7
|
+
}>;
|