{"_id":"@amsterdamdatalabs/enact-docs-search","_rev":"6-d0e11683e6da4f79a4fdf7e5307c3efe","name":"@amsterdamdatalabs/enact-docs-search","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.0":{"name":"@amsterdamdatalabs/enact-docs-search","version":"0.1.0","license":"UNLICENSED","_id":"@amsterdamdatalabs/enact-docs-search@0.1.0","maintainers":[{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"}],"bin":{"enact-docs-search":"dist/cli.js"},"dist":{"shasum":"481d3c432c252482dd493381859ac7128d77d431","tarball":"https://registry.npmjs.org/@amsterdamdatalabs/enact-docs-search/-/enact-docs-search-0.1.0.tgz","fileCount":47,"integrity":"sha512-kYizXRuTt+wY8TBvDD6JzBbVUToxjYcWOCvZ8j3tY++u9YBLOFDmvSmr609sc1ZijoOE7kGArT37C6NV1Si/zA==","signatures":[{"sig":"MEQCIA75BO00ziza4EAqxAkN4FxAcUCF9ZyOPdTk2yRuF3rCAiAS8C78ZpUJ0w0LKj+AiUQSsIHUnAYMbee/8mCcSNFvTQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":167149},"type":"module","engines":{"node":">=22"},"gitHead":"c4ac5673c23d9098cc35792fdf026bf843f3f96f","scripts":{"build":"rm -rf dist && tsc -p tsconfig.json","start":"node dist/cli.js","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"},"repository":{"url":"https://dev.azure.com/amsterdamdatalabs/Enact/_git/enact-docs-search","type":"git"},"_npmVersion":"10.9.8","description":"Hybrid (BM25 + vector) semantic search CLI over a repo's docs/.plans/.specs knowledge trees.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"minisearch":"^7.2.0","hnswlib-node":"^3.0.0","@xenova/transformers":"^2.17.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/enact-docs-search_0.1.0_1785958944883_0.48060207533023713","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@amsterdamdatalabs/enact-docs-search","version":"0.1.1","license":"UNLICENSED","_id":"@amsterdamdatalabs/enact-docs-search@0.1.1","maintainers":[{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"}],"bin":{"enact-docs-search":"dist/cli.js"},"dist":{"shasum":"d71f7dac05498372165cefa5037ff7d61e704951","tarball":"https://registry.npmjs.org/@amsterdamdatalabs/enact-docs-search/-/enact-docs-search-0.1.1.tgz","fileCount":47,"integrity":"sha512-TNJFN+RDakGv32YFwZYbPMLY5TjhhFhUvrgYVqDyWnIfvBnPekO9PBAjlYJnOoqIa3QBO/a0a7XvxlsEzXoVqw==","signatures":[{"sig":"MEQCICHibjdJd38PSwcuf7wVRlEF+agzgOzjW5juDPAq3hYpAiAziIJshc2xQ+SD1g1pV2FuQTMVCcYM21f2Kq32Myqf+Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":188386},"type":"module","engines":{"node":">=22"},"gitHead":"6610e67901922dfc4421a3f8e9287c44b03e9615","scripts":{"test":"npm run build && node --test","build":"rm -rf dist && tsc -p tsconfig.json","start":"node dist/cli.js","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"},"repository":{"url":"https://dev.azure.com/amsterdamdatalabs/Enact/_git/enact-docs-search","type":"git"},"_npmVersion":"10.9.8","description":"Hybrid (BM25 + vector) semantic search CLI over a repo's docs/.plans/.specs knowledge trees.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"minisearch":"^7.2.0","hnswlib-node":"^3.0.0","@huggingface/transformers":"3.4.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/enact-docs-search_0.1.1_1786641430159_0.5810019472698125","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@amsterdamdatalabs/enact-docs-search","version":"0.1.2","license":"UNLICENSED","_id":"@amsterdamdatalabs/enact-docs-search@0.1.2","maintainers":[{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"}],"bin":{"enact-docs-search":"dist/cli.js"},"dist":{"shasum":"7a1e26dce03ab3c72f07f6ce05c97164dc5ca589","tarball":"https://registry.npmjs.org/@amsterdamdatalabs/enact-docs-search/-/enact-docs-search-0.1.2.tgz","fileCount":55,"integrity":"sha512-iaYtiZXIlucGEoZLKM+mZj3dDyOxTXtHiyq8qUKmvB+Pfcfj2MehEIcfXqIrhWTtihQLivgVPiFAQIObEHfHnA==","signatures":[{"sig":"MEUCIBNIFZTbJ8W9Oe77wEVgc7i+o2pQSJqJ1AaqXBDTjjk+AiEAgiA8uQJm+3OKBFrZCWrsGSnknsyq4lfy03SEomt4ufE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":203159},"type":"module","engines":{"node":">=22"},"gitHead":"849b3619f3a114334de1026a6bee3a0140abbe97","scripts":{"test":"npm run build && node --test","build":"rm -rf dist && tsc -p tsconfig.json","start":"node dist/cli.js","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"},"repository":{"url":"https://dev.azure.com/amsterdamdatalabs/Enact/_git/enact-docs-search","type":"git"},"_npmVersion":"10.9.8","description":"Hybrid (BM25 + vector) semantic search CLI over a repo's docs/.plans/.specs knowledge trees.","directories":{},"_nodeVersion":"22.22.3","allowScripts":{"hnswlib-node":true,"sharp@0.33.5":true,"protobufjs@7.6.5":true,"hnswlib-node@3.0.0":true,"onnxruntime-node@1.20.1":true},"dependencies":{"minisearch":"^7.2.0","hnswlib-node":"^3.0.0","@huggingface/transformers":"3.4.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/enact-docs-search_0.1.2_1786712181039_0.7268625107195812","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@amsterdamdatalabs/enact-docs-search","version":"0.2.0","license":"UNLICENSED","_id":"@amsterdamdatalabs/enact-docs-search@0.2.0","maintainers":[{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"}],"bin":{"enact-docs-search":"dist/cli.js"},"dist":{"shasum":"208deb29e9d66c71aa8dd12a9dc6b114d7de60d4","tarball":"https://registry.npmjs.org/@amsterdamdatalabs/enact-docs-search/-/enact-docs-search-0.2.0.tgz","fileCount":71,"integrity":"sha512-JkJ5gEI9nwc5YwRE1GHNMV0s4/8JmsAdLj+4jIEU4Ek9bwWVOFnclHQOouTmFcX2hW+Te5KQ63PMmH/qYaHtBQ==","signatures":[{"sig":"MEYCIQDJMbzygjUuC3WbdROMkrbFpNUgLZsZkk8XAEgxpfWvNgIhAMDazFH5BBIzbACBBen1TGGiSUWD/kPcqlvul8H1O9Ka","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":273523},"type":"module","engines":{"node":">=22"},"gitHead":"2ebbf5f4b9b078eb1b975444ba513d5600e9d80f","scripts":{"test":"npm run build && node --test","build":"rm -rf dist && tsc -p tsconfig.json","start":"node dist/cli.js","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"},"repository":{"url":"https://dev.azure.com/amsterdamdatalabs/Enact/_git/enact-docs-search","type":"git"},"_npmVersion":"10.9.8","description":"Hybrid (BM25 + vector) semantic search CLI over a repo's docs/ knowledge tree.","directories":{},"_nodeVersion":"22.22.3","allowScripts":{"hnswlib-node":true,"sharp@0.33.5":true,"protobufjs@7.6.5":true,"hnswlib-node@3.0.0":true,"onnxruntime-node@1.20.1":true},"dependencies":{"minisearch":"^7.2.0","hnswlib-node":"^3.0.0","@huggingface/transformers":"3.4.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/enact-docs-search_0.2.0_1789519297015_0.618552819171704","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@amsterdamdatalabs/enact-docs-search","version":"0.2.1","license":"UNLICENSED","_id":"@amsterdamdatalabs/enact-docs-search@0.2.1","maintainers":[{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"}],"bin":{"enact-docs-search":"dist/cli.js"},"dist":{"shasum":"8767127d0ddd76c5e784f85ef8e762dbfd0d5b1d","tarball":"https://registry.npmjs.org/@amsterdamdatalabs/enact-docs-search/-/enact-docs-search-0.2.1.tgz","fileCount":71,"integrity":"sha512-JjnNJKVPf1wxxG24BWTGKWozBWf4PYfHgqh+KS+I9dOxepmQhIyitLcAV/7KA0bADiwbPSN7TR7uUUSHpI09eQ==","signatures":[{"sig":"MEUCIQCCjPCSmBYd0UnmV/2J7IZF08OMFIi0a01FqnDrbqH4OgIgYALndHXYcwTafHxRwEj0CDY3dqz+zXkWiuCxAVmZYrU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":273913},"type":"module","engines":{"node":">=22"},"gitHead":"0c7bf0384f055fcd0e4b369d4ac0f8eb48fa0199","scripts":{"test":"npm run build && node --test","build":"rm -rf dist && tsc -p tsconfig.json","start":"node dist/cli.js","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"},"repository":{"url":"https://dev.azure.com/amsterdamdatalabs/Enact/_git/enact-docs-search","type":"git"},"_npmVersion":"10.9.8","description":"Hybrid (BM25 + vector) semantic search CLI over a repo's docs/ knowledge tree.","directories":{},"_nodeVersion":"22.22.3","allowScripts":{"hnswlib-node":true,"sharp@0.33.5":true,"protobufjs@7.6.5":true,"hnswlib-node@3.0.0":true,"onnxruntime-node@1.20.1":true},"dependencies":{"minisearch":"^7.2.0","hnswlib-node":"^3.0.0","@huggingface/transformers":"3.4.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/enact-docs-search_0.2.1_1789545062773_0.5514308650250677","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"_id":"@amsterdamdatalabs/enact-docs-search@0.2.2","bin":{"enact-docs-search":"dist/cli.js"},"dist":{"shasum":"7e152c1942c314c4ff757914a50caccc03a28f70","tarball":"https://registry.npmjs.org/@amsterdamdatalabs/enact-docs-search/-/enact-docs-search-0.2.2.tgz","fileCount":71,"integrity":"sha512-ypWI8iYm7A4MBs8KSiNIdLlcnPFd585/jChbWxj+1EIpB92423HQ4tvv4yhVa0IxNOLRayJcSqzZDuk/QQ65cA==","signatures":[{"sig":"MEQCIGw/6Qw90a5hd+H8uuAUgN5rL9yYBVersa7IPkTlOkcCAiBQuyfsla6zs8u8Fzte3rEYy0s39TKQe5Vtov05lj6HkQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIB0RXMlf4QPGOk5yXOPt4MkVDigAz7TGicsX0XbyvG0QAiBD2hqt1E34VYoCpMrajaUwDnsXtj/1gjTXxM+Ku1trnQ=="}],"unpackedSize":276495},"name":"@amsterdamdatalabs/enact-docs-search","type":"module","engines":{"node":">=22"},"gitHead":"e567c8e68d2ac951584e8463093ff65c1935d9b1","license":"UNLICENSED","scripts":{"test":"npm run build && node --test","build":"rm -rf dist && tsc -p tsconfig.json","start":"node dist/cli.js","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"version":"0.2.2","_npmUser":{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"},"repository":{"url":"https://dev.azure.com/amsterdamdatalabs/Enact/_git/enact-docs-search","type":"git"},"_npmVersion":"10.9.8","description":"Hybrid (BM25 + vector) semantic search CLI over a repository's Git-visible Markdown files.","directories":{},"maintainers":[{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"}],"_nodeVersion":"22.22.3","allowScripts":{"hnswlib-node":true,"sharp@0.33.5":true,"protobufjs@7.6.5":true,"hnswlib-node@3.0.0":true,"onnxruntime-node@1.20.1":true},"dependencies":{"minisearch":"^7.2.0","hnswlib-node":"^3.0.0","@huggingface/transformers":"3.4.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^22.10.2"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/enact-docs-search_0.2.2_1790359832349_0.8016147711233177"}}},"time":{"created":"2026-08-05T19:42:24.664Z","modified":"2026-09-25T18:10:32.600Z","0.1.0":"2026-08-05T19:42:25.051Z","0.1.1":"2026-08-13T17:17:10.283Z","0.1.2":"2026-08-14T12:56:21.181Z","0.2.0":"2026-09-16T00:41:37.144Z","0.2.1":"2026-09-16T07:51:02.937Z","0.2.2":"2026-09-25T18:10:32.436Z"},"license":"UNLICENSED","repository":{"url":"https://dev.azure.com/amsterdamdatalabs/Enact/_git/enact-docs-search","type":"git"},"description":"Hybrid (BM25 + vector) semantic search CLI over a repository's Git-visible Markdown files.","maintainers":[{"name":"tarun.rana","email":"tarun.rana@amsterdamdatalabs.com"}],"readme":"# @amsterdamdatalabs/enact-docs-search\n\nHybrid BM25 and vector search over a repository's Git-visible Markdown files.\n\nArchitecture and operating guidance live in [`docs/`](docs/architecture/index.md).\nBoard-first Feature and backlog-item conventions live in\n[`plans/`](plans/AGENTS.md).\n\n## Install\n\n```bash\nnpm install -g @amsterdamdatalabs/enact-docs-search\n```\n\nVerify the installed version:\n\n```bash\nenact-docs-search --version\n```\n\nNode.js 22 or newer and Git are required. The first semantic query downloads the local\n`Xenova/all-MiniLM-L6-v2` embedding model into the target repository's\n`.cache/docs/models/` directory. The search index is stored alongside it under\n`.cache/docs/index/`.\n\nSemantic search uses `hnswlib-node`, a native Node addon compiled with\n`node-gyp` during installation. The machine installing the CLI therefore needs\nPython 3 and a C/C++ build toolchain: Xcode Command Line Tools on macOS,\n`make`/GCC on Linux, or Python plus Visual Studio Build Tools with the Desktop\ndevelopment with C++ workload on Windows. For a global install with npm's\nlifecycle-script policy enabled, use:\n\n```bash\nnpm install -g @amsterdamdatalabs/enact-docs-search \\\n  --allow-scripts=hnswlib-node,onnxruntime-node,sharp,protobufjs \\\n  --foreground-scripts\n```\n\nCheck the native installation without downloading the embedding model:\n\n```bash\nenact-docs-search doctor\nenact-docs-search doctor --json\n```\n\nFor a project-scoped install, put the lifecycle approvals in the consuming\nproject's root `package.json` (npm does not accept `--allow-scripts` on a\nproject-scoped install), then rebuild the native packages:\n\n```json\n{\n  \"allowScripts\": {\n    \"hnswlib-node\": true,\n    \"onnxruntime-node\": true,\n    \"sharp\": true,\n    \"protobufjs\": true\n  }\n}\n```\n\n```bash\nnpm rebuild hnswlib-node onnxruntime-node sharp protobufjs --foreground-scripts\n```\n\n## Usage\n\nRun inside a target repository:\n\n```bash\nenact-docs-search how crate boundaries are defined\nenact-docs-search query how crate boundaries are defined\nenact-docs-search index\nenact-docs-search index --force\nenact-docs-search prepare\n```\n\nThe `query` command is optional. Unquoted words are joined into one query;\nquotes remain useful when the shell must preserve punctuation or special\ncharacters.\n\nQueries automatically provision a missing model and refresh missing or stale\nindexes incrementally. If keyword-only indexing leaves semantic vectors stale,\nthe next hybrid or semantic query repairs them automatically before searching.\n`prepare` performs the model bootstrap and a complete semantic index build\nexplicitly. Use `enact-docs-search --help` for mode, JSON, and\nexclusion controls.\n\nThe corpus contains tracked and untracked, non-ignored `.md` files anywhere in\nthe Git worktree. Extension matching is case-insensitive. `.mdx` files,\nsymlinks, submodule contents, and files beneath dot-directories are excluded.\n`--exclude` adds repo-relative glob exclusions; it cannot re-include anything\nexcluded by Git or the built-in corpus rules. An explicit `--repo` path may\npoint anywhere inside the worktree, and omission uses the worktree containing\nthe current directory.\n\n## Ranking\n\nFrontmatter is parsed, not indexed as prose. `title` and `description` are\nweighted above heading text, which is weighted above body text, so a document\nwhose title answers the query outranks one that mentions it in passing. Results\ncollapse to one entry per file.\n\nEach result is labelled with what the document says about itself --\n`[stable · operations · 2026-09-15]`. A document marked `status: draft` is\ndemoted; one that makes no status claim is left alone. Age decays a result's\nscore with a 180-day half-life, floored so an old document is demoted, never\nburied. `--raw-rank` turns this weighting off, and `--explain` prints the score\nand the multiplier behind every result.\n\nResults that do not clear a relevance floor are dropped rather than padded out:\nsemantic hits need a minimum cosine similarity, and keyword hits must cover\nenough of the query's weight, measured by term rarity so the term that carried\nthe query is the one that counts. A query nothing matches exits `1` with no\nresults, which is a real answer -- not an empty list dressed up as ten weak\nones. `--min-score` and `--min-coverage` adjust both floors.\n\nThe package is also usable through `npx` or `bunx`:\n\n```bash\nnpx @amsterdamdatalabs/enact-docs-search query \"conversation vs tasks\"\nbunx @amsterdamdatalabs/enact-docs-search query \"conversation vs tasks\"\n```\n","readmeFilename":"README.md"}