cc-recommender 0.8.2 → 0.9.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 (34) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/config/enhanced-scoring-config.d.ts +46 -0
  3. package/dist/config/enhanced-scoring-config.d.ts.map +1 -0
  4. package/dist/config/enhanced-scoring-config.js +38 -0
  5. package/dist/config/enhanced-scoring-config.js.map +1 -0
  6. package/dist/services/analyzer/metadata-analyzer.service.d.ts +15 -0
  7. package/dist/services/analyzer/metadata-analyzer.service.d.ts.map +1 -0
  8. package/dist/services/analyzer/metadata-analyzer.service.js +122 -0
  9. package/dist/services/analyzer/metadata-analyzer.service.js.map +1 -0
  10. package/dist/services/analyzer/project-analyzer.service.d.ts.map +1 -1
  11. package/dist/services/analyzer/project-analyzer.service.js +9 -0
  12. package/dist/services/analyzer/project-analyzer.service.js.map +1 -1
  13. package/dist/services/recommender/recommendation.service.d.ts.map +1 -1
  14. package/dist/services/recommender/recommendation.service.js +20 -2
  15. package/dist/services/recommender/recommendation.service.js.map +1 -1
  16. package/dist/services/recommender/scoring/context-scorer.d.ts +20 -0
  17. package/dist/services/recommender/scoring/context-scorer.d.ts.map +1 -0
  18. package/dist/services/recommender/scoring/context-scorer.js +84 -0
  19. package/dist/services/recommender/scoring/context-scorer.js.map +1 -0
  20. package/dist/services/recommender/scoring/scorer.d.ts +7 -2
  21. package/dist/services/recommender/scoring/scorer.d.ts.map +1 -1
  22. package/dist/services/recommender/scoring/scorer.js +41 -4
  23. package/dist/services/recommender/scoring/scorer.js.map +1 -1
  24. package/dist/services/recommender/scoring/similarity-scorer.d.ts +35 -0
  25. package/dist/services/recommender/scoring/similarity-scorer.d.ts.map +1 -0
  26. package/dist/services/recommender/scoring/similarity-scorer.js +121 -0
  27. package/dist/services/recommender/scoring/similarity-scorer.js.map +1 -0
  28. package/dist/types/scoring-types.d.ts +45 -0
  29. package/dist/types/scoring-types.d.ts.map +1 -0
  30. package/dist/types/scoring-types.js +7 -0
  31. package/dist/types/scoring-types.js.map +1 -0
  32. package/dist/types/service-types.d.ts +5 -0
  33. package/dist/types/service-types.d.ts.map +1 -1
  34. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.9.0](https://github.com/yuji0809/cc-recommender/compare/v0.8.2...v0.9.0) (2026-02-01)
9
+
10
+
11
+ ### Features
12
+
13
+ * update scoring algorithm ([#22](https://github.com/yuji0809/cc-recommender/issues/22)) ([803818c](https://github.com/yuji0809/cc-recommender/commit/803818cc7fa54907ca94ebf023863804d8f08008))
14
+
8
15
  ## [0.8.2](https://github.com/yuji0809/cc-recommender/compare/v0.8.1...v0.8.2) (2026-02-01)
9
16
 
10
17
 
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Enhanced Scoring Configuration
3
+ *
4
+ * Configuration for context-aware and semantic similarity scoring
5
+ */
6
+ /** コンテキストスコアの重み */
7
+ export declare const CONTEXT_SCORE_WEIGHTS: {
8
+ /** プロジェクトサイズマッチ */
9
+ readonly sizeMatch: 2;
10
+ /** モノレポ対応ツール */
11
+ readonly monorepoBonus: 3;
12
+ /** チーム規模マッチ */
13
+ readonly teamSizeMatch: 1.5;
14
+ };
15
+ /** プロジェクトサイズ分類の閾値 */
16
+ export declare const PROJECT_SIZE_THRESHOLDS: {
17
+ readonly small: {
18
+ readonly maxFiles: 100;
19
+ readonly maxDeps: 10;
20
+ };
21
+ readonly medium: {
22
+ readonly maxFiles: 500;
23
+ readonly maxDeps: 30;
24
+ };
25
+ readonly large: {
26
+ readonly maxFiles: 2000;
27
+ readonly maxDeps: 100;
28
+ };
29
+ };
30
+ /** 意味的類似性の閾値 */
31
+ export declare const SIMILARITY_THRESHOLDS: {
32
+ /** 最小共起カウント(このペアを考慮する最小出現回数) */
33
+ readonly minCooccurrence: 3;
34
+ /** Jaccard係数の閾値 */
35
+ readonly minJaccardSimilarity: 0.3;
36
+ /** 類似性スコアの最大値 */
37
+ readonly maxSimilarityBonus: 5;
38
+ };
39
+ /** 拡張スコアリングの有効/無効フラグ */
40
+ export declare const ENHANCED_SCORING_FLAGS: {
41
+ /** コンテキストスコアリングを有効化 */
42
+ readonly enableContextScoring: true;
43
+ /** 意味的類似性スコアリングを有効化 */
44
+ readonly enableSimilarityScoring: true;
45
+ };
46
+ //# sourceMappingURL=enhanced-scoring-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enhanced-scoring-config.d.ts","sourceRoot":"","sources":["../../src/config/enhanced-scoring-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,mBAAmB;AACnB,eAAO,MAAM,qBAAqB;IAChC,mBAAmB;;IAEnB,gBAAgB;;IAEhB,eAAe;;CAEP,CAAC;AAEX,qBAAqB;AACrB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;CAK1B,CAAC;AAEX,gBAAgB;AAChB,eAAO,MAAM,qBAAqB;IAChC,gCAAgC;;IAEhC,mBAAmB;;IAEnB,iBAAiB;;CAET,CAAC;AAEX,wBAAwB;AACxB,eAAO,MAAM,sBAAsB;IACjC,uBAAuB;;IAEvB,uBAAuB;;CAEf,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Enhanced Scoring Configuration
3
+ *
4
+ * Configuration for context-aware and semantic similarity scoring
5
+ */
6
+ /** コンテキストスコアの重み */
7
+ export const CONTEXT_SCORE_WEIGHTS = {
8
+ /** プロジェクトサイズマッチ */
9
+ sizeMatch: 2.0,
10
+ /** モノレポ対応ツール */
11
+ monorepoBonus: 3.0,
12
+ /** チーム規模マッチ */
13
+ teamSizeMatch: 1.5,
14
+ };
15
+ /** プロジェクトサイズ分類の閾値 */
16
+ export const PROJECT_SIZE_THRESHOLDS = {
17
+ small: { maxFiles: 100, maxDeps: 10 },
18
+ medium: { maxFiles: 500, maxDeps: 30 },
19
+ large: { maxFiles: 2000, maxDeps: 100 },
20
+ // enterprise: それ以上
21
+ };
22
+ /** 意味的類似性の閾値 */
23
+ export const SIMILARITY_THRESHOLDS = {
24
+ /** 最小共起カウント(このペアを考慮する最小出現回数) */
25
+ minCooccurrence: 3,
26
+ /** Jaccard係数の閾値 */
27
+ minJaccardSimilarity: 0.3,
28
+ /** 類似性スコアの最大値 */
29
+ maxSimilarityBonus: 5.0,
30
+ };
31
+ /** 拡張スコアリングの有効/無効フラグ */
32
+ export const ENHANCED_SCORING_FLAGS = {
33
+ /** コンテキストスコアリングを有効化 */
34
+ enableContextScoring: true,
35
+ /** 意味的類似性スコアリングを有効化 */
36
+ enableSimilarityScoring: true,
37
+ };
38
+ //# sourceMappingURL=enhanced-scoring-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enhanced-scoring-config.js","sourceRoot":"","sources":["../../src/config/enhanced-scoring-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,mBAAmB;AACnB,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,mBAAmB;IACnB,SAAS,EAAE,GAAG;IACd,gBAAgB;IAChB,aAAa,EAAE,GAAG;IAClB,eAAe;IACf,aAAa,EAAE,GAAG;CACV,CAAC;AAEX,qBAAqB;AACrB,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE;IACrC,MAAM,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE;IACtC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE;IACvC,mBAAmB;CACX,CAAC;AAEX,gBAAgB;AAChB,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,gCAAgC;IAChC,eAAe,EAAE,CAAC;IAClB,mBAAmB;IACnB,oBAAoB,EAAE,GAAG;IACzB,iBAAiB;IACjB,kBAAkB,EAAE,GAAG;CACf,CAAC;AAEX,wBAAwB;AACxB,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,uBAAuB;IACvB,oBAAoB,EAAE,IAAI;IAC1B,uBAAuB;IACvB,uBAAuB,EAAE,IAAI;CACrB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Metadata Analyzer Service
3
+ *
4
+ * Analyzes project metadata (size, kind, team scale, etc.)
5
+ */
6
+ import type { ProjectMetadata } from "../../types/scoring-types.js";
7
+ import type { ProjectInfo } from "../../types/service-types.js";
8
+ /**
9
+ * Analyze project metadata from ProjectInfo
10
+ *
11
+ * @param project - The project information
12
+ * @returns Project metadata (size, kind, team size, etc.)
13
+ */
14
+ export declare function analyzeMetadata(project: ProjectInfo): ProjectMetadata;
15
+ //# sourceMappingURL=metadata-analyzer.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-analyzer.service.d.ts","sourceRoot":"","sources":["../../../src/services/analyzer/metadata-analyzer.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAe,eAAe,EAAe,MAAM,8BAA8B,CAAC;AAC9F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe,CAyBrE"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Metadata Analyzer Service
3
+ *
4
+ * Analyzes project metadata (size, kind, team scale, etc.)
5
+ */
6
+ import { PROJECT_SIZE_THRESHOLDS } from "../../config/enhanced-scoring-config.js";
7
+ /**
8
+ * Analyze project metadata from ProjectInfo
9
+ *
10
+ * @param project - The project information
11
+ * @returns Project metadata (size, kind, team size, etc.)
12
+ */
13
+ export function analyzeMetadata(project) {
14
+ const fileCount = project.files.length;
15
+ const depCount = project.dependencies.length;
16
+ const languageCount = project.languages.length;
17
+ // Classify project size
18
+ const size = classifyProjectSize(fileCount, depCount);
19
+ // Detect project kind
20
+ const kind = detectProjectKind(project);
21
+ // Estimate team size
22
+ const estimatedTeamSize = estimateTeamSize(project);
23
+ // Detect workspace count (for monorepo)
24
+ const workspaceCount = kind === "monorepo" ? detectWorkspaceCount(project) : undefined;
25
+ return {
26
+ size,
27
+ kind,
28
+ estimatedTeamSize,
29
+ workspaceCount,
30
+ fileCount,
31
+ languageCount,
32
+ };
33
+ }
34
+ /**
35
+ * Classify project size based on file count and dependency count
36
+ *
37
+ * @param fileCount - Number of files in the project
38
+ * @param depCount - Number of dependencies
39
+ * @returns Project size classification
40
+ */
41
+ function classifyProjectSize(fileCount, depCount) {
42
+ const { small, medium, large } = PROJECT_SIZE_THRESHOLDS;
43
+ if (fileCount <= small.maxFiles && depCount <= small.maxDeps) {
44
+ return "small";
45
+ }
46
+ if (fileCount <= medium.maxFiles && depCount <= medium.maxDeps) {
47
+ return "medium";
48
+ }
49
+ if (fileCount <= large.maxFiles && depCount <= large.maxDeps) {
50
+ return "large";
51
+ }
52
+ return "enterprise";
53
+ }
54
+ /**
55
+ * Detect project kind (monorepo, library, application, unknown)
56
+ *
57
+ * @param project - The project information
58
+ * @returns Project kind
59
+ */
60
+ function detectProjectKind(project) {
61
+ // Check for monorepo indicators
62
+ const hasMonorepoIndicators = project.files.some((f) => f === "pnpm-workspace.yaml" ||
63
+ f === "lerna.json" ||
64
+ f === "nx.json" ||
65
+ f.startsWith("packages/") ||
66
+ f.startsWith("apps/"));
67
+ if (hasMonorepoIndicators) {
68
+ return "monorepo";
69
+ }
70
+ // Check for library indicators
71
+ const hasLibraryIndicators = project.files.some((f) => f === "tsup.config.ts" ||
72
+ f === "rollup.config.js" ||
73
+ f === "vite.config.lib.ts" ||
74
+ f.includes("dist/index"));
75
+ if (hasLibraryIndicators) {
76
+ return "library";
77
+ }
78
+ // Check for application indicators
79
+ const hasAppIndicators = project.frameworks.length > 0 ||
80
+ project.files.some((f) => f.includes("src/app") || f.includes("src/pages") || f.includes("src/routes"));
81
+ if (hasAppIndicators) {
82
+ return "application";
83
+ }
84
+ return "unknown";
85
+ }
86
+ /**
87
+ * Estimate team size from project characteristics
88
+ *
89
+ * Heuristic formula: (fileCount / 50) + (depCount / 10) + (langCount * 2)
90
+ *
91
+ * @param project - The project information
92
+ * @returns Estimated team size (1 = solo, 2-5 = small, 6-20 = medium, 21+ = large)
93
+ */
94
+ function estimateTeamSize(project) {
95
+ const fileCount = project.files.length;
96
+ const depCount = project.dependencies.length;
97
+ const langCount = project.languages.length;
98
+ // Calculate complexity score
99
+ const score = fileCount / 50 + depCount / 10 + langCount * 2;
100
+ // Map score to team size
101
+ if (score < 5)
102
+ return 1; // Solo developer
103
+ if (score < 15)
104
+ return 3; // Small team (2-5)
105
+ if (score < 40)
106
+ return 10; // Medium team (6-20)
107
+ return 25; // Large team (21+)
108
+ }
109
+ /**
110
+ * Detect workspace count for monorepo projects
111
+ *
112
+ * @param project - The project information
113
+ * @returns Number of workspaces/packages in the monorepo
114
+ */
115
+ function detectWorkspaceCount(project) {
116
+ // Detect packages/ or apps/ directories
117
+ const workspaceDirs = project.files.filter((f) => f.startsWith("packages/") || f.startsWith("apps/"));
118
+ // Extract unique workspace directories (first two path segments)
119
+ const uniqueDirs = new Set(workspaceDirs.map((f) => f.split("/").slice(0, 2).join("/")));
120
+ return uniqueDirs.size;
121
+ }
122
+ //# sourceMappingURL=metadata-analyzer.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-analyzer.service.js","sourceRoot":"","sources":["../../../src/services/analyzer/metadata-analyzer.service.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"project-analyzer.service.d.ts","sourceRoot":"","sources":["../../../src/services/analyzer/project-analyzer.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAahE;;GAEG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAmC9E"}
1
+ {"version":3,"file":"project-analyzer.service.d.ts","sourceRoot":"","sources":["../../../src/services/analyzer/project-analyzer.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAchE;;GAEG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA2C9E"}
@@ -7,6 +7,7 @@ import { readdir } from "node:fs/promises";
7
7
  import { extname, join } from "node:path";
8
8
  import { FILE_SCAN_CONFIG, SKIP_DIRECTORIES } from "../../config/constants.js";
9
9
  import { CONFIG_FILE_MAPPINGS, EXTENSION_TO_LANGUAGE } from "../../config/file-mappings.js";
10
+ import { analyzeMetadata } from "./metadata-analyzer.service.js";
10
11
  import { parseBuildGradle } from "./parsers/build-gradle.parser.js";
11
12
  import { parseCargoToml } from "./parsers/cargo-toml.parser.js";
12
13
  import { parseComposerJson } from "./parsers/composer-json.parser.js";
@@ -48,6 +49,14 @@ export async function analyzeProject(projectPath) {
48
49
  info.languages = [...new Set(info.languages)];
49
50
  info.dependencies = [...new Set(info.dependencies)];
50
51
  info.frameworks = [...new Set(info.frameworks)];
52
+ // Analyze project metadata (size, kind, team scale)
53
+ try {
54
+ info.metadata = analyzeMetadata(info);
55
+ }
56
+ catch (metadataError) {
57
+ console.error("Error analyzing project metadata:", metadataError);
58
+ // Continue without metadata (it's optional)
59
+ }
51
60
  }
52
61
  catch (error) {
53
62
  console.error("Error analyzing project:", error);
@@ -1 +1 @@
1
- {"version":3,"file":"project-analyzer.service.js","sourceRoot":"","sources":["../../../src/services/analyzer/project-analyzer.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-analyzer.service.js","sourceRoot":"","sources":["../../../src/services/analyzer/project-analyzer.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE5F,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAE5E;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,WAAmB;IACtD,MAAM,IAAI,GAAgB;QACxB,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,EAAE;QACb,YAAY,EAAE,EAAE;QAChB,KAAK,EAAE,EAAE;QACT,UAAU,EAAE,EAAE;KACf,CAAC;IAEF,IAAI,CAAC;QACH,aAAa;QACb,MAAM,aAAa,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE1C,yBAAyB;QACzB,MAAM,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,oBAAoB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC9C,MAAM,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC5C,MAAM,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACpC,MAAM,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,iBAAiB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAE5C,cAAc;QACd,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAEhD,oDAAoD;QACpD,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,aAAa,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,aAAa,CAAC,CAAC;YAClE,4CAA4C;QAC9C,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,IAAiB,EAAE,KAAa;IAC5E,wBAAwB;IACxB,IAAI,KAAK,GAAG,gBAAgB,CAAC,QAAQ;QAAE,OAAO;IAE9C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAEhE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;YAE3D,kCAAkC;YAClC,IAAI,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YAE9C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,+BAA+B;gBAC/B,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjD,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,OAAO,CAAC,SAAS;wBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBAC/D,IAAI,OAAO,CAAC,QAAQ;wBAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC9D,CAAC;gBAED,UAAU;gBACV,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YACjD,CAAC;iBAAM,CAAC;gBACN,wCAAwC;gBACxC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC;oBAClD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAChC,CAAC;gBAED,qBAAqB;gBACrB,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CACtD,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,KAAK,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,GAAG,EAAE,CAAC,CAClE,CAAC;gBACF,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,OAAO,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;oBAChD,IAAI,OAAO,CAAC,SAAS;wBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBAC/D,IAAI,OAAO,CAAC,QAAQ;wBAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC9D,CAAC;gBAED,iCAAiC;gBACjC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC9C,MAAM,IAAI,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;gBACxC,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACvC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,IAAa,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC1E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"recommendation.service.d.ts","sourceRoot":"","sources":["../../../src/services/recommender/recommendation.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAItF,qCAAqC;AACrC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,KAAK,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;CAClC,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,sBAAsB,EAChC,OAAO,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,gBAAqB,GAC7B,oBAAoB,EAAE,CA8BxB"}
1
+ {"version":3,"file":"recommendation.service.d.ts","sourceRoot":"","sources":["../../../src/services/recommender/recommendation.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1F,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAKtF,qCAAqC;AACrC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,KAAK,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;CAClC,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,sBAAsB,EAChC,OAAO,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,gBAAqB,GAC7B,oBAAoB,EAAE,CAmDxB"}
@@ -3,8 +3,10 @@
3
3
  *
4
4
  * Main service for generating recommendations based on project analysis
5
5
  */
6
+ import { ENHANCED_SCORING_FLAGS } from "../../config/enhanced-scoring-config.js";
6
7
  import { calculateQualityScore } from "./quality-scorer.js";
7
8
  import { calculateScore } from "./scoring/scorer.js";
9
+ import { buildSimilarityMatrix } from "./scoring/similarity-scorer.js";
8
10
  /**
9
11
  * Generate recommendations based on project analysis
10
12
  *
@@ -16,20 +18,36 @@ import { calculateScore } from "./scoring/scorer.js";
16
18
  */
17
19
  export function recommend(database, project, userQuery, options = {}) {
18
20
  const { maxResults = 20, minScore = 1, types } = options;
21
+ // Build similarity matrix once (if feature is enabled)
22
+ let similarityMatrix;
23
+ if (ENHANCED_SCORING_FLAGS.enableSimilarityScoring) {
24
+ similarityMatrix = buildSimilarityMatrix(database);
25
+ }
19
26
  const results = [];
20
27
  for (const item of database.items) {
21
28
  // Filter by type if specified
22
29
  if (types && !types.includes(item.type)) {
23
30
  continue;
24
31
  }
25
- const { score: matchScore, reasons } = calculateScore(item, project, userQuery);
32
+ const { score: matchScore, reasons, breakdown, } = calculateScore(item, project, userQuery, { similarityMatrix });
26
33
  // Calculate quality score (0-100)
27
34
  const qualityScore = calculateQualityScore(item).total;
28
35
  // Combine match score and quality score
29
36
  // Match score is primary (0-100), quality score is a bonus (0-20)
30
37
  const finalScore = matchScore + qualityScore * 0.2;
31
38
  if (finalScore >= minScore) {
32
- results.push({ item, score: finalScore, reasons });
39
+ results.push({
40
+ item,
41
+ score: finalScore,
42
+ reasons,
43
+ breakdown: breakdown
44
+ ? {
45
+ ...breakdown,
46
+ qualityScore: qualityScore * 0.2,
47
+ finalScore,
48
+ }
49
+ : undefined,
50
+ });
33
51
  }
34
52
  }
35
53
  // Sort by score descending
@@ -1 +1 @@
1
- {"version":3,"file":"recommendation.service.js","sourceRoot":"","sources":["../../../src/services/recommender/recommendation.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAYrD;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CACvB,QAAgC,EAChC,OAAoB,EACpB,SAAkB,EAClB,UAA4B,EAAE;IAE9B,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEzD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,8BAA8B;QAC9B,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,SAAS;QACX,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAEhF,kCAAkC;QAClC,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;QAEvD,wCAAwC;QACxC,kEAAkE;QAClE,MAAM,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,GAAG,CAAC;QAEnD,IAAI,UAAU,IAAI,QAAQ,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAE1C,qBAAqB;IACrB,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"recommendation.service.js","sourceRoot":"","sources":["../../../src/services/recommender/recommendation.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAIjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAYvE;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CACvB,QAAgC,EAChC,OAAoB,EACpB,SAAkB,EAClB,UAA4B,EAAE;IAE9B,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEzD,uDAAuD;IACvD,IAAI,gBAA8C,CAAC;IACnD,IAAI,sBAAsB,CAAC,uBAAuB,EAAE,CAAC;QACnD,gBAAgB,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,8BAA8B;QAC9B,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,SAAS;QACX,CAAC;QAED,MAAM,EACJ,KAAK,EAAE,UAAU,EACjB,OAAO,EACP,SAAS,GACV,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAEnE,kCAAkC;QAClC,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;QAEvD,wCAAwC;QACxC,kEAAkE;QAClE,MAAM,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,GAAG,CAAC;QAEnD,IAAI,UAAU,IAAI,QAAQ,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI;gBACJ,KAAK,EAAE,UAAU;gBACjB,OAAO;gBACP,SAAS,EAAE,SAAS;oBAClB,CAAC,CAAC;wBACE,GAAG,SAAS;wBACZ,YAAY,EAAE,YAAY,GAAG,GAAG;wBAChC,UAAU;qBACX;oBACH,CAAC,CAAC,SAAS;aACd,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAE1C,qBAAqB;IACrB,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Context Scorer
3
+ *
4
+ * Calculates context-based scores for recommendations
5
+ * (project size, team scale, monorepo, etc.)
6
+ */
7
+ import type { Recommendation } from "../../../types/domain-types.js";
8
+ import type { ProjectMetadata } from "../../../types/scoring-types.js";
9
+ /**
10
+ * Calculate context score for a recommendation
11
+ *
12
+ * @param item - The recommendation item
13
+ * @param metadata - Project metadata
14
+ * @returns Score and reasons
15
+ */
16
+ export declare function calculateContextScore(item: Recommendation, metadata: ProjectMetadata): {
17
+ score: number;
18
+ reasons: string[];
19
+ };
20
+ //# sourceMappingURL=context-scorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-scorer.d.ts","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/context-scorer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,eAAe,GACxB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA+BtC"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Context Scorer
3
+ *
4
+ * Calculates context-based scores for recommendations
5
+ * (project size, team scale, monorepo, etc.)
6
+ */
7
+ import { CONTEXT_SCORE_WEIGHTS } from "../../../config/enhanced-scoring-config.js";
8
+ /**
9
+ * Calculate context score for a recommendation
10
+ *
11
+ * @param item - The recommendation item
12
+ * @param metadata - Project metadata
13
+ * @returns Score and reasons
14
+ */
15
+ export function calculateContextScore(item, metadata) {
16
+ let score = 0;
17
+ const reasons = [];
18
+ // 1. Monorepo bonus
19
+ if (metadata.kind === "monorepo") {
20
+ const isMonorepoTool = item.tags.some((tag) => ["monorepo", "workspace", "nx", "turborepo", "lerna", "pnpm"].includes(tag.toLowerCase()));
21
+ if (isMonorepoTool) {
22
+ score += CONTEXT_SCORE_WEIGHTS.monorepoBonus;
23
+ reasons.push("モノレポ対応");
24
+ }
25
+ }
26
+ // 2. Project size match
27
+ const sizeScore = calculateSizeMatchScore(item, metadata);
28
+ if (sizeScore > 0) {
29
+ score += sizeScore;
30
+ reasons.push(`${metadata.size}プロジェクト向け`);
31
+ }
32
+ // 3. Team size match
33
+ const teamScore = calculateTeamSizeScore(item, metadata);
34
+ if (teamScore > 0) {
35
+ score += teamScore;
36
+ reasons.push("チーム規模適合");
37
+ }
38
+ return { score, reasons };
39
+ }
40
+ /**
41
+ * Calculate score based on project size match
42
+ *
43
+ * @param item - The recommendation item
44
+ * @param metadata - Project metadata
45
+ * @returns Size match score
46
+ */
47
+ function calculateSizeMatchScore(item, metadata) {
48
+ // Enterprise/large project tools
49
+ const enterpriseTools = ["ci/cd", "monitoring", "testing", "documentation"];
50
+ if (metadata.size === "enterprise" || metadata.size === "large") {
51
+ const hasEnterpriseTag = item.tags.some((tag) => enterpriseTools.some((et) => tag.toLowerCase().includes(et)));
52
+ if (hasEnterpriseTag) {
53
+ return CONTEXT_SCORE_WEIGHTS.sizeMatch;
54
+ }
55
+ }
56
+ // Small project tools
57
+ const smallTools = ["quick-start", "beginner", "simple", "lightweight"];
58
+ if (metadata.size === "small") {
59
+ const hasSmallTag = item.tags.some((tag) => smallTools.some((st) => tag.toLowerCase().includes(st)));
60
+ if (hasSmallTag) {
61
+ return CONTEXT_SCORE_WEIGHTS.sizeMatch;
62
+ }
63
+ }
64
+ return 0;
65
+ }
66
+ /**
67
+ * Calculate score based on team size match
68
+ *
69
+ * @param item - The recommendation item
70
+ * @param metadata - Project metadata
71
+ * @returns Team size match score
72
+ */
73
+ function calculateTeamSizeScore(item, metadata) {
74
+ // Collaboration tools for teams
75
+ const collaborationTools = ["collaboration", "team", "review", "workflow"];
76
+ if (metadata.estimatedTeamSize > 5) {
77
+ const hasCollabTag = item.tags.some((tag) => collaborationTools.some((ct) => tag.toLowerCase().includes(ct)));
78
+ if (hasCollabTag) {
79
+ return CONTEXT_SCORE_WEIGHTS.teamSizeMatch;
80
+ }
81
+ }
82
+ return 0;
83
+ }
84
+ //# sourceMappingURL=context-scorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-scorer.js","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/context-scorer.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@
4
4
  * Calculates match scores for recommendations based on project information
5
5
  */
6
6
  import type { Recommendation } from "../../../types/domain-types.js";
7
+ import type { ScoreBreakdown, SimilarityMatrix } from "../../../types/scoring-types.js";
7
8
  import type { ProjectInfo } from "../../../types/service-types.js";
8
9
  /**
9
10
  * Calculate match score for a recommendation item
@@ -11,11 +12,15 @@ import type { ProjectInfo } from "../../../types/service-types.js";
11
12
  * @param item - The recommendation item to score
12
13
  * @param project - The project information to match against
13
14
  * @param userQuery - Optional user search query
14
- * @returns Score and reasons for the match
15
+ * @param options - Optional scoring options
16
+ * @returns Score, reasons, and optional breakdown
15
17
  */
16
- export declare function calculateScore(item: Recommendation, project: ProjectInfo, userQuery?: string): {
18
+ export declare function calculateScore(item: Recommendation, project: ProjectInfo, userQuery?: string, options?: {
19
+ similarityMatrix?: SimilarityMatrix;
20
+ }): {
17
21
  score: number;
18
22
  reasons: string[];
23
+ breakdown?: ScoreBreakdown;
19
24
  };
20
25
  /**
21
26
  * Get score indicator emoji and text
@@ -1 +1 @@
1
- {"version":3,"file":"scorer.d.ts","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/scorer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGnE;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA0FtC;AAkBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKvD"}
1
+ {"version":3,"file":"scorer.d.ts","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/scorer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAKnE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IAAE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CAAE,GAChD;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,cAAc,CAAA;CAAE,CAkIlE;AAkBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKvD"}
@@ -3,17 +3,21 @@
3
3
  *
4
4
  * Calculates match scores for recommendations based on project information
5
5
  */
6
+ import { ENHANCED_SCORING_FLAGS } from "../../../config/enhanced-scoring-config.js";
6
7
  import { SCORING_MULTIPLIERS, SCORING_THRESHOLDS, SCORING_WEIGHTS, } from "../../../config/scoring-config.js";
7
8
  import { matchGlob } from "../../../utils/glob-matcher.js";
9
+ import { calculateContextScore } from "./context-scorer.js";
10
+ import { calculateSimilarityScore, extractProjectTags } from "./similarity-scorer.js";
8
11
  /**
9
12
  * Calculate match score for a recommendation item
10
13
  *
11
14
  * @param item - The recommendation item to score
12
15
  * @param project - The project information to match against
13
16
  * @param userQuery - Optional user search query
14
- * @returns Score and reasons for the match
17
+ * @param options - Optional scoring options
18
+ * @returns Score, reasons, and optional breakdown
15
19
  */
16
- export function calculateScore(item, project, userQuery) {
20
+ export function calculateScore(item, project, userQuery, options) {
17
21
  let score = 0;
18
22
  const reasons = [];
19
23
  const detection = item.detection;
@@ -80,9 +84,42 @@ export function calculateScore(item, project, userQuery) {
80
84
  score *= SCORING_MULTIPLIERS.lowSecurity;
81
85
  }
82
86
  }
87
+ // Store base score (before context scoring)
88
+ const baseScore = score;
89
+ // 7. Context scoring (project size, monorepo, team scale)
90
+ let contextScore = 0;
91
+ const contextReasons = [];
92
+ if (ENHANCED_SCORING_FLAGS.enableContextScoring && project.metadata) {
93
+ const context = calculateContextScore(item, project.metadata);
94
+ contextScore = context.score;
95
+ contextReasons.push(...context.reasons);
96
+ }
97
+ // 8. Similarity scoring (tag co-occurrence)
98
+ let similarityScore = 0;
99
+ const similarityReasons = [];
100
+ if (ENHANCED_SCORING_FLAGS.enableSimilarityScoring && options?.similarityMatrix) {
101
+ const projectTags = extractProjectTags(project);
102
+ const similarity = calculateSimilarityScore(item, projectTags, options.similarityMatrix);
103
+ similarityScore = similarity.score;
104
+ similarityReasons.push(...similarity.reasons);
105
+ }
106
+ // Combine scores
107
+ const totalRawScore = score + contextScore + similarityScore;
83
108
  // Normalize score to 1-100 range
84
- const normalizedScore = normalizeScore(score);
85
- return { score: normalizedScore, reasons };
109
+ const normalizedScore = normalizeScore(totalRawScore);
110
+ // Build breakdown
111
+ const breakdown = {
112
+ baseScore,
113
+ contextScore,
114
+ similarityScore,
115
+ qualityScore: 0, // Will be set by recommendation.service
116
+ finalScore: normalizedScore,
117
+ };
118
+ return {
119
+ score: normalizedScore,
120
+ reasons: [...reasons, ...contextReasons, ...similarityReasons],
121
+ breakdown,
122
+ };
86
123
  }
87
124
  /**
88
125
  * Normalize raw score to 1-100 range
@@ -1 +1 @@
1
- {"version":3,"file":"scorer.js","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/scorer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scorer.js","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/scorer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Similarity Scorer
3
+ *
4
+ * Calculates semantic similarity scores based on tag co-occurrence
5
+ */
6
+ import type { Recommendation, RecommendationDatabase } from "../../../types/domain-types.js";
7
+ import type { SimilarityMatrix } from "../../../types/scoring-types.js";
8
+ import type { ProjectInfo } from "../../../types/service-types.js";
9
+ /**
10
+ * Extract tags from project information
11
+ *
12
+ * @param project - The project information
13
+ * @returns Array of normalized tags (languages + frameworks + top 10 dependencies)
14
+ */
15
+ export declare function extractProjectTags(project: ProjectInfo): string[];
16
+ /**
17
+ * Build similarity matrix from recommendation database
18
+ *
19
+ * @param database - The recommendations database
20
+ * @returns Similarity matrix with co-occurrence counts
21
+ */
22
+ export declare function buildSimilarityMatrix(database: RecommendationDatabase): SimilarityMatrix;
23
+ /**
24
+ * Calculate similarity score between item tags and project tags
25
+ *
26
+ * @param item - The recommendation item
27
+ * @param projectTags - Tags extracted from project (already normalized)
28
+ * @param matrix - Similarity matrix
29
+ * @returns Similarity score and reasons
30
+ */
31
+ export declare function calculateSimilarityScore(item: Recommendation, projectTags: string[], matrix: SimilarityMatrix): {
32
+ score: number;
33
+ reasons: string[];
34
+ };
35
+ //# sourceMappingURL=similarity-scorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"similarity-scorer.d.ts","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/similarity-scorer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,EAAE,CASjE;AA0BD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,gBAAgB,CAsBxF;AAyCD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,cAAc,EACpB,WAAW,EAAE,MAAM,EAAE,EACrB,MAAM,EAAE,gBAAgB,GACvB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA6BtC"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Similarity Scorer
3
+ *
4
+ * Calculates semantic similarity scores based on tag co-occurrence
5
+ */
6
+ import { SIMILARITY_THRESHOLDS } from "../../../config/enhanced-scoring-config.js";
7
+ /**
8
+ * Extract tags from project information
9
+ *
10
+ * @param project - The project information
11
+ * @returns Array of normalized tags (languages + frameworks + top 10 dependencies)
12
+ */
13
+ export function extractProjectTags(project) {
14
+ const tags = [
15
+ ...project.languages,
16
+ ...project.frameworks,
17
+ ...project.dependencies.slice(0, 10),
18
+ ];
19
+ // Normalize to lowercase for consistent matching
20
+ return tags.map((tag) => tag.toLowerCase());
21
+ }
22
+ /**
23
+ * Increment co-occurrence count bidirectionally
24
+ */
25
+ function incrementCooccurrence(cooccurrence, tag1, tag2) {
26
+ // Initialize maps if needed
27
+ if (!cooccurrence.has(tag1)) {
28
+ cooccurrence.set(tag1, new Map());
29
+ }
30
+ if (!cooccurrence.has(tag2)) {
31
+ cooccurrence.set(tag2, new Map());
32
+ }
33
+ // Increment bidirectional counts
34
+ const count1to2 = cooccurrence.get(tag1)?.get(tag2) || 0;
35
+ const count2to1 = cooccurrence.get(tag2)?.get(tag1) || 0;
36
+ cooccurrence.get(tag1)?.set(tag2, count1to2 + 1);
37
+ cooccurrence.get(tag2)?.set(tag1, count2to1 + 1);
38
+ }
39
+ /**
40
+ * Build similarity matrix from recommendation database
41
+ *
42
+ * @param database - The recommendations database
43
+ * @returns Similarity matrix with co-occurrence counts
44
+ */
45
+ export function buildSimilarityMatrix(database) {
46
+ const cooccurrence = new Map();
47
+ const tagCounts = new Map();
48
+ for (const item of database.items) {
49
+ // Normalize tags to lowercase and remove duplicates
50
+ const tags = [...new Set(item.tags.map((t) => t.toLowerCase()))];
51
+ // Count each tag
52
+ for (const tag of tags) {
53
+ tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);
54
+ }
55
+ // Count tag pairs (co-occurrence)
56
+ for (let i = 0; i < tags.length; i++) {
57
+ for (let j = i + 1; j < tags.length; j++) {
58
+ incrementCooccurrence(cooccurrence, tags[i], tags[j]);
59
+ }
60
+ }
61
+ }
62
+ return { cooccurrence, tagCounts };
63
+ }
64
+ /**
65
+ * Calculate Jaccard similarity between two tags
66
+ *
67
+ * Jaccard similarity = |intersection| / |union|
68
+ *
69
+ * @param tag1 - First tag
70
+ * @param tag2 - Second tag
71
+ * @param cooccurrence - Co-occurrence map
72
+ * @param tagCounts - Tag counts map
73
+ * @returns Jaccard similarity score (0-1)
74
+ */
75
+ function calculateJaccardSimilarity(tag1, tag2, cooccurrence, tagCounts) {
76
+ // Same tag = perfect similarity
77
+ if (tag1 === tag2)
78
+ return 1.0;
79
+ // Get co-occurrence count
80
+ const cooccur = cooccurrence.get(tag1)?.get(tag2) || 0;
81
+ // If co-occurrence is below threshold, consider them unrelated
82
+ if (cooccur < SIMILARITY_THRESHOLDS.minCooccurrence) {
83
+ return 0;
84
+ }
85
+ // Get individual counts
86
+ const count1 = tagCounts.get(tag1) || 0;
87
+ const count2 = tagCounts.get(tag2) || 0;
88
+ // Calculate Jaccard: |A ∩ B| / |A ∪ B|
89
+ const intersection = cooccur;
90
+ const union = count1 + count2 - cooccur;
91
+ return union > 0 ? intersection / union : 0;
92
+ }
93
+ /**
94
+ * Calculate similarity score between item tags and project tags
95
+ *
96
+ * @param item - The recommendation item
97
+ * @param projectTags - Tags extracted from project (already normalized)
98
+ * @param matrix - Similarity matrix
99
+ * @returns Similarity score and reasons
100
+ */
101
+ export function calculateSimilarityScore(item, projectTags, matrix) {
102
+ let totalSimilarity = 0;
103
+ const reasons = [];
104
+ // Normalize item tags to lowercase
105
+ const itemTags = item.tags.map((t) => t.toLowerCase());
106
+ // Calculate similarity for each pair
107
+ for (const projectTag of projectTags) {
108
+ for (const itemTag of itemTags) {
109
+ const similarity = calculateJaccardSimilarity(projectTag, itemTag, matrix.cooccurrence, matrix.tagCounts);
110
+ // Only add if above threshold
111
+ if (similarity >= SIMILARITY_THRESHOLDS.minJaccardSimilarity) {
112
+ totalSimilarity += similarity;
113
+ reasons.push(`類似タグ: ${projectTag} ≈ ${itemTag}`);
114
+ }
115
+ }
116
+ }
117
+ // Cap at max bonus
118
+ const score = Math.min(totalSimilarity, SIMILARITY_THRESHOLDS.maxSimilarityBonus);
119
+ return { score, reasons };
120
+ }
121
+ //# sourceMappingURL=similarity-scorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"similarity-scorer.js","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/similarity-scorer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Scoring Types
3
+ *
4
+ * Types for enhanced scoring features (context understanding and semantic similarity)
5
+ */
6
+ /** プロジェクトのサイズ分類 */
7
+ export type ProjectSize = "small" | "medium" | "large" | "enterprise";
8
+ /** プロジェクトの種類 */
9
+ export type ProjectKind = "monorepo" | "library" | "application" | "unknown";
10
+ /** プロジェクトメタデータ */
11
+ export type ProjectMetadata = {
12
+ /** プロジェクトサイズ */
13
+ size: ProjectSize;
14
+ /** プロジェクトの種類 */
15
+ kind: ProjectKind;
16
+ /** 推定チームサイズ (1: 個人, 2-5: 小規模, 6-20: 中規模, 21+: 大規模) */
17
+ estimatedTeamSize: number;
18
+ /** ワークスペース/パッケージ数(モノレポの場合) */
19
+ workspaceCount?: number;
20
+ /** ファイル総数 */
21
+ fileCount: number;
22
+ /** 言語数 */
23
+ languageCount: number;
24
+ };
25
+ /** タグの共起行列データ */
26
+ export type SimilarityMatrix = {
27
+ /** タグペアごとの共起カウント */
28
+ cooccurrence: Map<string, Map<string, number>>;
29
+ /** 各タグの出現総数 */
30
+ tagCounts: Map<string, number>;
31
+ };
32
+ /** スコアの内訳 */
33
+ export type ScoreBreakdown = {
34
+ /** 基本マッチスコア (言語、フレームワーク、依存関係、ファイル) */
35
+ baseScore: number;
36
+ /** コンテキストスコア (プロジェクトサイズ、チーム規模、モノレポ) */
37
+ contextScore: number;
38
+ /** 類似性スコア (タグの共起関係) */
39
+ similarityScore: number;
40
+ /** 品質スコア (公式性、スター、鮮度、ソース) */
41
+ qualityScore: number;
42
+ /** 最終スコア */
43
+ finalScore: number;
44
+ };
45
+ //# sourceMappingURL=scoring-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring-types.d.ts","sourceRoot":"","sources":["../../src/types/scoring-types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,mBAAmB;AACnB,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;AAEtE,gBAAgB;AAChB,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;AAE7E,kBAAkB;AAClB,MAAM,MAAM,eAAe,GAAG;IAC5B,gBAAgB;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,gBAAgB;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,sDAAsD;IACtD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8BAA8B;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU;IACV,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,iBAAiB;AACjB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,oBAAoB;IACpB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,eAAe;IACf,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAAC;AAEF,aAAa;AACb,MAAM,MAAM,cAAc,GAAG;IAC3B,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Scoring Types
3
+ *
4
+ * Types for enhanced scoring features (context understanding and semantic similarity)
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=scoring-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring-types.js","sourceRoot":"","sources":["../../src/types/scoring-types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -4,6 +4,7 @@
4
4
  * Types for service layer inputs and outputs
5
5
  */
6
6
  import type { Recommendation } from "./domain-types.js";
7
+ import type { ProjectMetadata, ScoreBreakdown } from "./scoring-types.js";
7
8
  /** プロジェクト情報 (分析結果) */
8
9
  export type ProjectInfo = {
9
10
  /** プロジェクトパス */
@@ -18,11 +19,15 @@ export type ProjectInfo = {
18
19
  frameworks: string[];
19
20
  /** プロジェクト説明 (README等から) */
20
21
  description?: string;
22
+ /** プロジェクトメタデータ (サイズ、種類、チーム規模等) */
23
+ metadata?: ProjectMetadata;
21
24
  };
22
25
  /** スコア付きレコメンデーション */
23
26
  export type ScoredRecommendation = {
24
27
  item: Recommendation;
25
28
  score: number;
26
29
  reasons: string[];
30
+ /** スコアの内訳 (拡張スコアリングが有効な場合) */
31
+ breakdown?: ScoreBreakdown;
27
32
  };
28
33
  //# sourceMappingURL=service-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-types.d.ts","sourceRoot":"","sources":["../../src/types/service-types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,sBAAsB;AACtB,MAAM,MAAM,WAAW,GAAG;IACxB,eAAe;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW;IACX,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kDAAkD;IAClD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,qBAAqB;AACrB,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC"}
1
+ {"version":3,"file":"service-types.d.ts","sourceRoot":"","sources":["../../src/types/service-types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE1E,sBAAsB;AACtB,MAAM,MAAM,WAAW,GAAG;IACxB,eAAe;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW;IACX,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kDAAkD;IAClD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B,CAAC;AAEF,qBAAqB;AACrB,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-recommender",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "MCP server for recommending Claude Code skills, plugins, and MCP servers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",