slopbrick 0.40.0 → 0.42.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.
@@ -41124,23 +41124,16 @@ var builtinRules = [
41124
41124
  // src/rules/registry.ts
41125
41125
  var RuleRegistry = class {
41126
41126
  rules = /* @__PURE__ */ new Map();
41127
- register(ruleOrId, factory) {
41128
- if (typeof ruleOrId === "string") {
41129
- if (!factory) {
41130
- throw new Error("Factory is required when registering by id");
41131
- }
41132
- const rule = {
41133
- id: ruleOrId,
41134
- category: factory.category,
41135
- severity: factory.severity,
41136
- aiSpecific: factory.aiSpecific,
41137
- create: factory.create,
41138
- analyze: factory.analyze
41139
- };
41140
- this.rules.set(ruleOrId, rule);
41141
- } else {
41142
- this.rules.set(ruleOrId.id, ruleOrId);
41143
- }
41127
+ /**
41128
+ * Register a rule. The 2-arg overload `register(id, factory)` was
41129
+ * deleted in v0.42.0 (architecture review F6): no callers used it,
41130
+ * every `Rule` carries its own `id`, and the per-id registration
41131
+ * was ergonomically redundant with the 1-arg form (`register(rule)`).
41132
+ * External consumers that needed `register-by-id` semantics can
41133
+ * construct a `Rule` directly and pass it in.
41134
+ */
41135
+ register(rule) {
41136
+ this.rules.set(rule.id, rule);
41144
41137
  }
41145
41138
  loadBuiltins(onlyRuleId) {
41146
41139
  for (const rule of builtinRules) {
@@ -41169,6 +41162,15 @@ var RuleRegistry = class {
41169
41162
  all() {
41170
41163
  return Array.from(this.rules.values());
41171
41164
  }
41165
+ /** v0.42.0 (§3b.5): look up a registered rule by id.
41166
+ * Returns undefined if not registered. */
41167
+ get(id) {
41168
+ return this.rules.get(id);
41169
+ }
41170
+ /** v0.42.0 (§3b.5): check whether a rule id is registered. */
41171
+ has(id) {
41172
+ return this.rules.has(id);
41173
+ }
41172
41174
  createContexts(config, filePath, cwd, hotspotIssues = []) {
41173
41175
  const context = {
41174
41176
  config,
@@ -44863,6 +44865,36 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
44863
44865
  const issues = applyRuleOverrides(rawIssues, config.rules);
44864
44866
  const triggeredRuleIds = Array.from(new Set(issues.map((i) => i.ruleId)));
44865
44867
  const compScore = compositeScore(triggeredRuleIds, loadSignalStrength());
44868
+ const fireSet = new Set(triggeredRuleIds);
44869
+ const factsWithFireSet = Object.assign(facts, {
44870
+ compositeFireSet: fireSet
44871
+ });
44872
+ for (const { rule } of rules) {
44873
+ if (!rule.id.startsWith("composite/")) continue;
44874
+ try {
44875
+ const compositeIssues = rule.analyze(
44876
+ rule.create({
44877
+ config,
44878
+ filePath,
44879
+ cwd,
44880
+ framework: config.framework,
44881
+ uiLibraries: config.uiLibraries,
44882
+ hasTailwind: config.hasTailwind,
44883
+ supportsRsc: config.supportsRsc,
44884
+ hotspotIssues: []
44885
+ }),
44886
+ factsWithFireSet
44887
+ );
44888
+ if (compositeIssues.length > 0) {
44889
+ issues.push(...compositeIssues);
44890
+ for (const ci of compositeIssues) fireSet.add(ci.ruleId);
44891
+ }
44892
+ } catch (err) {
44893
+ if (process.env.SLOP_AUDIT_DEBUG === "1") {
44894
+ console.error(`[worker] composite ${rule.id} threw: ${err.message}`);
44895
+ }
44896
+ }
44897
+ }
44866
44898
  const gapValues = collectGapValues(facts);
44867
44899
  const styleSources = collectStyleSources(facts);
44868
44900
  const elementTags = facts.v2.jsx.elements.map((e) => e.tag);
@@ -41095,23 +41095,16 @@ var builtinRules = [
41095
41095
  // src/rules/registry.ts
41096
41096
  var RuleRegistry = class {
41097
41097
  rules = /* @__PURE__ */ new Map();
41098
- register(ruleOrId, factory) {
41099
- if (typeof ruleOrId === "string") {
41100
- if (!factory) {
41101
- throw new Error("Factory is required when registering by id");
41102
- }
41103
- const rule = {
41104
- id: ruleOrId,
41105
- category: factory.category,
41106
- severity: factory.severity,
41107
- aiSpecific: factory.aiSpecific,
41108
- create: factory.create,
41109
- analyze: factory.analyze
41110
- };
41111
- this.rules.set(ruleOrId, rule);
41112
- } else {
41113
- this.rules.set(ruleOrId.id, ruleOrId);
41114
- }
41098
+ /**
41099
+ * Register a rule. The 2-arg overload `register(id, factory)` was
41100
+ * deleted in v0.42.0 (architecture review F6): no callers used it,
41101
+ * every `Rule` carries its own `id`, and the per-id registration
41102
+ * was ergonomically redundant with the 1-arg form (`register(rule)`).
41103
+ * External consumers that needed `register-by-id` semantics can
41104
+ * construct a `Rule` directly and pass it in.
41105
+ */
41106
+ register(rule) {
41107
+ this.rules.set(rule.id, rule);
41115
41108
  }
41116
41109
  loadBuiltins(onlyRuleId) {
41117
41110
  for (const rule of builtinRules) {
@@ -41140,6 +41133,15 @@ var RuleRegistry = class {
41140
41133
  all() {
41141
41134
  return Array.from(this.rules.values());
41142
41135
  }
41136
+ /** v0.42.0 (§3b.5): look up a registered rule by id.
41137
+ * Returns undefined if not registered. */
41138
+ get(id) {
41139
+ return this.rules.get(id);
41140
+ }
41141
+ /** v0.42.0 (§3b.5): check whether a rule id is registered. */
41142
+ has(id) {
41143
+ return this.rules.has(id);
41144
+ }
41143
41145
  createContexts(config, filePath, cwd, hotspotIssues = []) {
41144
41146
  const context = {
41145
41147
  config,
@@ -44834,6 +44836,36 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
44834
44836
  const issues = applyRuleOverrides(rawIssues, config.rules);
44835
44837
  const triggeredRuleIds = Array.from(new Set(issues.map((i) => i.ruleId)));
44836
44838
  const compScore = compositeScore(triggeredRuleIds, loadSignalStrength());
44839
+ const fireSet = new Set(triggeredRuleIds);
44840
+ const factsWithFireSet = Object.assign(facts, {
44841
+ compositeFireSet: fireSet
44842
+ });
44843
+ for (const { rule } of rules) {
44844
+ if (!rule.id.startsWith("composite/")) continue;
44845
+ try {
44846
+ const compositeIssues = rule.analyze(
44847
+ rule.create({
44848
+ config,
44849
+ filePath,
44850
+ cwd,
44851
+ framework: config.framework,
44852
+ uiLibraries: config.uiLibraries,
44853
+ hasTailwind: config.hasTailwind,
44854
+ supportsRsc: config.supportsRsc,
44855
+ hotspotIssues: []
44856
+ }),
44857
+ factsWithFireSet
44858
+ );
44859
+ if (compositeIssues.length > 0) {
44860
+ issues.push(...compositeIssues);
44861
+ for (const ci of compositeIssues) fireSet.add(ci.ruleId);
44862
+ }
44863
+ } catch (err) {
44864
+ if (process.env.SLOP_AUDIT_DEBUG === "1") {
44865
+ console.error(`[worker] composite ${rule.id} threw: ${err.message}`);
44866
+ }
44867
+ }
44868
+ }
44837
44869
  const gapValues = collectGapValues(facts);
44838
44870
  const styleSources = collectStyleSources(facts);
44839
44871
  const elementTags = facts.v2.jsx.elements.map((e) => e.tag);