@cejel/cejel 0.1.8 → 0.1.10
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 +29 -26
- package/dist/{chunk-SFEPABAX.js → chunk-EFOUXVJE.js} +2432 -234
- package/dist/index.js +49 -10
- package/dist/mcp/index.js +2 -2
- package/package.json +10 -12
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
runCejelScan,
|
|
10
10
|
serializeWitanReport,
|
|
11
11
|
verifyWitanAttestationBinding
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-EFOUXVJE.js";
|
|
13
13
|
|
|
14
14
|
// src/index.ts
|
|
15
15
|
import { createHash } from "crypto";
|
|
@@ -18,16 +18,23 @@ import { join, resolve } from "path";
|
|
|
18
18
|
import { pathToFileURL } from "url";
|
|
19
19
|
|
|
20
20
|
// src/terminal.ts
|
|
21
|
+
function renderMinScoreAbstentionFailure(summary, minScore) {
|
|
22
|
+
if (summary.verdict !== "Insufficient source" && summary.verdict !== "Insufficient evidence") {
|
|
23
|
+
throw new Error("A minimum-score abstention message requires an abstained Cejel summary.");
|
|
24
|
+
}
|
|
25
|
+
return `Cejel: cannot evaluate the required minimum ${minScore.toFixed(1)}/4.0 because this repository has ${summary.verdict.toLowerCase()}.
|
|
26
|
+
`;
|
|
27
|
+
}
|
|
21
28
|
function renderTerminalCertificate(summary) {
|
|
22
|
-
const abstained = summary.verdict === "Insufficient source";
|
|
29
|
+
const abstained = summary.verdict === "Insufficient source" || summary.verdict === "Insufficient evidence";
|
|
23
30
|
if (!abstained && (summary.overallScore === null || summary.codeTrustScore === null || summary.processTrustScore === null)) {
|
|
24
31
|
throw new Error("A scored Cejel summary must carry numeric headline scores.");
|
|
25
32
|
}
|
|
26
33
|
const lines = abstained ? [
|
|
27
34
|
`Cejel Trust Certificate \u2014 ${summary.productDisplayName}`,
|
|
28
35
|
"",
|
|
29
|
-
|
|
30
|
-
` ${summary.insufficientSourceReason ?? "No ratable source was found."}`,
|
|
36
|
+
`${summary.verdict} to certify.`,
|
|
37
|
+
` ${summary.insufficientSourceReason ?? "No ratable source or measurable evidence was found."}`,
|
|
31
38
|
""
|
|
32
39
|
] : [
|
|
33
40
|
`Cejel Trust Certificate \u2014 ${summary.productDisplayName}`,
|
|
@@ -49,9 +56,13 @@ function renderTerminalCertificate(summary) {
|
|
|
49
56
|
} else if (summary.topFindings.length === 0) {
|
|
50
57
|
lines.push("No evidence-backed findings.");
|
|
51
58
|
} else {
|
|
52
|
-
lines.push(
|
|
59
|
+
lines.push(
|
|
60
|
+
`Top findings (${summary.findingCount} total; labels distinguish finding severity from dimension band):`
|
|
61
|
+
);
|
|
53
62
|
for (const finding of summary.topFindings) {
|
|
54
|
-
lines.push(
|
|
63
|
+
lines.push(
|
|
64
|
+
` [finding severity: ${finding.severity}] ${finding.criterionId} [dimension band: ${finding.dimensionBand}]: ${finding.displaySummary ?? finding.summary}`
|
|
65
|
+
);
|
|
55
66
|
}
|
|
56
67
|
const remaining = summary.findingCount - summary.topFindings.length;
|
|
57
68
|
if (remaining > 0) {
|
|
@@ -96,6 +107,12 @@ var CLI_FLAG_SPECS = [
|
|
|
96
107
|
description: "exit nonzero below this overall score",
|
|
97
108
|
kind: "minScore"
|
|
98
109
|
},
|
|
110
|
+
{
|
|
111
|
+
tokens: ["--name"],
|
|
112
|
+
value: "<display>",
|
|
113
|
+
description: "override the project name shown on the certificate",
|
|
114
|
+
kind: "name"
|
|
115
|
+
},
|
|
99
116
|
{
|
|
100
117
|
tokens: ["--ingest"],
|
|
101
118
|
value: "<file>",
|
|
@@ -195,6 +212,7 @@ async function runWitanFreeCli(args) {
|
|
|
195
212
|
}
|
|
196
213
|
const { report, summary } = runCejelScan({
|
|
197
214
|
repoPath: options.repoPath,
|
|
215
|
+
...options.productDisplayName ? { productDisplayName: options.productDisplayName } : {},
|
|
198
216
|
ingestPatterns: options.ingestPatterns,
|
|
199
217
|
warnOnEmptyIngestMatch: !options.quiet
|
|
200
218
|
});
|
|
@@ -229,10 +247,7 @@ Wrote:
|
|
|
229
247
|
}
|
|
230
248
|
if (options.minScore != null) {
|
|
231
249
|
if (report.verdict === "insufficient_source") {
|
|
232
|
-
process.stderr.write(
|
|
233
|
-
`Cejel: cannot evaluate the required minimum ${options.minScore.toFixed(1)}/4.0 because this repository has insufficient source.
|
|
234
|
-
`
|
|
235
|
-
);
|
|
250
|
+
process.stderr.write(renderMinScoreAbstentionFailure(summary, options.minScore));
|
|
236
251
|
return 1;
|
|
237
252
|
}
|
|
238
253
|
if (report.overallScore < options.minScore) {
|
|
@@ -323,6 +338,7 @@ function parseArgs(args) {
|
|
|
323
338
|
let repoPath;
|
|
324
339
|
let outDir = DEFAULT_OUT_DIR;
|
|
325
340
|
let minScore;
|
|
341
|
+
let productDisplayName;
|
|
326
342
|
let quiet = false;
|
|
327
343
|
let showHelp = false;
|
|
328
344
|
let showVersion = false;
|
|
@@ -363,6 +379,19 @@ function parseArgs(args) {
|
|
|
363
379
|
index += 1;
|
|
364
380
|
break;
|
|
365
381
|
}
|
|
382
|
+
case "name": {
|
|
383
|
+
const value = args[index + 1];
|
|
384
|
+
if (!value) throw new Error("Missing value for --name");
|
|
385
|
+
const trimmed = value.trim();
|
|
386
|
+
if (trimmed.length === 0 || trimmed.length > 120 || hasUnsafeDisplayNameCharacter(trimmed)) {
|
|
387
|
+
throw new Error(
|
|
388
|
+
"--name must be a single printable line containing between 1 and 120 characters"
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
productDisplayName = trimmed;
|
|
392
|
+
index += 1;
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
366
395
|
case "ingest": {
|
|
367
396
|
const value = args[index + 1];
|
|
368
397
|
if (!value) throw new Error("Missing value for --ingest");
|
|
@@ -383,12 +412,22 @@ function parseArgs(args) {
|
|
|
383
412
|
repoPath: resolve(repoPath ?? "."),
|
|
384
413
|
outDir,
|
|
385
414
|
...minScore != null ? { minScore } : {},
|
|
415
|
+
...productDisplayName ? { productDisplayName } : {},
|
|
386
416
|
quiet,
|
|
387
417
|
showHelp,
|
|
388
418
|
showVersion,
|
|
389
419
|
ingestPatterns
|
|
390
420
|
};
|
|
391
421
|
}
|
|
422
|
+
function hasUnsafeDisplayNameCharacter(value) {
|
|
423
|
+
for (const character of value) {
|
|
424
|
+
const codePoint = character.codePointAt(0);
|
|
425
|
+
if (codePoint === void 0 || codePoint <= 31 || codePoint >= 127 && codePoint <= 159 || codePoint === 8232 || codePoint === 8233) {
|
|
426
|
+
return true;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
392
431
|
function isEntryPoint() {
|
|
393
432
|
const invokedPath = process.argv[1];
|
|
394
433
|
if (!invokedPath) return false;
|
package/dist/mcp/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
renderWitanBadgeSvg,
|
|
11
11
|
renderWitanHtmlReport,
|
|
12
12
|
runCejelScan
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-EFOUXVJE.js";
|
|
14
14
|
|
|
15
15
|
// node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js
|
|
16
16
|
var require_code = __commonJS({
|
|
@@ -17061,7 +17061,7 @@ function createCejelMcpServer(identity) {
|
|
|
17061
17061
|
});
|
|
17062
17062
|
server.tool(
|
|
17063
17063
|
"scan",
|
|
17064
|
-
`Score a repository's engineering-trust signals (tests, secrets, isolation, claim-vs-reality, CI discipline) with the ${identity.packageName} trust-certificate scan \u2014 the exact same offline, deterministic scoring as running the ${identity.packageName} CLI on the path. Returns the trust cert as JSON: overall + code/process sub-scores (0-4) for a scored repository, or null scores with an
|
|
17064
|
+
`Score a repository's engineering-trust signals (tests, secrets, isolation, claim-vs-reality, CI discipline) with the ${identity.packageName} trust-certificate scan \u2014 the exact same offline, deterministic scoring as running the ${identity.packageName} CLI on the path. Returns the trust cert as JSON: overall + code/process sub-scores (0-4) for a scored repository, or null scores with an abstention reason when Cejel establishes structural source absence or zero measurable free-core criteria; plus the verdict and top findings. No network, no telemetry, no signup. After a scan, the full HTML certificate and SVG badge are readable as the resources ${certificateUri} and ${badgeUri}.`,
|
|
17065
17065
|
{
|
|
17066
17066
|
path: external_exports.string().min(1).describe("Path to the repository to score (absolute, or relative to the server CWD)"),
|
|
17067
17067
|
format: external_exports.enum(["summary", "json"]).optional().describe(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cejel/cejel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"mcpName": "io.github.BargLabs/cejel",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -44,16 +44,6 @@
|
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=18"
|
|
46
46
|
},
|
|
47
|
-
"scripts": {
|
|
48
|
-
"build": "tsup",
|
|
49
|
-
"build:sea-js": "tsup --config tsup.public-sea.config.ts",
|
|
50
|
-
"validate:distribution": "node scripts/validate-distribution-metadata.mjs",
|
|
51
|
-
"prepublishOnly": "pnpm run build",
|
|
52
|
-
"prepack": "pnpm run build",
|
|
53
|
-
"dev": "tsx src/index.ts",
|
|
54
|
-
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
55
|
-
"test": "vitest run"
|
|
56
|
-
},
|
|
57
47
|
"devDependencies": {
|
|
58
48
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
59
49
|
"@types/node": "^25.9.1",
|
|
@@ -63,5 +53,13 @@
|
|
|
63
53
|
"typescript": "^5.5.0",
|
|
64
54
|
"vitest": "^2.0.0",
|
|
65
55
|
"zod": "^3.23.0"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsup",
|
|
59
|
+
"build:sea-js": "tsup --config tsup.public-sea.config.ts",
|
|
60
|
+
"validate:distribution": "node scripts/validate-distribution-metadata.mjs",
|
|
61
|
+
"dev": "tsx src/index.ts",
|
|
62
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
63
|
+
"test": "vitest run"
|
|
66
64
|
}
|
|
67
|
-
}
|
|
65
|
+
}
|