@dinyangetoh/codeplug-cli 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 (229) hide show
  1. package/README.md +291 -0
  2. package/dist/cli/commands/config.d.ts +4 -0
  3. package/dist/cli/commands/config.d.ts.map +1 -0
  4. package/dist/cli/commands/config.js +35 -0
  5. package/dist/cli/commands/config.js.map +1 -0
  6. package/dist/cli/commands/convention.d.ts +8 -0
  7. package/dist/cli/commands/convention.d.ts.map +1 -0
  8. package/dist/cli/commands/convention.js +92 -0
  9. package/dist/cli/commands/convention.js.map +1 -0
  10. package/dist/cli/commands/conventionPrompts.d.ts +3 -0
  11. package/dist/cli/commands/conventionPrompts.d.ts.map +1 -0
  12. package/dist/cli/commands/conventionPrompts.js +46 -0
  13. package/dist/cli/commands/conventionPrompts.js.map +1 -0
  14. package/dist/cli/commands/docs.d.ts +5 -0
  15. package/dist/cli/commands/docs.d.ts.map +1 -0
  16. package/dist/cli/commands/docs.js +49 -0
  17. package/dist/cli/commands/docs.js.map +1 -0
  18. package/dist/cli/commands/export.d.ts +3 -0
  19. package/dist/cli/commands/export.d.ts.map +1 -0
  20. package/dist/cli/commands/export.js +49 -0
  21. package/dist/cli/commands/export.js.map +1 -0
  22. package/dist/cli/index.d.ts +3 -0
  23. package/dist/cli/index.d.ts.map +1 -0
  24. package/dist/cli/index.js +114 -0
  25. package/dist/cli/index.js.map +1 -0
  26. package/dist/config/ConfigManager.d.ts +15 -0
  27. package/dist/config/ConfigManager.d.ts.map +1 -0
  28. package/dist/config/ConfigManager.js +69 -0
  29. package/dist/config/ConfigManager.js.map +1 -0
  30. package/dist/config/ConventionSchema.d.ts +85 -0
  31. package/dist/config/ConventionSchema.d.ts.map +1 -0
  32. package/dist/config/ConventionSchema.js +22 -0
  33. package/dist/config/ConventionSchema.js.map +1 -0
  34. package/dist/config/defaults.d.ts +13 -0
  35. package/dist/config/defaults.d.ts.map +1 -0
  36. package/dist/config/defaults.js +28 -0
  37. package/dist/config/defaults.js.map +1 -0
  38. package/dist/config/types.d.ts +138 -0
  39. package/dist/config/types.d.ts.map +1 -0
  40. package/dist/config/types.js +2 -0
  41. package/dist/config/types.js.map +1 -0
  42. package/dist/core/analyzer/AstAnalyzer.d.ts +17 -0
  43. package/dist/core/analyzer/AstAnalyzer.d.ts.map +1 -0
  44. package/dist/core/analyzer/AstAnalyzer.js +95 -0
  45. package/dist/core/analyzer/AstAnalyzer.js.map +1 -0
  46. package/dist/core/analyzer/ConventionDetector.d.ts +6 -0
  47. package/dist/core/analyzer/ConventionDetector.d.ts.map +1 -0
  48. package/dist/core/analyzer/ConventionDetector.js +38 -0
  49. package/dist/core/analyzer/ConventionDetector.js.map +1 -0
  50. package/dist/core/analyzer/PatternAggregator.d.ts +11 -0
  51. package/dist/core/analyzer/PatternAggregator.d.ts.map +1 -0
  52. package/dist/core/analyzer/PatternAggregator.js +94 -0
  53. package/dist/core/analyzer/PatternAggregator.js.map +1 -0
  54. package/dist/core/analyzer/visitors/ComponentVisitor.d.ts +6 -0
  55. package/dist/core/analyzer/visitors/ComponentVisitor.d.ts.map +1 -0
  56. package/dist/core/analyzer/visitors/ComponentVisitor.js +80 -0
  57. package/dist/core/analyzer/visitors/ComponentVisitor.js.map +1 -0
  58. package/dist/core/analyzer/visitors/ErrorHandlingVisitor.d.ts +6 -0
  59. package/dist/core/analyzer/visitors/ErrorHandlingVisitor.d.ts.map +1 -0
  60. package/dist/core/analyzer/visitors/ErrorHandlingVisitor.js +48 -0
  61. package/dist/core/analyzer/visitors/ErrorHandlingVisitor.js.map +1 -0
  62. package/dist/core/analyzer/visitors/ImportVisitor.d.ts +6 -0
  63. package/dist/core/analyzer/visitors/ImportVisitor.d.ts.map +1 -0
  64. package/dist/core/analyzer/visitors/ImportVisitor.js +68 -0
  65. package/dist/core/analyzer/visitors/ImportVisitor.js.map +1 -0
  66. package/dist/core/analyzer/visitors/NamingVisitor.d.ts +7 -0
  67. package/dist/core/analyzer/visitors/NamingVisitor.d.ts.map +1 -0
  68. package/dist/core/analyzer/visitors/NamingVisitor.js +88 -0
  69. package/dist/core/analyzer/visitors/NamingVisitor.js.map +1 -0
  70. package/dist/core/analyzer/visitors/StructureVisitor.d.ts +6 -0
  71. package/dist/core/analyzer/visitors/StructureVisitor.d.ts.map +1 -0
  72. package/dist/core/analyzer/visitors/StructureVisitor.js +8 -0
  73. package/dist/core/analyzer/visitors/StructureVisitor.js.map +1 -0
  74. package/dist/core/analyzer/visitors/TestVisitor.d.ts +6 -0
  75. package/dist/core/analyzer/visitors/TestVisitor.d.ts.map +1 -0
  76. package/dist/core/analyzer/visitors/TestVisitor.js +47 -0
  77. package/dist/core/analyzer/visitors/TestVisitor.js.map +1 -0
  78. package/dist/core/analyzer/visitors/types.d.ts +13 -0
  79. package/dist/core/analyzer/visitors/types.d.ts.map +1 -0
  80. package/dist/core/analyzer/visitors/types.js +2 -0
  81. package/dist/core/analyzer/visitors/types.js.map +1 -0
  82. package/dist/core/classifier/ConfidenceGate.d.ts +9 -0
  83. package/dist/core/classifier/ConfidenceGate.d.ts.map +1 -0
  84. package/dist/core/classifier/ConfidenceGate.js +11 -0
  85. package/dist/core/classifier/ConfidenceGate.js.map +1 -0
  86. package/dist/core/classifier/DriftClassifier.d.ts +17 -0
  87. package/dist/core/classifier/DriftClassifier.d.ts.map +1 -0
  88. package/dist/core/classifier/DriftClassifier.js +293 -0
  89. package/dist/core/classifier/DriftClassifier.js.map +1 -0
  90. package/dist/core/exporter/ExportEngine.d.ts +7 -0
  91. package/dist/core/exporter/ExportEngine.d.ts.map +1 -0
  92. package/dist/core/exporter/ExportEngine.js +52 -0
  93. package/dist/core/exporter/ExportEngine.js.map +1 -0
  94. package/dist/core/exporter/FreshnessChecker.d.ts +8 -0
  95. package/dist/core/exporter/FreshnessChecker.d.ts.map +1 -0
  96. package/dist/core/exporter/FreshnessChecker.js +49 -0
  97. package/dist/core/exporter/FreshnessChecker.js.map +1 -0
  98. package/dist/core/exporter/formatters/CiFormatter.d.ts +8 -0
  99. package/dist/core/exporter/formatters/CiFormatter.d.ts.map +1 -0
  100. package/dist/core/exporter/formatters/CiFormatter.js +51 -0
  101. package/dist/core/exporter/formatters/CiFormatter.js.map +1 -0
  102. package/dist/core/exporter/formatters/ClaudeFormatter.d.ts +9 -0
  103. package/dist/core/exporter/formatters/ClaudeFormatter.d.ts.map +1 -0
  104. package/dist/core/exporter/formatters/ClaudeFormatter.js +60 -0
  105. package/dist/core/exporter/formatters/ClaudeFormatter.js.map +1 -0
  106. package/dist/core/exporter/formatters/CopilotFormatter.d.ts +9 -0
  107. package/dist/core/exporter/formatters/CopilotFormatter.d.ts.map +1 -0
  108. package/dist/core/exporter/formatters/CopilotFormatter.js +50 -0
  109. package/dist/core/exporter/formatters/CopilotFormatter.js.map +1 -0
  110. package/dist/core/exporter/formatters/CursorFormatter.d.ts +9 -0
  111. package/dist/core/exporter/formatters/CursorFormatter.d.ts.map +1 -0
  112. package/dist/core/exporter/formatters/CursorFormatter.js +51 -0
  113. package/dist/core/exporter/formatters/CursorFormatter.js.map +1 -0
  114. package/dist/core/exporter/formatters/JsonFormatter.d.ts +8 -0
  115. package/dist/core/exporter/formatters/JsonFormatter.d.ts.map +1 -0
  116. package/dist/core/exporter/formatters/JsonFormatter.js +22 -0
  117. package/dist/core/exporter/formatters/JsonFormatter.js.map +1 -0
  118. package/dist/core/exporter/formatters/types.d.ts +7 -0
  119. package/dist/core/exporter/formatters/types.d.ts.map +1 -0
  120. package/dist/core/exporter/formatters/types.js +2 -0
  121. package/dist/core/exporter/formatters/types.js.map +1 -0
  122. package/dist/core/generator/DocGenerator.d.ts +14 -0
  123. package/dist/core/generator/DocGenerator.d.ts.map +1 -0
  124. package/dist/core/generator/DocGenerator.js +136 -0
  125. package/dist/core/generator/DocGenerator.js.map +1 -0
  126. package/dist/core/generator/PipelineOrchestrator.d.ts +11 -0
  127. package/dist/core/generator/PipelineOrchestrator.d.ts.map +1 -0
  128. package/dist/core/generator/PipelineOrchestrator.js +26 -0
  129. package/dist/core/generator/PipelineOrchestrator.js.map +1 -0
  130. package/dist/core/generator/StalenessTracker.d.ts +13 -0
  131. package/dist/core/generator/StalenessTracker.d.ts.map +1 -0
  132. package/dist/core/generator/StalenessTracker.js +76 -0
  133. package/dist/core/generator/StalenessTracker.js.map +1 -0
  134. package/dist/core/generator/documents/ArchitectureGenerator.d.ts +13 -0
  135. package/dist/core/generator/documents/ArchitectureGenerator.d.ts.map +1 -0
  136. package/dist/core/generator/documents/ArchitectureGenerator.js +101 -0
  137. package/dist/core/generator/documents/ArchitectureGenerator.js.map +1 -0
  138. package/dist/core/generator/documents/ContributingGenerator.d.ts +10 -0
  139. package/dist/core/generator/documents/ContributingGenerator.d.ts.map +1 -0
  140. package/dist/core/generator/documents/ContributingGenerator.js +90 -0
  141. package/dist/core/generator/documents/ContributingGenerator.js.map +1 -0
  142. package/dist/core/generator/documents/ConventionsGenerator.d.ts +8 -0
  143. package/dist/core/generator/documents/ConventionsGenerator.d.ts.map +1 -0
  144. package/dist/core/generator/documents/ConventionsGenerator.js +65 -0
  145. package/dist/core/generator/documents/ConventionsGenerator.js.map +1 -0
  146. package/dist/core/generator/documents/OnboardingGenerator.d.ts +12 -0
  147. package/dist/core/generator/documents/OnboardingGenerator.d.ts.map +1 -0
  148. package/dist/core/generator/documents/OnboardingGenerator.js +116 -0
  149. package/dist/core/generator/documents/OnboardingGenerator.js.map +1 -0
  150. package/dist/core/generator/documents/ReadmeGenerator.d.ts +12 -0
  151. package/dist/core/generator/documents/ReadmeGenerator.d.ts.map +1 -0
  152. package/dist/core/generator/documents/ReadmeGenerator.js +118 -0
  153. package/dist/core/generator/documents/ReadmeGenerator.js.map +1 -0
  154. package/dist/core/generator/documents/types.d.ts +18 -0
  155. package/dist/core/generator/documents/types.d.ts.map +1 -0
  156. package/dist/core/generator/documents/types.js +2 -0
  157. package/dist/core/generator/documents/types.js.map +1 -0
  158. package/dist/core/generator/llm/LlmClient.d.ts +12 -0
  159. package/dist/core/generator/llm/LlmClient.d.ts.map +1 -0
  160. package/dist/core/generator/llm/LlmClient.js +26 -0
  161. package/dist/core/generator/llm/LlmClient.js.map +1 -0
  162. package/dist/core/generator/llm/healthCheck.d.ts +6 -0
  163. package/dist/core/generator/llm/healthCheck.d.ts.map +1 -0
  164. package/dist/core/generator/llm/healthCheck.js +19 -0
  165. package/dist/core/generator/llm/healthCheck.js.map +1 -0
  166. package/dist/core/generator/llm/providerPresets.d.ts +8 -0
  167. package/dist/core/generator/llm/providerPresets.d.ts.map +1 -0
  168. package/dist/core/generator/llm/providerPresets.js +9 -0
  169. package/dist/core/generator/llm/providerPresets.js.map +1 -0
  170. package/dist/core/generator/pipelines/ExtractionPipeline.d.ts +7 -0
  171. package/dist/core/generator/pipelines/ExtractionPipeline.d.ts.map +1 -0
  172. package/dist/core/generator/pipelines/ExtractionPipeline.js +13 -0
  173. package/dist/core/generator/pipelines/ExtractionPipeline.js.map +1 -0
  174. package/dist/core/generator/pipelines/NerPipeline.d.ts +12 -0
  175. package/dist/core/generator/pipelines/NerPipeline.d.ts.map +1 -0
  176. package/dist/core/generator/pipelines/NerPipeline.js +17 -0
  177. package/dist/core/generator/pipelines/NerPipeline.js.map +1 -0
  178. package/dist/core/generator/pipelines/SummarizationPipeline.d.ts +7 -0
  179. package/dist/core/generator/pipelines/SummarizationPipeline.d.ts.map +1 -0
  180. package/dist/core/generator/pipelines/SummarizationPipeline.js +13 -0
  181. package/dist/core/generator/pipelines/SummarizationPipeline.js.map +1 -0
  182. package/dist/core/git/GitIntegration.d.ts +30 -0
  183. package/dist/core/git/GitIntegration.d.ts.map +1 -0
  184. package/dist/core/git/GitIntegration.js +92 -0
  185. package/dist/core/git/GitIntegration.js.map +1 -0
  186. package/dist/core/git/PreCommitHook.d.ts +9 -0
  187. package/dist/core/git/PreCommitHook.d.ts.map +1 -0
  188. package/dist/core/git/PreCommitHook.js +80 -0
  189. package/dist/core/git/PreCommitHook.js.map +1 -0
  190. package/dist/core/scorer/AutoFixer.d.ts +12 -0
  191. package/dist/core/scorer/AutoFixer.d.ts.map +1 -0
  192. package/dist/core/scorer/AutoFixer.js +121 -0
  193. package/dist/core/scorer/AutoFixer.js.map +1 -0
  194. package/dist/core/scorer/ComplianceScorer.d.ts +7 -0
  195. package/dist/core/scorer/ComplianceScorer.d.ts.map +1 -0
  196. package/dist/core/scorer/ComplianceScorer.js +76 -0
  197. package/dist/core/scorer/ComplianceScorer.js.map +1 -0
  198. package/dist/core/scorer/TrendTracker.d.ts +6 -0
  199. package/dist/core/scorer/TrendTracker.d.ts.map +1 -0
  200. package/dist/core/scorer/TrendTracker.js +45 -0
  201. package/dist/core/scorer/TrendTracker.js.map +1 -0
  202. package/dist/core/scorer/ViolationDetector.d.ts +17 -0
  203. package/dist/core/scorer/ViolationDetector.d.ts.map +1 -0
  204. package/dist/core/scorer/ViolationDetector.js +178 -0
  205. package/dist/core/scorer/ViolationDetector.js.map +1 -0
  206. package/dist/models/ModelManager.d.ts +15 -0
  207. package/dist/models/ModelManager.d.ts.map +1 -0
  208. package/dist/models/ModelManager.js +72 -0
  209. package/dist/models/ModelManager.js.map +1 -0
  210. package/dist/models/ModelRegistry.d.ts +12 -0
  211. package/dist/models/ModelRegistry.d.ts.map +1 -0
  212. package/dist/models/ModelRegistry.js +76 -0
  213. package/dist/models/ModelRegistry.js.map +1 -0
  214. package/dist/storage/ConventionStore.d.ts +11 -0
  215. package/dist/storage/ConventionStore.d.ts.map +1 -0
  216. package/dist/storage/ConventionStore.js +37 -0
  217. package/dist/storage/ConventionStore.js.map +1 -0
  218. package/dist/storage/ScoreStore.d.ts +18 -0
  219. package/dist/storage/ScoreStore.d.ts.map +1 -0
  220. package/dist/storage/ScoreStore.js +112 -0
  221. package/dist/storage/ScoreStore.js.map +1 -0
  222. package/dist/storage/ViolationStore.d.ts +11 -0
  223. package/dist/storage/ViolationStore.d.ts.map +1 -0
  224. package/dist/storage/ViolationStore.js +30 -0
  225. package/dist/storage/ViolationStore.js.map +1 -0
  226. package/package.json +75 -0
  227. package/templates/claude/CLAUDE.md.hbs +15 -0
  228. package/templates/copilot/copilot-instructions.md.hbs +13 -0
  229. package/templates/cursor/conventions.mdc.hbs +16 -0
@@ -0,0 +1,121 @@
1
+ import { join, dirname, extname } from 'node:path';
2
+ export class AutoFixer {
3
+ projectRoot;
4
+ constructor(projectRoot) {
5
+ this.projectRoot = projectRoot;
6
+ }
7
+ async fixById(id) {
8
+ const chalk = (await import('chalk')).default;
9
+ const { ViolationStore } = await import('../../storage/ViolationStore.js');
10
+ const store = new ViolationStore(this.projectRoot);
11
+ if (!(await store.exists())) {
12
+ console.log(chalk.yellow('No violations found. Run "codeplug convention audit" first.'));
13
+ return;
14
+ }
15
+ const violations = await store.load();
16
+ const violation = violations.find((v) => v.id === id);
17
+ if (!violation) {
18
+ console.log(chalk.red(`Violation "${id}" not found.`));
19
+ return;
20
+ }
21
+ if (!violation.autoFixable) {
22
+ console.log(chalk.yellow(`Violation "${id}" is not auto-fixable.`));
23
+ this.printManualGuidance(chalk, violation);
24
+ return;
25
+ }
26
+ console.log(chalk.bold('\n🔧 Dry-run preview:\n'));
27
+ this.printFixPreview(chalk, violation);
28
+ const success = await this.tryFix(chalk, violation);
29
+ if (success) {
30
+ const remaining = violations.filter((v) => v.id !== id);
31
+ await store.save(remaining);
32
+ console.log(chalk.green('\n✅ Fix applied successfully.'));
33
+ }
34
+ }
35
+ async fixAll() {
36
+ const chalk = (await import('chalk')).default;
37
+ const { ViolationStore } = await import('../../storage/ViolationStore.js');
38
+ const store = new ViolationStore(this.projectRoot);
39
+ if (!(await store.exists())) {
40
+ console.log(chalk.yellow('No violations found. Run "codeplug convention audit" first.'));
41
+ return;
42
+ }
43
+ const violations = await store.load();
44
+ const fixable = violations.filter((v) => v.autoFixable);
45
+ if (fixable.length === 0) {
46
+ console.log(chalk.yellow('No auto-fixable violations found.'));
47
+ return;
48
+ }
49
+ console.log(chalk.bold(`\n🔧 Dry-run preview: ${fixable.length} auto-fixable violation(s)\n`));
50
+ for (const v of fixable) {
51
+ this.printFixPreview(chalk, v);
52
+ }
53
+ console.log('');
54
+ let fixed = 0;
55
+ const remaining = [...violations];
56
+ for (const v of fixable) {
57
+ const success = await this.tryFix(chalk, v);
58
+ if (success) {
59
+ fixed++;
60
+ const idx = remaining.findIndex((r) => r.id === v.id);
61
+ if (idx >= 0)
62
+ remaining.splice(idx, 1);
63
+ }
64
+ }
65
+ await store.save(remaining);
66
+ console.log(chalk.green(`\n✅ Fixed ${fixed}/${fixable.length} violation(s).`));
67
+ if (remaining.length > 0) {
68
+ console.log(chalk.dim(` ${remaining.length} violation(s) remaining.`));
69
+ }
70
+ }
71
+ isFileRename(v) {
72
+ const foundExt = extname(v.found);
73
+ const expectedExt = extname(v.expected);
74
+ return foundExt.length > 0 && expectedExt.length > 0 && foundExt === expectedExt;
75
+ }
76
+ printFixPreview(chalk, v) {
77
+ if (this.isFileRename(v)) {
78
+ console.log(chalk.cyan(` [rename] ${v.found} → ${v.expected}`));
79
+ console.log(chalk.dim(` in ${dirname(v.file)}/`));
80
+ }
81
+ else {
82
+ console.log(chalk.cyan(` [manual] ${v.file}`));
83
+ console.log(chalk.dim(` ${v.message}`));
84
+ }
85
+ }
86
+ async tryFix(chalk, v) {
87
+ if (this.isFileRename(v)) {
88
+ return this.applyFileRename(chalk, v);
89
+ }
90
+ this.printManualGuidance(chalk, v);
91
+ return false;
92
+ }
93
+ async applyFileRename(chalk, v) {
94
+ const { rename } = await import('node:fs/promises');
95
+ const { existsSync } = await import('node:fs');
96
+ const filePath = join(this.projectRoot, v.file);
97
+ const dir = dirname(filePath);
98
+ const newPath = join(dir, v.expected);
99
+ if (!existsSync(filePath)) {
100
+ console.log(chalk.red(` ✗ File not found: ${v.file}`));
101
+ return false;
102
+ }
103
+ try {
104
+ await rename(filePath, newPath);
105
+ console.log(chalk.green(` ✓ Renamed ${v.found} → ${v.expected}`));
106
+ return true;
107
+ }
108
+ catch (err) {
109
+ const msg = err instanceof Error ? err.message : String(err);
110
+ console.log(chalk.red(` ✗ Rename failed: ${msg}`));
111
+ return false;
112
+ }
113
+ }
114
+ printManualGuidance(chalk, v) {
115
+ console.log(chalk.yellow(`\n Manual fix needed for ${v.file}:`));
116
+ console.log(chalk.dim(` ${v.message}`));
117
+ console.log(chalk.dim(` Expected: ${v.expected}`));
118
+ console.log(chalk.dim(` Found: ${v.found}`));
119
+ }
120
+ }
121
+ //# sourceMappingURL=AutoFixer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutoFixer.js","sourceRoot":"","sources":["../../../src/core/scorer/AutoFixer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Violation, ComplianceScore } from '../../config/types.js';
2
+ export declare class ComplianceScorer {
3
+ calculate(violations: Violation[]): ComplianceScore;
4
+ scoreAndPersist(violations: Violation[], projectRoot: string): Promise<ComplianceScore>;
5
+ printReport(score: ComplianceScore, violations: Violation[]): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=ComplianceScorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComplianceScorer.d.ts","sourceRoot":"","sources":["../../../src/core/scorer/ComplianceScorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAyB,MAAM,uBAAuB,CAAC;AAS/F,qBAAa,gBAAgB;IAC3B,SAAS,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,eAAe;IAiB7C,eAAe,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA8BvF,WAAW,CAAC,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAkClF"}
@@ -0,0 +1,76 @@
1
+ const SEVERITY_WEIGHTS = {
2
+ critical: 15,
3
+ high: 8,
4
+ medium: 3,
5
+ low: 1,
6
+ };
7
+ export class ComplianceScorer {
8
+ calculate(violations) {
9
+ const breakdown = { critical: 0, high: 0, medium: 0, low: 0 };
10
+ let totalDeduction = 0;
11
+ for (const v of violations) {
12
+ breakdown[v.severity]++;
13
+ totalDeduction += SEVERITY_WEIGHTS[v.severity];
14
+ }
15
+ return {
16
+ total: Math.max(0, 100 - totalDeduction),
17
+ breakdown,
18
+ violationCount: violations.length,
19
+ threshold: 70,
20
+ };
21
+ }
22
+ async scoreAndPersist(violations, projectRoot) {
23
+ const score = this.calculate(violations);
24
+ const { ScoreStore } = await import('../../storage/ScoreStore.js');
25
+ const store = new ScoreStore(projectRoot);
26
+ try {
27
+ const { randomUUID, createHash } = await import('node:crypto');
28
+ const record = {
29
+ id: randomUUID(),
30
+ projectHash: createHash('sha256').update(projectRoot).digest('hex').slice(0, 12),
31
+ score: score.total,
32
+ breakdown: score.breakdown,
33
+ createdAt: new Date().toISOString(),
34
+ };
35
+ await store.save(record);
36
+ const { TrendTracker } = await import('./TrendTracker.js');
37
+ const tracker = new TrendTracker();
38
+ const history = await store.getHistory(8);
39
+ score.trend = tracker.computeTrend(history);
40
+ }
41
+ finally {
42
+ store.close();
43
+ }
44
+ return score;
45
+ }
46
+ async printReport(score, violations) {
47
+ const chalk = (await import('chalk')).default;
48
+ const trendIcon = score.trend === 'improving' ? '\ud83d\udcc8' : score.trend === 'declining' ? '\ud83d\udcc9' : '\u27a1\ufe0f';
49
+ console.log(chalk.bold(`\n\ud83d\udcca Compliance Score: ${score.total}/100 ${trendIcon}\n`));
50
+ if (violations.length === 0) {
51
+ console.log(chalk.green('\u2705 No violations found.\n'));
52
+ return;
53
+ }
54
+ const severityOrder = ['critical', 'high', 'medium', 'low'];
55
+ const icons = { critical: '\ud83d\udd34', high: '\ud83d\udfe0', medium: '\ud83d\udfe1', low: '\ud83d\udd35' };
56
+ for (const sev of severityOrder) {
57
+ const group = violations.filter((v) => v.severity === sev);
58
+ if (group.length === 0)
59
+ continue;
60
+ console.log(`${icons[sev]} ${chalk.bold(sev.toUpperCase())} (${group.length}):`);
61
+ for (const v of group) {
62
+ console.log(chalk.red(` ${v.file}${v.line ? `:${v.line}` : ''}`));
63
+ console.log(chalk.dim(` ${v.message}`));
64
+ console.log(chalk.dim(` Expected: ${v.expected}`));
65
+ console.log(chalk.dim(` Found: ${v.found}`));
66
+ if (v.autoFixable) {
67
+ console.log(chalk.cyan(` \u2192 Auto-fixable: codeplug convention fix --id ${v.id}`));
68
+ }
69
+ console.log('');
70
+ }
71
+ }
72
+ const passIcon = score.total >= (score.threshold ?? 70) ? '\u2705' : '\u274c';
73
+ console.log(`${passIcon} Threshold: ${score.threshold ?? 70} | Score: ${score.total}\n`);
74
+ }
75
+ }
76
+ //# sourceMappingURL=ComplianceScorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComplianceScorer.js","sourceRoot":"","sources":["../../../src/core/scorer/ComplianceScorer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { ScoreRecord } from '../../config/types.js';
2
+ export declare class TrendTracker {
3
+ computeTrend(history: ScoreRecord[]): 'improving' | 'stable' | 'declining';
4
+ renderTrendChart(history: ScoreRecord[]): string;
5
+ }
6
+ //# sourceMappingURL=TrendTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrendTracker.d.ts","sourceRoot":"","sources":["../../../src/core/scorer/TrendTracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOzD,qBAAa,YAAY;IACvB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW;IA4B1E,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM;CAejD"}
@@ -0,0 +1,45 @@
1
+ const MAX_CHART_ENTRIES = 12;
2
+ const MAX_BAR_WIDTH = 40;
3
+ const REGRESSION_WINDOW = 8;
4
+ const SLOPE_THRESHOLD = 1;
5
+ export class TrendTracker {
6
+ computeTrend(history) {
7
+ if (history.length < 2)
8
+ return 'stable';
9
+ const points = history.slice(-REGRESSION_WINDOW);
10
+ const n = points.length;
11
+ let sumX = 0;
12
+ let sumY = 0;
13
+ let sumXY = 0;
14
+ let sumX2 = 0;
15
+ for (let i = 0; i < n; i++) {
16
+ sumX += i;
17
+ sumY += points[i].score;
18
+ sumXY += i * points[i].score;
19
+ sumX2 += i * i;
20
+ }
21
+ const denominator = n * sumX2 - sumX * sumX;
22
+ if (denominator === 0)
23
+ return 'stable';
24
+ const slope = (n * sumXY - sumX * sumY) / denominator;
25
+ if (slope > SLOPE_THRESHOLD)
26
+ return 'improving';
27
+ if (slope < -SLOPE_THRESHOLD)
28
+ return 'declining';
29
+ return 'stable';
30
+ }
31
+ renderTrendChart(history) {
32
+ if (history.length === 0)
33
+ return 'No score history available.';
34
+ const entries = history.slice(-MAX_CHART_ENTRIES);
35
+ const lines = [];
36
+ for (const record of entries) {
37
+ const date = record.createdAt.slice(0, 10);
38
+ const barLen = Math.round((record.score / 100) * MAX_BAR_WIDTH);
39
+ const bar = '\u2588'.repeat(barLen) + '\u2591'.repeat(MAX_BAR_WIDTH - barLen);
40
+ lines.push(`${date} \u2502${bar}\u2502 ${record.score}`);
41
+ }
42
+ return lines.join('\n');
43
+ }
44
+ }
45
+ //# sourceMappingURL=TrendTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrendTracker.js","sourceRoot":"","sources":["../../../src/core/scorer/TrendTracker.ts"],"names":[],"mappings":"AAEA,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,MAAM,OAAO,YAAY;IACvB,YAAY,CAAC,OAAsB;QACjC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,QAAQ,CAAC;QAExC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACjD,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAExB,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,CAAC;YACV,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACxB,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;QAC5C,IAAI,WAAW,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC;QAEvC,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC;QAEtD,IAAI,KAAK,GAAG,eAAe;YAAE,OAAO,WAAW,CAAC;QAChD,IAAI,KAAK,GAAG,CAAC,eAAe;YAAE,OAAO,WAAW,CAAC;QACjD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,gBAAgB,CAAC,OAAsB;QACrC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,6BAA6B,CAAC;QAE/D,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAClD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC;YAChE,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,CAAC;YAC9E,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,GAAG,UAAU,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ import type { Convention, Violation, ConventionAuditOptions } from '../../config/types.js';
2
+ export declare class ViolationDetector {
3
+ private projectRoot;
4
+ constructor(projectRoot: string);
5
+ detect(conventions: Convention[], options: ConventionAuditOptions): Promise<Violation[]>;
6
+ private persistViolations;
7
+ private getTargetFiles;
8
+ private getChangedFilesSince;
9
+ private parseFile;
10
+ private createVisitors;
11
+ private describeFinding;
12
+ private computeExpectedFilename;
13
+ private splitWords;
14
+ private toCamelCase;
15
+ private toPascalCase;
16
+ }
17
+ //# sourceMappingURL=ViolationDetector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ViolationDetector.d.ts","sourceRoot":"","sources":["../../../src/core/scorer/ViolationDetector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAI3F,qBAAa,iBAAiB;IAChB,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEjC,MAAM,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YA4DhF,iBAAiB;YAMjB,cAAc;YAmBd,oBAAoB;YAcpB,SAAS;YA0BT,cAAc;IAwB5B,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,YAAY;CAKrB"}
@@ -0,0 +1,178 @@
1
+ import { join, basename, extname } from 'node:path';
2
+ import { readFile } from 'node:fs/promises';
3
+ export class ViolationDetector {
4
+ projectRoot;
5
+ constructor(projectRoot) {
6
+ this.projectRoot = projectRoot;
7
+ }
8
+ async detect(conventions, options) {
9
+ const confirmed = conventions.filter((c) => c.confirmed);
10
+ if (confirmed.length === 0)
11
+ return [];
12
+ const files = await this.getTargetFiles(options);
13
+ if (files.length === 0)
14
+ return [];
15
+ const [visitors, { randomUUID }] = await Promise.all([
16
+ this.createVisitors(),
17
+ import('node:crypto'),
18
+ ]);
19
+ const conventionMap = new Map();
20
+ for (const c of confirmed) {
21
+ conventionMap.set(`${c.dimension}:${c.rule}`, c);
22
+ }
23
+ const violations = [];
24
+ for (const filePath of files) {
25
+ const parsed = await this.parseFile(filePath);
26
+ if (!parsed)
27
+ continue;
28
+ for (const visitor of visitors) {
29
+ try {
30
+ const findings = visitor.visit(parsed);
31
+ for (const finding of findings) {
32
+ if (finding.count >= finding.total)
33
+ continue;
34
+ const key = `${finding.dimension}:${finding.pattern}`;
35
+ const convention = conventionMap.get(key);
36
+ if (!convention)
37
+ continue;
38
+ const isNamingFile = finding.dimension === 'naming' && finding.total === 1;
39
+ const ext = extname(filePath);
40
+ const expectedName = isNamingFile
41
+ ? this.computeExpectedFilename(basename(filePath, ext), ext, finding.pattern)
42
+ : null;
43
+ violations.push({
44
+ id: randomUUID(),
45
+ conventionId: convention.id,
46
+ severity: convention.severity,
47
+ file: filePath,
48
+ message: `Violates: ${finding.pattern}`,
49
+ expected: expectedName ?? finding.pattern,
50
+ found: isNamingFile ? basename(filePath) : this.describeFinding(finding, filePath),
51
+ autoFixable: expectedName !== null,
52
+ });
53
+ }
54
+ }
55
+ catch {
56
+ // Visitor may fail on certain files; skip gracefully
57
+ }
58
+ }
59
+ }
60
+ await this.persistViolations(violations);
61
+ return violations;
62
+ }
63
+ async persistViolations(violations) {
64
+ const { ViolationStore } = await import('../../storage/ViolationStore.js');
65
+ const store = new ViolationStore(this.projectRoot);
66
+ await store.save(violations);
67
+ }
68
+ async getTargetFiles(options) {
69
+ const { globby } = await import('globby');
70
+ const allFiles = await globby(['**/*.{ts,tsx,js,jsx,mjs,cjs}'], {
71
+ cwd: this.projectRoot,
72
+ gitignore: true,
73
+ ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.codeplug/**'],
74
+ absolute: false,
75
+ });
76
+ if (!options.since)
77
+ return allFiles;
78
+ const changedFiles = await this.getChangedFilesSince(options.since);
79
+ if (changedFiles.length === 0)
80
+ return [];
81
+ const changedSet = new Set(changedFiles);
82
+ return allFiles.filter((f) => changedSet.has(f));
83
+ }
84
+ async getChangedFilesSince(since) {
85
+ try {
86
+ const { simpleGit } = await import('simple-git');
87
+ const git = simpleGit(this.projectRoot);
88
+ const isRepo = await git.checkIsRepo();
89
+ if (!isRepo)
90
+ return [];
91
+ const result = await git.raw(['log', '--since', since, '--name-only', '--format=']);
92
+ return [...new Set(result.split('\n').map((l) => l.trim()).filter(Boolean))];
93
+ }
94
+ catch {
95
+ return [];
96
+ }
97
+ }
98
+ async parseFile(filePath) {
99
+ try {
100
+ const absolutePath = join(this.projectRoot, filePath);
101
+ const code = await readFile(absolutePath, 'utf-8');
102
+ const { parse } = await import('@babel/parser');
103
+ const ast = parse(code, {
104
+ sourceType: 'module',
105
+ plugins: [
106
+ 'typescript',
107
+ 'jsx',
108
+ 'decorators-legacy',
109
+ 'classProperties',
110
+ 'optionalChaining',
111
+ 'nullishCoalescingOperator',
112
+ 'dynamicImport',
113
+ ],
114
+ errorRecovery: true,
115
+ });
116
+ return { filePath, code, ast };
117
+ }
118
+ catch {
119
+ return null;
120
+ }
121
+ }
122
+ async createVisitors() {
123
+ const [{ NamingVisitor }, { ComponentVisitor }, { TestVisitor }, { ErrorHandlingVisitor }, { ImportVisitor },] = await Promise.all([
124
+ import('../analyzer/visitors/NamingVisitor.js'),
125
+ import('../analyzer/visitors/ComponentVisitor.js'),
126
+ import('../analyzer/visitors/TestVisitor.js'),
127
+ import('../analyzer/visitors/ErrorHandlingVisitor.js'),
128
+ import('../analyzer/visitors/ImportVisitor.js'),
129
+ ]);
130
+ return [
131
+ new NamingVisitor(),
132
+ new ComponentVisitor(),
133
+ new TestVisitor(),
134
+ new ErrorHandlingVisitor(),
135
+ new ImportVisitor(),
136
+ ];
137
+ }
138
+ describeFinding(finding, filePath) {
139
+ if (finding.total === 1) {
140
+ return basename(filePath, extname(filePath));
141
+ }
142
+ return `${finding.count}/${finding.total} conforming`;
143
+ }
144
+ computeExpectedFilename(stem, ext, pattern) {
145
+ const lower = pattern.toLowerCase();
146
+ if (lower.includes('pascalcase')) {
147
+ const converted = this.toPascalCase(stem);
148
+ return converted !== stem ? converted + ext : null;
149
+ }
150
+ if (lower.includes('camelcase')) {
151
+ const converted = this.toCamelCase(stem);
152
+ return converted !== stem ? converted + ext : null;
153
+ }
154
+ return null;
155
+ }
156
+ splitWords(str) {
157
+ return str
158
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
159
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
160
+ .split(/[-_.\s]+/)
161
+ .filter(Boolean);
162
+ }
163
+ toCamelCase(str) {
164
+ const words = this.splitWords(str);
165
+ if (words.length === 0)
166
+ return str;
167
+ return words
168
+ .map((w, i) => i === 0 ? w.toLowerCase() : w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
169
+ .join('');
170
+ }
171
+ toPascalCase(str) {
172
+ const words = this.splitWords(str);
173
+ if (words.length === 0)
174
+ return str;
175
+ return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join('');
176
+ }
177
+ }
178
+ //# sourceMappingURL=ViolationDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ViolationDetector.js","sourceRoot":"","sources":["../../../src/core/scorer/ViolationDetector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ModelTier } from '../config/types.js';
2
+ import { type ModelRole, type ModelSpec } from './ModelRegistry.js';
3
+ export declare class ModelManager {
4
+ private loadedModel;
5
+ private cacheDir;
6
+ private tier;
7
+ constructor(tier: ModelTier, cacheDir?: string);
8
+ ensureCacheDir(): Promise<void>;
9
+ loadModel(role: ModelRole): Promise<unknown>;
10
+ disposeModel(): Promise<void>;
11
+ getSpec(role: ModelRole): ModelSpec;
12
+ isModelLoaded(): boolean;
13
+ getCurrentRole(): ModelRole | null;
14
+ }
15
+ //# sourceMappingURL=ModelManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelManager.d.ts","sourceRoot":"","sources":["../../src/models/ModelManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAgB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAIlF,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAuD;IAC1E,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAY;gBAEZ,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM;IAKxC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAyC5C,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAUnC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS;IAInC,aAAa,IAAI,OAAO;IAIxB,cAAc,IAAI,SAAS,GAAG,IAAI;CAGnC"}
@@ -0,0 +1,72 @@
1
+ import { join } from 'node:path';
2
+ import { homedir } from 'node:os';
3
+ import { existsSync } from 'node:fs';
4
+ import { mkdir } from 'node:fs/promises';
5
+ import { getModelSpec } from './ModelRegistry.js';
6
+ const DEFAULT_CACHE_DIR = join(homedir(), '.codeplug', 'models');
7
+ export class ModelManager {
8
+ loadedModel = null;
9
+ cacheDir;
10
+ tier;
11
+ constructor(tier, cacheDir) {
12
+ this.tier = tier;
13
+ this.cacheDir = cacheDir ?? process.env['CODEPLUG_MODEL_CACHE'] ?? DEFAULT_CACHE_DIR;
14
+ }
15
+ async ensureCacheDir() {
16
+ if (!existsSync(this.cacheDir)) {
17
+ await mkdir(this.cacheDir, { recursive: true });
18
+ }
19
+ }
20
+ async loadModel(role) {
21
+ if (this.loadedModel?.role === role) {
22
+ return this.loadedModel.pipeline;
23
+ }
24
+ if (this.loadedModel) {
25
+ await this.disposeModel();
26
+ }
27
+ const spec = getModelSpec(role, this.tier);
28
+ await this.ensureCacheDir();
29
+ const ora = (await import('ora')).default;
30
+ const spinner = ora(`Loading ${spec.description} (~${spec.sizeEstimateMb}MB)...`).start();
31
+ try {
32
+ const { pipeline, env } = await import('@huggingface/transformers');
33
+ env.cacheDir = this.cacheDir;
34
+ env.allowLocalModels = true;
35
+ const taskMap = {
36
+ classifier: 'feature-extraction',
37
+ summarizer: 'summarization',
38
+ extractor: 'question-answering',
39
+ ner: 'token-classification',
40
+ };
41
+ const pipe = await pipeline(taskMap[role], spec.huggingFaceId, {
42
+ dtype: spec.dtype,
43
+ });
44
+ this.loadedModel = { role, pipeline: pipe };
45
+ spinner.succeed(`Loaded ${spec.description}`);
46
+ return pipe;
47
+ }
48
+ catch (err) {
49
+ spinner.fail(`Failed to load ${spec.description}`);
50
+ throw err;
51
+ }
52
+ }
53
+ async disposeModel() {
54
+ if (this.loadedModel) {
55
+ const pipe = this.loadedModel.pipeline;
56
+ if (typeof pipe.dispose === 'function') {
57
+ await pipe.dispose();
58
+ }
59
+ this.loadedModel = null;
60
+ }
61
+ }
62
+ getSpec(role) {
63
+ return getModelSpec(role, this.tier);
64
+ }
65
+ isModelLoaded() {
66
+ return this.loadedModel !== null;
67
+ }
68
+ getCurrentRole() {
69
+ return this.loadedModel?.role ?? null;
70
+ }
71
+ }
72
+ //# sourceMappingURL=ModelManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelManager.js","sourceRoot":"","sources":["../../src/models/ModelManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ModelTier } from '../config/types.js';
2
+ export type ModelRole = 'classifier' | 'summarizer' | 'extractor' | 'ner';
3
+ export interface ModelSpec {
4
+ huggingFaceId: string;
5
+ dtype: 'q4' | 'q8' | 'fp32';
6
+ sizeEstimateMb: number;
7
+ description: string;
8
+ }
9
+ export declare function getModelSpec(role: ModelRole, tier: ModelTier): ModelSpec;
10
+ export declare function getAllModelSpecs(tier: ModelTier): Record<ModelRole, ModelSpec>;
11
+ export declare function getTotalDiskEstimate(tier: ModelTier): number;
12
+ //# sourceMappingURL=ModelRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelRegistry.d.ts","sourceRoot":"","sources":["../../src/models/ModelRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,WAAW,GAAG,KAAK,CAAC;AAE1E,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AA6DD,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,CAExE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAM9E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAM5D"}