@4da/mcp-server 3.2.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 (123) hide show
  1. package/README.md +135 -0
  2. package/dist/db.d.ts +64 -0
  3. package/dist/db.d.ts.map +1 -0
  4. package/dist/db.js +578 -0
  5. package/dist/db.js.map +1 -0
  6. package/dist/index.d.ts +37 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +422 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/llm.d.ts +144 -0
  11. package/dist/llm.d.ts.map +1 -0
  12. package/dist/llm.js +447 -0
  13. package/dist/llm.js.map +1 -0
  14. package/dist/output-manager.d.ts +156 -0
  15. package/dist/output-manager.d.ts.map +1 -0
  16. package/dist/output-manager.js +156 -0
  17. package/dist/output-manager.js.map +1 -0
  18. package/dist/schema-registry.d.ts +46 -0
  19. package/dist/schema-registry.d.ts.map +1 -0
  20. package/dist/schema-registry.js +133 -0
  21. package/dist/schema-registry.js.map +1 -0
  22. package/dist/schemas/config-validator.json +18 -0
  23. package/dist/schemas/context-analysis.json +25 -0
  24. package/dist/schemas/daily-briefing.json +34 -0
  25. package/dist/schemas/explain-relevance.json +19 -0
  26. package/dist/schemas/get-actionable-signals.json +29 -0
  27. package/dist/schemas/get-context.json +17 -0
  28. package/dist/schemas/get-relevant-content.json +26 -0
  29. package/dist/schemas/llm-status.json +13 -0
  30. package/dist/schemas/record-feedback.json +24 -0
  31. package/dist/schemas/score-autopsy.json +30 -0
  32. package/dist/schemas/source-health.json +17 -0
  33. package/dist/schemas/topic-connections.json +34 -0
  34. package/dist/schemas/trend-analysis.json +29 -0
  35. package/dist/tools/attention-report.d.ts +39 -0
  36. package/dist/tools/attention-report.d.ts.map +1 -0
  37. package/dist/tools/attention-report.js +72 -0
  38. package/dist/tools/attention-report.js.map +1 -0
  39. package/dist/tools/config-validator.d.ts +59 -0
  40. package/dist/tools/config-validator.d.ts.map +1 -0
  41. package/dist/tools/config-validator.js +375 -0
  42. package/dist/tools/config-validator.js.map +1 -0
  43. package/dist/tools/context-analysis.d.ts +108 -0
  44. package/dist/tools/context-analysis.d.ts.map +1 -0
  45. package/dist/tools/context-analysis.js +300 -0
  46. package/dist/tools/context-analysis.js.map +1 -0
  47. package/dist/tools/daily-briefing.d.ts +103 -0
  48. package/dist/tools/daily-briefing.d.ts.map +1 -0
  49. package/dist/tools/daily-briefing.js +278 -0
  50. package/dist/tools/daily-briefing.js.map +1 -0
  51. package/dist/tools/explain-relevance.d.ts +36 -0
  52. package/dist/tools/explain-relevance.d.ts.map +1 -0
  53. package/dist/tools/explain-relevance.js +50 -0
  54. package/dist/tools/explain-relevance.js.map +1 -0
  55. package/dist/tools/export-context.d.ts +43 -0
  56. package/dist/tools/export-context.d.ts.map +1 -0
  57. package/dist/tools/export-context.js +104 -0
  58. package/dist/tools/export-context.js.map +1 -0
  59. package/dist/tools/get-actionable-signals.d.ts +65 -0
  60. package/dist/tools/get-actionable-signals.d.ts.map +1 -0
  61. package/dist/tools/get-actionable-signals.js +268 -0
  62. package/dist/tools/get-actionable-signals.js.map +1 -0
  63. package/dist/tools/get-context.d.ts +34 -0
  64. package/dist/tools/get-context.d.ts.map +1 -0
  65. package/dist/tools/get-context.js +43 -0
  66. package/dist/tools/get-context.js.map +1 -0
  67. package/dist/tools/get-relevant-content.d.ts +44 -0
  68. package/dist/tools/get-relevant-content.d.ts.map +1 -0
  69. package/dist/tools/get-relevant-content.js +56 -0
  70. package/dist/tools/get-relevant-content.js.map +1 -0
  71. package/dist/tools/index.d.ts +40 -0
  72. package/dist/tools/index.d.ts.map +1 -0
  73. package/dist/tools/index.js +44 -0
  74. package/dist/tools/index.js.map +1 -0
  75. package/dist/tools/knowledge-gaps.d.ts +36 -0
  76. package/dist/tools/knowledge-gaps.d.ts.map +1 -0
  77. package/dist/tools/knowledge-gaps.js +76 -0
  78. package/dist/tools/knowledge-gaps.js.map +1 -0
  79. package/dist/tools/llm-status.d.ts +45 -0
  80. package/dist/tools/llm-status.d.ts.map +1 -0
  81. package/dist/tools/llm-status.js +92 -0
  82. package/dist/tools/llm-status.js.map +1 -0
  83. package/dist/tools/project-health.d.ts +41 -0
  84. package/dist/tools/project-health.d.ts.map +1 -0
  85. package/dist/tools/project-health.js +71 -0
  86. package/dist/tools/project-health.js.map +1 -0
  87. package/dist/tools/record-feedback.d.ts +39 -0
  88. package/dist/tools/record-feedback.d.ts.map +1 -0
  89. package/dist/tools/record-feedback.js +60 -0
  90. package/dist/tools/record-feedback.js.map +1 -0
  91. package/dist/tools/reverse-mentions.d.ts +38 -0
  92. package/dist/tools/reverse-mentions.d.ts.map +1 -0
  93. package/dist/tools/reverse-mentions.js +57 -0
  94. package/dist/tools/reverse-mentions.js.map +1 -0
  95. package/dist/tools/score-autopsy.d.ts +93 -0
  96. package/dist/tools/score-autopsy.d.ts.map +1 -0
  97. package/dist/tools/score-autopsy.js +288 -0
  98. package/dist/tools/score-autopsy.js.map +1 -0
  99. package/dist/tools/semantic-shifts.d.ts +37 -0
  100. package/dist/tools/semantic-shifts.d.ts.map +1 -0
  101. package/dist/tools/semantic-shifts.js +73 -0
  102. package/dist/tools/semantic-shifts.js.map +1 -0
  103. package/dist/tools/signal-chains.d.ts +45 -0
  104. package/dist/tools/signal-chains.d.ts.map +1 -0
  105. package/dist/tools/signal-chains.js +60 -0
  106. package/dist/tools/signal-chains.js.map +1 -0
  107. package/dist/tools/source-health.d.ts +64 -0
  108. package/dist/tools/source-health.d.ts.map +1 -0
  109. package/dist/tools/source-health.js +176 -0
  110. package/dist/tools/source-health.js.map +1 -0
  111. package/dist/tools/topic-connections.d.ts +112 -0
  112. package/dist/tools/topic-connections.d.ts.map +1 -0
  113. package/dist/tools/topic-connections.js +318 -0
  114. package/dist/tools/topic-connections.js.map +1 -0
  115. package/dist/tools/trend-analysis.d.ts +105 -0
  116. package/dist/tools/trend-analysis.d.ts.map +1 -0
  117. package/dist/tools/trend-analysis.js +295 -0
  118. package/dist/tools/trend-analysis.js.map +1 -0
  119. package/dist/types.d.ts +163 -0
  120. package/dist/types.d.ts.map +1 -0
  121. package/dist/types.js +7 -0
  122. package/dist/types.js.map +1 -0
  123. package/package.json +61 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * knowledge_gaps tool
3
+ *
4
+ * Detect knowledge gaps - dependencies with relevant content you haven't engaged with.
5
+ */
6
+ export const knowledgeGapsTool = {
7
+ name: "knowledge_gaps",
8
+ description: `Detect knowledge gaps by cross-referencing your project dependencies with source items you haven't engaged with. Identifies things you should know about but might have missed.`,
9
+ inputSchema: {
10
+ type: "object",
11
+ properties: {
12
+ min_severity: {
13
+ type: "string",
14
+ enum: ["critical", "high", "medium", "low"],
15
+ description: "Minimum gap severity to include. Default: medium",
16
+ default: "medium",
17
+ },
18
+ },
19
+ },
20
+ };
21
+ export function executeKnowledgeGaps(db, params) {
22
+ const rawDb = db.getRawDb();
23
+ // Get all tracked dependencies
24
+ const deps = rawDb
25
+ .prepare("SELECT package_name, version, project_path, language FROM project_dependencies")
26
+ .all();
27
+ if (deps.length === 0) {
28
+ return {
29
+ gaps: [],
30
+ summary: "No project dependencies tracked. Add context directories to enable knowledge gap detection.",
31
+ };
32
+ }
33
+ const gaps = [];
34
+ for (const dep of deps) {
35
+ // Find source items mentioning this dependency
36
+ const pattern = `%${dep.package_name}%`;
37
+ const mentionedItems = rawDb
38
+ .prepare(`SELECT si.id, si.title, si.url, si.source_type, si.created_at
39
+ FROM source_items si
40
+ WHERE (si.title LIKE ? OR si.content LIKE ?)
41
+ AND si.id NOT IN (SELECT source_item_id FROM interactions WHERE action IN ('click', 'save'))
42
+ ORDER BY si.created_at DESC LIMIT 5`)
43
+ .all(pattern, pattern);
44
+ if (mentionedItems.length > 0) {
45
+ // Check if any are security-related
46
+ const hasSecurityMention = mentionedItems.some((item) => item.title?.toLowerCase().includes("cve") ||
47
+ item.title?.toLowerCase().includes("security") ||
48
+ item.title?.toLowerCase().includes("vulnerability"));
49
+ const severity = hasSecurityMention
50
+ ? "critical"
51
+ : mentionedItems.length >= 3
52
+ ? "high"
53
+ : "medium";
54
+ gaps.push({
55
+ dependency: dep.package_name,
56
+ version: dep.version,
57
+ project_path: dep.project_path,
58
+ language: dep.language,
59
+ missed_items: mentionedItems,
60
+ gap_severity: severity,
61
+ missed_count: mentionedItems.length,
62
+ });
63
+ }
64
+ }
65
+ // Filter by severity
66
+ const severityOrder = { critical: 4, high: 3, medium: 2, low: 1 };
67
+ const minLevel = severityOrder[params.min_severity || "medium"] || 2;
68
+ const filtered = gaps.filter((g) => (severityOrder[g.gap_severity] || 0) >= minLevel);
69
+ return {
70
+ gaps: filtered.sort((a, b) => (severityOrder[b.gap_severity] || 0) - (severityOrder[a.gap_severity] || 0)),
71
+ total_dependencies: deps.length,
72
+ gaps_found: filtered.length,
73
+ summary: `${filtered.length} knowledge gaps across ${deps.length} tracked dependencies`,
74
+ };
75
+ }
76
+ //# sourceMappingURL=knowledge-gaps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-gaps.js","sourceRoot":"","sources":["../../src/tools/knowledge-gaps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * LLM Status Tool
3
+ *
4
+ * Check the status of the LLM configuration and Ollama availability.
5
+ * Helps diagnose why AI synthesis might not be working.
6
+ */
7
+ import type { FourDADatabase } from "../db.js";
8
+ export declare const llmStatusTool: {
9
+ name: string;
10
+ description: string;
11
+ inputSchema: {
12
+ type: string;
13
+ properties: {
14
+ check_ollama: {
15
+ type: string;
16
+ description: string;
17
+ };
18
+ };
19
+ };
20
+ };
21
+ export interface LLMStatusParams {
22
+ check_ollama?: boolean;
23
+ }
24
+ interface LLMStatusResult {
25
+ provider: string | null;
26
+ can_synthesize: boolean;
27
+ config: {
28
+ model: string | null;
29
+ model_light: string | null;
30
+ model_heavy: string | null;
31
+ ollama_url: string | null;
32
+ };
33
+ ollama?: {
34
+ available: boolean;
35
+ models: string[];
36
+ has_recommended: boolean;
37
+ missing_models: string[];
38
+ error?: string;
39
+ };
40
+ recommendations: string[];
41
+ setup_commands?: string[];
42
+ }
43
+ export declare function executeLLMStatus(db: FourDADatabase, params: LLMStatusParams): Promise<LLMStatusResult>;
44
+ export {};
45
+ //# sourceMappingURL=llm-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-status.d.ts","sourceRoot":"","sources":["../../src/tools/llm-status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAS/C,eAAO,MAAM,aAAa;;;;;;;;;;;;CAoBzB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,CAAC;IACF,MAAM,CAAC,EAAE;QACP,SAAS,EAAE,OAAO,CAAC;QACnB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,eAAe,EAAE,OAAO,CAAC;QACzB,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,cAAc,EAClB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,eAAe,CAAC,CAsE1B"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * LLM Status Tool
3
+ *
4
+ * Check the status of the LLM configuration and Ollama availability.
5
+ * Helps diagnose why AI synthesis might not be working.
6
+ */
7
+ import { getLLMConfig, canSynthesize, checkOllamaStatus, DEFAULT_OLLAMA_MODELS, RECOMMENDED_MODELS, } from "../llm.js";
8
+ export const llmStatusTool = {
9
+ name: "llm_status",
10
+ description: `Check LLM configuration and availability.
11
+ Returns:
12
+ - Current LLM provider configuration
13
+ - Ollama status (if configured)
14
+ - Available models
15
+ - Recommended models for your hardware
16
+ - Configuration recommendations
17
+
18
+ Use this to diagnose AI synthesis issues.`,
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ check_ollama: {
23
+ type: "boolean",
24
+ description: "Check Ollama connectivity (default: true)",
25
+ },
26
+ },
27
+ },
28
+ };
29
+ export async function executeLLMStatus(db, params) {
30
+ const { check_ollama = true } = params;
31
+ const dbInstance = db.db;
32
+ const config = getLLMConfig(dbInstance);
33
+ const result = {
34
+ provider: config.provider,
35
+ can_synthesize: canSynthesize(config),
36
+ config: {
37
+ model: config.model || null,
38
+ model_light: config.model_light || null,
39
+ model_heavy: config.model_heavy || null,
40
+ ollama_url: config.ollama_url || null,
41
+ },
42
+ recommendations: [],
43
+ };
44
+ // Check Ollama if configured
45
+ if (config.provider === "ollama" && check_ollama) {
46
+ const ollamaUrl = config.ollama_url || "http://localhost:11434";
47
+ const status = await checkOllamaStatus(ollamaUrl);
48
+ const recommendedModels = [
49
+ DEFAULT_OLLAMA_MODELS.light,
50
+ DEFAULT_OLLAMA_MODELS.medium,
51
+ DEFAULT_OLLAMA_MODELS.heavy,
52
+ ];
53
+ const missingModels = recommendedModels.filter(m => !status.models.some(installed => installed.startsWith(m.split(":")[0])));
54
+ result.ollama = {
55
+ available: status.available,
56
+ models: status.models,
57
+ has_recommended: missingModels.length === 0,
58
+ missing_models: missingModels,
59
+ error: status.error,
60
+ };
61
+ // Generate recommendations
62
+ if (!status.available) {
63
+ result.recommendations.push("Ollama is not running. Start it with: ollama serve");
64
+ result.setup_commands = ["ollama serve"];
65
+ }
66
+ else if (status.models.length === 0) {
67
+ result.recommendations.push("No models installed. Pull recommended models.");
68
+ result.setup_commands = [
69
+ RECOMMENDED_MODELS["16GB_VRAM"].install,
70
+ `ollama pull ${DEFAULT_OLLAMA_MODELS.light}`,
71
+ ];
72
+ }
73
+ else if (missingModels.length > 0) {
74
+ result.recommendations.push(`Missing recommended models: ${missingModels.join(", ")}`);
75
+ result.setup_commands = missingModels.map(m => `ollama pull ${m}`);
76
+ }
77
+ else {
78
+ result.recommendations.push("Ollama is properly configured with recommended models.");
79
+ }
80
+ }
81
+ else if (!config.provider) {
82
+ result.recommendations.push("No LLM provider configured. Set llm_provider to 'ollama', 'anthropic', or 'openai' in settings.");
83
+ }
84
+ else if (config.provider === "anthropic" && !config.anthropic_api_key) {
85
+ result.recommendations.push("Anthropic selected but no API key configured.");
86
+ }
87
+ else if (config.provider === "openai" && !config.openai_api_key) {
88
+ result.recommendations.push("OpenAI selected but no API key configured.");
89
+ }
90
+ return result;
91
+ }
92
+ //# sourceMappingURL=llm-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-status.js","sourceRoot":"","sources":["../../src/tools/llm-status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * project_health tool
3
+ *
4
+ * Get project health summary across all tracked projects.
5
+ */
6
+ import type { FourDADatabase } from "../db.js";
7
+ export interface ProjectHealthParams {
8
+ project_path?: string;
9
+ }
10
+ export declare const projectHealthTool: {
11
+ name: string;
12
+ description: string;
13
+ inputSchema: {
14
+ type: "object";
15
+ properties: {
16
+ project_path: {
17
+ type: string;
18
+ description: string;
19
+ };
20
+ };
21
+ };
22
+ };
23
+ export declare function executeProjectHealth(db: FourDADatabase, params: ProjectHealthParams): {
24
+ projects: {
25
+ project_path: any;
26
+ project_name: any;
27
+ dependency_count: any;
28
+ dependencies: {
29
+ name: any;
30
+ version: any;
31
+ language: any;
32
+ }[];
33
+ health: {
34
+ security_score: number;
35
+ security_issues: number;
36
+ };
37
+ }[];
38
+ total_projects: number;
39
+ summary: string;
40
+ };
41
+ //# sourceMappingURL=project-health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-health.d.ts","sourceRoot":"","sources":["../../src/tools/project-health.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;CAY7B,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,cAAc,EAClB,MAAM,EAAE,mBAAmB;;;;;;;;;;;;;;;;;EA+D5B"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * project_health tool
3
+ *
4
+ * Get project health summary across all tracked projects.
5
+ */
6
+ export const projectHealthTool = {
7
+ name: "project_health",
8
+ description: `Get project health radar - dependency freshness, security exposure, ecosystem momentum, and community signals for your tracked projects.`,
9
+ inputSchema: {
10
+ type: "object",
11
+ properties: {
12
+ project_path: {
13
+ type: "string",
14
+ description: "Specific project path to check. Omit for all projects.",
15
+ },
16
+ },
17
+ },
18
+ };
19
+ export function executeProjectHealth(db, params) {
20
+ const rawDb = db.getRawDb();
21
+ // Get all projects with their dependency counts
22
+ let query = `SELECT project_path, COUNT(*) as dep_count,
23
+ GROUP_CONCAT(package_name, ', ') as packages
24
+ FROM project_dependencies`;
25
+ const queryParams = [];
26
+ if (params.project_path) {
27
+ query += " WHERE project_path = ?";
28
+ queryParams.push(params.project_path);
29
+ }
30
+ query += " GROUP BY project_path";
31
+ const projects = rawDb.prepare(query).all(...queryParams);
32
+ const healthReports = projects.map((proj) => {
33
+ // Get dependencies for this project
34
+ const deps = rawDb
35
+ .prepare("SELECT package_name, version, language, is_dev FROM project_dependencies WHERE project_path = ?")
36
+ .all(proj.project_path);
37
+ // Check for security-related source items mentioning these deps
38
+ let securityIssues = 0;
39
+ for (const dep of deps.slice(0, 20)) {
40
+ const pattern = `%${dep.package_name}%`;
41
+ const securityMentions = rawDb
42
+ .prepare(`SELECT COUNT(*) as cnt FROM source_items
43
+ WHERE (title LIKE ? OR content LIKE ?)
44
+ AND (signal_type = 'security_alert' OR title LIKE '%CVE%' OR title LIKE '%vulnerability%')`)
45
+ .get(pattern, pattern);
46
+ if (securityMentions.cnt > 0)
47
+ securityIssues++;
48
+ }
49
+ const securityScore = deps.length > 0 ? 1.0 - securityIssues / deps.length : 1.0;
50
+ return {
51
+ project_path: proj.project_path,
52
+ project_name: proj.project_path.split(/[/\\]/).pop() || proj.project_path,
53
+ dependency_count: proj.dep_count,
54
+ dependencies: deps.slice(0, 20).map((d) => ({
55
+ name: d.package_name,
56
+ version: d.version,
57
+ language: d.language,
58
+ })),
59
+ health: {
60
+ security_score: Math.max(0, securityScore),
61
+ security_issues: securityIssues,
62
+ },
63
+ };
64
+ });
65
+ return {
66
+ projects: healthReports,
67
+ total_projects: healthReports.length,
68
+ summary: `${healthReports.length} project${healthReports.length !== 1 ? "s" : ""} tracked`,
69
+ };
70
+ }
71
+ //# sourceMappingURL=project-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-health.js","sourceRoot":"","sources":["../../src/tools/project-health.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,0IAA0I;IACvJ,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,wDAAwD;aACtE;SACF;KACF;CACF,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAClC,EAAkB,EAClB,MAA2B;IAE3B,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAE5B,gDAAgD;IAChD,IAAI,KAAK,GAAG;;yCAE2B,CAAC;IAExC,MAAM,WAAW,GAAU,EAAE,CAAC;IAC9B,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,KAAK,IAAI,yBAAyB,CAAC;QACnC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC;IACD,KAAK,IAAI,wBAAwB,CAAC;IAElC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,WAAW,CAAU,CAAC;IAEnE,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE;QAC/C,oCAAoC;QACpC,MAAM,IAAI,GAAG,KAAK;aACf,OAAO,CACN,iGAAiG,CAClG;aACA,GAAG,CAAC,IAAI,CAAC,YAAY,CAAU,CAAC;QAEnC,gEAAgE;QAChE,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,YAAY,GAAG,CAAC;YACxC,MAAM,gBAAgB,GAAG,KAAK;iBAC3B,OAAO,CACN;;sGAE4F,CAC7F;iBACA,GAAG,CAAC,OAAO,EAAE,OAAO,CAAQ,CAAC;YAChC,IAAI,gBAAgB,CAAC,GAAG,GAAG,CAAC;gBAAE,cAAc,EAAE,CAAC;QACjD,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;QAEjF,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,YAAY;YACzE,gBAAgB,EAAE,IAAI,CAAC,SAAS;YAChC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;gBAC/C,IAAI,EAAE,CAAC,CAAC,YAAY;gBACpB,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ;aACrB,CAAC,CAAC;YACH,MAAM,EAAE;gBACN,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC;gBAC1C,eAAe,EAAE,cAAc;aAChC;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ,EAAE,aAAa;QACvB,cAAc,EAAE,aAAa,CAAC,MAAM;QACpC,OAAO,EAAE,GAAG,aAAa,CAAC,MAAM,WAAW,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU;KAC3F,CAAC;AACJ,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * record_feedback tool
3
+ *
4
+ * Record user feedback on an item for learning.
5
+ */
6
+ import type { FourDADatabase } from "../db.js";
7
+ import type { RecordFeedbackParams, FeedbackResult } from "../types.js";
8
+ /**
9
+ * Tool definition for MCP registration
10
+ */
11
+ export declare const recordFeedbackTool: {
12
+ name: string;
13
+ description: string;
14
+ inputSchema: {
15
+ type: "object";
16
+ properties: {
17
+ item_id: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ source_type: {
22
+ type: string;
23
+ description: string;
24
+ enum: string[];
25
+ };
26
+ action: {
27
+ type: string;
28
+ description: string;
29
+ enum: string[];
30
+ };
31
+ };
32
+ required: string[];
33
+ };
34
+ };
35
+ /**
36
+ * Execute the record_feedback tool
37
+ */
38
+ export declare function executeRecordFeedback(db: FourDADatabase, params: RecordFeedbackParams): FeedbackResult;
39
+ //# sourceMappingURL=record-feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-feedback.d.ts","sourceRoot":"","sources":["../../src/tools/record-feedback.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAkB,MAAM,aAAa,CAAC;AAExF;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;CA+B9B,CAAC;AAIF;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,cAAc,EAClB,MAAM,EAAE,oBAAoB,GAC3B,cAAc,CAgBhB"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * record_feedback tool
3
+ *
4
+ * Record user feedback on an item for learning.
5
+ */
6
+ /**
7
+ * Tool definition for MCP registration
8
+ */
9
+ export const recordFeedbackTool = {
10
+ name: "record_feedback",
11
+ description: `Record user feedback on a content item.
12
+
13
+ Feedback actions:
14
+ - "click": User clicked/opened the item (moderate positive signal)
15
+ - "save": User saved/bookmarked the item (strong positive signal)
16
+ - "dismiss": User dismissed the item (weak negative signal)
17
+ - "mark_irrelevant": User marked item as not relevant (strong negative signal)
18
+
19
+ This feedback helps 4DA learn user preferences over time.`,
20
+ inputSchema: {
21
+ type: "object",
22
+ properties: {
23
+ item_id: {
24
+ type: "number",
25
+ description: "The database ID of the item",
26
+ },
27
+ source_type: {
28
+ type: "string",
29
+ description: 'The source type: "hackernews", "arxiv", or "reddit"',
30
+ enum: ["hackernews", "arxiv", "reddit"],
31
+ },
32
+ action: {
33
+ type: "string",
34
+ description: 'The feedback action: "click", "save", "dismiss", or "mark_irrelevant"',
35
+ enum: ["click", "save", "dismiss", "mark_irrelevant"],
36
+ },
37
+ },
38
+ required: ["item_id", "source_type", "action"],
39
+ },
40
+ };
41
+ const validActions = ["click", "save", "dismiss", "mark_irrelevant"];
42
+ /**
43
+ * Execute the record_feedback tool
44
+ */
45
+ export function executeRecordFeedback(db, params) {
46
+ if (!params.item_id || !params.source_type || !params.action) {
47
+ return {
48
+ success: false,
49
+ message: "item_id, source_type, and action are required",
50
+ };
51
+ }
52
+ if (!validActions.includes(params.action)) {
53
+ return {
54
+ success: false,
55
+ message: `Invalid action: ${params.action}. Valid actions: ${validActions.join(", ")}`,
56
+ };
57
+ }
58
+ return db.recordFeedback(params.item_id, params.source_type, params.action);
59
+ }
60
+ //# sourceMappingURL=record-feedback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-feedback.js","sourceRoot":"","sources":["../../src/tools/record-feedback.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE;;;;;;;;0DAQ2C;IACxD,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,6BAA6B;aAC3C;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,qDAAqD;gBAClE,IAAI,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC;aACxC;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,uEAAuE;gBACpF,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,CAAC;aACtD;SACF;QACD,QAAQ,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,QAAQ,CAAC;KAC/C;CACF,CAAC;AAEF,MAAM,YAAY,GAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAEvF;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,EAAkB,EAClB,MAA4B;IAE5B,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC7D,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,+CAA+C;SACzD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,mBAAmB,MAAM,CAAC,MAAM,oBAAoB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACvF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * reverse_mentions tool
3
+ *
4
+ * Detect when your projects/packages are mentioned in sources.
5
+ */
6
+ import type { FourDADatabase } from "../db.js";
7
+ export interface ReverseMentionsParams {
8
+ limit?: number;
9
+ }
10
+ export declare const reverseMentionsTool: {
11
+ name: string;
12
+ description: string;
13
+ inputSchema: {
14
+ type: "object";
15
+ properties: {
16
+ limit: {
17
+ type: string;
18
+ description: string;
19
+ default: number;
20
+ };
21
+ };
22
+ };
23
+ };
24
+ export declare function executeReverseMentions(db: FourDADatabase, params: ReverseMentionsParams): {
25
+ mentions: {
26
+ source_item_id: any;
27
+ title: any;
28
+ url: any;
29
+ source_type: any;
30
+ mentioned_project: any;
31
+ mention_context: any;
32
+ discovered_at: any;
33
+ }[];
34
+ total: number;
35
+ tracked_projects: any[];
36
+ summary: string;
37
+ };
38
+ //# sourceMappingURL=reverse-mentions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverse-mentions.d.ts","sourceRoot":"","sources":["../../src/tools/reverse-mentions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;CAa/B,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,cAAc,EAClB,MAAM,EAAE,qBAAqB;;;;;;;;;;;;;EA2C9B"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * reverse_mentions tool
3
+ *
4
+ * Detect when your projects/packages are mentioned in sources.
5
+ */
6
+ export const reverseMentionsTool = {
7
+ name: "reverse_mentions",
8
+ description: `Detect when your projects or packages are mentioned in sources. Finds discussions about your work in HN, Reddit, etc.`,
9
+ inputSchema: {
10
+ type: "object",
11
+ properties: {
12
+ limit: {
13
+ type: "number",
14
+ description: "Maximum mentions to return. Default: 20",
15
+ default: 20,
16
+ },
17
+ },
18
+ },
19
+ };
20
+ export function executeReverseMentions(db, params) {
21
+ const rawDb = db.getRawDb();
22
+ const limit = params.limit || 20;
23
+ // Get project identifiers from item_relationships
24
+ const mentions = rawDb
25
+ .prepare(`SELECT ir.source_item_id, ir.related_item_id, ir.metadata, ir.created_at,
26
+ si.title, si.url, si.source_type
27
+ FROM item_relationships ir
28
+ JOIN source_items si ON ir.source_item_id = si.id
29
+ WHERE ir.relationship_type = 'mentions_project'
30
+ ORDER BY ir.created_at DESC
31
+ LIMIT ?`)
32
+ .all(limit);
33
+ const results = mentions.map((m) => {
34
+ const metadata = m.metadata ? JSON.parse(m.metadata) : {};
35
+ return {
36
+ source_item_id: m.source_item_id,
37
+ title: m.title,
38
+ url: m.url,
39
+ source_type: m.source_type,
40
+ mentioned_project: metadata.project_name || "unknown",
41
+ mention_context: metadata.context || "",
42
+ discovered_at: m.created_at,
43
+ };
44
+ });
45
+ // Also check for mentions via text search of project names from dependencies
46
+ const projectNames = rawDb
47
+ .prepare("SELECT DISTINCT package_name FROM project_dependencies LIMIT 10")
48
+ .all()
49
+ .map((r) => r.package_name);
50
+ return {
51
+ mentions: results,
52
+ total: results.length,
53
+ tracked_projects: projectNames,
54
+ summary: `${results.length} mention${results.length !== 1 ? "s" : ""} found across ${projectNames.length} tracked projects`,
55
+ };
56
+ }
57
+ //# sourceMappingURL=reverse-mentions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverse-mentions.js","sourceRoot":"","sources":["../../src/tools/reverse-mentions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,uHAAuH;IACpI,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yCAAyC;gBACtD,OAAO,EAAE,EAAE;aACZ;SACF;KACF;CACF,CAAC;AAEF,MAAM,UAAU,sBAAsB,CACpC,EAAkB,EAClB,MAA6B;IAE7B,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IAEjC,kDAAkD;IAClD,MAAM,QAAQ,GAAG,KAAK;SACnB,OAAO,CACN;;;;;;eAMS,CACV;SACA,GAAG,CAAC,KAAK,CAAU,CAAC;IAEvB,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE;QACtC,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,OAAO;YACL,cAAc,EAAE,CAAC,CAAC,cAAc;YAChC,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,iBAAiB,EAAE,QAAQ,CAAC,YAAY,IAAI,SAAS;YACrD,eAAe,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE;YACvC,aAAa,EAAE,CAAC,CAAC,UAAU;SAC5B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,6EAA6E;IAC7E,MAAM,YAAY,GAAG,KAAK;SACvB,OAAO,CAAC,iEAAiE,CAAC;SAC1E,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAEnC,OAAO;QACL,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,gBAAgB,EAAE,YAAY;QAC9B,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,WAAW,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,iBAAiB,YAAY,CAAC,MAAM,mBAAmB;KAC5H,CAAC;AACJ,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Score Autopsy Tool
3
+ *
4
+ * Deep forensic analysis of why content scored the way it did.
5
+ * This is a SUPERPOWER - it reveals the complete scoring breakdown.
6
+ *
7
+ * With synthesize=true, uses LLM to explain whether the score makes sense.
8
+ */
9
+ import type { FourDADatabase } from "../db.js";
10
+ import { type CompactResult, type ScoreAutopsyKeyData } from "../output-manager.js";
11
+ export declare const scoreAutopsyTool: {
12
+ name: string;
13
+ description: string;
14
+ inputSchema: {
15
+ type: string;
16
+ properties: {
17
+ item_id: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ source_type: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ compare_count: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ synthesize: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ compact: {
34
+ type: string;
35
+ description: string;
36
+ };
37
+ };
38
+ required: string[];
39
+ };
40
+ };
41
+ export interface ScoreAutopsyParams {
42
+ item_id: number;
43
+ source_type: string;
44
+ compare_count?: number;
45
+ synthesize?: boolean;
46
+ compact?: boolean;
47
+ }
48
+ interface ScoreComponent {
49
+ name: string;
50
+ raw_value: number;
51
+ weight: number;
52
+ contribution: number;
53
+ explanation: string;
54
+ }
55
+ interface SimilarItem {
56
+ id: number;
57
+ title: string;
58
+ score: number;
59
+ score_difference: number;
60
+ key_difference: string;
61
+ }
62
+ interface AutopsyResult {
63
+ item: {
64
+ id: number;
65
+ title: string;
66
+ url: string | null;
67
+ source_type: string;
68
+ created_at: string;
69
+ age_hours: number;
70
+ };
71
+ final_score: number;
72
+ components: ScoreComponent[];
73
+ matching_context: {
74
+ interests: string[];
75
+ tech_stack: string[];
76
+ active_topics: string[];
77
+ learned_affinities: string[];
78
+ exclusions_hit: string[];
79
+ };
80
+ similar_items: SimilarItem[];
81
+ recommendations: string[];
82
+ narrative: string;
83
+ ai_analysis?: {
84
+ verdict: string;
85
+ score_assessment: "accurate" | "too_high" | "too_low" | "uncertain";
86
+ reasoning: string;
87
+ suggested_action: string;
88
+ model_used: string;
89
+ };
90
+ }
91
+ export declare function executeScoreAutopsy(db: FourDADatabase, params: ScoreAutopsyParams): Promise<AutopsyResult | CompactResult<ScoreAutopsyKeyData>>;
92
+ export {};
93
+ //# sourceMappingURL=score-autopsy.d.ts.map