@skastr0/pulsar-rs-pack 0.1.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.
Files changed (189) hide show
  1. package/dist/cargo-metadata.d.ts +59 -0
  2. package/dist/cargo-metadata.d.ts.map +1 -0
  3. package/dist/cargo-metadata.js +162 -0
  4. package/dist/cargo-metadata.js.map +1 -0
  5. package/dist/index.d.ts +7 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +7 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/lock-file.d.ts +20 -0
  10. package/dist/lock-file.d.ts.map +1 -0
  11. package/dist/lock-file.js +144 -0
  12. package/dist/lock-file.js.map +1 -0
  13. package/dist/pack.d.ts +6 -0
  14. package/dist/pack.d.ts.map +1 -0
  15. package/dist/pack.js +55 -0
  16. package/dist/pack.js.map +1 -0
  17. package/dist/project.d.ts +26 -0
  18. package/dist/project.d.ts.map +1 -0
  19. package/dist/project.js +172 -0
  20. package/dist/project.js.map +1 -0
  21. package/dist/rust-analysis-collect.d.ts +4 -0
  22. package/dist/rust-analysis-collect.d.ts.map +1 -0
  23. package/dist/rust-analysis-collect.js +84 -0
  24. package/dist/rust-analysis-collect.js.map +1 -0
  25. package/dist/rust-analysis-functions.d.ts +4 -0
  26. package/dist/rust-analysis-functions.d.ts.map +1 -0
  27. package/dist/rust-analysis-functions.js +140 -0
  28. package/dist/rust-analysis-functions.js.map +1 -0
  29. package/dist/rust-analysis-identifiers.d.ts +3 -0
  30. package/dist/rust-analysis-identifiers.d.ts.map +1 -0
  31. package/dist/rust-analysis-identifiers.js +5 -0
  32. package/dist/rust-analysis-identifiers.js.map +1 -0
  33. package/dist/rust-analysis-items.d.ts +4 -0
  34. package/dist/rust-analysis-items.d.ts.map +1 -0
  35. package/dist/rust-analysis-items.js +58 -0
  36. package/dist/rust-analysis-items.js.map +1 -0
  37. package/dist/rust-analysis-modules.d.ts +7 -0
  38. package/dist/rust-analysis-modules.d.ts.map +1 -0
  39. package/dist/rust-analysis-modules.js +52 -0
  40. package/dist/rust-analysis-modules.js.map +1 -0
  41. package/dist/rust-analysis-syntax.d.ts +12 -0
  42. package/dist/rust-analysis-syntax.d.ts.map +1 -0
  43. package/dist/rust-analysis-syntax.js +102 -0
  44. package/dist/rust-analysis-syntax.js.map +1 -0
  45. package/dist/rust-analysis-types.d.ts +109 -0
  46. package/dist/rust-analysis-types.d.ts.map +1 -0
  47. package/dist/rust-analysis-types.js +2 -0
  48. package/dist/rust-analysis-types.js.map +1 -0
  49. package/dist/rust-analysis-uses.d.ts +4 -0
  50. package/dist/rust-analysis-uses.d.ts.map +1 -0
  51. package/dist/rust-analysis-uses.js +63 -0
  52. package/dist/rust-analysis-uses.js.map +1 -0
  53. package/dist/rust-analysis.d.ts +5 -0
  54. package/dist/rust-analysis.d.ts.map +1 -0
  55. package/dist/rust-analysis.js +4 -0
  56. package/dist/rust-analysis.js.map +1 -0
  57. package/dist/signals/rs-ab-01-unused-pub.d.ts +29 -0
  58. package/dist/signals/rs-ab-01-unused-pub.d.ts.map +1 -0
  59. package/dist/signals/rs-ab-01-unused-pub.js +184 -0
  60. package/dist/signals/rs-ab-01-unused-pub.js.map +1 -0
  61. package/dist/signals/rs-ab-02-trait-object-depth.d.ts +26 -0
  62. package/dist/signals/rs-ab-02-trait-object-depth.d.ts.map +1 -0
  63. package/dist/signals/rs-ab-02-trait-object-depth.js +157 -0
  64. package/dist/signals/rs-ab-02-trait-object-depth.js.map +1 -0
  65. package/dist/signals/rs-ab-03-generic-proliferation.d.ts +28 -0
  66. package/dist/signals/rs-ab-03-generic-proliferation.d.ts.map +1 -0
  67. package/dist/signals/rs-ab-03-generic-proliferation.js +108 -0
  68. package/dist/signals/rs-ab-03-generic-proliferation.js.map +1 -0
  69. package/dist/signals/rs-ab-04-derive-density.d.ts +25 -0
  70. package/dist/signals/rs-ab-04-derive-density.d.ts.map +1 -0
  71. package/dist/signals/rs-ab-04-derive-density.js +101 -0
  72. package/dist/signals/rs-ab-04-derive-density.js.map +1 -0
  73. package/dist/signals/rs-ad-01-visibility-surface.d.ts +29 -0
  74. package/dist/signals/rs-ad-01-visibility-surface.d.ts.map +1 -0
  75. package/dist/signals/rs-ad-01-visibility-surface.js +129 -0
  76. package/dist/signals/rs-ad-01-visibility-surface.js.map +1 -0
  77. package/dist/signals/rs-ad-02-boundary-rules.d.ts +3 -0
  78. package/dist/signals/rs-ad-02-boundary-rules.d.ts.map +1 -0
  79. package/dist/signals/rs-ad-02-boundary-rules.js +26 -0
  80. package/dist/signals/rs-ad-02-boundary-rules.js.map +1 -0
  81. package/dist/signals/rs-ad-02-crate-analysis.d.ts +9 -0
  82. package/dist/signals/rs-ad-02-crate-analysis.d.ts.map +1 -0
  83. package/dist/signals/rs-ad-02-crate-analysis.js +117 -0
  84. package/dist/signals/rs-ad-02-crate-analysis.js.map +1 -0
  85. package/dist/signals/rs-ad-02-crate-boundaries.d.ts +6 -0
  86. package/dist/signals/rs-ad-02-crate-boundaries.d.ts.map +1 -0
  87. package/dist/signals/rs-ad-02-crate-boundaries.js +84 -0
  88. package/dist/signals/rs-ad-02-crate-boundaries.js.map +1 -0
  89. package/dist/signals/rs-ad-02-types.d.ts +26 -0
  90. package/dist/signals/rs-ad-02-types.d.ts.map +1 -0
  91. package/dist/signals/rs-ad-02-types.js +6 -0
  92. package/dist/signals/rs-ad-02-types.js.map +1 -0
  93. package/dist/signals/rs-ad-03-circular-crate-deps.d.ts +30 -0
  94. package/dist/signals/rs-ad-03-circular-crate-deps.d.ts.map +1 -0
  95. package/dist/signals/rs-ad-03-circular-crate-deps.js +185 -0
  96. package/dist/signals/rs-ad-03-circular-crate-deps.js.map +1 -0
  97. package/dist/signals/rs-de-01-trait-coupling.d.ts +43 -0
  98. package/dist/signals/rs-de-01-trait-coupling.d.ts.map +1 -0
  99. package/dist/signals/rs-de-01-trait-coupling.js +222 -0
  100. package/dist/signals/rs-de-01-trait-coupling.js.map +1 -0
  101. package/dist/signals/rs-de-02-dep-tree.d.ts +28 -0
  102. package/dist/signals/rs-de-02-dep-tree.d.ts.map +1 -0
  103. package/dist/signals/rs-de-02-dep-tree.js +173 -0
  104. package/dist/signals/rs-de-02-dep-tree.js.map +1 -0
  105. package/dist/signals/rs-de-03-feature-flags.d.ts +32 -0
  106. package/dist/signals/rs-de-03-feature-flags.d.ts.map +1 -0
  107. package/dist/signals/rs-de-03-feature-flags.js +139 -0
  108. package/dist/signals/rs-de-03-feature-flags.js.map +1 -0
  109. package/dist/signals/rs-de-04-fan-in-fan-out.d.ts +28 -0
  110. package/dist/signals/rs-de-04-fan-in-fan-out.d.ts.map +1 -0
  111. package/dist/signals/rs-de-04-fan-in-fan-out.js +109 -0
  112. package/dist/signals/rs-de-04-fan-in-fan-out.js.map +1 -0
  113. package/dist/signals/rs-ld-01-unsafe.d.ts +28 -0
  114. package/dist/signals/rs-ld-01-unsafe.d.ts.map +1 -0
  115. package/dist/signals/rs-ld-01-unsafe.js +116 -0
  116. package/dist/signals/rs-ld-01-unsafe.js.map +1 -0
  117. package/dist/signals/rs-ld-02-lifetimes.d.ts +30 -0
  118. package/dist/signals/rs-ld-02-lifetimes.d.ts.map +1 -0
  119. package/dist/signals/rs-ld-02-lifetimes.js +79 -0
  120. package/dist/signals/rs-ld-02-lifetimes.js.map +1 -0
  121. package/dist/signals/rs-ld-03-match-catch-all.d.ts +26 -0
  122. package/dist/signals/rs-ld-03-match-catch-all.d.ts.map +1 -0
  123. package/dist/signals/rs-ld-03-match-catch-all.js +68 -0
  124. package/dist/signals/rs-ld-03-match-catch-all.js.map +1 -0
  125. package/dist/signals/rs-ld-04-error-granularity.d.ts +25 -0
  126. package/dist/signals/rs-ld-04-error-granularity.d.ts.map +1 -0
  127. package/dist/signals/rs-ld-04-error-granularity.js +77 -0
  128. package/dist/signals/rs-ld-04-error-granularity.js.map +1 -0
  129. package/dist/signals/rs-ld-05-complexity.d.ts +26 -0
  130. package/dist/signals/rs-ld-05-complexity.d.ts.map +1 -0
  131. package/dist/signals/rs-ld-05-complexity.js +70 -0
  132. package/dist/signals/rs-ld-05-complexity.js.map +1 -0
  133. package/dist/signals/rs-ld-06-domain-terms.d.ts +29 -0
  134. package/dist/signals/rs-ld-06-domain-terms.d.ts.map +1 -0
  135. package/dist/signals/rs-ld-06-domain-terms.js +158 -0
  136. package/dist/signals/rs-ld-06-domain-terms.js.map +1 -0
  137. package/dist/signals/rs-rp-01-hotspots.d.ts +27 -0
  138. package/dist/signals/rs-rp-01-hotspots.d.ts.map +1 -0
  139. package/dist/signals/rs-rp-01-hotspots.js +110 -0
  140. package/dist/signals/rs-rp-01-hotspots.js.map +1 -0
  141. package/dist/signals/rs-rp-02-compile-time.d.ts +25 -0
  142. package/dist/signals/rs-rp-02-compile-time.d.ts.map +1 -0
  143. package/dist/signals/rs-rp-02-compile-time.js +177 -0
  144. package/dist/signals/rs-rp-02-compile-time.js.map +1 -0
  145. package/dist/signals/rs-rp-03-pr-size.d.ts +23 -0
  146. package/dist/signals/rs-rp-03-pr-size.d.ts.map +1 -0
  147. package/dist/signals/rs-rp-03-pr-size.js +160 -0
  148. package/dist/signals/rs-rp-03-pr-size.js.map +1 -0
  149. package/dist/signals/rs-sl-01-duplication.d.ts +28 -0
  150. package/dist/signals/rs-sl-01-duplication.d.ts.map +1 -0
  151. package/dist/signals/rs-sl-01-duplication.js +172 -0
  152. package/dist/signals/rs-sl-01-duplication.js.map +1 -0
  153. package/dist/signals/rs-sl-02-suppressions.d.ts +30 -0
  154. package/dist/signals/rs-sl-02-suppressions.d.ts.map +1 -0
  155. package/dist/signals/rs-sl-02-suppressions.js +176 -0
  156. package/dist/signals/rs-sl-02-suppressions.js.map +1 -0
  157. package/dist/signals/rs-sl-03-unwrap-expect.d.ts +22 -0
  158. package/dist/signals/rs-sl-03-unwrap-expect.d.ts.map +1 -0
  159. package/dist/signals/rs-sl-03-unwrap-expect.js +94 -0
  160. package/dist/signals/rs-sl-03-unwrap-expect.js.map +1 -0
  161. package/dist/signals/rs-sl-04-clone-abuse.d.ts +22 -0
  162. package/dist/signals/rs-sl-04-clone-abuse.d.ts.map +1 -0
  163. package/dist/signals/rs-sl-04-clone-abuse.js +115 -0
  164. package/dist/signals/rs-sl-04-clone-abuse.js.map +1 -0
  165. package/dist/signals/shared-globs.d.ts +4 -0
  166. package/dist/signals/shared-globs.d.ts.map +1 -0
  167. package/dist/signals/shared-globs.js +12 -0
  168. package/dist/signals/shared-globs.js.map +1 -0
  169. package/dist/signals/shared-record-guards.d.ts +4 -0
  170. package/dist/signals/shared-record-guards.d.ts.map +1 -0
  171. package/dist/signals/shared-record-guards.js +4 -0
  172. package/dist/signals/shared-record-guards.js.map +1 -0
  173. package/dist/signals/shared-rust-ast.d.ts +30 -0
  174. package/dist/signals/shared-rust-ast.d.ts.map +1 -0
  175. package/dist/signals/shared-rust-ast.js +78 -0
  176. package/dist/signals/shared-rust-ast.js.map +1 -0
  177. package/dist/signals/shared-rust-resolution.d.ts +10 -0
  178. package/dist/signals/shared-rust-resolution.d.ts.map +1 -0
  179. package/dist/signals/shared-rust-resolution.js +53 -0
  180. package/dist/signals/shared-rust-resolution.js.map +1 -0
  181. package/dist/signals/shared-threshold-score.d.ts +2 -0
  182. package/dist/signals/shared-threshold-score.d.ts.map +1 -0
  183. package/dist/signals/shared-threshold-score.js +6 -0
  184. package/dist/signals/shared-threshold-score.js.map +1 -0
  185. package/dist/syn-walker.d.ts +7 -0
  186. package/dist/syn-walker.d.ts.map +1 -0
  187. package/dist/syn-walker.js +61 -0
  188. package/dist/syn-walker.js.map +1 -0
  189. package/package.json +56 -0
@@ -0,0 +1,77 @@
1
+ import { SignalComputeError, } from "@skastr0/pulsar-core/signal";
2
+ import { Effect, Schema } from "effect";
3
+ import { collectRustProjectFacts } from "../rust-analysis.js";
4
+ import { RustProjectTag } from "../project.js";
5
+ import { isExcluded } from "./shared-globs.js";
6
+ const RsLd04Config = Schema.Struct({
7
+ exclude_globs: Schema.Array(Schema.String),
8
+ top_n_diagnostics: Schema.Number,
9
+ });
10
+ export const RsLd04 = {
11
+ id: "RS-LD-04-error-granularity",
12
+ title: "Error granularity",
13
+ aliases: ["RS-LD-04"],
14
+ tier: 1,
15
+ category: "legibility-decay",
16
+ kind: "legibility",
17
+ configSchema: RsLd04Config,
18
+ defaultConfig: {
19
+ exclude_globs: ["**/target/**", "**/tests/**", "**/examples/**", "**/benches/**"],
20
+ top_n_diagnostics: 10,
21
+ },
22
+ inputs: [],
23
+ compute: (config) => Effect.gen(function* () {
24
+ const project = yield* RustProjectTag;
25
+ return yield* Effect.tryPromise({
26
+ try: async () => {
27
+ const facts = await collectRustProjectFacts(project);
28
+ const boundaryFunctions = facts.functions
29
+ .filter((fn) => !isExcluded(fn.file, config.exclude_globs))
30
+ .filter((fn) => fn.visibility.kind !== "private")
31
+ .filter((fn) => fn.resultErrorType !== undefined)
32
+ .map((fn) => ({
33
+ file: fn.file,
34
+ module: fn.modulePath,
35
+ name: fn.name,
36
+ line: fn.line,
37
+ errorType: fn.resultErrorType,
38
+ classification: classifyErrorType(fn.resultErrorType),
39
+ }))
40
+ .sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
41
+ return {
42
+ granularCount: boundaryFunctions.filter((fn) => fn.classification === "granular").length,
43
+ collapsedCount: boundaryFunctions.filter((fn) => fn.classification === "collapsed").length,
44
+ totalBoundaryResults: boundaryFunctions.length,
45
+ boundaryFunctions,
46
+ };
47
+ },
48
+ catch: (cause) => new SignalComputeError({ signalId: "RS-LD-04-error-granularity", message: String(cause), cause }),
49
+ });
50
+ }),
51
+ score: (out) => {
52
+ if (out.totalBoundaryResults === 0)
53
+ return 1;
54
+ return out.granularCount / out.totalBoundaryResults;
55
+ },
56
+ diagnose: (out) => out.boundaryFunctions
57
+ .filter((fn) => fn.classification === "collapsed")
58
+ .slice(0, 10)
59
+ .map((fn) => ({
60
+ severity: "warn",
61
+ message: `Boundary function ${fn.name} returns collapsed error type ${fn.errorType}`,
62
+ location: { file: fn.file, line: fn.line },
63
+ data: { ...fn },
64
+ })),
65
+ };
66
+ const classifyErrorType = (errorType) => {
67
+ const normalized = errorType.replace(/\s+/g, "");
68
+ if (normalized === "anyhow::Error" ||
69
+ normalized === "String" ||
70
+ normalized === "&'staticstr" ||
71
+ /Box<dyn.*Error.*>/.test(normalized) ||
72
+ /dyn.*Error/.test(normalized)) {
73
+ return "collapsed";
74
+ }
75
+ return "granular";
76
+ };
77
+ //# sourceMappingURL=rs-ld-04-error-granularity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rs-ld-04-error-granularity.js","sourceRoot":"","sources":["../../src/signals/rs-ld-04-error-granularity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type DistributionalSummary, type Signal } from "@skastr0/pulsar-core/signal";
2
+ import { Schema } from "effect";
3
+ import { RustProjectTag } from "../project.js";
4
+ declare const RsLd05Config: Schema.Struct<{
5
+ exclude_globs: Schema.Array$<typeof Schema.String>;
6
+ max_complexity: typeof Schema.Number;
7
+ top_n_diagnostics: typeof Schema.Number;
8
+ }>;
9
+ type RsLd05Config = typeof RsLd05Config.Type;
10
+ interface RustFunctionComplexity {
11
+ readonly file: string;
12
+ readonly module: string;
13
+ readonly name: string;
14
+ readonly line: number;
15
+ readonly complexity: number;
16
+ }
17
+ interface RsLd05Output {
18
+ readonly functions: ReadonlyArray<RustFunctionComplexity>;
19
+ readonly byFile: ReadonlyMap<string, DistributionalSummary>;
20
+ readonly overThresholdCount: number;
21
+ readonly totalFunctions: number;
22
+ readonly analysisMode: "standard-cyclomatic";
23
+ }
24
+ export declare const RsLd05: Signal<RsLd05Config, RsLd05Output, RustProjectTag>;
25
+ export {};
26
+ //# sourceMappingURL=rs-ld-05-complexity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rs-ld-05-complexity.d.ts","sourceRoot":"","sources":["../../src/signals/rs-ld-05-complexity.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EAGZ,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAI9C,QAAA,MAAM,YAAY;;;;EAIhB,CAAA;AACF,KAAK,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAE5C,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAA;IACzD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAA;IAC3D,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,YAAY,EAAE,qBAAqB,CAAA;CAC7C;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,CA8DrE,CAAA"}
@@ -0,0 +1,70 @@
1
+ import { SignalComputeError, summarize, } from "@skastr0/pulsar-core/signal";
2
+ import { Effect, Schema } from "effect";
3
+ import { collectRustProjectFacts } from "../rust-analysis.js";
4
+ import { RustProjectTag } from "../project.js";
5
+ import { isExcluded } from "./shared-globs.js";
6
+ import { scoreDoubleWeightedThresholdRatio } from "./shared-threshold-score.js";
7
+ const RsLd05Config = Schema.Struct({
8
+ exclude_globs: Schema.Array(Schema.String),
9
+ max_complexity: Schema.Number,
10
+ top_n_diagnostics: Schema.Number,
11
+ });
12
+ export const RsLd05 = {
13
+ id: "RS-LD-05-cyclomatic-complexity",
14
+ title: "Cyclomatic complexity",
15
+ aliases: ["RS-LD-05"],
16
+ tier: 1,
17
+ category: "legibility-decay",
18
+ kind: "legibility",
19
+ configSchema: RsLd05Config,
20
+ defaultConfig: {
21
+ exclude_globs: ["**/target/**", "**/tests/**", "**/examples/**", "**/benches/**"],
22
+ max_complexity: 10,
23
+ top_n_diagnostics: 10,
24
+ },
25
+ inputs: [],
26
+ compute: (config) => Effect.gen(function* () {
27
+ const project = yield* RustProjectTag;
28
+ return yield* Effect.tryPromise({
29
+ try: async () => {
30
+ const facts = await collectRustProjectFacts(project);
31
+ const functions = facts.functions
32
+ .filter((fn) => !isExcluded(fn.file, config.exclude_globs))
33
+ .map((fn) => ({
34
+ file: fn.file,
35
+ module: fn.modulePath,
36
+ name: fn.name,
37
+ line: fn.line,
38
+ complexity: fn.complexity,
39
+ }))
40
+ .sort((a, b) => b.complexity - a.complexity || a.file.localeCompare(b.file));
41
+ const byFileValues = new Map();
42
+ for (const fn of functions) {
43
+ const bucket = byFileValues.get(fn.file) ?? [];
44
+ bucket.push(fn.complexity);
45
+ byFileValues.set(fn.file, bucket);
46
+ }
47
+ const byFile = new Map();
48
+ for (const [file, values] of byFileValues) {
49
+ byFile.set(file, summarize(values));
50
+ }
51
+ return {
52
+ functions,
53
+ byFile,
54
+ overThresholdCount: functions.filter((fn) => fn.complexity > config.max_complexity).length,
55
+ totalFunctions: functions.length,
56
+ analysisMode: "standard-cyclomatic",
57
+ };
58
+ },
59
+ catch: (cause) => new SignalComputeError({ signalId: "RS-LD-05-cyclomatic-complexity", message: String(cause), cause }),
60
+ });
61
+ }),
62
+ score: (out) => scoreDoubleWeightedThresholdRatio(out.overThresholdCount, out.totalFunctions),
63
+ diagnose: (out) => out.functions.slice(0, 10).map((fn) => ({
64
+ severity: fn.complexity > 10 ? "warn" : "info",
65
+ message: `Function ${fn.name} has cyclomatic complexity ${fn.complexity}`,
66
+ location: { file: fn.file, line: fn.line },
67
+ data: { ...fn, analysisMode: out.analysisMode },
68
+ })),
69
+ };
70
+ //# sourceMappingURL=rs-ld-05-complexity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rs-ld-05-complexity.js","sourceRoot":"","sources":["../../src/signals/rs-ld-05-complexity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type Signal } from "@skastr0/pulsar-core/signal";
2
+ import { ReferenceDataTag } from "@skastr0/pulsar-core/reference-data";
3
+ import { Schema } from "effect";
4
+ import { RustProjectTag } from "../project.js";
5
+ declare const RsLd06Config: Schema.Struct<{
6
+ exclude_globs: Schema.Array$<typeof Schema.String>;
7
+ top_n_diagnostics: typeof Schema.Number;
8
+ }>;
9
+ type RsLd06Config = typeof RsLd06Config.Type;
10
+ type IdentifierClassification = "matches-glossary" | "new-unique" | "duplicates-canonical" | "conflicts-with-canonical";
11
+ interface IdentifierGlossaryMatch {
12
+ readonly file: string;
13
+ readonly module: string;
14
+ readonly name: string;
15
+ readonly line: number;
16
+ readonly classification: IdentifierClassification;
17
+ readonly suggestedCanonical: string | undefined;
18
+ }
19
+ interface RsLd06Output {
20
+ readonly identifiers: ReadonlyArray<IdentifierGlossaryMatch>;
21
+ readonly matchCount: number;
22
+ readonly newUniqueCount: number;
23
+ readonly duplicateCount: number;
24
+ readonly conflictCount: number;
25
+ readonly referenceDataStatus: "loaded" | "missing";
26
+ }
27
+ export declare const RsLd06: Signal<RsLd06Config, RsLd06Output, RustProjectTag | ReferenceDataTag>;
28
+ export {};
29
+ //# sourceMappingURL=rs-ld-06-domain-terms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rs-ld-06-domain-terms.d.ts","sourceRoot":"","sources":["../../src/signals/rs-ld-06-domain-terms.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,MAAM,EAEZ,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;AACtE,OAAO,EAGL,MAAM,EACP,MAAM,QAAQ,CAAA;AAEf,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAI9C,QAAA,MAAM,YAAY;;;EAGhB,CAAA;AACF,KAAK,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAE5C,KAAK,wBAAwB,GACzB,kBAAkB,GAClB,YAAY,GACZ,sBAAsB,GACtB,0BAA0B,CAAA;AAE9B,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,cAAc,EAAE,wBAAwB,CAAA;IACjD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAA;CAChD;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAA;IAC5D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,GAAG,SAAS,CAAA;CACnD;AAOD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,GAAG,gBAAgB,CAiFxF,CAAA"}
@@ -0,0 +1,158 @@
1
+ import { levenshteinDistance, SignalComputeError, } from "@skastr0/pulsar-core/signal";
2
+ import { ReferenceDataTag } from "@skastr0/pulsar-core/reference-data";
3
+ import { Option, Effect, Schema, } from "effect";
4
+ import { collectRustProjectFacts, tokenizeIdentifier } from "../rust-analysis.js";
5
+ import { RustProjectTag } from "../project.js";
6
+ import { isExcluded } from "./shared-globs.js";
7
+ import { asUnknownRecord } from "./shared-record-guards.js";
8
+ const RsLd06Config = Schema.Struct({
9
+ exclude_globs: Schema.Array(Schema.String),
10
+ top_n_diagnostics: Schema.Number,
11
+ });
12
+ export const RsLd06 = {
13
+ id: "RS-LD-06-domain-term-consistency",
14
+ title: "Domain term consistency",
15
+ aliases: ["RS-LD-06"],
16
+ tier: 2,
17
+ category: "legibility-decay",
18
+ kind: "legibility",
19
+ configSchema: RsLd06Config,
20
+ defaultConfig: {
21
+ exclude_globs: ["**/target/**", "**/tests/**", "**/examples/**", "**/benches/**"],
22
+ top_n_diagnostics: 10,
23
+ },
24
+ inputs: [],
25
+ compute: (config) => Effect.gen(function* () {
26
+ const project = yield* RustProjectTag;
27
+ const referenceData = yield* ReferenceDataTag;
28
+ return yield* Effect.tryPromise({
29
+ try: async () => {
30
+ const facts = await collectRustProjectFacts(project);
31
+ const identifiers = facts.identifiers.filter((identifier) => !isExcluded(identifier.file, config.exclude_globs));
32
+ const rawGlossary = await Effect.runPromise(referenceData.get("glossary"));
33
+ if (Option.isNone(rawGlossary)) {
34
+ return {
35
+ identifiers: [],
36
+ matchCount: 0,
37
+ newUniqueCount: 0,
38
+ duplicateCount: 0,
39
+ conflictCount: 0,
40
+ referenceDataStatus: "missing",
41
+ };
42
+ }
43
+ const glossary = normalizeGlossary(rawGlossary.value);
44
+ const classified = identifiers.map((identifier) => classifyIdentifier(identifier.name, glossary, {
45
+ file: identifier.file,
46
+ module: identifier.modulePath,
47
+ line: identifier.line,
48
+ }));
49
+ return {
50
+ identifiers: classified,
51
+ matchCount: classified.filter((item) => item.classification === "matches-glossary").length,
52
+ newUniqueCount: classified.filter((item) => item.classification === "new-unique").length,
53
+ duplicateCount: classified.filter((item) => item.classification === "duplicates-canonical").length,
54
+ conflictCount: classified.filter((item) => item.classification === "conflicts-with-canonical").length,
55
+ referenceDataStatus: "loaded",
56
+ };
57
+ },
58
+ catch: (cause) => new SignalComputeError({ signalId: "RS-LD-06-domain-term-consistency", message: String(cause), cause }),
59
+ });
60
+ }),
61
+ score: (out) => {
62
+ const total = out.identifiers.length;
63
+ if (total === 0)
64
+ return 1;
65
+ const penalty = out.conflictCount * 0.8 + out.duplicateCount * 0.5 + out.newUniqueCount * 0.2;
66
+ return Math.max(0, 1 - penalty / total);
67
+ },
68
+ diagnose: (out) => {
69
+ if (out.referenceDataStatus === "missing") {
70
+ return [
71
+ {
72
+ severity: "warn",
73
+ message: "RS-LD-06 requires glossary reference data; no glossary was loaded",
74
+ },
75
+ ];
76
+ }
77
+ return out.identifiers
78
+ .filter((identifier) => identifier.classification !== "matches-glossary")
79
+ .slice(0, 10)
80
+ .map((identifier) => ({
81
+ severity: identifier.classification === "conflicts-with-canonical" ? "warn" : "info",
82
+ message: `Identifier ${identifier.name} classified as ${identifier.classification}${identifier.suggestedCanonical ? ` (suggested: ${identifier.suggestedCanonical})` : ""}`,
83
+ location: { file: identifier.file, line: identifier.line },
84
+ data: { ...identifier },
85
+ }));
86
+ },
87
+ };
88
+ const normalizeGlossary = (raw) => {
89
+ if (Array.isArray(raw)) {
90
+ return raw.flatMap((entry) => normalizeGlossaryEntry(entry));
91
+ }
92
+ const record = asUnknownRecord(raw);
93
+ if (record === undefined)
94
+ return [];
95
+ if (Array.isArray(record.terms)) {
96
+ return record.terms.flatMap((entry) => normalizeGlossaryEntry(entry));
97
+ }
98
+ if (Array.isArray(record.canonical_terms)) {
99
+ return record.canonical_terms.flatMap((entry) => normalizeGlossaryEntry(entry));
100
+ }
101
+ return Object.entries(record).flatMap(([canonical, aliases]) => normalizeGlossaryEntry({ canonical, aliases }));
102
+ };
103
+ const normalizeGlossaryEntry = (entry) => {
104
+ if (typeof entry === "string") {
105
+ return [{ canonical: entry, aliases: [] }];
106
+ }
107
+ const record = asUnknownRecord(entry);
108
+ if (record === undefined || typeof record.canonical !== "string")
109
+ return [];
110
+ return [
111
+ {
112
+ canonical: record.canonical,
113
+ aliases: Array.isArray(record.aliases) && record.aliases.every((alias) => typeof alias === "string")
114
+ ? record.aliases
115
+ : [],
116
+ },
117
+ ];
118
+ };
119
+ const classifyIdentifier = (name, glossary, context) => {
120
+ const tokens = tokenizeIdentifier(name);
121
+ const normalized = tokens.join(" ");
122
+ const knownPhrases = new Set(glossary.flatMap((entry) => [entry.canonical, ...entry.aliases]).map((value) => tokenizeIdentifier(value).join(" ")));
123
+ const canonicalBySortedTokens = new Map(glossary.map((entry) => [sortTokens(entry.canonical), entry.canonical]));
124
+ const knownTokens = new Set(glossary.flatMap((entry) => tokenizeIdentifier(entry.canonical)).filter((token) => token.length > 0));
125
+ const unknownTokens = tokens.filter((token) => !knownTokens.has(token));
126
+ let classification = "new-unique";
127
+ let suggestedCanonical;
128
+ if (knownPhrases.has(normalized)) {
129
+ classification = "matches-glossary";
130
+ }
131
+ else {
132
+ const duplicateCanonical = canonicalBySortedTokens.get(sortTokens(name));
133
+ if (duplicateCanonical !== undefined) {
134
+ classification = "duplicates-canonical";
135
+ suggestedCanonical = duplicateCanonical;
136
+ }
137
+ else if (tokens.every((token) => knownTokens.has(token))) {
138
+ classification = "matches-glossary";
139
+ }
140
+ else {
141
+ const conflicting = glossary.find((entry) => unknownTokens.some((candidate) => tokenizeIdentifier(entry.canonical).some((token) => levenshteinDistance(token, candidate) <= 1)));
142
+ if (conflicting !== undefined) {
143
+ classification = "conflicts-with-canonical";
144
+ suggestedCanonical = conflicting.canonical;
145
+ }
146
+ }
147
+ }
148
+ return {
149
+ file: context.file,
150
+ module: context.module,
151
+ name,
152
+ line: context.line,
153
+ classification,
154
+ suggestedCanonical,
155
+ };
156
+ };
157
+ const sortTokens = (value) => tokenizeIdentifier(value).slice().sort().join(" ");
158
+ //# sourceMappingURL=rs-ld-06-domain-terms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rs-ld-06-domain-terms.js","sourceRoot":"","sources":["../../src/signals/rs-ld-06-domain-terms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type Signal } from "@skastr0/pulsar-core/signal";
2
+ import { Schema } from "effect";
3
+ declare const RsRp01Config: Schema.Struct<{
4
+ top_n: typeof Schema.Number;
5
+ min_churn: typeof Schema.Number;
6
+ min_complexity: typeof Schema.Number;
7
+ }>;
8
+ type RsRp01Config = typeof RsRp01Config.Type;
9
+ type RustQuadrant = "top-right" | "top-left" | "bottom-right" | "bottom-left";
10
+ interface RustHotspot {
11
+ readonly file: string;
12
+ readonly churn: number;
13
+ readonly complexity: number;
14
+ readonly hotspotScore: number;
15
+ readonly quadrant: RustQuadrant;
16
+ readonly rank: number;
17
+ }
18
+ type RsRp01Output = {
19
+ readonly hotspots: ReadonlyArray<RustHotspot>;
20
+ readonly totalFilesConsidered: number;
21
+ readonly topRightShare: number;
22
+ readonly medianChurn: number;
23
+ readonly medianComplexity: number;
24
+ };
25
+ export declare const RsRp01: Signal<RsRp01Config, RsRp01Output, never>;
26
+ export {};
27
+ //# sourceMappingURL=rs-rp-01-hotspots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rs-rp-01-hotspots.d.ts","sourceRoot":"","sources":["../../src/signals/rs-rp-01-hotspots.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EACZ,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvC,QAAA,MAAM,YAAY;;;;EAIhB,CAAA;AACF,KAAK,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAE5C,KAAK,YAAY,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,aAAa,CAAA;AAE7E,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,KAAK,YAAY,GAAG;IAClB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;IAC7C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;CAClC,CAAA;AAMD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,CAwF5D,CAAA"}
@@ -0,0 +1,110 @@
1
+ import { Effect, Schema } from "effect";
2
+ const RsRp01Config = Schema.Struct({
3
+ top_n: Schema.Number,
4
+ min_churn: Schema.Number,
5
+ min_complexity: Schema.Number,
6
+ });
7
+ export const RsRp01 = {
8
+ id: "RS-RP-01-hotspots",
9
+ title: "Hotspots",
10
+ aliases: ["RS-RP-01"],
11
+ tier: 1.5,
12
+ category: "review-pain",
13
+ kind: "compound",
14
+ configSchema: RsRp01Config,
15
+ defaultConfig: {
16
+ top_n: 10,
17
+ min_churn: 2,
18
+ min_complexity: 5,
19
+ },
20
+ inputs: [
21
+ { id: "RS-LD-05-cyclomatic-complexity" },
22
+ { id: "SHARED-CHURN-01-recent-churn" },
23
+ ],
24
+ compute: (config, inputs) => Effect.sync(() => {
25
+ const complexity = (inputs.get("RS-LD-05-cyclomatic-complexity") ??
26
+ inputs.get("RS-LD-05"));
27
+ const churn = (inputs.get("SHARED-CHURN-01-recent-churn") ??
28
+ inputs.get("SHARED-CHURN-01"));
29
+ if (complexity === undefined || churn === undefined) {
30
+ return {
31
+ hotspots: [],
32
+ totalFilesConsidered: 0,
33
+ topRightShare: 0,
34
+ medianChurn: 0,
35
+ medianComplexity: 0,
36
+ };
37
+ }
38
+ const files = new Map();
39
+ for (const [file, summary] of complexity.byFile) {
40
+ const cplx = summary.max;
41
+ const fileChurn = churn.byFile.get(file) ?? 0;
42
+ if (fileChurn < config.min_churn || cplx < config.min_complexity)
43
+ continue;
44
+ files.set(file, { churn: fileChurn, complexity: cplx });
45
+ }
46
+ const churnValues = [...files.values()].map((entry) => entry.churn);
47
+ const complexityValues = [...files.values()].map((entry) => entry.complexity);
48
+ const medChurn = median(churnValues);
49
+ const medComplexity = median(complexityValues);
50
+ const hotspots = [...files.entries()]
51
+ .map(([file, entry]) => ({
52
+ file,
53
+ churn: entry.churn,
54
+ complexity: entry.complexity,
55
+ hotspotScore: entry.churn * entry.complexity,
56
+ quadrant: classifyQuadrant(entry.churn, entry.complexity, medChurn, medComplexity),
57
+ rank: 0,
58
+ }))
59
+ .sort((left, right) => right.hotspotScore - left.hotspotScore)
60
+ .map((entry, index) => ({ ...entry, rank: index + 1 }));
61
+ const topRightShare = hotspots.length === 0
62
+ ? 0
63
+ : hotspots.filter((entry) => entry.quadrant === "top-right").length / hotspots.length;
64
+ return {
65
+ hotspots,
66
+ totalFilesConsidered: hotspots.length,
67
+ topRightShare,
68
+ medianChurn: medChurn,
69
+ medianComplexity: medComplexity,
70
+ };
71
+ }),
72
+ score: (out) => {
73
+ if (out.totalFilesConsidered === 0)
74
+ return 1;
75
+ return Math.max(0, 1 - out.topRightShare * 1.5);
76
+ },
77
+ diagnose: (out) => out.hotspots.slice(0, 10).map((entry) => ({
78
+ severity: entry.quadrant === "top-right" ? "warn" : "info",
79
+ message: `Hotspot #${entry.rank}: ${entry.file} (churn=${entry.churn}, complexity=${entry.complexity.toFixed(1)})`,
80
+ location: { file: entry.file },
81
+ data: {
82
+ churn: entry.churn,
83
+ complexity: entry.complexity,
84
+ hotspotScore: entry.hotspotScore,
85
+ quadrant: entry.quadrant,
86
+ rank: entry.rank,
87
+ },
88
+ })),
89
+ };
90
+ const median = (values) => {
91
+ if (values.length === 0)
92
+ return 0;
93
+ const sorted = [...values].sort((left, right) => left - right);
94
+ const middle = Math.floor(sorted.length / 2);
95
+ return sorted.length % 2 === 0
96
+ ? ((sorted[middle - 1] ?? 0) + (sorted[middle] ?? 0)) / 2
97
+ : (sorted[middle] ?? 0);
98
+ };
99
+ const classifyQuadrant = (churn, complexity, medianChurn, medianComplexity) => {
100
+ const highChurn = churn > medianChurn;
101
+ const highComplexity = complexity > medianComplexity;
102
+ if (highChurn && highComplexity)
103
+ return "top-right";
104
+ if (highChurn)
105
+ return "top-left";
106
+ if (highComplexity)
107
+ return "bottom-right";
108
+ return "bottom-left";
109
+ };
110
+ //# sourceMappingURL=rs-rp-01-hotspots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rs-rp-01-hotspots.js","sourceRoot":"","sources":["../../src/signals/rs-rp-01-hotspots.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type Signal } from "@skastr0/pulsar-core/signal";
2
+ import { Schema } from "effect";
3
+ import { RustProjectTag } from "../project.js";
4
+ declare const RsRp02Config: Schema.Struct<{
5
+ top_n_diagnostics: typeof Schema.Number;
6
+ measure_live_builds: typeof Schema.Boolean;
7
+ }>;
8
+ type RsRp02Config = typeof RsRp02Config.Type;
9
+ interface CompileTimingCrate {
10
+ readonly crate: string;
11
+ readonly totalDurationMs: number;
12
+ readonly unitCount: number;
13
+ readonly cascadeImpact: number;
14
+ readonly incrementalCacheHitRate: number | undefined;
15
+ }
16
+ interface RsRp02Output {
17
+ readonly crates: ReadonlyArray<CompileTimingCrate>;
18
+ readonly totalUnits: number;
19
+ readonly buildStatus: "measured" | "unavailable";
20
+ readonly timingSource: "cargo-timings-html";
21
+ readonly cacheProbeMode: "noop-second-build" | "unavailable";
22
+ }
23
+ export declare const RsRp02: Signal<RsRp02Config, RsRp02Output, RustProjectTag>;
24
+ export {};
25
+ //# sourceMappingURL=rs-rp-02-compile-time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rs-rp-02-compile-time.d.ts","sourceRoot":"","sources":["../../src/signals/rs-rp-02-compile-time.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EAEZ,MAAM,6BAA6B,CAAA;AAQpC,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,cAAc,EAAyB,MAAM,eAAe,CAAA;AAIrE,QAAA,MAAM,YAAY;;;EAGhB,CAAA;AACF,KAAK,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAa5C,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAA;CACrD;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAA;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,WAAW,EAAE,UAAU,GAAG,aAAa,CAAA;IAChD,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAA;IAC3C,QAAQ,CAAC,cAAc,EAAE,mBAAmB,GAAG,aAAa,CAAA;CAC7D;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,CAgFrE,CAAA"}