{"_id":"@deneuv34/sensei","_rev":"12-195b3348bd39a95adcf8dab94e1bd1a2","name":"@deneuv34/sensei","dist-tags":{"latest":"1.0.0"},"versions":{"0.2.0":{"name":"@deneuv34/sensei","version":"0.2.0","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.2.0","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"b9988a1abb7a88340c0fb6a6d360b152b505eac4","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.2.0.tgz","fileCount":68,"integrity":"sha512-KfgDXSxufGpbirHu5Dhp1rnLav343ULRpB7+CQndL2k1k2T95wSHPRCrteVmgwEcgR3NMvHTf42sYt2wYH6tDw==","signatures":[{"sig":"MEYCIQCcHP/9z0QxY0lD06KoaQpvo4p9v1xkTPb4aDujwTgSbwIhANvwCai8W4d6EUZzOBnreFjFs/oIwx4U3xLaHYBkP5T8","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110858},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"011ac62aaeec39b2a5f61abd74f58d621b7337ed","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"deneuv34","email":"deneuv3.4@gmail.com"},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.16.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"26.3.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","ts-morph":"^24.0.0","fast-glob":"^3.3.0","simple-git":"^3.25.0","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.0.0","typescript":"^5.5.0","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.2.0_1781574197173_0.11627702799696316","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@deneuv34/sensei","version":"0.2.1","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.2.1","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"93b3b7a3c557cda6c7bdc681323d8301a7a4ef72","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.2.1.tgz","fileCount":68,"integrity":"sha512-Cm3FNTnVUjOe/zn5mnkP6eX5IJGPYeKsZ9Z/yz3KDgI1QEGhYjZdu4PXZ0pB6Jr0CnbgM6KqnzuW3FnfePJCAA==","signatures":[{"sig":"MEYCIQCpwYFg/hdqOwNhXJdYoK3GXCzfsl7/6tnml8BYSzSEmgIhAMsDtSASb11YrorgZv8hlFGuU/E1HhZ0pjNRtfy/9npD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110858},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"011ac62aaeec39b2a5f61abd74f58d621b7337ed","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"deneuv34","email":"deneuv3.4@gmail.com"},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.16.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"26.3.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","ts-morph":"^24.0.0","fast-glob":"^3.3.0","simple-git":"^3.25.0","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.0.0","typescript":"^5.5.0","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.2.1_1781574426257_0.21373910557669795","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@deneuv34/sensei","version":"0.2.2","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.2.2","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"f8424209026963ad41d04b9c8b3836e0a30303fc","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.2.2.tgz","fileCount":68,"integrity":"sha512-KxWmt6zbGJ5YVdb2dU/K8wcQHsIVpHKBoJFK1fylxdQFGieLnMsR6nLUjPMHzZScFZii9odF85+ODSKPcasdaQ==","signatures":[{"sig":"MEUCIFH1PsexJ/KQXcary0mrcH5/09qjc5UkV9TFiEb4+k0QAiEA8eVb+/1rB954F7uVUaF7/Eqx1zPrr94bXjGmGQFWLEk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110920},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"8e44782505e76bdbc7dc673f39d44b59e526e3b0","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"deneuv34","email":"deneuv3.4@gmail.com"},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.16.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"26.3.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","ts-morph":"^24.0.0","fast-glob":"^3.3.0","simple-git":"^3.25.0","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.0.0","typescript":"^5.5.0","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.2.2_1781574716118_0.5218371914179425","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@deneuv34/sensei","version":"0.3.0","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.3.0","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"ba8401b45ed76f2d1b5a05c5c17c9bf0d08a4d6b","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.3.0.tgz","fileCount":72,"integrity":"sha512-B3ySPahQyAoqaDvnlRaZncWaEDm6uLstJhlpUNiwEsYinX7lqze0Y4wNpBekkzY/vqKwLWQfL83FIyO1rPPx3w==","signatures":[{"sig":"MEQCIE4MZ5b1t4zCQikbyMVCn+rAaJVI1QC6PrlljoAL3RnwAiBBY0QyMIhM0s5uH67Mgmgz4fMNPpHkcN8pYYZ3IWs4RA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":125433},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"694756c041284c2a99c9fe8f955d96bcdb6c9279","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"deneuv34","email":"deneuv3.4@gmail.com"},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.16.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"26.3.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","listr2":"^10.2.1","fast-glob":"^3.3.0","simple-git":"^3.25.0","typescript":"^6.0.3","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.3.0_1781578416242_0.91885279878877","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@deneuv34/sensei","version":"0.4.0","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.4.0","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"087f88cb14edc126423b69c6e71287863bd86a13","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.4.0.tgz","fileCount":84,"integrity":"sha512-IVBm89bZOJkRMc5vYjOjgSVmV1klLyz9o6IRLEmq2z0G67bscWrULjLiRleP5pWKabxKEjUjZXUr9m54WOGTSg==","signatures":[{"sig":"MEUCIG5D/N9EBUoIyTHJN8GgMDHSVx2G30zloH3phtk5sbpSAiEA9bTPaIARsjjAWMmBJ9BL+d0pXSKbWavZAwjwa2n5NV0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@deneuv34%2fsensei@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":158412},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"b8010708e1845ec41fff207db4df400688d8a18c","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:213f50bd-c3f6-4097-87ee-64448682555f"}},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.13.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","listr2":"^10.2.1","fast-glob":"^3.3.0","simple-git":"^3.25.0","typescript":"^6.0.3","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.4.0_1781583510421_0.1624926662464381","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@deneuv34/sensei","version":"0.5.0","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.5.0","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"1333f09492f2b2c49f4500c696c345448d2b1c36","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.5.0.tgz","fileCount":84,"integrity":"sha512-OK2/VJ3B5ceheYj53TKpEAHc7FDDILuAeBR933vTe6ZabDAgqlYFW/pUZ/xoCkTNldT9l5Jns9cajSJBD55EVg==","signatures":[{"sig":"MEUCIBy6pAlrInY+UHmphLjlyahvjxhafRJbfrgcdWxu8LEWAiEAt1thR3TKPbme2EMXVVAF1kTg+xUVRDsi8fTu2FZ112E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@deneuv34%2fsensei@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":158627},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","plugins":["@oclif/plugin-autocomplete"],"commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"a7b105092f0cdb3eb3be809fd3fd5eecfa19cd55","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:213f50bd-c3f6-4097-87ee-64448682555f"}},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.13.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","listr2":"^10.2.1","fast-glob":"^3.3.0","simple-git":"^3.25.0","typescript":"^6.0.3","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1","@oclif/plugin-autocomplete":"^3.2.50"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.5.0_1781586241875_0.1416782350006025","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@deneuv34/sensei","version":"0.6.0","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.6.0","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"79aa8825d7849d8bdcd420ddf1f700020a9bd84c","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.6.0.tgz","fileCount":84,"integrity":"sha512-AjzmmzPBWMGbVvHBTOLjbKIYaPGc1w0B8e+7Q7xpZAMMtBVDk3GZprgi66ft9S/KpMposmWN1kFag+kLsv6NAQ==","signatures":[{"sig":"MEUCIQDkdQpW1mXHXQUQebKp7R68bnTiV9BHfMTcxoBwkXGTMQIgDZelBmogCXKkgDiRPOBI6tww7eYu6Q+lr0WB0rrwAmQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@deneuv34%2fsensei@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":160115},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","plugins":["@oclif/plugin-autocomplete"],"commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"7530c75250d23d697cb2f69eec2a2e3d0447ef02","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:213f50bd-c3f6-4097-87ee-64448682555f"}},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.13.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","listr2":"^10.2.1","fast-glob":"^3.3.0","simple-git":"^3.25.0","typescript":"^6.0.3","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1","@oclif/plugin-autocomplete":"^3.2.50"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.6.0_1781601199316_0.883983506289902","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@deneuv34/sensei","version":"0.7.0","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.7.0","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"5f24e8ac24983c271a515fc3f288654835ed6093","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.7.0.tgz","fileCount":110,"integrity":"sha512-MhqBeuiTh2n3rRi559UgRY3BYbN6NHC4YJh2SQ4/nasHTnn90V2ccE9ytOnqWqk238ALkUHNx5eqKczFlMC6LA==","signatures":[{"sig":"MEYCIQDBzLl9catByq7QyLshfhlt1E5Nin7Gn93bjMPmS1i3HwIhALuFEH5WNftCEeEfcTwvmXxwdn6lFB0kOTJQIxV3kUX1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@deneuv34%2fsensei@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2154743},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","plugins":["@oclif/plugin-autocomplete"],"commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"f8f1a6f9c7bc24704302efd09947502a1c7af60d","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build","vendor:grammars":"node scripts/vendor-grammars.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:213f50bd-c3f6-4097-87ee-64448682555f"}},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.13.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","listr2":"^10.2.1","fast-glob":"^3.3.0","simple-git":"^3.25.0","typescript":"^6.0.3","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1","web-tree-sitter":"^0.25.10","@oclif/plugin-autocomplete":"^3.2.50"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","@types/node":"^22.0.0","tree-sitter-wasms":"^0.1.13","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.7.0_1781798398139_0.330244627519787","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@deneuv34/sensei","version":"0.8.0","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.8.0","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"7b00d1fe9d54871fc376c872413996a49ce93098","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.8.0.tgz","fileCount":116,"integrity":"sha512-9BjH5Tdf5vDFuo+XbzVCYT/Eiqa+3upMbimWmZ/uTeyo0v/TJFT9M/lnN6QB0vWHDZ3i/Dv5JtlEnUDKh2hRtg==","signatures":[{"sig":"MEYCIQDpMBKl8Af3+CT2E9ohsOODHfk5FgJNNUHbCS0LLW6ZLwIhAJENv+4bM2DQW099XlHC6cwzeBu/Koo8zrR9RqGqQa5b","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@deneuv34%2fsensei@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2163005},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","plugins":["@oclif/plugin-autocomplete"],"commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"21c8e52f62a1554d8e38a3ca572299a303f8111e","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build","vendor:grammars":"node scripts/vendor-grammars.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:213f50bd-c3f6-4097-87ee-64448682555f"}},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.13.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","listr2":"^10.2.1","fast-glob":"^3.3.0","simple-git":"^3.25.0","typescript":"^6.0.3","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1","web-tree-sitter":"^0.25.10","@oclif/plugin-autocomplete":"^3.2.50"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","@types/node":"^22.0.0","tree-sitter-wasms":"^0.1.13","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.8.0_1781925091872_0.08230364268873025","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@deneuv34/sensei","version":"0.9.0","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.9.0","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"e716f640f443e0d67f838cd5dad2120a2cf038f2","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.9.0.tgz","fileCount":120,"integrity":"sha512-Wr8W40U2MweSFOhmFhaV81+EDMZZYpiL8u9FrvUmaD9cRzlXXNQL20nGMM36tEhoiqxB1fKEwCJ8o9c6pAKGgA==","signatures":[{"sig":"MEQCIGJMmnxxE3K9JU4SMIlepyugITaVwrO48M+xvBjZLWNZAiAxCtPP8RX0SgbC9eWKgLrurICWDhA9WBr6Zst6MTqA2w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@deneuv34%2fsensei@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2169708},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","plugins":["@oclif/plugin-autocomplete"],"commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"9ad421fee143aae13ac0a82c51f5c285fc023ba7","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build","vendor:grammars":"node scripts/vendor-grammars.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:213f50bd-c3f6-4097-87ee-64448682555f"}},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.13.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","listr2":"^10.2.1","fast-glob":"^3.3.0","simple-git":"^3.25.0","typescript":"^6.0.3","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1","web-tree-sitter":"^0.25.10","@modelcontextprotocol/sdk":"^1.29.0","@oclif/plugin-autocomplete":"^3.2.50"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","@types/node":"^22.19.21","tree-sitter-wasms":"^0.1.13","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.9.0_1781940670962_0.9736148222126857","host":"s3://npm-registry-packages-npm-production"}},"0.11.0":{"name":"@deneuv34/sensei","version":"0.11.0","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"author":{"name":"Rangga Adhitya"},"license":"MIT","_id":"@deneuv34/sensei@0.11.0","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"homepage":"https://github.com/deneuv34/sensei#readme","bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"bin":{"sensei":"bin/run.js"},"dist":{"shasum":"4da5b019847ec30beba51808b1605aaa94b57210","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-0.11.0.tgz","fileCount":138,"integrity":"sha512-fR7dlL4PeT1kenCqki5FGCMaLyWjZi8etD2/sJFfRTCOTA4X92dLl8TLQIQXGeISd+zIoIwHtnacLc8ZQC4idA==","signatures":[{"sig":"MEUCIB2PvjK7HwkOZsKyeInZdOIF+l37I9UaBYb9ftq48izQAiEAoP9kkit/RxzzptIu9mz/Gg9kgqii8ogBHzkBNVlnyoQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@deneuv34%2fsensei@0.11.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2211431},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"type":"module","oclif":{"bin":"sensei","dirname":"sensei","plugins":["@oclif/plugin-autocomplete"],"commands":"./dist/commands","topicSeparator":" "},"engines":{"node":">=22"},"gitHead":"4589cd1a9f1c9b535fb7393c6d54c7a873b916f5","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build","vendor:grammars":"node scripts/vendor-grammars.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:213f50bd-c3f6-4097-87ee-64448682555f"}},"repository":{"url":"git+https://github.com/deneuv34/sensei.git","type":"git"},"_npmVersion":"11.13.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","directories":{},"_nodeVersion":"24.17.0","dependencies":{"zod":"^3.23.0","ignore":"^6.0.0","listr2":"^10.2.1","fast-glob":"^3.3.0","simple-git":"^3.25.0","typescript":"^6.0.3","@oclif/core":"^4.0.0","better-sqlite3":"^12.10.1","web-tree-sitter":"^0.25.10","@xenova/transformers":"^2.17.2","@modelcontextprotocol/sdk":"^1.29.0","@oclif/plugin-autocomplete":"^3.2.50"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","@types/node":"^22.19.21","tree-sitter-wasms":"^0.1.13","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sensei_0.11.0_1782497172060_0.9698475530019626","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@deneuv34/sensei","version":"1.0.0","description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","type":"module","license":"MIT","author":{"name":"Rangga Adhitya"},"homepage":"https://github.com/deneuv34/sensei#readme","repository":{"type":"git","url":"git+https://github.com/deneuv34/sensei.git"},"bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"publishConfig":{"access":"public"},"bin":{"sensei":"bin/run.js"},"engines":{"node":">=22"},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test":"vitest run","test:watch":"vitest","vendor:grammars":"node scripts/vendor-grammars.mjs","prepublishOnly":"npm run build"},"dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","@oclif/core":"^4.0.0","@oclif/plugin-autocomplete":"^3.2.50","@xenova/transformers":"^2.17.2","better-sqlite3":"^12.10.1","fast-glob":"^3.3.0","ignore":"^6.0.0","listr2":"^10.2.1","simple-git":"^3.25.0","typescript":"^6.0.3","web-tree-sitter":"^0.25.10","zod":"^3.23.0"},"devDependencies":{"@types/better-sqlite3":"^7.6.0","@types/node":"^22.19.21","tree-sitter-wasms":"^0.1.13","vitest":"^4.1.9"},"oclif":{"bin":"sensei","dirname":"sensei","commands":"./dist/commands","topicSeparator":" ","plugins":["@oclif/plugin-autocomplete"]},"pnpm":{"onlyBuiltDependencies":["better-sqlite3","esbuild"]},"gitHead":"bc2fe3667f553c38355aa942d389d4ed7c52538b","_id":"@deneuv34/sensei@1.0.0","_nodeVersion":"24.17.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-xKEJqL0M2YQCrc8ckYUNXY5C2UNHUbDXLHaQAiCjYtOX3VgZohSUmegq2ghrIx8v9dbI8u84YqYqAS6iM4e9ow==","shasum":"77c8ec66ea7cad79da871351bd91dcae60b7c40c","tarball":"https://registry.npmjs.org/@deneuv34/sensei/-/sensei-1.0.0.tgz","fileCount":138,"unpackedSize":2211557,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@deneuv34%2fsensei@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD5gc68x/3VraSfBbAUPBqOhWfWqkg+7PrlkUVYa01y5gIgGrQzvwl+o8tvJ4Chd8urqEzD2h7dQiXYfWwj2jEUqGM="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:213f50bd-c3f6-4097-87ee-64448682555f"}},"directories":{},"maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sensei_1.0.0_1782748558951_0.14610951905537628"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-16T01:43:17.042Z","modified":"2026-06-29T15:55:59.478Z","0.2.0":"2026-06-16T01:43:17.318Z","0.2.1":"2026-06-16T01:47:06.403Z","0.2.2":"2026-06-16T01:51:56.272Z","0.3.0":"2026-06-16T02:53:36.378Z","0.4.0":"2026-06-16T04:18:30.564Z","0.5.0":"2026-06-16T05:04:02.050Z","0.6.0":"2026-06-16T09:13:19.470Z","0.7.0":"2026-06-18T15:59:58.343Z","0.8.0":"2026-06-20T03:11:32.025Z","0.9.0":"2026-06-20T07:31:11.124Z","0.11.0":"2026-06-26T18:06:12.261Z","1.0.0":"2026-06-29T15:55:59.173Z"},"bugs":{"url":"https://github.com/deneuv34/sensei/issues"},"author":{"name":"Rangga Adhitya"},"license":"MIT","homepage":"https://github.com/deneuv34/sensei#readme","keywords":["ai","ai-agent","code-context","code-reuse","duplicate-detection","static-analysis","typescript","javascript","cli","llm","codegen","developer-tools"],"repository":{"type":"git","url":"git+https://github.com/deneuv34/sensei.git"},"description":"Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.","maintainers":[{"name":"deneuv34","email":"deneuv3.4@gmail.com"}],"readme":"# Sensei\n\n> Before your AI agent writes code, Sensei tells it what already exists, what to reuse, and what not to touch.\n\nSensei is a **local-first, deterministic** CLI for TypeScript/JavaScript, Python, Go, Rust, and Java repos. No API key, no network, no LLM in the loop. It scans your code into a local SQLite symbol index, then answers two questions an AI coding agent almost never gets right on its own:\n\n1. **What already exists here that I should reuse?**\n2. **Which files are load-bearing and dangerous to touch?**\n\n---\n\n## Why Sensei?\n\nAI coding agents are powerful and context-blind. Dropped into a real repo, they reliably make the same expensive mistakes:\n\n- **They reimplement what's already there.** The agent writes a new `formatCurrency`, `getUser`, or `validateEmail` because it never saw the one you already shipped three folders away. Now you maintain two.\n- **They edit the wrong files.** The agent casually rewrites your DI entrypoint, a 15-importer types module, or the auth barrel — the exact files where a small mistake breaks everything.\n- **They have no memory of your codebase.** Every session starts cold. The agent's \"context\" is whatever happened to fit in the prompt, not what's actually in the repo.\n\nThe usual fix — stuffing the whole codebase into the model's context — is slow, expensive, non-deterministic, and still misses things. Sensei takes the opposite approach: **a cheap, deterministic index that hands the agent a short, ranked, factual brief before it writes a line.**\n\nSame repo + same task = same answer, every time. You can diff it, cache it, and trust it in CI.\n\n```\nYou: \"add password reset\"\n        │\n        ▼\n   sensei context \"add password reset\"\n        │\n        ▼\n   ┌────────────────────────────────────────────┐\n   │ REUSE: src/auth/token.ts:12 issueToken()    │\n   │ REUSE: src/mail/send.ts:8 sendEmail()       │\n   │ AVOID: src/types.ts (15 importers)          │\n   │ AVOID: src/index.ts (entrypoint)            │\n   └────────────────────────────────────────────┘\n        │\n        ▼\n   feed to your agent → it reuses instead of reinventing\n        │\n        ▼\n   sensei validate-diff  → catches duplicates/dangerous edits before commit\n```\n\n---\n\n## Install\n\nRequires Node `>=22`.\n\n```bash\nnpm install -g @deneuv34/sensei\n```\n\nThis installs the `sensei` command. Or build from source:\n\n```bash\ngit clone https://github.com/deneuv34/sensei.git\ncd sensei\nnpm install\nnpm run build\nnpm link        # optional: put `sensei` on your PATH\n```\n\n> This project uses npm. If you use pnpm and have a `pnpm-workspace.yaml` higher in your home directory, run pnpm commands with `--ignore-workspace`.\n\n## Quickstart\n\n```bash\nsensei init                          # create .sensei/ (config + agent rules)\nsensei scan                          # build the local symbol index\nsensei context \"add password reset\"  # write .sensei/current-task-context.md\nsensei export --target claude        # print a Claude-ready context block\n```\n\nPipe the export straight into your agent's prompt, or point the agent at `.sensei/current-task-context.md`.\n\n## Enforcement\n\n`context` is advice up front. `validate-diff` is a check after the fact: it compares the changed code against the index and flags two things.\n\n```bash\nsensei validate-diff                  # check staged changes (warn-only)\nsensei validate-diff --against main   # check this branch vs main\nsensei validate-diff --all            # check the whole working tree\nsensei validate-diff --block          # exit non-zero on any finding (for CI/hooks)\nsensei validate-diff --json           # machine-readable output\n```\n\n| Finding | Meaning |\n|---|---|\n| **duplicate-candidate** | A newly introduced symbol closely matches existing code (token-Jaccard similarity ≥ threshold). Reuse it instead of reimplementing. |\n| **dangerous-edit** | You touched a high-fan-in or entrypoint file — the kind where a small mistake has wide blast radius. |\n\nThe JSON form is always written to `.sensei/last-validation.json`.\n\nWire it into git so it runs automatically:\n\n```bash\nsensei guard install                  # warn-only pre-commit hook\nsensei guard install --block          # block commits on findings\nsensei guard install --hook pre-push  # run on push instead\nsensei guard run                      # run the check manually\nsensei guard uninstall\n```\n\nThe hook is installed as an idempotent **managed block** — it coexists with any hook content you already have. It never breaks your commit on a tooling error (missing index, parse failure) unless you installed it with `--block`.\n\n### Before code: `validate-plan`\n\n`validate-diff` checks code after it is written. `validate-plan` moves the same judgment earlier — to the agent's written plan, before any code exists. Hand it the plan an agent produced and it flags reuse violations and dangerous targets up front.\n\n```bash\nsensei validate-plan plan.md                      # check a plan file (warn-only)\ncat plan.md | sensei validate-plan --stdin        # pipe a plan straight in\nsensei validate-plan plan.md --block              # exit non-zero on any finding\nsensei validate-plan plan.md --json               # machine-readable output\n```\n\n| Finding | Meaning |\n|---|---|\n| **reuse-candidate** | The plan proposes creating a file/symbol whose name echoes existing code. Extend it instead of creating new. |\n| **dangerous-target** | The plan proposes touching a file under a `dangerous.paths` glob, a high-fan-in file, or an entrypoint — even if that file does not exist yet. |\n\nThe plan is parsed with a hybrid reader: explicit `## Files` / `## New Symbols` sections when present, plus a heuristic fallback over prose. The JSON form is written to `.sensei/last-plan-validation.json`.\n\n## How it works\n\n1. **`scan`** walks the repo (respecting `.gitignore`), parses TS/JS with the raw `typescript` compiler API (error-tolerant, no type-checker), and indexes symbols + the import graph into `.sensei/cache.db` (SQLite + FTS5). Git metadata is collected in a single `git log` pass; re-scans are incremental via per-file content hashing.\n2. **`context`** tokenizes your task, retrieves candidate symbols via FTS5 **and local embedding similarity** (offline ONNX, `all-MiniLM-L6-v2`), unions the two candidate sets, and scores them with a deterministic heuristic (name/signature overlap, path/domain match, exported, git-recency, tests-nearby, **semantic similarity**). It also flags high-fan-in \"do not touch\" files from the import graph.\n3. **`validate-diff`** resolves changed files (staged / working-tree / vs a ref), extracts the symbols each change *introduces*, and scores them against the index with a purpose-built token-Jaccard similarity (½ name + ½ signature). Dangerous edits come from the same fan-in analysis as `context`.\n4. **`validate-plan`** parses an agent's plan into proposed files/symbols (structured sections + heuristic fallback) and runs the same reuse + dangerous checks against the index, using name-containment since a plan has no signatures yet. Dangerous targets also match `dangerous.paths` globs, so proposed *new* files are caught before they exist.\n5. **`export`** renders the latest report for an AI agent. **`guard`** installs the git hook.\n\nNo API key. No network. Deterministic.\n\n## MCP server\n\nRun Sensei as a Model Context Protocol server so an AI agent can pull reuse\ncontext itself:\n\n```bash\nsensei mcp\n```\n\nIt serves two tools over stdio:\n\n- `find_reuse({ task })` — reuse candidates and high-impact files for a task (runs an incremental scan first, returns markdown).\n- `scan()` — rebuild the local index on demand.\n\nRegister it with an MCP client (cwd = your repo root). Example (Claude Code `.mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"sensei\": { \"command\": \"sensei\", \"args\": [\"mcp\"] }\n  }\n}\n```\n\n## Languages\n\nSensei extracts reuse candidates from:\n\n| Language | Parser | Reuse detection | Dangerous-by-fan-in |\n|----------|--------|-----------------|---------------------|\n| TypeScript / JavaScript | `typescript` compiler | ✅ | ✅ |\n| Python, Go, Rust, Java | Tree-sitter | ✅ | ✅ |\n\nFor the Tree-sitter languages, `validate-diff`/`validate-plan` detect duplicate symbols and flag files matched by `dangerous.paths`. As of `0.11.0`, high-fan-in (\"do not touch\") detection also works for Python, Go, Rust, and Java via Tree-sitter import extraction — so the product promise means the same thing in every supported language. `dangerous.paths` globs still apply alongside fan-in for all languages.\n\n**Upgrading:** existing repos with a written `.sensei/sensei.config.json` keep their `include` globs. To index the new languages, add the patterns you need (e.g. `\"**/*.py\"`, `\"**/*.go\"`, `\"**/*.rs\"`, `\"**/*.java\"`) and re-run `sensei scan`. A fresh `sensei init` includes them by default.\n\n## Configuration\n\n`.sensei/sensei.config.json` controls:\n\n- include / ignore globs\n- `context.topN` (reuse candidates surfaced) and `context.vectorTopK` (vector recall breadth before fusion, default `50`)\n- scoring weights, including `scoring.semanticSim` (default `0.25`) for embedding similarity\n- dangerous-file `importerThreshold` and `dangerous.paths` (gitignore-style globs flagged by `validate-plan`/`validate-diff`)\n- `validate` block: `duplicateThreshold` (default `0.7`), `block`, `checkDuplicates`, `checkDangerous`\n\nEmbeddings are computed locally on `scan` with no API key. The model is cached under `.sensei/models/` on first run; later runs are offline. If the model can't load (e.g. no network on the very first run), Sensei warns and falls back to lexical-only retrieval — `scan` and `context` still work.\n\n## Development\n\n```bash\nnpm test         # run the vitest suite (200 tests)\nnpm run typecheck\nnpm run build\n```\n\n## Versioning\n\nThis repo follows [Semantic Versioning](https://semver.org/). See [CHANGELOG.md](./CHANGELOG.md) for the full history.\n\n- **`0.1.0`** — MVP: `init`, `scan`, `context`, `export`.\n- **`0.2.0`** — Enforcement: `validate-diff`, `guard`.\n- **`0.3.0`** — Live scan TUI + batched git scan performance.\n- **`0.4.0`** — `validate-plan`: agent plan validation before code.\n- **`0.5.0`** — shell autocomplete (`zsh`, `bash`, `powershell`).\n- **`0.6.0`** — GitHub Action: gate pull requests in CI.\n- **`0.7.0`** — multi-language support via Tree-sitter (Python, Go, Rust, Java).\n- **`0.8.0`** — Cursor/Codex export targets + `--write` managed-section injection.\n- **`0.9.0`** — MCP server (`sensei mcp`): serve reuse context over stdio.\n- **`0.10.0`** — embeddings-based semantic retrieval (local offline `all-MiniLM-L6-v2`).\n- **`0.11.0`** — tree-sitter fan-in danger detection (Python, Go, Rust, Java).\n- **`1.0.0`** — backward-compatibility commitment: CLI surface and config schema are stable.\n\nAs of `1.0.0` the CLI surface and config schema are stable and follow SemVer: breaking changes only in a major version.\n\n## GitHub Action\n\nGate pull requests with Sensei. The action scans your repo and checks the PR's\nchanged files for code-reuse violations and dangerous edits.\n\n```yaml\n# .github/workflows/sensei.yml\nname: Sensei\non:\n  pull_request:\n    branches: [main]\npermissions:\n  contents: read\njobs:\n  sensei:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0 # required: validate-diff needs the merge-base\n      - uses: deneuv34/sensei@v1\n        with:\n          block: true # fail the check on findings (omit for warn-only)\n```\n\n`fetch-depth: 0` is required so the action can compute the diff against the base branch.\n\n### Inputs\n\n| input | default | description |\n|-------|---------|-------------|\n| `version` | `latest` | Sensei npm version to run. Pin (e.g. `1.2.3`) for reproducible runs. |\n| `base` | _(auto)_ | Diff base ref. Auto-resolves from the event when empty. |\n| `block` | `false` | Fail the check when findings exist. Warn-only by default. |\n| `working-directory` | `.` | Directory to run in (for monorepos). |\n| `node-version` | `24` | Node.js version. |\n\n### Outputs\n\n| output | description |\n|--------|-------------|\n| `blocked` | `\"true\"` if blocking findings gated the check. |\n| `findings` | Number of findings in the report. |\n| `report-path` | Path to `.sensei/last-validation.json`. |\n\n## Roadmap\n\nShipped: `init` · `scan` · `context` · `export` (claude/cursor/codex + `--write`) · `validate-diff` · `validate-plan` · `guard` · GitHub Action · MCP server (`sensei mcp`).\n\nMulti-language: TypeScript/JavaScript (TypeScript compiler) · Python, Go, Rust, Java (Tree-sitter).\n\nSemantic retrieval: local offline embeddings (`all-MiniLM-L6-v2`) fused into reuse ranking.\n\nSee the [full roadmap](docs/superpowers/specs/2026-06-20-sensei-roadmap.md) for what's next.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}