veryfront 0.1.161 → 0.1.163
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/deno.js +1 -1
- package/esm/src/platform/adapters/fs/veryfront/base-operations.d.ts +1 -1
- package/esm/src/platform/adapters/fs/veryfront/base-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/directory-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/directory-operations.js +9 -52
- package/esm/src/platform/adapters/fs/veryfront/file-list-access.d.ts +33 -0
- package/esm/src/platform/adapters/fs/veryfront/file-list-access.d.ts.map +1 -0
- package/esm/src/platform/adapters/fs/veryfront/file-list-access.js +49 -0
- package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts +1 -20
- package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.js +8 -49
- package/esm/src/rendering/orchestrator/html-project-css.d.ts +31 -0
- package/esm/src/rendering/orchestrator/html-project-css.d.ts.map +1 -0
- package/esm/src/rendering/orchestrator/html-project-css.js +126 -0
- package/esm/src/rendering/orchestrator/html.d.ts +0 -5
- package/esm/src/rendering/orchestrator/html.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/html.js +7 -119
- package/esm/src/tool/factory.d.ts +3 -5
- package/esm/src/tool/factory.d.ts.map +1 -1
- package/esm/src/tool/factory.js +2 -1
- package/esm/src/tool/index.d.ts +2 -0
- package/esm/src/tool/index.d.ts.map +1 -1
- package/esm/src/tool/index.js +1 -0
- package/esm/src/tool/remote-source-tools.d.ts +8 -0
- package/esm/src/tool/remote-source-tools.d.ts.map +1 -0
- package/esm/src/tool/remote-source-tools.js +33 -0
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/platform/adapters/fs/veryfront/base-operations.ts +1 -1
- package/src/src/platform/adapters/fs/veryfront/directory-operations.ts +10 -75
- package/src/src/platform/adapters/fs/veryfront/file-list-access.ts +109 -0
- package/src/src/platform/adapters/fs/veryfront/read-operations.ts +1 -22
- package/src/src/platform/adapters/fs/veryfront/stat-operations.ts +8 -71
- package/src/src/rendering/orchestrator/html-project-css.ts +203 -0
- package/src/src/rendering/orchestrator/html.ts +12 -169
- package/src/src/tool/factory.ts +4 -6
- package/src/src/tool/index.ts +5 -0
- package/src/src/tool/remote-source-tools.ts +54 -0
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -10,11 +10,7 @@ import { resolveAppComponentPath } from "../layouts/utils/app-resolver.js";
|
|
|
10
10
|
import { StreamTimeoutError, streamToString } from "../utils/stream-utils.js";
|
|
11
11
|
import { profilePhase, profileSyncPhase } from "../../observability/request-profiler.js";
|
|
12
12
|
import { normalizeCssModuleKey, rewriteCssModuleContent, } from "../../transforms/css-modules/naming.js";
|
|
13
|
-
import {
|
|
14
|
-
import { warmPreparedCSSArtifactFromFiles } from "../../html/styles-builder/css-pregeneration.js";
|
|
15
|
-
import { getRouteCandidates } from "./css-candidate-manifest.js";
|
|
16
|
-
import { resolveStyleContentVersion } from "../../html/styles-builder/content-version.js";
|
|
17
|
-
import { createStyleScopeProfile } from "../../html/styles-builder/style-scope-profile.js";
|
|
13
|
+
import { extractProjectClassesForRoute, startPreparedCSSWarmup, startProjectCSSPreparation, } from "./html-project-css.js";
|
|
18
14
|
const logger = rendererLogger.component("html-generator");
|
|
19
15
|
function applyExplicitThemeToDocument(html, colorScheme, enabled) {
|
|
20
16
|
if (!enabled || !colorScheme)
|
|
@@ -67,7 +63,7 @@ export class HTMLGenerator {
|
|
|
67
63
|
if (this.config.mode === "production" && context.options?.environment === "production") {
|
|
68
64
|
const mergedFrontmatter = this.mergeFrontmatter(context);
|
|
69
65
|
const htmlOptions = await profilePhase("html.build_options", () => this.buildHTMLOptions(context, mergedFrontmatter));
|
|
70
|
-
projectCSSPromise =
|
|
66
|
+
projectCSSPromise = startProjectCSSPreparation(context, htmlOptions);
|
|
71
67
|
}
|
|
72
68
|
html = await this.handleFullHTMLDocument(context, projectCSSPromise);
|
|
73
69
|
}
|
|
@@ -84,8 +80,8 @@ export class HTMLGenerator {
|
|
|
84
80
|
const fullContext = context;
|
|
85
81
|
const mergedFrontmatter = this.mergeFrontmatter(fullContext);
|
|
86
82
|
const htmlOptions = await profilePhase("html.build_options", () => this.buildHTMLOptions(fullContext, mergedFrontmatter));
|
|
87
|
-
const projectCSSPromise =
|
|
88
|
-
this.
|
|
83
|
+
const projectCSSPromise = startProjectCSSPreparation(fullContext, htmlOptions);
|
|
84
|
+
startPreparedCSSWarmup(this.config, fullContext, htmlOptions);
|
|
89
85
|
let reactContent;
|
|
90
86
|
try {
|
|
91
87
|
reactContent = (await streamToString(reactStream)).trim();
|
|
@@ -181,8 +177,8 @@ export class HTMLGenerator {
|
|
|
181
177
|
async wrapHTMLFragment(context) {
|
|
182
178
|
const mergedFrontmatter = this.mergeFrontmatter(context);
|
|
183
179
|
const htmlOptions = await profilePhase("html.build_options", () => this.buildHTMLOptions(context, mergedFrontmatter));
|
|
184
|
-
const projectCSSPromise =
|
|
185
|
-
this.
|
|
180
|
+
const projectCSSPromise = startProjectCSSPreparation(context, htmlOptions);
|
|
181
|
+
startPreparedCSSWarmup(this.config, context, htmlOptions);
|
|
186
182
|
const reactContent = context.html.trim();
|
|
187
183
|
const { start, end } = await profilePhase("html.generate_shell_parts", () => this.generateShellParts(context, mergedFrontmatter, htmlOptions, reactContent, projectCSSPromise));
|
|
188
184
|
return `${start}${reactContent}${end}`;
|
|
@@ -224,54 +220,6 @@ export class HTMLGenerator {
|
|
|
224
220
|
}
|
|
225
221
|
return { start: modifiedStart, end };
|
|
226
222
|
}
|
|
227
|
-
startProjectCSSPreparation(context, htmlOptions) {
|
|
228
|
-
const isLocalProject = htmlOptions.isLocalProject ?? false;
|
|
229
|
-
if (isLocalProject || htmlOptions.environment !== "production")
|
|
230
|
-
return undefined;
|
|
231
|
-
const projectScope = htmlOptions.projectSlug || htmlOptions.projectId || context.slug;
|
|
232
|
-
if (!projectScope || projectScope === "default")
|
|
233
|
-
return undefined;
|
|
234
|
-
return getProjectCSS(projectScope, htmlOptions.globalCSS, new Set([...(htmlOptions.projectClasses ?? [])]), {
|
|
235
|
-
minify: true,
|
|
236
|
-
environment: htmlOptions.environment,
|
|
237
|
-
buildMode: htmlOptions.mode,
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
startPreparedCSSWarmup(context, htmlOptions) {
|
|
241
|
-
const isLocalProject = htmlOptions.isLocalProject ?? false;
|
|
242
|
-
const usesPreviewStylesheet = isLocalProject || htmlOptions.environment !== "production";
|
|
243
|
-
if (!usesPreviewStylesheet)
|
|
244
|
-
return;
|
|
245
|
-
const wrappedFs = this.config.adapter.fs;
|
|
246
|
-
if (typeof wrappedFs.getUnderlyingAdapter !== "function")
|
|
247
|
-
return;
|
|
248
|
-
const fsAdapter = wrappedFs.getUnderlyingAdapter();
|
|
249
|
-
if (typeof fsAdapter.getAllSourceFiles !== "function")
|
|
250
|
-
return;
|
|
251
|
-
const projectScope = htmlOptions.projectSlug || htmlOptions.projectId || context.slug;
|
|
252
|
-
if (!projectScope || projectScope === "default")
|
|
253
|
-
return;
|
|
254
|
-
const projectVersion = this.getProjectContentVersion() ??
|
|
255
|
-
(this.config.mode === "development" ? "dev" : "unknown");
|
|
256
|
-
const styleProfile = createStyleScopeProfile(this.config.config);
|
|
257
|
-
const stylesheetPath = this.config.config?.tailwind?.stylesheet;
|
|
258
|
-
Promise.resolve(fsAdapter.getAllSourceFiles()).then((files) => warmPreparedCSSArtifactFromFiles({
|
|
259
|
-
projectSlug: projectScope,
|
|
260
|
-
projectVersion,
|
|
261
|
-
projectDir: this.config.projectDir,
|
|
262
|
-
files,
|
|
263
|
-
styleProfile,
|
|
264
|
-
stylesheetPath,
|
|
265
|
-
minify: true,
|
|
266
|
-
environment: "preview",
|
|
267
|
-
buildMode: "production",
|
|
268
|
-
})).catch((error) => {
|
|
269
|
-
logger.debug("Prepared CSS warmup skipped after source scan failure", {
|
|
270
|
-
projectScope,
|
|
271
|
-
error: error instanceof Error ? error.message : String(error),
|
|
272
|
-
});
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
223
|
buildHeadElements(head) {
|
|
276
224
|
if (!head)
|
|
277
225
|
return { scripts: "", other: "" };
|
|
@@ -360,7 +308,7 @@ export class HTMLGenerator {
|
|
|
360
308
|
profilePhase("html.load_global_css", () => this.loadProjectFile(stylesheetPath)),
|
|
361
309
|
]);
|
|
362
310
|
const appComponentPath = appComponentPathOrNull ?? undefined;
|
|
363
|
-
const projectClasses = await profilePhase("html.route_candidates", () => this.
|
|
311
|
+
const projectClasses = await profilePhase("html.route_candidates", () => extractProjectClassesForRoute(this.config, context, appComponentPath));
|
|
364
312
|
// Load CSS imported by components and merge with globalCSS.
|
|
365
313
|
// Deduplicate against the configured stylesheet to avoid double-loading.
|
|
366
314
|
const combinedCSS = await profilePhase("html.merge_imported_css", () => this.mergeImportedCSS(globalCSS, context.cssImports, stylesheetPath));
|
|
@@ -462,64 +410,4 @@ export class HTMLGenerator {
|
|
|
462
410
|
});
|
|
463
411
|
return combined;
|
|
464
412
|
}
|
|
465
|
-
getProjectContentVersion() {
|
|
466
|
-
const wrappedFs = this.config.adapter.fs;
|
|
467
|
-
if (typeof wrappedFs.getUnderlyingAdapter !== "function")
|
|
468
|
-
return undefined;
|
|
469
|
-
const fsAdapter = wrappedFs.getUnderlyingAdapter();
|
|
470
|
-
const contentContext = typeof fsAdapter.getContentContext === "function"
|
|
471
|
-
? fsAdapter.getContentContext()
|
|
472
|
-
: null;
|
|
473
|
-
if (contentContext)
|
|
474
|
-
return resolveStyleContentVersion(contentContext);
|
|
475
|
-
return fsAdapter.getProjectData?.()?.updated_at;
|
|
476
|
-
}
|
|
477
|
-
buildRouteManifestKey(pagePath) {
|
|
478
|
-
const relativePagePath = extractRelativePath(pagePath, this.config.projectDir);
|
|
479
|
-
return relativePagePath
|
|
480
|
-
.replace(/\.(tsx|ts|jsx|mdx|md|js)$/, "")
|
|
481
|
-
.replace(/^pages\//, "");
|
|
482
|
-
}
|
|
483
|
-
async extractProjectClassesForRoute(context, appComponentPath) {
|
|
484
|
-
const classes = new Set();
|
|
485
|
-
const wrappedFs = this.config.adapter.fs;
|
|
486
|
-
if (typeof wrappedFs.getUnderlyingAdapter !== "function")
|
|
487
|
-
return classes;
|
|
488
|
-
const fsAdapter = wrappedFs.getUnderlyingAdapter();
|
|
489
|
-
if (typeof fsAdapter.getAllSourceFiles !== "function")
|
|
490
|
-
return classes;
|
|
491
|
-
const files = await fsAdapter.getAllSourceFiles();
|
|
492
|
-
const projectScope = context.options?.projectSlug || context.options?.projectId ||
|
|
493
|
-
this.config.projectDir;
|
|
494
|
-
const projectVersion = this.getProjectContentVersion() ??
|
|
495
|
-
(this.config.mode === "development" ? "dev" : "unknown");
|
|
496
|
-
const routeKey = this.buildRouteManifestKey(context.pageInfo.entity.path);
|
|
497
|
-
const routeLayoutPaths = context.nestedLayouts
|
|
498
|
-
.map((layout) => layout.componentPath || layout.path)
|
|
499
|
-
.filter((path) => Boolean(path));
|
|
500
|
-
const routeFilePaths = [
|
|
501
|
-
context.pageInfo.entity.path,
|
|
502
|
-
...routeLayoutPaths,
|
|
503
|
-
...(appComponentPath ? [appComponentPath] : []),
|
|
504
|
-
];
|
|
505
|
-
const routeCandidates = getRouteCandidates({
|
|
506
|
-
projectScope,
|
|
507
|
-
projectVersion,
|
|
508
|
-
projectDir: this.config.projectDir,
|
|
509
|
-
styleProfile: createStyleScopeProfile(this.config.config),
|
|
510
|
-
routeKey,
|
|
511
|
-
routeFilePaths,
|
|
512
|
-
files,
|
|
513
|
-
developmentMode: this.config.mode === "development",
|
|
514
|
-
});
|
|
515
|
-
for (const cls of routeCandidates)
|
|
516
|
-
classes.add(cls);
|
|
517
|
-
logger.debug("extractProjectClasses", {
|
|
518
|
-
filesProcessed: files.length,
|
|
519
|
-
routeKey,
|
|
520
|
-
routeFileCount: routeFilePaths.length,
|
|
521
|
-
totalClasses: classes.size,
|
|
522
|
-
});
|
|
523
|
-
return classes;
|
|
524
|
-
}
|
|
525
413
|
}
|
|
@@ -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;
|
|
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"}
|
package/esm/src/tool/factory.js
CHANGED
|
@@ -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 =
|
|
108
|
+
const inputSchemaJson = config.inputSchemaJson ??
|
|
109
|
+
convertSchemaToJson(config.inputSchema, id, "DYNAMIC_TOOL", true);
|
|
109
110
|
const createdTool = {
|
|
110
111
|
id,
|
|
111
112
|
type: "dynamic",
|
package/esm/src/tool/index.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/esm/src/tool/index.js
CHANGED
|
@@ -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.
|
|
1
|
+
export declare const VERSION = "0.1.163";
|
|
2
2
|
//# sourceMappingURL=version-constant.d.ts.map
|
package/package.json
CHANGED
package/src/deno.js
CHANGED
|
@@ -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
|
-
|
|
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",
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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;
|