swift-skills 0.0.1
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.
- package/LICENSE +21 -0
- package/README.md +410 -0
- package/build/cli/auth.d.ts +3 -0
- package/build/cli/auth.d.ts.map +1 -0
- package/build/cli/auth.js +44 -0
- package/build/cli/auth.js.map +1 -0
- package/build/cli/setup.d.ts +2 -0
- package/build/cli/setup.d.ts.map +1 -0
- package/build/cli/setup.js +150 -0
- package/build/cli/setup.js.map +1 -0
- package/build/cli/source-manager.d.ts +3 -0
- package/build/cli/source-manager.d.ts.map +1 -0
- package/build/cli/source-manager.js +117 -0
- package/build/cli/source-manager.js.map +1 -0
- package/build/config/creators.d.ts +11 -0
- package/build/config/creators.d.ts.map +1 -0
- package/build/config/creators.js +32 -0
- package/build/config/creators.js.map +1 -0
- package/build/config/sources.d.ts +91 -0
- package/build/config/sources.d.ts.map +1 -0
- package/build/config/sources.js +231 -0
- package/build/config/sources.js.map +1 -0
- package/build/config/sources.test.d.ts +2 -0
- package/build/config/sources.test.d.ts.map +1 -0
- package/build/config/sources.test.js +199 -0
- package/build/config/sources.test.js.map +1 -0
- package/build/config/swift-keywords.d.ts +29 -0
- package/build/config/swift-keywords.d.ts.map +1 -0
- package/build/config/swift-keywords.js +77 -0
- package/build/config/swift-keywords.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +181 -0
- package/build/index.js.map +1 -0
- package/build/integration/cache-behavior.test.d.ts +2 -0
- package/build/integration/cache-behavior.test.d.ts.map +1 -0
- package/build/integration/cache-behavior.test.js +521 -0
- package/build/integration/cache-behavior.test.js.map +1 -0
- package/build/integration/mcp-client.test.d.ts +2 -0
- package/build/integration/mcp-client.test.d.ts.map +1 -0
- package/build/integration/mcp-client.test.js +82 -0
- package/build/integration/mcp-client.test.js.map +1 -0
- package/build/integration/response-quality.test.d.ts +2 -0
- package/build/integration/response-quality.test.d.ts.map +1 -0
- package/build/integration/response-quality.test.js +230 -0
- package/build/integration/response-quality.test.js.map +1 -0
- package/build/integration/test-client.d.ts +25 -0
- package/build/integration/test-client.d.ts.map +1 -0
- package/build/integration/test-client.js +93 -0
- package/build/integration/test-client.js.map +1 -0
- package/build/sources/free/nilcoalescing.d.ts +8 -0
- package/build/sources/free/nilcoalescing.d.ts.map +1 -0
- package/build/sources/free/nilcoalescing.js +26 -0
- package/build/sources/free/nilcoalescing.js.map +1 -0
- package/build/sources/free/nilcoalescing.test.d.ts +2 -0
- package/build/sources/free/nilcoalescing.test.d.ts.map +1 -0
- package/build/sources/free/nilcoalescing.test.js +63 -0
- package/build/sources/free/nilcoalescing.test.js.map +1 -0
- package/build/sources/free/pointfree.d.ts +15 -0
- package/build/sources/free/pointfree.d.ts.map +1 -0
- package/build/sources/free/pointfree.js +175 -0
- package/build/sources/free/pointfree.js.map +1 -0
- package/build/sources/free/pointfree.test.d.ts +2 -0
- package/build/sources/free/pointfree.test.d.ts.map +1 -0
- package/build/sources/free/pointfree.test.js +86 -0
- package/build/sources/free/pointfree.test.js.map +1 -0
- package/build/sources/free/rssPatternSource.d.ts +42 -0
- package/build/sources/free/rssPatternSource.d.ts.map +1 -0
- package/build/sources/free/rssPatternSource.js +109 -0
- package/build/sources/free/rssPatternSource.js.map +1 -0
- package/build/sources/free/rssPatternSource.test.d.ts +2 -0
- package/build/sources/free/rssPatternSource.test.d.ts.map +1 -0
- package/build/sources/free/rssPatternSource.test.js +89 -0
- package/build/sources/free/rssPatternSource.test.js.map +1 -0
- package/build/sources/free/sundell.d.ts +8 -0
- package/build/sources/free/sundell.d.ts.map +1 -0
- package/build/sources/free/sundell.js +17 -0
- package/build/sources/free/sundell.js.map +1 -0
- package/build/sources/free/sundell.test.d.ts +2 -0
- package/build/sources/free/sundell.test.d.ts.map +1 -0
- package/build/sources/free/sundell.test.js +63 -0
- package/build/sources/free/sundell.test.js.map +1 -0
- package/build/sources/free/vanderlee.d.ts +8 -0
- package/build/sources/free/vanderlee.d.ts.map +1 -0
- package/build/sources/free/vanderlee.js +63 -0
- package/build/sources/free/vanderlee.js.map +1 -0
- package/build/sources/free/vanderlee.test.d.ts +2 -0
- package/build/sources/free/vanderlee.test.d.ts.map +1 -0
- package/build/sources/free/vanderlee.test.js +77 -0
- package/build/sources/free/vanderlee.test.js.map +1 -0
- package/build/sources/premium/patreon-dl.d.ts +45 -0
- package/build/sources/premium/patreon-dl.d.ts.map +1 -0
- package/build/sources/premium/patreon-dl.js +189 -0
- package/build/sources/premium/patreon-dl.js.map +1 -0
- package/build/sources/premium/patreon-fetch.d.ts +3 -0
- package/build/sources/premium/patreon-fetch.d.ts.map +1 -0
- package/build/sources/premium/patreon-fetch.js +18 -0
- package/build/sources/premium/patreon-fetch.js.map +1 -0
- package/build/sources/premium/patreon-oauth.d.ts +24 -0
- package/build/sources/premium/patreon-oauth.d.ts.map +1 -0
- package/build/sources/premium/patreon-oauth.js +208 -0
- package/build/sources/premium/patreon-oauth.js.map +1 -0
- package/build/sources/premium/patreon-zip.d.ts +17 -0
- package/build/sources/premium/patreon-zip.d.ts.map +1 -0
- package/build/sources/premium/patreon-zip.js +127 -0
- package/build/sources/premium/patreon-zip.js.map +1 -0
- package/build/sources/premium/patreon.d.ts +48 -0
- package/build/sources/premium/patreon.d.ts.map +1 -0
- package/build/sources/premium/patreon.js +221 -0
- package/build/sources/premium/patreon.js.map +1 -0
- package/build/sources/premium/youtube.d.ts +14 -0
- package/build/sources/premium/youtube.d.ts.map +1 -0
- package/build/sources/premium/youtube.js +92 -0
- package/build/sources/premium/youtube.js.map +1 -0
- package/build/tools/extract-cookie.d.ts +2 -0
- package/build/tools/extract-cookie.d.ts.map +1 -0
- package/build/tools/extract-cookie.js +40 -0
- package/build/tools/extract-cookie.js.map +1 -0
- package/build/tools/handlers/enableSource.d.ts +3 -0
- package/build/tools/handlers/enableSource.d.ts.map +1 -0
- package/build/tools/handlers/enableSource.js +25 -0
- package/build/tools/handlers/enableSource.js.map +1 -0
- package/build/tools/handlers/getPatreonPatterns.d.ts +3 -0
- package/build/tools/handlers/getPatreonPatterns.d.ts.map +1 -0
- package/build/tools/handlers/getPatreonPatterns.js +43 -0
- package/build/tools/handlers/getPatreonPatterns.js.map +1 -0
- package/build/tools/handlers/getSwiftPattern.d.ts +3 -0
- package/build/tools/handlers/getSwiftPattern.d.ts.map +1 -0
- package/build/tools/handlers/getSwiftPattern.js +72 -0
- package/build/tools/handlers/getSwiftPattern.js.map +1 -0
- package/build/tools/handlers/handlers.test.d.ts +2 -0
- package/build/tools/handlers/handlers.test.d.ts.map +1 -0
- package/build/tools/handlers/handlers.test.js +359 -0
- package/build/tools/handlers/handlers.test.js.map +1 -0
- package/build/tools/handlers/listContentSources.d.ts +3 -0
- package/build/tools/handlers/listContentSources.d.ts.map +1 -0
- package/build/tools/handlers/listContentSources.js +34 -0
- package/build/tools/handlers/listContentSources.js.map +1 -0
- package/build/tools/handlers/searchSwiftContent.d.ts +3 -0
- package/build/tools/handlers/searchSwiftContent.d.ts.map +1 -0
- package/build/tools/handlers/searchSwiftContent.js +121 -0
- package/build/tools/handlers/searchSwiftContent.js.map +1 -0
- package/build/tools/handlers/setupPatreon.d.ts +3 -0
- package/build/tools/handlers/setupPatreon.d.ts.map +1 -0
- package/build/tools/handlers/setupPatreon.js +40 -0
- package/build/tools/handlers/setupPatreon.js.map +1 -0
- package/build/tools/index.d.ts +3 -0
- package/build/tools/index.d.ts.map +1 -0
- package/build/tools/index.js +18 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/registry.d.ts +14 -0
- package/build/tools/registry.d.ts.map +1 -0
- package/build/tools/registry.js +21 -0
- package/build/tools/registry.js.map +1 -0
- package/build/tools/registry.test.d.ts +2 -0
- package/build/tools/registry.test.d.ts.map +1 -0
- package/build/tools/registry.test.js +54 -0
- package/build/tools/registry.test.js.map +1 -0
- package/build/tools/types.d.ts +67 -0
- package/build/tools/types.d.ts.map +1 -0
- package/build/tools/types.js +3 -0
- package/build/tools/types.js.map +1 -0
- package/build/utils/cache.d.ts +20 -0
- package/build/utils/cache.d.ts.map +1 -0
- package/build/utils/cache.js +186 -0
- package/build/utils/cache.js.map +1 -0
- package/build/utils/concurrency.d.ts +13 -0
- package/build/utils/concurrency.d.ts.map +1 -0
- package/build/utils/concurrency.js +33 -0
- package/build/utils/concurrency.js.map +1 -0
- package/build/utils/errors.d.ts +19 -0
- package/build/utils/errors.d.ts.map +1 -0
- package/build/utils/errors.js +35 -0
- package/build/utils/errors.js.map +1 -0
- package/build/utils/fetch.d.ts +6 -0
- package/build/utils/fetch.d.ts.map +1 -0
- package/build/utils/fetch.js +6 -0
- package/build/utils/fetch.js.map +1 -0
- package/build/utils/http.d.ts +21 -0
- package/build/utils/http.d.ts.map +1 -0
- package/build/utils/http.js +53 -0
- package/build/utils/http.js.map +1 -0
- package/build/utils/intent-cache.d.ts +94 -0
- package/build/utils/intent-cache.d.ts.map +1 -0
- package/build/utils/intent-cache.js +164 -0
- package/build/utils/intent-cache.js.map +1 -0
- package/build/utils/intent-cache.test.d.ts +2 -0
- package/build/utils/intent-cache.test.d.ts.map +1 -0
- package/build/utils/intent-cache.test.js +290 -0
- package/build/utils/intent-cache.test.js.map +1 -0
- package/build/utils/logger.d.ts +4 -0
- package/build/utils/logger.d.ts.map +1 -0
- package/build/utils/logger.js +9 -0
- package/build/utils/logger.js.map +1 -0
- package/build/utils/paths.d.ts +27 -0
- package/build/utils/paths.d.ts.map +1 -0
- package/build/utils/paths.js +43 -0
- package/build/utils/paths.js.map +1 -0
- package/build/utils/pattern-formatter.d.ts +40 -0
- package/build/utils/pattern-formatter.d.ts.map +1 -0
- package/build/utils/pattern-formatter.js +124 -0
- package/build/utils/pattern-formatter.js.map +1 -0
- package/build/utils/response-helpers.d.ts +17 -0
- package/build/utils/response-helpers.d.ts.map +1 -0
- package/build/utils/response-helpers.js +34 -0
- package/build/utils/response-helpers.js.map +1 -0
- package/build/utils/search-terms.d.ts +17 -0
- package/build/utils/search-terms.d.ts.map +1 -0
- package/build/utils/search-terms.js +71 -0
- package/build/utils/search-terms.js.map +1 -0
- package/build/utils/search-terms.test.d.ts +2 -0
- package/build/utils/search-terms.test.d.ts.map +1 -0
- package/build/utils/search-terms.test.js +107 -0
- package/build/utils/search-terms.test.js.map +1 -0
- package/build/utils/search.d.ts +48 -0
- package/build/utils/search.d.ts.map +1 -0
- package/build/utils/search.js +158 -0
- package/build/utils/search.js.map +1 -0
- package/build/utils/search.test.d.ts +2 -0
- package/build/utils/search.test.d.ts.map +1 -0
- package/build/utils/search.test.js +199 -0
- package/build/utils/search.test.js.map +1 -0
- package/build/utils/semantic-recall.d.ts +38 -0
- package/build/utils/semantic-recall.d.ts.map +1 -0
- package/build/utils/semantic-recall.js +134 -0
- package/build/utils/semantic-recall.js.map +1 -0
- package/build/utils/semantic-recall.test.d.ts +2 -0
- package/build/utils/semantic-recall.test.d.ts.map +1 -0
- package/build/utils/semantic-recall.test.js +326 -0
- package/build/utils/semantic-recall.test.js.map +1 -0
- package/build/utils/source-registry.d.ts +45 -0
- package/build/utils/source-registry.d.ts.map +1 -0
- package/build/utils/source-registry.js +113 -0
- package/build/utils/source-registry.js.map +1 -0
- package/build/utils/source-registry.test.d.ts +2 -0
- package/build/utils/source-registry.test.d.ts.map +1 -0
- package/build/utils/source-registry.test.js +206 -0
- package/build/utils/source-registry.test.js.map +1 -0
- package/build/utils/swift-analysis.d.ts +61 -0
- package/build/utils/swift-analysis.d.ts.map +1 -0
- package/build/utils/swift-analysis.js +339 -0
- package/build/utils/swift-analysis.js.map +1 -0
- package/build/utils/swift-analysis.test.d.ts +2 -0
- package/build/utils/swift-analysis.test.d.ts.map +1 -0
- package/build/utils/swift-analysis.test.js +473 -0
- package/build/utils/swift-analysis.test.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;IACtC,IAAI,EAAE;QACJ,OAAO,EAAE,oBAAoB;KAC9B;CACF,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the base directory for swift-patterns-mcp configuration and data
|
|
3
|
+
* @returns The absolute path to ~/.swift-patterns-mcp directory
|
|
4
|
+
*/
|
|
5
|
+
export declare function getSwiftMcpDir(): string;
|
|
6
|
+
/**
|
|
7
|
+
* Get the configuration file path
|
|
8
|
+
* @returns The absolute path to the config.json file
|
|
9
|
+
*/
|
|
10
|
+
export declare function getConfigPath(): string;
|
|
11
|
+
/**
|
|
12
|
+
* Get the cache directory path
|
|
13
|
+
* @param namespace Optional namespace for cache isolation
|
|
14
|
+
* @returns The absolute path to the cache directory
|
|
15
|
+
*/
|
|
16
|
+
export declare function getCacheDir(namespace?: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Get the Patreon content download directory
|
|
19
|
+
* @returns The absolute path to the patreon-content directory
|
|
20
|
+
*/
|
|
21
|
+
export declare function getPatreonContentDir(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Get the Patreon creators configuration path
|
|
24
|
+
* @returns The absolute path to the patreon-creators.json file
|
|
25
|
+
*/
|
|
26
|
+
export declare function getPatreonCreatorsPath(): string;
|
|
27
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAGvC;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// src/utils/paths.ts
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Get the base directory for swift-patterns-mcp configuration and data
|
|
5
|
+
* @returns The absolute path to ~/.swift-patterns-mcp directory
|
|
6
|
+
*/
|
|
7
|
+
export function getSwiftMcpDir() {
|
|
8
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
9
|
+
return path.join(home, '.swift-patterns-mcp');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get the configuration file path
|
|
13
|
+
* @returns The absolute path to the config.json file
|
|
14
|
+
*/
|
|
15
|
+
export function getConfigPath() {
|
|
16
|
+
return path.join(getSwiftMcpDir(), 'config.json');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get the cache directory path
|
|
20
|
+
* @param namespace Optional namespace for cache isolation
|
|
21
|
+
* @returns The absolute path to the cache directory
|
|
22
|
+
*/
|
|
23
|
+
export function getCacheDir(namespace) {
|
|
24
|
+
if (namespace) {
|
|
25
|
+
return path.join(getSwiftMcpDir(), 'cache', namespace);
|
|
26
|
+
}
|
|
27
|
+
return path.join(getSwiftMcpDir(), 'cache');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get the Patreon content download directory
|
|
31
|
+
* @returns The absolute path to the patreon-content directory
|
|
32
|
+
*/
|
|
33
|
+
export function getPatreonContentDir() {
|
|
34
|
+
return path.join(getSwiftMcpDir(), 'patreon-content');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get the Patreon creators configuration path
|
|
38
|
+
* @returns The absolute path to the patreon-creators.json file
|
|
39
|
+
*/
|
|
40
|
+
export function getPatreonCreatorsPath() {
|
|
41
|
+
return path.join(getSwiftMcpDir(), 'patreon-creators.json');
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,qBAAqB;AAErB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,aAAa,CAAC,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,SAAkB;IAC5C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,uBAAuB,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for formatting patterns in responses
|
|
3
|
+
*/
|
|
4
|
+
import type { BasePattern } from '../sources/free/rssPatternSource.js';
|
|
5
|
+
export interface FormatOptions {
|
|
6
|
+
maxResults?: number;
|
|
7
|
+
includeQuality?: boolean;
|
|
8
|
+
includeTopics?: boolean;
|
|
9
|
+
includeCode?: boolean;
|
|
10
|
+
excerptLength?: number;
|
|
11
|
+
includeSnippets?: boolean;
|
|
12
|
+
includeTechniques?: boolean;
|
|
13
|
+
includeComplexity?: boolean;
|
|
14
|
+
maxSnippets?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Common format options used by tool handlers
|
|
18
|
+
*/
|
|
19
|
+
export declare const COMMON_FORMAT_OPTIONS: FormatOptions;
|
|
20
|
+
/**
|
|
21
|
+
* Detect if the user wants to see code examples based on args or query content
|
|
22
|
+
*/
|
|
23
|
+
export declare function detectCodeIntent(args: any, query: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Format a single pattern as markdown
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatPattern(pattern: BasePattern, options?: FormatOptions): string;
|
|
28
|
+
/**
|
|
29
|
+
* Format multiple patterns as a markdown document
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatPatterns(patterns: BasePattern[], title: string, options?: FormatOptions): string;
|
|
32
|
+
/**
|
|
33
|
+
* Format patterns for topic-based queries (with quality and topics)
|
|
34
|
+
*/
|
|
35
|
+
export declare function formatTopicPatterns(patterns: BasePattern[], topic: string, options?: FormatOptions): string;
|
|
36
|
+
/**
|
|
37
|
+
* Format patterns for general search queries
|
|
38
|
+
*/
|
|
39
|
+
export declare function formatSearchPatterns(patterns: BasePattern[], query: string, options?: FormatOptions): string;
|
|
40
|
+
//# sourceMappingURL=pattern-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-formatter.d.ts","sourceRoot":"","sources":["../../src/utils/pattern-formatter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AASvE,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAcD;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAMnC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAoDvF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,MAAM,CAsBR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,MAAM,CAQR"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for formatting patterns in responses
|
|
3
|
+
*/
|
|
4
|
+
import { extractCodeSnippets, extractTechniques, detectComplexity, truncateAtSentence, extractDescriptiveTitle } from './swift-analysis.js';
|
|
5
|
+
const DEFAULT_OPTIONS = {
|
|
6
|
+
maxResults: 10,
|
|
7
|
+
includeQuality: false,
|
|
8
|
+
includeTopics: false,
|
|
9
|
+
includeCode: true,
|
|
10
|
+
excerptLength: 200,
|
|
11
|
+
includeSnippets: true,
|
|
12
|
+
includeTechniques: true,
|
|
13
|
+
includeComplexity: true,
|
|
14
|
+
maxSnippets: 1,
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Common format options used by tool handlers
|
|
18
|
+
*/
|
|
19
|
+
export const COMMON_FORMAT_OPTIONS = {
|
|
20
|
+
maxResults: 4,
|
|
21
|
+
includeSnippets: false,
|
|
22
|
+
includeTechniques: false,
|
|
23
|
+
includeComplexity: false,
|
|
24
|
+
excerptLength: 200,
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Detect if the user wants to see code examples based on args or query content
|
|
28
|
+
*/
|
|
29
|
+
export function detectCodeIntent(args, query) {
|
|
30
|
+
return Boolean(args?.includeCode) || /code|example|snippet/i.test(query);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Format a single pattern as markdown
|
|
34
|
+
*/
|
|
35
|
+
export function formatPattern(pattern, options = {}) {
|
|
36
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
37
|
+
const sourceId = pattern.id.split('-')[0];
|
|
38
|
+
// Extract descriptive title from content
|
|
39
|
+
const title = extractDescriptiveTitle(pattern.content, pattern.title);
|
|
40
|
+
let formatted = `## ${title}\n`;
|
|
41
|
+
formatted += `**Source**: ${sourceId}\n`;
|
|
42
|
+
if (opts.includeQuality) {
|
|
43
|
+
formatted += `**Quality**: ${pattern.relevanceScore}/100\n`;
|
|
44
|
+
}
|
|
45
|
+
if (opts.includeComplexity) {
|
|
46
|
+
const complexity = detectComplexity(pattern.content, pattern.topics);
|
|
47
|
+
formatted += `**Complexity**: ${complexity}\n`;
|
|
48
|
+
}
|
|
49
|
+
if (opts.includeTopics && pattern.topics.length > 0) {
|
|
50
|
+
formatted += `**Topics**: ${pattern.topics.join(', ')}\n`;
|
|
51
|
+
}
|
|
52
|
+
if (opts.includeTechniques) {
|
|
53
|
+
const techniques = extractTechniques(pattern.content);
|
|
54
|
+
if (techniques.length > 0) {
|
|
55
|
+
formatted += `**Techniques**: ${techniques.join(', ')}\n`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Show code snippets if available and requested
|
|
59
|
+
if (opts.includeSnippets && pattern.hasCode) {
|
|
60
|
+
const snippets = extractCodeSnippets(pattern.content, opts.maxSnippets);
|
|
61
|
+
if (snippets.length > 0) {
|
|
62
|
+
formatted += `\n**Code Example**:\n`;
|
|
63
|
+
snippets.forEach(snippet => {
|
|
64
|
+
formatted += '```swift\n' + snippet + '\n```\n';
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else if (opts.includeCode) {
|
|
68
|
+
// Fallback to checkmark if no snippets extracted
|
|
69
|
+
formatted += `**Code**: ✅\n`;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else if (opts.includeCode && pattern.hasCode) {
|
|
73
|
+
formatted += `**Code**: ✅\n`;
|
|
74
|
+
}
|
|
75
|
+
// Use smart truncation at sentence boundaries
|
|
76
|
+
const excerpt = truncateAtSentence(pattern.excerpt, opts.excerptLength);
|
|
77
|
+
formatted += `\n${excerpt}...\n\n`;
|
|
78
|
+
formatted += `[Read more](${pattern.url})`;
|
|
79
|
+
return formatted;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Format multiple patterns as a markdown document
|
|
83
|
+
*/
|
|
84
|
+
export function formatPatterns(patterns, title, options = {}) {
|
|
85
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
86
|
+
const limited = patterns.slice(0, opts.maxResults);
|
|
87
|
+
const formatted = limited.map(p => formatPattern(p, opts)).join('\n\n---\n\n');
|
|
88
|
+
const count = patterns.length;
|
|
89
|
+
const shown = limited.length;
|
|
90
|
+
let result = `# ${title}\n\n`;
|
|
91
|
+
if (count > 0) {
|
|
92
|
+
result += `Found ${count} result${count === 1 ? '' : 's'}:\n\n`;
|
|
93
|
+
}
|
|
94
|
+
result += formatted;
|
|
95
|
+
if (count > shown) {
|
|
96
|
+
result += `\n\n*Showing top ${shown} of ${count} results*`;
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Format patterns for topic-based queries (with quality and topics)
|
|
102
|
+
*/
|
|
103
|
+
export function formatTopicPatterns(patterns, topic, options = {}) {
|
|
104
|
+
return formatPatterns(patterns, `Swift Patterns: ${topic}`, {
|
|
105
|
+
...options,
|
|
106
|
+
includeQuality: true,
|
|
107
|
+
includeTopics: true,
|
|
108
|
+
includeCode: true,
|
|
109
|
+
excerptLength: 300,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Format patterns for general search queries
|
|
114
|
+
*/
|
|
115
|
+
export function formatSearchPatterns(patterns, query, options = {}) {
|
|
116
|
+
return formatPatterns(patterns, `Search Results: "${query}"`, {
|
|
117
|
+
...options,
|
|
118
|
+
includeQuality: false,
|
|
119
|
+
includeTopics: false,
|
|
120
|
+
includeCode: true,
|
|
121
|
+
excerptLength: 200,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=pattern-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-formatter.js","sourceRoot":"","sources":["../../src/utils/pattern-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response formatting helpers for consistent MCP tool responses
|
|
3
|
+
*/
|
|
4
|
+
import type { ToolResponse } from '../tools/types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create a standard text response
|
|
7
|
+
*/
|
|
8
|
+
export declare function createTextResponse(text: string): ToolResponse;
|
|
9
|
+
/**
|
|
10
|
+
* Create an error response
|
|
11
|
+
*/
|
|
12
|
+
export declare function createErrorResponse(message: string): ToolResponse;
|
|
13
|
+
/**
|
|
14
|
+
* Create a response from an error (uses error utilities)
|
|
15
|
+
*/
|
|
16
|
+
export declare function createErrorResponseFromError(error: unknown): ToolResponse;
|
|
17
|
+
//# sourceMappingURL=response-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/response-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAO7D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAQjE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAEzE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response formatting helpers for consistent MCP tool responses
|
|
3
|
+
*/
|
|
4
|
+
import { toErrorMessage } from './errors.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create a standard text response
|
|
7
|
+
*/
|
|
8
|
+
export function createTextResponse(text) {
|
|
9
|
+
return {
|
|
10
|
+
content: [{
|
|
11
|
+
type: "text",
|
|
12
|
+
text,
|
|
13
|
+
}],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create an error response
|
|
18
|
+
*/
|
|
19
|
+
export function createErrorResponse(message) {
|
|
20
|
+
return {
|
|
21
|
+
content: [{
|
|
22
|
+
type: "text",
|
|
23
|
+
text: `Error: ${message}`,
|
|
24
|
+
}],
|
|
25
|
+
isError: true,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a response from an error (uses error utilities)
|
|
30
|
+
*/
|
|
31
|
+
export function createErrorResponseFromError(error) {
|
|
32
|
+
return createErrorResponse(toErrorMessage(error));
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=response-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-helpers.js","sourceRoot":"","sources":["../../src/utils/response-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI;aACL,CAAC;KACH,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,UAAU,OAAO,EAAE;aAC1B,CAAC;QACF,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAAC,KAAc;IACzD,OAAO,mBAAmB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const STOPWORDS: Set<string>;
|
|
2
|
+
export declare const PRESERVE_TERMS: Set<string>;
|
|
3
|
+
/**
|
|
4
|
+
* Shared token normalization logic used by both search and intent caching.
|
|
5
|
+
*
|
|
6
|
+
* - Lowercase
|
|
7
|
+
* - Strip non-word characters (keeping hyphens)
|
|
8
|
+
* - Split on whitespace
|
|
9
|
+
* - Split hyphenated terms
|
|
10
|
+
* - Filter stopwords while preserving Swift-specific terms
|
|
11
|
+
*
|
|
12
|
+
* @param text - Text to normalize
|
|
13
|
+
* @param applyTransform - Optional transform function (e.g., stemmer) applied to non-preserved terms
|
|
14
|
+
* @returns Array of normalized tokens
|
|
15
|
+
*/
|
|
16
|
+
export declare function normalizeTokens(text: string, applyTransform?: (token: string) => string): string[];
|
|
17
|
+
//# sourceMappingURL=search-terms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-terms.d.ts","sourceRoot":"","sources":["../../src/utils/search-terms.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,aAUpB,CAAC;AAIH,eAAO,MAAM,cAAc,aAOzB,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GACzC,MAAM,EAAE,CAmCV"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// src/utils/search-terms.ts
|
|
2
|
+
// Shared search-related term lists
|
|
3
|
+
// Common stopwords to filter out
|
|
4
|
+
export const STOPWORDS = new Set([
|
|
5
|
+
'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
|
|
6
|
+
'of', 'with', 'by', 'from', 'as', 'is', 'was', 'are', 'were', 'been',
|
|
7
|
+
'be', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
|
|
8
|
+
'should', 'may', 'might', 'must', 'shall', 'can', 'this', 'that', 'these',
|
|
9
|
+
'those', 'it', 'its', 'they', 'them', 'their', 'we', 'our', 'you', 'your',
|
|
10
|
+
'i', 'my', 'me', 'he', 'she', 'him', 'her', 'his', 'who', 'what', 'which',
|
|
11
|
+
'when', 'where', 'why', 'how', 'all', 'each', 'every', 'both', 'few',
|
|
12
|
+
'more', 'most', 'other', 'some', 'such', 'no', 'not', 'only', 'same',
|
|
13
|
+
'so', 'than', 'too', 'very', 'just', 'also', 'now', 'here', 'there'
|
|
14
|
+
]);
|
|
15
|
+
// Swift-specific terms that shouldn't be stemmed (preserve technical accuracy)
|
|
16
|
+
// NOTE: If you add hyphenated terms here (e.g. "objective-c"), the tokenizer will now respect them.
|
|
17
|
+
export const PRESERVE_TERMS = new Set([
|
|
18
|
+
'swift', 'swiftui', 'uikit', 'combine', 'async', 'await', 'actor',
|
|
19
|
+
'struct', 'class', 'enum', 'protocol', 'extension', 'func', 'var', 'let',
|
|
20
|
+
'mvvm', 'viper', 'mvc', 'tca', 'xctest', 'xcode', 'ios', 'macos',
|
|
21
|
+
'watchos', 'tvos', 'ipados', 'appkit', 'foundation', 'coredata',
|
|
22
|
+
'cloudkit', 'urlsession', 'codable', 'observable', 'published',
|
|
23
|
+
'stateobject', 'observedobject', 'environmentobject', 'binding', 'state'
|
|
24
|
+
]);
|
|
25
|
+
/**
|
|
26
|
+
* Shared token normalization logic used by both search and intent caching.
|
|
27
|
+
*
|
|
28
|
+
* - Lowercase
|
|
29
|
+
* - Strip non-word characters (keeping hyphens)
|
|
30
|
+
* - Split on whitespace
|
|
31
|
+
* - Split hyphenated terms
|
|
32
|
+
* - Filter stopwords while preserving Swift-specific terms
|
|
33
|
+
*
|
|
34
|
+
* @param text - Text to normalize
|
|
35
|
+
* @param applyTransform - Optional transform function (e.g., stemmer) applied to non-preserved terms
|
|
36
|
+
* @returns Array of normalized tokens
|
|
37
|
+
*/
|
|
38
|
+
export function normalizeTokens(text, applyTransform) {
|
|
39
|
+
// 1. Clean text but keep hyphens temporarily
|
|
40
|
+
const rawTokens = text
|
|
41
|
+
.toLowerCase()
|
|
42
|
+
.replace(/[^\w\s-]/g, ' ')
|
|
43
|
+
.split(/\s+/)
|
|
44
|
+
.filter(t => t.length > 0);
|
|
45
|
+
const finalTokens = [];
|
|
46
|
+
for (const token of rawTokens) {
|
|
47
|
+
// 2. Check if the full token is a preserved term (e.g., "objective-c")
|
|
48
|
+
if (PRESERVE_TERMS.has(token)) {
|
|
49
|
+
finalTokens.push(token);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
// 3. If not preserved, split on hyphens to separate words like "async-await" -> "async", "await"
|
|
53
|
+
const subTokens = token.split('-');
|
|
54
|
+
for (const sub of subTokens) {
|
|
55
|
+
if (sub.length <= 1 || STOPWORDS.has(sub))
|
|
56
|
+
continue;
|
|
57
|
+
// 4. Check sub-tokens against preserved terms or apply transform
|
|
58
|
+
if (PRESERVE_TERMS.has(sub)) {
|
|
59
|
+
finalTokens.push(sub);
|
|
60
|
+
}
|
|
61
|
+
else if (applyTransform) {
|
|
62
|
+
finalTokens.push(applyTransform(sub));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
finalTokens.push(sub);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return finalTokens;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=search-terms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-terms.js","sourceRoot":"","sources":["../../src/utils/search-terms.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-terms.test.d.ts","sourceRoot":"","sources":["../../src/utils/search-terms.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// src/utils/search-terms.test.ts
|
|
2
|
+
// Tests for shared normalization logic
|
|
3
|
+
import { describe, it, expect } from 'vitest';
|
|
4
|
+
import { normalizeTokens } from './search-terms.js';
|
|
5
|
+
describe('normalizeTokens', () => {
|
|
6
|
+
describe('basic normalization', () => {
|
|
7
|
+
it('should lowercase text', () => {
|
|
8
|
+
const result = normalizeTokens('SwiftUI Combine');
|
|
9
|
+
expect(result).toContain('swiftui');
|
|
10
|
+
expect(result).toContain('combine');
|
|
11
|
+
});
|
|
12
|
+
it('should filter stopwords', () => {
|
|
13
|
+
const result = normalizeTokens('how to use async await');
|
|
14
|
+
expect(result).not.toContain('how');
|
|
15
|
+
expect(result).not.toContain('to');
|
|
16
|
+
expect(result).toContain('use');
|
|
17
|
+
expect(result).toContain('async');
|
|
18
|
+
expect(result).toContain('await');
|
|
19
|
+
});
|
|
20
|
+
it('should handle hyphenated terms', () => {
|
|
21
|
+
const result = normalizeTokens('async-await patterns');
|
|
22
|
+
expect(result).toContain('async');
|
|
23
|
+
expect(result).toContain('await');
|
|
24
|
+
expect(result).toContain('patterns');
|
|
25
|
+
});
|
|
26
|
+
it('should preserve Swift-specific terms', () => {
|
|
27
|
+
const result = normalizeTokens('swiftui actor protocol');
|
|
28
|
+
expect(result).toContain('swiftui');
|
|
29
|
+
expect(result).toContain('actor');
|
|
30
|
+
expect(result).toContain('protocol');
|
|
31
|
+
});
|
|
32
|
+
it('should strip non-word characters', () => {
|
|
33
|
+
const result = normalizeTokens('test@email.com (example) [brackets]');
|
|
34
|
+
// Only valid word tokens should remain
|
|
35
|
+
expect(result).not.toContain('@');
|
|
36
|
+
expect(result).not.toContain('(');
|
|
37
|
+
expect(result).not.toContain(')');
|
|
38
|
+
});
|
|
39
|
+
it('should filter short tokens', () => {
|
|
40
|
+
const result = normalizeTokens('a b swift ui');
|
|
41
|
+
expect(result).not.toContain('a');
|
|
42
|
+
expect(result).not.toContain('b');
|
|
43
|
+
expect(result).toContain('swift');
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe('with transform function', () => {
|
|
47
|
+
it('should apply transform to non-preserved terms', () => {
|
|
48
|
+
const mockStemmer = (token) => token + '_stem';
|
|
49
|
+
const result = normalizeTokens('testing patterns', mockStemmer);
|
|
50
|
+
// "patterns" should be stemmed
|
|
51
|
+
expect(result).toContain('patterns_stem');
|
|
52
|
+
});
|
|
53
|
+
it('should not apply transform to preserved terms', () => {
|
|
54
|
+
const mockStemmer = (token) => token + '_stem';
|
|
55
|
+
const result = normalizeTokens('swiftui patterns', mockStemmer);
|
|
56
|
+
// "swiftui" should NOT be stemmed
|
|
57
|
+
expect(result).toContain('swiftui');
|
|
58
|
+
expect(result).not.toContain('swiftui_stem');
|
|
59
|
+
// "patterns" should be stemmed
|
|
60
|
+
expect(result).toContain('patterns_stem');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('edge cases', () => {
|
|
64
|
+
it('should handle empty string', () => {
|
|
65
|
+
const result = normalizeTokens('');
|
|
66
|
+
expect(result).toEqual([]);
|
|
67
|
+
});
|
|
68
|
+
it('should handle only stopwords', () => {
|
|
69
|
+
const result = normalizeTokens('the and or but');
|
|
70
|
+
expect(result).toEqual([]);
|
|
71
|
+
});
|
|
72
|
+
it('should handle whitespace-only', () => {
|
|
73
|
+
const result = normalizeTokens(' \t\n ');
|
|
74
|
+
expect(result).toEqual([]);
|
|
75
|
+
});
|
|
76
|
+
it('should handle mixed case preserved terms', () => {
|
|
77
|
+
const result = normalizeTokens('SwiftUI ASYNC Await');
|
|
78
|
+
expect(result).toContain('swiftui');
|
|
79
|
+
expect(result).toContain('async');
|
|
80
|
+
expect(result).toContain('await');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
describe('consistency with IntentCache and search', () => {
|
|
84
|
+
it('should produce same tokens for query normalization (without transform)', () => {
|
|
85
|
+
const query = 'how to use async-await with SwiftUI';
|
|
86
|
+
const result = normalizeTokens(query);
|
|
87
|
+
// Should contain: use, async, await, swiftui (sorted elsewhere)
|
|
88
|
+
expect(result).toContain('use');
|
|
89
|
+
expect(result).toContain('async');
|
|
90
|
+
expect(result).toContain('await');
|
|
91
|
+
expect(result).toContain('swiftui');
|
|
92
|
+
// Should NOT contain stopwords
|
|
93
|
+
expect(result).not.toContain('how');
|
|
94
|
+
expect(result).not.toContain('to');
|
|
95
|
+
expect(result).not.toContain('with');
|
|
96
|
+
});
|
|
97
|
+
it('should handle technical terms consistently', () => {
|
|
98
|
+
const query = 'mvvm architecture objective-c';
|
|
99
|
+
const result = normalizeTokens(query);
|
|
100
|
+
expect(result).toContain('mvvm');
|
|
101
|
+
expect(result).toContain('architecture');
|
|
102
|
+
expect(result).toContain('objective'); // Split from hyphen
|
|
103
|
+
expect(result).not.toContain('c'); // Filtered as <= 1 char
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=search-terms.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-terms.test.js","sourceRoot":"","sources":["../../src/utils/search-terms.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export interface SearchableDocument {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
content: string;
|
|
5
|
+
topics: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface SearchResult<T> {
|
|
8
|
+
item: T;
|
|
9
|
+
score: number;
|
|
10
|
+
matches: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface SearchOptions {
|
|
13
|
+
fuzzy?: number;
|
|
14
|
+
boost?: Record<string, number>;
|
|
15
|
+
minScore?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class SearchIndex<T extends SearchableDocument> {
|
|
18
|
+
private miniSearch;
|
|
19
|
+
private documents;
|
|
20
|
+
constructor(fields?: string[]);
|
|
21
|
+
addDocuments(docs: T[]): void;
|
|
22
|
+
search(query: string, options?: SearchOptions): SearchResult<T>[];
|
|
23
|
+
private findMatches;
|
|
24
|
+
}
|
|
25
|
+
export declare function fuzzySearch<T extends SearchableDocument>(documents: T[], query: string, options?: SearchOptions): SearchResult<T>[];
|
|
26
|
+
export declare function combineScores(searchScore: number, staticRelevance: number, searchWeight?: number): number;
|
|
27
|
+
export declare function suggestSimilar(query: string, knownTerms: string[], maxSuggestions?: number): string[];
|
|
28
|
+
/**
|
|
29
|
+
* CachedSearchIndex - Manages a SearchIndex with automatic invalidation based on document changes.
|
|
30
|
+
* Eliminates duplicated search caching logic across pattern sources.
|
|
31
|
+
*/
|
|
32
|
+
export declare class CachedSearchIndex<T extends SearchableDocument> {
|
|
33
|
+
private searchIndex;
|
|
34
|
+
private indexedPatternsHash;
|
|
35
|
+
private fields;
|
|
36
|
+
constructor(fields?: string[]);
|
|
37
|
+
/**
|
|
38
|
+
* Search patterns with automatic index caching.
|
|
39
|
+
* Index is rebuilt only when patterns change (detected via hash).
|
|
40
|
+
*/
|
|
41
|
+
search(patterns: T[], query: string, options?: SearchOptions): T[];
|
|
42
|
+
/**
|
|
43
|
+
* Invalidate the cached index (call after fetching new patterns)
|
|
44
|
+
*/
|
|
45
|
+
invalidate(): void;
|
|
46
|
+
}
|
|
47
|
+
export default SearchIndex;
|
|
48
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/utils/search.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAYD,qBAAa,WAAW,CAAC,CAAC,SAAS,kBAAkB;IACnD,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,SAAS,CAA6B;gBAElC,MAAM,GAAE,MAAM,EAAmC;IAc7D,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI;IAmB7B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE;IAqCrE,OAAO,CAAC,WAAW;CAapB;AAGD,wBAAgB,WAAW,CAAC,CAAC,SAAS,kBAAkB,EACtD,SAAS,EAAE,CAAC,EAAE,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAAC,CAAC,CAAC,EAAE,CAInB;AAGD,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,YAAY,GAAE,MAAY,GACzB,MAAM,CASR;AAGD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAAE,EACpB,cAAc,GAAE,MAAU,GACzB,MAAM,EAAE,CAeV;AAED;;;GAGG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,kBAAkB;IACzD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,MAAM,CAAW;gBAEb,MAAM,GAAE,MAAM,EAAmC;IAI7D;;;OAGG;IACH,MAAM,CACJ,QAAQ,EAAE,CAAC,EAAE,EACb,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,CAAC,EAAE;IA0BN;;OAEG;IACH,UAAU,IAAI,IAAI;CAInB;AAED,eAAe,WAAW,CAAC"}
|