executeImpl method

  1. @override
Future executeImpl(
  1. Map<String, dynamic> params
)
override

Implement the actual tool logic

params are the validated parameters (never null here) Returns the result data to send in the response

Implementation

@override
Future<dynamic> executeImpl(Map<String, dynamic> params) async {
  final pattern = params['pattern'] as String? ?? '';
  final path = params['path'] as String?;
  final excludePatterns = params['exclude_patterns'] as List<dynamic>?;
  final maxResults = params['max_results'] as int? ?? 100;

  final project = ServerPodLocator.getProject();
  if (project == null || !project.isValid) {
    return {'error': 'Not a valid ServerPod project'};
  }

  // Determine search path
  String searchPath = project.rootPath;
  if (path != null && path.isNotEmpty) {
    searchPath = p.normalize(p.join(project.rootPath, path));
  }

  final searchDir = Directory(searchPath);
  if (!searchDir.existsSync()) {
    return {
      'error': 'Search path not found',
      'path': searchPath,
    };
  }

  final results = <Map<String, dynamic>>[];
  final excludeList = excludePatterns?.cast<String>();

  try {
    // Use recursive directory listing
    final entities = searchDir.list(recursive: true, followLinks: false);

    await for (final entity in entities) {
      if (results.length >= maxResults) break;

      if (entity is File) {
        final filePath = entity.path;
        final fileName = p.basename(filePath);
        final relativePath = p.relative(filePath, from: searchPath);

        // Check if pattern matches
        if (!_matchesPattern(relativePath, pattern)) {
          continue;
        }

        // Check exclusions
        if (_shouldExclude(filePath, excludeList)) {
          continue;
        }

        final stat = await entity.stat();
        final projectRelativePath = p.relative(filePath, from: project.rootPath);

        results.add({
          'name': fileName,
          'path': filePath,
          'relativePath': projectRelativePath,
          'size': stat.size,
          'modified': stat.modified.toIso8601String(),
        });
      }
    }
  } catch (e) {
    return {
      'error': 'File system error',
      'message': e.toString(),
    };
  }

  // Sort by path
  results.sort((a, b) => a['path'].compareTo(b['path']));

  return {
    'files': results,
    'count': results.length,
    'pattern': pattern,
    'searchPath': searchPath,
    'maxResults': maxResults,
    'truncated': results.length >= maxResults,
  };
}