sdd-mcp-server 5.4.0 → 5.5.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/CHANGELOG.md +29 -0
- package/README.md +9 -6
- package/agents/security-auditor.md +2 -2
- package/dist/__tests__/unit/jev/helpers.d.ts +84 -0
- package/dist/__tests__/unit/jev/helpers.js +188 -0
- package/dist/__tests__/unit/jev/helpers.js.map +1 -0
- package/dist/adapters/cli/SDDToolAdapter.d.ts +5 -1
- package/dist/adapters/cli/SDDToolAdapter.js +21 -2
- package/dist/adapters/cli/SDDToolAdapter.js.map +1 -1
- package/dist/application/services/JevAdvisoryService.d.ts +53 -0
- package/dist/application/services/JevAdvisoryService.js +310 -0
- package/dist/application/services/JevAdvisoryService.js.map +1 -0
- package/dist/application/services/JevBaseRef.d.ts +21 -0
- package/dist/application/services/JevBaseRef.js +46 -0
- package/dist/application/services/JevBaseRef.js.map +1 -0
- package/dist/application/services/JevChangeManifest.d.ts +33 -0
- package/dist/application/services/JevChangeManifest.js +208 -0
- package/dist/application/services/JevChangeManifest.js.map +1 -0
- package/dist/application/services/JevCheckTypes.d.ts +74 -0
- package/dist/application/services/JevCheckTypes.js +2 -0
- package/dist/application/services/JevCheckTypes.js.map +1 -0
- package/dist/application/services/JevCodeExcerpts.d.ts +23 -0
- package/dist/application/services/JevCodeExcerpts.js +102 -0
- package/dist/application/services/JevCodeExcerpts.js.map +1 -0
- package/dist/application/services/JevCommitLookup.d.ts +17 -0
- package/dist/application/services/JevCommitLookup.js +72 -0
- package/dist/application/services/JevCommitLookup.js.map +1 -0
- package/dist/application/services/JevExchange.d.ts +48 -0
- package/dist/application/services/JevExchange.js +119 -0
- package/dist/application/services/JevExchange.js.map +1 -0
- package/dist/application/services/JevQuestionCatalog.d.ts +28 -0
- package/dist/application/services/JevQuestionCatalog.js +194 -0
- package/dist/application/services/JevQuestionCatalog.js.map +1 -0
- package/dist/application/services/JevRedaction.d.ts +12 -0
- package/dist/application/services/JevRedaction.js +56 -0
- package/dist/application/services/JevRedaction.js.map +1 -0
- package/dist/application/services/JevReport.d.ts +41 -0
- package/dist/application/services/JevReport.js +101 -0
- package/dist/application/services/JevReport.js.map +1 -0
- package/dist/application/services/JevResponseValidator.d.ts +34 -0
- package/dist/application/services/JevResponseValidator.js +98 -0
- package/dist/application/services/JevResponseValidator.js.map +1 -0
- package/dist/application/services/JevResults.d.ts +3 -0
- package/dist/application/services/JevResults.js +7 -0
- package/dist/application/services/JevResults.js.map +1 -0
- package/dist/application/services/JevReviewCheck.d.ts +20 -0
- package/dist/application/services/JevReviewCheck.js +120 -0
- package/dist/application/services/JevReviewCheck.js.map +1 -0
- package/dist/application/services/JevSettings.d.ts +18 -0
- package/dist/application/services/JevSettings.js +72 -0
- package/dist/application/services/JevSettings.js.map +1 -0
- package/dist/application/services/JevSidecarStore.d.ts +68 -0
- package/dist/application/services/JevSidecarStore.js +201 -0
- package/dist/application/services/JevSidecarStore.js.map +1 -0
- package/dist/application/services/JevSpecState.d.ts +38 -0
- package/dist/application/services/JevSpecState.js +109 -0
- package/dist/application/services/JevSpecState.js.map +1 -0
- package/dist/application/services/JevTestcaseState.d.ts +22 -0
- package/dist/application/services/JevTestcaseState.js +85 -0
- package/dist/application/services/JevTestcaseState.js.map +1 -0
- package/dist/application/services/RedEvidenceClassifier.d.ts +10 -0
- package/dist/application/services/RedEvidenceClassifier.js +32 -0
- package/dist/application/services/RedEvidenceClassifier.js.map +1 -0
- package/dist/application/services/WorkflowEngineService.d.ts +28 -0
- package/dist/application/services/WorkflowEngineService.js +50 -2
- package/dist/application/services/WorkflowEngineService.js.map +1 -1
- package/dist/application/services/WorkflowValidationService.d.ts +16 -0
- package/dist/application/services/WorkflowValidationService.js +10 -5
- package/dist/application/services/WorkflowValidationService.js.map +1 -1
- package/dist/cli/install-target.d.ts +6 -6
- package/dist/cli/install-target.js +9 -3
- package/dist/cli/install-target.js.map +1 -1
- package/dist/domain/ports.d.ts +34 -0
- package/dist/domain/ports.js +11 -1
- package/dist/domain/ports.js.map +1 -1
- package/dist/infrastructure/adapters/FetchJevHttpAdapter.d.ts +4 -0
- package/dist/infrastructure/adapters/FetchJevHttpAdapter.js +73 -0
- package/dist/infrastructure/adapters/FetchJevHttpAdapter.js.map +1 -0
- package/dist/infrastructure/adapters/NodeGitAdapter.d.ts +5 -0
- package/dist/infrastructure/adapters/NodeGitAdapter.js +31 -0
- package/dist/infrastructure/adapters/NodeGitAdapter.js.map +1 -0
- package/dist/infrastructure/di/container.js +10 -0
- package/dist/infrastructure/di/container.js.map +1 -1
- package/dist/infrastructure/di/types.d.ts +4 -0
- package/dist/infrastructure/di/types.js +4 -0
- package/dist/infrastructure/di/types.js.map +1 -1
- package/dist/infrastructure/mcp/sddToolDefinitions.d.ts +1 -1
- package/dist/infrastructure/mcp/sddToolDefinitions.js +72 -1
- package/dist/infrastructure/mcp/sddToolDefinitions.js.map +1 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/version.js +1 -1
- package/package.json +1 -1
- package/skills/sdd-commit/SKILL.md +4 -3
- package/skills/sdd-design/SKILL.md +1 -1
- package/skills/sdd-implement/SKILL.md +4 -4
- package/skills/sdd-requirements/SKILL.md +6 -6
- package/skills/sdd-review/SKILL.md +3 -2
- package/skills/sdd-security-check/SKILL.md +3 -2
- package/skills/sdd-tasks/REFERENCE.md +4 -0
- package/skills/sdd-tasks/SKILL.md +8 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JevChangeManifest.js","sourceRoot":"","sources":["../../../src/application/services/JevChangeManifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export declare const JEV_CHECK_KINDS: readonly ["requirements", "design", "testcases", "red", "security", "principles", "commit"];
|
|
2
|
+
export type JevCheckKind = (typeof JEV_CHECK_KINDS)[number];
|
|
3
|
+
export type JevSkipReason = 'not-ready' | 'cases-required' | 'feature-not-found' | 'no-changes' | 'disabled' | 'invalid-base-ref';
|
|
4
|
+
export interface JevCase {
|
|
5
|
+
taskId: string;
|
|
6
|
+
kind: 'behavior' | 'boundary' | 'error' | 'transition' | 'security';
|
|
7
|
+
given: string;
|
|
8
|
+
when: string;
|
|
9
|
+
then: string;
|
|
10
|
+
covers: string;
|
|
11
|
+
}
|
|
12
|
+
export interface JevFindingInput {
|
|
13
|
+
id: string;
|
|
14
|
+
path: string;
|
|
15
|
+
line: number;
|
|
16
|
+
title: string;
|
|
17
|
+
severity: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
preconditions?: string;
|
|
20
|
+
remediation?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface JevUnitInput {
|
|
23
|
+
id: string;
|
|
24
|
+
path: string;
|
|
25
|
+
line: number;
|
|
26
|
+
summary: string;
|
|
27
|
+
}
|
|
28
|
+
export interface JevEvidenceInput {
|
|
29
|
+
command: string;
|
|
30
|
+
exitCode: number;
|
|
31
|
+
summary: string;
|
|
32
|
+
}
|
|
33
|
+
export interface JevCheckRequest {
|
|
34
|
+
check: JevCheckKind;
|
|
35
|
+
projectRoot: string;
|
|
36
|
+
featureName?: string;
|
|
37
|
+
cases?: readonly JevCase[];
|
|
38
|
+
taskNumber?: string;
|
|
39
|
+
testName?: string;
|
|
40
|
+
evidence?: JevEvidenceInput;
|
|
41
|
+
findings?: readonly JevFindingInput[];
|
|
42
|
+
units?: readonly JevUnitInput[];
|
|
43
|
+
/** `security` and `principles` only: review merge-base(baseRef, HEAD) against the working tree. */
|
|
44
|
+
baseRef?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface JevItemDetail {
|
|
47
|
+
id: string;
|
|
48
|
+
flagged: boolean;
|
|
49
|
+
location?: string;
|
|
50
|
+
principle?: string;
|
|
51
|
+
note?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface JevCheckResult {
|
|
54
|
+
check: JevCheckKind;
|
|
55
|
+
status: 'answered' | 'unavailable' | 'skipped';
|
|
56
|
+
/** Present for `unavailable`: disabled, no-key, network, timeout, http-<n>, invalid-response, code-disabled. */
|
|
57
|
+
reason?: string;
|
|
58
|
+
/** Present for `skipped`. */
|
|
59
|
+
skipReason?: JevSkipReason;
|
|
60
|
+
/** The one report line to show, or null when there is nothing to show. */
|
|
61
|
+
line: string | null;
|
|
62
|
+
flagged: string[];
|
|
63
|
+
details: JevItemDetail[];
|
|
64
|
+
persisted: boolean;
|
|
65
|
+
/** Project-relative path of the sidecar, when one was written. */
|
|
66
|
+
sidecar?: string;
|
|
67
|
+
truncated: boolean;
|
|
68
|
+
redactions: number;
|
|
69
|
+
classification?: 'setup' | 'assertion' | 'ambiguous';
|
|
70
|
+
matchedPattern?: string;
|
|
71
|
+
droppedFindingIds?: string[];
|
|
72
|
+
unknownTasks?: string[];
|
|
73
|
+
truncatedTasks?: string[];
|
|
74
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JevCheckTypes.js","sourceRoot":"","sources":["../../../src/application/services/JevCheckTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,CAAU,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const MAX_EXCERPT_BYTES = 8192;
|
|
2
|
+
export declare const EXCERPT_CONTEXT_LINES = 15;
|
|
3
|
+
export interface ExcerptRequest {
|
|
4
|
+
id: string;
|
|
5
|
+
path: string;
|
|
6
|
+
line: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ExcerptResult {
|
|
9
|
+
id: string;
|
|
10
|
+
path: string;
|
|
11
|
+
line: number;
|
|
12
|
+
excerpt: string | null;
|
|
13
|
+
excerptSha256: string | null;
|
|
14
|
+
redactions: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ExcerptBatch {
|
|
17
|
+
items: ExcerptResult[];
|
|
18
|
+
droppedFindingIds: string[];
|
|
19
|
+
redactions: number;
|
|
20
|
+
}
|
|
21
|
+
/** Secrets, keys, lockfiles, and generated output never leave the machine, even redacted. */
|
|
22
|
+
export declare function isExcludedPath(relativePath: string): boolean;
|
|
23
|
+
export declare function buildExcerpts(projectRoot: string, requests: readonly ExcerptRequest[]): Promise<ExcerptBatch>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFile, realpath, stat } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { redactSecrets } from './JevRedaction.js';
|
|
5
|
+
export const MAX_EXCERPT_BYTES = 8192;
|
|
6
|
+
export const EXCERPT_CONTEXT_LINES = 15;
|
|
7
|
+
const MAX_SOURCE_BYTES = 1_048_576;
|
|
8
|
+
const EXCLUDED_BASENAME_PREFIXES = ['.env', 'id_rsa', 'id_ed25519'];
|
|
9
|
+
const EXCLUDED_BASENAME_SUFFIXES = ['.pem', '.key', '.p12', '.pfx', '.crt', '.min.js'];
|
|
10
|
+
const EXCLUDED_BASENAMES = new Set([
|
|
11
|
+
'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb', 'cargo.lock', 'poetry.lock', 'gemfile.lock', 'go.sum',
|
|
12
|
+
]);
|
|
13
|
+
const EXCLUDED_SEGMENTS = new Set(['dist', 'build', 'node_modules', '.claude', '.agents', '.codex', '.omp']);
|
|
14
|
+
const normalize = (value) => value.replace(/\\/g, '/');
|
|
15
|
+
/** Secrets, keys, lockfiles, and generated output never leave the machine, even redacted. */
|
|
16
|
+
export function isExcludedPath(relativePath) {
|
|
17
|
+
const segments = normalize(relativePath).toLowerCase().split('/').filter(Boolean);
|
|
18
|
+
const base = segments[segments.length - 1] ?? '';
|
|
19
|
+
return EXCLUDED_BASENAMES.has(base)
|
|
20
|
+
|| EXCLUDED_BASENAME_PREFIXES.some((prefix) => base.startsWith(prefix))
|
|
21
|
+
|| EXCLUDED_BASENAME_SUFFIXES.some((suffix) => base.endsWith(suffix))
|
|
22
|
+
|| segments.slice(0, -1).some((segment) => EXCLUDED_SEGMENTS.has(segment));
|
|
23
|
+
}
|
|
24
|
+
function isSafeRelative(relativePath) {
|
|
25
|
+
const normalized = normalize(relativePath);
|
|
26
|
+
return normalized.length > 0
|
|
27
|
+
&& !normalized.includes('\0')
|
|
28
|
+
&& !normalized.startsWith('/')
|
|
29
|
+
&& !/^[A-Za-z]:/.test(normalized)
|
|
30
|
+
&& !normalized.split('/').includes('..');
|
|
31
|
+
}
|
|
32
|
+
const isInside = (root, candidate) => {
|
|
33
|
+
const relative = path.relative(root, candidate);
|
|
34
|
+
return relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative);
|
|
35
|
+
};
|
|
36
|
+
/** Reads the window of lines around `line`, or null for any unsafe, unreadable, or binary file. */
|
|
37
|
+
async function readWindow(root, request) {
|
|
38
|
+
if (!isSafeRelative(request.path) || isExcludedPath(request.path))
|
|
39
|
+
return null;
|
|
40
|
+
try {
|
|
41
|
+
const canonicalRoot = await realpath(root);
|
|
42
|
+
const canonicalFile = await realpath(path.join(root, normalize(request.path)));
|
|
43
|
+
if (!isInside(canonicalRoot, canonicalFile))
|
|
44
|
+
return null;
|
|
45
|
+
if (isExcludedPath(path.relative(canonicalRoot, canonicalFile)))
|
|
46
|
+
return null;
|
|
47
|
+
const info = await stat(canonicalFile);
|
|
48
|
+
if (!info.isFile() || info.size > MAX_SOURCE_BYTES)
|
|
49
|
+
return null;
|
|
50
|
+
const content = await readFile(canonicalFile, 'utf8');
|
|
51
|
+
if (content.includes('\0'))
|
|
52
|
+
return null;
|
|
53
|
+
const lines = content.replace(/\r\n?/g, '\n').split('\n');
|
|
54
|
+
if (request.line < 1 || request.line > lines.length)
|
|
55
|
+
return null;
|
|
56
|
+
const start = Math.max(1, request.line - EXCERPT_CONTEXT_LINES);
|
|
57
|
+
const end = Math.min(lines.length, request.line + EXCERPT_CONTEXT_LINES);
|
|
58
|
+
return lines.slice(start - 1, end).join('\n');
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const empty = (request) => ({ ...request, excerpt: null, excerptSha256: null, redactions: 0 });
|
|
65
|
+
export async function buildExcerpts(projectRoot, requests) {
|
|
66
|
+
const root = path.resolve(projectRoot);
|
|
67
|
+
const items = [];
|
|
68
|
+
const droppedFindingIds = [];
|
|
69
|
+
let usedBytes = 0;
|
|
70
|
+
let overflowed = false;
|
|
71
|
+
let redactions = 0;
|
|
72
|
+
for (const request of requests) {
|
|
73
|
+
if (overflowed) {
|
|
74
|
+
items.push(empty(request));
|
|
75
|
+
droppedFindingIds.push(request.id);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const window = await readWindow(root, request);
|
|
79
|
+
if (window === null) {
|
|
80
|
+
items.push(empty(request));
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const redacted = redactSecrets(window);
|
|
84
|
+
const bytes = Buffer.byteLength(redacted.text, 'utf8');
|
|
85
|
+
if (usedBytes + bytes > MAX_EXCERPT_BYTES) {
|
|
86
|
+
overflowed = true;
|
|
87
|
+
items.push(empty(request));
|
|
88
|
+
droppedFindingIds.push(request.id);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
usedBytes += bytes;
|
|
92
|
+
redactions += redacted.count;
|
|
93
|
+
items.push({
|
|
94
|
+
...request,
|
|
95
|
+
excerpt: redacted.text,
|
|
96
|
+
excerptSha256: createHash('sha256').update(redacted.text).digest('hex'),
|
|
97
|
+
redactions: redacted.count,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return { items, droppedFindingIds, redactions };
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=JevCodeExcerpts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JevCodeExcerpts.js","sourceRoot":"","sources":["../../../src/application/services/JevCodeExcerpts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FileSystemPort, GitPort } from '../../domain/ports.js';
|
|
2
|
+
import type { JevCheckResult } from './JevCheckTypes.js';
|
|
3
|
+
import type { JevSidecarStore } from './JevSidecarStore.js';
|
|
4
|
+
/**
|
|
5
|
+
* Read-only: shows one warning when a saved working-tree code review of exactly the staged change
|
|
6
|
+
* holds a confirmed high or critical finding. Committed-range reviews and sidecars from another
|
|
7
|
+
* question-set version never match. It never contacts JEV, needs no key, and writes nothing.
|
|
8
|
+
*/
|
|
9
|
+
export declare class JevCommitLookup {
|
|
10
|
+
private readonly fileSystem;
|
|
11
|
+
private readonly git;
|
|
12
|
+
private readonly store;
|
|
13
|
+
constructor(fileSystem: FileSystemPort, git: GitPort, store: JevSidecarStore);
|
|
14
|
+
run(projectRoot: string): Promise<JevCheckResult>;
|
|
15
|
+
/** `undefined` stands for the feature-less `.spec/reviews` location. */
|
|
16
|
+
private locationsWithSidecars;
|
|
17
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { buildStagedManifest } from './JevChangeManifest.js';
|
|
3
|
+
import { QUESTION_SET_VERSION } from './JevQuestionCatalog.js';
|
|
4
|
+
import { renderCommitWarning } from './JevReport.js';
|
|
5
|
+
import { skippedResult } from './JevResults.js';
|
|
6
|
+
import { validateFeatureName } from './SpecPathResolver.js';
|
|
7
|
+
const MAX_FEATURES_SCANNED = 200;
|
|
8
|
+
const SERIOUS = new Set(['high', 'critical']);
|
|
9
|
+
/**
|
|
10
|
+
* Read-only: shows one warning when a saved working-tree code review of exactly the staged change
|
|
11
|
+
* holds a confirmed high or critical finding. Committed-range reviews and sidecars from another
|
|
12
|
+
* question-set version never match. It never contacts JEV, needs no key, and writes nothing.
|
|
13
|
+
*/
|
|
14
|
+
export class JevCommitLookup {
|
|
15
|
+
fileSystem;
|
|
16
|
+
git;
|
|
17
|
+
store;
|
|
18
|
+
constructor(fileSystem, git, store) {
|
|
19
|
+
this.fileSystem = fileSystem;
|
|
20
|
+
this.git = git;
|
|
21
|
+
this.store = store;
|
|
22
|
+
}
|
|
23
|
+
async run(projectRoot) {
|
|
24
|
+
// Cheap local scan first: with no review sidecar there is nothing to match, so skip git entirely.
|
|
25
|
+
const locations = await this.locationsWithSidecars(projectRoot);
|
|
26
|
+
if (locations.length === 0)
|
|
27
|
+
return skippedResult('commit', 'not-ready');
|
|
28
|
+
const staged = await buildStagedManifest(this.git, projectRoot);
|
|
29
|
+
if (staged.status !== 'ok')
|
|
30
|
+
return skippedResult('commit', 'not-ready');
|
|
31
|
+
const flagged = [];
|
|
32
|
+
for (const featureName of locations) {
|
|
33
|
+
const sidecar = await this.store.findByDiff(projectRoot, featureName, 'security', staged.diffSha256, QUESTION_SET_VERSION);
|
|
34
|
+
for (const item of sidecar?.items ?? []) {
|
|
35
|
+
if (item.classification === 'confirmed' && SERIOUS.has(item.jevSeverity ?? ''))
|
|
36
|
+
flagged.push(item.id);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (flagged.length === 0)
|
|
40
|
+
return skippedResult('commit', 'not-ready');
|
|
41
|
+
return {
|
|
42
|
+
check: 'commit', status: 'answered', line: renderCommitWarning(flagged.length), flagged,
|
|
43
|
+
details: flagged.map((id) => ({ id, flagged: true })), persisted: false, truncated: false, redactions: 0,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** `undefined` stands for the feature-less `.spec/reviews` location. */
|
|
47
|
+
async locationsWithSidecars(projectRoot) {
|
|
48
|
+
const found = [];
|
|
49
|
+
try {
|
|
50
|
+
if ((await this.store.listReviewSidecars(projectRoot, undefined, 'security')).length > 0)
|
|
51
|
+
found.push(undefined);
|
|
52
|
+
const specsRoot = path.join(path.resolve(projectRoot), '.spec', 'specs');
|
|
53
|
+
if (!(await this.fileSystem.exists(specsRoot)))
|
|
54
|
+
return found;
|
|
55
|
+
for (const name of (await this.fileSystem.readdir(specsRoot)).sort().slice(0, MAX_FEATURES_SCANNED)) {
|
|
56
|
+
try {
|
|
57
|
+
validateFeatureName(name);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if ((await this.store.listReviewSidecars(projectRoot, name, 'security')).length > 0)
|
|
63
|
+
found.push(name);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// A scan problem means no warning, never an error at commit time.
|
|
68
|
+
}
|
|
69
|
+
return found;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=JevCommitLookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JevCommitLookup.js","sourceRoot":"","sources":["../../../src/application/services/JevCommitLookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { JevHttpPort, LoggerPort } from '../../domain/ports.js';
|
|
2
|
+
import type { JevCheckKind, JevCheckResult, JevItemDetail } from './JevCheckTypes.js';
|
|
3
|
+
import type { ExchangeState } from './JevSpecState.js';
|
|
4
|
+
import type { JevAnswer, JevQuestionSet } from './JevResponseValidator.js';
|
|
5
|
+
import type { JevSettings } from './JevSettings.js';
|
|
6
|
+
import type { JevSidecarStore, SidecarBinding, SidecarItem, SidecarKind } from './JevSidecarStore.js';
|
|
7
|
+
export interface Interpretation {
|
|
8
|
+
flagged: string[];
|
|
9
|
+
details: JevItemDetail[];
|
|
10
|
+
items?: SidecarItem[];
|
|
11
|
+
extras?: Partial<JevCheckResult>;
|
|
12
|
+
}
|
|
13
|
+
/** Everything one request/response round trip needs; built by the per-check state builders. */
|
|
14
|
+
export interface ExchangePlan {
|
|
15
|
+
check: JevCheckKind;
|
|
16
|
+
kind: SidecarKind;
|
|
17
|
+
taskNumber?: string;
|
|
18
|
+
binding: SidecarBinding;
|
|
19
|
+
state: ExchangeState | Record<string, unknown>;
|
|
20
|
+
questions: JevQuestionSet;
|
|
21
|
+
omittedIds: string[];
|
|
22
|
+
truncated: boolean;
|
|
23
|
+
redactions: number;
|
|
24
|
+
droppedFindingIds?: string[];
|
|
25
|
+
baseCommit?: string | null;
|
|
26
|
+
sidecarItems?: SidecarItem[];
|
|
27
|
+
source?: 'jev' | 'local';
|
|
28
|
+
/** No stable binding exists (for example git is unavailable): neither read nor write a sidecar. */
|
|
29
|
+
unbound?: boolean;
|
|
30
|
+
interpret(answers: Record<string, JevAnswer>): Interpretation;
|
|
31
|
+
}
|
|
32
|
+
export interface ExchangeContext {
|
|
33
|
+
projectRoot: string;
|
|
34
|
+
featureName?: string;
|
|
35
|
+
settings: JevSettings;
|
|
36
|
+
}
|
|
37
|
+
/** Reuse a matching sidecar, else send exactly one request, validate, persist, and report. */
|
|
38
|
+
export declare class JevExchange {
|
|
39
|
+
private readonly http;
|
|
40
|
+
private readonly store;
|
|
41
|
+
private readonly logger;
|
|
42
|
+
constructor(http: JevHttpPort, store: JevSidecarStore, logger: LoggerPort);
|
|
43
|
+
run(plan: ExchangePlan, context: ExchangeContext): Promise<JevCheckResult>;
|
|
44
|
+
private send;
|
|
45
|
+
private persist;
|
|
46
|
+
private decorate;
|
|
47
|
+
private answered;
|
|
48
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { JEV_DECIDE_URL, JevTransportError } from '../../domain/ports.js';
|
|
2
|
+
import { renderJevLine } from './JevReport.js';
|
|
3
|
+
import { MAX_JEV_RESPONSE_BYTES, validateJevResponse } from './JevResponseValidator.js';
|
|
4
|
+
import { unavailableResult } from './JevResults.js';
|
|
5
|
+
/** Extra time beyond the adapter timeout before the caller gives up on a port that never settles. */
|
|
6
|
+
const DEADLINE_GRACE_MS = 200;
|
|
7
|
+
function withDeadline(promise, ms) {
|
|
8
|
+
let timer;
|
|
9
|
+
const deadline = new Promise((_, reject) => {
|
|
10
|
+
timer = setTimeout(() => reject(new JevTransportError('timeout')), ms);
|
|
11
|
+
});
|
|
12
|
+
return Promise.race([promise, deadline]).finally(() => clearTimeout(timer));
|
|
13
|
+
}
|
|
14
|
+
const reasonFor = (error) => {
|
|
15
|
+
if (!(error instanceof JevTransportError))
|
|
16
|
+
return 'network';
|
|
17
|
+
return error.kind === 'too-large' ? 'invalid-response' : error.kind;
|
|
18
|
+
};
|
|
19
|
+
/** Reuse a matching sidecar, else send exactly one request, validate, persist, and report. */
|
|
20
|
+
export class JevExchange {
|
|
21
|
+
http;
|
|
22
|
+
store;
|
|
23
|
+
logger;
|
|
24
|
+
constructor(http, store, logger) {
|
|
25
|
+
this.http = http;
|
|
26
|
+
this.store = store;
|
|
27
|
+
this.logger = logger;
|
|
28
|
+
}
|
|
29
|
+
async run(plan, context) {
|
|
30
|
+
const reused = plan.unbound
|
|
31
|
+
? undefined
|
|
32
|
+
: await this.store.readMatching(context.projectRoot, context.featureName, plan.kind, plan.binding, plan.taskNumber);
|
|
33
|
+
if (reused?.answers) {
|
|
34
|
+
const path = this.store.relativePath(context.featureName, plan.kind, plan.binding, plan.taskNumber);
|
|
35
|
+
return this.answered(plan, reused.answers, { persisted: true, path, truncated: reused.truncated, redactions: reused.redactions });
|
|
36
|
+
}
|
|
37
|
+
const started = Date.now();
|
|
38
|
+
const outcome = await this.send(plan, context.settings);
|
|
39
|
+
this.logger.debug('JEV exchange finished', { check: plan.check, ok: outcome.ok, durationMs: Date.now() - started });
|
|
40
|
+
if (outcome.ok === false) {
|
|
41
|
+
const written = await this.persist(plan, context, { status: 'unavailable', reason: outcome.reason });
|
|
42
|
+
return this.decorate(unavailableResult(plan.check, outcome.reason), plan, written.persisted, written.path);
|
|
43
|
+
}
|
|
44
|
+
const interpretation = plan.interpret(outcome.answers);
|
|
45
|
+
const written = await this.persist(plan, context, {
|
|
46
|
+
status: 'answered', answers: outcome.answers, meta: outcome.meta, items: interpretation.items,
|
|
47
|
+
});
|
|
48
|
+
return this.answered(plan, outcome.answers, { persisted: written.persisted, path: written.path, interpretation });
|
|
49
|
+
}
|
|
50
|
+
async send(plan, settings) {
|
|
51
|
+
const key = settings.apiKey();
|
|
52
|
+
if (!key)
|
|
53
|
+
return { ok: false, reason: 'no-key' };
|
|
54
|
+
try {
|
|
55
|
+
const response = await withDeadline(this.http.post({
|
|
56
|
+
url: JEV_DECIDE_URL,
|
|
57
|
+
body: JSON.stringify({ state: plan.state, questions: plan.questions }),
|
|
58
|
+
headers: { 'Content-Type': 'application/json', Accept: 'application/json', Authorization: `Bearer ${key}` },
|
|
59
|
+
timeoutMs: settings.timeoutMs,
|
|
60
|
+
maxResponseBytes: MAX_JEV_RESPONSE_BYTES,
|
|
61
|
+
}), settings.timeoutMs + DEADLINE_GRACE_MS);
|
|
62
|
+
if (response.status < 200 || response.status > 299)
|
|
63
|
+
return { ok: false, reason: `http-${response.status}` };
|
|
64
|
+
const validated = validateJevResponse(response.body, plan.questions);
|
|
65
|
+
return validated.ok
|
|
66
|
+
? { ok: true, answers: validated.answers, meta: validated.meta }
|
|
67
|
+
: { ok: false, reason: 'invalid-response' };
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
return { ok: false, reason: reasonFor(error) };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async persist(plan, context, body) {
|
|
74
|
+
if (plan.unbound)
|
|
75
|
+
return { persisted: false };
|
|
76
|
+
const sidecar = {
|
|
77
|
+
schema: 1,
|
|
78
|
+
kind: plan.kind,
|
|
79
|
+
createdAt: new Date().toISOString(),
|
|
80
|
+
binding: plan.binding,
|
|
81
|
+
source: plan.source ?? 'jev',
|
|
82
|
+
baseCommit: plan.baseCommit,
|
|
83
|
+
truncated: plan.truncated,
|
|
84
|
+
omittedIds: plan.omittedIds,
|
|
85
|
+
droppedFindingIds: plan.droppedFindingIds ?? [],
|
|
86
|
+
redactions: plan.redactions,
|
|
87
|
+
...body,
|
|
88
|
+
items: body.items ?? plan.sidecarItems,
|
|
89
|
+
};
|
|
90
|
+
return this.store.write(context.projectRoot, context.featureName, sidecar, plan.taskNumber);
|
|
91
|
+
}
|
|
92
|
+
decorate(result, plan, persisted, path) {
|
|
93
|
+
return {
|
|
94
|
+
...result,
|
|
95
|
+
persisted,
|
|
96
|
+
sidecar: path,
|
|
97
|
+
truncated: plan.truncated,
|
|
98
|
+
redactions: plan.redactions,
|
|
99
|
+
...(plan.droppedFindingIds?.length ? { droppedFindingIds: plan.droppedFindingIds } : {}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
answered(plan, answers, stored) {
|
|
103
|
+
const interpretation = stored.interpretation ?? plan.interpret(answers);
|
|
104
|
+
const result = {
|
|
105
|
+
check: plan.check,
|
|
106
|
+
status: 'answered',
|
|
107
|
+
line: renderJevLine({ status: 'answered', flagged: interpretation.flagged }),
|
|
108
|
+
flagged: interpretation.flagged,
|
|
109
|
+
details: interpretation.details,
|
|
110
|
+
persisted: stored.persisted,
|
|
111
|
+
sidecar: stored.path,
|
|
112
|
+
truncated: stored.truncated ?? plan.truncated,
|
|
113
|
+
redactions: stored.redactions ?? plan.redactions,
|
|
114
|
+
...interpretation.extras,
|
|
115
|
+
};
|
|
116
|
+
return plan.droppedFindingIds?.length ? { ...result, droppedFindingIds: plan.droppedFindingIds } : result;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=JevExchange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JevExchange.js","sourceRoot":"","sources":["../../../src/application/services/JevExchange.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { JevQuestionSet } from './JevResponseValidator.js';
|
|
2
|
+
/** Bump when any question text, label, or level changes; sidecars bind to it. */
|
|
3
|
+
export declare const QUESTION_SET_VERSION = 3;
|
|
4
|
+
/** Score answers are zero-based: an integer from 0 to the last level's index. The validator accepts nothing else. */
|
|
5
|
+
export declare const SCORE_SCALE_INSTRUCTION = "Answer with the zero-based index of the matching level (0 = first level listed).";
|
|
6
|
+
/** Constant preamble. Artifact, evidence, and code text only ever appear under `state`. */
|
|
7
|
+
export declare const INSTRUCTION_PREAMBLE: string;
|
|
8
|
+
export interface PrincipleSource {
|
|
9
|
+
file: 'coding-style.md' | 'error-handling.md';
|
|
10
|
+
heading: string;
|
|
11
|
+
}
|
|
12
|
+
export interface Principle {
|
|
13
|
+
key: 'srp' | 'dry' | 'kissYagni' | 'dip' | 'swallowedErrors' | 'sensitiveLogging';
|
|
14
|
+
/** Rule headings the criteria are drawn from; a test checks they exist verbatim. */
|
|
15
|
+
sources: readonly PrincipleSource[];
|
|
16
|
+
question: string;
|
|
17
|
+
violated: string;
|
|
18
|
+
}
|
|
19
|
+
export declare const PRINCIPLES: readonly Principle[];
|
|
20
|
+
export declare function buildRequirementsQuestions(requirementIds: readonly string[]): JevQuestionSet;
|
|
21
|
+
export declare function buildDesignQuestions(decisionIds: readonly string[], nfrIds: readonly string[]): JevQuestionSet;
|
|
22
|
+
export declare function buildTestcaseQuestions(tasks: ReadonlyArray<{
|
|
23
|
+
id: string;
|
|
24
|
+
notApplicable: boolean;
|
|
25
|
+
}>): JevQuestionSet;
|
|
26
|
+
export declare function buildRedQuestions(): JevQuestionSet;
|
|
27
|
+
export declare function buildSecurityQuestions(findingIds: readonly string[]): JevQuestionSet;
|
|
28
|
+
export declare function buildPrincipleQuestions(unitIds: readonly string[]): JevQuestionSet;
|