@sigloch/graphcode-client 1.2.0 → 1.3.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/dist/panels.d.ts CHANGED
@@ -57,6 +57,32 @@ export interface RecommendationsPanel {
57
57
  total: number;
58
58
  }
59
59
  export declare function recommendationsPanel(violations: RuleViolation[], limit?: number): RecommendationsPanel;
60
+ /** One rule's firings, collapsed: the true count plus a NAMED-capped element sample. */
61
+ export interface ViolationGroup {
62
+ ruleId: string;
63
+ severity: 'error' | 'warning' | 'info';
64
+ /** Firings of this rule over the UNCAPPED input — never derived from `elementIds`. */
65
+ count: number;
66
+ message: string;
67
+ fixHint?: string;
68
+ /** At most `elementLimit` element ids, in input order. */
69
+ elementIds: string[];
70
+ /** How many element ids the cap cut off — the cap is never silent. */
71
+ elementIdsOmitted: number;
72
+ }
73
+ /**
74
+ * Group violations by ruleId — **group first, cap after**.
75
+ *
76
+ * The counting runs over the UNCAPPED violations, never over an already-capped
77
+ * item list: cap-then-count reports "50×" for a rule that fired 60×, and a wrong
78
+ * number is worse than a long list (CR-GVE-250). `elementIds` is cut at
79
+ * `elementLimit` and says via `elementIdsOmitted` how many are missing — a silent
80
+ * cap is exactly the defect this function exists to prevent.
81
+ *
82
+ * Pure projection: the input array is not mutated, and violations without an
83
+ * `elementId` (graph-scoped findings) still count, they just contribute no id.
84
+ */
85
+ export declare function groupViolations(violations: RuleViolation[], elementLimit?: number): ViolationGroup[];
60
86
  export type Freshness = 'live' | 'stale' | 'absent';
61
87
  /**
62
88
  * Two artifact kinds with TWO distinct staleness mechanisms (CR-GC-222):
package/dist/panels.js CHANGED
@@ -27,6 +27,47 @@ export function recommendationsPanel(violations, limit = 5) {
27
27
  });
28
28
  return { items, total: violations.length };
29
29
  }
30
+ /**
31
+ * Group violations by ruleId — **group first, cap after**.
32
+ *
33
+ * The counting runs over the UNCAPPED violations, never over an already-capped
34
+ * item list: cap-then-count reports "50×" for a rule that fired 60×, and a wrong
35
+ * number is worse than a long list (CR-GVE-250). `elementIds` is cut at
36
+ * `elementLimit` and says via `elementIdsOmitted` how many are missing — a silent
37
+ * cap is exactly the defect this function exists to prevent.
38
+ *
39
+ * Pure projection: the input array is not mutated, and violations without an
40
+ * `elementId` (graph-scoped findings) still count, they just contribute no id.
41
+ */
42
+ export function groupViolations(violations, elementLimit = 10) {
43
+ const byRule = new Map();
44
+ for (const v of violations) {
45
+ let g = byRule.get(v.ruleId);
46
+ if (!g) {
47
+ g = {
48
+ ruleId: v.ruleId,
49
+ severity: v.severity,
50
+ count: 0,
51
+ message: v.message,
52
+ fixHint: v.fixHint,
53
+ elementIds: [],
54
+ elementIdsOmitted: 0,
55
+ allElementIds: [],
56
+ };
57
+ byRule.set(v.ruleId, g);
58
+ }
59
+ g.count += 1;
60
+ if (v.elementId)
61
+ g.allElementIds.push(v.elementId);
62
+ }
63
+ return [...byRule.values()]
64
+ .sort((a, b) => b.count - a.count)
65
+ .map(({ allElementIds, ...g }) => ({
66
+ ...g,
67
+ elementIds: allElementIds.slice(0, Math.max(0, elementLimit)),
68
+ elementIdsOmitted: Math.max(0, allElementIds.length - Math.max(0, elementLimit)),
69
+ }));
70
+ }
30
71
  /**
31
72
  * The canonical INCOSE-tab artifact catalog (readiness-artifact-model.md §6). Renders are the
32
73
  * deterministic CR-GC-220 views; the 5 analysis ids are exactly CR-GC-221's creation keys
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigloch/graphcode-client",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -37,11 +37,11 @@
37
37
  "access": "public"
38
38
  },
39
39
  "peerDependencies": {
40
- "@sigloch/contracts": ">=5 <7",
40
+ "@sigloch/contracts": ">=5 <10",
41
41
  "@sigloch/graph-api-core": ">=5 <6"
42
42
  },
43
43
  "devDependencies": {
44
- "@sigloch/contracts": "^6.0.0",
44
+ "@sigloch/contracts": ">=6 <10",
45
45
  "@sigloch/graph-api-core": "^5.0.0"
46
46
  }
47
47
  }