feat(flutter-cursor-templates): introduce MCP integration and conventions in project brief
- Added optional MCP integration settings in project-brief.yaml, allowing for environment-based server configurations. - Introduced conventions for strict package imports to enhance code organization and maintainability. - Updated brief schema to validate new MCP properties and ensure correct usage. - Implemented MCP JSON builder to generate .cursor/mcp.json based on project brief settings. - Enhanced resolver to include MCP configuration in generated files when enabled. This update improves integration capabilities and enforces coding standards across the project.
This commit is contained in:
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# cursor_gen — run from any Flutter repo: bash path/to/generator/tool/cursor_audit.sh [ROOT]
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "${1:-.}" && pwd)"
|
||||
CURSOR="${ROOT}/.cursor"
|
||||
RULES="${CURSOR}/rules"
|
||||
|
||||
echo "== cursor_audit (${ROOT}) =="
|
||||
|
||||
if [[ ! -d "$CURSOR" ]]; then
|
||||
echo "ERROR: missing ${CURSOR}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d "$RULES" ]]; then
|
||||
ac="$(grep -R "alwaysApply: true" "$RULES" --include='*.mdc' 2>/dev/null | wc -l | tr -d ' ')"
|
||||
echo "alwaysApply: true occurrences in .cursor/rules: ${ac}"
|
||||
echo " (expect a small number — meta/safety; prefer scoped globs for domain rules)"
|
||||
else
|
||||
echo "WARN: no ${RULES}"
|
||||
fi
|
||||
|
||||
if [[ -d "$RULES/features" ]]; then
|
||||
shopt -s nullglob
|
||||
for f in "$RULES/features"/*.mdc; do
|
||||
base="$(basename "$f" .mdc)"
|
||||
if [[ ! -d "${ROOT}/lib/features/${base}" ]] && [[ ! -d "${ROOT}/lib/feature_${base}" ]]; then
|
||||
echo "WARN: rules/features/${base}.mdc has no obvious lib/features/${base} folder — update features.modules or lib layout"
|
||||
fi
|
||||
done
|
||||
shopt -u nullglob
|
||||
fi
|
||||
|
||||
echo "OK — review warnings above after brief or folder renames"
|
||||
@@ -0,0 +1,47 @@
|
||||
// Regenerates test/golden/* after intentional template changes.
|
||||
// Run from generator/: dart run tool/refresh_goldens.dart
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import '../src/models.dart';
|
||||
import '../src/renderer.dart';
|
||||
import '../src/resolver.dart';
|
||||
import '../test/golden_briefs.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
final templateSrc = _templateDir();
|
||||
if (!Directory(templateSrc).existsSync()) {
|
||||
stderr.writeln('Template dir not found: $templateSrc');
|
||||
exitCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
final cases = <String, ProjectBrief>{
|
||||
'bloc-clean-firebase': kBlocCleanFirebaseBrief,
|
||||
'riverpod-ff-supabase': kRiverpodFfSupabaseBrief,
|
||||
'getx-mvc-rest': kGetxMvcRestBrief,
|
||||
};
|
||||
|
||||
for (final e in cases.entries) {
|
||||
final profile = e.key;
|
||||
final brief = e.value;
|
||||
final rendered = await Renderer.render(
|
||||
brief: brief,
|
||||
templateFiles: Resolver.resolve(brief),
|
||||
templateSrc: templateSrc,
|
||||
);
|
||||
for (final out in rendered.entries) {
|
||||
final file = File('test/golden/$profile/${out.key}');
|
||||
await file.parent.create(recursive: true);
|
||||
await file.writeAsString(out.value);
|
||||
stdout.writeln('Wrote ${file.path}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String _templateDir() {
|
||||
final scriptDir = File(Platform.script.toFilePath()).parent;
|
||||
return p.normalize(p.join(scriptDir.path, '..', '..', 'templates'));
|
||||
}
|
||||
Reference in New Issue
Block a user