@defai.digital/ax-cli 3.3.0 → 3.4.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 (192) hide show
  1. package/.ax-cli/memory.json +6 -6
  2. package/README.md +110 -0
  3. package/config/settings.yaml +6 -0
  4. package/dist/agent/dependency-resolver.js +2 -1
  5. package/dist/agent/dependency-resolver.js.map +1 -1
  6. package/dist/agent/llm-agent.d.ts +3 -0
  7. package/dist/agent/llm-agent.js +57 -8
  8. package/dist/agent/llm-agent.js.map +1 -1
  9. package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.d.ts +29 -0
  10. package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js +103 -0
  11. package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js.map +1 -0
  12. package/dist/analyzers/architecture/architecture-analyzer.d.ts +58 -0
  13. package/dist/analyzers/architecture/architecture-analyzer.js +276 -0
  14. package/dist/analyzers/architecture/architecture-analyzer.js.map +1 -0
  15. package/dist/analyzers/architecture/index.d.ts +12 -0
  16. package/dist/analyzers/architecture/index.js +14 -0
  17. package/dist/analyzers/architecture/index.js.map +1 -0
  18. package/dist/analyzers/architecture/pattern-detectors/base-detector.d.ts +27 -0
  19. package/dist/analyzers/architecture/pattern-detectors/base-detector.js +31 -0
  20. package/dist/analyzers/architecture/pattern-detectors/base-detector.js.map +1 -0
  21. package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.d.ts +11 -0
  22. package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js +57 -0
  23. package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js.map +1 -0
  24. package/dist/analyzers/architecture/pattern-detectors/mvc-detector.d.ts +11 -0
  25. package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js +43 -0
  26. package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js.map +1 -0
  27. package/dist/analyzers/architecture/pattern-detectors/repository-detector.d.ts +11 -0
  28. package/dist/analyzers/architecture/pattern-detectors/repository-detector.js +49 -0
  29. package/dist/analyzers/architecture/pattern-detectors/repository-detector.js.map +1 -0
  30. package/dist/analyzers/architecture/project-structure-scanner.d.ts +54 -0
  31. package/dist/analyzers/architecture/project-structure-scanner.js +200 -0
  32. package/dist/analyzers/architecture/project-structure-scanner.js.map +1 -0
  33. package/dist/analyzers/best-practices/base-rule.d.ts +45 -0
  34. package/dist/analyzers/best-practices/base-rule.js +45 -0
  35. package/dist/analyzers/best-practices/base-rule.js.map +1 -0
  36. package/dist/analyzers/best-practices/best-practice-validator.d.ts +35 -0
  37. package/dist/analyzers/best-practices/best-practice-validator.js +181 -0
  38. package/dist/analyzers/best-practices/best-practice-validator.js.map +1 -0
  39. package/dist/analyzers/best-practices/rules/index.d.ts +7 -0
  40. package/dist/analyzers/best-practices/rules/index.js +56 -0
  41. package/dist/analyzers/best-practices/rules/index.js.map +1 -0
  42. package/dist/analyzers/best-practices/rules/typescript/consistent-naming.d.ts +17 -0
  43. package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js +41 -0
  44. package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js.map +1 -0
  45. package/dist/analyzers/best-practices/rules/typescript/function-complexity.d.ts +27 -0
  46. package/dist/analyzers/best-practices/rules/typescript/function-complexity.js +76 -0
  47. package/dist/analyzers/best-practices/rules/typescript/function-complexity.js.map +1 -0
  48. package/dist/analyzers/best-practices/rules/typescript/index.d.ts +15 -0
  49. package/dist/analyzers/best-practices/rules/typescript/index.js +16 -0
  50. package/dist/analyzers/best-practices/rules/typescript/index.js.map +1 -0
  51. package/dist/analyzers/best-practices/rules/typescript/max-file-length.d.ts +18 -0
  52. package/dist/analyzers/best-practices/rules/typescript/max-file-length.js +25 -0
  53. package/dist/analyzers/best-practices/rules/typescript/max-file-length.js.map +1 -0
  54. package/dist/analyzers/best-practices/rules/typescript/no-any-type.d.ts +17 -0
  55. package/dist/analyzers/best-practices/rules/typescript/no-any-type.js +27 -0
  56. package/dist/analyzers/best-practices/rules/typescript/no-any-type.js.map +1 -0
  57. package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.d.ts +18 -0
  58. package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js +39 -0
  59. package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js.map +1 -0
  60. package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.d.ts +17 -0
  61. package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js +32 -0
  62. package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js.map +1 -0
  63. package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.d.ts +17 -0
  64. package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js +36 -0
  65. package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js.map +1 -0
  66. package/dist/analyzers/best-practices/rules/typescript/prefer-const.d.ts +17 -0
  67. package/dist/analyzers/best-practices/rules/typescript/prefer-const.js +33 -0
  68. package/dist/analyzers/best-practices/rules/typescript/prefer-const.js.map +1 -0
  69. package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.d.ts +17 -0
  70. package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js +34 -0
  71. package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js.map +1 -0
  72. package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.d.ts +17 -0
  73. package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js +27 -0
  74. package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js.map +1 -0
  75. package/dist/analyzers/best-practices/types.d.ts +86 -0
  76. package/dist/analyzers/best-practices/types.js +7 -0
  77. package/dist/analyzers/best-practices/types.js.map +1 -0
  78. package/dist/analyzers/cache/analysis-cache.d.ts +41 -0
  79. package/dist/analyzers/cache/analysis-cache.js +84 -0
  80. package/dist/analyzers/cache/analysis-cache.js.map +1 -0
  81. package/dist/analyzers/errors.d.ts +51 -0
  82. package/dist/analyzers/errors.js +79 -0
  83. package/dist/analyzers/errors.js.map +1 -0
  84. package/dist/commands/doctor.js +2 -1
  85. package/dist/commands/doctor.js.map +1 -1
  86. package/dist/commands/mcp.js +243 -0
  87. package/dist/commands/mcp.js.map +1 -1
  88. package/dist/commands/setup.js +85 -28
  89. package/dist/commands/setup.js.map +1 -1
  90. package/dist/constants.d.ts +3 -0
  91. package/dist/constants.js +3 -0
  92. package/dist/constants.js.map +1 -1
  93. package/dist/hooks/use-input-handler.js +2 -1
  94. package/dist/hooks/use-input-handler.js.map +1 -1
  95. package/dist/llm/tools.js +86 -0
  96. package/dist/llm/tools.js.map +1 -1
  97. package/dist/mcp/client.d.ts +5 -0
  98. package/dist/mcp/client.js +55 -0
  99. package/dist/mcp/client.js.map +1 -1
  100. package/dist/mcp/health.d.ts +11 -2
  101. package/dist/mcp/health.js +35 -12
  102. package/dist/mcp/health.js.map +1 -1
  103. package/dist/mcp/reconnection.d.ts +93 -0
  104. package/dist/mcp/reconnection.js +216 -0
  105. package/dist/mcp/reconnection.js.map +1 -0
  106. package/dist/mcp/registry.d.ts +71 -0
  107. package/dist/mcp/registry.js +257 -0
  108. package/dist/mcp/registry.js.map +1 -0
  109. package/dist/mcp/resources.d.ts +53 -0
  110. package/dist/mcp/resources.js +135 -0
  111. package/dist/mcp/resources.js.map +1 -0
  112. package/dist/mcp/validation.d.ts +25 -0
  113. package/dist/mcp/validation.js +209 -0
  114. package/dist/mcp/validation.js.map +1 -0
  115. package/dist/memory/context-generator.js +1 -2
  116. package/dist/memory/context-generator.js.map +1 -1
  117. package/dist/planner/types.d.ts +2 -2
  118. package/dist/schemas/index.d.ts +4 -4
  119. package/dist/schemas/tool-schemas.d.ts +2 -2
  120. package/dist/schemas/yaml-schemas.d.ts +15 -0
  121. package/dist/schemas/yaml-schemas.js +3 -0
  122. package/dist/schemas/yaml-schemas.js.map +1 -1
  123. package/dist/sdk/index.d.ts +138 -0
  124. package/dist/sdk/index.js +173 -0
  125. package/dist/sdk/index.js.map +1 -0
  126. package/dist/sdk/types.d.ts +53 -0
  127. package/dist/sdk/types.js +8 -0
  128. package/dist/sdk/types.js.map +1 -0
  129. package/dist/tools/analysis-tools/architecture-tool.d.ts +46 -0
  130. package/dist/tools/analysis-tools/architecture-tool.js +124 -0
  131. package/dist/tools/analysis-tools/architecture-tool.js.map +1 -0
  132. package/dist/tools/analysis-tools/validation-tool.d.ts +51 -0
  133. package/dist/tools/analysis-tools/validation-tool.js +121 -0
  134. package/dist/tools/analysis-tools/validation-tool.js.map +1 -0
  135. package/dist/tools/web-search/cache.d.ts +62 -0
  136. package/dist/tools/web-search/cache.js +105 -0
  137. package/dist/tools/web-search/cache.js.map +1 -0
  138. package/dist/tools/web-search/engines/brave.d.ts +16 -0
  139. package/dist/tools/web-search/engines/brave.js +99 -0
  140. package/dist/tools/web-search/engines/brave.js.map +1 -0
  141. package/dist/tools/web-search/engines/crates.d.ts +19 -0
  142. package/dist/tools/web-search/engines/crates.js +87 -0
  143. package/dist/tools/web-search/engines/crates.js.map +1 -0
  144. package/dist/tools/web-search/engines/npm.d.ts +18 -0
  145. package/dist/tools/web-search/engines/npm.js +86 -0
  146. package/dist/tools/web-search/engines/npm.js.map +1 -0
  147. package/dist/tools/web-search/engines/pypi.d.ts +18 -0
  148. package/dist/tools/web-search/engines/pypi.js +75 -0
  149. package/dist/tools/web-search/engines/pypi.js.map +1 -0
  150. package/dist/tools/web-search/engines/tavily.d.ts +17 -0
  151. package/dist/tools/web-search/engines/tavily.js +73 -0
  152. package/dist/tools/web-search/engines/tavily.js.map +1 -0
  153. package/dist/tools/web-search/index.d.ts +13 -0
  154. package/dist/tools/web-search/index.js +13 -0
  155. package/dist/tools/web-search/index.js.map +1 -0
  156. package/dist/tools/web-search/router.d.ts +36 -0
  157. package/dist/tools/web-search/router.js +280 -0
  158. package/dist/tools/web-search/router.js.map +1 -0
  159. package/dist/tools/web-search/types.d.ts +45 -0
  160. package/dist/tools/web-search/types.js +6 -0
  161. package/dist/tools/web-search/types.js.map +1 -0
  162. package/dist/tools/web-search/web-search-tool.d.ts +51 -0
  163. package/dist/tools/web-search/web-search-tool.js +256 -0
  164. package/dist/tools/web-search/web-search-tool.js.map +1 -0
  165. package/dist/types/analysis.d.ts +177 -0
  166. package/dist/types/analysis.js +8 -0
  167. package/dist/types/analysis.js.map +1 -0
  168. package/dist/ui/components/chat-interface.js +11 -1
  169. package/dist/ui/components/chat-interface.js.map +1 -1
  170. package/dist/ui/components/keyboard-hints.js +2 -2
  171. package/dist/ui/components/keyboard-hints.js.map +1 -1
  172. package/dist/ui/components/status-bar.d.ts +1 -0
  173. package/dist/ui/components/status-bar.js +37 -39
  174. package/dist/ui/components/status-bar.js.map +1 -1
  175. package/dist/ui/components/toast-notification.js +2 -2
  176. package/dist/ui/components/toast-notification.js.map +1 -1
  177. package/dist/ui/components/welcome-panel.d.ts +1 -0
  178. package/dist/ui/components/welcome-panel.js +94 -11
  179. package/dist/ui/components/welcome-panel.js.map +1 -1
  180. package/dist/utils/analysis-logger.d.ts +47 -0
  181. package/dist/utils/analysis-logger.js +70 -0
  182. package/dist/utils/analysis-logger.js.map +1 -0
  183. package/dist/utils/automatosx-detector.d.ts +19 -0
  184. package/dist/utils/automatosx-detector.js +52 -0
  185. package/dist/utils/automatosx-detector.js.map +1 -0
  186. package/dist/utils/config-loader.d.ts +3 -0
  187. package/dist/utils/config-loader.js.map +1 -1
  188. package/dist/utils/confirmation-service.js +1 -1
  189. package/dist/utils/confirmation-service.js.map +1 -1
  190. package/dist/utils/init-previewer.js +26 -4
  191. package/dist/utils/init-previewer.js.map +1 -1
  192. package/package.json +19 -3
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Search Cache
3
+ * In-memory cache for web search results
4
+ */
5
+ import NodeCache from "node-cache";
6
+ export class SearchCache {
7
+ cache;
8
+ DEFAULT_TTL = 300; // 5 minutes in seconds
9
+ MAX_KEYS = 500; // Maximum cache entries
10
+ constructor(ttl, maxKeys) {
11
+ this.cache = new NodeCache({
12
+ stdTTL: ttl || this.DEFAULT_TTL,
13
+ checkperiod: 60, // Check for expired entries every 60 seconds
14
+ maxKeys: maxKeys || this.MAX_KEYS,
15
+ useClones: false, // Better performance, but watch for mutations
16
+ });
17
+ }
18
+ /**
19
+ * Generate cache key from query
20
+ */
21
+ getCacheKey(query) {
22
+ return `search:${query.toLowerCase().trim()}`;
23
+ }
24
+ /**
25
+ * Get cached results for a query
26
+ */
27
+ get(query) {
28
+ const key = this.getCacheKey(query);
29
+ const entry = this.cache.get(key);
30
+ if (!entry) {
31
+ return null;
32
+ }
33
+ // Return the cached results
34
+ return entry.results;
35
+ }
36
+ /**
37
+ * Cache search results for a query
38
+ */
39
+ set(query, results, ttl) {
40
+ const key = this.getCacheKey(query);
41
+ const effectiveTtl = ttl || this.DEFAULT_TTL;
42
+ const entry = {
43
+ query,
44
+ results,
45
+ timestamp: Date.now(),
46
+ ttl: effectiveTtl,
47
+ };
48
+ this.cache.set(key, entry, effectiveTtl);
49
+ }
50
+ /**
51
+ * Check if query has cached results
52
+ */
53
+ has(query) {
54
+ const key = this.getCacheKey(query);
55
+ return this.cache.has(key);
56
+ }
57
+ /**
58
+ * Clear specific query from cache
59
+ */
60
+ delete(query) {
61
+ const key = this.getCacheKey(query);
62
+ this.cache.del(key);
63
+ }
64
+ /**
65
+ * Clear all cached results
66
+ */
67
+ clear() {
68
+ this.cache.flushAll();
69
+ }
70
+ /**
71
+ * Get cache statistics
72
+ */
73
+ getStats() {
74
+ const stats = this.cache.getStats();
75
+ const total = stats.hits + stats.misses;
76
+ const hitRate = total > 0 ? stats.hits / total : 0;
77
+ return {
78
+ keys: stats.keys,
79
+ hits: stats.hits,
80
+ misses: stats.misses,
81
+ hitRate: Math.round(hitRate * 100) / 100,
82
+ };
83
+ }
84
+ /**
85
+ * Get all cached queries (for debugging)
86
+ */
87
+ getCachedQueries() {
88
+ return this.cache.keys().map((key) => key.replace("search:", ""));
89
+ }
90
+ /**
91
+ * Get cache entry with metadata
92
+ */
93
+ getEntry(query) {
94
+ const key = this.getCacheKey(query);
95
+ return this.cache.get(key) || null;
96
+ }
97
+ /**
98
+ * Get TTL for a cached query
99
+ */
100
+ getTTL(query) {
101
+ const key = this.getCacheKey(query);
102
+ return this.cache.getTtl(key);
103
+ }
104
+ }
105
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/tools/web-search/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Brave Search Engine
3
+ * Privacy-focused independent search
4
+ * https://brave.com/search/api/
5
+ */
6
+ import type { SearchEngine, WebSearchResult, SearchOptions } from "../types.js";
7
+ export declare class BraveSearch implements SearchEngine {
8
+ readonly name = "brave";
9
+ private apiKey;
10
+ private baseUrl;
11
+ private timeout;
12
+ constructor();
13
+ isAvailable(): boolean;
14
+ search(query: string, options?: SearchOptions): Promise<WebSearchResult[]>;
15
+ private formatResults;
16
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Brave Search Engine
3
+ * Privacy-focused independent search
4
+ * https://brave.com/search/api/
5
+ */
6
+ import axios from "axios";
7
+ export class BraveSearch {
8
+ name = "brave";
9
+ apiKey;
10
+ baseUrl = "https://api.search.brave.com/res/v1/web/search";
11
+ timeout = 10000; // 10 second timeout
12
+ constructor() {
13
+ this.apiKey = process.env.BRAVE_API_KEY;
14
+ }
15
+ isAvailable() {
16
+ return !!this.apiKey;
17
+ }
18
+ async search(query, options) {
19
+ if (!this.isAvailable()) {
20
+ throw new Error("Brave API key not configured");
21
+ }
22
+ try {
23
+ const params = new URLSearchParams({
24
+ q: query,
25
+ count: Math.min(options?.maxResults || 10, 20).toString(),
26
+ offset: "0",
27
+ text_decorations: "false",
28
+ spellcheck: "true",
29
+ });
30
+ // Add freshness filter if specified
31
+ if (options?.freshness) {
32
+ const freshnessMap = {
33
+ day: "pd",
34
+ week: "pw",
35
+ month: "pm",
36
+ year: "py",
37
+ };
38
+ params.append("freshness", freshnessMap[options.freshness]);
39
+ }
40
+ const response = await axios.get(`${this.baseUrl}?${params.toString()}`, {
41
+ timeout: options?.timeout || this.timeout,
42
+ headers: {
43
+ Accept: "application/json",
44
+ "Accept-Encoding": "gzip",
45
+ "X-Subscription-Token": this.apiKey,
46
+ },
47
+ });
48
+ return this.formatResults(response.data);
49
+ }
50
+ catch (error) {
51
+ if (axios.isAxiosError(error)) {
52
+ if (error.code === "ECONNABORTED") {
53
+ throw new Error("Brave search timeout");
54
+ }
55
+ if (error.response?.status === 401) {
56
+ throw new Error("Invalid Brave API key");
57
+ }
58
+ if (error.response?.status === 429) {
59
+ throw new Error("Brave rate limit exceeded");
60
+ }
61
+ throw new Error(`Brave API error: ${error.response?.data?.message || error.message}`);
62
+ }
63
+ throw error;
64
+ }
65
+ }
66
+ formatResults(response) {
67
+ const results = [];
68
+ // Add web results
69
+ if (response.web?.results) {
70
+ results.push(...response.web.results.map((result, index) => ({
71
+ title: result.title,
72
+ url: result.url,
73
+ snippet: result.description,
74
+ source: this.name,
75
+ relevanceScore: 100 - index * 5, // Simple scoring based on position
76
+ publishedDate: result.age || result.page_age,
77
+ metadata: {
78
+ language: result.language,
79
+ },
80
+ })));
81
+ }
82
+ // Add news results if available
83
+ if (response.news?.results) {
84
+ results.push(...response.news.results.map((result, index) => ({
85
+ title: result.title,
86
+ url: result.url,
87
+ snippet: result.description,
88
+ source: `${this.name}-news`,
89
+ relevanceScore: 95 - index * 5,
90
+ publishedDate: result.age,
91
+ metadata: {
92
+ type: "news",
93
+ },
94
+ })));
95
+ }
96
+ return results;
97
+ }
98
+ }
99
+ //# sourceMappingURL=brave.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brave.js","sourceRoot":"","sources":["../../../../src/tools/web-search/engines/brave.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * crates.io (Rust Crates) Search Engine
3
+ * Free, unlimited search for Rust crates
4
+ * No API key required
5
+ */
6
+ import type { SearchEngine, WebSearchResult, SearchOptions } from "../types.js";
7
+ export declare class CratesSearch implements SearchEngine {
8
+ readonly name = "crates.io";
9
+ private baseUrl;
10
+ private timeout;
11
+ /**
12
+ * Always available - no API key required
13
+ */
14
+ isAvailable(): boolean;
15
+ search(query: string, options?: SearchOptions): Promise<WebSearchResult[]>;
16
+ private formatResults;
17
+ private createSnippet;
18
+ private calculateScore;
19
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * crates.io (Rust Crates) Search Engine
3
+ * Free, unlimited search for Rust crates
4
+ * No API key required
5
+ */
6
+ import axios from "axios";
7
+ export class CratesSearch {
8
+ name = "crates.io";
9
+ baseUrl = "https://crates.io/api/v1/crates";
10
+ timeout = 10000; // 10 second timeout
11
+ /**
12
+ * Always available - no API key required
13
+ */
14
+ isAvailable() {
15
+ return true;
16
+ }
17
+ async search(query, options) {
18
+ try {
19
+ const params = new URLSearchParams({
20
+ q: query,
21
+ per_page: Math.min(options?.maxResults || 5, 20).toString(),
22
+ });
23
+ const response = await axios.get(`${this.baseUrl}?${params.toString()}`, {
24
+ timeout: options?.timeout || this.timeout,
25
+ headers: {
26
+ "User-Agent": "ax-cli",
27
+ Accept: "application/json",
28
+ },
29
+ });
30
+ return this.formatResults(response.data);
31
+ }
32
+ catch (error) {
33
+ if (axios.isAxiosError(error)) {
34
+ if (error.code === "ECONNABORTED") {
35
+ throw new Error("crates.io search timeout");
36
+ }
37
+ throw new Error(`crates.io error: ${error.response?.data?.errors?.[0]?.detail || error.message}`);
38
+ }
39
+ throw error;
40
+ }
41
+ }
42
+ formatResults(response) {
43
+ return response.crates.map((crate) => ({
44
+ title: crate.name,
45
+ url: `https://crates.io/crates/${crate.name}`,
46
+ snippet: this.createSnippet(crate),
47
+ source: this.name,
48
+ relevanceScore: this.calculateScore(crate),
49
+ metadata: {
50
+ version: crate.newest_version,
51
+ downloads: crate.downloads,
52
+ recentDownloads: crate.recent_downloads,
53
+ documentation: crate.documentation,
54
+ homepage: crate.homepage,
55
+ repository: crate.repository,
56
+ },
57
+ }));
58
+ }
59
+ createSnippet(crate) {
60
+ const parts = [];
61
+ if (crate.description) {
62
+ parts.push(crate.description);
63
+ }
64
+ parts.push(`v${crate.newest_version}`);
65
+ if (crate.downloads > 1000000) {
66
+ parts.push(`${(crate.downloads / 1000000).toFixed(1)}M downloads`);
67
+ }
68
+ else if (crate.downloads > 1000) {
69
+ parts.push(`${(crate.downloads / 1000).toFixed(1)}K downloads`);
70
+ }
71
+ const indicators = [];
72
+ if (crate.downloads > 1000000)
73
+ indicators.push("very popular");
74
+ else if (crate.downloads > 100000)
75
+ indicators.push("popular");
76
+ if (indicators.length > 0) {
77
+ parts.push(`(${indicators.join(", ")})`);
78
+ }
79
+ return parts.join(" • ");
80
+ }
81
+ calculateScore(crate) {
82
+ // Score based on downloads (logarithmic scale)
83
+ const downloadScore = Math.min(Math.log10(crate.downloads + 1) * 10, 100);
84
+ return downloadScore;
85
+ }
86
+ }
87
+ //# sourceMappingURL=crates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crates.js","sourceRoot":"","sources":["../../../../src/tools/web-search/engines/crates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * npm Registry Search Engine
3
+ * Free, unlimited search for npm packages
4
+ * No API key required
5
+ */
6
+ import type { SearchEngine, WebSearchResult, SearchOptions } from "../types.js";
7
+ export declare class NpmSearch implements SearchEngine {
8
+ readonly name = "npm";
9
+ private baseUrl;
10
+ private timeout;
11
+ /**
12
+ * Always available - no API key required
13
+ */
14
+ isAvailable(): boolean;
15
+ search(query: string, options?: SearchOptions): Promise<WebSearchResult[]>;
16
+ private formatResults;
17
+ private createSnippet;
18
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * npm Registry Search Engine
3
+ * Free, unlimited search for npm packages
4
+ * No API key required
5
+ */
6
+ import axios from "axios";
7
+ export class NpmSearch {
8
+ name = "npm";
9
+ baseUrl = "https://registry.npmjs.org/-/v1/search";
10
+ timeout = 10000; // 10 second timeout
11
+ /**
12
+ * Always available - no API key required
13
+ */
14
+ isAvailable() {
15
+ return true;
16
+ }
17
+ async search(query, options) {
18
+ try {
19
+ const params = new URLSearchParams({
20
+ text: query,
21
+ size: Math.min(options?.maxResults || 5, 20).toString(),
22
+ });
23
+ const response = await axios.get(`${this.baseUrl}?${params.toString()}`, {
24
+ timeout: options?.timeout || this.timeout,
25
+ headers: {
26
+ Accept: "application/json",
27
+ },
28
+ });
29
+ return this.formatResults(response.data);
30
+ }
31
+ catch (error) {
32
+ if (axios.isAxiosError(error)) {
33
+ if (error.code === "ECONNABORTED") {
34
+ throw new Error("npm search timeout");
35
+ }
36
+ throw new Error(`npm registry error: ${error.response?.data?.error || error.message}`);
37
+ }
38
+ throw error;
39
+ }
40
+ }
41
+ formatResults(response) {
42
+ return response.objects.map((pkg) => ({
43
+ title: pkg.package.name,
44
+ url: pkg.package.links.npm || `https://www.npmjs.com/package/${pkg.package.name}`,
45
+ snippet: this.createSnippet(pkg),
46
+ source: this.name,
47
+ relevanceScore: pkg.score.final * 100, // Convert 0-1 to 0-100
48
+ publishedDate: pkg.package.date,
49
+ metadata: {
50
+ version: pkg.package.version,
51
+ author: pkg.package.author?.name || pkg.package.publisher.username,
52
+ quality: pkg.score.detail.quality,
53
+ popularity: pkg.score.detail.popularity,
54
+ maintenance: pkg.score.detail.maintenance,
55
+ homepage: pkg.package.links.homepage,
56
+ repository: pkg.package.links.repository,
57
+ },
58
+ }));
59
+ }
60
+ createSnippet(pkg) {
61
+ const parts = [];
62
+ if (pkg.package.description) {
63
+ parts.push(pkg.package.description);
64
+ }
65
+ parts.push(`v${pkg.package.version}`);
66
+ if (pkg.package.author?.name) {
67
+ parts.push(`by ${pkg.package.author.name}`);
68
+ }
69
+ // Add quality indicators
70
+ const quality = pkg.score.detail.quality;
71
+ const popularity = pkg.score.detail.popularity;
72
+ const maintenance = pkg.score.detail.maintenance;
73
+ const indicators = [];
74
+ if (quality > 0.7)
75
+ indicators.push("high quality");
76
+ if (popularity > 0.7)
77
+ indicators.push("popular");
78
+ if (maintenance > 0.7)
79
+ indicators.push("well-maintained");
80
+ if (indicators.length > 0) {
81
+ parts.push(`(${indicators.join(", ")})`);
82
+ }
83
+ return parts.join(" • ");
84
+ }
85
+ }
86
+ //# sourceMappingURL=npm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm.js","sourceRoot":"","sources":["../../../../src/tools/web-search/engines/npm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * PyPI (Python Package Index) Search Engine
3
+ * Free, unlimited search for Python packages
4
+ * No API key required
5
+ */
6
+ import type { SearchEngine, WebSearchResult, SearchOptions } from "../types.js";
7
+ export declare class PyPISearch implements SearchEngine {
8
+ readonly name = "pypi";
9
+ private baseUrl;
10
+ private timeout;
11
+ /**
12
+ * Always available - no API key required
13
+ */
14
+ isAvailable(): boolean;
15
+ search(query: string, options?: SearchOptions): Promise<WebSearchResult[]>;
16
+ private formatResult;
17
+ private createSnippet;
18
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * PyPI (Python Package Index) Search Engine
3
+ * Free, unlimited search for Python packages
4
+ * No API key required
5
+ */
6
+ import axios from "axios";
7
+ // Note: PyPI's search API is being rebuilt, so we use direct package lookup instead
8
+ export class PyPISearch {
9
+ name = "pypi";
10
+ baseUrl = "https://pypi.org/pypi";
11
+ timeout = 10000; // 10 second timeout
12
+ /**
13
+ * Always available - no API key required
14
+ */
15
+ isAvailable() {
16
+ return true;
17
+ }
18
+ async search(query, options) {
19
+ try {
20
+ // PyPI's official search is being rebuilt, so we use direct package lookup
21
+ // Try to fetch package info directly
22
+ const packageResponse = await axios.get(`${this.baseUrl}/${encodeURIComponent(query)}/json`, {
23
+ timeout: options?.timeout || this.timeout,
24
+ validateStatus: (status) => status === 200 || status === 404,
25
+ });
26
+ if (packageResponse.status === 404) {
27
+ // Package not found, return empty results
28
+ return [];
29
+ }
30
+ return this.formatResult(packageResponse.data);
31
+ }
32
+ catch (error) {
33
+ // Return empty results on error rather than failing
34
+ // PyPI search is a best-effort feature
35
+ return [];
36
+ }
37
+ }
38
+ formatResult(data) {
39
+ if (!data.info)
40
+ return [];
41
+ const info = data.info;
42
+ return [
43
+ {
44
+ title: info.name,
45
+ url: `https://pypi.org/project/${info.name}/`,
46
+ snippet: this.createSnippet(info),
47
+ source: this.name,
48
+ relevanceScore: 100, // Exact match
49
+ publishedDate: info.release_date,
50
+ metadata: {
51
+ version: info.version,
52
+ author: info.author,
53
+ license: info.license,
54
+ homepage: info.home_page || info.project_urls?.Homepage,
55
+ requiresPython: info.requires_python,
56
+ },
57
+ },
58
+ ];
59
+ }
60
+ createSnippet(info) {
61
+ const parts = [];
62
+ if (info.summary) {
63
+ parts.push(info.summary);
64
+ }
65
+ parts.push(`v${info.version}`);
66
+ if (info.author) {
67
+ parts.push(`by ${info.author}`);
68
+ }
69
+ if (info.license) {
70
+ parts.push(`License: ${info.license}`);
71
+ }
72
+ return parts.join(" • ");
73
+ }
74
+ }
75
+ //# sourceMappingURL=pypi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pypi.js","sourceRoot":"","sources":["../../../../src/tools/web-search/engines/pypi.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,oFAAoF;AAEpF,MAAM,OAAO,UAAU;IACL,IAAI,GAAG,MAAM,CAAC;IACtB,OAAO,GAAG,uBAAuB,CAAC;IAClC,OAAO,GAAG,KAAK,CAAC,CAAC,oBAAoB;IAE7C;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CACV,KAAa,EACb,OAAuB;QAEvB,IAAI,CAAC;YACH,2EAA2E;YAC3E,qCAAqC;YACrC,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,GAAG,CACrC,GAAG,IAAI,CAAC,OAAO,IAAI,kBAAkB,CAAC,KAAK,CAAC,OAAO,EACnD;gBACE,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,OAAO;gBACzC,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG;aAC7D,CACF,CAAC;YAEF,IAAI,eAAe,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACnC,0CAA0C;gBAC1C,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,oDAAoD;YACpD,uCAAuC;YACvC,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,IAAS;QAC5B,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO;YACL;gBACE,KAAK,EAAE,IAAI,CAAC,IAAI;gBAChB,GAAG,EAAE,4BAA4B,IAAI,CAAC,IAAI,GAAG;gBAC7C,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;gBACjC,MAAM,EAAE,IAAI,CAAC,IAAI;gBACjB,cAAc,EAAE,GAAG,EAAE,cAAc;gBACnC,aAAa,EAAE,IAAI,CAAC,YAAY;gBAChC,QAAQ,EAAE;oBACR,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,QAAQ,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,EAAE,QAAQ;oBACvD,cAAc,EAAE,IAAI,CAAC,eAAe;iBACrC;aACF;SACF,CAAC;IACJ,CAAC;IAEO,aAAa,CAAC,IAAS;QAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAE/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Tavily AI Search Engine
3
+ * AI-optimized search designed for LLMs
4
+ * https://tavily.com/
5
+ */
6
+ import type { SearchEngine, WebSearchResult, SearchOptions } from "../types.js";
7
+ export declare class TavilySearch implements SearchEngine {
8
+ readonly name = "tavily";
9
+ private apiKey;
10
+ private baseUrl;
11
+ private timeout;
12
+ constructor();
13
+ isAvailable(): boolean;
14
+ search(query: string, options?: SearchOptions): Promise<WebSearchResult[]>;
15
+ private formatResults;
16
+ getAnswer(results: WebSearchResult[]): string | undefined;
17
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Tavily AI Search Engine
3
+ * AI-optimized search designed for LLMs
4
+ * https://tavily.com/
5
+ */
6
+ import axios from "axios";
7
+ export class TavilySearch {
8
+ name = "tavily";
9
+ apiKey;
10
+ baseUrl = "https://api.tavily.com/search";
11
+ timeout = 10000; // 10 second timeout
12
+ constructor() {
13
+ this.apiKey = process.env.TAVILY_API_KEY;
14
+ }
15
+ isAvailable() {
16
+ return !!this.apiKey;
17
+ }
18
+ async search(query, options) {
19
+ if (!this.isAvailable()) {
20
+ throw new Error("Tavily API key not configured");
21
+ }
22
+ try {
23
+ const response = await axios.post(this.baseUrl, {
24
+ api_key: this.apiKey,
25
+ query: query,
26
+ search_depth: options?.searchDepth || "basic",
27
+ max_results: Math.min(options?.maxResults || 5, 10),
28
+ include_answer: options?.includeAnswer ?? true,
29
+ include_domains: options?.includeDomains || [],
30
+ exclude_domains: options?.excludeDomains || [],
31
+ }, {
32
+ timeout: options?.timeout || this.timeout,
33
+ headers: {
34
+ "Content-Type": "application/json",
35
+ },
36
+ });
37
+ return this.formatResults(response.data);
38
+ }
39
+ catch (error) {
40
+ if (axios.isAxiosError(error)) {
41
+ if (error.code === "ECONNABORTED") {
42
+ throw new Error("Tavily search timeout");
43
+ }
44
+ if (error.response?.status === 401) {
45
+ throw new Error("Invalid Tavily API key");
46
+ }
47
+ if (error.response?.status === 429) {
48
+ throw new Error("Tavily rate limit exceeded");
49
+ }
50
+ throw new Error(`Tavily API error: ${error.response?.data?.message || error.message}`);
51
+ }
52
+ throw error;
53
+ }
54
+ }
55
+ formatResults(response) {
56
+ return response.results.map((result) => ({
57
+ title: result.title,
58
+ url: result.url,
59
+ snippet: result.content,
60
+ source: this.name,
61
+ relevanceScore: result.score * 100, // Convert 0-1 to 0-100
62
+ publishedDate: result.published_date,
63
+ metadata: {
64
+ answer: response.answer,
65
+ responseTime: response.response_time,
66
+ },
67
+ }));
68
+ }
69
+ getAnswer(results) {
70
+ return results[0]?.metadata?.answer;
71
+ }
72
+ }
73
+ //# sourceMappingURL=tavily.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tavily.js","sourceRoot":"","sources":["../../../../src/tools/web-search/engines/tavily.ts"],"names":[],"mappings":"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"}