enpilink 1.0.2
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 +289 -0
- package/bin/run.js +5 -0
- package/dist/cli/build-helpers.d.ts +8 -0
- package/dist/cli/build-helpers.js +105 -0
- package/dist/cli/build-helpers.js.map +1 -0
- package/dist/cli/build-helpers.test.d.ts +1 -0
- package/dist/cli/build-helpers.test.js +100 -0
- package/dist/cli/build-helpers.test.js.map +1 -0
- package/dist/cli/detect-port.d.ts +18 -0
- package/dist/cli/detect-port.js +50 -0
- package/dist/cli/detect-port.js.map +1 -0
- package/dist/cli/ensure-ssh-key.d.ts +17 -0
- package/dist/cli/ensure-ssh-key.js +45 -0
- package/dist/cli/ensure-ssh-key.js.map +1 -0
- package/dist/cli/ensure-ssh-key.test.d.ts +1 -0
- package/dist/cli/ensure-ssh-key.test.js +68 -0
- package/dist/cli/ensure-ssh-key.test.js.map +1 -0
- package/dist/cli/header.d.ts +4 -0
- package/dist/cli/header.js +6 -0
- package/dist/cli/header.js.map +1 -0
- package/dist/cli/resolve-views-dir.d.ts +1 -0
- package/dist/cli/resolve-views-dir.js +17 -0
- package/dist/cli/resolve-views-dir.js.map +1 -0
- package/dist/cli/run-command.d.ts +2 -0
- package/dist/cli/run-command.js +43 -0
- package/dist/cli/run-command.js.map +1 -0
- package/dist/cli/telemetry.d.ts +14 -0
- package/dist/cli/telemetry.js +24 -0
- package/dist/cli/telemetry.js.map +1 -0
- package/dist/cli/tunnel-control-server.d.ts +11 -0
- package/dist/cli/tunnel-control-server.js +35 -0
- package/dist/cli/tunnel-control-server.js.map +1 -0
- package/dist/cli/tunnel-control-server.test.d.ts +1 -0
- package/dist/cli/tunnel-control-server.test.js +39 -0
- package/dist/cli/tunnel-control-server.test.js.map +1 -0
- package/dist/cli/tunnel-handler.d.ts +3 -0
- package/dist/cli/tunnel-handler.js +48 -0
- package/dist/cli/tunnel-handler.js.map +1 -0
- package/dist/cli/tunnel-handler.test.d.ts +1 -0
- package/dist/cli/tunnel-handler.test.js +107 -0
- package/dist/cli/tunnel-handler.test.js.map +1 -0
- package/dist/cli/tunnel-providers/index.d.ts +5 -0
- package/dist/cli/tunnel-providers/index.js +5 -0
- package/dist/cli/tunnel-providers/index.js.map +1 -0
- package/dist/cli/tunnel-providers/srv-us.d.ts +18 -0
- package/dist/cli/tunnel-providers/srv-us.js +66 -0
- package/dist/cli/tunnel-providers/srv-us.js.map +1 -0
- package/dist/cli/tunnel-providers/srv-us.test.d.ts +1 -0
- package/dist/cli/tunnel-providers/srv-us.test.js +74 -0
- package/dist/cli/tunnel-providers/srv-us.test.js.map +1 -0
- package/dist/cli/tunnel-providers/types.d.ts +49 -0
- package/dist/cli/tunnel-providers/types.js +2 -0
- package/dist/cli/tunnel-providers/types.js.map +1 -0
- package/dist/cli/tunnel.d.ts +75 -0
- package/dist/cli/tunnel.js +254 -0
- package/dist/cli/tunnel.js.map +1 -0
- package/dist/cli/tunnel.test.d.ts +1 -0
- package/dist/cli/tunnel.test.js +255 -0
- package/dist/cli/tunnel.test.js.map +1 -0
- package/dist/cli/types.d.ts +5 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/use-execute-steps.d.ts +11 -0
- package/dist/cli/use-execute-steps.js +36 -0
- package/dist/cli/use-execute-steps.js.map +1 -0
- package/dist/cli/use-messages.d.ts +3 -0
- package/dist/cli/use-messages.js +11 -0
- package/dist/cli/use-messages.js.map +1 -0
- package/dist/cli/use-nodemon.d.ts +2 -0
- package/dist/cli/use-nodemon.js +73 -0
- package/dist/cli/use-nodemon.js.map +1 -0
- package/dist/cli/use-open-browser.d.ts +1 -0
- package/dist/cli/use-open-browser.js +44 -0
- package/dist/cli/use-open-browser.js.map +1 -0
- package/dist/cli/use-open-tunnel-browser.d.ts +6 -0
- package/dist/cli/use-open-tunnel-browser.js +19 -0
- package/dist/cli/use-open-tunnel-browser.js.map +1 -0
- package/dist/cli/use-tunnel.d.ts +17 -0
- package/dist/cli/use-tunnel.js +131 -0
- package/dist/cli/use-tunnel.js.map +1 -0
- package/dist/cli/use-typescript-check.d.ts +9 -0
- package/dist/cli/use-typescript-check.js +94 -0
- package/dist/cli/use-typescript-check.js.map +1 -0
- package/dist/commands/build.d.ts +8 -0
- package/dist/commands/build.js +97 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/create.d.ts +9 -0
- package/dist/commands/create.js +30 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dev.d.ts +13 -0
- package/dist/commands/dev.js +112 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/start.d.ts +10 -0
- package/dist/commands/start.js +76 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/telemetry/disable.d.ts +5 -0
- package/dist/commands/telemetry/disable.js +12 -0
- package/dist/commands/telemetry/disable.js.map +1 -0
- package/dist/commands/telemetry/enable.d.ts +5 -0
- package/dist/commands/telemetry/enable.js +12 -0
- package/dist/commands/telemetry/enable.js.map +1 -0
- package/dist/commands/telemetry/status.d.ts +5 -0
- package/dist/commands/telemetry/status.js +12 -0
- package/dist/commands/telemetry/status.js.map +1 -0
- package/dist/server/admin.d.ts +79 -0
- package/dist/server/admin.js +239 -0
- package/dist/server/admin.js.map +1 -0
- package/dist/server/admin.test.d.ts +1 -0
- package/dist/server/admin.test.js +226 -0
- package/dist/server/admin.test.js.map +1 -0
- package/dist/server/analytics.d.ts +60 -0
- package/dist/server/analytics.js +168 -0
- package/dist/server/analytics.js.map +1 -0
- package/dist/server/analytics.test.d.ts +1 -0
- package/dist/server/analytics.test.js +179 -0
- package/dist/server/analytics.test.js.map +1 -0
- package/dist/server/asset-base-url-transform-plugin.d.ts +11 -0
- package/dist/server/asset-base-url-transform-plugin.js +48 -0
- package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
- package/dist/server/asset-base-url-transform-plugin.test.d.ts +1 -0
- package/dist/server/asset-base-url-transform-plugin.test.js +134 -0
- package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
- package/dist/server/auth.d.ts +20 -0
- package/dist/server/auth.js +28 -0
- package/dist/server/auth.js.map +1 -0
- package/dist/server/build-manifest.test.d.ts +1 -0
- package/dist/server/build-manifest.test.js +27 -0
- package/dist/server/build-manifest.test.js.map +1 -0
- package/dist/server/config/config.test.d.ts +1 -0
- package/dist/server/config/config.test.js +214 -0
- package/dist/server/config/config.test.js.map +1 -0
- package/dist/server/config/index.d.ts +3 -0
- package/dist/server/config/index.js +4 -0
- package/dist/server/config/index.js.map +1 -0
- package/dist/server/config/resolve.d.ts +73 -0
- package/dist/server/config/resolve.js +167 -0
- package/dist/server/config/resolve.js.map +1 -0
- package/dist/server/config/router.d.ts +23 -0
- package/dist/server/config/router.js +119 -0
- package/dist/server/config/router.js.map +1 -0
- package/dist/server/config/schema.d.ts +78 -0
- package/dist/server/config/schema.js +158 -0
- package/dist/server/config/schema.js.map +1 -0
- package/dist/server/content-helpers.d.ts +67 -0
- package/dist/server/content-helpers.js +79 -0
- package/dist/server/content-helpers.js.map +1 -0
- package/dist/server/content-helpers.test.d.ts +1 -0
- package/dist/server/content-helpers.test.js +70 -0
- package/dist/server/content-helpers.test.js.map +1 -0
- package/dist/server/express.d.ts +11 -0
- package/dist/server/express.js +129 -0
- package/dist/server/express.js.map +1 -0
- package/dist/server/express.test.d.ts +1 -0
- package/dist/server/express.test.js +464 -0
- package/dist/server/express.test.js.map +1 -0
- package/dist/server/file-ref.d.ts +28 -0
- package/dist/server/file-ref.js +27 -0
- package/dist/server/file-ref.js.map +1 -0
- package/dist/server/index.d.ts +17 -0
- package/dist/server/index.js +14 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/inferUtilityTypes.d.ts +64 -0
- package/dist/server/inferUtilityTypes.js +2 -0
- package/dist/server/inferUtilityTypes.js.map +1 -0
- package/dist/server/log-sink.d.ts +16 -0
- package/dist/server/log-sink.js +66 -0
- package/dist/server/log-sink.js.map +1 -0
- package/dist/server/metric.d.ts +12 -0
- package/dist/server/metric.js +13 -0
- package/dist/server/metric.js.map +1 -0
- package/dist/server/middleware.d.ts +137 -0
- package/dist/server/middleware.js +93 -0
- package/dist/server/middleware.js.map +1 -0
- package/dist/server/middleware.test-d.d.ts +1 -0
- package/dist/server/middleware.test-d.js +75 -0
- package/dist/server/middleware.test-d.js.map +1 -0
- package/dist/server/middleware.test.d.ts +1 -0
- package/dist/server/middleware.test.js +493 -0
- package/dist/server/middleware.test.js.map +1 -0
- package/dist/server/mock-seed.d.ts +62 -0
- package/dist/server/mock-seed.js +251 -0
- package/dist/server/mock-seed.js.map +1 -0
- package/dist/server/mock-seed.test.d.ts +1 -0
- package/dist/server/mock-seed.test.js +122 -0
- package/dist/server/mock-seed.test.js.map +1 -0
- package/dist/server/observability.d.ts +149 -0
- package/dist/server/observability.js +340 -0
- package/dist/server/observability.js.map +1 -0
- package/dist/server/observability.test.d.ts +1 -0
- package/dist/server/observability.test.js +251 -0
- package/dist/server/observability.test.js.map +1 -0
- package/dist/server/otel.d.ts +45 -0
- package/dist/server/otel.js +117 -0
- package/dist/server/otel.js.map +1 -0
- package/dist/server/otel.test.d.ts +1 -0
- package/dist/server/otel.test.js +122 -0
- package/dist/server/otel.test.js.map +1 -0
- package/dist/server/server.d.ts +422 -0
- package/dist/server/server.js +684 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/storage/index.d.ts +23 -0
- package/dist/server/storage/index.js +46 -0
- package/dist/server/storage/index.js.map +1 -0
- package/dist/server/storage/memory.d.ts +30 -0
- package/dist/server/storage/memory.js +98 -0
- package/dist/server/storage/memory.js.map +1 -0
- package/dist/server/storage/memory.test.d.ts +1 -0
- package/dist/server/storage/memory.test.js +81 -0
- package/dist/server/storage/memory.test.js.map +1 -0
- package/dist/server/storage/postgres.d.ts +65 -0
- package/dist/server/storage/postgres.js +242 -0
- package/dist/server/storage/postgres.js.map +1 -0
- package/dist/server/storage/postgres.test.d.ts +1 -0
- package/dist/server/storage/postgres.test.js +182 -0
- package/dist/server/storage/postgres.test.js.map +1 -0
- package/dist/server/storage/sqlite.d.ts +33 -0
- package/dist/server/storage/sqlite.js +250 -0
- package/dist/server/storage/sqlite.js.map +1 -0
- package/dist/server/storage/sqlite.test.d.ts +1 -0
- package/dist/server/storage/sqlite.test.js +133 -0
- package/dist/server/storage/sqlite.test.js.map +1 -0
- package/dist/server/storage/types.d.ts +119 -0
- package/dist/server/storage/types.js +11 -0
- package/dist/server/storage/types.js.map +1 -0
- package/dist/server/templateHelper.d.ts +16 -0
- package/dist/server/templateHelper.js +11 -0
- package/dist/server/templateHelper.js.map +1 -0
- package/dist/server/templates.generated.d.ts +4 -0
- package/dist/server/templates.generated.js +47 -0
- package/dist/server/templates.generated.js.map +1 -0
- package/dist/server/tunnel-proxy-router.d.ts +7 -0
- package/dist/server/tunnel-proxy-router.js +110 -0
- package/dist/server/tunnel-proxy-router.js.map +1 -0
- package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
- package/dist/server/tunnel-proxy-router.test.js +229 -0
- package/dist/server/tunnel-proxy-router.test.js.map +1 -0
- package/dist/server/viewsDevServer.d.ts +14 -0
- package/dist/server/viewsDevServer.js +45 -0
- package/dist/server/viewsDevServer.js.map +1 -0
- package/dist/test/utils.d.ts +127 -0
- package/dist/test/utils.js +247 -0
- package/dist/test/utils.js.map +1 -0
- package/dist/test/view.test.d.ts +1 -0
- package/dist/test/view.test.js +568 -0
- package/dist/test/view.test.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/web/bridges/apps-sdk/adaptor.d.ts +54 -0
- package/dist/web/bridges/apps-sdk/adaptor.js +164 -0
- package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -0
- package/dist/web/bridges/apps-sdk/bridge.d.ts +11 -0
- package/dist/web/bridges/apps-sdk/bridge.js +47 -0
- package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
- package/dist/web/bridges/apps-sdk/index.d.ts +5 -0
- package/dist/web/bridges/apps-sdk/index.js +5 -0
- package/dist/web/bridges/apps-sdk/index.js.map +1 -0
- package/dist/web/bridges/apps-sdk/types.d.ts +147 -0
- package/dist/web/bridges/apps-sdk/types.js +10 -0
- package/dist/web/bridges/apps-sdk/types.js.map +1 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +13 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +18 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
- package/dist/web/bridges/get-adaptor.d.ts +9 -0
- package/dist/web/bridges/get-adaptor.js +15 -0
- package/dist/web/bridges/get-adaptor.js.map +1 -0
- package/dist/web/bridges/index.d.ts +5 -0
- package/dist/web/bridges/index.js +6 -0
- package/dist/web/bridges/index.js.map +1 -0
- package/dist/web/bridges/mcp-app/adaptor.d.ts +81 -0
- package/dist/web/bridges/mcp-app/adaptor.js +346 -0
- package/dist/web/bridges/mcp-app/adaptor.js.map +1 -0
- package/dist/web/bridges/mcp-app/bridge.d.ts +28 -0
- package/dist/web/bridges/mcp-app/bridge.js +124 -0
- package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
- package/dist/web/bridges/mcp-app/index.d.ts +4 -0
- package/dist/web/bridges/mcp-app/index.js +4 -0
- package/dist/web/bridges/mcp-app/index.js.map +1 -0
- package/dist/web/bridges/mcp-app/types.d.ts +8 -0
- package/dist/web/bridges/mcp-app/types.js +2 -0
- package/dist/web/bridges/mcp-app/types.js.map +1 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +19 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +19 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.d.ts +1 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +26 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
- package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
- package/dist/web/bridges/mcp-app/view-tools.test.js +144 -0
- package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
- package/dist/web/bridges/types.d.ts +243 -0
- package/dist/web/bridges/types.js +2 -0
- package/dist/web/bridges/types.js.map +1 -0
- package/dist/web/bridges/use-host-context.d.ts +7 -0
- package/dist/web/bridges/use-host-context.js +13 -0
- package/dist/web/bridges/use-host-context.js.map +1 -0
- package/dist/web/components/modal-provider.d.ts +4 -0
- package/dist/web/components/modal-provider.js +45 -0
- package/dist/web/components/modal-provider.js.map +1 -0
- package/dist/web/create-store.d.ts +29 -0
- package/dist/web/create-store.js +64 -0
- package/dist/web/create-store.js.map +1 -0
- package/dist/web/create-store.test.d.ts +1 -0
- package/dist/web/create-store.test.js +129 -0
- package/dist/web/create-store.test.js.map +1 -0
- package/dist/web/data-llm.d.ts +47 -0
- package/dist/web/data-llm.js +100 -0
- package/dist/web/data-llm.js.map +1 -0
- package/dist/web/data-llm.test.d.ts +1 -0
- package/dist/web/data-llm.test.js +142 -0
- package/dist/web/data-llm.test.js.map +1 -0
- package/dist/web/generate-helpers.d.ts +120 -0
- package/dist/web/generate-helpers.js +115 -0
- package/dist/web/generate-helpers.js.map +1 -0
- package/dist/web/generate-helpers.test-d.d.ts +1 -0
- package/dist/web/generate-helpers.test-d.js +211 -0
- package/dist/web/generate-helpers.test-d.js.map +1 -0
- package/dist/web/generate-helpers.test.d.ts +1 -0
- package/dist/web/generate-helpers.test.js +17 -0
- package/dist/web/generate-helpers.test.js.map +1 -0
- package/dist/web/helpers/state.d.ts +7 -0
- package/dist/web/helpers/state.js +45 -0
- package/dist/web/helpers/state.js.map +1 -0
- package/dist/web/helpers/state.test.d.ts +1 -0
- package/dist/web/helpers/state.test.js +53 -0
- package/dist/web/helpers/state.test.js.map +1 -0
- package/dist/web/hooks/index.d.ts +17 -0
- package/dist/web/hooks/index.js +18 -0
- package/dist/web/hooks/index.js.map +1 -0
- package/dist/web/hooks/test/utils.d.ts +20 -0
- package/dist/web/hooks/test/utils.js +75 -0
- package/dist/web/hooks/test/utils.js.map +1 -0
- package/dist/web/hooks/use-call-tool.d.ts +146 -0
- package/dist/web/hooks/use-call-tool.js +96 -0
- package/dist/web/hooks/use-call-tool.js.map +1 -0
- package/dist/web/hooks/use-call-tool.test-d.d.ts +1 -0
- package/dist/web/hooks/use-call-tool.test-d.js +104 -0
- package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
- package/dist/web/hooks/use-call-tool.test.d.ts +1 -0
- package/dist/web/hooks/use-call-tool.test.js +211 -0
- package/dist/web/hooks/use-call-tool.test.js.map +1 -0
- package/dist/web/hooks/use-display-mode.d.ts +24 -0
- package/dist/web/hooks/use-display-mode.js +29 -0
- package/dist/web/hooks/use-display-mode.js.map +1 -0
- package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
- package/dist/web/hooks/use-display-mode.test-d.js +8 -0
- package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
- package/dist/web/hooks/use-display-mode.test.d.ts +1 -0
- package/dist/web/hooks/use-display-mode.test.js +41 -0
- package/dist/web/hooks/use-display-mode.test.js.map +1 -0
- package/dist/web/hooks/use-download.d.ts +5 -0
- package/dist/web/hooks/use-download.js +8 -0
- package/dist/web/hooks/use-download.js.map +1 -0
- package/dist/web/hooks/use-download.test.d.ts +1 -0
- package/dist/web/hooks/use-download.test.js +95 -0
- package/dist/web/hooks/use-download.test.js.map +1 -0
- package/dist/web/hooks/use-files.d.ts +39 -0
- package/dist/web/hooks/use-files.js +42 -0
- package/dist/web/hooks/use-files.js.map +1 -0
- package/dist/web/hooks/use-files.test.d.ts +1 -0
- package/dist/web/hooks/use-files.test.js +54 -0
- package/dist/web/hooks/use-files.test.js.map +1 -0
- package/dist/web/hooks/use-intent.d.ts +30 -0
- package/dist/web/hooks/use-intent.js +34 -0
- package/dist/web/hooks/use-intent.js.map +1 -0
- package/dist/web/hooks/use-intent.test.d.ts +1 -0
- package/dist/web/hooks/use-intent.test.js +85 -0
- package/dist/web/hooks/use-intent.test.js.map +1 -0
- package/dist/web/hooks/use-layout.d.ts +24 -0
- package/dist/web/hooks/use-layout.js +25 -0
- package/dist/web/hooks/use-layout.js.map +1 -0
- package/dist/web/hooks/use-layout.test.d.ts +1 -0
- package/dist/web/hooks/use-layout.test.js +96 -0
- package/dist/web/hooks/use-layout.test.js.map +1 -0
- package/dist/web/hooks/use-notify.d.ts +29 -0
- package/dist/web/hooks/use-notify.js +33 -0
- package/dist/web/hooks/use-notify.js.map +1 -0
- package/dist/web/hooks/use-notify.test.d.ts +1 -0
- package/dist/web/hooks/use-notify.test.js +105 -0
- package/dist/web/hooks/use-notify.test.js.map +1 -0
- package/dist/web/hooks/use-open-external.d.ts +20 -0
- package/dist/web/hooks/use-open-external.js +24 -0
- package/dist/web/hooks/use-open-external.js.map +1 -0
- package/dist/web/hooks/use-open-external.test.d.ts +1 -0
- package/dist/web/hooks/use-open-external.test.js +65 -0
- package/dist/web/hooks/use-open-external.test.js.map +1 -0
- package/dist/web/hooks/use-register-view-tool.d.ts +38 -0
- package/dist/web/hooks/use-register-view-tool.js +50 -0
- package/dist/web/hooks/use-register-view-tool.js.map +1 -0
- package/dist/web/hooks/use-request-close.d.ts +16 -0
- package/dist/web/hooks/use-request-close.js +21 -0
- package/dist/web/hooks/use-request-close.js.map +1 -0
- package/dist/web/hooks/use-request-close.test.d.ts +1 -0
- package/dist/web/hooks/use-request-close.test.js +52 -0
- package/dist/web/hooks/use-request-close.test.js.map +1 -0
- package/dist/web/hooks/use-request-modal.d.ts +24 -0
- package/dist/web/hooks/use-request-modal.js +31 -0
- package/dist/web/hooks/use-request-modal.js.map +1 -0
- package/dist/web/hooks/use-request-modal.test.d.ts +1 -0
- package/dist/web/hooks/use-request-modal.test.js +61 -0
- package/dist/web/hooks/use-request-modal.test.js.map +1 -0
- package/dist/web/hooks/use-request-size.d.ts +20 -0
- package/dist/web/hooks/use-request-size.js +24 -0
- package/dist/web/hooks/use-request-size.js.map +1 -0
- package/dist/web/hooks/use-request-size.test.d.ts +1 -0
- package/dist/web/hooks/use-request-size.test.js +65 -0
- package/dist/web/hooks/use-request-size.test.js.map +1 -0
- package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -0
- package/dist/web/hooks/use-send-follow-up-message.js +25 -0
- package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
- package/dist/web/hooks/use-set-open-in-app-url.d.ts +18 -0
- package/dist/web/hooks/use-set-open-in-app-url.js +25 -0
- package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
- package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
- package/dist/web/hooks/use-set-open-in-app-url.test.js +43 -0
- package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
- package/dist/web/hooks/use-tool-info.d.ts +87 -0
- package/dist/web/hooks/use-tool-info.js +49 -0
- package/dist/web/hooks/use-tool-info.js.map +1 -0
- package/dist/web/hooks/use-tool-info.test-d.d.ts +1 -0
- package/dist/web/hooks/use-tool-info.test-d.js +91 -0
- package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
- package/dist/web/hooks/use-tool-info.test.d.ts +1 -0
- package/dist/web/hooks/use-tool-info.test.js +130 -0
- package/dist/web/hooks/use-tool-info.test.js.map +1 -0
- package/dist/web/hooks/use-user.d.ts +20 -0
- package/dist/web/hooks/use-user.js +37 -0
- package/dist/web/hooks/use-user.js.map +1 -0
- package/dist/web/hooks/use-user.test.d.ts +1 -0
- package/dist/web/hooks/use-user.test.js +122 -0
- package/dist/web/hooks/use-user.test.js.map +1 -0
- package/dist/web/hooks/use-view-state.d.ts +25 -0
- package/dist/web/hooks/use-view-state.js +32 -0
- package/dist/web/hooks/use-view-state.js.map +1 -0
- package/dist/web/hooks/use-view-state.test.d.ts +1 -0
- package/dist/web/hooks/use-view-state.test.js +177 -0
- package/dist/web/hooks/use-view-state.test.js.map +1 -0
- package/dist/web/index.d.ts +7 -0
- package/dist/web/index.js +8 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/mount-view.d.ts +20 -0
- package/dist/web/mount-view.js +46 -0
- package/dist/web/mount-view.js.map +1 -0
- package/dist/web/plugin/data-llm.test.d.ts +1 -0
- package/dist/web/plugin/data-llm.test.js +81 -0
- package/dist/web/plugin/data-llm.test.js.map +1 -0
- package/dist/web/plugin/plugin.d.ts +33 -0
- package/dist/web/plugin/plugin.js +189 -0
- package/dist/web/plugin/plugin.js.map +1 -0
- package/dist/web/plugin/scan-views.d.ts +16 -0
- package/dist/web/plugin/scan-views.js +88 -0
- package/dist/web/plugin/scan-views.js.map +1 -0
- package/dist/web/plugin/scan-views.test.d.ts +1 -0
- package/dist/web/plugin/scan-views.test.js +99 -0
- package/dist/web/plugin/scan-views.test.js.map +1 -0
- package/dist/web/plugin/transform-data-llm.d.ts +12 -0
- package/dist/web/plugin/transform-data-llm.js +96 -0
- package/dist/web/plugin/transform-data-llm.js.map +1 -0
- package/dist/web/plugin/transform-data-llm.test.d.ts +1 -0
- package/dist/web/plugin/transform-data-llm.test.js +81 -0
- package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
- package/dist/web/plugin/validate-view.d.ts +1 -0
- package/dist/web/plugin/validate-view.js +9 -0
- package/dist/web/plugin/validate-view.js.map +1 -0
- package/dist/web/plugin/validate-view.test.d.ts +1 -0
- package/dist/web/plugin/validate-view.test.js +24 -0
- package/dist/web/plugin/validate-view.test.js.map +1 -0
- package/dist/web/proxy.d.ts +1 -0
- package/dist/web/proxy.js +52 -0
- package/dist/web/proxy.js.map +1 -0
- package/dist/web/types.d.ts +20 -0
- package/dist/web/types.js +2 -0
- package/dist/web/types.js.map +1 -0
- package/package.json +125 -0
- package/scripts/postinstall.mjs +45 -0
- package/tsconfig.base.json +36 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.test.js","sourceRoot":"","sources":["../../src/server/observability.test.ts"],"names":[],"mappings":"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","sourcesContent":["import express from \"express\";\nimport { afterEach, describe, expect, it } from \"vitest\";\nimport {\n createObservabilityRouter,\n percentile,\n summarize,\n} from \"./observability.js\";\nimport { MemoryStorageAdapter } from \"./storage/memory.js\";\nimport type { AnalyticsEvent, StorageAdapter } from \"./storage/types.js\";\n\nfunction ev(p: Partial<AnalyticsEvent>): AnalyticsEvent {\n return { ts: 0, type: \"tool_call\", ...p };\n}\n\ndescribe(\"percentile\", () => {\n it(\"returns 0 for an empty sample\", () => {\n expect(percentile([], 0.5)).toBe(0);\n expect(percentile([], 0.95)).toBe(0);\n });\n\n it(\"returns the single value for a one-element sample\", () => {\n expect(percentile([42], 0.5)).toBe(42);\n });\n\n it(\"computes p50/p95 by nearest-rank interpolation\", () => {\n const s = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];\n expect(percentile(s, 0.5)).toBeCloseTo(55, 5);\n expect(percentile(s, 0.95)).toBeCloseTo(95.5, 5);\n });\n\n it(\"tolerates a zero-latency sample (ms === 0)\", () => {\n expect(percentile([0, 0, 0], 0.5)).toBe(0);\n expect(percentile([0, 10], 0.5)).toBe(5);\n });\n});\n\ndescribe(\"summarize\", () => {\n it(\"aggregates totals, error rate, p50/p95, top tools, and buckets\", () => {\n const base = 1_000_000;\n const events: AnalyticsEvent[] = [\n ev({ ts: base + 0, tool: \"echo\", ms: 10, ok: true }),\n ev({ ts: base + 1000, tool: \"echo\", ms: 20, ok: true }),\n ev({ ts: base + 2000, tool: \"echo\", ms: 30, ok: false }),\n ev({ ts: base + 70_000, tool: \"search\", ms: 100, ok: true }),\n ev({ ts: base + 71_000, tool: \"search\", ms: 0, ok: true }),\n ];\n\n const s = summarize(events, { since: base, bucketMs: 60_000 });\n\n expect(s.enabled).toBe(true);\n expect(s.total).toBe(5);\n expect(s.errors).toBe(1);\n expect(s.errorRate).toBeCloseTo(0.2, 5);\n // overall latencies sorted: [0,10,20,30,100]\n expect(s.p50).toBe(20);\n\n // Two 60s buckets: first has 3 (1 error), second has 2.\n expect(s.callsOverTime).toHaveLength(2);\n const [b0, b1] = s.callsOverTime;\n expect(b0).toMatchObject({ count: 3, errors: 1 });\n expect(b1).toMatchObject({ count: 2, errors: 0 });\n // Buckets oldest-first.\n expect(b0?.ts ?? 0).toBeLessThan(b1?.ts ?? 0);\n\n // Top tools: echo (3) then search (2).\n expect(s.topTools.map((t) => t.name)).toEqual([\"echo\", \"search\"]);\n const [t0, t1] = s.topTools;\n expect(t0).toMatchObject({ count: 3, errors: 1 });\n expect(t0?.errorRate ?? 0).toBeCloseTo(1 / 3, 5);\n expect(t1).toMatchObject({ count: 2, errors: 0 });\n });\n\n it(\"counts a thrown error (ok undefined + error set) as an error\", () => {\n const s = summarize(\n [ev({ ts: 1, error: \"boom\" }), ev({ ts: 2, ok: true, ms: 5 })],\n { since: 0 },\n );\n expect(s.errors).toBe(1);\n expect(s.errorRate).toBe(0.5);\n });\n\n it(\"excludes timing-less events from percentiles but counts them in totals\", () => {\n const s = summarize(\n [ev({ ts: 1, ok: true }), ev({ ts: 2, ok: true, ms: 50 })],\n { since: 0 },\n );\n expect(s.total).toBe(2);\n // Only one event has ms → p50 is that value.\n expect(s.p50).toBe(50);\n });\n\n it(\"returns zeroed aggregates (not NaN) for no events\", () => {\n const s = summarize([], { since: 0 });\n expect(s).toMatchObject({\n total: 0,\n errors: 0,\n errorRate: 0,\n p50: 0,\n p95: 0,\n p99: 0,\n avg: 0,\n throughputPerMin: 0,\n callsOverTime: [],\n topTools: [],\n slowestTools: [],\n byMethod: [],\n });\n // The histogram always has fixed buckets; they're just all zero.\n expect(s.latencyHistogram.every((b) => b.count === 0)).toBe(true);\n });\n\n it(\"computes p99 + avg overall and per-tool\", () => {\n const events: AnalyticsEvent[] = [];\n // echo: latencies 1..100 → avg 50.5, p99 ~99\n for (let i = 1; i <= 100; i++) {\n events.push(ev({ ts: i, tool: \"echo\", ms: i, ok: true }));\n }\n const s = summarize(events, { since: 0 });\n expect(s.avg).toBeCloseTo(50.5, 5);\n // nearest-rank: p99 of 1..100 → 99 + 0.01 interp\n expect(s.p99).toBeCloseTo(99, 0);\n const echo = s.topTools.find((t) => t.name === \"echo\");\n expect(echo?.avg).toBeCloseTo(50.5, 5);\n expect(echo?.p99).toBeGreaterThan(echo?.p95 ?? 0);\n });\n\n it(\"groups calls by method and ranks slowest tools by p95\", () => {\n const s = summarize(\n [\n ev({ ts: 1, tool: \"fast\", method: \"tools/call\", ms: 5, ok: true }),\n ev({ ts: 2, tool: \"fast\", method: \"tools/call\", ms: 7, ok: true }),\n ev({ ts: 3, tool: \"slow\", method: \"tools/call\", ms: 900, ok: true }),\n ev({ ts: 4, method: \"tools/list\", ms: 2, ok: true }),\n ],\n { since: 0 },\n );\n // byMethod descending by count: tools/call (3) then tools/list (1)\n expect(s.byMethod.map((m) => m.method)).toEqual([\n \"tools/call\",\n \"tools/list\",\n ]);\n expect(s.byMethod[0]?.count).toBe(3);\n // slowest by p95: slow first\n expect(s.slowestTools[0]?.name).toBe(\"slow\");\n });\n\n it(\"buckets latencies into a fixed histogram\", () => {\n const s = summarize(\n [\n ev({ ts: 1, tool: \"a\", ms: 5, ok: true }), // [0,10)\n ev({ ts: 2, tool: \"a\", ms: 5, ok: true }), // [0,10)\n ev({ ts: 3, tool: \"a\", ms: 30, ok: true }), // [25,50)\n ev({ ts: 4, tool: \"a\", ms: 3000, ok: true }), // >=2500\n ],\n { since: 0 },\n );\n const total = s.latencyHistogram.reduce((n, b) => n + b.count, 0);\n expect(total).toBe(4);\n const first = s.latencyHistogram.find((b) => b.from === 0);\n expect(first?.count).toBe(2);\n const top = s.latencyHistogram.find((b) => b.to === null);\n expect(top?.count).toBe(1);\n });\n\n it(\"falls back to method then 'unknown' for the tool name\", () => {\n const s = summarize(\n [ev({ ts: 1, method: \"initialize\", ms: 1 }), ev({ ts: 2, ms: 1 })],\n { since: 0 },\n );\n const names = s.topTools.map((t) => t.name).sort();\n expect(names).toEqual([\"initialize\", \"unknown\"]);\n });\n});\n\ndescribe(\"summarize — bucket size per range (M9)\", () => {\n const MINUTE = 60_000;\n const HOUR = 60 * MINUTE;\n const DAY = 24 * HOUR;\n const base = 1_700_000_000_000;\n\n // One event at the start of each of 14 consecutive days.\n const daily: AnalyticsEvent[] = Array.from({ length: 14 }, (_, i) =>\n ev({ ts: base + i * DAY, tool: \"echo\", ms: 5, ok: true }),\n );\n\n it(\"echoes the chosen bucketMs and aligns buckets to it\", () => {\n for (const bucketMs of [MINUTE, HOUR, 6 * HOUR, DAY]) {\n const s = summarize(daily, { since: base, bucketMs });\n expect(s.bucketMs).toBe(bucketMs);\n // Every bucket start is aligned to bucketMs.\n for (const b of s.callsOverTime) {\n expect(b.ts % bucketMs).toBe(0);\n }\n }\n });\n\n it(\"daily buckets (30d range): 14 daily events → 14 buckets\", () => {\n const s = summarize(daily, { since: base, bucketMs: DAY });\n expect(s.callsOverTime).toHaveLength(14);\n expect(s.callsOverTime.every((b) => b.count === 1)).toBe(true);\n });\n\n it(\"6h buckets (7d range) keep each daily event in its own bucket\", () => {\n const s = summarize(daily, { since: base, bucketMs: 6 * HOUR });\n // Events are a full day apart, so no two share a 6h bucket.\n expect(s.callsOverTime).toHaveLength(14);\n });\n\n it(\"coarser buckets merge sub-bucket events; finer buckets split them\", () => {\n // Two events 90 minutes apart.\n const pair: AnalyticsEvent[] = [\n ev({ ts: base, tool: \"echo\", ms: 1, ok: true }),\n ev({ ts: base + 90 * MINUTE, tool: \"echo\", ms: 1, ok: true }),\n ];\n // Minute buckets (1h range): two distinct buckets.\n expect(\n summarize(pair, { since: base, bucketMs: MINUTE }).callsOverTime,\n ).toHaveLength(2);\n // Hourly buckets (24h range): still two (they straddle the hour boundary).\n expect(\n summarize(pair, { since: base, bucketMs: HOUR }).callsOverTime,\n ).toHaveLength(2);\n // Daily buckets (30d range): both fall in one day → a single bucket of 2.\n const dayBuckets = summarize(pair, {\n since: base,\n bucketMs: DAY,\n }).callsOverTime;\n expect(dayBuckets).toHaveLength(1);\n expect(dayBuckets[0]?.count).toBe(2);\n });\n});\n\n// --- Router behaviour (incl. the disabled/no-storage path) ---\n\nconst servers: Array<{ close: () => Promise<void> }> = [];\nafterEach(async () => {\n while (servers.length > 0) {\n await servers.pop()?.close();\n }\n});\n\nasync function mount(getStorage: () => StorageAdapter | null) {\n const app = express();\n app.use(createObservabilityRouter(getStorage));\n const server = app.listen(0, \"127.0.0.1\");\n await new Promise<void>((resolve) => server.once(\"listening\", resolve));\n const port = (server.address() as { port: number }).port;\n servers.push({\n close: () =>\n new Promise<void>((resolve) => {\n server.closeAllConnections?.();\n server.close(() => resolve());\n }),\n });\n return `http://127.0.0.1:${port}`;\n}\n\ndescribe(\"createObservabilityRouter (disabled / no storage)\", () => {\n it(\"returns 200 { enabled: false } empty payloads, never 500\", async () => {\n const url = await mount(() => null);\n\n const summary = await fetch(`${url}/__enpilink/observability/summary`);\n expect(summary.status).toBe(200);\n expect(await summary.json()).toMatchObject({\n enabled: false,\n total: 0,\n callsOverTime: [],\n topTools: [],\n });\n\n const events = await fetch(`${url}/__enpilink/observability/events`);\n expect(events.status).toBe(200);\n expect(await events.json()).toEqual({ enabled: false, events: [] });\n\n const logs = await fetch(`${url}/__enpilink/observability/logs`);\n expect(logs.status).toBe(200);\n expect(await logs.json()).toEqual({ enabled: false, logs: [] });\n });\n});\n\ndescribe(\"createObservabilityRouter (with storage)\", () => {\n it(\"serves a real summary + events from the active adapter\", async () => {\n const storage = new MemoryStorageAdapter();\n await storage.init();\n await storage.recordEvent(\n ev({ ts: Date.now(), tool: \"echo\", ms: 5, ok: true }),\n );\n await storage.recordEvent(\n ev({ ts: Date.now(), tool: \"echo\", ms: 15, ok: false }),\n );\n\n const url = await mount(() => storage);\n\n const summary = await (\n await fetch(`${url}/__enpilink/observability/summary?since=0`)\n ).json();\n expect(summary.enabled).toBe(true);\n expect(summary.total).toBe(2);\n expect(summary.errors).toBe(1);\n expect(summary.topTools[0].name).toBe(\"echo\");\n\n const events = await (\n await fetch(`${url}/__enpilink/observability/events?since=0`)\n ).json();\n expect(events.enabled).toBe(true);\n expect(events.events).toHaveLength(2);\n });\n\n it(\"returns a 200 empty summary (not 500) when storage throws\", async () => {\n const broken = {\n queryEvents: async () => {\n throw new Error(\"db down\");\n },\n } as unknown as StorageAdapter;\n const url = await mount(() => broken);\n const res = await fetch(`${url}/__enpilink/observability/summary`);\n expect(res.status).toBe(200);\n expect(await res.json()).toMatchObject({ enabled: false, total: 0 });\n });\n});\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AnalyticsEvent } from "./storage/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Whether OTel export is enabled. OFF unless `ENPILINK_OTEL` is truthy AND a
|
|
4
|
+
* standard OTLP endpoint var is set. No endpoint → disabled (never hardcoded).
|
|
5
|
+
*/
|
|
6
|
+
export declare function otelEnabled(): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* The configured OTLP endpoint (metrics-specific var preferred), or `undefined`
|
|
9
|
+
* when none is set. Never returns a hardcoded default.
|
|
10
|
+
*/
|
|
11
|
+
export declare function otelEndpoint(): string | undefined;
|
|
12
|
+
/** A single recording sink for analytics events. */
|
|
13
|
+
export interface OtelSink {
|
|
14
|
+
/** Record one analytics event into the OTel metric instruments. */
|
|
15
|
+
record(e: AnalyticsEvent): void;
|
|
16
|
+
/** Flush + shut down the meter provider (closes the exporter cleanly). */
|
|
17
|
+
shutdown(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/** Minimal structural shape of an OTel counter/histogram instrument. */
|
|
20
|
+
interface Instrument {
|
|
21
|
+
add?(value: number, attrs?: Record<string, unknown>): void;
|
|
22
|
+
record?(value: number, attrs?: Record<string, unknown>): void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Build the OTel sink. Injectable instrument factory lets tests verify the
|
|
26
|
+
* recording logic deterministically without constructing a real meter provider
|
|
27
|
+
* or exporter (so disabled-path tests prove nothing is imported/constructed).
|
|
28
|
+
*
|
|
29
|
+
* Attributes are kept low-cardinality: `tool`, `method`, `ok`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createOtelSink(instruments: {
|
|
32
|
+
count: Instrument;
|
|
33
|
+
errors: Instrument;
|
|
34
|
+
duration: Instrument;
|
|
35
|
+
shutdown: () => Promise<void>;
|
|
36
|
+
}): OtelSink;
|
|
37
|
+
/**
|
|
38
|
+
* Initialize the OTel metrics export sink, ONLY when enabled. Lazily imports the
|
|
39
|
+
* `@opentelemetry/*` packages so a disabled deployment never loads them.
|
|
40
|
+
*
|
|
41
|
+
* @returns an {@link OtelSink}, or `null` when disabled / on init failure (never
|
|
42
|
+
* throws into the caller).
|
|
43
|
+
*/
|
|
44
|
+
export declare function initOtel(): Promise<OtelSink | null>;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional OpenTelemetry export of the analytics event stream (M6).
|
|
3
|
+
*
|
|
4
|
+
* OFF by default. When OFF, this module constructs NOTHING, imports no
|
|
5
|
+
* `@opentelemetry/*` package, opens no connection, and adds zero overhead — the
|
|
6
|
+
* leak-lesson rule. Enabling requires BOTH:
|
|
7
|
+
*
|
|
8
|
+
* - `ENPILINK_OTEL` = `1`/`true`/`yes`/`on` (the explicit opt-in), AND
|
|
9
|
+
* - `OTEL_EXPORTER_OTLP_ENDPOINT` (or `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`) —
|
|
10
|
+
* the standard OTLP endpoint var. NO endpoint is ever hardcoded; if it is
|
|
11
|
+
* unset, OTel stays disabled.
|
|
12
|
+
*
|
|
13
|
+
* When enabled, each analytics event (a `tool_call`) is exported as OpenTelemetry
|
|
14
|
+
* metrics to the configured OTLP/HTTP endpoint:
|
|
15
|
+
* - `enpilink.tool_call.count` (counter, attrs: tool, method, ok)
|
|
16
|
+
* - `enpilink.tool_call.errors` (counter, attrs: tool, method)
|
|
17
|
+
* - `enpilink.tool_call.duration` (histogram, ms, attrs: tool, method, ok)
|
|
18
|
+
*
|
|
19
|
+
* The exporter is wired as an ADDITIONAL, guarded sink alongside
|
|
20
|
+
* `storage.recordEvent` in analytics.ts; recording is fire-and-forget and never
|
|
21
|
+
* blocks or breaks a tool call.
|
|
22
|
+
*/
|
|
23
|
+
/** Truthy values that enable OTel via {@link otelEnabled}. */
|
|
24
|
+
const TRUTHY = new Set(["1", "true", "yes", "on"]);
|
|
25
|
+
/**
|
|
26
|
+
* Whether OTel export is enabled. OFF unless `ENPILINK_OTEL` is truthy AND a
|
|
27
|
+
* standard OTLP endpoint var is set. No endpoint → disabled (never hardcoded).
|
|
28
|
+
*/
|
|
29
|
+
export function otelEnabled() {
|
|
30
|
+
const raw = process.env.ENPILINK_OTEL;
|
|
31
|
+
const flag = raw !== undefined && TRUTHY.has(raw.trim().toLowerCase());
|
|
32
|
+
return flag && otelEndpoint() !== undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The configured OTLP endpoint (metrics-specific var preferred), or `undefined`
|
|
36
|
+
* when none is set. Never returns a hardcoded default.
|
|
37
|
+
*/
|
|
38
|
+
export function otelEndpoint() {
|
|
39
|
+
const url = process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT ??
|
|
40
|
+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
41
|
+
const trimmed = url?.trim();
|
|
42
|
+
return trimmed ? trimmed : undefined;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build the OTel sink. Injectable instrument factory lets tests verify the
|
|
46
|
+
* recording logic deterministically without constructing a real meter provider
|
|
47
|
+
* or exporter (so disabled-path tests prove nothing is imported/constructed).
|
|
48
|
+
*
|
|
49
|
+
* Attributes are kept low-cardinality: `tool`, `method`, `ok`.
|
|
50
|
+
*/
|
|
51
|
+
export function createOtelSink(instruments) {
|
|
52
|
+
return {
|
|
53
|
+
record(e) {
|
|
54
|
+
const attrs = {
|
|
55
|
+
tool: e.tool ?? "(none)",
|
|
56
|
+
method: e.method ?? "(unknown)",
|
|
57
|
+
ok: e.ok !== false,
|
|
58
|
+
};
|
|
59
|
+
instruments.count.add?.(1, attrs);
|
|
60
|
+
if (e.ok === false) {
|
|
61
|
+
instruments.errors.add?.(1, { tool: attrs.tool, method: attrs.method });
|
|
62
|
+
}
|
|
63
|
+
if (typeof e.ms === "number") {
|
|
64
|
+
instruments.duration.record?.(e.ms, attrs);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
shutdown: instruments.shutdown,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Initialize the OTel metrics export sink, ONLY when enabled. Lazily imports the
|
|
72
|
+
* `@opentelemetry/*` packages so a disabled deployment never loads them.
|
|
73
|
+
*
|
|
74
|
+
* @returns an {@link OtelSink}, or `null` when disabled / on init failure (never
|
|
75
|
+
* throws into the caller).
|
|
76
|
+
*/
|
|
77
|
+
export async function initOtel() {
|
|
78
|
+
if (!otelEnabled()) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const [{ metrics }, { MeterProvider, PeriodicExportingMetricReader }, { OTLPMetricExporter },] = await Promise.all([
|
|
83
|
+
import("@opentelemetry/api"),
|
|
84
|
+
import("@opentelemetry/sdk-metrics"),
|
|
85
|
+
import("@opentelemetry/exporter-metrics-otlp-http"),
|
|
86
|
+
]);
|
|
87
|
+
// Endpoint comes from the env-resolved value; the exporter also honors the
|
|
88
|
+
// standard OTEL_* vars, but we pass it explicitly to be unambiguous.
|
|
89
|
+
const exporter = new OTLPMetricExporter({ url: otelEndpoint() });
|
|
90
|
+
const reader = new PeriodicExportingMetricReader({ exporter });
|
|
91
|
+
const provider = new MeterProvider({ readers: [reader] });
|
|
92
|
+
metrics.setGlobalMeterProvider(provider);
|
|
93
|
+
const meter = provider.getMeter("enpilink");
|
|
94
|
+
const count = meter.createCounter("enpilink.tool_call.count", {
|
|
95
|
+
description: "Number of MCP tool calls / requests recorded.",
|
|
96
|
+
});
|
|
97
|
+
const errors = meter.createCounter("enpilink.tool_call.errors", {
|
|
98
|
+
description: "Number of failed MCP tool calls.",
|
|
99
|
+
});
|
|
100
|
+
const duration = meter.createHistogram("enpilink.tool_call.duration", {
|
|
101
|
+
description: "MCP tool-call duration in milliseconds.",
|
|
102
|
+
unit: "ms",
|
|
103
|
+
});
|
|
104
|
+
return createOtelSink({
|
|
105
|
+
count,
|
|
106
|
+
errors,
|
|
107
|
+
duration,
|
|
108
|
+
shutdown: () => provider.shutdown(),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
// OTel must never break startup; degrade to no-op.
|
|
113
|
+
console.error("[enpilink] OTel export disabled: init failed:", err instanceof Error ? err.message : err);
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=otel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel.js","sourceRoot":"","sources":["../../src/server/otel.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnalyticsEvent } from \"./storage/types.js\";\n\n/**\n * Optional OpenTelemetry export of the analytics event stream (M6).\n *\n * OFF by default. When OFF, this module constructs NOTHING, imports no\n * `@opentelemetry/*` package, opens no connection, and adds zero overhead — the\n * leak-lesson rule. Enabling requires BOTH:\n *\n * - `ENPILINK_OTEL` = `1`/`true`/`yes`/`on` (the explicit opt-in), AND\n * - `OTEL_EXPORTER_OTLP_ENDPOINT` (or `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`) —\n * the standard OTLP endpoint var. NO endpoint is ever hardcoded; if it is\n * unset, OTel stays disabled.\n *\n * When enabled, each analytics event (a `tool_call`) is exported as OpenTelemetry\n * metrics to the configured OTLP/HTTP endpoint:\n * - `enpilink.tool_call.count` (counter, attrs: tool, method, ok)\n * - `enpilink.tool_call.errors` (counter, attrs: tool, method)\n * - `enpilink.tool_call.duration` (histogram, ms, attrs: tool, method, ok)\n *\n * The exporter is wired as an ADDITIONAL, guarded sink alongside\n * `storage.recordEvent` in analytics.ts; recording is fire-and-forget and never\n * blocks or breaks a tool call.\n */\n\n/** Truthy values that enable OTel via {@link otelEnabled}. */\nconst TRUTHY = new Set([\"1\", \"true\", \"yes\", \"on\"]);\n\n/**\n * Whether OTel export is enabled. OFF unless `ENPILINK_OTEL` is truthy AND a\n * standard OTLP endpoint var is set. No endpoint → disabled (never hardcoded).\n */\nexport function otelEnabled(): boolean {\n const raw = process.env.ENPILINK_OTEL;\n const flag = raw !== undefined && TRUTHY.has(raw.trim().toLowerCase());\n return flag && otelEndpoint() !== undefined;\n}\n\n/**\n * The configured OTLP endpoint (metrics-specific var preferred), or `undefined`\n * when none is set. Never returns a hardcoded default.\n */\nexport function otelEndpoint(): string | undefined {\n const url =\n process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT ??\n process.env.OTEL_EXPORTER_OTLP_ENDPOINT;\n const trimmed = url?.trim();\n return trimmed ? trimmed : undefined;\n}\n\n/** A single recording sink for analytics events. */\nexport interface OtelSink {\n /** Record one analytics event into the OTel metric instruments. */\n record(e: AnalyticsEvent): void;\n /** Flush + shut down the meter provider (closes the exporter cleanly). */\n shutdown(): Promise<void>;\n}\n\n/** Minimal structural shape of an OTel counter/histogram instrument. */\ninterface Instrument {\n add?(value: number, attrs?: Record<string, unknown>): void;\n record?(value: number, attrs?: Record<string, unknown>): void;\n}\n\n/**\n * Build the OTel sink. Injectable instrument factory lets tests verify the\n * recording logic deterministically without constructing a real meter provider\n * or exporter (so disabled-path tests prove nothing is imported/constructed).\n *\n * Attributes are kept low-cardinality: `tool`, `method`, `ok`.\n */\nexport function createOtelSink(instruments: {\n count: Instrument;\n errors: Instrument;\n duration: Instrument;\n shutdown: () => Promise<void>;\n}): OtelSink {\n return {\n record(e: AnalyticsEvent): void {\n const attrs: Record<string, unknown> = {\n tool: e.tool ?? \"(none)\",\n method: e.method ?? \"(unknown)\",\n ok: e.ok !== false,\n };\n instruments.count.add?.(1, attrs);\n if (e.ok === false) {\n instruments.errors.add?.(1, { tool: attrs.tool, method: attrs.method });\n }\n if (typeof e.ms === \"number\") {\n instruments.duration.record?.(e.ms, attrs);\n }\n },\n shutdown: instruments.shutdown,\n };\n}\n\n/**\n * Initialize the OTel metrics export sink, ONLY when enabled. Lazily imports the\n * `@opentelemetry/*` packages so a disabled deployment never loads them.\n *\n * @returns an {@link OtelSink}, or `null` when disabled / on init failure (never\n * throws into the caller).\n */\nexport async function initOtel(): Promise<OtelSink | null> {\n if (!otelEnabled()) {\n return null;\n }\n try {\n const [\n { metrics },\n { MeterProvider, PeriodicExportingMetricReader },\n { OTLPMetricExporter },\n ] = await Promise.all([\n import(\"@opentelemetry/api\"),\n import(\"@opentelemetry/sdk-metrics\"),\n import(\"@opentelemetry/exporter-metrics-otlp-http\"),\n ]);\n\n // Endpoint comes from the env-resolved value; the exporter also honors the\n // standard OTEL_* vars, but we pass it explicitly to be unambiguous.\n const exporter = new OTLPMetricExporter({ url: otelEndpoint() });\n const reader = new PeriodicExportingMetricReader({ exporter });\n const provider = new MeterProvider({ readers: [reader] });\n metrics.setGlobalMeterProvider(provider);\n\n const meter = provider.getMeter(\"enpilink\");\n const count = meter.createCounter(\"enpilink.tool_call.count\", {\n description: \"Number of MCP tool calls / requests recorded.\",\n });\n const errors = meter.createCounter(\"enpilink.tool_call.errors\", {\n description: \"Number of failed MCP tool calls.\",\n });\n const duration = meter.createHistogram(\"enpilink.tool_call.duration\", {\n description: \"MCP tool-call duration in milliseconds.\",\n unit: \"ms\",\n });\n\n return createOtelSink({\n count,\n errors,\n duration,\n shutdown: () => provider.shutdown(),\n });\n } catch (err) {\n // OTel must never break startup; degrade to no-op.\n console.error(\n \"[enpilink] OTel export disabled: init failed:\",\n err instanceof Error ? err.message : err,\n );\n return null;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { createOtelSink, initOtel, otelEnabled, otelEndpoint } from "./otel.js";
|
|
3
|
+
describe("otel gating", () => {
|
|
4
|
+
const saved = {
|
|
5
|
+
flag: process.env.ENPILINK_OTEL,
|
|
6
|
+
ep: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
7
|
+
mep: process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
|
|
8
|
+
};
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
delete process.env.ENPILINK_OTEL;
|
|
11
|
+
delete process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
12
|
+
delete process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT;
|
|
13
|
+
});
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
restore("ENPILINK_OTEL", saved.flag);
|
|
16
|
+
restore("OTEL_EXPORTER_OTLP_ENDPOINT", saved.ep);
|
|
17
|
+
restore("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT", saved.mep);
|
|
18
|
+
});
|
|
19
|
+
it("is OFF by default (no env)", () => {
|
|
20
|
+
expect(otelEnabled()).toBe(false);
|
|
21
|
+
expect(otelEndpoint()).toBeUndefined();
|
|
22
|
+
});
|
|
23
|
+
it("stays OFF when the flag is set but NO endpoint is configured", () => {
|
|
24
|
+
process.env.ENPILINK_OTEL = "1";
|
|
25
|
+
// No hardcoded default endpoint — must remain disabled.
|
|
26
|
+
expect(otelEndpoint()).toBeUndefined();
|
|
27
|
+
expect(otelEnabled()).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
it("stays OFF when an endpoint is set but the flag is not", () => {
|
|
30
|
+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT = "http://localhost:4318";
|
|
31
|
+
expect(otelEnabled()).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
it("is ON only when BOTH the flag and an endpoint are set", () => {
|
|
34
|
+
process.env.ENPILINK_OTEL = "true";
|
|
35
|
+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT = "http://localhost:4318";
|
|
36
|
+
expect(otelEnabled()).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it("prefers the metrics-specific endpoint var", () => {
|
|
39
|
+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT = "http://generic:4318";
|
|
40
|
+
process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = "http://metrics:4318";
|
|
41
|
+
expect(otelEndpoint()).toBe("http://metrics:4318");
|
|
42
|
+
});
|
|
43
|
+
it("initOtel returns null (no exporter constructed) when disabled", async () => {
|
|
44
|
+
// Disabled → zero network, nothing imported/constructed.
|
|
45
|
+
expect(await initOtel()).toBeNull();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe("createOtelSink recording", () => {
|
|
49
|
+
function makeInstruments() {
|
|
50
|
+
const count = { add: vi.fn() };
|
|
51
|
+
const errors = { add: vi.fn() };
|
|
52
|
+
const duration = { record: vi.fn() };
|
|
53
|
+
const shutdown = vi.fn(async () => { });
|
|
54
|
+
return { count, errors, duration, shutdown };
|
|
55
|
+
}
|
|
56
|
+
it("records count + duration with low-cardinality attrs on success", () => {
|
|
57
|
+
const i = makeInstruments();
|
|
58
|
+
const sink = createOtelSink(i);
|
|
59
|
+
sink.record({
|
|
60
|
+
ts: 1,
|
|
61
|
+
type: "tool_call",
|
|
62
|
+
tool: "echo",
|
|
63
|
+
method: "tools/call",
|
|
64
|
+
ms: 12,
|
|
65
|
+
ok: true,
|
|
66
|
+
});
|
|
67
|
+
expect(i.count.add).toHaveBeenCalledWith(1, {
|
|
68
|
+
tool: "echo",
|
|
69
|
+
method: "tools/call",
|
|
70
|
+
ok: true,
|
|
71
|
+
});
|
|
72
|
+
expect(i.duration.record).toHaveBeenCalledWith(12, {
|
|
73
|
+
tool: "echo",
|
|
74
|
+
method: "tools/call",
|
|
75
|
+
ok: true,
|
|
76
|
+
});
|
|
77
|
+
expect(i.errors.add).not.toHaveBeenCalled();
|
|
78
|
+
});
|
|
79
|
+
it("also increments the error counter when ok === false", () => {
|
|
80
|
+
const i = makeInstruments();
|
|
81
|
+
const sink = createOtelSink(i);
|
|
82
|
+
sink.record({
|
|
83
|
+
ts: 1,
|
|
84
|
+
type: "tool_call",
|
|
85
|
+
tool: "boom",
|
|
86
|
+
method: "tools/call",
|
|
87
|
+
ms: 3,
|
|
88
|
+
ok: false,
|
|
89
|
+
});
|
|
90
|
+
expect(i.count.add).toHaveBeenCalledTimes(1);
|
|
91
|
+
expect(i.errors.add).toHaveBeenCalledWith(1, {
|
|
92
|
+
tool: "boom",
|
|
93
|
+
method: "tools/call",
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
it("skips the duration histogram when ms is absent", () => {
|
|
97
|
+
const i = makeInstruments();
|
|
98
|
+
const sink = createOtelSink(i);
|
|
99
|
+
sink.record({ ts: 1, type: "tool_call", method: "initialize", ok: true });
|
|
100
|
+
expect(i.count.add).toHaveBeenCalledWith(1, {
|
|
101
|
+
tool: "(none)",
|
|
102
|
+
method: "initialize",
|
|
103
|
+
ok: true,
|
|
104
|
+
});
|
|
105
|
+
expect(i.duration.record).not.toHaveBeenCalled();
|
|
106
|
+
});
|
|
107
|
+
it("shutdown delegates to the provider shutdown", async () => {
|
|
108
|
+
const i = makeInstruments();
|
|
109
|
+
const sink = createOtelSink(i);
|
|
110
|
+
await sink.shutdown();
|
|
111
|
+
expect(i.shutdown).toHaveBeenCalledTimes(1);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
function restore(key, value) {
|
|
115
|
+
if (value === undefined) {
|
|
116
|
+
delete process.env[key];
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
process.env[key] = value;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=otel.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel.test.js","sourceRoot":"","sources":["../../src/server/otel.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { createOtelSink, initOtel, otelEnabled, otelEndpoint } from \"./otel.js\";\n\ndescribe(\"otel gating\", () => {\n const saved = {\n flag: process.env.ENPILINK_OTEL,\n ep: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,\n mep: process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,\n };\n beforeEach(() => {\n delete process.env.ENPILINK_OTEL;\n delete process.env.OTEL_EXPORTER_OTLP_ENDPOINT;\n delete process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT;\n });\n afterEach(() => {\n restore(\"ENPILINK_OTEL\", saved.flag);\n restore(\"OTEL_EXPORTER_OTLP_ENDPOINT\", saved.ep);\n restore(\"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT\", saved.mep);\n });\n\n it(\"is OFF by default (no env)\", () => {\n expect(otelEnabled()).toBe(false);\n expect(otelEndpoint()).toBeUndefined();\n });\n\n it(\"stays OFF when the flag is set but NO endpoint is configured\", () => {\n process.env.ENPILINK_OTEL = \"1\";\n // No hardcoded default endpoint — must remain disabled.\n expect(otelEndpoint()).toBeUndefined();\n expect(otelEnabled()).toBe(false);\n });\n\n it(\"stays OFF when an endpoint is set but the flag is not\", () => {\n process.env.OTEL_EXPORTER_OTLP_ENDPOINT = \"http://localhost:4318\";\n expect(otelEnabled()).toBe(false);\n });\n\n it(\"is ON only when BOTH the flag and an endpoint are set\", () => {\n process.env.ENPILINK_OTEL = \"true\";\n process.env.OTEL_EXPORTER_OTLP_ENDPOINT = \"http://localhost:4318\";\n expect(otelEnabled()).toBe(true);\n });\n\n it(\"prefers the metrics-specific endpoint var\", () => {\n process.env.OTEL_EXPORTER_OTLP_ENDPOINT = \"http://generic:4318\";\n process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = \"http://metrics:4318\";\n expect(otelEndpoint()).toBe(\"http://metrics:4318\");\n });\n\n it(\"initOtel returns null (no exporter constructed) when disabled\", async () => {\n // Disabled → zero network, nothing imported/constructed.\n expect(await initOtel()).toBeNull();\n });\n});\n\ndescribe(\"createOtelSink recording\", () => {\n function makeInstruments() {\n const count = { add: vi.fn() };\n const errors = { add: vi.fn() };\n const duration = { record: vi.fn() };\n const shutdown = vi.fn(async () => {});\n return { count, errors, duration, shutdown };\n }\n\n it(\"records count + duration with low-cardinality attrs on success\", () => {\n const i = makeInstruments();\n const sink = createOtelSink(i);\n sink.record({\n ts: 1,\n type: \"tool_call\",\n tool: \"echo\",\n method: \"tools/call\",\n ms: 12,\n ok: true,\n });\n expect(i.count.add).toHaveBeenCalledWith(1, {\n tool: \"echo\",\n method: \"tools/call\",\n ok: true,\n });\n expect(i.duration.record).toHaveBeenCalledWith(12, {\n tool: \"echo\",\n method: \"tools/call\",\n ok: true,\n });\n expect(i.errors.add).not.toHaveBeenCalled();\n });\n\n it(\"also increments the error counter when ok === false\", () => {\n const i = makeInstruments();\n const sink = createOtelSink(i);\n sink.record({\n ts: 1,\n type: \"tool_call\",\n tool: \"boom\",\n method: \"tools/call\",\n ms: 3,\n ok: false,\n });\n expect(i.count.add).toHaveBeenCalledTimes(1);\n expect(i.errors.add).toHaveBeenCalledWith(1, {\n tool: \"boom\",\n method: \"tools/call\",\n });\n });\n\n it(\"skips the duration histogram when ms is absent\", () => {\n const i = makeInstruments();\n const sink = createOtelSink(i);\n sink.record({ ts: 1, type: \"tool_call\", method: \"initialize\", ok: true });\n expect(i.count.add).toHaveBeenCalledWith(1, {\n tool: \"(none)\",\n method: \"initialize\",\n ok: true,\n });\n expect(i.duration.record).not.toHaveBeenCalled();\n });\n\n it(\"shutdown delegates to the provider shutdown\", async () => {\n const i = makeInstruments();\n const sink = createOtelSink(i);\n await sink.shutdown();\n expect(i.shutdown).toHaveBeenCalledTimes(1);\n });\n});\n\nfunction restore(key: string, value: string | undefined): void {\n if (value === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = value;\n }\n}\n"]}
|