veryfront 0.1.157 → 0.1.161
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/cli/mcp/remote-file-tools.d.ts.map +1 -1
- package/esm/cli/mcp/remote-file-tools.js +16 -9
- package/esm/deno.js +1 -1
- package/esm/src/agent/human-input.d.ts +298 -0
- package/esm/src/agent/human-input.d.ts.map +1 -0
- package/esm/src/agent/human-input.js +112 -0
- package/esm/src/agent/index.d.ts +2 -1
- package/esm/src/agent/index.d.ts.map +1 -1
- package/esm/src/agent/index.js +1 -0
- package/esm/src/agent/runtime/index.d.ts +2 -12
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +62 -25
- package/esm/src/agent/types.d.ts +37 -0
- package/esm/src/agent/types.d.ts.map +1 -1
- package/esm/src/mcp/http-transport.d.ts +33 -0
- package/esm/src/mcp/http-transport.d.ts.map +1 -0
- package/esm/src/mcp/http-transport.js +97 -0
- package/esm/src/mcp/server.d.ts +2 -1
- package/esm/src/mcp/server.d.ts.map +1 -1
- package/esm/src/mcp/server.js +20 -106
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.js +13 -45
- package/esm/src/routing/api/module-loader/loader.d.ts +7 -0
- package/esm/src/routing/api/module-loader/loader.d.ts.map +1 -1
- package/esm/src/routing/api/module-loader/loader.js +104 -94
- 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/cli/mcp/remote-file-tools.ts +24 -13
- package/src/deno.js +1 -1
- package/src/src/agent/human-input.ts +152 -0
- package/src/src/agent/index.ts +24 -0
- package/src/src/agent/runtime/index.ts +118 -11
- package/src/src/agent/types.ts +47 -0
- package/src/src/mcp/http-transport.ts +163 -0
- package/src/src/mcp/server.ts +21 -120
- package/src/src/platform/adapters/fs/veryfront/stat-operations.ts +19 -49
- package/src/src/routing/api/module-loader/loader.ts +127 -100
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -329,6 +329,7 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
329
329
|
private buildResolveSearchPatterns(
|
|
330
330
|
normalizedPath: string,
|
|
331
331
|
options?: ResolveFileOptions,
|
|
332
|
+
knownExtensionFallback: "exact" | "wildcard" = "exact",
|
|
332
333
|
): string[] {
|
|
333
334
|
const patterns = new Set<string>();
|
|
334
335
|
const pathWithoutExt = stripKnownExtension(normalizedPath, EXTENSION_PRIORITY);
|
|
@@ -338,7 +339,9 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
338
339
|
};
|
|
339
340
|
|
|
340
341
|
if (EXTENSION_PRIORITY.some((ext) => normalizedPath.endsWith(ext))) {
|
|
341
|
-
addPattern(
|
|
342
|
+
addPattern(
|
|
343
|
+
knownExtensionFallback === "wildcard" ? `${pathWithoutExt}.*` : normalizedPath,
|
|
344
|
+
);
|
|
342
345
|
return [...patterns];
|
|
343
346
|
}
|
|
344
347
|
|
|
@@ -366,6 +369,7 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
366
369
|
private async tryResolveViaApiSearch(
|
|
367
370
|
normalizedPath: string,
|
|
368
371
|
options?: ResolveFileOptions,
|
|
372
|
+
knownExtensionFallback: "exact" | "wildcard" = "exact",
|
|
369
373
|
): Promise<string | null | undefined> {
|
|
370
374
|
if (isFrameworkSourcePath(normalizedPath)) {
|
|
371
375
|
logger.debug("Skipping API search for framework path", { normalizedPath });
|
|
@@ -377,7 +381,11 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
377
381
|
return undefined;
|
|
378
382
|
}
|
|
379
383
|
|
|
380
|
-
const patterns = this.buildResolveSearchPatterns(
|
|
384
|
+
const patterns = this.buildResolveSearchPatterns(
|
|
385
|
+
normalizedPath,
|
|
386
|
+
options,
|
|
387
|
+
knownExtensionFallback,
|
|
388
|
+
);
|
|
381
389
|
let sawSuccessfulSearch = false;
|
|
382
390
|
|
|
383
391
|
for (const pattern of patterns) {
|
|
@@ -573,55 +581,17 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
573
581
|
return null;
|
|
574
582
|
}
|
|
575
583
|
|
|
576
|
-
// NOTE:
|
|
577
|
-
//
|
|
578
|
-
//
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
return null;
|
|
584
|
+
// NOTE: Keep the post-index API fallback aligned with the pre-index helper for extensionless
|
|
585
|
+
// paths, while preserving the older wildcard sibling-extension lookup for known-extension
|
|
586
|
+
// paths. Incomplete file-list snapshots otherwise hide valid files until the cache refreshes.
|
|
587
|
+
const apiResolved = await this.tryResolveViaApiSearch(normalizedPath, options, "wildcard");
|
|
588
|
+
if (typeof apiResolved === "string") {
|
|
589
|
+
this.cache.set(cacheKey, apiResolved);
|
|
590
|
+
return apiResolved;
|
|
584
591
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
logger.debug("Searching for file via API", {
|
|
588
|
-
pattern: searchPattern,
|
|
589
|
-
normalizedPath,
|
|
590
|
-
});
|
|
591
|
-
|
|
592
|
-
try {
|
|
593
|
-
const matches = await this.client.searchFiles(searchPattern);
|
|
594
|
-
this.apiSearchCircuitBreaker.recordSuccess();
|
|
595
|
-
|
|
596
|
-
logger.debug("API search result", {
|
|
597
|
-
pattern: searchPattern,
|
|
598
|
-
matchCount: matches.length,
|
|
599
|
-
matches: matches.map((m) => m.path).slice(0, 5),
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
const sortedMatches = sortPathsByExtensionPriority(matches, EXTENSION_PRIORITY);
|
|
603
|
-
const first = sortedMatches[0];
|
|
604
|
-
if (first) {
|
|
605
|
-
logger.debug("resolveFile found via API search", { path: first.path });
|
|
606
|
-
this.cache.set(cacheKey, first.path);
|
|
607
|
-
return first.path;
|
|
608
|
-
}
|
|
609
|
-
} catch (error) {
|
|
610
|
-
const result = this.apiSearchCircuitBreaker.recordFailure();
|
|
611
|
-
if (result.tripped) {
|
|
612
|
-
logger.warn("API search circuit breaker tripped", {
|
|
613
|
-
failures: result.failures,
|
|
614
|
-
});
|
|
615
|
-
}
|
|
616
|
-
logger.error("API pattern search failed", { pattern: searchPattern, error });
|
|
592
|
+
if (apiResolved === null) {
|
|
593
|
+
this.cache.set(cacheKey, NOT_FOUND_SENTINEL);
|
|
617
594
|
}
|
|
618
|
-
|
|
619
|
-
logger.debug("resolveFile not found after API search", {
|
|
620
|
-
normalizedPath,
|
|
621
|
-
pathWithoutExt,
|
|
622
|
-
});
|
|
623
|
-
|
|
624
|
-
this.cache.set(cacheKey, NOT_FOUND_SENTINEL);
|
|
625
595
|
return null;
|
|
626
596
|
}
|
|
627
597
|
}
|
|
@@ -661,129 +661,156 @@ async function loadModuleFromCode(
|
|
|
661
661
|
}
|
|
662
662
|
}
|
|
663
663
|
|
|
664
|
-
|
|
665
|
-
|
|
664
|
+
export function getNodeExternalPackagesToResolve(userDeps: Map<string, string>): string[] {
|
|
665
|
+
const externalPackagesToResolve = ["zod"];
|
|
666
|
+
|
|
667
|
+
for (const name of userDeps.keys()) {
|
|
668
|
+
if (!externalPackagesToResolve.includes(name)) {
|
|
669
|
+
externalPackagesToResolve.push(name);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
return externalPackagesToResolve;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
export async function resolveNodePackageToFileUrl(
|
|
666
677
|
projectDir: string,
|
|
678
|
+
packageName: string,
|
|
667
679
|
fs: FileSystem,
|
|
668
|
-
|
|
669
|
-
): Promise<string> {
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
if (isNode) {
|
|
673
|
-
try {
|
|
674
|
-
const { pathToFileURL } = await import("node:url");
|
|
680
|
+
pathToFileURL: typeof import("node:url").pathToFileURL,
|
|
681
|
+
): Promise<string | null> {
|
|
682
|
+
const packagePath = pathHelper.join(projectDir, "node_modules", packageName);
|
|
683
|
+
const packageJsonPath = pathHelper.join(packagePath, "package.json");
|
|
675
684
|
|
|
676
|
-
|
|
685
|
+
try {
|
|
686
|
+
const pkgJson = JSON.parse(await fs.readTextFile(packageJsonPath));
|
|
687
|
+
let entryPoint: string | undefined;
|
|
677
688
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
689
|
+
if (pkgJson.exports) {
|
|
690
|
+
entryPoint = resolveExportEntry(pkgJson.exports["."]);
|
|
691
|
+
}
|
|
681
692
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
let entryPoint: string | undefined;
|
|
693
|
+
entryPoint ||= pkgJson.module || pkgJson.main || "index.js";
|
|
694
|
+
if (!entryPoint) return null;
|
|
685
695
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
696
|
+
return pathToFileURL(pathHelper.join(packagePath, entryPoint)).href;
|
|
697
|
+
} catch (_) {
|
|
698
|
+
/* expected: package.json may not exist or be invalid */
|
|
699
|
+
return null;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
689
702
|
|
|
690
|
-
|
|
691
|
-
|
|
703
|
+
export async function loadVeryfrontExportsMap(
|
|
704
|
+
projectDir: string,
|
|
705
|
+
fs: FileSystem,
|
|
706
|
+
): Promise<Record<string, { import?: string }>> {
|
|
707
|
+
const vfPackagePath = pathHelper.join(projectDir, "node_modules", "veryfront");
|
|
708
|
+
const vfPackageJsonPath = pathHelper.join(vfPackagePath, "package.json");
|
|
692
709
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
710
|
+
try {
|
|
711
|
+
const pkgJson = JSON.parse(await fs.readTextFile(vfPackageJsonPath));
|
|
712
|
+
return pkgJson.exports || {};
|
|
713
|
+
} catch (_error) {
|
|
714
|
+
logger.debug("Could not read veryfront package.json");
|
|
715
|
+
return {};
|
|
716
|
+
}
|
|
717
|
+
}
|
|
699
718
|
|
|
700
|
-
|
|
719
|
+
export async function rewriteNodeExternalImports(
|
|
720
|
+
code: string,
|
|
721
|
+
projectDir: string,
|
|
722
|
+
fs: FileSystem,
|
|
723
|
+
userDeps: Map<string, string>,
|
|
724
|
+
): Promise<string> {
|
|
725
|
+
const { pathToFileURL } = await import("node:url");
|
|
726
|
+
let transformed = code;
|
|
701
727
|
|
|
702
|
-
|
|
703
|
-
if (!externalPackagesToResolve.includes(name)) {
|
|
704
|
-
externalPackagesToResolve.push(name);
|
|
705
|
-
}
|
|
706
|
-
}
|
|
728
|
+
logger.debug(`Rewriting external imports for Node.js, projectDir: ${projectDir}`);
|
|
707
729
|
|
|
708
|
-
|
|
709
|
-
|
|
730
|
+
for (const pkg of getNodeExternalPackagesToResolve(userDeps)) {
|
|
731
|
+
const escapedPkg = pkg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
710
732
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
);
|
|
733
|
+
const staticImportRegex = new RegExp(`from\\s*["']${escapedPkg}(/[^"']*)?["']`, "g");
|
|
734
|
+
const dynamicImportRegex = new RegExp(
|
|
735
|
+
`import\\s*\\(\\s*["']${escapedPkg}(/[^"']*)?["']\\s*\\)`,
|
|
736
|
+
"g",
|
|
737
|
+
);
|
|
717
738
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
}
|
|
734
|
-
if (!resolvedUrl) return `from "${pkg}"`;
|
|
735
|
-
logger.debug(`Resolved ${pkg} -> ${resolvedUrl}`);
|
|
736
|
-
return `from "${resolvedUrl}"`;
|
|
737
|
-
});
|
|
739
|
+
const needsStatic = staticImportRegex.test(transformed);
|
|
740
|
+
staticImportRegex.lastIndex = 0;
|
|
741
|
+
const needsDynamic = dynamicImportRegex.test(transformed);
|
|
742
|
+
dynamicImportRegex.lastIndex = 0;
|
|
743
|
+
if (!needsStatic && !needsDynamic) continue;
|
|
744
|
+
|
|
745
|
+
const packageDir = pathToFileURL(pathHelper.join(projectDir, "node_modules", pkg)).href;
|
|
746
|
+
const resolvedUrl = await resolveNodePackageToFileUrl(projectDir, pkg, fs, pathToFileURL);
|
|
747
|
+
|
|
748
|
+
if (needsStatic) {
|
|
749
|
+
transformed = transformed.replace(staticImportRegex, (_, subpath) => {
|
|
750
|
+
if (subpath) {
|
|
751
|
+
const subUrl = `${packageDir}${subpath}`;
|
|
752
|
+
logger.debug(`Resolved ${pkg}${subpath} -> ${subUrl}`);
|
|
753
|
+
return `from "${subUrl}"`;
|
|
738
754
|
}
|
|
755
|
+
if (!resolvedUrl) return `from "${pkg}"`;
|
|
756
|
+
logger.debug(`Resolved ${pkg} -> ${resolvedUrl}`);
|
|
757
|
+
return `from "${resolvedUrl}"`;
|
|
758
|
+
});
|
|
759
|
+
}
|
|
739
760
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
return `import("${subUrl}")`;
|
|
745
|
-
}
|
|
746
|
-
if (!resolvedUrl) return `import("${pkg}")`;
|
|
747
|
-
return `import("${resolvedUrl}")`;
|
|
748
|
-
});
|
|
761
|
+
if (needsDynamic) {
|
|
762
|
+
transformed = transformed.replace(dynamicImportRegex, (_, subpath) => {
|
|
763
|
+
if (subpath) {
|
|
764
|
+
return `import("${packageDir}${subpath}")`;
|
|
749
765
|
}
|
|
766
|
+
if (!resolvedUrl) return `import("${pkg}")`;
|
|
767
|
+
return `import("${resolvedUrl}")`;
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
const vfPackagePath = pathHelper.join(projectDir, "node_modules", "veryfront");
|
|
773
|
+
const exportsMap = await loadVeryfrontExportsMap(projectDir, fs);
|
|
774
|
+
|
|
775
|
+
transformed = transformed.replace(
|
|
776
|
+
/from\s+["'](veryfront\/[^"']+)["']/g,
|
|
777
|
+
(match, fullSpecifier: string) => {
|
|
778
|
+
const subpath = "./" + fullSpecifier.replace("veryfront/", "");
|
|
779
|
+
const exportEntry = exportsMap[subpath];
|
|
780
|
+
if (!exportEntry?.import) {
|
|
781
|
+
logger.warn(`No export found for ${subpath}`);
|
|
782
|
+
return match;
|
|
750
783
|
}
|
|
751
784
|
|
|
752
|
-
const
|
|
753
|
-
|
|
785
|
+
const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);
|
|
786
|
+
logger.debug(`Resolved ${fullSpecifier} -> ${resolvedPath}`);
|
|
787
|
+
return `from "${pathToFileURL(resolvedPath).href}"`;
|
|
788
|
+
},
|
|
789
|
+
);
|
|
754
790
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
exportsMap = pkgJson.exports || {};
|
|
759
|
-
} catch (_error) {
|
|
760
|
-
logger.debug(`Could not read veryfront package.json: `);
|
|
761
|
-
}
|
|
791
|
+
transformed = transformed.replace(/from\s+["']veryfront["']/g, () => {
|
|
792
|
+
const exportEntry = exportsMap["."];
|
|
793
|
+
if (!exportEntry?.import) return 'from "veryfront"';
|
|
762
794
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
const exportEntry = exportsMap[subpath];
|
|
768
|
-
if (!exportEntry?.import) {
|
|
769
|
-
logger.warn(`No export found for ${subpath}`);
|
|
770
|
-
return match;
|
|
771
|
-
}
|
|
795
|
+
const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);
|
|
796
|
+
logger.debug(`Resolved veryfront -> ${resolvedPath}`);
|
|
797
|
+
return `from "${pathToFileURL(resolvedPath).href}"`;
|
|
798
|
+
});
|
|
772
799
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
return `from "${pathToFileURL(resolvedPath).href}"`;
|
|
776
|
-
},
|
|
777
|
-
);
|
|
800
|
+
return transformed;
|
|
801
|
+
}
|
|
778
802
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
803
|
+
async function rewriteExternalImports(
|
|
804
|
+
code: string,
|
|
805
|
+
projectDir: string,
|
|
806
|
+
fs: FileSystem,
|
|
807
|
+
userDeps: Map<string, string> = new Map(),
|
|
808
|
+
): Promise<string> {
|
|
809
|
+
let transformed = code;
|
|
782
810
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
});
|
|
811
|
+
if (isNode) {
|
|
812
|
+
try {
|
|
813
|
+
transformed = await rewriteNodeExternalImports(transformed, projectDir, fs, userDeps);
|
|
787
814
|
} catch (e) {
|
|
788
815
|
logger.warn(`Failed to import node:module: ${e}`);
|
|
789
816
|
}
|