veryfront 0.1.159 → 0.1.162

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 (51) hide show
  1. package/esm/deno.js +1 -1
  2. package/esm/src/agent/index.d.ts +1 -1
  3. package/esm/src/agent/index.d.ts.map +1 -1
  4. package/esm/src/agent/runtime/index.d.ts +2 -12
  5. package/esm/src/agent/runtime/index.d.ts.map +1 -1
  6. package/esm/src/agent/runtime/index.js +62 -25
  7. package/esm/src/agent/types.d.ts +37 -0
  8. package/esm/src/agent/types.d.ts.map +1 -1
  9. package/esm/src/mcp/http-transport.d.ts +33 -0
  10. package/esm/src/mcp/http-transport.d.ts.map +1 -0
  11. package/esm/src/mcp/http-transport.js +97 -0
  12. package/esm/src/mcp/server.d.ts.map +1 -1
  13. package/esm/src/mcp/server.js +14 -107
  14. package/esm/src/platform/adapters/fs/veryfront/base-operations.d.ts +1 -1
  15. package/esm/src/platform/adapters/fs/veryfront/base-operations.d.ts.map +1 -1
  16. package/esm/src/platform/adapters/fs/veryfront/directory-operations.d.ts.map +1 -1
  17. package/esm/src/platform/adapters/fs/veryfront/directory-operations.js +9 -52
  18. package/esm/src/platform/adapters/fs/veryfront/file-list-access.d.ts +33 -0
  19. package/esm/src/platform/adapters/fs/veryfront/file-list-access.d.ts.map +1 -0
  20. package/esm/src/platform/adapters/fs/veryfront/file-list-access.js +49 -0
  21. package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts +1 -20
  22. package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts.map +1 -1
  23. package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts.map +1 -1
  24. package/esm/src/platform/adapters/fs/veryfront/stat-operations.js +21 -94
  25. package/esm/src/tool/factory.d.ts +3 -5
  26. package/esm/src/tool/factory.d.ts.map +1 -1
  27. package/esm/src/tool/factory.js +2 -1
  28. package/esm/src/tool/index.d.ts +2 -0
  29. package/esm/src/tool/index.d.ts.map +1 -1
  30. package/esm/src/tool/index.js +1 -0
  31. package/esm/src/tool/remote-source-tools.d.ts +8 -0
  32. package/esm/src/tool/remote-source-tools.d.ts.map +1 -0
  33. package/esm/src/tool/remote-source-tools.js +33 -0
  34. package/esm/src/utils/version-constant.d.ts +1 -1
  35. package/esm/src/utils/version-constant.js +1 -1
  36. package/package.json +1 -1
  37. package/src/deno.js +1 -1
  38. package/src/src/agent/index.ts +6 -0
  39. package/src/src/agent/runtime/index.ts +118 -11
  40. package/src/src/agent/types.ts +47 -0
  41. package/src/src/mcp/http-transport.ts +163 -0
  42. package/src/src/mcp/server.ts +15 -123
  43. package/src/src/platform/adapters/fs/veryfront/base-operations.ts +1 -1
  44. package/src/src/platform/adapters/fs/veryfront/directory-operations.ts +10 -75
  45. package/src/src/platform/adapters/fs/veryfront/file-list-access.ts +109 -0
  46. package/src/src/platform/adapters/fs/veryfront/read-operations.ts +1 -22
  47. package/src/src/platform/adapters/fs/veryfront/stat-operations.ts +27 -120
  48. package/src/src/tool/factory.ts +4 -6
  49. package/src/src/tool/index.ts +5 -0
  50. package/src/src/tool/remote-source-tools.ts +54 -0
  51. package/src/src/utils/version-constant.ts +1 -1
@@ -1,4 +1,3 @@
1
- import * as dntShim from "../../_dnt.shims.js";
2
1
  import { getMCPRegistry } from "./registry.js";
3
2
  import { executeTool } from "../tool/index.js";
4
3
  import { zodToJsonSchema } from "../tool/schema/index.js";
@@ -7,15 +6,12 @@ import { promptRegistry } from "../prompt/index.js";
7
6
  import { createError, toError } from "../errors/veryfront-error.js";
8
7
  import { withSpan } from "../observability/tracing/otlp-setup.js";
9
8
  import { VERSION } from "../utils/version.js";
10
- import { validateContentType } from "../security/input-validation/limits.js";
11
- import { VeryfrontError } from "../security/input-validation/errors.js";
12
9
  import { logger as baseLogger } from "../utils/index.js";
10
+ import { createMCPHTTPHandler } from "./http-transport.js";
13
11
  import { SessionManager } from "./session.js";
14
12
  import { TaskStore } from "./task-store.js";
15
13
  const logger = baseLogger.component("mcp-server");
16
- const MAX_REQUEST_BODY_SIZE = 1_048_576; // 1 MB
17
14
  const MAX_CONTEXT_HEADER_LENGTH = 255;
18
- const JSON_CONTENT_TYPE = "application/json";
19
15
  const END_USER_ID_PATTERN = /^[a-zA-Z0-9._@-]+$/;
20
16
  const PROJECT_ID_PATTERN = /^[a-zA-Z0-9._-]+$/;
21
17
  class JsonRpcError extends Error {
@@ -46,18 +42,6 @@ function toParamsRecord(params) {
46
42
  return {};
47
43
  return params;
48
44
  }
49
- function createJSONResponse(body, init) {
50
- const headers = new dntShim.Headers(init?.headers);
51
- headers.set("Content-Type", JSON_CONTENT_TYPE);
52
- return new dntShim.Response(JSON.stringify(body), { ...init, headers });
53
- }
54
- function createJSONRPCErrorResponse(status, code, message) {
55
- return createJSONResponse({
56
- jsonrpc: "2.0",
57
- id: null,
58
- error: { code, message },
59
- }, { status });
60
- }
61
45
  function readAllowedHeader(request, headerName, pattern) {
62
46
  const value = request.headers.get(headerName);
63
47
  if (!value || value.length > MAX_CONTEXT_HEADER_LENGTH || !pattern.test(value)) {
@@ -485,96 +469,19 @@ export class MCPServer {
485
469
  return Promise.all(this.pendingTasks.values()).then(() => { });
486
470
  }
487
471
  createHTTPHandler() {
488
- return async (request) => {
489
- const requestOrigin = request.headers.get("Origin");
490
- // CORS preflight
491
- if (request.method === "OPTIONS") {
492
- return new dntShim.Response(null, { status: 204, headers: this.getCORSHeaders(requestOrigin) });
493
- }
494
- // Origin validation (DNS rebinding protection)
495
- if (requestOrigin && this.config.cors?.enabled && this.config.cors.origins?.length) {
496
- if (!this.config.cors.origins.includes(requestOrigin)) {
497
- return createJSONRPCErrorResponse(403, -32600, "Forbidden: Origin not allowed");
498
- }
499
- }
500
- // Auth check (applies to all methods including DELETE)
501
- if (this.config.auth?.type && this.config.auth.type !== "none") {
502
- const authorized = await this.validateAuth(request);
503
- if (!authorized)
504
- return new dntShim.Response("Unauthorized", { status: 401 });
505
- }
506
- // DELETE = terminate session
507
- if (request.method === "DELETE") {
508
- const sessionId = request.headers.get("MCP-Session-Id");
509
- if (sessionId) {
510
- this.sessionManager.terminate(sessionId);
511
- this.sessionCapabilities.delete(sessionId);
512
- }
513
- return new dntShim.Response(null, { status: 200, headers: this.getCORSHeaders(requestOrigin) });
514
- }
515
- // Only POST allowed for JSON-RPC messages
516
- if (request.method !== "POST") {
517
- return new dntShim.Response("Method Not Allowed", { status: 405 });
518
- }
519
- // Enforce request body size limit (fast path via Content-Length header)
520
- const contentLength = request.headers.get("content-length");
521
- if (contentLength && Number(contentLength) > MAX_REQUEST_BODY_SIZE) {
522
- return createJSONRPCErrorResponse(413, -32600, "Request body too large");
523
- }
524
- try {
525
- validateContentType(request, JSON_CONTENT_TYPE);
526
- }
527
- catch (error) {
528
- const message = error instanceof VeryfrontError ? error.message : "Invalid Content-Type";
529
- return createJSONRPCErrorResponse(400, -32700, message);
530
- }
531
- let rpcRequest;
532
- try {
533
- const bodyText = await request.text();
534
- if (bodyText.length > MAX_REQUEST_BODY_SIZE) {
535
- return createJSONRPCErrorResponse(413, -32600, "Request body too large");
536
- }
537
- rpcRequest = JSON.parse(bodyText);
538
- }
539
- catch (_) {
540
- // expected: malformed JSON in request body
541
- return createJSONRPCErrorResponse(400, -32700, "Parse error");
542
- }
543
- // Session management: initialize creates session, everything else requires it
544
- const responseHeaders = {
545
- ...this.getCORSHeaders(requestOrigin),
546
- };
547
- if (rpcRequest.method === "initialize") {
548
- const context = this.extractRequestContext(request);
549
- const rpcResponse = await this.handleRequest(rpcRequest, context);
550
- const clientCaps = toParamsRecord(rpcRequest.params).capabilities ??
551
- {};
552
- const sessionId = this.sessionManager.create();
553
- this.sessionCapabilities.set(sessionId, clientCaps);
554
- responseHeaders["MCP-Session-Id"] = sessionId;
555
- return createJSONResponse(rpcResponse, { headers: responseHeaders });
556
- }
557
- // Post-init: require session ID when sessions are active
558
- if (this.sessionManager.size > 0) {
559
- const sessionId = request.headers.get("MCP-Session-Id");
560
- if (!sessionId) {
561
- return createJSONRPCErrorResponse(400, -32600, "Missing MCP-Session-Id header");
562
- }
563
- if (!this.sessionManager.isValid(sessionId)) {
564
- return createJSONRPCErrorResponse(404, -32600, "Session not found or expired");
565
- }
566
- }
567
- // Notifications have no id member — return 202 Accepted
568
- // Note: id:0 is a valid request ID per JSON-RPC 2.0, so check for undefined
569
- if (rpcRequest.id === undefined) {
570
- const context = this.extractRequestContext(request);
571
- await this.handleRequest(rpcRequest, context);
572
- return new dntShim.Response(null, { status: 202, headers: responseHeaders });
573
- }
574
- const context = this.extractRequestContext(request);
575
- const rpcResponse = await this.handleRequest(rpcRequest, context);
576
- return createJSONResponse(rpcResponse, { headers: responseHeaders });
577
- };
472
+ return createMCPHTTPHandler({
473
+ authEnabled: Boolean(this.config.auth?.type && this.config.auth.type !== "none"),
474
+ getCORSHeaders: (requestOrigin) => this.getCORSHeaders(requestOrigin),
475
+ validateAuth: (request) => this.validateAuth(request),
476
+ handleRequest: (request, context) => this.handleRequest(request, context),
477
+ extractRequestContext: (request) => this.extractRequestContext(request),
478
+ isOriginAllowed: (requestOrigin) => !requestOrigin ||
479
+ !this.config.cors?.enabled ||
480
+ !this.config.cors.origins?.length ||
481
+ this.config.cors.origins.includes(requestOrigin),
482
+ sessionCapabilities: this.sessionCapabilities,
483
+ sessionManager: this.sessionManager,
484
+ });
578
485
  }
579
486
  extractRequestContext(request) {
580
487
  const context = {};
@@ -1,7 +1,7 @@
1
1
  import type { VeryfrontApiClient } from "../../veryfront-api-client/index.js";
2
2
  import { FileCache } from "../cache/file-cache.js";
3
+ import type { ContentContextProvider } from "./file-list-access.js";
3
4
  import { PathNormalizer } from "./path-normalizer.js";
4
- import type { ContentContextProvider } from "./read-operations.js";
5
5
  export declare class VeryfrontOperationsBase {
6
6
  protected readonly client: VeryfrontApiClient;
7
7
  protected readonly cache: FileCache;
@@ -1 +1 @@
1
- {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,qBAAa,uBAAuB;IAEhC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB;IAC7C,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS;IACnC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc;IAC7C,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,sBAAsB;gBAHxC,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,cAAc,EAC1B,eAAe,CAAC,EAAE,sBAAsB,YAAA;CAE9D"}
1
+ {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,qBAAa,uBAAuB;IAEhC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB;IAC7C,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS;IACnC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc;IAC7C,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,sBAAsB;gBAHxC,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,cAAc,EAC1B,eAAe,CAAC,EAAE,sBAAsB,YAAA;CAE9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"directory-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/directory-operations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAgB/D,qBAAa,mBAAoB,SAAQ,uBAAuB;IAC9D,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAA8B;IAElD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;YAsDlC,eAAe;IAa7B,OAAO,CAAC,SAAS;IA6DjB,SAAS,IAAI,IAAI;IAIjB,OAAO,CAAC,cAAc;CAuEvB"}
1
+ {"version":3,"file":"directory-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/directory-operations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAY/D,qBAAa,mBAAoB,SAAQ,uBAAuB;IAC9D,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAA8B;IAElD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;YAsDlC,eAAe;IAa7B,OAAO,CAAC,SAAS;IA6DjB,SAAS,IAAI,IAAI;IAIjB,OAAO,CAAC,cAAc;CAUvB"}
@@ -1,8 +1,8 @@
1
1
  import { logger as baseLogger } from "../../../../utils/index.js";
2
2
  import { VeryfrontOperationsBase } from "./base-operations.js";
3
- import { buildDirCacheKeyPrefix, buildFileCacheKeyPrefix, buildFileListCacheKey, } from "./cache-keys.js";
3
+ import { buildDirCacheKeyPrefix } from "./cache-keys.js";
4
+ import { loadAllProjectFiles } from "./file-list-access.js";
4
5
  import { withSpan } from "../../../../observability/tracing/otlp-setup.js";
5
- import { withRetryOnTransient } from "./retry.js";
6
6
  const logger = baseLogger.component("directory-operations");
7
7
  export class DirectoryOperations extends VeryfrontOperationsBase {
8
8
  dirTree = null;
@@ -110,55 +110,12 @@ export class DirectoryOperations extends VeryfrontOperationsBase {
110
110
  this.dirTree = null;
111
111
  }
112
112
  getAllFilesRaw() {
113
- return withSpan("fs.veryfront.getAllFilesRaw", async () => {
114
- const cacheStart = performance.now();
115
- const ctx = this.contextProvider?.getContentContext();
116
- const cacheKeyPrefix = buildFileCacheKeyPrefix(ctx);
117
- const skipPersistentCache = this.contextProvider?.isPersistentCacheInvalidated?.(cacheKeyPrefix) ?? false;
118
- const adapterFiles = !skipPersistentCache
119
- ? await this.contextProvider?.getFileList?.()
120
- : undefined;
121
- if (adapterFiles) {
122
- const cacheMs = Math.round(performance.now() - cacheStart);
123
- logger.debug("getAllFilesRaw - from adapter cache", {
124
- cacheMs,
125
- fileCount: adapterFiles.length,
126
- });
127
- return adapterFiles;
128
- }
129
- const cacheKey = buildFileListCacheKey(ctx);
130
- if (skipPersistentCache) {
131
- logger.debug("getAllFilesRaw - skipping persistent cache", {
132
- cacheKey,
133
- cacheKeyPrefix,
134
- });
135
- }
136
- const cached = skipPersistentCache
137
- ? undefined
138
- : await this.cache.getAsync(cacheKey);
139
- const cacheMs = Math.round(performance.now() - cacheStart);
140
- if (cached) {
141
- logger.debug("getAllFilesRaw - fallback cache HIT", {
142
- cacheKey,
143
- cacheMs,
144
- fileCount: cached.length,
145
- });
146
- return cached;
147
- }
148
- logger.warn("getAllFilesRaw - cache MISS, fetching from API", {
149
- cacheKey,
150
- cacheMs,
151
- });
152
- const isPublished = ctx?.sourceType !== "branch";
153
- logger.debug("Fetching files from API", {
154
- sourceType: ctx?.sourceType,
155
- cacheKey,
156
- });
157
- const files = await withRetryOnTransient(() => isPublished
158
- ? this.client.listPublishedFiles(undefined, ctx?.releaseId ?? undefined, ctx?.environmentName ?? undefined)
159
- : this.client.listAllFiles(), "getAllFilesRaw (dir)");
160
- this.cache.set(cacheKey, files);
161
- return files;
162
- });
113
+ return withSpan("fs.veryfront.getAllFilesRaw", () => loadAllProjectFiles({
114
+ client: this.client,
115
+ cache: this.cache,
116
+ contextProvider: this.contextProvider,
117
+ logger,
118
+ operationLabel: "dir",
119
+ }));
163
120
  }
164
121
  }
@@ -0,0 +1,33 @@
1
+ import type { ProjectFile, VeryfrontApiClient } from "../../veryfront-api-client/index.js";
2
+ import { FileCache } from "../cache/file-cache.js";
3
+ import type { ResolvedContentContext } from "./types.js";
4
+ export interface ContentContextProvider {
5
+ isProductionMode: () => boolean;
6
+ getReleaseId: () => string | null;
7
+ getContentContext: () => ResolvedContentContext | null;
8
+ getFileList?: () => Promise<Array<{
9
+ id?: string;
10
+ path: string;
11
+ content?: string;
12
+ type?: string;
13
+ size?: number;
14
+ updated_at?: string;
15
+ }> | undefined>;
16
+ hasCachedFileList?: () => Promise<boolean>;
17
+ isPersistentCacheInvalidated?: (prefix: string) => boolean;
18
+ isReleaseBeingInvalidated?: (releaseId: string) => boolean;
19
+ }
20
+ interface FileListLogger {
21
+ debug(message: string, context?: Record<string, unknown>): void;
22
+ warn(message: string, context?: Record<string, unknown>): void;
23
+ }
24
+ interface LoadAllProjectFilesOptions {
25
+ client: VeryfrontApiClient;
26
+ cache: FileCache;
27
+ contextProvider?: ContentContextProvider;
28
+ logger: FileListLogger;
29
+ operationLabel: string;
30
+ }
31
+ export declare function loadAllProjectFiles({ client, cache, contextProvider, logger, operationLabel, }: LoadAllProjectFilesOptions): Promise<ProjectFile[]>;
32
+ export {};
33
+ //# sourceMappingURL=file-list-access.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-list-access.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/file-list-access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,MAAM,OAAO,CAAC;IAChC,YAAY,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,MAAM,sBAAsB,GAAG,IAAI,CAAC;IACvD,WAAW,CAAC,EAAE,MAAM,OAAO,CACzB,KAAK,CAAC;QACJ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,GAAG,SAAS,CACf,CAAC;IACF,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,4BAA4B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3D,yBAAyB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAC5D;AAED,UAAU,cAAc;IACtB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAChE;AAED,UAAU,0BAA0B;IAClC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,KAAK,EAAE,SAAS,CAAC;IACjB,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,mBAAmB,CAAC,EACxC,MAAM,EACN,KAAK,EACL,eAAe,EACf,MAAM,EACN,cAAc,GACf,EAAE,0BAA0B,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAgErD"}
@@ -0,0 +1,49 @@
1
+ import { buildFileCacheKeyPrefix, buildFileListCacheKey } from "./cache-keys.js";
2
+ import { withRetryOnTransient } from "./retry.js";
3
+ export async function loadAllProjectFiles({ client, cache, contextProvider, logger, operationLabel, }) {
4
+ const cacheStart = performance.now();
5
+ const ctx = contextProvider?.getContentContext();
6
+ const cacheKeyPrefix = buildFileCacheKeyPrefix(ctx);
7
+ const skipPersistentCache = contextProvider?.isPersistentCacheInvalidated?.(cacheKeyPrefix) ??
8
+ false;
9
+ const adapterFiles = !skipPersistentCache ? await contextProvider?.getFileList?.() : undefined;
10
+ if (adapterFiles) {
11
+ const cacheMs = Math.round(performance.now() - cacheStart);
12
+ logger.debug("getAllFilesRaw - from adapter cache", {
13
+ cacheMs,
14
+ fileCount: adapterFiles.length,
15
+ });
16
+ return adapterFiles;
17
+ }
18
+ const cacheKey = buildFileListCacheKey(ctx);
19
+ if (skipPersistentCache) {
20
+ logger.debug("getAllFilesRaw - skipping persistent cache", {
21
+ cacheKey,
22
+ cacheKeyPrefix,
23
+ });
24
+ }
25
+ const cached = skipPersistentCache ? undefined : await cache.getAsync(cacheKey);
26
+ const cacheMs = Math.round(performance.now() - cacheStart);
27
+ if (cached) {
28
+ logger.debug("getAllFilesRaw - fallback cache HIT", {
29
+ cacheKey,
30
+ cacheMs,
31
+ fileCount: cached.length,
32
+ });
33
+ return cached;
34
+ }
35
+ logger.warn("getAllFilesRaw - cache MISS, fetching from API", {
36
+ cacheKey,
37
+ cacheMs,
38
+ });
39
+ const isPublished = ctx?.sourceType !== "branch";
40
+ logger.debug("Fetching files from API", {
41
+ sourceType: ctx?.sourceType,
42
+ cacheKey,
43
+ });
44
+ const files = await withRetryOnTransient(() => isPublished
45
+ ? client.listPublishedFiles(undefined, ctx?.releaseId ?? undefined, ctx?.environmentName ?? undefined)
46
+ : client.listAllFiles(), `getAllFilesRaw (${operationLabel})`);
47
+ cache.set(cacheKey, files);
48
+ return files;
49
+ }
@@ -1,27 +1,8 @@
1
1
  import type { VeryfrontApiClient } from "../../veryfront-api-client/index.js";
2
2
  import { FileCache } from "../cache/file-cache.js";
3
3
  import { PathNormalizer } from "./path-normalizer.js";
4
- import type { ResolvedContentContext } from "./types.js";
4
+ import type { ContentContextProvider } from "./file-list-access.js";
5
5
  export { endRequestMetrics, getContentMetricsSnapshot, resetContentMetrics, startRequestMetrics, } from "./content-metrics.js";
6
- export interface ContentContextProvider {
7
- isProductionMode: () => boolean;
8
- getReleaseId: () => string | null;
9
- getContentContext: () => ResolvedContentContext | null;
10
- /** Cached file list from adapter initialization (single source of truth) */
11
- getFileList?: () => Promise<Array<{
12
- id?: string;
13
- path: string;
14
- content?: string;
15
- type?: string;
16
- size?: number;
17
- updated_at?: string;
18
- }> | undefined>;
19
- hasCachedFileList?: () => Promise<boolean>;
20
- /** True if cache prefix is being deleted - skip persistent cache reads */
21
- isPersistentCacheInvalidated?: (prefix: string) => boolean;
22
- /** Back-compat: release-scoped invalidation */
23
- isReleaseBeingInvalidated?: (releaseId: string) => boolean;
24
- }
25
6
  export declare class ReadOperations {
26
7
  private readonly client;
27
8
  private readonly cache;
@@ -1 +1 @@
1
- {"version":3,"file":"read-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/read-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAWtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAI9B,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,MAAM,OAAO,CAAC;IAChC,YAAY,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,MAAM,sBAAsB,GAAG,IAAI,CAAC;IACvD,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,OAAO,CACzB,KAAK,CAAC;QACJ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,GAAG,SAAS,CACf,CAAC;IACF,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,0EAA0E;IAC1E,4BAA4B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3D,+CAA+C;IAC/C,yBAAyB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAC5D;AAUD,qBAAa,cAAc;IAWvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAfpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAI9B;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,mGAAmG;IACnG,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA6B;gBAGnD,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,cAAc,EAC1B,eAAe,CAAC,EAAE,sBAAsB,YAAA,EACxC,kBAAkB,CAAC,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,aAAA,EAC7C,gBAAgB,CAAC,GAAE,MAAM,OAAO,CAC/C,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CACtD,aAAA;IAKH,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIrD,kBAAkB,IAAI,IAAI;IAK1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAY3C,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAY3C,OAAO,CAAC,mBAAmB;YAsBb,+BAA+B;YA0C/B,mBAAmB;IA0CjC,OAAO,CAAC,kBAAkB;YAoFZ,2BAA2B;YA8D3B,uCAAuC;IAmCrD,OAAO,CAAC,oBAAoB;YAgBd,YAAY;YA6JZ,qBAAqB;YA8DrB,qBAAqB;YAgDrB,+BAA+B;YA8D/B,iBAAiB;CAyBhC"}
1
+ {"version":3,"file":"read-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/read-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAapE,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAY9B,qBAAa,cAAc;IAWvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAfpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAI9B;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,mGAAmG;IACnG,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA6B;gBAGnD,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,cAAc,EAC1B,eAAe,CAAC,EAAE,sBAAsB,YAAA,EACxC,kBAAkB,CAAC,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,aAAA,EAC7C,gBAAgB,CAAC,GAAE,MAAM,OAAO,CAC/C,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CACtD,aAAA;IAKH,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIrD,kBAAkB,IAAI,IAAI;IAK1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAY3C,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAY3C,OAAO,CAAC,mBAAmB;YAsBb,+BAA+B;YA0C/B,mBAAmB;IA0CjC,OAAO,CAAC,kBAAkB;YAoFZ,2BAA2B;YA8D3B,uCAAuC;IAmCrD,OAAO,CAAC,oBAAoB;YAgBd,YAAY;YA6JZ,qBAAqB;YA8DrB,qBAAqB;YAgDrB,+BAA+B;YA8D/B,iBAAiB;CAyBhC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stat-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/stat-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AA2B/D,qBAAa,cAAe,SAAQ,uBAAuB;IACzD,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,aAAa,CAA8B;IAEnD,OAAO,CAAC,sBAAsB,CAA6B;IAC3D,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,OAAO,CAAC,WAAW,CAAkC;IAErD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAGrC;IAEH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;YAiHvB,gBAAgB;YAwChB,UAAU;IAkDxB,UAAU,IAAI,IAAI;IAMlB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM;YAIpC,cAAc;IAqE5B,OAAO,CAAC,0BAA0B;IA6BlC,OAAO,CAAC,qBAAqB;YAQf,sBAAsB;YAyEtB,iBAAiB;IASzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWtC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAwK1F"}
1
+ {"version":3,"file":"stat-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/stat-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAuB/D,qBAAa,cAAe,SAAQ,uBAAuB;IACzD,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,aAAa,CAA8B;IAEnD,OAAO,CAAC,sBAAsB,CAA6B;IAC3D,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,OAAO,CAAC,WAAW,CAAkC;IAErD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAGrC;IAEH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;YAiHvB,gBAAgB;YAwChB,UAAU;IAkDxB,UAAU,IAAI,IAAI;IAMlB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM;YAIpC,cAAc;IAU5B,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,qBAAqB;YAQf,sBAAsB;YA8EtB,iBAAiB;IASzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWtC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAkI1F"}
@@ -2,12 +2,12 @@ import { logger as baseLogger } from "../../../../utils/index.js";
2
2
  import { isFrameworkSourcePath } from "../../../../utils/path-utils.js";
3
3
  import { VeryfrontOperationsBase } from "./base-operations.js";
4
4
  import { createError, toError } from "../../../../errors/index.js";
5
- import { buildFileCacheKeyPrefix, buildFileListCacheKey, buildStatCacheKeyPrefix, } from "./cache-keys.js";
6
- import { withRetryOnTransient } from "./retry.js";
5
+ import { buildStatCacheKeyPrefix } from "./cache-keys.js";
7
6
  import { STAT_OPERATION_EXTENSION_PRIORITY as EXTENSION_PRIORITY } from "./extension-priority.js";
8
7
  import { collectParentDirectories, normalizeIndexedFilePath, resolveByExtensionPriority, resolveIndexByExtensionPriority, sortPathsByExtensionPriority, stripKnownExtension, } from "./stat-operations-helpers.js";
9
8
  import { ApiSearchCircuitBreaker } from "./api-search-circuit-breaker.js";
10
9
  import { withSpan } from "../../../../observability/tracing/otlp-setup.js";
10
+ import { loadAllProjectFiles } from "./file-list-access.js";
11
11
  const logger = baseLogger.component("stat-operations");
12
12
  const NOT_FOUND_SENTINEL = "__NOT_FOUND__";
13
13
  const API_SEARCH_CIRCUIT_BREAKER_THRESHOLD = 5;
@@ -206,56 +206,15 @@ export class StatOperations extends VeryfrontOperationsBase {
206
206
  return this.pathMapping.get(normalizedPath) ?? normalizedPath;
207
207
  }
208
208
  async getAllFilesRaw() {
209
- const cacheStart = performance.now();
210
- const ctx = this.contextProvider?.getContentContext();
211
- const cacheKeyPrefix = buildFileCacheKeyPrefix(ctx);
212
- const skipPersistentCache = this.contextProvider?.isPersistentCacheInvalidated?.(cacheKeyPrefix) ?? false;
213
- if (!skipPersistentCache) {
214
- const files = await this.contextProvider?.getFileList?.();
215
- if (files) {
216
- const cacheMs = Math.round(performance.now() - cacheStart);
217
- logger.debug("getAllFilesRaw - from adapter cache", {
218
- cacheMs,
219
- fileCount: files.length,
220
- });
221
- return files;
222
- }
223
- }
224
- const cacheKey = buildFileListCacheKey(ctx);
225
- if (skipPersistentCache) {
226
- logger.debug("getAllFilesRaw - skipping persistent cache (invalidation)", {
227
- cacheKey,
228
- cacheKeyPrefix,
229
- });
230
- }
231
- const cached = skipPersistentCache
232
- ? undefined
233
- : await this.cache.getAsync(cacheKey);
234
- const cacheMs = Math.round(performance.now() - cacheStart);
235
- if (cached) {
236
- logger.debug("getAllFilesRaw - fallback cache HIT", {
237
- cacheKey,
238
- cacheMs,
239
- fileCount: cached.length,
240
- });
241
- return cached;
242
- }
243
- logger.warn("getAllFilesRaw - cache MISS, fetching from API", {
244
- cacheKey,
245
- cacheMs,
209
+ return await loadAllProjectFiles({
210
+ client: this.client,
211
+ cache: this.cache,
212
+ contextProvider: this.contextProvider,
213
+ logger,
214
+ operationLabel: "stat",
246
215
  });
247
- const isPublished = ctx?.sourceType !== "branch";
248
- logger.debug("Fetching files from API", {
249
- sourceType: ctx?.sourceType,
250
- cacheKey,
251
- });
252
- const files = await withRetryOnTransient(() => isPublished
253
- ? this.client.listPublishedFiles(undefined, ctx?.releaseId ?? undefined, ctx?.environmentName ?? undefined)
254
- : this.client.listAllFiles(), "getAllFilesRaw (stat)");
255
- this.cache.set(cacheKey, files);
256
- return files;
257
216
  }
258
- buildResolveSearchPatterns(normalizedPath, options) {
217
+ buildResolveSearchPatterns(normalizedPath, options, knownExtensionFallback = "exact") {
259
218
  const patterns = new Set();
260
219
  const pathWithoutExt = stripKnownExtension(normalizedPath, EXTENSION_PRIORITY);
261
220
  const allowPagesPrefix = options?.allowPagesPrefix !== false;
@@ -264,7 +223,7 @@ export class StatOperations extends VeryfrontOperationsBase {
264
223
  patterns.add(pattern);
265
224
  };
266
225
  if (EXTENSION_PRIORITY.some((ext) => normalizedPath.endsWith(ext))) {
267
- addPattern(normalizedPath);
226
+ addPattern(knownExtensionFallback === "wildcard" ? `${pathWithoutExt}.*` : normalizedPath);
268
227
  return [...patterns];
269
228
  }
270
229
  addPattern(`${pathWithoutExt}.*`);
@@ -282,7 +241,7 @@ export class StatOperations extends VeryfrontOperationsBase {
282
241
  path: normalizeIndexedFilePath(match).normalizedPath,
283
242
  }));
284
243
  }
285
- async tryResolveViaApiSearch(normalizedPath, options) {
244
+ async tryResolveViaApiSearch(normalizedPath, options, knownExtensionFallback = "exact") {
286
245
  if (isFrameworkSourcePath(normalizedPath)) {
287
246
  logger.debug("Skipping API search for framework path", { normalizedPath });
288
247
  return null;
@@ -291,7 +250,7 @@ export class StatOperations extends VeryfrontOperationsBase {
291
250
  logger.warn("API search circuit breaker open, skipping", { normalizedPath });
292
251
  return undefined;
293
252
  }
294
- const patterns = this.buildResolveSearchPatterns(normalizedPath, options);
253
+ const patterns = this.buildResolveSearchPatterns(normalizedPath, options, knownExtensionFallback);
295
254
  let sawSuccessfulSearch = false;
296
255
  for (const pattern of patterns) {
297
256
  try {
@@ -459,49 +418,17 @@ export class StatOperations extends VeryfrontOperationsBase {
459
418
  logger.debug("Skipping API search for framework path", { normalizedPath });
460
419
  return null;
461
420
  }
462
- // NOTE: Removed optimization that skipped API search for paths with extensions.
463
- // This was causing layout files and other project files to not be found when
464
- // they were missing from the file index (due to cache issues, incomplete fetch, etc.).
465
- // The API pattern search is the fallback to ensure files can still be found.
466
- if (!this.apiSearchCircuitBreaker.canSearch()) {
467
- logger.warn("API search circuit breaker open, skipping", { normalizedPath });
468
- return null;
469
- }
470
- const searchPattern = `${pathWithoutExt}.*`;
471
- logger.debug("Searching for file via API", {
472
- pattern: searchPattern,
473
- normalizedPath,
474
- });
475
- try {
476
- const matches = await this.client.searchFiles(searchPattern);
477
- this.apiSearchCircuitBreaker.recordSuccess();
478
- logger.debug("API search result", {
479
- pattern: searchPattern,
480
- matchCount: matches.length,
481
- matches: matches.map((m) => m.path).slice(0, 5),
482
- });
483
- const sortedMatches = sortPathsByExtensionPriority(matches, EXTENSION_PRIORITY);
484
- const first = sortedMatches[0];
485
- if (first) {
486
- logger.debug("resolveFile found via API search", { path: first.path });
487
- this.cache.set(cacheKey, first.path);
488
- return first.path;
489
- }
421
+ // NOTE: Keep the post-index API fallback aligned with the pre-index helper for extensionless
422
+ // paths, while preserving the older wildcard sibling-extension lookup for known-extension
423
+ // paths. Incomplete file-list snapshots otherwise hide valid files until the cache refreshes.
424
+ const apiResolved = await this.tryResolveViaApiSearch(normalizedPath, options, "wildcard");
425
+ if (typeof apiResolved === "string") {
426
+ this.cache.set(cacheKey, apiResolved);
427
+ return apiResolved;
490
428
  }
491
- catch (error) {
492
- const result = this.apiSearchCircuitBreaker.recordFailure();
493
- if (result.tripped) {
494
- logger.warn("API search circuit breaker tripped", {
495
- failures: result.failures,
496
- });
497
- }
498
- logger.error("API pattern search failed", { pattern: searchPattern, error });
429
+ if (apiResolved === null) {
430
+ this.cache.set(cacheKey, NOT_FOUND_SENTINEL);
499
431
  }
500
- logger.debug("resolveFile not found after API search", {
501
- normalizedPath,
502
- pathWithoutExt,
503
- });
504
- this.cache.set(cacheKey, NOT_FOUND_SENTINEL);
505
432
  return null;
506
433
  }
507
434
  }
@@ -1,16 +1,14 @@
1
1
  import type { Tool, ToolConfig, ToolExecutionContext } from "./types.js";
2
+ import type { JsonSchema } from "./schema/json-schema.js";
2
3
  export declare function tool<TInput = unknown, TOutput = unknown>(config: ToolConfig<TInput, TOutput>): Tool<TInput, TOutput>;
3
4
  export interface DynamicToolConfig {
4
5
  id?: string;
5
6
  description: string;
6
7
  inputSchema: unknown;
8
+ inputSchemaJson?: JsonSchema;
7
9
  execute: (input: unknown, context?: ToolExecutionContext) => Promise<unknown> | unknown;
8
10
  toModelOutput?: (output: unknown) => unknown;
9
- mcp?: {
10
- enabled?: boolean;
11
- requiresAuth?: boolean;
12
- cachePolicy?: "no-cache" | "cache" | "cache-first";
13
- };
11
+ mcp?: ToolConfig["mcp"];
14
12
  }
15
13
  export declare function dynamicTool(config: DynamicToolConfig): Tool<unknown, unknown>;
16
14
  //# sourceMappingURL=factory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/src/tool/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAwIzE,wBAAgB,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EACtD,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAqCvB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACxF,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAC7C,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,WAAW,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,aAAa,CAAC;KACpD,CAAC;CACH;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CA2B7E"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/src/tool/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAuI1D,wBAAgB,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EACtD,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAqCvB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,UAAU,CAAC;IAC7B,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACxF,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAC7C,GAAG,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;CACzB;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CA4B7E"}
@@ -105,7 +105,8 @@ export function tool(config) {
105
105
  export function dynamicTool(config) {
106
106
  const explicitId = typeof config.id === "string" && config.id.length > 0 ? config.id : undefined;
107
107
  const id = explicitId ?? generateToolId();
108
- const inputSchemaJson = convertSchemaToJson(config.inputSchema, id, "DYNAMIC_TOOL", true);
108
+ const inputSchemaJson = config.inputSchemaJson ??
109
+ convertSchemaToJson(config.inputSchema, id, "DYNAMIC_TOOL", true);
109
110
  const createdTool = {
110
111
  id,
111
112
  type: "dynamic",
@@ -48,6 +48,8 @@ export { dynamicTool, tool } from "./factory.js";
48
48
  export type { DynamicToolConfig } from "./factory.js";
49
49
  export { createRemoteMCPToolSource } from "./remote-mcp.js";
50
50
  export type { RemoteMCPToolSourceConfig } from "./remote-mcp.js";
51
+ export { createToolsFromRemoteDefinitions, loadRemoteToolsFromSource, } from "./remote-source-tools.js";
52
+ export type { RemoteToolMaterializationOptions } from "./remote-source-tools.js";
51
53
  export { toolRegistry } from "./registry.js";
52
54
  export { executeTool } from "./executor.js";
53
55
  export type { JsonSchema } from "./schema/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/tool/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,OAAO,yBAAyB,CAAC;AAGjC,YAAY,EACV,gBAAgB,EAChB,IAAI,EACJ,UAAU,EACV,cAAc,EACd,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/tool/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,OAAO,yBAAyB,CAAC;AAGjC,YAAY,EACV,gBAAgB,EAChB,IAAI,EACJ,UAAU,EACV,cAAc,EACd,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EACL,gCAAgC,EAChC,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,gCAAgC,EAAE,MAAM,0BAA0B,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
@@ -45,5 +45,6 @@
45
45
  import "../../_dnt.polyfills.js";
46
46
  export { dynamicTool, tool } from "./factory.js";
47
47
  export { createRemoteMCPToolSource } from "./remote-mcp.js";
48
+ export { createToolsFromRemoteDefinitions, loadRemoteToolsFromSource, } from "./remote-source-tools.js";
48
49
  export { toolRegistry } from "./registry.js";
49
50
  export { executeTool } from "./executor.js";
@@ -0,0 +1,8 @@
1
+ import type { RemoteToolSource, Tool, ToolDefinition, ToolExecutionContext } from "./types.js";
2
+ export interface RemoteToolMaterializationOptions {
3
+ context?: ToolExecutionContext;
4
+ toolNameAliases?: Record<string, string>;
5
+ }
6
+ export declare function createToolsFromRemoteDefinitions(source: RemoteToolSource, definitions: readonly ToolDefinition[], options?: Omit<RemoteToolMaterializationOptions, "context">): Record<string, Tool<unknown, unknown>>;
7
+ export declare function loadRemoteToolsFromSource(source: RemoteToolSource, options?: RemoteToolMaterializationOptions): Promise<Record<string, Tool<unknown, unknown>>>;
8
+ //# sourceMappingURL=remote-source-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-source-tools.d.ts","sourceRoot":"","sources":["../../../src/src/tool/remote-source-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE/F,MAAM,WAAW,gCAAgC;IAC/C,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAUD,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,gBAAgB,EACxB,WAAW,EAAE,SAAS,cAAc,EAAE,EACtC,OAAO,GAAE,IAAI,CAAC,gCAAgC,EAAE,SAAS,CAAM,GAC9D,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAsBxC;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAKjD"}