veryfront 0.1.161 → 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 (34) hide show
  1. package/esm/deno.js +1 -1
  2. package/esm/src/platform/adapters/fs/veryfront/base-operations.d.ts +1 -1
  3. package/esm/src/platform/adapters/fs/veryfront/base-operations.d.ts.map +1 -1
  4. package/esm/src/platform/adapters/fs/veryfront/directory-operations.d.ts.map +1 -1
  5. package/esm/src/platform/adapters/fs/veryfront/directory-operations.js +9 -52
  6. package/esm/src/platform/adapters/fs/veryfront/file-list-access.d.ts +33 -0
  7. package/esm/src/platform/adapters/fs/veryfront/file-list-access.d.ts.map +1 -0
  8. package/esm/src/platform/adapters/fs/veryfront/file-list-access.js +49 -0
  9. package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts +1 -20
  10. package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts.map +1 -1
  11. package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts.map +1 -1
  12. package/esm/src/platform/adapters/fs/veryfront/stat-operations.js +8 -49
  13. package/esm/src/tool/factory.d.ts +3 -5
  14. package/esm/src/tool/factory.d.ts.map +1 -1
  15. package/esm/src/tool/factory.js +2 -1
  16. package/esm/src/tool/index.d.ts +2 -0
  17. package/esm/src/tool/index.d.ts.map +1 -1
  18. package/esm/src/tool/index.js +1 -0
  19. package/esm/src/tool/remote-source-tools.d.ts +8 -0
  20. package/esm/src/tool/remote-source-tools.d.ts.map +1 -0
  21. package/esm/src/tool/remote-source-tools.js +33 -0
  22. package/esm/src/utils/version-constant.d.ts +1 -1
  23. package/esm/src/utils/version-constant.js +1 -1
  24. package/package.json +1 -1
  25. package/src/deno.js +1 -1
  26. package/src/src/platform/adapters/fs/veryfront/base-operations.ts +1 -1
  27. package/src/src/platform/adapters/fs/veryfront/directory-operations.ts +10 -75
  28. package/src/src/platform/adapters/fs/veryfront/file-list-access.ts +109 -0
  29. package/src/src/platform/adapters/fs/veryfront/read-operations.ts +1 -22
  30. package/src/src/platform/adapters/fs/veryfront/stat-operations.ts +8 -71
  31. package/src/src/tool/factory.ts +4 -6
  32. package/src/src/tool/index.ts +5 -0
  33. package/src/src/tool/remote-source-tools.ts +54 -0
  34. package/src/src/utils/version-constant.ts +1 -1
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.161",
3
+ "version": "0.1.162",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "exclude": [
@@ -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;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"}
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,54 +206,13 @@ 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,
246
- });
247
- const isPublished = ctx?.sourceType !== "branch";
248
- logger.debug("Fetching files from API", {
249
- sourceType: ctx?.sourceType,
250
- cacheKey,
209
+ return await loadAllProjectFiles({
210
+ client: this.client,
211
+ cache: this.cache,
212
+ contextProvider: this.contextProvider,
213
+ logger,
214
+ operationLabel: "stat",
251
215
  });
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
217
  buildResolveSearchPatterns(normalizedPath, options, knownExtensionFallback = "exact") {
259
218
  const patterns = new Set();
@@ -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"}
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ import { dynamicTool } from "./factory.js";
3
+ function toToolInputRecord(input) {
4
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
5
+ return {};
6
+ }
7
+ return Object.fromEntries(Object.entries(input));
8
+ }
9
+ export function createToolsFromRemoteDefinitions(source, definitions, options = {}) {
10
+ return Object.fromEntries(definitions.map((definition) => {
11
+ const toolName = options.toolNameAliases?.[definition.name] ?? definition.name;
12
+ return [
13
+ toolName,
14
+ dynamicTool({
15
+ id: toolName,
16
+ description: definition.description,
17
+ inputSchema: z.object({}).passthrough(),
18
+ inputSchemaJson: definition.parameters,
19
+ mcp: {
20
+ title: definition.title,
21
+ annotations: definition.annotations,
22
+ },
23
+ execute: async (input, context) => await source.executeTool(definition.name, toToolInputRecord(input), context),
24
+ }),
25
+ ];
26
+ }));
27
+ }
28
+ export async function loadRemoteToolsFromSource(source, options = {}) {
29
+ const definitions = await source.listTools(options.context);
30
+ return createToolsFromRemoteDefinitions(source, definitions, {
31
+ toolNameAliases: options.toolNameAliases,
32
+ });
33
+ }
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.1.161";
1
+ export declare const VERSION = "0.1.162";
2
2
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
- export const VERSION = "0.1.161";
3
+ export const VERSION = "0.1.162";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.161",
3
+ "version": "0.1.162",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
package/src/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.161",
3
+ "version": "0.1.162",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "exclude": [
@@ -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
 
6
6
  export class VeryfrontOperationsBase {
7
7
  constructor(
@@ -2,13 +2,9 @@ import { logger as baseLogger } from "../../../../utils/index.js";
2
2
  import type { DirectoryEntry } from "./types.js";
3
3
  import type { ProjectFile } from "../../veryfront-api-client/index.js";
4
4
  import { VeryfrontOperationsBase } from "./base-operations.js";
5
- import {
6
- buildDirCacheKeyPrefix,
7
- buildFileCacheKeyPrefix,
8
- buildFileListCacheKey,
9
- } from "./cache-keys.js";
5
+ import { buildDirCacheKeyPrefix } from "./cache-keys.js";
6
+ import { loadAllProjectFiles } from "./file-list-access.js";
10
7
  import { withSpan } from "../../../../observability/tracing/otlp-setup.js";
11
- import { withRetryOnTransient } from "./retry.js";
12
8
 
13
9
  const logger = baseLogger.component("directory-operations");
14
10
 
@@ -154,74 +150,13 @@ export class DirectoryOperations extends VeryfrontOperationsBase {
154
150
  }
155
151
 
156
152
  private getAllFilesRaw(): Promise<ProjectFile[]> {
157
- return withSpan("fs.veryfront.getAllFilesRaw", async () => {
158
- const cacheStart = performance.now();
159
- const ctx = this.contextProvider?.getContentContext();
160
- const cacheKeyPrefix = buildFileCacheKeyPrefix(ctx);
161
- const skipPersistentCache =
162
- this.contextProvider?.isPersistentCacheInvalidated?.(cacheKeyPrefix) ?? false;
163
-
164
- const adapterFiles = !skipPersistentCache
165
- ? await this.contextProvider?.getFileList?.()
166
- : undefined;
167
-
168
- if (adapterFiles) {
169
- const cacheMs = Math.round(performance.now() - cacheStart);
170
- logger.debug("getAllFilesRaw - from adapter cache", {
171
- cacheMs,
172
- fileCount: adapterFiles.length,
173
- });
174
- return adapterFiles as ProjectFile[];
175
- }
176
-
177
- const cacheKey = buildFileListCacheKey(ctx);
178
-
179
- if (skipPersistentCache) {
180
- logger.debug("getAllFilesRaw - skipping persistent cache", {
181
- cacheKey,
182
- cacheKeyPrefix,
183
- });
184
- }
185
-
186
- const cached = skipPersistentCache
187
- ? undefined
188
- : await this.cache.getAsync<ProjectFile[]>(cacheKey);
189
-
190
- const cacheMs = Math.round(performance.now() - cacheStart);
191
- if (cached) {
192
- logger.debug("getAllFilesRaw - fallback cache HIT", {
193
- cacheKey,
194
- cacheMs,
195
- fileCount: cached.length,
196
- });
197
- return cached;
198
- }
199
-
200
- logger.warn("getAllFilesRaw - cache MISS, fetching from API", {
201
- cacheKey,
202
- cacheMs,
203
- });
204
-
205
- const isPublished = ctx?.sourceType !== "branch";
206
- logger.debug("Fetching files from API", {
207
- sourceType: ctx?.sourceType,
208
- cacheKey,
209
- });
210
-
211
- const files = await withRetryOnTransient(
212
- () =>
213
- isPublished
214
- ? this.client.listPublishedFiles(
215
- undefined,
216
- ctx?.releaseId ?? undefined,
217
- ctx?.environmentName ?? undefined,
218
- )
219
- : this.client.listAllFiles(),
220
- "getAllFilesRaw (dir)",
221
- );
222
-
223
- this.cache.set(cacheKey, files);
224
- return files;
225
- });
153
+ return withSpan("fs.veryfront.getAllFilesRaw", () =>
154
+ loadAllProjectFiles({
155
+ client: this.client,
156
+ cache: this.cache,
157
+ contextProvider: this.contextProvider,
158
+ logger,
159
+ operationLabel: "dir",
160
+ }));
226
161
  }
227
162
  }
@@ -0,0 +1,109 @@
1
+ import type { ProjectFile, VeryfrontApiClient } from "../../veryfront-api-client/index.js";
2
+ import { FileCache } from "../cache/file-cache.js";
3
+ import { buildFileCacheKeyPrefix, buildFileListCacheKey } from "./cache-keys.js";
4
+ import { withRetryOnTransient } from "./retry.js";
5
+ import type { ResolvedContentContext } from "./types.js";
6
+
7
+ export interface ContentContextProvider {
8
+ isProductionMode: () => boolean;
9
+ getReleaseId: () => string | null;
10
+ getContentContext: () => ResolvedContentContext | null;
11
+ getFileList?: () => Promise<
12
+ Array<{
13
+ id?: string;
14
+ path: string;
15
+ content?: string;
16
+ type?: string;
17
+ size?: number;
18
+ updated_at?: string;
19
+ }> | undefined
20
+ >;
21
+ hasCachedFileList?: () => Promise<boolean>;
22
+ isPersistentCacheInvalidated?: (prefix: string) => boolean;
23
+ isReleaseBeingInvalidated?: (releaseId: string) => boolean;
24
+ }
25
+
26
+ interface FileListLogger {
27
+ debug(message: string, context?: Record<string, unknown>): void;
28
+ warn(message: string, context?: Record<string, unknown>): void;
29
+ }
30
+
31
+ interface LoadAllProjectFilesOptions {
32
+ client: VeryfrontApiClient;
33
+ cache: FileCache;
34
+ contextProvider?: ContentContextProvider;
35
+ logger: FileListLogger;
36
+ operationLabel: string;
37
+ }
38
+
39
+ export async function loadAllProjectFiles({
40
+ client,
41
+ cache,
42
+ contextProvider,
43
+ logger,
44
+ operationLabel,
45
+ }: LoadAllProjectFilesOptions): Promise<ProjectFile[]> {
46
+ const cacheStart = performance.now();
47
+ const ctx = contextProvider?.getContentContext();
48
+ const cacheKeyPrefix = buildFileCacheKeyPrefix(ctx);
49
+ const skipPersistentCache = contextProvider?.isPersistentCacheInvalidated?.(cacheKeyPrefix) ??
50
+ false;
51
+
52
+ const adapterFiles = !skipPersistentCache ? await contextProvider?.getFileList?.() : undefined;
53
+
54
+ if (adapterFiles) {
55
+ const cacheMs = Math.round(performance.now() - cacheStart);
56
+ logger.debug("getAllFilesRaw - from adapter cache", {
57
+ cacheMs,
58
+ fileCount: adapterFiles.length,
59
+ });
60
+ return adapterFiles as ProjectFile[];
61
+ }
62
+
63
+ const cacheKey = buildFileListCacheKey(ctx);
64
+
65
+ if (skipPersistentCache) {
66
+ logger.debug("getAllFilesRaw - skipping persistent cache", {
67
+ cacheKey,
68
+ cacheKeyPrefix,
69
+ });
70
+ }
71
+
72
+ const cached = skipPersistentCache ? undefined : await cache.getAsync<ProjectFile[]>(cacheKey);
73
+ const cacheMs = Math.round(performance.now() - cacheStart);
74
+
75
+ if (cached) {
76
+ logger.debug("getAllFilesRaw - fallback cache HIT", {
77
+ cacheKey,
78
+ cacheMs,
79
+ fileCount: cached.length,
80
+ });
81
+ return cached;
82
+ }
83
+
84
+ logger.warn("getAllFilesRaw - cache MISS, fetching from API", {
85
+ cacheKey,
86
+ cacheMs,
87
+ });
88
+
89
+ const isPublished = ctx?.sourceType !== "branch";
90
+ logger.debug("Fetching files from API", {
91
+ sourceType: ctx?.sourceType,
92
+ cacheKey,
93
+ });
94
+
95
+ const files = await withRetryOnTransient(
96
+ () =>
97
+ isPublished
98
+ ? client.listPublishedFiles(
99
+ undefined,
100
+ ctx?.releaseId ?? undefined,
101
+ ctx?.environmentName ?? undefined,
102
+ )
103
+ : client.listAllFiles(),
104
+ `getAllFilesRaw (${operationLabel})`,
105
+ );
106
+
107
+ cache.set(cacheKey, files);
108
+ return files;
109
+ }
@@ -7,6 +7,7 @@ import { FileListIndex, type FileListMatchResult } from "./file-list-index.js";
7
7
  import { InFlightRequestDeduper } from "./in-flight-dedupe.js";
8
8
  import { getRequestScopedFile, setRequestScopedFile } from "./multi-project-adapter.js";
9
9
  import { PathNormalizer } from "./path-normalizer.js";
10
+ import type { ContentContextProvider } from "./file-list-access.js";
10
11
  import {
11
12
  assertProjectSourcePath,
12
13
  buildExtensionCandidatePaths,
@@ -28,28 +29,6 @@ export {
28
29
 
29
30
  const logger = baseLogger.component("read-operations");
30
31
 
31
- export interface ContentContextProvider {
32
- isProductionMode: () => boolean;
33
- getReleaseId: () => string | null;
34
- getContentContext: () => ResolvedContentContext | null;
35
- /** Cached file list from adapter initialization (single source of truth) */
36
- getFileList?: () => Promise<
37
- Array<{
38
- id?: string;
39
- path: string;
40
- content?: string;
41
- type?: string;
42
- size?: number;
43
- updated_at?: string;
44
- }> | undefined
45
- >;
46
- hasCachedFileList?: () => Promise<boolean>;
47
- /** True if cache prefix is being deleted - skip persistent cache reads */
48
- isPersistentCacheInvalidated?: (prefix: string) => boolean;
49
- /** Back-compat: release-scoped invalidation */
50
- isReleaseBeingInvalidated?: (releaseId: string) => boolean;
51
- }
52
-
53
32
  const IN_FLIGHT_REQUEST_TIMEOUT_MS = 15_000;
54
33
  const MAX_IN_FLIGHT_REQUESTS = 100;
55
34
  const IN_FLIGHT_CLEANUP_INTERVAL_MS = 1_000;
@@ -4,12 +4,7 @@ import type { FileInfo, ResolveFileOptions } from "../../base.js";
4
4
  import type { ProjectFile } from "../../veryfront-api-client/index.js";
5
5
  import { VeryfrontOperationsBase } from "./base-operations.js";
6
6
  import { createError, toError } from "../../../../errors/index.js";
7
- import {
8
- buildFileCacheKeyPrefix,
9
- buildFileListCacheKey,
10
- buildStatCacheKeyPrefix,
11
- } from "./cache-keys.js";
12
- import { withRetryOnTransient } from "./retry.js";
7
+ import { buildStatCacheKeyPrefix } from "./cache-keys.js";
13
8
  import { STAT_OPERATION_EXTENSION_PRIORITY as EXTENSION_PRIORITY } from "./extension-priority.js";
14
9
  import {
15
10
  collectParentDirectories,
@@ -21,6 +16,7 @@ import {
21
16
  } from "./stat-operations-helpers.js";
22
17
  import { ApiSearchCircuitBreaker } from "./api-search-circuit-breaker.js";
23
18
  import { withSpan } from "../../../../observability/tracing/otlp-setup.js";
19
+ import { loadAllProjectFiles } from "./file-list-access.js";
24
20
 
25
21
  const logger = baseLogger.component("stat-operations");
26
22
 
@@ -258,72 +254,13 @@ export class StatOperations extends VeryfrontOperationsBase {
258
254
  }
259
255
 
260
256
  private async getAllFilesRaw(): Promise<ProjectFile[]> {
261
- const cacheStart = performance.now();
262
- const ctx = this.contextProvider?.getContentContext();
263
- const cacheKeyPrefix = buildFileCacheKeyPrefix(ctx);
264
- const skipPersistentCache =
265
- this.contextProvider?.isPersistentCacheInvalidated?.(cacheKeyPrefix) ?? false;
266
-
267
- if (!skipPersistentCache) {
268
- const files = await this.contextProvider?.getFileList?.();
269
- if (files) {
270
- const cacheMs = Math.round(performance.now() - cacheStart);
271
- logger.debug("getAllFilesRaw - from adapter cache", {
272
- cacheMs,
273
- fileCount: files.length,
274
- });
275
- return files as ProjectFile[];
276
- }
277
- }
278
-
279
- const cacheKey = buildFileListCacheKey(ctx);
280
-
281
- if (skipPersistentCache) {
282
- logger.debug("getAllFilesRaw - skipping persistent cache (invalidation)", {
283
- cacheKey,
284
- cacheKeyPrefix,
285
- });
286
- }
287
-
288
- const cached = skipPersistentCache
289
- ? undefined
290
- : await this.cache.getAsync<ProjectFile[]>(cacheKey);
291
- const cacheMs = Math.round(performance.now() - cacheStart);
292
-
293
- if (cached) {
294
- logger.debug("getAllFilesRaw - fallback cache HIT", {
295
- cacheKey,
296
- cacheMs,
297
- fileCount: cached.length,
298
- });
299
- return cached;
300
- }
301
-
302
- logger.warn("getAllFilesRaw - cache MISS, fetching from API", {
303
- cacheKey,
304
- cacheMs,
257
+ return await loadAllProjectFiles({
258
+ client: this.client,
259
+ cache: this.cache,
260
+ contextProvider: this.contextProvider,
261
+ logger,
262
+ operationLabel: "stat",
305
263
  });
306
-
307
- const isPublished = ctx?.sourceType !== "branch";
308
- logger.debug("Fetching files from API", {
309
- sourceType: ctx?.sourceType,
310
- cacheKey,
311
- });
312
-
313
- const files = await withRetryOnTransient(
314
- () =>
315
- isPublished
316
- ? this.client.listPublishedFiles(
317
- undefined,
318
- ctx?.releaseId ?? undefined,
319
- ctx?.environmentName ?? undefined,
320
- )
321
- : this.client.listAllFiles(),
322
- "getAllFilesRaw (stat)",
323
- );
324
-
325
- this.cache.set(cacheKey, files);
326
- return files;
327
264
  }
328
265
 
329
266
  private buildResolveSearchPatterns(
@@ -179,20 +179,18 @@ export interface DynamicToolConfig {
179
179
  id?: string;
180
180
  description: string;
181
181
  inputSchema: unknown;
182
+ inputSchemaJson?: JsonSchema;
182
183
  execute: (input: unknown, context?: ToolExecutionContext) => Promise<unknown> | unknown;
183
184
  toModelOutput?: (output: unknown) => unknown;
184
- mcp?: {
185
- enabled?: boolean;
186
- requiresAuth?: boolean;
187
- cachePolicy?: "no-cache" | "cache" | "cache-first";
188
- };
185
+ mcp?: ToolConfig["mcp"];
189
186
  }
190
187
 
191
188
  export function dynamicTool(config: DynamicToolConfig): Tool<unknown, unknown> {
192
189
  const explicitId = typeof config.id === "string" && config.id.length > 0 ? config.id : undefined;
193
190
  const id = explicitId ?? generateToolId();
194
191
 
195
- const inputSchemaJson = convertSchemaToJson(config.inputSchema, id, "DYNAMIC_TOOL", true);
192
+ const inputSchemaJson = config.inputSchemaJson ??
193
+ convertSchemaToJson(config.inputSchema, id, "DYNAMIC_TOOL", true);
196
194
 
197
195
  const createdTool: Tool<unknown, unknown> = {
198
196
  id,
@@ -57,6 +57,11 @@ export { dynamicTool, tool } from "./factory.js";
57
57
  export type { DynamicToolConfig } from "./factory.js";
58
58
  export { createRemoteMCPToolSource } from "./remote-mcp.js";
59
59
  export type { RemoteMCPToolSourceConfig } from "./remote-mcp.js";
60
+ export {
61
+ createToolsFromRemoteDefinitions,
62
+ loadRemoteToolsFromSource,
63
+ } from "./remote-source-tools.js";
64
+ export type { RemoteToolMaterializationOptions } from "./remote-source-tools.js";
60
65
 
61
66
  export { toolRegistry } from "./registry.js";
62
67
 
@@ -0,0 +1,54 @@
1
+ import { z } from "zod";
2
+ import { dynamicTool } from "./factory.js";
3
+ import type { RemoteToolSource, Tool, ToolDefinition, ToolExecutionContext } from "./types.js";
4
+
5
+ export interface RemoteToolMaterializationOptions {
6
+ context?: ToolExecutionContext;
7
+ toolNameAliases?: Record<string, string>;
8
+ }
9
+
10
+ function toToolInputRecord(input: unknown): Record<string, unknown> {
11
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
12
+ return {};
13
+ }
14
+
15
+ return Object.fromEntries(Object.entries(input));
16
+ }
17
+
18
+ export function createToolsFromRemoteDefinitions(
19
+ source: RemoteToolSource,
20
+ definitions: readonly ToolDefinition[],
21
+ options: Omit<RemoteToolMaterializationOptions, "context"> = {},
22
+ ): Record<string, Tool<unknown, unknown>> {
23
+ return Object.fromEntries(
24
+ definitions.map((definition) => {
25
+ const toolName = options.toolNameAliases?.[definition.name] ?? definition.name;
26
+
27
+ return [
28
+ toolName,
29
+ dynamicTool({
30
+ id: toolName,
31
+ description: definition.description,
32
+ inputSchema: z.object({}).passthrough(),
33
+ inputSchemaJson: definition.parameters,
34
+ mcp: {
35
+ title: definition.title,
36
+ annotations: definition.annotations,
37
+ },
38
+ execute: async (input, context) =>
39
+ await source.executeTool(definition.name, toToolInputRecord(input), context),
40
+ }),
41
+ ];
42
+ }),
43
+ );
44
+ }
45
+
46
+ export async function loadRemoteToolsFromSource(
47
+ source: RemoteToolSource,
48
+ options: RemoteToolMaterializationOptions = {},
49
+ ): Promise<Record<string, Tool<unknown, unknown>>> {
50
+ const definitions = await source.listTools(options.context);
51
+ return createToolsFromRemoteDefinitions(source, definitions, {
52
+ toolNameAliases: options.toolNameAliases,
53
+ });
54
+ }
@@ -1,3 +1,3 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
- export const VERSION = "0.1.161";
3
+ export const VERSION = "0.1.162";