@cejel/cejel 0.4.6 → 0.4.8

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.
@@ -5,10 +5,10 @@ import {
5
5
  describeGitFailure,
6
6
  execGit,
7
7
  isExpectedGitAbsence
8
- } from "./chunk-BZXBLDCJ.js";
8
+ } from "./chunk-KNQBI3IX.js";
9
9
  import {
10
10
  init_esm_shims
11
- } from "./chunk-H55KECVT.js";
11
+ } from "./chunk-V3B2V4WA.js";
12
12
 
13
13
  // src/packs/llm/files.ts
14
14
  init_esm_shims();
@@ -4,7 +4,7 @@ const require = __cejelCreateRequire(import.meta.url);
4
4
  import {
5
5
  __export,
6
6
  init_esm_shims
7
- } from "./chunk-H55KECVT.js";
7
+ } from "./chunk-V3B2V4WA.js";
8
8
 
9
9
  // node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
10
10
  var external_exports = {};
@@ -3,7 +3,7 @@ import { createRequire as __cejelCreateRequire } from 'node:module';
3
3
  const require = __cejelCreateRequire(import.meta.url);
4
4
  import {
5
5
  init_esm_shims
6
- } from "./chunk-H55KECVT.js";
6
+ } from "./chunk-V3B2V4WA.js";
7
7
 
8
8
  // src/witan/git-exec.ts
9
9
  init_esm_shims();
@@ -62,7 +62,35 @@ var MAX_REPOSITORY_CONTENT_BYTES = 512e3;
62
62
  init_esm_shims();
63
63
  import { closeSync, lstatSync, openSync, readFileSync, readSync } from "fs";
64
64
  import { resolve } from "path";
65
+ var READ_FAILURE_REASONS = /* @__PURE__ */ new Set(["unreadable", "denied_path"]);
66
+ function isReadFailureReason(reason) {
67
+ return READ_FAILURE_REASONS.has(reason);
68
+ }
69
+ function classifyAbstentionReason(reasons) {
70
+ if (!reasons || reasons.size === 0) return {};
71
+ for (const reason of reasons) {
72
+ if (isReadFailureReason(reason)) return {};
73
+ }
74
+ const priority = [
75
+ "too_large",
76
+ "excluded_by_extension",
77
+ "non_regular_file"
78
+ ];
79
+ const chosen = priority.find((reason) => reasons.has(reason));
80
+ return chosen ? { insufficientDataReason: chosen } : {};
81
+ }
82
+ function contentReadSignalKey(criterionId, signalId) {
83
+ return [criterionId, signalId].join(":");
84
+ }
65
85
  var activeSession;
86
+ function addSkipReason(map, key, reason) {
87
+ const existing = map.get(key);
88
+ if (existing) {
89
+ existing.add(reason);
90
+ } else {
91
+ map.set(key, /* @__PURE__ */ new Set([reason]));
92
+ }
93
+ }
66
94
  function errnoClass(error) {
67
95
  if (typeof error !== "object" || error === null || !("code" in error)) return null;
68
96
  const code = error.code;
@@ -73,6 +101,17 @@ function recordSkip(path2, reason, errno, affectsCurrentCriterion = false, dedup
73
101
  if (!session) return;
74
102
  if (affectsCurrentCriterion && session.criterion) {
75
103
  session.affectedCriteria.add(session.criterion);
104
+ const signals = session.signals;
105
+ if (signals && signals.length > 0) {
106
+ for (const signal of signals) {
107
+ const key = contentReadSignalKey(session.criterion, signal);
108
+ session.affectedSignals.add(key);
109
+ addSkipReason(session.signalSkipReasons, key, reason);
110
+ }
111
+ } else {
112
+ session.unattributedCriteria.add(session.criterion);
113
+ addSkipReason(session.criterionSkipReasons, session.criterion, reason);
114
+ }
76
115
  }
77
116
  if (deduplicate) {
78
117
  const key = `${resolve(path2)}\0${reason}\0${errno ?? ""}`;
@@ -108,7 +147,11 @@ function trackContentReads(_repoPath, collect) {
108
147
  return {
109
148
  value: collect(),
110
149
  summary: summaryFor(existing),
111
- affectedCriteria: existing.affectedCriteria
150
+ affectedCriteria: existing.affectedCriteria,
151
+ affectedSignals: existing.affectedSignals,
152
+ unattributedCriteria: existing.unattributedCriteria,
153
+ criterionSkipReasons: existing.criterionSkipReasons,
154
+ signalSkipReasons: existing.signalSkipReasons
112
155
  };
113
156
  }
114
157
  const session = {
@@ -121,7 +164,11 @@ function trackContentReads(_repoPath, collect) {
121
164
  },
122
165
  unreadableByErrno: /* @__PURE__ */ new Map(),
123
166
  deduplicatedSkips: /* @__PURE__ */ new Set(),
124
- affectedCriteria: /* @__PURE__ */ new Set()
167
+ affectedCriteria: /* @__PURE__ */ new Set(),
168
+ affectedSignals: /* @__PURE__ */ new Set(),
169
+ unattributedCriteria: /* @__PURE__ */ new Set(),
170
+ criterionSkipReasons: /* @__PURE__ */ new Map(),
171
+ signalSkipReasons: /* @__PURE__ */ new Map()
125
172
  };
126
173
  activeSession = session;
127
174
  try {
@@ -129,7 +176,11 @@ function trackContentReads(_repoPath, collect) {
129
176
  return {
130
177
  value,
131
178
  summary: summaryFor(session),
132
- affectedCriteria: session.affectedCriteria
179
+ affectedCriteria: session.affectedCriteria,
180
+ affectedSignals: session.affectedSignals,
181
+ unattributedCriteria: session.unattributedCriteria,
182
+ criterionSkipReasons: session.criterionSkipReasons,
183
+ signalSkipReasons: session.signalSkipReasons
133
184
  };
134
185
  } finally {
135
186
  activeSession = void 0;
@@ -146,14 +197,24 @@ function withContentReadCriterion(criterion, collect) {
146
197
  session.criterion = previous;
147
198
  }
148
199
  }
149
- function recordContentSkip(path2, reason, deduplicate = false) {
150
- recordSkip(path2, reason, void 0, false, deduplicate);
200
+ function withContentReadSignal(criterionId, signalId, collect) {
201
+ return withContentReadSignals(criterionId, [signalId], collect);
151
202
  }
152
- function recordContentSkipForCriteria(path2, reason, criteria, deduplicate = false) {
203
+ function withContentReadSignals(criterionId, signalIds, collect) {
204
+ if (signalIds.length === 0) {
205
+ throw new Error("Cejel invariant: withContentReadSignals requires at least one signal id");
206
+ }
153
207
  const session = activeSession;
154
- if (session) {
155
- for (const criterion of criteria) session.affectedCriteria.add(criterion);
208
+ if (!session || session.criterion !== criterionId) return collect();
209
+ const previous = session.signals;
210
+ session.signals = signalIds;
211
+ try {
212
+ return collect();
213
+ } finally {
214
+ session.signals = previous;
156
215
  }
216
+ }
217
+ function recordContentSkip(path2, reason, deduplicate = false) {
157
218
  recordSkip(path2, reason, void 0, false, deduplicate);
158
219
  }
159
220
  function recordFilesystemSkip(path2, error, deniedContext = false, deduplicate = true) {
@@ -227,10 +288,13 @@ export {
227
288
  __filename,
228
289
  init_esm_shims,
229
290
  MAX_REPOSITORY_CONTENT_BYTES,
291
+ classifyAbstentionReason,
292
+ contentReadSignalKey,
230
293
  trackContentReads,
231
294
  withContentReadCriterion,
295
+ withContentReadSignal,
296
+ withContentReadSignals,
232
297
  recordContentSkip,
233
- recordContentSkipForCriteria,
234
298
  recordFilesystemSkip,
235
299
  readRepoText,
236
300
  readRepoTextPrefix
@@ -7,7 +7,7 @@ import {
7
7
  __filename,
8
8
  __require,
9
9
  init_esm_shims
10
- } from "./chunk-H55KECVT.js";
10
+ } from "./chunk-V3B2V4WA.js";
11
11
 
12
12
  // node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/typescript.js
13
13
  var require_typescript = __commonJS({
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  assertSelectableRubricVersion,
11
11
  buildRelyingPartySummary,
12
12
  createWitanAttestation,
13
+ formatCertificateMetricAppliedWeightPercent,
13
14
  formatCertificateMetricLabel,
14
15
  formatCertificateMetricValue,
15
16
  formatExternalSourceLine,
@@ -20,12 +21,12 @@ import {
20
21
  runCejelScan,
21
22
  serializeWitanReport,
22
23
  verifyWitanAttestationBinding
23
- } from "./chunk-VEJLHO5F.js";
24
- import "./chunk-BZXBLDCJ.js";
25
- import "./chunk-Y6NO5HAI.js";
24
+ } from "./chunk-6R3VJGJ2.js";
25
+ import "./chunk-KNQBI3IX.js";
26
+ import "./chunk-J6R5OHN7.js";
26
27
  import {
27
28
  init_esm_shims
28
- } from "./chunk-H55KECVT.js";
29
+ } from "./chunk-V3B2V4WA.js";
29
30
 
30
31
  // src/index.ts
31
32
  init_esm_shims();
@@ -113,13 +114,16 @@ function renderTerminalCertificate(summary, report) {
113
114
  (criterion) => criterion.metrics.map((metric) => ({
114
115
  criterionId: criterion.id,
115
116
  label: formatCertificateMetricLabel(metric),
116
- value: formatCertificateMetricValue(criterion, metric)
117
+ value: formatCertificateMetricValue(criterion, metric),
118
+ weightPercent: formatCertificateMetricAppliedWeightPercent(criterion, metric)
117
119
  }))
118
120
  );
119
121
  if (!abstained && (measurements?.length ?? 0) > 0) {
120
122
  lines.push("Measurements:");
121
123
  for (const measurement of measurements ?? []) {
122
- lines.push(` ${measurement.criterionId} \u2014 ${measurement.label}: ${measurement.value}`);
124
+ lines.push(
125
+ ` ${measurement.criterionId} \u2014 ${measurement.label}: ${measurement.value} (weight ${measurement.weightPercent}% of ${measurement.criterionId})`
126
+ );
123
127
  }
124
128
  lines.push("");
125
129
  }
@@ -210,6 +214,12 @@ var CLI_FLAG_SPECS = [
210
214
  description: "EXPLICIT OPT-IN: pin a rubric other than the calibrated default (see docs); prospective rubrics carry no calibration claim",
211
215
  kind: "rubricPin"
212
216
  },
217
+ {
218
+ tokens: ["--run-attempt"],
219
+ value: "<n>",
220
+ description: "record which CI run attempt produced this certificate (set by the GitHub Action; omit otherwise)",
221
+ kind: "runAttempt"
222
+ },
213
223
  {
214
224
  tokens: ["--quiet"],
215
225
  description: "suppress the terminal summary",
@@ -314,9 +324,14 @@ async function runWitanCli(args, rubricVersion) {
314
324
  ...options.productDisplayName ? { productDisplayName: options.productDisplayName } : {},
315
325
  ...effectiveRubricVersion ? { rubricVersion: effectiveRubricVersion } : {},
316
326
  ingestPatterns: options.ingestPatterns,
317
- warnOnEmptyIngestMatch: !options.quiet
327
+ warnOnEmptyIngestMatch: !options.quiet,
328
+ toolVersion: cliVersion()
329
+ });
330
+ const attestation = createWitanAttestation(report, {
331
+ toolVersion: cliVersion(),
332
+ generatedAt,
333
+ ...options.runAttempt ? { githubRunAttempt: options.runAttempt } : {}
318
334
  });
319
- const attestation = createWitanAttestation(report, { toolVersion: cliVersion(), generatedAt });
320
335
  mkdirSync(options.outDir, { recursive: true });
321
336
  writeFileSync(join(options.outDir, "report.json"), serializeWitanReport(report), "utf8");
322
337
  writeFileSync(
@@ -326,7 +341,11 @@ async function runWitanCli(args, rubricVersion) {
326
341
  );
327
342
  writeFileSync(
328
343
  join(options.outDir, "certificate.html"),
329
- renderWitanHtmlReport(report, { cliVersion: cliVersion(), generatedAt }),
344
+ renderWitanHtmlReport(report, {
345
+ cliVersion: cliVersion(),
346
+ generatedAt,
347
+ ...options.runAttempt ? { runAttempt: options.runAttempt } : {}
348
+ }),
330
349
  "utf8"
331
350
  );
332
351
  writeFileSync(
@@ -453,6 +472,7 @@ function parseArgs(args) {
453
472
  let showHelp = false;
454
473
  let showVersion = false;
455
474
  let rubricPin;
475
+ let runAttempt;
456
476
  const ingestPatterns = [];
457
477
  for (let index = 0; index < args.length; index += 1) {
458
478
  const arg = args[index];
@@ -531,6 +551,16 @@ function parseArgs(args) {
531
551
  index += 1;
532
552
  break;
533
553
  }
554
+ case "runAttempt": {
555
+ const value = args[index + 1];
556
+ if (!value) throw new Error("Missing value for --run-attempt");
557
+ if (!/^[1-9][0-9]*$/.test(value)) {
558
+ throw new Error(`--run-attempt must be a positive integer, got: ${value}`);
559
+ }
560
+ runAttempt = value;
561
+ index += 1;
562
+ break;
563
+ }
534
564
  }
535
565
  continue;
536
566
  }
@@ -553,7 +583,8 @@ function parseArgs(args) {
553
583
  showHelp,
554
584
  showVersion,
555
585
  ingestPatterns,
556
- ...rubricPin ? { rubricPin } : {}
586
+ ...rubricPin ? { rubricPin } : {},
587
+ ...runAttempt ? { runAttempt } : {}
557
588
  };
558
589
  }
559
590
  function hasUnsafeDisplayNameCharacter(value) {
package/dist/mcp/index.js CHANGED
@@ -5,20 +5,20 @@ import {
5
5
  renderWitanBadgeSvg,
6
6
  renderWitanHtmlReport,
7
7
  runCejelScan
8
- } from "../chunk-VEJLHO5F.js";
9
- import "../chunk-BZXBLDCJ.js";
8
+ } from "../chunk-6R3VJGJ2.js";
9
+ import "../chunk-KNQBI3IX.js";
10
10
  import {
11
11
  ZodFirstPartyTypeKind,
12
12
  ZodOptional,
13
13
  external_exports,
14
14
  objectType
15
- } from "../chunk-Y6NO5HAI.js";
15
+ } from "../chunk-J6R5OHN7.js";
16
16
  import {
17
17
  __commonJS,
18
18
  __export,
19
19
  __toESM,
20
20
  init_esm_shims
21
- } from "../chunk-H55KECVT.js";
21
+ } from "../chunk-V3B2V4WA.js";
22
22
 
23
23
  // node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js
24
24
  var require_code = __commonJS({
@@ -17280,7 +17280,7 @@ function createCejelMcpServer(identity) {
17280
17280
  async ({ path, format }) => {
17281
17281
  let result;
17282
17282
  try {
17283
- result = runCejelScan({ repoPath: resolve(path) });
17283
+ result = runCejelScan({ repoPath: resolve(path), toolVersion: identity.version });
17284
17284
  } catch (error2) {
17285
17285
  const message = error2 instanceof Error ? error2.message : String(error2);
17286
17286
  return {
@@ -3,18 +3,18 @@ import { createRequire as __cejelCreateRequire } from 'node:module';
3
3
  const require = __cejelCreateRequire(import.meta.url);
4
4
  import {
5
5
  listCejelLlmPackFiles
6
- } from "../../chunk-QRWLHTGR.js";
6
+ } from "../../chunk-ERNYMFH4.js";
7
7
  import {
8
8
  execGit
9
- } from "../../chunk-BZXBLDCJ.js";
9
+ } from "../../chunk-KNQBI3IX.js";
10
10
  import {
11
11
  require_typescript
12
- } from "../../chunk-2IBG5OBF.js";
12
+ } from "../../chunk-ZPQOZLB7.js";
13
13
  import {
14
14
  __toESM,
15
15
  init_esm_shims,
16
16
  readRepoText
17
- } from "../../chunk-H55KECVT.js";
17
+ } from "../../chunk-V3B2V4WA.js";
18
18
 
19
19
  // src/packs/d-series/index.ts
20
20
  init_esm_shims();
@@ -3,15 +3,15 @@ import { createRequire as __cejelCreateRequire } from 'node:module';
3
3
  const require = __cejelCreateRequire(import.meta.url);
4
4
  import {
5
5
  external_exports
6
- } from "../../chunk-Y6NO5HAI.js";
6
+ } from "../../chunk-J6R5OHN7.js";
7
7
  import {
8
8
  require_typescript
9
- } from "../../chunk-2IBG5OBF.js";
9
+ } from "../../chunk-ZPQOZLB7.js";
10
10
  import {
11
11
  __toESM,
12
12
  init_esm_shims,
13
13
  readRepoText
14
- } from "../../chunk-H55KECVT.js";
14
+ } from "../../chunk-V3B2V4WA.js";
15
15
 
16
16
  // src/packs/decision-contracts/index.ts
17
17
  init_esm_shims();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cejel/cejel",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "mcpName": "io.github.BargLabs/cejel",
5
5
  "private": false,
6
6
  "publishConfig": {