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.
Files changed (39) hide show
  1. package/esm/cli/mcp/remote-file-tools.d.ts.map +1 -1
  2. package/esm/cli/mcp/remote-file-tools.js +16 -9
  3. package/esm/deno.js +1 -1
  4. package/esm/src/agent/human-input.d.ts +298 -0
  5. package/esm/src/agent/human-input.d.ts.map +1 -0
  6. package/esm/src/agent/human-input.js +112 -0
  7. package/esm/src/agent/index.d.ts +2 -1
  8. package/esm/src/agent/index.d.ts.map +1 -1
  9. package/esm/src/agent/index.js +1 -0
  10. package/esm/src/agent/runtime/index.d.ts +2 -12
  11. package/esm/src/agent/runtime/index.d.ts.map +1 -1
  12. package/esm/src/agent/runtime/index.js +62 -25
  13. package/esm/src/agent/types.d.ts +37 -0
  14. package/esm/src/agent/types.d.ts.map +1 -1
  15. package/esm/src/mcp/http-transport.d.ts +33 -0
  16. package/esm/src/mcp/http-transport.d.ts.map +1 -0
  17. package/esm/src/mcp/http-transport.js +97 -0
  18. package/esm/src/mcp/server.d.ts +2 -1
  19. package/esm/src/mcp/server.d.ts.map +1 -1
  20. package/esm/src/mcp/server.js +20 -106
  21. package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts.map +1 -1
  22. package/esm/src/platform/adapters/fs/veryfront/stat-operations.js +13 -45
  23. package/esm/src/routing/api/module-loader/loader.d.ts +7 -0
  24. package/esm/src/routing/api/module-loader/loader.d.ts.map +1 -1
  25. package/esm/src/routing/api/module-loader/loader.js +104 -94
  26. package/esm/src/utils/version-constant.d.ts +1 -1
  27. package/esm/src/utils/version-constant.js +1 -1
  28. package/package.json +1 -1
  29. package/src/cli/mcp/remote-file-tools.ts +24 -13
  30. package/src/deno.js +1 -1
  31. package/src/src/agent/human-input.ts +152 -0
  32. package/src/src/agent/index.ts +24 -0
  33. package/src/src/agent/runtime/index.ts +118 -11
  34. package/src/src/agent/types.ts +47 -0
  35. package/src/src/mcp/http-transport.ts +163 -0
  36. package/src/src/mcp/server.ts +21 -120
  37. package/src/src/platform/adapters/fs/veryfront/stat-operations.ts +19 -49
  38. package/src/src/routing/api/module-loader/loader.ts +127 -100
  39. 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(normalizedPath);
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(normalizedPath, options);
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: Removed optimization that skipped API search for paths with extensions.
577
- // This was causing layout files and other project files to not be found when
578
- // they were missing from the file index (due to cache issues, incomplete fetch, etc.).
579
- // The API pattern search is the fallback to ensure files can still be found.
580
-
581
- if (!this.apiSearchCircuitBreaker.canSearch()) {
582
- logger.warn("API search circuit breaker open, skipping", { normalizedPath });
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
- const searchPattern = `${pathWithoutExt}.*`;
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
- async function rewriteExternalImports(
665
- code: string,
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
- userDeps: Map<string, string> = new Map(),
669
- ): Promise<string> {
670
- let transformed = code;
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
- logger.debug(`Rewriting external imports for Node.js, projectDir: ${projectDir}`);
685
+ try {
686
+ const pkgJson = JSON.parse(await fs.readTextFile(packageJsonPath));
687
+ let entryPoint: string | undefined;
677
688
 
678
- const resolvePackageToFileUrl = async (packageName: string): Promise<string | null> => {
679
- const packagePath = pathHelper.join(projectDir, "node_modules", packageName);
680
- const packageJsonPath = pathHelper.join(packagePath, "package.json");
689
+ if (pkgJson.exports) {
690
+ entryPoint = resolveExportEntry(pkgJson.exports["."]);
691
+ }
681
692
 
682
- try {
683
- const pkgJson = JSON.parse(await fs.readTextFile(packageJsonPath));
684
- let entryPoint: string | undefined;
693
+ entryPoint ||= pkgJson.module || pkgJson.main || "index.js";
694
+ if (!entryPoint) return null;
685
695
 
686
- if (pkgJson.exports) {
687
- entryPoint = resolveExportEntry(pkgJson.exports["."]);
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
- entryPoint ||= pkgJson.module || pkgJson.main || "index.js";
691
- if (!entryPoint) return null;
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
- return pathToFileURL(pathHelper.join(packagePath, entryPoint)).href;
694
- } catch (_) {
695
- /* expected: package.json may not exist or be invalid */
696
- return null;
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
- const externalPackagesToResolve = ["zod"];
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
- for (const name of userDeps.keys()) {
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
- for (const pkg of externalPackagesToResolve) {
709
- const escapedPkg = pkg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
730
+ for (const pkg of getNodeExternalPackagesToResolve(userDeps)) {
731
+ const escapedPkg = pkg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
710
732
 
711
- // Match both exact imports (from "pkg") and subpath imports (from "pkg/sub")
712
- const staticImportRegex = new RegExp(`from\\s*["']${escapedPkg}(/[^"']*)?["']`, "g");
713
- const dynamicImportRegex = new RegExp(
714
- `import\\s*\\(\\s*["']${escapedPkg}(/[^"']*)?["']\\s*\\)`,
715
- "g",
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
- const needsStatic = staticImportRegex.test(transformed);
719
- staticImportRegex.lastIndex = 0;
720
- const needsDynamic = dynamicImportRegex.test(transformed);
721
- dynamicImportRegex.lastIndex = 0;
722
- if (!needsStatic && !needsDynamic) continue;
723
-
724
- const packageDir = pathToFileURL(pathHelper.join(projectDir, "node_modules", pkg)).href;
725
- const resolvedUrl = await resolvePackageToFileUrl(pkg);
726
-
727
- if (needsStatic) {
728
- transformed = transformed.replace(staticImportRegex, (_, subpath) => {
729
- if (subpath) {
730
- const subUrl = `${packageDir}${subpath}`;
731
- logger.debug(`Resolved ${pkg}${subpath} -> ${subUrl}`);
732
- return `from "${subUrl}"`;
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
- if (needsDynamic) {
741
- transformed = transformed.replace(dynamicImportRegex, (_, subpath) => {
742
- if (subpath) {
743
- const subUrl = `${packageDir}${subpath}`;
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 vfPackagePath = pathHelper.join(projectDir, "node_modules", "veryfront");
753
- const vfPackageJsonPath = pathHelper.join(vfPackagePath, "package.json");
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
- let exportsMap: Record<string, { import?: string }> = {};
756
- try {
757
- const pkgJson = JSON.parse(await fs.readTextFile(vfPackageJsonPath));
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
- transformed = transformed.replace(
764
- /from\s+["'](veryfront\/[^"']+)["']/g,
765
- (match, fullSpecifier: string) => {
766
- const subpath = "./" + fullSpecifier.replace("veryfront/", "");
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
- const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);
774
- logger.debug(`Resolved ${fullSpecifier} -> ${resolvedPath}`);
775
- return `from "${pathToFileURL(resolvedPath).href}"`;
776
- },
777
- );
800
+ return transformed;
801
+ }
778
802
 
779
- transformed = transformed.replace(/from\s+["']veryfront["']/g, () => {
780
- const exportEntry = exportsMap["."];
781
- if (!exportEntry?.import) return 'from "veryfront"';
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
- const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);
784
- logger.debug(`Resolved veryfront -> ${resolvedPath}`);
785
- return `from "${pathToFileURL(resolvedPath).href}"`;
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
  }
@@ -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.157";
3
+ export const VERSION = "0.1.161";