veryfront 0.1.246 → 0.1.248

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.
Files changed (160) hide show
  1. package/esm/cli/mcp/tools/project-tools.d.ts +1 -1
  2. package/esm/cli/mcp/tools/scaffold-tools.d.ts +2 -2
  3. package/esm/cli/shared/server-startup.d.ts.map +1 -1
  4. package/esm/cli/shared/server-startup.js +8 -0
  5. package/esm/deno.d.ts +0 -9
  6. package/esm/deno.js +5 -12
  7. package/esm/src/agent/durable.d.ts +67 -0
  8. package/esm/src/agent/durable.d.ts.map +1 -1
  9. package/esm/src/agent/durable.js +134 -0
  10. package/esm/src/agent/index.d.ts +1 -1
  11. package/esm/src/agent/index.d.ts.map +1 -1
  12. package/esm/src/agent/index.js +1 -1
  13. package/esm/src/embedding/upload-loader.d.ts +2 -2
  14. package/esm/src/embedding/upload-loader.d.ts.map +1 -1
  15. package/esm/src/embedding/upload-loader.js +11 -48
  16. package/esm/src/errors/middleware/cli-error-boundary.js +1 -1
  17. package/esm/src/errors/middleware/http-error-boundary.js +1 -1
  18. package/esm/src/errors/tracing.d.ts +3 -3
  19. package/esm/src/errors/tracing.d.ts.map +1 -1
  20. package/esm/src/errors/tracing.js +3 -3
  21. package/esm/src/extensions/interfaces/index.d.ts +2 -2
  22. package/esm/src/extensions/interfaces/index.d.ts.map +1 -1
  23. package/esm/src/extensions/interfaces/node-compat.d.ts +68 -10
  24. package/esm/src/extensions/interfaces/node-compat.d.ts.map +1 -1
  25. package/esm/src/extensions/interfaces/tracing-exporter.d.ts +35 -1
  26. package/esm/src/extensions/interfaces/tracing-exporter.d.ts.map +1 -1
  27. package/esm/src/integrations/schema.d.ts +10 -10
  28. package/esm/src/mcp/index.d.ts +7 -2
  29. package/esm/src/mcp/index.d.ts.map +1 -1
  30. package/esm/src/mcp/index.js +7 -2
  31. package/esm/src/mcp/schemas/index.d.ts +1 -1
  32. package/esm/src/mcp/schemas/index.d.ts.map +1 -1
  33. package/esm/src/mcp/schemas/index.js +1 -1
  34. package/esm/src/mcp/schemas/mcp.schema.d.ts +13 -7
  35. package/esm/src/mcp/schemas/mcp.schema.d.ts.map +1 -1
  36. package/esm/src/mcp/schemas/mcp.schema.js +17 -7
  37. package/esm/src/mcp/server.d.ts +13 -0
  38. package/esm/src/mcp/server.d.ts.map +1 -1
  39. package/esm/src/mcp/server.js +43 -6
  40. package/esm/src/observability/auto-instrument/http-instrumentation.js +1 -1
  41. package/esm/src/observability/auto-instrument/react-instrumentation.js +1 -1
  42. package/esm/src/observability/instruments/build-instruments.d.ts +1 -1
  43. package/esm/src/observability/instruments/build-instruments.d.ts.map +1 -1
  44. package/esm/src/observability/instruments/cache-instruments.d.ts +1 -1
  45. package/esm/src/observability/instruments/cache-instruments.d.ts.map +1 -1
  46. package/esm/src/observability/instruments/data-instruments.d.ts +1 -1
  47. package/esm/src/observability/instruments/data-instruments.d.ts.map +1 -1
  48. package/esm/src/observability/instruments/error-instruments.d.ts +1 -1
  49. package/esm/src/observability/instruments/error-instruments.d.ts.map +1 -1
  50. package/esm/src/observability/instruments/http-instruments.d.ts +1 -1
  51. package/esm/src/observability/instruments/http-instruments.d.ts.map +1 -1
  52. package/esm/src/observability/instruments/instruments-factory.d.ts +1 -1
  53. package/esm/src/observability/instruments/instruments-factory.d.ts.map +1 -1
  54. package/esm/src/observability/instruments/memory-instruments.d.ts +1 -1
  55. package/esm/src/observability/instruments/memory-instruments.d.ts.map +1 -1
  56. package/esm/src/observability/instruments/render-instruments.d.ts +1 -1
  57. package/esm/src/observability/instruments/render-instruments.d.ts.map +1 -1
  58. package/esm/src/observability/instruments/rsc-instruments.d.ts +1 -1
  59. package/esm/src/observability/instruments/rsc-instruments.d.ts.map +1 -1
  60. package/esm/src/observability/metrics/manager.d.ts.map +1 -1
  61. package/esm/src/observability/metrics/manager.js +10 -2
  62. package/esm/src/observability/metrics/types.d.ts +1 -1
  63. package/esm/src/observability/metrics/types.d.ts.map +1 -1
  64. package/esm/src/observability/simple-metrics/otel-instruments.d.ts.map +1 -1
  65. package/esm/src/observability/simple-metrics/otel-instruments.js +7 -2
  66. package/esm/src/observability/simple-metrics/types.d.ts +1 -1
  67. package/esm/src/observability/simple-metrics/types.d.ts.map +1 -1
  68. package/esm/src/observability/tracing/api-shim.d.ts +177 -0
  69. package/esm/src/observability/tracing/api-shim.d.ts.map +1 -0
  70. package/esm/src/observability/tracing/api-shim.js +234 -0
  71. package/esm/src/observability/tracing/manager.d.ts.map +1 -1
  72. package/esm/src/observability/tracing/manager.js +29 -4
  73. package/esm/src/observability/tracing/otlp-setup.d.ts +12 -8
  74. package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
  75. package/esm/src/observability/tracing/otlp-setup.js +59 -136
  76. package/esm/src/observability/tracing/types.d.ts +1 -1
  77. package/esm/src/observability/tracing/types.d.ts.map +1 -1
  78. package/esm/src/platform/compat/kv/factory.d.ts.map +1 -1
  79. package/esm/src/platform/compat/kv/factory.js +15 -6
  80. package/esm/src/platform/compat/opaque-deps.d.ts +6 -5
  81. package/esm/src/platform/compat/opaque-deps.d.ts.map +1 -1
  82. package/esm/src/platform/compat/opaque-deps.js +13 -37
  83. package/esm/src/proxy/tracing.d.ts +7 -2
  84. package/esm/src/proxy/tracing.d.ts.map +1 -1
  85. package/esm/src/proxy/tracing.js +31 -96
  86. package/esm/src/rendering/rsc/client-module-strategy.d.ts.map +1 -1
  87. package/esm/src/rendering/rsc/client-module-strategy.js +9 -1
  88. package/esm/src/server/bootstrap.d.ts.map +1 -1
  89. package/esm/src/server/bootstrap.js +27 -1
  90. package/esm/src/server/context/request-context.d.ts.map +1 -1
  91. package/esm/src/server/context/request-context.js +7 -4
  92. package/esm/src/server/dev-server/middleware.js +1 -1
  93. package/esm/src/server/handlers/dev/files/dev-file.handler.d.ts.map +1 -1
  94. package/esm/src/server/handlers/dev/files/dev-file.handler.js +4 -14
  95. package/esm/src/server/services/rendering/ssr.service.d.ts.map +1 -1
  96. package/esm/src/server/services/rendering/ssr.service.js +4 -1
  97. package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +1 -1
  98. package/esm/src/utils/version-constant.d.ts +1 -1
  99. package/esm/src/utils/version-constant.js +1 -1
  100. package/esm/src/workflow/claude-code/workspace-sync.d.ts +17 -2
  101. package/esm/src/workflow/claude-code/workspace-sync.d.ts.map +1 -1
  102. package/esm/src/workflow/claude-code/workspace-sync.js +106 -19
  103. package/esm/src/workflow/schemas/workflow.schema.d.ts +3 -3
  104. package/package.json +1 -9
  105. package/src/cli/shared/server-startup.ts +8 -0
  106. package/src/deno.js +5 -12
  107. package/src/src/agent/durable.ts +237 -0
  108. package/src/src/agent/index.ts +4 -0
  109. package/src/src/cache/backends/factory.ts +1 -1
  110. package/src/src/cache/backends/redis.ts +1 -1
  111. package/src/src/cache/keys/utils.ts +1 -1
  112. package/src/src/cache/registry.ts +1 -1
  113. package/src/src/data/static-paths-fetcher.ts +1 -1
  114. package/src/src/embedding/upload-loader.ts +14 -63
  115. package/src/src/errors/middleware/cli-error-boundary.ts +1 -1
  116. package/src/src/errors/middleware/http-error-boundary.ts +1 -1
  117. package/src/src/errors/tracing.ts +4 -4
  118. package/src/src/extensions/interfaces/index.ts +7 -2
  119. package/src/src/extensions/interfaces/node-compat.ts +74 -10
  120. package/src/src/extensions/interfaces/tracing-exporter.ts +36 -1
  121. package/src/src/mcp/index.ts +7 -2
  122. package/src/src/mcp/schemas/index.ts +1 -0
  123. package/src/src/mcp/schemas/mcp.schema.ts +20 -7
  124. package/src/src/mcp/server.ts +60 -6
  125. package/src/src/observability/auto-instrument/http-instrumentation.ts +1 -1
  126. package/src/src/observability/auto-instrument/react-instrumentation.ts +1 -1
  127. package/src/src/observability/auto-instrument/wrappers.ts +1 -1
  128. package/src/src/observability/instruments/build-instruments.ts +1 -1
  129. package/src/src/observability/instruments/cache-instruments.ts +6 -1
  130. package/src/src/observability/instruments/data-instruments.ts +1 -1
  131. package/src/src/observability/instruments/error-instruments.ts +1 -1
  132. package/src/src/observability/instruments/http-instruments.ts +6 -1
  133. package/src/src/observability/instruments/instruments-factory.ts +1 -1
  134. package/src/src/observability/instruments/memory-instruments.ts +5 -1
  135. package/src/src/observability/instruments/render-instruments.ts +1 -1
  136. package/src/src/observability/instruments/rsc-instruments.ts +1 -1
  137. package/src/src/observability/metrics/manager.ts +11 -3
  138. package/src/src/observability/metrics/types.ts +7 -1
  139. package/src/src/observability/simple-metrics/otel-instruments.ts +7 -2
  140. package/src/src/observability/simple-metrics/types.ts +1 -1
  141. package/src/src/observability/tracing/api-shim.ts +409 -0
  142. package/src/src/observability/tracing/manager.ts +29 -4
  143. package/src/src/observability/tracing/otlp-setup.ts +76 -168
  144. package/src/src/observability/tracing/types.ts +1 -1
  145. package/src/src/platform/compat/kv/factory.ts +18 -7
  146. package/src/src/platform/compat/opaque-deps.ts +16 -44
  147. package/src/src/proxy/tracing.ts +43 -117
  148. package/src/src/rendering/rsc/client-module-strategy.ts +9 -1
  149. package/src/src/server/bootstrap.ts +38 -1
  150. package/src/src/server/context/request-context.ts +10 -7
  151. package/src/src/server/dev-server/middleware.ts +1 -1
  152. package/src/src/server/handlers/dev/files/dev-file.handler.ts +4 -22
  153. package/src/src/server/services/rendering/ssr.service.ts +4 -1
  154. package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +1 -1
  155. package/src/src/utils/version-constant.ts +1 -1
  156. package/src/src/workflow/claude-code/workspace-sync.ts +109 -20
  157. package/esm/src/utils/logger/trace-bridge.d.ts +0 -11
  158. package/esm/src/utils/logger/trace-bridge.d.ts.map +0 -1
  159. package/esm/src/utils/logger/trace-bridge.js +0 -12
  160. package/src/src/utils/logger/trace-bridge.ts +0 -14
@@ -9,7 +9,7 @@
9
9
  import { VERSION } from "../../utils/version.js";
10
10
  import { withSpan } from "../../observability/tracing/otlp-setup.js";
11
11
  import { SpanNames } from "../../observability/tracing/span-names.js";
12
- import type { Span } from "@opentelemetry/api";
12
+ import type { Span } from "../../observability/tracing/api-shim.js";
13
13
 
14
14
  import { cacheRegistry } from "../registry.js";
15
15
 
@@ -2,7 +2,7 @@ import { rendererLogger } from "../utils/index.js";
2
2
  import { getRedisClient, isRedisConfigured } from "../utils/redis-client.js";
3
3
  import { withSpan } from "../observability/tracing/otlp-setup.js";
4
4
  import { SpanNames } from "../observability/tracing/span-names.js";
5
- import type { Span } from "@opentelemetry/api";
5
+ import type { Span } from "../observability/tracing/api-shim.js";
6
6
 
7
7
  const logger = rendererLogger.component("cache-registry");
8
8
 
@@ -2,7 +2,7 @@ import type { PageWithData, StaticPathsResult } from "./types.js";
2
2
  import { serverLogger } from "../utils/index.js";
3
3
  import { withSpan } from "../observability/tracing/otlp-setup.js";
4
4
  import { SpanNames } from "../observability/tracing/span-names.js";
5
- import type { Span } from "@opentelemetry/api";
5
+ import type { Span } from "../observability/tracing/api-shim.js";
6
6
 
7
7
  const EMPTY_STATIC_PATHS_RESULT: StaticPathsResult = { paths: [], fallback: false };
8
8
 
@@ -1,18 +1,13 @@
1
- import * as dntShim from "../../_dnt.shims.js";
2
- import { importKreuzberg } from "../platform/compat/opaque-deps.js";
3
- import { isDeno } from "../platform/compat/runtime.js";
4
- import { serverLogger } from "../utils/index.js";
5
-
6
- /** Maximum time to wait for document text extraction before aborting. */
7
- const EXTRACTION_TIMEOUT_MS = 30_000;
1
+ import { tryResolve } from "../extensions/contracts.js";
2
+ import type { NodeCompat } from "../extensions/interfaces/node-compat.js";
8
3
 
9
4
  /**
10
5
  * Extracts plain text from various upload formats.
11
6
  *
12
7
  * Text and CSV are handled inline (CSV uses a RAG-optimized format that
13
8
  * denormalizes headers into every row). All other formats (PDF, DOCX, XLSX,
14
- * PPTX, HTML, RTF, EPUB, etc.) are delegated to kreuzberg for extraction
15
- * inside a Worker thread so that hung WASM calls cannot block the server.
9
+ * PPTX, HTML, RTF, EPUB, etc.) are delegated to the `NodeCompat` extension
10
+ * contract, which owns kreuzberg and the Worker isolation on Deno.
16
11
  *
17
12
  * @example
18
13
  * ```ts
@@ -34,61 +29,17 @@ export async function loadUpload(buffer: ArrayBuffer, mimeType: string): Promise
34
29
  return new TextDecoder().decode(buffer);
35
30
  }
36
31
 
37
- // Everything else (PDF, DOCX, XLSX, PPTX, HTML, XML, etc.) → kreuzberg
38
- // Deno: run in a Worker thread to prevent hung WASM from blocking the server.
39
- // Node/Bun: call kreuzberg directly (no global Worker; @kreuzberg/node uses
40
- // native bindings that don't have the WASM hang issue).
41
- if (isDeno) {
42
- return extractInWorker(buffer, mimeType);
32
+ // Everything else (PDF, DOCX, XLSX, PPTX, HTML, XML, etc.) → NodeCompat.
33
+ // Synchronous registry check so the missing-extension error surfaces
34
+ // directly from `loadUpload()` rather than through a spawned Worker.
35
+ const nodeCompat = tryResolve<NodeCompat>("NodeCompat");
36
+ if (!nodeCompat?.extractInWorker) {
37
+ throw new Error(
38
+ "Document extraction requires the NodeCompat extension. " +
39
+ "Install @veryfront/ext-node-compat and add it to your extensions configuration.",
40
+ );
43
41
  }
44
- return extractDirect(buffer, mimeType);
45
- }
46
-
47
- async function extractDirect(
48
- buffer: ArrayBuffer,
49
- mimeType: string,
50
- ): Promise<string> {
51
- const { extractBytes } = await importKreuzberg();
52
- const result = await extractBytes(new Uint8Array(buffer), mimeType);
53
- return result.content;
54
- }
55
-
56
- function extractInWorker(buffer: ArrayBuffer, mimeType: string): Promise<string> {
57
- return new Promise<string>((resolve, reject) => {
58
- const workerUrl = new URL("./upload-extraction-worker.ts", import.meta.url);
59
- const worker = new Worker(workerUrl, { type: "module" });
60
-
61
- const timer = dntShim.setTimeout(() => {
62
- worker.terminate();
63
- reject(
64
- new Error(
65
- `Text extraction timed out after ${
66
- EXTRACTION_TIMEOUT_MS / 1000
67
- }s — the file may be corrupted or unsupported`,
68
- ),
69
- );
70
- }, EXTRACTION_TIMEOUT_MS);
71
-
72
- worker.onmessage = (event: MessageEvent) => {
73
- clearTimeout(timer);
74
- worker.terminate();
75
- const { content, error } = event.data;
76
- if (error) {
77
- reject(new Error(error));
78
- } else {
79
- resolve(content);
80
- }
81
- };
82
-
83
- worker.onerror = (event) => {
84
- clearTimeout(timer);
85
- worker.terminate();
86
- serverLogger.error("[upload-loader] Worker error:", event);
87
- reject(new Error("Text extraction worker failed"));
88
- };
89
-
90
- worker.postMessage({ buffer, mimeType }, [buffer]);
91
- });
42
+ return nodeCompat.extractInWorker(buffer, mimeType);
92
43
  }
93
44
 
94
45
  function extractCSV(buffer: ArrayBuffer): string {
@@ -9,7 +9,7 @@
9
9
  import * as dntShim from "../../../_dnt.shims.js";
10
10
 
11
11
 
12
- import { trace } from "@opentelemetry/api";
12
+ import { trace } from "../../observability/tracing/api-shim.js";
13
13
  import { VeryfrontError } from "../types.js";
14
14
  import { UNKNOWN_ERROR } from "../error-registry.js";
15
15
  import { getErrorMessage } from "../veryfront-error.js";
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import type { Handler, HandlerContext, HandlerResult } from "../../types/index.js";
12
- import { trace } from "@opentelemetry/api";
12
+ import { trace } from "../../observability/tracing/api-shim.js";
13
13
  import { PROBLEM_JSON_CONTENT_TYPE } from "../http-error.js";
14
14
  import { recordErrorCount } from "../../observability/metrics/index.js";
15
15
  import { attachErrorToActiveSpan } from "../tracing.js";
@@ -4,8 +4,8 @@
4
4
  * Attaches error metadata to spans for distributed tracing and error correlation.
5
5
  */
6
6
 
7
- import type { Span } from "@opentelemetry/api";
8
- import { SpanStatusCode } from "@opentelemetry/api";
7
+ import type { Span } from "../observability/tracing/api-shim.js";
8
+ import { SpanStatusCode } from "../observability/tracing/api-shim.js";
9
9
  import type { VeryfrontError } from "./types.js";
10
10
 
11
11
  /**
@@ -27,7 +27,7 @@ import type { VeryfrontError } from "./types.js";
27
27
  *
28
28
  * @example
29
29
  * ```typescript
30
- * import { trace } from "@opentelemetry/api";
30
+ * import { trace } from "#veryfront/observability/tracing/api-shim.ts";
31
31
  *
32
32
  * const span = trace.getActiveSpan();
33
33
  * if (span) {
@@ -68,7 +68,7 @@ export function attachErrorToSpan(error: VeryfrontError, span: Span): void {
68
68
  *
69
69
  * @example
70
70
  * ```typescript
71
- * import { trace } from "@opentelemetry/api";
71
+ * import { trace } from "#veryfront/observability/tracing/api-shim.ts";
72
72
  *
73
73
  * try {
74
74
  * // ... operation that may throw
@@ -49,7 +49,7 @@ export type {
49
49
  } from "./auth-provider.js";
50
50
 
51
51
  // Tracing exporter
52
- export type { SpanData, TracingExporter } from "./tracing-exporter.js";
52
+ export type { SpanData, TracerProvider, TracingExporter } from "./tracing-exporter.js";
53
53
 
54
54
  // AI model provider
55
55
  export type {
@@ -87,4 +87,9 @@ export type {
87
87
  } from "./schema-validator.js";
88
88
 
89
89
  // Node compatibility
90
- export type { NodeCompat } from "./node-compat.js";
90
+ export type {
91
+ KreuzbergExtractor,
92
+ NodeCompat,
93
+ NodeCompatSqliteDatabase,
94
+ SqliteStatement,
95
+ } from "./node-compat.js";
@@ -6,20 +6,84 @@
6
6
  * @module extensions/interfaces/node-compat
7
7
  */
8
8
 
9
+ /**
10
+ * Minimal interface for a prepared SQLite statement, compatible with
11
+ * `better-sqlite3`'s `Statement` shape.
12
+ */
13
+ export interface SqliteStatement {
14
+ get(...params: unknown[]): unknown;
15
+ run(...params: unknown[]): void;
16
+ all(...params: unknown[]): unknown[];
17
+ }
18
+
19
+ /**
20
+ * Minimal interface for a SQLite database connection, compatible with
21
+ * `better-sqlite3`'s `Database` shape as consumed by `SqliteKv`.
22
+ *
23
+ * Mirrors `SqliteDatabase` in `src/platform/compat/kv/types.ts` — kept
24
+ * separate here so extensions can import from the public
25
+ * `veryfront/extensions/interfaces` entrypoint without taking a dependency
26
+ * on internal platform paths.
27
+ */
28
+ export interface NodeCompatSqliteDatabase {
29
+ exec(sql: string): void;
30
+ prepare(sql: string): SqliteStatement;
31
+ close(): void;
32
+ }
33
+
34
+ /**
35
+ * Shape returned by the kreuzberg document-extraction module.
36
+ *
37
+ * Matches the subset used by `importKreuzberg()` in `opaque-deps.ts`.
38
+ */
39
+ export interface KreuzbergExtractor {
40
+ extractBytes(
41
+ data: Uint8Array,
42
+ mimeType: string,
43
+ ): Promise<{ content: string }>;
44
+ }
45
+
9
46
  /**
10
47
  * NodeCompat contract interface.
11
48
  *
12
- * Implementations provide access to Node.js-compatible APIs in
13
- * environments where native Node modules are unavailable (e.g. Deno).
49
+ * Implementations provide access to Node.js-only packages
50
+ * (`@kreuzberg/wasm`, `better-sqlite3`) in environments where those
51
+ * packages are available (i.e. a full Node/Deno runtime, not a compiled
52
+ * binary or edge runtime).
14
53
  *
15
- * Each getter returns the module's namespace object, matching the
16
- * shape of the corresponding Node.js built-in.
54
+ * Both methods are optional on the interface so that partial
55
+ * implementations (e.g. SQLite-only or kreuzberg-only) are valid.
17
56
  */
18
57
  export interface NodeCompat {
19
- /** Return a Node-compatible `fs` module (sync + async + promises). */
20
- getFS(): unknown;
21
- /** Return a Node-compatible `path` module. */
22
- getPath(): unknown;
23
- /** Return a Node-compatible `WebSocket` constructor. */
24
- getWebSocket(): unknown;
58
+ /**
59
+ * Initialise and return the kreuzberg document-extraction module.
60
+ *
61
+ * Callers should fall back to a "no extraction" path when this
62
+ * method is absent or throws.
63
+ */
64
+ importKreuzberg?(): Promise<KreuzbergExtractor>;
65
+
66
+ /**
67
+ * Run kreuzberg extraction inside an isolated Worker thread.
68
+ *
69
+ * Owned by the extension so that the worker script lives in a module
70
+ * graph where `@kreuzberg/wasm` resolves and the NodeCompat contract
71
+ * is reachable (Deno worker isolates do not share the main-thread
72
+ * contract registry).
73
+ *
74
+ * Callers on Node/Bun can skip workers and use `importKreuzberg()`
75
+ * directly — native bindings don't need WASM-hang isolation.
76
+ */
77
+ extractInWorker?(buffer: ArrayBuffer, mimeType: string): Promise<string>;
78
+
79
+ /**
80
+ * Open (or create) a SQLite database at `path`.
81
+ *
82
+ * Returns a database compatible with `SqliteKv`.
83
+ * When `path` is omitted an in-memory database is created.
84
+ *
85
+ * Callers should fall back to the in-memory KV when this method is
86
+ * absent or throws.
87
+ */
88
+ openSqliteDatabase?(path?: string): Promise<NodeCompatSqliteDatabase>;
25
89
  }
@@ -6,6 +6,14 @@
6
6
  * @module extensions/interfaces/tracing-exporter
7
7
  */
8
8
 
9
+ /**
10
+ * Minimal TracerProvider interface for the contract.
11
+ * Structurally compatible with both the core shim and the real OTel SDK.
12
+ */
13
+ export interface TracerProvider {
14
+ getTracer(name: string, version?: string): unknown;
15
+ }
16
+
9
17
  /** Data describing a single trace span. */
10
18
  export interface SpanData {
11
19
  /** Unique span identifier. */
@@ -32,11 +40,38 @@ export interface SpanData {
32
40
  * TracingExporter contract interface.
33
41
  *
34
42
  * Implementations export collected trace spans to an observability
35
- * backend (e.g. Jaeger, Zipkin, OTLP collector).
43
+ * backend (e.g. Jaeger, Zipkin, OTLP collector) and expose the SDK
44
+ * TracerProvider so the core shim can delegate to it.
36
45
  */
37
46
  export interface TracingExporter {
47
+ /**
48
+ * Initialize the SDK provider and exporter.
49
+ * Called during extension setup.
50
+ */
51
+ start(config: Record<string, unknown>): Promise<void>;
52
+
38
53
  /** Export a batch of completed spans. */
39
54
  export(spans: SpanData[]): Promise<void>;
55
+
40
56
  /** Flush pending data and release resources. */
41
57
  shutdown(): Promise<void>;
58
+
59
+ /**
60
+ * Return the SDK TracerProvider so the core shim can delegate to it.
61
+ * The shim calls this after `start()` completes.
62
+ */
63
+ getProvider(): TracerProvider;
64
+
65
+ /**
66
+ * Return the OTel Metrics API so the metrics subsystem can get meters.
67
+ * Returns `null` when metrics are not available.
68
+ */
69
+ getMetricsAPI(): { getMeter(name: string | undefined, version?: string): unknown } | null;
70
+
71
+ /**
72
+ * Return the OTel Trace API so the core shim can look up the active span
73
+ * (for error correlation, proxy trace-id extraction, etc.). Returns `null`
74
+ * when tracing is disabled.
75
+ */
76
+ getTraceAPI?(): { getActiveSpan(): unknown; getSpan(ctx: unknown): unknown } | null;
42
77
  }
@@ -17,8 +17,13 @@
17
17
  * execute: async ({ query }) => ({ results: [] }),
18
18
  * });
19
19
  *
20
- * // Start MCP server — registered tools are exposed automatically
21
- * const server = createMCPServer();
20
+ * // Start MCP server — registered tools are exposed automatically.
21
+ * // `auth` is required: use bearer for production, or the explicit
22
+ * // `{ type: "none", allowUnauthenticated: true }` opt-in for local dev only.
23
+ * const server = createMCPServer({
24
+ * enabled: true,
25
+ * auth: { type: "none", allowUnauthenticated: true },
26
+ * });
22
27
  * ```
23
28
  */
24
29
  import "../../_dnt.polyfills.js";
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  export {
8
+ MCPAuthConfigSchema,
8
9
  type MCPServerConfig,
9
10
  MCPServerConfigSchema,
10
11
  type MCPStats,
@@ -1,15 +1,28 @@
1
1
  import { z } from "zod";
2
2
 
3
+ /**
4
+ * MCP auth configuration. One of:
5
+ * - `{ type: "bearer", validate?: (token) => Promise<boolean> }` — bearer-token auth.
6
+ * - `{ type: "none", allowUnauthenticated: true }` — explicit opt-in to an
7
+ * unauthenticated server. Required for local dev/testing; prevents accidental
8
+ * exposure of the JSON-RPC surface in production (VULN-SRV-5).
9
+ */
10
+ const AuthValidatedSchema = z.object({
11
+ type: z.literal("bearer"),
12
+ validate: z.function().optional(),
13
+ });
14
+
15
+ const AuthNoneSchema = z.object({
16
+ type: z.literal("none"),
17
+ allowUnauthenticated: z.literal(true),
18
+ });
19
+
20
+ export const MCPAuthConfigSchema = z.union([AuthValidatedSchema, AuthNoneSchema]);
21
+
3
22
  export const MCPServerConfigSchema = z.object({
4
23
  enabled: z.boolean(),
5
24
  port: z.number().int().positive().optional(),
6
- auth: z
7
- .object({
8
- type: z.enum(["bearer", "api-key", "none"]),
9
- validate: z.function()
10
- .optional(),
11
- })
12
- .optional(),
25
+ auth: MCPAuthConfigSchema,
13
26
  cors: z
14
27
  .object({
15
28
  enabled: z.boolean(),
@@ -113,13 +113,69 @@ export class MCPServer {
113
113
  onNotification?: (notification: { jsonrpc: "2.0"; method: string; params?: unknown }) => void;
114
114
 
115
115
  constructor(config: MCPServerConfig) {
116
+ MCPServer.validateAuthConfig(config);
116
117
  this.config = config;
117
118
 
118
- if (!config.auth || config.auth.type === "none") {
119
- logger.warn("MCP server has no authentication configured — all requests will be accepted");
119
+ if (config.auth.type === "none") {
120
+ logger.warn(
121
+ "MCP server started with auth.type='none' (allowUnauthenticated) — all requests will be accepted",
122
+ );
120
123
  }
121
124
  }
122
125
 
126
+ /**
127
+ * Fail-closed validation of the auth configuration (VULN-SRV-5).
128
+ *
129
+ * Historically, an unset `auth` field — or `{ type: "none" }` — silently
130
+ * accepted every request with only a warning log. That meant an operator who
131
+ * forgot to configure auth shipped an unauthenticated JSON-RPC surface.
132
+ *
133
+ * The new contract: `auth` is required, and the only way to accept
134
+ * unauthenticated traffic is to explicitly set
135
+ * `{ type: "none", allowUnauthenticated: true }`. Any other shape is
136
+ * rejected at construction time.
137
+ */
138
+ private static validateAuthConfig(config: MCPServerConfig): void {
139
+ const auth = (config as { auth?: unknown }).auth;
140
+
141
+ if (auth === undefined || auth === null) {
142
+ throw new Error(
143
+ "MCP auth must be configured. For local dev, pass " +
144
+ "{ auth: { type: 'none', allowUnauthenticated: true } } explicitly.",
145
+ );
146
+ }
147
+
148
+ if (typeof auth !== "object") {
149
+ throw new Error(
150
+ "MCP auth must be an object. For local dev, pass " +
151
+ "{ auth: { type: 'none', allowUnauthenticated: true } } explicitly.",
152
+ );
153
+ }
154
+
155
+ const type = (auth as { type?: unknown }).type;
156
+
157
+ if (type === "none") {
158
+ const allow = (auth as { allowUnauthenticated?: unknown }).allowUnauthenticated;
159
+ if (allow !== true) {
160
+ throw new Error(
161
+ "MCP auth type 'none' requires allowUnauthenticated: true to acknowledge " +
162
+ "the server will accept all requests.",
163
+ );
164
+ }
165
+ return;
166
+ }
167
+
168
+ if (type === "bearer") {
169
+ return;
170
+ }
171
+
172
+ throw new Error(
173
+ `MCP auth type '${String(type)}' is not supported. Use 'bearer' ` +
174
+ "or { type: 'none', allowUnauthenticated: true } for explicit opt-in to " +
175
+ "unauthenticated traffic.",
176
+ );
177
+ }
178
+
123
179
  notifyToolsChanged(): void {
124
180
  this.onNotification?.({ jsonrpc: "2.0", method: "notifications/tools/list_changed" });
125
181
  }
@@ -607,7 +663,7 @@ export class MCPServer {
607
663
 
608
664
  createHTTPHandler(): (request: Request) => Promise<Response> {
609
665
  return createMCPHTTPHandler({
610
- authEnabled: Boolean(this.config.auth?.type && this.config.auth.type !== "none"),
666
+ authEnabled: this.config.auth.type !== "none",
611
667
  getCORSHeaders: (requestOrigin) => this.getCORSHeaders(requestOrigin),
612
668
  validateAuth: (request) => this.validateAuth(request),
613
669
  handleRequest: (request, context) => this.handleRequest(request, context),
@@ -640,13 +696,11 @@ export class MCPServer {
640
696
 
641
697
  private async validateAuth(request: Request): Promise<boolean> {
642
698
  const auth = this.config.auth;
643
- if (!auth || auth.type === "none") return true;
699
+ if (auth.type === "none") return true;
644
700
 
645
701
  const authHeader = request.headers.get("Authorization");
646
702
  if (!authHeader) return false;
647
703
 
648
- if (auth.type !== "bearer") return false;
649
-
650
704
  const token = authHeader.replace("Bearer ", "");
651
705
 
652
706
  // When bearer auth is configured without a validate function, reject all requests
@@ -6,7 +6,7 @@ import {
6
6
  SpanKind,
7
7
  SpanStatusCode,
8
8
  trace,
9
- } from "@opentelemetry/api";
9
+ } from "../tracing/api-shim.js";
10
10
  import type { ErrorAttributes, HttpAttributes } from "./types.js";
11
11
 
12
12
  const logger = serverLogger.component("auto-instrument");
@@ -1,4 +1,4 @@
1
- import { type Span, SpanStatusCode } from "@opentelemetry/api";
1
+ import { type Span, SpanStatusCode } from "../tracing/api-shim.js";
2
2
  import { endSpan, setSpanAttributes, SpanNames, startSpan, withSpan } from "../tracing/index.js";
3
3
  import { recordRenderError } from "../metrics/index.js";
4
4
 
@@ -1,4 +1,4 @@
1
- import type { Span } from "@opentelemetry/api";
1
+ import type { Span } from "../tracing/api-shim.js";
2
2
  import { endSpan, setSpanAttributes, type SpanOptions, startSpan } from "../tracing/index.js";
3
3
  import type { BatchOptions, InstrumentOptions } from "./types.js";
4
4
 
@@ -1,4 +1,4 @@
1
- import type { Counter, Histogram, Meter } from "@opentelemetry/api";
1
+ import type { Counter, Histogram, Meter } from "../tracing/api-shim.js";
2
2
  import {
3
3
  DURATION_HISTOGRAM_BOUNDARIES_MS,
4
4
  SIZE_HISTOGRAM_BOUNDARIES_KB,
@@ -1,4 +1,9 @@
1
- import type { Counter, Meter, ObservableGauge, ObservableResult } from "@opentelemetry/api";
1
+ import type {
2
+ Counter,
3
+ Meter,
4
+ ObservableGauge,
5
+ ObservableResult,
6
+ } from "../tracing/api-shim.js";
2
7
  import type { MetricsConfig, RuntimeState } from "../metrics/types.js";
3
8
 
4
9
  export interface CacheInstruments {
@@ -1,4 +1,4 @@
1
- import type { Counter, Histogram, Meter } from "@opentelemetry/api";
1
+ import type { Counter, Histogram, Meter } from "../tracing/api-shim.js";
2
2
  import { DURATION_HISTOGRAM_BOUNDARIES_MS } from "../../config/defaults.js";
3
3
  import type { MetricsConfig } from "../metrics/types.js";
4
4
 
@@ -5,7 +5,7 @@
5
5
  * observability dashboards and alerting.
6
6
  */
7
7
 
8
- import type { Counter, Meter } from "@opentelemetry/api";
8
+ import type { Counter, Meter } from "../tracing/api-shim.js";
9
9
  import type { MetricsConfig } from "../metrics/types.js";
10
10
  import type { VeryfrontError } from "../../errors/types.js";
11
11
 
@@ -1,4 +1,9 @@
1
- import type { Counter, Histogram, Meter, UpDownCounter } from "@opentelemetry/api";
1
+ import type {
2
+ Counter,
3
+ Histogram,
4
+ Meter,
5
+ UpDownCounter,
6
+ } from "../tracing/api-shim.js";
2
7
  import { DURATION_HISTOGRAM_BOUNDARIES_MS } from "../../config/defaults.js";
3
8
  import type { MetricsConfig } from "../metrics/types.js";
4
9
 
@@ -1,4 +1,4 @@
1
- import type { Meter } from "@opentelemetry/api";
1
+ import type { Meter } from "../tracing/api-shim.js";
2
2
  import { serverLogger } from "../../utils/index.js";
3
3
  import type { MetricsConfig, MetricsInstruments, RuntimeState } from "../metrics/types.js";
4
4
  import { createBuildInstruments } from "./build-instruments.js";
@@ -1,4 +1,8 @@
1
- import type { Meter, ObservableGauge, ObservableResult } from "@opentelemetry/api";
1
+ import type {
2
+ Meter,
3
+ ObservableGauge,
4
+ ObservableResult,
5
+ } from "../tracing/api-shim.js";
2
6
  import { getV8FlagsEnv } from "../../config/env.js";
3
7
  import { getMemoryUsage } from "../metrics/config.js";
4
8
  import type { MetricsConfig } from "../metrics/types.js";
@@ -1,4 +1,4 @@
1
- import type { Counter, Histogram, Meter } from "@opentelemetry/api";
1
+ import type { Counter, Histogram, Meter } from "../tracing/api-shim.js";
2
2
  import { DURATION_HISTOGRAM_BOUNDARIES_MS } from "../../config/defaults.js";
3
3
  import type { MetricsConfig } from "../metrics/types.js";
4
4
 
@@ -1,4 +1,4 @@
1
- import type { Counter, Histogram, Meter } from "@opentelemetry/api";
1
+ import type { Counter, Histogram, Meter } from "../tracing/api-shim.js";
2
2
  import { DURATION_HISTOGRAM_BOUNDARIES_MS } from "../../config/defaults.js";
3
3
  import type { MetricsConfig } from "../metrics/types.js";
4
4
 
@@ -3,7 +3,8 @@
3
3
  * Main OpenTelemetry metrics initialization and management
4
4
  */
5
5
 
6
- import type { Meter } from "@opentelemetry/api";
6
+ import type { Meter } from "../tracing/api-shim.js";
7
+ import { getGlobalMetricsAPI } from "../tracing/api-shim.js";
7
8
  import { serverLogger } from "../../utils/index.js";
8
9
  import type { RuntimeAdapter } from "../../platform/adapters/base.js";
9
10
  import { loadConfig } from "./config.js";
@@ -79,8 +80,15 @@ export class MetricsManager {
79
80
  }
80
81
 
81
82
  try {
82
- this.api = await import("@opentelemetry/api");
83
- this.meter = this.api.metrics.getMeter(finalConfig.prefix, RUNTIME_VERSION);
83
+ // The metrics API is injected by ext-opentelemetry via setGlobalMetricsAPI().
84
+ // When the extension is not active, metrics collection is disabled.
85
+ const metricsApi = getGlobalMetricsAPI();
86
+ if (!metricsApi) {
87
+ logger.debug("No metrics API available — metrics collection disabled");
88
+ return;
89
+ }
90
+ this.api = { metrics: metricsApi } as OpenTelemetryAPI;
91
+ this.meter = metricsApi.getMeter(finalConfig.prefix, RUNTIME_VERSION);
84
92
 
85
93
  this.instruments = initializeInstruments(this.meter, finalConfig, this.runtimeState);
86
94
  this.recorder.instruments = this.instruments;
@@ -3,7 +3,13 @@
3
3
  * Type definitions for OpenTelemetry metrics system
4
4
  */
5
5
 
6
- import type { Counter, Histogram, Meter, ObservableGauge, UpDownCounter } from "@opentelemetry/api";
6
+ import type {
7
+ Counter,
8
+ Histogram,
9
+ Meter,
10
+ ObservableGauge,
11
+ UpDownCounter,
12
+ } from "../tracing/api-shim.js";
7
13
 
8
14
  export interface OpenTelemetryAPI {
9
15
  metrics: {