karajan-code 4.28.1 → 4.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -9
- package/package.json +2 -2
- package/scripts/verify-pack.mjs +19 -1
- package/src/checks/config-files.js +86 -0
- package/src/checks/method.js +34 -1
- package/src/checks/sonar.js +16 -7
- package/src/cli/register-pipeline.js +4 -1
- package/src/commands/identity.js +5 -2
- package/src/commands/review-gate.js +71 -3
- package/src/git/automation.js +3 -1
- package/src/harden/harden-engine.js +5 -2
- package/src/harden/hook-templates.js +25 -10
- package/src/harden/phone-sign.js +82 -13
- package/src/harden/supervisor-commit.js +7 -0
- package/src/mcp/handlers/direct-handlers.js +34 -21
- package/src/mcp/handlers/rag-handler.js +10 -4
- package/src/mcp/server-handlers.js +11 -1
- package/src/mcp/tools.js +1 -0
- package/src/review/one-shot-review.js +3 -0
- package/src/review/sonar-pregate.js +64 -15
- package/src/review/sonar-requirement.js +47 -0
- package/src/review/tests-with-code.js +17 -6
- package/src/review/verdict-store.js +61 -1
- package/src/roles/commiter-role.js +4 -1
- package/src/sonar/scanner.js +40 -15
- package/src/utils/paths.js +1 -0
|
@@ -35,7 +35,9 @@ export class CommiterRole extends BaseRole {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
async execute(input) {
|
|
38
|
-
|
|
38
|
+
// KJC-TSK-0838: the caller hands the sonar stage result (pipelineSonarBlock);
|
|
39
|
+
// without it the stamp carries no proof and the commit gate refuses code.
|
|
40
|
+
const { task, commitMessage, push = false, createPr = false, sonar = null } = input || {};
|
|
39
41
|
|
|
40
42
|
const isRepo = await ensureGitRepo();
|
|
41
43
|
if (!isRepo) {
|
|
@@ -65,6 +67,7 @@ export class CommiterRole extends BaseRole {
|
|
|
65
67
|
projectDir: this.config?.projectDir || process.cwd(),
|
|
66
68
|
reviewer: this.config?.reviewer || "pipeline-reviewer",
|
|
67
69
|
summary: "kj pipeline (commiter role): review passed",
|
|
70
|
+
sonar,
|
|
68
71
|
}),
|
|
69
72
|
});
|
|
70
73
|
const commitHash = await revParse("HEAD");
|
package/src/sonar/scanner.js
CHANGED
|
@@ -37,8 +37,23 @@ export async function pickSonarScanner(scannerConfig = {}, deps = {}) {
|
|
|
37
37
|
return { type: "docker" };
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* KJC-TSK-0838: the files the scanner ITSELF reports having indexed
|
|
42
|
+
* (`'<path>' indexed with language '<lang>'`, emitted with sonar.verbose).
|
|
43
|
+
* Paths are relative to the scanned base dir. This is the proof of coverage:
|
|
44
|
+
* what the engine saw, not what the config claims it should see.
|
|
45
|
+
* @param {string} scanOutput @returns {Set<string>}
|
|
46
|
+
*/
|
|
47
|
+
export function indexedFilesFrom(scanOutput) {
|
|
48
|
+
const files = new Set();
|
|
49
|
+
for (const m of String(scanOutput || "").matchAll(/'([^']+)' indexed with language '/g)) files.add(m[1]);
|
|
50
|
+
return files;
|
|
51
|
+
}
|
|
52
|
+
|
|
40
53
|
export function buildScannerOpts(projectKey, scanner = {}) {
|
|
41
54
|
const opts = [`-Dsonar.projectKey=${projectKey}`];
|
|
55
|
+
// KJC-TSK-0838: verbose is what makes the scanner name every indexed file.
|
|
56
|
+
if (scanner.verbose) opts.push("-Dsonar.verbose=true");
|
|
42
57
|
if (scanner.sources) opts.push(`-Dsonar.sources=${scanner.sources}`);
|
|
43
58
|
if (scanner.exclusions) opts.push(`-Dsonar.exclusions=${scanner.exclusions}`);
|
|
44
59
|
if (scanner.test_inclusions) opts.push(`-Dsonar.test.inclusions=${scanner.test_inclusions}`);
|
|
@@ -225,18 +240,27 @@ export async function ensureSonarProjectProperties(cwd = process.cwd()) {
|
|
|
225
240
|
}
|
|
226
241
|
}
|
|
227
242
|
|
|
228
|
-
export async function runSonarScan(config, projectKey = null) {
|
|
243
|
+
export async function runSonarScan(config, projectKey = null, { verbose = false, cwd = null } = {}) {
|
|
244
|
+
const scanCwd = cwd || process.cwd();
|
|
245
|
+
// KJC-TSK-0838 step 3 (monorepo): a nested package scans from its own
|
|
246
|
+
// directory under the key its properties declare — so the proof of
|
|
247
|
+
// coverage is about that package, not the root's `sonar.sources`.
|
|
248
|
+
const repoProps = await ensureSonarProjectProperties(scanCwd);
|
|
229
249
|
let effectiveProjectKey;
|
|
230
|
-
|
|
231
|
-
effectiveProjectKey =
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
250
|
+
if (cwd && !projectKey && repoProps.declaredKey) {
|
|
251
|
+
effectiveProjectKey = repoProps.declaredKey;
|
|
252
|
+
} else {
|
|
253
|
+
try {
|
|
254
|
+
effectiveProjectKey = await resolveSonarProjectKey(config, { projectKey });
|
|
255
|
+
} catch (error) {
|
|
256
|
+
return {
|
|
257
|
+
ok: false,
|
|
258
|
+
projectKey: null,
|
|
259
|
+
stdout: "",
|
|
260
|
+
stderr: error?.message || String(error),
|
|
261
|
+
exitCode: 1
|
|
262
|
+
};
|
|
263
|
+
}
|
|
240
264
|
}
|
|
241
265
|
const sonarConfig = config?.sonarqube || {};
|
|
242
266
|
const rawHost = sonarConfig.host || "http://localhost:9000";
|
|
@@ -260,7 +284,6 @@ export async function runSonarScan(config, projectKey = null) {
|
|
|
260
284
|
}
|
|
261
285
|
// KJC-BUG-0156: kj's -Dsonar.projectKey stays (scan and query must use the
|
|
262
286
|
// SAME key), but the repo's properties own the LAYOUT from here on.
|
|
263
|
-
const repoProps = await ensureSonarProjectProperties();
|
|
264
287
|
const token = await resolveSonarTokenWithFallback(config, apiHost);
|
|
265
288
|
if (!token) {
|
|
266
289
|
return {
|
|
@@ -284,7 +307,8 @@ export async function runSonarScan(config, projectKey = null) {
|
|
|
284
307
|
const scannerConfig = respectRepoProperties(
|
|
285
308
|
normalizeScannerConfig({
|
|
286
309
|
...sonarConfig.scanner,
|
|
287
|
-
...coverage.scannerPatch
|
|
310
|
+
...coverage.scannerPatch,
|
|
311
|
+
...(verbose ? { verbose: true } : {})
|
|
288
312
|
}),
|
|
289
313
|
repoProps
|
|
290
314
|
);
|
|
@@ -310,7 +334,7 @@ export async function runSonarScan(config, projectKey = null) {
|
|
|
310
334
|
"run",
|
|
311
335
|
"--rm",
|
|
312
336
|
"-v",
|
|
313
|
-
`${
|
|
337
|
+
`${scanCwd}:/usr/src`,
|
|
314
338
|
...(isLocalHost ? ["--add-host", "host.docker.internal:host-gateway"] : []),
|
|
315
339
|
...(isLocalHost || isExternalSonar ? [] : ["--network", sonarNetwork]),
|
|
316
340
|
"-e", "SONAR_HOST_URL",
|
|
@@ -320,10 +344,11 @@ export async function runSonarScan(config, projectKey = null) {
|
|
|
320
344
|
];
|
|
321
345
|
}
|
|
322
346
|
|
|
323
|
-
const result = await runCommand(cmd, args, { timeout: scannerTimeout, env });
|
|
347
|
+
const result = await runCommand(cmd, args, { timeout: scannerTimeout, env, cwd: scanCwd });
|
|
324
348
|
return {
|
|
325
349
|
ok: result.exitCode === 0,
|
|
326
350
|
projectKey: effectiveProjectKey,
|
|
351
|
+
cwd: scanCwd,
|
|
327
352
|
scanner: pick.type,
|
|
328
353
|
note,
|
|
329
354
|
stdout: result.stdout,
|