{"_id":"@airnauts/comments-core","_rev":"8-e178b3cd535c5ebbd7613c8bc0328611","name":"@airnauts/comments-core","dist-tags":{"latest":"0.7.0"},"versions":{"0.1.0":{"name":"@airnauts/comments-core","version":"0.1.0","keywords":["comments","commenting","annotations","feedback","airnauts","zod","openapi"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-core@0.1.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"71ce7ca135c471c9ab55f0b7f7c837a569445407","tarball":"https://registry.npmjs.org/@airnauts/comments-core/-/comments-core-0.1.0.tgz","fileCount":44,"integrity":"sha512-zSVvc858pSebwTHjraTEfi+lUwb8DKshObUBzj7Ukgep3kaBdhjTA/PGzPtlgq8xs0TVXgAFxtlzXOA2VcDCjw==","signatures":[{"sig":"MEYCIQCwiUmIojYVknalqvbjqaF6Zcc2T1lOtbaB+BnaJcM61QIhAJ6XOaW1zJ9804e2UuFfF4uSC+s6efF/Ps/IZ5agdBVX","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":130339},"type":"module","_from":"file:airnauts-comments-core-0.1.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force && tsx scripts/emit-openapi.ts","typecheck":"tsc --build","emit:openapi":"tsx scripts/emit-openapi.ts"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/private/var/folders/2n/cymmpn8j3p962bjb2kqxq7n80000gn/T/f15bb19b7e0d7a2ca73a72210758d7bb/airnauts-comments-core-0.1.0.tgz","_integrity":"sha512-zSVvc858pSebwTHjraTEfi+lUwb8DKshObUBzj7Ukgep3kaBdhjTA/PGzPtlgq8xs0TVXgAFxtlzXOA2VcDCjw==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/core"},"_npmVersion":"10.9.2","description":"Framework-agnostic core for the Airnauts embeddable commenting tool: zod schemas, page-key normalization, the scoring/threshold policy, and the OpenAPI contract.","directories":{},"_nodeVersion":"22.13.0","dependencies":{"zod":"^4.4.3","zod-openapi":"^5.4.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","@scalar/openapi-parser":"^0.28.5"},"_npmOperationalInternal":{"tmp":"tmp/comments-core_0.1.0_1780410889738_0.6854074099034013","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-core — install that instead. No longer maintained."},"0.2.0":{"name":"@airnauts/comments-core","version":"0.2.0","keywords":["comments","commenting","annotations","feedback","airnauts","zod","openapi"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-core@0.2.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"a2698ff34a3d922fdd7e9c4a1a9ea9ce367b7b53","tarball":"https://registry.npmjs.org/@airnauts/comments-core/-/comments-core-0.2.0.tgz","fileCount":44,"integrity":"sha512-WnBRi65trbzV2vUik5t2kYech8n+9Y79AabP6qSPRh072K+DKqaEOg5DqIeQYOiRtTa9QArGiPRoAhCim1BD6A==","signatures":[{"sig":"MEYCIQD+X0DiB0OMj2QtzsNP18ZdmwrX7u6AeW6LXkBgliVK+AIhANUMb2XxjqgYpLnJRPgx2PqkHveVkMsQspSjLlTi28as","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131557},"type":"module","_from":"file:airnauts-comments-core-0.2.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force && tsx scripts/emit-openapi.ts","typecheck":"tsc --build","emit:openapi":"tsx scripts/emit-openapi.ts"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/3e51d622204b237dd26f3fbbe79aac38/airnauts-comments-core-0.2.0.tgz","_integrity":"sha512-WnBRi65trbzV2vUik5t2kYech8n+9Y79AabP6qSPRh072K+DKqaEOg5DqIeQYOiRtTa9QArGiPRoAhCim1BD6A==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/core"},"_npmVersion":"10.9.8","description":"Framework-agnostic core for the Airnauts embeddable commenting tool: zod schemas, page-key normalization, the scoring/threshold policy, and the OpenAPI contract.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"zod":"^4.4.3","zod-openapi":"^5.4.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","@scalar/openapi-parser":"^0.28.5"},"_npmOperationalInternal":{"tmp":"tmp/comments-core_0.2.0_1780913164844_0.5335536850915275","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-core — install that instead. No longer maintained."},"0.4.0":{"name":"@airnauts/comments-core","version":"0.4.0","keywords":["comments","commenting","annotations","feedback","airnauts","zod","openapi"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-core@0.4.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"5409f8db9b04eeb5b632f83016475c2c065ec546","tarball":"https://registry.npmjs.org/@airnauts/comments-core/-/comments-core-0.4.0.tgz","fileCount":44,"integrity":"sha512-FCQur2RVydF3YOwxkJaIjoZFKMsFP8KSIXZAQFp1vGsf0Z4kp2mYixbsp48877WnuLsTJ5MTpyztH3iOS/CSZA==","signatures":[{"sig":"MEUCIEKN5hMeiECqw6Zdnm/BiNLaSSEc87STTyHADBunBn/bAiEApxtf6bzblB8S/25D11wUUzu4pZnY9uwzkD1NH2STCDI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131557},"type":"module","_from":"file:airnauts-comments-core-0.4.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force && tsx scripts/emit-openapi.ts","typecheck":"tsc --build","emit:openapi":"tsx scripts/emit-openapi.ts"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/1c202196fde1132a747a1cc7413c733a/airnauts-comments-core-0.4.0.tgz","_integrity":"sha512-FCQur2RVydF3YOwxkJaIjoZFKMsFP8KSIXZAQFp1vGsf0Z4kp2mYixbsp48877WnuLsTJ5MTpyztH3iOS/CSZA==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/core"},"_npmVersion":"10.9.8","description":"Framework-agnostic core for the Airnauts embeddable commenting tool: zod schemas, page-key normalization, the scoring/threshold policy, and the OpenAPI contract.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"zod":"^4.4.3","zod-openapi":"^5.4.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","@scalar/openapi-parser":"^0.28.5"},"_npmOperationalInternal":{"tmp":"tmp/comments-core_0.4.0_1780915787440_0.22347647487465538","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-core — install that instead. No longer maintained."},"0.5.0":{"name":"@airnauts/comments-core","version":"0.5.0","keywords":["comments","commenting","annotations","feedback","airnauts","zod","openapi"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-core@0.5.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"81ce676c1acf576682af32566c8c253c295cf9a6","tarball":"https://registry.npmjs.org/@airnauts/comments-core/-/comments-core-0.5.0.tgz","fileCount":44,"integrity":"sha512-XlUO/U2dxxLfV0vHlXipLgjJtzFhkEQefLgmuVanv3KoCDbY0AzCyvDlvg8j3jfN2EZGQ6Z3AGUBcc4SViHEGw==","signatures":[{"sig":"MEUCIB8M+5JfiKIhOOmUGyuZ7ZL/AdSrkI+351DU+q1e6oCfAiEA08zrm8NEI7gCBL2JIUqf62qQBeX+PBpgcKBFcf3VpsE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131557},"type":"module","_from":"file:airnauts-comments-core-0.5.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force && tsx scripts/emit-openapi.ts","typecheck":"tsc --build","emit:openapi":"tsx scripts/emit-openapi.ts"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/0337570a3f9c3c01c18332e7479d69b0/airnauts-comments-core-0.5.0.tgz","_integrity":"sha512-XlUO/U2dxxLfV0vHlXipLgjJtzFhkEQefLgmuVanv3KoCDbY0AzCyvDlvg8j3jfN2EZGQ6Z3AGUBcc4SViHEGw==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/core"},"_npmVersion":"10.9.8","description":"Framework-agnostic core for the Airnauts embeddable commenting tool: zod schemas, page-key normalization, the scoring/threshold policy, and the OpenAPI contract.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"zod":"^4.4.3","zod-openapi":"^5.4.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","@scalar/openapi-parser":"^0.28.5"},"_npmOperationalInternal":{"tmp":"tmp/comments-core_0.5.0_1780919620602_0.498950005966891","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-core — install that instead. No longer maintained."},"0.5.1":{"name":"@airnauts/comments-core","version":"0.5.1","keywords":["comments","commenting","annotations","feedback","airnauts","zod","openapi"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-core@0.5.1","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"fa59dbe7256abb761788b903f635ea7045f39983","tarball":"https://registry.npmjs.org/@airnauts/comments-core/-/comments-core-0.5.1.tgz","fileCount":44,"integrity":"sha512-aOddkrHrTu41elpCldvKkOEInzA/s14iT9SDKc1BFECsp9ax+oEIAhahsrmzs06BMpPwD/nn/aUacpyN+udqZA==","signatures":[{"sig":"MEQCIAMSHBxxfwOFFjejR7oi+XxdmSMdeg8vW0iih0AC/4vsAiAPmXPDFzSmubamevCxzt1kfrQbp55LvYfrAi82NQ+uQA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131557},"type":"module","_from":"file:airnauts-comments-core-0.5.1.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force && tsx scripts/emit-openapi.ts","typecheck":"tsc --build","emit:openapi":"tsx scripts/emit-openapi.ts"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/f6b175414eceb09c75252b76c49fbeac/airnauts-comments-core-0.5.1.tgz","_integrity":"sha512-aOddkrHrTu41elpCldvKkOEInzA/s14iT9SDKc1BFECsp9ax+oEIAhahsrmzs06BMpPwD/nn/aUacpyN+udqZA==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/core"},"_npmVersion":"10.9.8","description":"Framework-agnostic core for the Airnauts embeddable commenting tool: zod schemas, page-key normalization, the scoring/threshold policy, and the OpenAPI contract.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"zod":"^4.4.3","zod-openapi":"^5.4.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","@scalar/openapi-parser":"^0.28.5"},"_npmOperationalInternal":{"tmp":"tmp/comments-core_0.5.1_1780924735739_0.7004217344365902","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-core — install that instead. No longer maintained."},"0.6.0":{"name":"@airnauts/comments-core","version":"0.6.0","keywords":["comments","commenting","annotations","feedback","airnauts","zod","openapi"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-core@0.6.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"62a498748ca433a442caf4292003f0aa5b38fde9","tarball":"https://registry.npmjs.org/@airnauts/comments-core/-/comments-core-0.6.0.tgz","fileCount":50,"integrity":"sha512-GL+4541Jh2vvDeD21DzTys+NL5mfFx00tNYXMDbJ4tNuvFyF155EoCtc2g+IKsRQxLjiT6q6eweOzDmVF6FBeg==","signatures":[{"sig":"MEUCIQCgIO1G8fkQNcMQvUc6xK3qWP4AHMfPsrRCnNgyPtGw7QIgLIZ7QJ8gAnMZtaY+eeOoEXUQGio5IdDRdGYznp7CrjQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":163845},"type":"module","_from":"file:airnauts-comments-core-0.6.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force && tsx scripts/emit-openapi.ts","typecheck":"tsc --build","emit:openapi":"tsx scripts/emit-openapi.ts"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/2186009fda6f8bcef47e8cf9cc03138a/airnauts-comments-core-0.6.0.tgz","_integrity":"sha512-GL+4541Jh2vvDeD21DzTys+NL5mfFx00tNYXMDbJ4tNuvFyF155EoCtc2g+IKsRQxLjiT6q6eweOzDmVF6FBeg==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/core"},"_npmVersion":"10.9.8","description":"Framework-agnostic core for the Airnauts embeddable commenting tool: zod schemas, page-key normalization, the scoring/threshold policy, and the OpenAPI contract.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"zod":"^4.4.3","zod-openapi":"^5.4.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","@scalar/openapi-parser":"^0.28.5"},"_npmOperationalInternal":{"tmp":"tmp/comments-core_0.6.0_1781537514496_0.6460730732077591","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-core — install that instead. No longer maintained."},"0.7.0":{"name":"@airnauts/comments-core","version":"0.7.0","keywords":["comments","commenting","annotations","feedback","airnauts","zod","openapi"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-core@0.7.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"117b14a94bb188013a7cd1207aec211341370b6f","tarball":"https://registry.npmjs.org/@airnauts/comments-core/-/comments-core-0.7.0.tgz","fileCount":50,"integrity":"sha512-ykbLCu5CTvYeRs5wp+hxQGeohFN0ThvFbADnfAjEl83QS2GMZs5b2xmnZJVTuj2QwaQFncOl/gMlW61dhGEGYA==","signatures":[{"sig":"MEQCIHIr5h5G5gN1yUqP39KcQi2POEcA0tEanmXORiXUlp1aAiBaLKh7Y+aOy7aqsPg8k7eFJ15MrSXY6vsSRm2JHse9ew==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":163845},"type":"module","_from":"file:airnauts-comments-core-0.7.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force && tsx scripts/emit-openapi.ts","typecheck":"tsc --build","emit:openapi":"tsx scripts/emit-openapi.ts"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/6d4b23bec577f9fa6530b17d787117a9/airnauts-comments-core-0.7.0.tgz","_integrity":"sha512-ykbLCu5CTvYeRs5wp+hxQGeohFN0ThvFbADnfAjEl83QS2GMZs5b2xmnZJVTuj2QwaQFncOl/gMlW61dhGEGYA==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/core"},"_npmVersion":"10.9.8","description":"Framework-agnostic core for the Airnauts embeddable commenting tool: zod schemas, page-key normalization, the scoring/threshold policy, and the OpenAPI contract.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"zod":"^4.4.3","zod-openapi":"^5.4.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","@scalar/openapi-parser":"^0.28.5"},"_npmOperationalInternal":{"tmp":"tmp/comments-core_0.7.0_1781540305525_0.6162076538726808","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-core — install that instead. No longer maintained."}},"time":{"created":"2026-06-02T14:34:49.551Z","modified":"2026-06-16T09:40:45.129Z","0.1.0":"2026-06-02T14:34:49.884Z","0.2.0":"2026-06-08T10:06:05.011Z","0.4.0":"2026-06-08T10:49:47.584Z","0.5.0":"2026-06-08T11:53:40.740Z","0.5.1":"2026-06-08T13:18:55.870Z","0.6.0":"2026-06-15T15:31:54.661Z","0.7.0":"2026-06-15T16:18:25.693Z"},"bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"author":{"name":"Airnauts"},"license":"MIT","homepage":"https://github.com/Airnauts/commenting-tool#readme","keywords":["comments","commenting","annotations","feedback","airnauts","zod","openapi"],"repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/core"},"description":"Framework-agnostic core for the Airnauts embeddable commenting tool: zod schemas, page-key normalization, the scoring/threshold policy, and the OpenAPI contract.","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"readme":"# @airnauts/comments-core\n\nFramework-agnostic core for the [Airnauts commenting tool](https://github.com/Airnauts/commenting-tool): Zod schemas, page-key normalization, the anchor scoring/threshold policy, and the HTTP contract types shared by the client and server.\n\nMost consumers get this transitively via `@airnauts/comments-client` or `@airnauts/comments-server`. Install it directly only when you need the shared types in code that sits outside those packages.\n\n## Installation\n\n```bash\npnpm add @airnauts/comments-core\n# or\nnpm install @airnauts/comments-core\n```\n\n## Quick start\n\n```ts\nimport { normalizePageKey, threadLink, DEFAULT_THREAD_PARAM } from '@airnauts/comments-core'\n\n// Canonical page identity key (origin + pathname, trailing slash stripped)\nconst key = normalizePageKey('https://example.com/page/?q=1')\n// → \"https://example.com/page\"\n\n// Build a deep-link URL that focuses a thread when the page is opened\nconst url = threadLink('https://example.com/page', 'thread-abc123')\n// → \"https://example.com/page?comments-thread=thread-abc123\"\n```\n\n## API reference\n\n### Page key\n\n| Export | Signature / value |\n|---|---|\n| `normalizePageKey` | `(url: string \\| URL) => string` — `origin + pathname`, trailing slash stripped, hash and query excluded |\n| `PageKeyFn` | `type PageKeyFn = (url: string) => string` |\n\n### Deep-link\n\n| Export | Signature / value |\n|---|---|\n| `threadLink` | `(pageUrl: string, threadId: string, param?: string) => string` — appends `?<param>=<id>` to the page URL |\n| `DEFAULT_THREAD_PARAM` | `\"comments-thread\"` |\n\n### Anchor scoring (pure policy)\n\nThese are consumed by `@airnauts/comments-client` to implement re-matching. Integrators building custom anchoring can use them directly.\n\n| Export | Description |\n|---|---|\n| `scoreCandidate(candidate, stored, weights?)` | Score a single DOM candidate against the stored anchor signals; returns `{ score: number }` |\n| `decide(scores, thresholds?)` | Decide anchored / orphaned / ambiguous from an array of scores |\n| `locateQuote(container, ctx)` | Find a text-range quote within a DOM node |\n| `DEFAULT_WEIGHTS` | Default scoring weights (stable attr +0.40, text +0.25, class +0.15, role +0.10, sibling +0.05, ancestor +0.05) |\n| `DEFAULT_THRESHOLDS` | `{ accept: 0.60, margin: 0.10 }` |\n\n### HTTP contract\n\nThese types describe the wire API served by `@airnauts/comments-server` and consumed by the client. They are defined as Zod schemas and exported both as schemas and as TypeScript types.\n\n**Request bodies / queries:**\n\n| Export | Description |\n|---|---|\n| `CreateThreadBody` | POST `/threads` body |\n| `ListThreadsQuery` | GET `/threads` query params |\n| `AddCommentBody` | POST `/threads/:id/comments` body |\n| `SetThreadStatusBody` | PATCH `/threads/:id` body |\n| `RefreshAnchorBody` | PATCH `/threads/:id/anchor` body |\n| `ThreadIdParam` | `:id` path param |\n| `ThreadActionParam` | `:id` + `:actionId` path params |\n\n**Responses:**\n\n| Export | Description |\n|---|---|\n| `ThreadListResponse` | `{ threads: ThreadListItem[]; nextCursor: string \\| null }` |\n\n**Domain types:**\n\n`Thread`, `Comment`, `Attachment`, `ThreadListItem`, `Anchor`, `Signals`, `Author`, `CaptureContext`, `Provenance`, `ExternalLink`, `ThreadStatus`, `AnchorState`, `ExtensionSlot`, `ThreadActionDescriptor`\n\n**OpenAPI:**\n\n| Export | Description |\n|---|---|\n| `buildOpenApiDocument()` | Returns the full OpenAPI 3.1 document object (served by the server at `GET /openapi.json`) |\n| `operations` | The frozen route table (`Operation[]`) |\n| `Operation` | Route descriptor type |\n\n**Wire constants:**\n\n| Export | Value |\n|---|---|\n| `KEY_HEADER_NAME` | `\"x-comments-key\"` |\n| `ERROR_CODES` | Tuple of all error code strings |\n| `ERROR_STATUS` | `Record<ErrorCode, number>` mapping codes to HTTP status |\n| `ErrorCode` | Union of all error code strings |\n| `ErrorResponse` | Zod schema for the error wire shape |\n\n### Branded ID types\n\n`ThreadId`, `CommentId`, `AuthorId`, `AttachmentId` — branded Zod string schemas; use these as the type for IDs in custom adapters.\n\n## Requirements\n\n- Node.js ≥ 18 (or any runtime that provides `URL`)\n- No DOM or Node-specific APIs — fully isomorphic\n\n## Related packages\n\nThis is the shared contract layer for the `@airnauts/comments-*` suite:\n\n- **`@airnauts/comments-client`** — widget engine and React wrapper\n- **`@airnauts/comments-server`** — HTTP server, use cases, and adapter interfaces\n- **`@airnauts/comments-adapter-mongo`** — MongoDB persistence\n- **`@airnauts/comments-adapter-postgres`** — PostgreSQL persistence\n- **`@airnauts/comments-storage-vercel-blob`** — Vercel Blob file storage\n- **`@airnauts/comments-storage-fs`** — filesystem file storage\n\nSee [docs/architecture.md](https://github.com/Airnauts/commenting-tool/blob/main/docs/architecture.md) for the full system design.\n\n## License\n\nMIT © Airnauts\n","readmeFilename":"README.md"}