{"_id":"@4meta5/semantic-matcher","_rev":"7-164e520597bfc864ee1d93d001ea8e99","name":"@4meta5/semantic-matcher","dist-tags":{"latest":"0.5.3"},"versions":{"0.1.0":{"name":"@4meta5/semantic-matcher","version":"0.1.0","keywords":["semantic","matching","embeddings","search","router","keyword","similarity"],"author":{"name":"Amar Singh"},"license":"MIT","_id":"@4meta5/semantic-matcher@0.1.0","maintainers":[{"name":"4meta5","email":"orlandodowntownhome@gmail.com"}],"homepage":"https://github.com/4meta5/skills#readme","bugs":{"url":"https://github.com/4meta5/skills/issues"},"dist":{"shasum":"dbb1e003f83ca5e51bfeab2a5085a5043eb5782e","tarball":"https://registry.npmjs.org/@4meta5/semantic-matcher/-/semantic-matcher-0.1.0.tgz","fileCount":26,"integrity":"sha512-cRqauJkauYncOxIUrUWwNz16U9fhQlWjQWd22H21WB8EkiAb6X3Mzje5TWE3ZM7uAnftRz78EiFK2PffJ0yXqg==","signatures":[{"sig":"MEQCIE6c8zTwog6JyGaYlG0NU/wu6NERWE3EOqBokeTf+5UgAiA7ZjyuGhHUO+BaXz6m54v0zr8feGe/I0ZysePKOPlASg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54451},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"6cbe0f88d5a5d7c15ddfd34591fb179159d0def2","scripts":{"test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"4meta5","email":"orlandodowntownhome@gmail.com"},"repository":{"url":"git+https://github.com/4meta5/skills.git","type":"git","directory":"packages/semantic-matcher"},"_npmVersion":"11.6.2","description":"Hybrid keyword + embedding semantic matcher with RRF fusion","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.3.0","@types/node":"^20.10.0"},"peerDependencies":{"@xenova/transformers":"^2.17.0"},"peerDependenciesMeta":{"@xenova/transformers":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/semantic-matcher_0.1.0_1770012908168_0.4137995706321773","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@4meta5/semantic-matcher","version":"0.2.0","keywords":["semantic","matching","embeddings","search","router","keyword","similarity"],"author":{"name":"Amar Singh"},"license":"MIT","_id":"@4meta5/semantic-matcher@0.2.0","maintainers":[{"name":"4meta5","email":"orlandodowntownhome@gmail.com"}],"homepage":"https://github.com/4meta5/skills#readme","bugs":{"url":"https://github.com/4meta5/skills/issues"},"dist":{"shasum":"22bfbdbe023f51d1418eb587c345196c5a99d0ad","tarball":"https://registry.npmjs.org/@4meta5/semantic-matcher/-/semantic-matcher-0.2.0.tgz","fileCount":26,"integrity":"sha512-G312yq2tzY22kJXh+Z5ArxK8JCgDgHVgj4e3OXwtPTNIfi0gUtNcedKnvW7pMEh6+zBVhItXzG+YT1aRWpkeSA==","signatures":[{"sig":"MEUCIFlToLtP96sHMyhnsvkzsgOlVaUO00eJZWKFJbvfo1q2AiEA7+5Rv+/WZGNX0JVnS+5ccmj+lSXIAU2c4F1cs1NGgrw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54451},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"2e5b4abe0f62c987427f566801f373f52d275af5","scripts":{"test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"4meta5","email":"orlandodowntownhome@gmail.com"},"repository":{"url":"git+https://github.com/4meta5/skills.git","type":"git","directory":"packages/semantic-matcher"},"_npmVersion":"11.6.2","description":"Hybrid keyword + embedding semantic matcher with RRF fusion","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.3.0","@types/node":"^20.10.0"},"peerDependencies":{"@xenova/transformers":"^2.17.0"},"peerDependenciesMeta":{"@xenova/transformers":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/semantic-matcher_0.2.0_1770170426840_0.4932892054985769","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@4meta5/semantic-matcher","version":"0.3.0","keywords":["semantic","matching","embeddings","search","router","keyword","similarity"],"author":{"name":"Amar Singh"},"license":"MIT","_id":"@4meta5/semantic-matcher@0.3.0","maintainers":[{"name":"4meta5","email":"orlandodowntownhome@gmail.com"}],"homepage":"https://github.com/4meta5/skills#readme","bugs":{"url":"https://github.com/4meta5/skills/issues"},"dist":{"shasum":"3979569809a743d41c271feb1bd2a9c6a28dde53","tarball":"https://registry.npmjs.org/@4meta5/semantic-matcher/-/semantic-matcher-0.3.0.tgz","fileCount":26,"integrity":"sha512-nfIAHhePHeUh9rzcSRJSqGh97Yr2ErD52B5S0BYmrg1elIYLdncoYVRN2dr9AMr2hwbQXPqVyujbJ07WzLlA8A==","signatures":[{"sig":"MEQCIDeIMXch0rtFcr4+QK3w2eoNndfRn+DmyCm0nvOr2G3BAiBo+80DyQ4O7kZYpDxvrFf+2Nn+rBbbqt4Nh3yMgDi/Ng==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54627},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"6111ffcadc2d568e6fd96c9ec68511afc58e839c","scripts":{"test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"4meta5","email":"orlandodowntownhome@gmail.com"},"repository":{"url":"git+https://github.com/4meta5/skills.git","type":"git","directory":"packages/semantic-matcher"},"_npmVersion":"11.6.2","description":"Hybrid keyword + embedding semantic matcher with RRF fusion","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.3.0","@types/node":"^20.10.0"},"peerDependencies":{"@xenova/transformers":"^2.17.0"},"peerDependenciesMeta":{"@xenova/transformers":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/semantic-matcher_0.3.0_1770296769186_0.9313947970690866","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@4meta5/semantic-matcher","version":"0.4.0","keywords":["semantic","matching","embeddings","search","router","keyword","similarity"],"author":{"name":"Amar Singh"},"license":"MIT","_id":"@4meta5/semantic-matcher@0.4.0","maintainers":[{"name":"4meta5","email":"orlandodowntownhome@gmail.com"}],"homepage":"https://github.com/4meta5/skills#readme","bugs":{"url":"https://github.com/4meta5/skills/issues"},"dist":{"shasum":"a275f6c3737e3c013b4184e73a2a97074d81543f","tarball":"https://registry.npmjs.org/@4meta5/semantic-matcher/-/semantic-matcher-0.4.0.tgz","fileCount":26,"integrity":"sha512-NoB4wMVzZ9W0RiCfloiz0lJ+T4rWRkVA6QcIUkE8Ce/vFYzV9asBlhBNWERJmkRGugPIppXMI+tQFJ9Ej3o5Cg==","signatures":[{"sig":"MEYCIQCv+NszEsEt0CBwowk8Qjrn2pmofRY3ljh1EUiDynAQ6AIhAJr+93qUt+DXpNSH2K8vQV+1iG5F+YAOAlJRKnIFP/zC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54627},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"76a6d2041fdc7810e63a0441d26574e4804ba0bb","scripts":{"test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"4meta5","email":"orlandodowntownhome@gmail.com"},"repository":{"url":"git+https://github.com/4meta5/skills.git","type":"git","directory":"packages/semantic-matcher"},"_npmVersion":"11.6.2","description":"Hybrid keyword + embedding semantic matcher with RRF fusion","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.3.0","@types/node":"^20.10.0"},"peerDependencies":{"@xenova/transformers":"^2.17.0"},"peerDependenciesMeta":{"@xenova/transformers":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/semantic-matcher_0.4.0_1771026906261_0.0636908456241232","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@4meta5/semantic-matcher","version":"0.5.1","keywords":["semantic","matching","embeddings","search","router","keyword","similarity"],"author":{"name":"Amar Singh"},"license":"MIT","_id":"@4meta5/semantic-matcher@0.5.1","maintainers":[{"name":"4meta5","email":"orlandodowntownhome@gmail.com"}],"homepage":"https://github.com/4meta5/skills#readme","bugs":{"url":"https://github.com/4meta5/skills/issues"},"dist":{"shasum":"00722d51eee7d4422e4bdd8769618907b23b724a","tarball":"https://registry.npmjs.org/@4meta5/semantic-matcher/-/semantic-matcher-0.5.1.tgz","fileCount":26,"integrity":"sha512-RmDb24gnwFj88cWaN0Yh+BAlZ4DfZis1ux1V4Yhh7AF7HKRHIMAycOR/nKVQSgKbnfJodJ5YZhYfGtmPUoDZhg==","signatures":[{"sig":"MEUCIQC7VCmu7QMekLn4I1XN186juigES++eY0e9i7qi4PeFugIgbKsfaLcyo738p89u8Oa5gUt3ZZk4dsmloIA7DPCOe0g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54627},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"52c629415cc261d1d0c4b68d86a0ad8ec06883df","scripts":{"test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"4meta5","email":"orlandodowntownhome@gmail.com"},"repository":{"url":"git+https://github.com/4meta5/skills.git","type":"git","directory":"packages/semantic-matcher"},"_npmVersion":"11.6.2","description":"Hybrid keyword + embedding semantic matcher with RRF fusion","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.3.0","@types/node":"^20.10.0"},"peerDependencies":{"@xenova/transformers":"^2.17.0"},"peerDependenciesMeta":{"@xenova/transformers":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/semantic-matcher_0.5.1_1771100516509_0.12061830096050219","host":"s3://npm-registry-packages-npm-production"}},"0.5.2":{"name":"@4meta5/semantic-matcher","version":"0.5.2","keywords":["semantic","matching","embeddings","search","router","keyword","similarity"],"author":{"name":"Amar Singh"},"license":"MIT","_id":"@4meta5/semantic-matcher@0.5.2","maintainers":[{"name":"4meta5","email":"orlandodowntownhome@gmail.com"}],"homepage":"https://github.com/4meta5/skills#readme","bugs":{"url":"https://github.com/4meta5/skills/issues"},"dist":{"shasum":"1aaadd037b278688609d93a876d2da1f42c9cc6d","tarball":"https://registry.npmjs.org/@4meta5/semantic-matcher/-/semantic-matcher-0.5.2.tgz","fileCount":26,"integrity":"sha512-26IQWMsS+rHTA7orsLBbBQ0TMLSb6NsNs20+H3FROSJjLi+6RL5eQ21fkvcCfhB8kwbfJuF1pyBy8j1EGUnYBA==","signatures":[{"sig":"MEYCIQDAaeq8hmd8CwXvviESB1gIp2MZIhI0t1JMMbCZKwwyVAIhAJ1XQ1Gj7VAeLULN//eT1QNV4/zB7UClbfxAs/D1zXGm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54627},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"cd5dd7db868244a0ba173e506bac18617ebc8908","scripts":{"test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"4meta5","email":"orlandodowntownhome@gmail.com"},"repository":{"url":"git+https://github.com/4meta5/skills.git","type":"git","directory":"packages/semantic-matcher"},"_npmVersion":"11.6.2","description":"Hybrid keyword + embedding semantic matcher with RRF fusion","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.3.0","@types/node":"^20.10.0"},"peerDependencies":{"@xenova/transformers":"^2.17.0"},"peerDependenciesMeta":{"@xenova/transformers":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/semantic-matcher_0.5.2_1771104586080_0.5927658286289303","host":"s3://npm-registry-packages-npm-production"}},"0.5.3":{"name":"@4meta5/semantic-matcher","version":"0.5.3","description":"Hybrid keyword + embedding semantic matcher with RRF fusion","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"tsc","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"keywords":["semantic","matching","embeddings","search","router","keyword","similarity"],"author":{"name":"Amar Singh"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/4meta5/skills.git","directory":"packages/semantic-matcher"},"homepage":"https://github.com/4meta5/skills#readme","bugs":{"url":"https://github.com/4meta5/skills/issues"},"devDependencies":{"@types/node":"^20.10.0","typescript":"^5.3.0","vitest":"^1.6.0"},"peerDependencies":{"@xenova/transformers":"^2.17.0"},"peerDependenciesMeta":{"@xenova/transformers":{"optional":true}},"gitHead":"1fc8d9fd71f7225845659c0557cd818e59c8200d","_id":"@4meta5/semantic-matcher@0.5.3","_nodeVersion":"25.2.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-JH4i9uONNPSe4VAVoZ+XtNysNlxBcTL+PKZYzXH8gr/Gg6+rgQxotsJ++mk5Ozz2ihFSd4hRXtjOnztU/b4anA==","shasum":"bdd0202849d82a05d6017d09852516b52631b190","tarball":"https://registry.npmjs.org/@4meta5/semantic-matcher/-/semantic-matcher-0.5.3.tgz","fileCount":26,"unpackedSize":54627,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAjg7K5xXzKVC+PbjM5aR46PQ67HYpNM6Wjv6UnsRtTEAiBU5RlElhJWUd5hWim9YZAcDjkUKWvlplMVApF4BHKWnQ=="}]},"_npmUser":{"name":"4meta5","email":"orlandodowntownhome@gmail.com"},"directories":{},"maintainers":[{"name":"4meta5","email":"orlandodowntownhome@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/semantic-matcher_0.5.3_1771107320122_0.6816291128871841"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-02T06:15:08.066Z","modified":"2026-02-14T22:15:20.383Z","0.1.0":"2026-02-02T06:15:08.322Z","0.2.0":"2026-02-04T02:00:27.002Z","0.3.0":"2026-02-05T13:06:09.351Z","0.4.0":"2026-02-13T23:55:06.407Z","0.5.1":"2026-02-14T20:21:56.653Z","0.5.2":"2026-02-14T21:29:46.220Z","0.5.3":"2026-02-14T22:15:20.286Z"},"bugs":{"url":"https://github.com/4meta5/skills/issues"},"author":{"name":"Amar Singh"},"license":"MIT","homepage":"https://github.com/4meta5/skills#readme","keywords":["semantic","matching","embeddings","search","router","keyword","similarity"],"repository":{"type":"git","url":"git+https://github.com/4meta5/skills.git","directory":"packages/semantic-matcher"},"description":"Hybrid keyword + embedding semantic matcher with RRF fusion","maintainers":[{"name":"4meta5","email":"orlandodowntownhome@gmail.com"}],"readme":"# @4meta5/semantic-matcher\n\nHybrid keyword + embedding semantic matcher with RRF (Reciprocal Rank Fusion) scoring.\n\n## Installation\n\n```bash\nnpm install @4meta5/semantic-matcher\n```\n\nFor embedding support, also install the peer dependency:\n\n```bash\nnpm install @xenova/transformers\n```\n\n## Usage\n\n### Basic matching\n\n```typescript\nimport { createMatcher } from '@4meta5/semantic-matcher';\n\nconst matcher = await createMatcher({\n  keywordWeight: 0.3,    // 30% keyword score\n  embeddingWeight: 0.7,  // 70% embedding score\n});\n\nconst candidates = [\n  {\n    id: 'tdd',\n    text: 'Test-driven development workflow',\n    keywords: ['tdd', 'test-driven', 'testing']\n  },\n  {\n    id: 'code-review',\n    text: 'Code review guidelines',\n    keywords: ['review', 'pr', 'pull request']\n  }\n];\n\nconst result = await matcher.match('write tests first', candidates);\n\nconsole.log(result.matches[0].candidate.id); // 'tdd'\nconsole.log(result.matches[0].score);        // 0.85\nconsole.log(result.matches[0].mode);         // 'immediate' | 'suggestion' | 'none'\n```\n\n### With pre-computed embeddings\n\n```typescript\nconst candidates = [\n  {\n    id: 'skill-1',\n    text: 'Test-driven development',\n    embedding: [0.1, 0.2, ...], // 384-dim vector\n    keywords: ['tdd']\n  }\n];\n\nconst result = await matcher.match(query, candidates);\n```\n\n### Custom thresholds\n\n```typescript\nconst matcher = await createMatcher({\n  immediateThreshold: 0.90,   // Score >= 0.90 → immediate mode\n  suggestionThreshold: 0.75,  // Score >= 0.75 → suggestion mode\n  maxMatches: 5,              // Return top 5 matches\n});\n```\n\n### Direct embedding generation\n\n```typescript\nconst embedding = await matcher.embed('some text');\n// Returns 384-dimensional normalized vector\n```\n\n## API\n\n### createMatcher(options?)\n\nCreates a matcher instance.\n\n**Options:**\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `embeddingModel` | string | `'Xenova/all-MiniLM-L6-v2'` | Model for embeddings |\n| `keywordWeight` | number | `0.3` | Weight for keyword score (0-1) |\n| `embeddingWeight` | number | `0.7` | Weight for embedding score (0-1) |\n| `immediateThreshold` | number | `0.85` | Score threshold for immediate mode |\n| `suggestionThreshold` | number | `0.70` | Score threshold for suggestion mode |\n| `cacheEmbeddings` | boolean | `true` | Cache computed embeddings |\n| `maxMatches` | number | `10` | Maximum matches to return |\n\n### Matcher.match(query, candidates)\n\nMatch a query against candidates.\n\n**Returns:** `MatchResult`\n```typescript\ninterface MatchResult {\n  query: string;\n  matches: Match[];\n  signals: MatchSignal[];\n  processingTimeMs: number;\n}\n\ninterface Match {\n  candidate: Candidate;\n  score: number;           // Combined score (0-1)\n  keywordScore: number;    // Keyword match score\n  embeddingScore: number;  // Embedding similarity\n  matchedKeywords: string[];\n  mode: 'immediate' | 'suggestion' | 'none';\n  confidence: 'high' | 'medium' | 'low';\n}\n```\n\n### Candidate interface\n\n```typescript\ninterface Candidate<T = unknown> {\n  id: string;              // Unique identifier\n  text: string;            // Text for embedding\n  keywords?: string[];     // Keywords for fast matching\n  embedding?: number[];    // Pre-computed embedding\n  metadata?: T;            // Optional metadata\n}\n```\n\n## Vector Operations\n\nUtility functions for working with embeddings:\n\n```typescript\nimport {\n  cosineSimilarity,\n  dotProduct,\n  normalize,\n  magnitude,\n  euclideanDistance,\n  manhattanDistance\n} from '@4meta5/semantic-matcher';\n\nconst similarity = cosineSimilarity(embedding1, embedding2);\n```\n\n## Keyword Matching\n\nStandalone keyword matching utilities:\n\n```typescript\nimport {\n  buildKeywordPatterns,\n  matchKeywords,\n  extractQueryTerms,\n  keywordOverlapScore\n} from '@4meta5/semantic-matcher';\n\nconst patterns = buildKeywordPatterns([\n  { id: 'skill-1', keywords: ['test', 'tdd'] }\n]);\n\nconst matches = matchKeywords('run the tests', patterns);\n```\n\n## How It Works\n\n1. **Keyword Matching**: Fast regex-based matching against candidate keywords\n2. **Embedding Similarity**: Cosine similarity between query and candidate embeddings\n3. **RRF Fusion**: Combines scores with configurable weights (default: 30% keyword, 70% embedding)\n4. **Threshold-Based Activation**: Determines mode based on combined score\n\n## Fallback Mode\n\nIf `@xenova/transformers` is not installed, the matcher uses a simple hash-based fallback for embeddings. This is suitable for testing but not recommended for production.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}