purecontext-mcp 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +207 -0
- package/dist/adapters/actix-web.d.ts +28 -0
- package/dist/adapters/actix-web.d.ts.map +1 -0
- package/dist/adapters/actix-web.js +362 -0
- package/dist/adapters/actix-web.js.map +1 -0
- package/dist/adapters/adapter-registry.d.ts +34 -0
- package/dist/adapters/adapter-registry.d.ts.map +1 -0
- package/dist/adapters/adapter-registry.js +92 -0
- package/dist/adapters/adapter-registry.js.map +1 -0
- package/dist/adapters/angular.d.ts +13 -0
- package/dist/adapters/angular.d.ts.map +1 -0
- package/dist/adapters/angular.js +348 -0
- package/dist/adapters/angular.js.map +1 -0
- package/dist/adapters/axum.d.ts +16 -0
- package/dist/adapters/axum.d.ts.map +1 -0
- package/dist/adapters/axum.js +299 -0
- package/dist/adapters/axum.js.map +1 -0
- package/dist/adapters/django-orm.d.ts +28 -0
- package/dist/adapters/django-orm.d.ts.map +1 -0
- package/dist/adapters/django-orm.js +464 -0
- package/dist/adapters/django-orm.js.map +1 -0
- package/dist/adapters/django.d.ts +16 -0
- package/dist/adapters/django.d.ts.map +1 -0
- package/dist/adapters/django.js +257 -0
- package/dist/adapters/django.js.map +1 -0
- package/dist/adapters/echo.d.ts +15 -0
- package/dist/adapters/echo.d.ts.map +1 -0
- package/dist/adapters/echo.js +142 -0
- package/dist/adapters/echo.js.map +1 -0
- package/dist/adapters/express.d.ts +15 -0
- package/dist/adapters/express.d.ts.map +1 -0
- package/dist/adapters/express.js +126 -0
- package/dist/adapters/express.js.map +1 -0
- package/dist/adapters/fastapi.d.ts +16 -0
- package/dist/adapters/fastapi.d.ts.map +1 -0
- package/dist/adapters/fastapi.js +113 -0
- package/dist/adapters/fastapi.js.map +1 -0
- package/dist/adapters/fastify.d.ts +14 -0
- package/dist/adapters/fastify.d.ts.map +1 -0
- package/dist/adapters/fastify.js +124 -0
- package/dist/adapters/fastify.js.map +1 -0
- package/dist/adapters/fiber.d.ts +15 -0
- package/dist/adapters/fiber.d.ts.map +1 -0
- package/dist/adapters/fiber.js +147 -0
- package/dist/adapters/fiber.js.map +1 -0
- package/dist/adapters/flask.d.ts +18 -0
- package/dist/adapters/flask.d.ts.map +1 -0
- package/dist/adapters/flask.js +175 -0
- package/dist/adapters/flask.js.map +1 -0
- package/dist/adapters/flutter.d.ts +19 -0
- package/dist/adapters/flutter.d.ts.map +1 -0
- package/dist/adapters/flutter.js +251 -0
- package/dist/adapters/flutter.js.map +1 -0
- package/dist/adapters/gin.d.ts +16 -0
- package/dist/adapters/gin.d.ts.map +1 -0
- package/dist/adapters/gin.js +159 -0
- package/dist/adapters/gin.js.map +1 -0
- package/dist/adapters/hibernate.d.ts +24 -0
- package/dist/adapters/hibernate.d.ts.map +1 -0
- package/dist/adapters/hibernate.js +448 -0
- package/dist/adapters/hibernate.js.map +1 -0
- package/dist/adapters/ktor.d.ts +18 -0
- package/dist/adapters/ktor.d.ts.map +1 -0
- package/dist/adapters/ktor.js +219 -0
- package/dist/adapters/ktor.js.map +1 -0
- package/dist/adapters/laravel.d.ts +19 -0
- package/dist/adapters/laravel.d.ts.map +1 -0
- package/dist/adapters/laravel.js +370 -0
- package/dist/adapters/laravel.js.map +1 -0
- package/dist/adapters/micronaut.d.ts +21 -0
- package/dist/adapters/micronaut.d.ts.map +1 -0
- package/dist/adapters/micronaut.js +435 -0
- package/dist/adapters/micronaut.js.map +1 -0
- package/dist/adapters/nestjs.d.ts +12 -0
- package/dist/adapters/nestjs.d.ts.map +1 -0
- package/dist/adapters/nestjs.js +401 -0
- package/dist/adapters/nestjs.js.map +1 -0
- package/dist/adapters/nextjs.d.ts +49 -0
- package/dist/adapters/nextjs.d.ts.map +1 -0
- package/dist/adapters/nextjs.js +412 -0
- package/dist/adapters/nextjs.js.map +1 -0
- package/dist/adapters/nuxt.d.ts +44 -0
- package/dist/adapters/nuxt.d.ts.map +1 -0
- package/dist/adapters/nuxt.js +243 -0
- package/dist/adapters/nuxt.js.map +1 -0
- package/dist/adapters/quarkus.d.ts +21 -0
- package/dist/adapters/quarkus.d.ts.map +1 -0
- package/dist/adapters/quarkus.js +395 -0
- package/dist/adapters/quarkus.js.map +1 -0
- package/dist/adapters/rails.d.ts +18 -0
- package/dist/adapters/rails.d.ts.map +1 -0
- package/dist/adapters/rails.js +363 -0
- package/dist/adapters/rails.js.map +1 -0
- package/dist/adapters/react.d.ts +18 -0
- package/dist/adapters/react.d.ts.map +1 -0
- package/dist/adapters/react.js +95 -0
- package/dist/adapters/react.js.map +1 -0
- package/dist/adapters/rocket.d.ts +19 -0
- package/dist/adapters/rocket.d.ts.map +1 -0
- package/dist/adapters/rocket.js +271 -0
- package/dist/adapters/rocket.js.map +1 -0
- package/dist/adapters/sinatra.d.ts +16 -0
- package/dist/adapters/sinatra.d.ts.map +1 -0
- package/dist/adapters/sinatra.js +114 -0
- package/dist/adapters/sinatra.js.map +1 -0
- package/dist/adapters/spring-boot.d.ts +24 -0
- package/dist/adapters/spring-boot.d.ts.map +1 -0
- package/dist/adapters/spring-boot.js +399 -0
- package/dist/adapters/spring-boot.js.map +1 -0
- package/dist/adapters/spring-kotlin.d.ts +19 -0
- package/dist/adapters/spring-kotlin.d.ts.map +1 -0
- package/dist/adapters/spring-kotlin.js +297 -0
- package/dist/adapters/spring-kotlin.js.map +1 -0
- package/dist/adapters/sqlalchemy.d.ts +28 -0
- package/dist/adapters/sqlalchemy.d.ts.map +1 -0
- package/dist/adapters/sqlalchemy.js +435 -0
- package/dist/adapters/sqlalchemy.js.map +1 -0
- package/dist/adapters/symfony.d.ts +16 -0
- package/dist/adapters/symfony.d.ts.map +1 -0
- package/dist/adapters/symfony.js +242 -0
- package/dist/adapters/symfony.js.map +1 -0
- package/dist/adapters/vapor.d.ts +21 -0
- package/dist/adapters/vapor.d.ts.map +1 -0
- package/dist/adapters/vapor.js +269 -0
- package/dist/adapters/vapor.js.map +1 -0
- package/dist/adapters/vue-preprocessor.d.ts +26 -0
- package/dist/adapters/vue-preprocessor.d.ts.map +1 -0
- package/dist/adapters/vue-preprocessor.js +82 -0
- package/dist/adapters/vue-preprocessor.js.map +1 -0
- package/dist/adapters/vue.d.ts +13 -0
- package/dist/adapters/vue.d.ts.map +1 -0
- package/dist/adapters/vue.js +134 -0
- package/dist/adapters/vue.js.map +1 -0
- package/dist/config/cli.d.ts +26 -0
- package/dist/config/cli.d.ts.map +1 -0
- package/dist/config/cli.js +291 -0
- package/dist/config/cli.js.map +1 -0
- package/dist/config/config-loader.d.ts +26 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +168 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/config-schema.d.ts +228 -0
- package/dist/config/config-schema.d.ts.map +1 -0
- package/dist/config/config-schema.js +400 -0
- package/dist/config/config-schema.js.map +1 -0
- package/dist/config/keys-cli.d.ts +37 -0
- package/dist/config/keys-cli.d.ts.map +1 -0
- package/dist/config/keys-cli.js +179 -0
- package/dist/config/keys-cli.js.map +1 -0
- package/dist/config/workspaces-cli.d.ts +2 -0
- package/dist/config/workspaces-cli.d.ts.map +1 -0
- package/dist/config/workspaces-cli.js +84 -0
- package/dist/config/workspaces-cli.js.map +1 -0
- package/dist/core/db/api-keys.d.ts +95 -0
- package/dist/core/db/api-keys.d.ts.map +1 -0
- package/dist/core/db/api-keys.js +293 -0
- package/dist/core/db/api-keys.js.map +1 -0
- package/dist/core/db/dep-store.d.ts +18 -0
- package/dist/core/db/dep-store.d.ts.map +1 -0
- package/dist/core/db/dep-store.js +155 -0
- package/dist/core/db/dep-store.js.map +1 -0
- package/dist/core/db/embedding-store.d.ts +40 -0
- package/dist/core/db/embedding-store.d.ts.map +1 -0
- package/dist/core/db/embedding-store.js +120 -0
- package/dist/core/db/embedding-store.js.map +1 -0
- package/dist/core/db/file-store.d.ts +27 -0
- package/dist/core/db/file-store.d.ts.map +1 -0
- package/dist/core/db/file-store.js +101 -0
- package/dist/core/db/file-store.js.map +1 -0
- package/dist/core/db/request-log.d.ts +40 -0
- package/dist/core/db/request-log.d.ts.map +1 -0
- package/dist/core/db/request-log.js +90 -0
- package/dist/core/db/request-log.js.map +1 -0
- package/dist/core/db/savings-store.d.ts +9 -0
- package/dist/core/db/savings-store.d.ts.map +1 -0
- package/dist/core/db/savings-store.js +64 -0
- package/dist/core/db/savings-store.js.map +1 -0
- package/dist/core/db/schema.d.ts +14 -0
- package/dist/core/db/schema.d.ts.map +1 -0
- package/dist/core/db/schema.js +235 -0
- package/dist/core/db/schema.js.map +1 -0
- package/dist/core/db/symbol-store.d.ts +64 -0
- package/dist/core/db/symbol-store.d.ts.map +1 -0
- package/dist/core/db/symbol-store.js +243 -0
- package/dist/core/db/symbol-store.js.map +1 -0
- package/dist/core/db/tenants.d.ts +91 -0
- package/dist/core/db/tenants.d.ts.map +1 -0
- package/dist/core/db/tenants.js +219 -0
- package/dist/core/db/tenants.js.map +1 -0
- package/dist/core/errors.d.ts +72 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +140 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/file-discovery.d.ts +17 -0
- package/dist/core/file-discovery.d.ts.map +1 -0
- package/dist/core/file-discovery.js +136 -0
- package/dist/core/file-discovery.js.map +1 -0
- package/dist/core/file-processor.d.ts +21 -0
- package/dist/core/file-processor.d.ts.map +1 -0
- package/dist/core/file-processor.js +110 -0
- package/dist/core/file-processor.js.map +1 -0
- package/dist/core/hash-cache.d.ts +18 -0
- package/dist/core/hash-cache.d.ts.map +1 -0
- package/dist/core/hash-cache.js +35 -0
- package/dist/core/hash-cache.js.map +1 -0
- package/dist/core/index-manager.d.ts +18 -0
- package/dist/core/index-manager.d.ts.map +1 -0
- package/dist/core/index-manager.js +461 -0
- package/dist/core/index-manager.js.map +1 -0
- package/dist/core/indexing-worker.d.ts +60 -0
- package/dist/core/indexing-worker.d.ts.map +1 -0
- package/dist/core/indexing-worker.js +128 -0
- package/dist/core/indexing-worker.js.map +1 -0
- package/dist/core/logger.d.ts +10 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +40 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/parse-dispatcher.d.ts +18 -0
- package/dist/core/parse-dispatcher.d.ts.map +1 -0
- package/dist/core/parse-dispatcher.js +74 -0
- package/dist/core/parse-dispatcher.js.map +1 -0
- package/dist/core/search/query-preprocessor.d.ts +22 -0
- package/dist/core/search/query-preprocessor.d.ts.map +1 -0
- package/dist/core/search/query-preprocessor.js +77 -0
- package/dist/core/search/query-preprocessor.js.map +1 -0
- package/dist/core/search/relevance-ranker.d.ts +34 -0
- package/dist/core/search/relevance-ranker.d.ts.map +1 -0
- package/dist/core/search/relevance-ranker.js +132 -0
- package/dist/core/search/relevance-ranker.js.map +1 -0
- package/dist/core/security.d.ts +40 -0
- package/dist/core/security.d.ts.map +1 -0
- package/dist/core/security.js +133 -0
- package/dist/core/security.js.map +1 -0
- package/dist/core/telemetry.d.ts +19 -0
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/core/telemetry.js +101 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/core/tenant-context.d.ts +22 -0
- package/dist/core/tenant-context.d.ts.map +1 -0
- package/dist/core/tenant-context.js +16 -0
- package/dist/core/tenant-context.js.map +1 -0
- package/dist/core/token-tracker.d.ts +39 -0
- package/dist/core/token-tracker.d.ts.map +1 -0
- package/dist/core/token-tracker.js +153 -0
- package/dist/core/token-tracker.js.map +1 -0
- package/dist/core/types.d.ts +145 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/watcher/file-watcher.d.ts +18 -0
- package/dist/core/watcher/file-watcher.d.ts.map +1 -0
- package/dist/core/watcher/file-watcher.js +123 -0
- package/dist/core/watcher/file-watcher.js.map +1 -0
- package/dist/core/worker-pool.d.ts +24 -0
- package/dist/core/worker-pool.d.ts.map +1 -0
- package/dist/core/worker-pool.js +92 -0
- package/dist/core/worker-pool.js.map +1 -0
- package/dist/graph/graph-builder.d.ts +16 -0
- package/dist/graph/graph-builder.d.ts.map +1 -0
- package/dist/graph/graph-builder.js +51 -0
- package/dist/graph/graph-builder.js.map +1 -0
- package/dist/graph/graph-traversal.d.ts +57 -0
- package/dist/graph/graph-traversal.d.ts.map +1 -0
- package/dist/graph/graph-traversal.js +144 -0
- package/dist/graph/graph-traversal.js.map +1 -0
- package/dist/graph/path-resolver.d.ts +13 -0
- package/dist/graph/path-resolver.d.ts.map +1 -0
- package/dist/graph/path-resolver.js +161 -0
- package/dist/graph/path-resolver.js.map +1 -0
- package/dist/handlers/c.d.ts +3 -0
- package/dist/handlers/c.d.ts.map +1 -0
- package/dist/handlers/c.js +473 -0
- package/dist/handlers/c.js.map +1 -0
- package/dist/handlers/cpp.d.ts +3 -0
- package/dist/handlers/cpp.d.ts.map +1 -0
- package/dist/handlers/cpp.js +682 -0
- package/dist/handlers/cpp.js.map +1 -0
- package/dist/handlers/csharp.d.ts +3 -0
- package/dist/handlers/csharp.d.ts.map +1 -0
- package/dist/handlers/csharp.js +369 -0
- package/dist/handlers/csharp.js.map +1 -0
- package/dist/handlers/dart.d.ts +3 -0
- package/dist/handlers/dart.d.ts.map +1 -0
- package/dist/handlers/dart.js +596 -0
- package/dist/handlers/dart.js.map +1 -0
- package/dist/handlers/elixir.d.ts +8 -0
- package/dist/handlers/elixir.d.ts.map +1 -0
- package/dist/handlers/elixir.js +412 -0
- package/dist/handlers/elixir.js.map +1 -0
- package/dist/handlers/go.d.ts +3 -0
- package/dist/handlers/go.d.ts.map +1 -0
- package/dist/handlers/go.js +262 -0
- package/dist/handlers/go.js.map +1 -0
- package/dist/handlers/handler-registry.d.ts +20 -0
- package/dist/handlers/handler-registry.d.ts.map +1 -0
- package/dist/handlers/handler-registry.js +69 -0
- package/dist/handlers/handler-registry.js.map +1 -0
- package/dist/handlers/haskell.d.ts +17 -0
- package/dist/handlers/haskell.d.ts.map +1 -0
- package/dist/handlers/haskell.js +356 -0
- package/dist/handlers/haskell.js.map +1 -0
- package/dist/handlers/java.d.ts +3 -0
- package/dist/handlers/java.d.ts.map +1 -0
- package/dist/handlers/java.js +350 -0
- package/dist/handlers/java.js.map +1 -0
- package/dist/handlers/javascript.d.ts +3 -0
- package/dist/handlers/javascript.d.ts.map +1 -0
- package/dist/handlers/javascript.js +232 -0
- package/dist/handlers/javascript.js.map +1 -0
- package/dist/handlers/kotlin.d.ts +3 -0
- package/dist/handlers/kotlin.d.ts.map +1 -0
- package/dist/handlers/kotlin.js +317 -0
- package/dist/handlers/kotlin.js.map +1 -0
- package/dist/handlers/lua.d.ts +3 -0
- package/dist/handlers/lua.d.ts.map +1 -0
- package/dist/handlers/lua.js +328 -0
- package/dist/handlers/lua.js.map +1 -0
- package/dist/handlers/php.d.ts +3 -0
- package/dist/handlers/php.d.ts.map +1 -0
- package/dist/handlers/php.js +343 -0
- package/dist/handlers/php.js.map +1 -0
- package/dist/handlers/python.d.ts +3 -0
- package/dist/handlers/python.d.ts.map +1 -0
- package/dist/handlers/python.js +343 -0
- package/dist/handlers/python.js.map +1 -0
- package/dist/handlers/r.d.ts +9 -0
- package/dist/handlers/r.d.ts.map +1 -0
- package/dist/handlers/r.js +452 -0
- package/dist/handlers/r.js.map +1 -0
- package/dist/handlers/ruby.d.ts +8 -0
- package/dist/handlers/ruby.d.ts.map +1 -0
- package/dist/handlers/ruby.js +271 -0
- package/dist/handlers/ruby.js.map +1 -0
- package/dist/handlers/rust.d.ts +3 -0
- package/dist/handlers/rust.d.ts.map +1 -0
- package/dist/handlers/rust.js +420 -0
- package/dist/handlers/rust.js.map +1 -0
- package/dist/handlers/scala.d.ts +9 -0
- package/dist/handlers/scala.d.ts.map +1 -0
- package/dist/handlers/scala.js +480 -0
- package/dist/handlers/scala.js.map +1 -0
- package/dist/handlers/swift.d.ts +3 -0
- package/dist/handlers/swift.d.ts.map +1 -0
- package/dist/handlers/swift.js +553 -0
- package/dist/handlers/swift.js.map +1 -0
- package/dist/handlers/typescript.d.ts +4 -0
- package/dist/handlers/typescript.d.ts.map +1 -0
- package/dist/handlers/typescript.js +325 -0
- package/dist/handlers/typescript.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +266 -0
- package/dist/index.js.map +1 -0
- package/dist/semantic/embedding-provider.d.ts +66 -0
- package/dist/semantic/embedding-provider.d.ts.map +1 -0
- package/dist/semantic/embedding-provider.js +176 -0
- package/dist/semantic/embedding-provider.js.map +1 -0
- package/dist/semantic/hnsw-index.d.ts +96 -0
- package/dist/semantic/hnsw-index.d.ts.map +1 -0
- package/dist/semantic/hnsw-index.js +364 -0
- package/dist/semantic/hnsw-index.js.map +1 -0
- package/dist/semantic/hybrid-search.d.ts +46 -0
- package/dist/semantic/hybrid-search.d.ts.map +1 -0
- package/dist/semantic/hybrid-search.js +164 -0
- package/dist/semantic/hybrid-search.js.map +1 -0
- package/dist/semantic/query-expansion.d.ts +25 -0
- package/dist/semantic/query-expansion.d.ts.map +1 -0
- package/dist/semantic/query-expansion.js +150 -0
- package/dist/semantic/query-expansion.js.map +1 -0
- package/dist/semantic/semantic-indexer.d.ts +64 -0
- package/dist/semantic/semantic-indexer.d.ts.map +1 -0
- package/dist/semantic/semantic-indexer.js +162 -0
- package/dist/semantic/semantic-indexer.js.map +1 -0
- package/dist/semantic/text-preparation.d.ts +23 -0
- package/dist/semantic/text-preparation.d.ts.map +1 -0
- package/dist/semantic/text-preparation.js +56 -0
- package/dist/semantic/text-preparation.js.map +1 -0
- package/dist/semantic/vector-store.d.ts +81 -0
- package/dist/semantic/vector-store.d.ts.map +1 -0
- package/dist/semantic/vector-store.js +157 -0
- package/dist/semantic/vector-store.js.map +1 -0
- package/dist/server/admin-api.d.ts +88 -0
- package/dist/server/admin-api.d.ts.map +1 -0
- package/dist/server/admin-api.js +661 -0
- package/dist/server/admin-api.js.map +1 -0
- package/dist/server/auth/api-key.d.ts +105 -0
- package/dist/server/auth/api-key.d.ts.map +1 -0
- package/dist/server/auth/api-key.js +276 -0
- package/dist/server/auth/api-key.js.map +1 -0
- package/dist/server/http-server.d.ts +100 -0
- package/dist/server/http-server.d.ts.map +1 -0
- package/dist/server/http-server.js +823 -0
- package/dist/server/http-server.js.map +1 -0
- package/dist/server/mcp-server.d.ts +23 -0
- package/dist/server/mcp-server.d.ts.map +1 -0
- package/dist/server/mcp-server.js +214 -0
- package/dist/server/mcp-server.js.map +1 -0
- package/dist/server/rate-limit-store.d.ts +25 -0
- package/dist/server/rate-limit-store.d.ts.map +1 -0
- package/dist/server/rate-limit-store.js +46 -0
- package/dist/server/rate-limit-store.js.map +1 -0
- package/dist/server/rate-limiter.d.ts +59 -0
- package/dist/server/rate-limiter.d.ts.map +1 -0
- package/dist/server/rate-limiter.js +85 -0
- package/dist/server/rate-limiter.js.map +1 -0
- package/dist/server/tools/_meta.d.ts +24 -0
- package/dist/server/tools/_meta.d.ts.map +1 -0
- package/dist/server/tools/_meta.js +35 -0
- package/dist/server/tools/_meta.js.map +1 -0
- package/dist/server/tools/find-dead-code.d.ts +11 -0
- package/dist/server/tools/find-dead-code.d.ts.map +1 -0
- package/dist/server/tools/find-dead-code.js +45 -0
- package/dist/server/tools/find-dead-code.js.map +1 -0
- package/dist/server/tools/find-importers.d.ts +13 -0
- package/dist/server/tools/find-importers.d.ts.map +1 -0
- package/dist/server/tools/find-importers.js +46 -0
- package/dist/server/tools/find-importers.js.map +1 -0
- package/dist/server/tools/get-blast-radius.d.ts +15 -0
- package/dist/server/tools/get-blast-radius.d.ts.map +1 -0
- package/dist/server/tools/get-blast-radius.js +51 -0
- package/dist/server/tools/get-blast-radius.js.map +1 -0
- package/dist/server/tools/get-context-bundle.d.ts +15 -0
- package/dist/server/tools/get-context-bundle.d.ts.map +1 -0
- package/dist/server/tools/get-context-bundle.js +53 -0
- package/dist/server/tools/get-context-bundle.js.map +1 -0
- package/dist/server/tools/get-file-outline.d.ts +13 -0
- package/dist/server/tools/get-file-outline.d.ts.map +1 -0
- package/dist/server/tools/get-file-outline.js +42 -0
- package/dist/server/tools/get-file-outline.js.map +1 -0
- package/dist/server/tools/get-file-tree.d.ts +11 -0
- package/dist/server/tools/get-file-tree.d.ts.map +1 -0
- package/dist/server/tools/get-file-tree.js +63 -0
- package/dist/server/tools/get-file-tree.js.map +1 -0
- package/dist/server/tools/get-graph.d.ts +46 -0
- package/dist/server/tools/get-graph.d.ts.map +1 -0
- package/dist/server/tools/get-graph.js +168 -0
- package/dist/server/tools/get-graph.js.map +1 -0
- package/dist/server/tools/get-layer-violations.d.ts +37 -0
- package/dist/server/tools/get-layer-violations.d.ts.map +1 -0
- package/dist/server/tools/get-layer-violations.js +138 -0
- package/dist/server/tools/get-layer-violations.js.map +1 -0
- package/dist/server/tools/get-repo-outline.d.ts +13 -0
- package/dist/server/tools/get-repo-outline.d.ts.map +1 -0
- package/dist/server/tools/get-repo-outline.js +72 -0
- package/dist/server/tools/get-repo-outline.js.map +1 -0
- package/dist/server/tools/get-savings-stats.d.ts +11 -0
- package/dist/server/tools/get-savings-stats.d.ts.map +1 -0
- package/dist/server/tools/get-savings-stats.js +56 -0
- package/dist/server/tools/get-savings-stats.js.map +1 -0
- package/dist/server/tools/get-symbol-source.d.ts +13 -0
- package/dist/server/tools/get-symbol-source.d.ts.map +1 -0
- package/dist/server/tools/get-symbol-source.js +93 -0
- package/dist/server/tools/get-symbol-source.js.map +1 -0
- package/dist/server/tools/index-folder.d.ts +15 -0
- package/dist/server/tools/index-folder.d.ts.map +1 -0
- package/dist/server/tools/index-folder.js +45 -0
- package/dist/server/tools/index-folder.js.map +1 -0
- package/dist/server/tools/index-repo.d.ts +26 -0
- package/dist/server/tools/index-repo.d.ts.map +1 -0
- package/dist/server/tools/index-repo.js +164 -0
- package/dist/server/tools/index-repo.js.map +1 -0
- package/dist/server/tools/list-repos.d.ts +11 -0
- package/dist/server/tools/list-repos.d.ts.map +1 -0
- package/dist/server/tools/list-repos.js +60 -0
- package/dist/server/tools/list-repos.js.map +1 -0
- package/dist/server/tools/resolve-repo.d.ts +11 -0
- package/dist/server/tools/resolve-repo.d.ts.map +1 -0
- package/dist/server/tools/resolve-repo.js +44 -0
- package/dist/server/tools/resolve-repo.js.map +1 -0
- package/dist/server/tools/search-semantic.d.ts +56 -0
- package/dist/server/tools/search-semantic.d.ts.map +1 -0
- package/dist/server/tools/search-semantic.js +187 -0
- package/dist/server/tools/search-semantic.js.map +1 -0
- package/dist/server/tools/search-symbols.d.ts +43 -0
- package/dist/server/tools/search-symbols.d.ts.map +1 -0
- package/dist/server/tools/search-symbols.js +197 -0
- package/dist/server/tools/search-symbols.js.map +1 -0
- package/dist/server/tools/search-text.d.ts +21 -0
- package/dist/server/tools/search-text.d.ts.map +1 -0
- package/dist/server/tools/search-text.js +131 -0
- package/dist/server/tools/search-text.js.map +1 -0
- package/dist/server/transport.d.ts +59 -0
- package/dist/server/transport.d.ts.map +1 -0
- package/dist/server/transport.js +92 -0
- package/dist/server/transport.js.map +1 -0
- package/dist/summarizer/ai-summarizer.d.ts +71 -0
- package/dist/summarizer/ai-summarizer.d.ts.map +1 -0
- package/dist/summarizer/ai-summarizer.js +228 -0
- package/dist/summarizer/ai-summarizer.js.map +1 -0
- package/dist/summarizer/docstring-extractor.d.ts +9 -0
- package/dist/summarizer/docstring-extractor.d.ts.map +1 -0
- package/dist/summarizer/docstring-extractor.js +89 -0
- package/dist/summarizer/docstring-extractor.js.map +1 -0
- package/dist/summarizer/embeddings.d.ts +29 -0
- package/dist/summarizer/embeddings.d.ts.map +1 -0
- package/dist/summarizer/embeddings.js +133 -0
- package/dist/summarizer/embeddings.js.map +1 -0
- package/dist/summarizer/summarizer.d.ts +22 -0
- package/dist/summarizer/summarizer.d.ts.map +1 -0
- package/dist/summarizer/summarizer.js +86 -0
- package/dist/summarizer/summarizer.js.map +1 -0
- package/dist/ui/assets/BlastRadius-ccQ3ktbv.js +1 -0
- package/dist/ui/assets/DependencyGraph-BZV40eAE.css +1 -0
- package/dist/ui/assets/DependencyGraph-Ca84q89b.js +27 -0
- package/dist/ui/assets/NotFound-C1wVKP-6.js +1 -0
- package/dist/ui/assets/RepoDetail-B_8qid2Y.js +1 -0
- package/dist/ui/assets/RepoList-BuPu-ODM.js +1 -0
- package/dist/ui/assets/Search-BzZ9Og8E.js +1 -0
- package/dist/ui/assets/SymbolView-FdpKlzql.js +14 -0
- package/dist/ui/assets/client-BANW_tIp.js +1 -0
- package/dist/ui/assets/index-CnwwQi_S.js +61 -0
- package/dist/ui/assets/index-SS2IXr8I.css +1 -0
- package/dist/ui/assets/repoStore-SbGR6YI6.js +1 -0
- package/dist/ui/assets/useSearch-DHyve22h.js +1 -0
- package/dist/ui/index.html +13 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/grammars/tree-sitter-c.wasm +0 -0
- package/grammars/tree-sitter-cpp.wasm +0 -0
- package/grammars/tree-sitter-csharp.wasm +0 -0
- package/grammars/tree-sitter-dart.wasm +0 -0
- package/grammars/tree-sitter-elixir.wasm +0 -0
- package/grammars/tree-sitter-go.wasm +0 -0
- package/grammars/tree-sitter-haskell.wasm +0 -0
- package/grammars/tree-sitter-java.wasm +0 -0
- package/grammars/tree-sitter-javascript.wasm +0 -0
- package/grammars/tree-sitter-kotlin.wasm +0 -0
- package/grammars/tree-sitter-lua.wasm +0 -0
- package/grammars/tree-sitter-php.wasm +0 -0
- package/grammars/tree-sitter-python.wasm +0 -0
- package/grammars/tree-sitter-r.wasm +0 -0
- package/grammars/tree-sitter-ruby.wasm +0 -0
- package/grammars/tree-sitter-rust.wasm +0 -0
- package/grammars/tree-sitter-scala.wasm +0 -0
- package/grammars/tree-sitter-swift.wasm +0 -0
- package/grammars/tree-sitter-tsx.wasm +0 -0
- package/grammars/tree-sitter-typescript.wasm +0 -0
- package/package.json +104 -0
- package/scripts/check-sqlite.js +41 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { resolve, sep, basename } from 'path';
|
|
2
|
+
import { realpathSync, openSync, readSync, closeSync } from 'fs';
|
|
3
|
+
import { PureContextError } from './errors.js';
|
|
4
|
+
// ─── SecurityError ────────────────────────────────────────────────────────────
|
|
5
|
+
export class SecurityError extends PureContextError {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
// ─── Path validation ──────────────────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Resolve `filePath` relative to `projectRoot` and verify it stays within the
|
|
15
|
+
* project root. Throws `SecurityError('path_traversal')` on escape attempts.
|
|
16
|
+
* Returns the absolute resolved path.
|
|
17
|
+
*/
|
|
18
|
+
export function validatePath(filePath, projectRoot) {
|
|
19
|
+
const resolvedRoot = resolve(projectRoot);
|
|
20
|
+
const resolvedFile = resolve(projectRoot, filePath);
|
|
21
|
+
if (resolvedFile !== resolvedRoot &&
|
|
22
|
+
!resolvedFile.startsWith(resolvedRoot + sep)) {
|
|
23
|
+
throw new SecurityError('path_traversal', `Path traversal detected: "${filePath}"`);
|
|
24
|
+
}
|
|
25
|
+
return resolvedFile;
|
|
26
|
+
}
|
|
27
|
+
// ─── Symlink check ────────────────────────────────────────────────────────────
|
|
28
|
+
/**
|
|
29
|
+
* Verify that `resolvedPath` does not escape `projectRoot` after all symlinks
|
|
30
|
+
* are resolved. Throws `SecurityError('symlink_escape')` if it does.
|
|
31
|
+
* No-ops when the path does not exist (not yet created files are not a threat).
|
|
32
|
+
*/
|
|
33
|
+
export function checkSymlinkEscape(resolvedPath, projectRoot) {
|
|
34
|
+
// Resolve symlinks in the root itself (e.g. macOS /tmp → /private/tmp)
|
|
35
|
+
let realRoot;
|
|
36
|
+
try {
|
|
37
|
+
realRoot = realpathSync(projectRoot);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
realRoot = resolve(projectRoot);
|
|
41
|
+
}
|
|
42
|
+
let realPath;
|
|
43
|
+
try {
|
|
44
|
+
realPath = realpathSync(resolvedPath);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return; // File doesn't exist — nothing to check
|
|
48
|
+
}
|
|
49
|
+
if (realPath !== realRoot &&
|
|
50
|
+
!realPath.startsWith(realRoot + sep)) {
|
|
51
|
+
throw new SecurityError('symlink_escape', `Symlink resolves outside project root: "${resolvedPath}"`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// ─── Secret-file detection ────────────────────────────────────────────────────
|
|
55
|
+
const SECRET_PATTERNS = [
|
|
56
|
+
/^\.env$/i,
|
|
57
|
+
/^\.env\./i,
|
|
58
|
+
/\.pem$/i,
|
|
59
|
+
/\.key$/i,
|
|
60
|
+
/\.p12$/i,
|
|
61
|
+
/\.pfx$/i,
|
|
62
|
+
/\.crt$/i,
|
|
63
|
+
/\.cer$/i,
|
|
64
|
+
/^id_rsa(\.pub)?$/i,
|
|
65
|
+
/^id_ed25519(\.pub)?$/i,
|
|
66
|
+
/^id_ecdsa(\.pub)?$/i,
|
|
67
|
+
/^id_dsa(\.pub)?$/i,
|
|
68
|
+
/^credentials\.(json|yaml|yml)$/i,
|
|
69
|
+
/^secrets\.(json|yaml|yml)$/i,
|
|
70
|
+
/^serviceaccountkey.*\.json$/i,
|
|
71
|
+
/.*-service-account\.json$/i,
|
|
72
|
+
/\.token$/i,
|
|
73
|
+
/\.secret$/i,
|
|
74
|
+
];
|
|
75
|
+
/**
|
|
76
|
+
* Returns `true` when the file name matches a known credential/secret pattern
|
|
77
|
+
* and should be excluded from indexing. Case-insensitive.
|
|
78
|
+
*/
|
|
79
|
+
export function isSecretFile(filePath) {
|
|
80
|
+
const name = basename(filePath);
|
|
81
|
+
return SECRET_PATTERNS.some((re) => re.test(name));
|
|
82
|
+
}
|
|
83
|
+
// ─── Binary detection ─────────────────────────────────────────────────────────
|
|
84
|
+
const BINARY_PEEK_BYTES = 8192;
|
|
85
|
+
/**
|
|
86
|
+
* Returns `true` when the content buffer contains a null byte, which is a
|
|
87
|
+
* reliable indicator of binary (non-text) content. Only the first 8192 bytes
|
|
88
|
+
* are examined.
|
|
89
|
+
*/
|
|
90
|
+
export function isBinaryFile(content) {
|
|
91
|
+
const len = Math.min(content.length, BINARY_PEEK_BYTES);
|
|
92
|
+
for (let i = 0; i < len; i++) {
|
|
93
|
+
if (content[i] === 0)
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Read up to `BINARY_PEEK_BYTES` from the beginning of a file for binary
|
|
100
|
+
* detection without loading the whole file into memory.
|
|
101
|
+
* Returns an empty buffer on read failure.
|
|
102
|
+
*/
|
|
103
|
+
export function peekFileContent(absPath) {
|
|
104
|
+
const buf = Buffer.allocUnsafe(BINARY_PEEK_BYTES);
|
|
105
|
+
let fd = -1;
|
|
106
|
+
try {
|
|
107
|
+
fd = openSync(absPath, 'r');
|
|
108
|
+
const bytesRead = readSync(fd, buf, 0, BINARY_PEEK_BYTES, 0);
|
|
109
|
+
return buf.subarray(0, bytesRead);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return Buffer.alloc(0);
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
if (fd >= 0) {
|
|
116
|
+
try {
|
|
117
|
+
closeSync(fd);
|
|
118
|
+
}
|
|
119
|
+
catch { /* ignore */ }
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// ─── File-size check ──────────────────────────────────────────────────────────
|
|
124
|
+
export const DEFAULT_MAX_FILE_BYTES = 1_048_576; // 1 MB
|
|
125
|
+
/**
|
|
126
|
+
* Throws `SecurityError('file_too_large')` when `size` exceeds `maxBytes`.
|
|
127
|
+
*/
|
|
128
|
+
export function checkFileSize(size, maxBytes = DEFAULT_MAX_FILE_BYTES) {
|
|
129
|
+
if (size > maxBytes) {
|
|
130
|
+
throw new SecurityError('file_too_large', `File size ${size} bytes exceeds limit of ${maxBytes} bytes`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/core/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface TelemetryEvent {
|
|
2
|
+
event: string;
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Returns true when telemetry is enabled in config.
|
|
7
|
+
* Synchronous — config is loaded at startup.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isTelemetryEnabled(): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Track an anonymous telemetry event.
|
|
12
|
+
*
|
|
13
|
+
* When disabled: logs at debug level what would have been sent, returns immediately.
|
|
14
|
+
* When enabled: appends to ~/.purecontext/telemetry.jsonl, then POSTs to the
|
|
15
|
+
* configured endpoint. Network errors are silently discarded.
|
|
16
|
+
* Never throws.
|
|
17
|
+
*/
|
|
18
|
+
export declare function track(event: TelemetryEvent): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/core/telemetry.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAmCD;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAM5C;AAED;;;;;;;GAOG;AACH,wBAAsB,KAAK,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA0ChE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
import { appendFileSync, mkdirSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir, platform } from 'os';
|
|
5
|
+
import { logger } from './logger.js';
|
|
6
|
+
import { getConfig } from '../config/config-loader.js';
|
|
7
|
+
import { VERSION } from '../version.js';
|
|
8
|
+
// ─── Session ID ───────────────────────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* Random UUID generated once per process start.
|
|
11
|
+
* Not persisted — no cross-session tracking.
|
|
12
|
+
*/
|
|
13
|
+
const SESSION_ID = randomUUID();
|
|
14
|
+
// ─── PII blocklist ────────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Keys that must never appear in a telemetry payload.
|
|
17
|
+
* If accidentally passed, they are silently dropped.
|
|
18
|
+
*/
|
|
19
|
+
const PII_KEYS = new Set([
|
|
20
|
+
'filePath', 'path', 'rootPath', 'repoPath', 'clonePath',
|
|
21
|
+
'name', 'symbolName', 'repoName', 'source', 'content',
|
|
22
|
+
'signature', 'summary', 'importedNames', 'specifier',
|
|
23
|
+
]);
|
|
24
|
+
function sanitize(event) {
|
|
25
|
+
const safe = {};
|
|
26
|
+
for (const [k, v] of Object.entries(event)) {
|
|
27
|
+
if (PII_KEYS.has(k))
|
|
28
|
+
continue;
|
|
29
|
+
// Drop string values that look like file-system paths
|
|
30
|
+
if (typeof v === 'string' && (v.includes('/') || v.includes('\\')))
|
|
31
|
+
continue;
|
|
32
|
+
safe[k] = v;
|
|
33
|
+
}
|
|
34
|
+
return safe;
|
|
35
|
+
}
|
|
36
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Returns true when telemetry is enabled in config.
|
|
39
|
+
* Synchronous — config is loaded at startup.
|
|
40
|
+
*/
|
|
41
|
+
export function isTelemetryEnabled() {
|
|
42
|
+
try {
|
|
43
|
+
return getConfig().telemetry.enabled;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Track an anonymous telemetry event.
|
|
51
|
+
*
|
|
52
|
+
* When disabled: logs at debug level what would have been sent, returns immediately.
|
|
53
|
+
* When enabled: appends to ~/.purecontext/telemetry.jsonl, then POSTs to the
|
|
54
|
+
* configured endpoint. Network errors are silently discarded.
|
|
55
|
+
* Never throws.
|
|
56
|
+
*/
|
|
57
|
+
export async function track(event) {
|
|
58
|
+
const payload = sanitize({
|
|
59
|
+
...event,
|
|
60
|
+
version: VERSION,
|
|
61
|
+
nodeVersion: process.version.replace(/^v/, ''),
|
|
62
|
+
platform: platform(),
|
|
63
|
+
sessionId: SESSION_ID,
|
|
64
|
+
timestamp: new Date().toISOString(),
|
|
65
|
+
});
|
|
66
|
+
if (!isTelemetryEnabled()) {
|
|
67
|
+
logger.debug(`Telemetry (disabled) — would have sent: ${JSON.stringify(payload)}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Always write to local JSONL log so the user can inspect what was sent
|
|
71
|
+
try {
|
|
72
|
+
const logDir = join(homedir(), '.purecontext');
|
|
73
|
+
mkdirSync(logDir, { recursive: true });
|
|
74
|
+
appendFileSync(join(logDir, 'telemetry.jsonl'), JSON.stringify(payload) + '\n', 'utf8');
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Non-fatal — proceed to network send regardless
|
|
78
|
+
}
|
|
79
|
+
// Send to configured endpoint (best-effort)
|
|
80
|
+
let endpoint;
|
|
81
|
+
try {
|
|
82
|
+
endpoint = getConfig().telemetry.endpoint ?? DEFAULT_TELEMETRY_ENDPOINT;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
endpoint = DEFAULT_TELEMETRY_ENDPOINT;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
await fetch(endpoint, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
headers: { 'Content-Type': 'application/json' },
|
|
91
|
+
body: JSON.stringify(payload),
|
|
92
|
+
signal: AbortSignal.timeout(5000),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Silently discard network errors — telemetry must never affect the user
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
100
|
+
const DEFAULT_TELEMETRY_ENDPOINT = 'https://telemetry.purecontext.dev/v1/event';
|
|
101
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/core/telemetry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TenantContext — identifies the current tenant for a request.
|
|
3
|
+
*
|
|
4
|
+
* In single-tenant (stdio) mode, the context is always DEFAULT_TENANT_CONTEXT.
|
|
5
|
+
* In multi-tenant HTTP mode, the context is derived from the authenticated API key
|
|
6
|
+
* and attached to each request before calling any service method.
|
|
7
|
+
*
|
|
8
|
+
* All data-store operations accept an optional TenantContext. When provided,
|
|
9
|
+
* queries are scoped with `AND tenant_id = ?` to prevent cross-tenant data access.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEFAULT_TENANT_ID = "local";
|
|
12
|
+
export interface TenantContext {
|
|
13
|
+
/** Identifies the owning tenant for data isolation. */
|
|
14
|
+
tenantId: string;
|
|
15
|
+
/** Permissions granted to the current request (from API key). */
|
|
16
|
+
permissions?: string[];
|
|
17
|
+
/** Rate limit tier identifier (from API key). */
|
|
18
|
+
rateLimitTier?: string;
|
|
19
|
+
}
|
|
20
|
+
/** Context used in single-tenant / local CLI mode — no auth, no isolation. */
|
|
21
|
+
export declare const DEFAULT_TENANT_CONTEXT: TenantContext;
|
|
22
|
+
//# sourceMappingURL=tenant-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-context.d.ts","sourceRoot":"","sources":["../../src/core/tenant-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,EAAE,aAEpC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TenantContext — identifies the current tenant for a request.
|
|
3
|
+
*
|
|
4
|
+
* In single-tenant (stdio) mode, the context is always DEFAULT_TENANT_CONTEXT.
|
|
5
|
+
* In multi-tenant HTTP mode, the context is derived from the authenticated API key
|
|
6
|
+
* and attached to each request before calling any service method.
|
|
7
|
+
*
|
|
8
|
+
* All data-store operations accept an optional TenantContext. When provided,
|
|
9
|
+
* queries are scoped with `AND tenant_id = ?` to prevent cross-tenant data access.
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_TENANT_ID = 'local';
|
|
12
|
+
/** Context used in single-tenant / local CLI mode — no auth, no isolation. */
|
|
13
|
+
export const DEFAULT_TENANT_CONTEXT = {
|
|
14
|
+
tenantId: DEFAULT_TENANT_ID,
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=tenant-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-context.js","sourceRoot":"","sources":["../../src/core/tenant-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAWzC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,QAAQ,EAAE,iBAAiB;CAC5B,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const BYTES_PER_TOKEN = 4;
|
|
2
|
+
export interface CostEstimates {
|
|
3
|
+
cost_avoided: Record<string, number>;
|
|
4
|
+
total_cost_avoided: Record<string, number>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Estimate tokens saved by comparing raw file size vs response size.
|
|
8
|
+
* Returns 0 if response is larger than raw (never negative).
|
|
9
|
+
*/
|
|
10
|
+
export declare function estimateSavings(rawBytes: number, responseBytes: number): number;
|
|
11
|
+
/**
|
|
12
|
+
* Add tokensSaved to the running total. Flushes to disk every FLUSH_INTERVAL calls.
|
|
13
|
+
* Returns the new cumulative total.
|
|
14
|
+
*/
|
|
15
|
+
export declare function recordSavings(tokensSaved: number): number;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the current cumulative total without modifying state.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getTotalSaved(): number;
|
|
20
|
+
/**
|
|
21
|
+
* Compute cost avoided in USD for a single call and cumulatively,
|
|
22
|
+
* based on model pricing tiers. Values rounded to 4 decimal places.
|
|
23
|
+
*/
|
|
24
|
+
export declare function costAvoided(tokensSaved: number, totalTokensSaved: number): CostEstimates;
|
|
25
|
+
/**
|
|
26
|
+
* Resets the cumulative total to zero, both in-memory and on disk.
|
|
27
|
+
* Returns the previous total before the reset.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resetSavings(): number;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the timestamp when the current session started (first recordSavings() call).
|
|
32
|
+
* Returns the current time if recordSavings() has never been called this session.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getSessionStart(): Date;
|
|
35
|
+
/**
|
|
36
|
+
* Reset in-memory state. For testing only.
|
|
37
|
+
*/
|
|
38
|
+
export declare function _resetForTesting(): void;
|
|
39
|
+
//# sourceMappingURL=token-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-tracker.d.ts","sourceRoot":"","sources":["../../src/core/token-tracker.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,eAAe,IAAI,CAAC;AAKjC,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAsED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAiBzD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,aAAa,CAUxF;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAqBrC;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAID;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAOvC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { loadSavings, saveSavings } from './db/savings-store.js';
|
|
2
|
+
import { logger } from './logger.js';
|
|
3
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
4
|
+
export const BYTES_PER_TOKEN = 4;
|
|
5
|
+
const FLUSH_INTERVAL = 5;
|
|
6
|
+
// ─── Pricing tiers (USD per million input tokens) ─────────────────────────────
|
|
7
|
+
const PRICING_TIERS = {
|
|
8
|
+
claude_opus_4: 15.0,
|
|
9
|
+
claude_sonnet_4: 3.0,
|
|
10
|
+
claude_haiku_4: 0.8,
|
|
11
|
+
gpt4o: 2.5,
|
|
12
|
+
gpt4o_mini: 0.15,
|
|
13
|
+
};
|
|
14
|
+
// ─── In-memory state ──────────────────────────────────────────────────────────
|
|
15
|
+
class _State {
|
|
16
|
+
total = 0;
|
|
17
|
+
unflushed = 0;
|
|
18
|
+
callCount = 0;
|
|
19
|
+
loaded = false;
|
|
20
|
+
anonId = '';
|
|
21
|
+
sessionStart = null;
|
|
22
|
+
}
|
|
23
|
+
const state = new _State();
|
|
24
|
+
let handlersRegistered = false;
|
|
25
|
+
// ─── Internal helpers ─────────────────────────────────────────────────────────
|
|
26
|
+
function ensureLoaded() {
|
|
27
|
+
if (state.loaded)
|
|
28
|
+
return;
|
|
29
|
+
const data = loadSavings();
|
|
30
|
+
state.total = data.total_tokens_saved;
|
|
31
|
+
state.anonId = data.anon_id;
|
|
32
|
+
state.loaded = true;
|
|
33
|
+
}
|
|
34
|
+
function flush() {
|
|
35
|
+
if (state.unflushed === 0)
|
|
36
|
+
return;
|
|
37
|
+
try {
|
|
38
|
+
saveSavings({
|
|
39
|
+
total_tokens_saved: state.total,
|
|
40
|
+
anon_id: state.anonId,
|
|
41
|
+
last_updated: new Date().toISOString(),
|
|
42
|
+
});
|
|
43
|
+
state.unflushed = 0;
|
|
44
|
+
state.callCount = 0;
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
logger.warn('Failed to flush token savings to disk', { error: String(err) });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function registerExitHandlers() {
|
|
51
|
+
if (handlersRegistered)
|
|
52
|
+
return;
|
|
53
|
+
handlersRegistered = true;
|
|
54
|
+
process.on('exit', () => flush());
|
|
55
|
+
process.on('SIGTERM', () => {
|
|
56
|
+
flush();
|
|
57
|
+
process.exit(0);
|
|
58
|
+
});
|
|
59
|
+
process.on('SIGINT', () => {
|
|
60
|
+
flush();
|
|
61
|
+
process.exit(0);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
65
|
+
/**
|
|
66
|
+
* Estimate tokens saved by comparing raw file size vs response size.
|
|
67
|
+
* Returns 0 if response is larger than raw (never negative).
|
|
68
|
+
*/
|
|
69
|
+
export function estimateSavings(rawBytes, responseBytes) {
|
|
70
|
+
return Math.max(0, Math.floor((rawBytes - responseBytes) / BYTES_PER_TOKEN));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Add tokensSaved to the running total. Flushes to disk every FLUSH_INTERVAL calls.
|
|
74
|
+
* Returns the new cumulative total.
|
|
75
|
+
*/
|
|
76
|
+
export function recordSavings(tokensSaved) {
|
|
77
|
+
ensureLoaded();
|
|
78
|
+
registerExitHandlers();
|
|
79
|
+
if (state.sessionStart === null) {
|
|
80
|
+
state.sessionStart = new Date();
|
|
81
|
+
}
|
|
82
|
+
state.total += tokensSaved;
|
|
83
|
+
state.unflushed += tokensSaved;
|
|
84
|
+
state.callCount++;
|
|
85
|
+
if (state.callCount >= FLUSH_INTERVAL) {
|
|
86
|
+
flush();
|
|
87
|
+
}
|
|
88
|
+
return state.total;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Returns the current cumulative total without modifying state.
|
|
92
|
+
*/
|
|
93
|
+
export function getTotalSaved() {
|
|
94
|
+
ensureLoaded();
|
|
95
|
+
return state.total;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Compute cost avoided in USD for a single call and cumulatively,
|
|
99
|
+
* based on model pricing tiers. Values rounded to 4 decimal places.
|
|
100
|
+
*/
|
|
101
|
+
export function costAvoided(tokensSaved, totalTokensSaved) {
|
|
102
|
+
const cost_avoided = {};
|
|
103
|
+
const total_cost_avoided = {};
|
|
104
|
+
for (const [model, ratePerMillion] of Object.entries(PRICING_TIERS)) {
|
|
105
|
+
cost_avoided[model] = parseFloat((tokensSaved * ratePerMillion / 1_000_000).toFixed(4));
|
|
106
|
+
total_cost_avoided[model] = parseFloat((totalTokensSaved * ratePerMillion / 1_000_000).toFixed(4));
|
|
107
|
+
}
|
|
108
|
+
return { cost_avoided, total_cost_avoided };
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Resets the cumulative total to zero, both in-memory and on disk.
|
|
112
|
+
* Returns the previous total before the reset.
|
|
113
|
+
*/
|
|
114
|
+
export function resetSavings() {
|
|
115
|
+
ensureLoaded();
|
|
116
|
+
const previous = state.total;
|
|
117
|
+
state.total = 0;
|
|
118
|
+
state.unflushed = 0;
|
|
119
|
+
state.callCount = 0;
|
|
120
|
+
state.sessionStart = null;
|
|
121
|
+
// Write zeroed state to disk immediately
|
|
122
|
+
try {
|
|
123
|
+
saveSavings({
|
|
124
|
+
total_tokens_saved: 0,
|
|
125
|
+
anon_id: state.anonId,
|
|
126
|
+
last_updated: new Date().toISOString(),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
logger.warn('Failed to persist savings reset to disk', { error: String(err) });
|
|
131
|
+
}
|
|
132
|
+
return previous;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Returns the timestamp when the current session started (first recordSavings() call).
|
|
136
|
+
* Returns the current time if recordSavings() has never been called this session.
|
|
137
|
+
*/
|
|
138
|
+
export function getSessionStart() {
|
|
139
|
+
return state.sessionStart ?? new Date();
|
|
140
|
+
}
|
|
141
|
+
// ─── Test utilities ───────────────────────────────────────────────────────────
|
|
142
|
+
/**
|
|
143
|
+
* Reset in-memory state. For testing only.
|
|
144
|
+
*/
|
|
145
|
+
export function _resetForTesting() {
|
|
146
|
+
state.total = 0;
|
|
147
|
+
state.unflushed = 0;
|
|
148
|
+
state.callCount = 0;
|
|
149
|
+
state.loaded = false;
|
|
150
|
+
state.anonId = '';
|
|
151
|
+
state.sessionStart = null;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=token-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-tracker.js","sourceRoot":"","sources":["../../src/core/token-tracker.ts"],"names":[],"mappings":"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"}
|