Initial commit of the Flutter Cursor Generator project, including the core generator tool, project brief schema, example project setup, and CI configuration. Added README documentation outlining repository structure, quick start guide, and detailed descriptions of features and architecture pillars.
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
// resolver.dart — Maps brief values → template file paths (Pillar 3, 4 improvements)
|
||||
|
||||
import 'models.dart';
|
||||
|
||||
class Resolver {
|
||||
/// Returns an ordered list of template file keys to render.
|
||||
/// Each key maps to: templates/<key>.mdc.tmpl (or SKILL.md.tmpl for skills)
|
||||
static List<String> resolve(ProjectBrief brief) {
|
||||
final files = <String>[];
|
||||
|
||||
// ── Universal (every project) ──────────────────────────────────────
|
||||
files.addAll([
|
||||
'rules/universal/flutter-core',
|
||||
'rules/universal/ui-ux-standards',
|
||||
'rules/universal/project-context',
|
||||
]);
|
||||
|
||||
// ── Security (Pillar 5: always-on, not just for large/auth projects) ──
|
||||
files.add('rules/security/security-standards');
|
||||
|
||||
// ── Error handling (always-on) ────────────────────────────────────
|
||||
files.add('rules/error-handling/error-handling');
|
||||
|
||||
// ── State management — exactly one ───────────────────────────────
|
||||
files.add('rules/state-management/${brief.stateManagement}');
|
||||
|
||||
// ── Architecture — exactly one ────────────────────────────────────
|
||||
files.add('rules/architecture/${brief.architecture}');
|
||||
|
||||
// ── Backend — one or more ─────────────────────────────────────────
|
||||
for (final b in brief.backends) files.add('rules/backend/$b');
|
||||
if (brief.specialFeatures.contains('realtime')) {
|
||||
files.add('rules/backend/realtime');
|
||||
}
|
||||
|
||||
// ── Routing — exactly one ─────────────────────────────────────────
|
||||
files.add('rules/routing/${brief.routing}');
|
||||
|
||||
// ── Testing — SM-matched ──────────────────────────────────────────
|
||||
files.add('rules/testing/testing-${brief.stateManagement}');
|
||||
if (brief.testingDepth == 'full' || brief.testingDepth == 'e2e') {
|
||||
files.add('rules/testing/testing-e2e-${brief.e2eTool}');
|
||||
}
|
||||
|
||||
// ── Platform targets (Pillar 4) ───────────────────────────────────
|
||||
for (final platform in brief.platforms) {
|
||||
files.add('rules/platform/platform-$platform');
|
||||
}
|
||||
|
||||
// ── Code generation tools (Pillar 4) ─────────────────────────────
|
||||
for (final tool in brief.codegenTools) {
|
||||
files.add('rules/codegen/codegen-$tool');
|
||||
}
|
||||
|
||||
// ── Localization ──────────────────────────────────────────────────
|
||||
if (brief.i18nEnabled) {
|
||||
files.add('rules/i18n/localization');
|
||||
}
|
||||
|
||||
// ── Skills ────────────────────────────────────────────────────────
|
||||
files.addAll([
|
||||
'skills/scaffold-feature',
|
||||
'skills/scaffold-screen',
|
||||
'skills/generate-tests',
|
||||
]);
|
||||
if (brief.apiDocsFormat != 'none') files.add('skills/generate-api-client');
|
||||
if (brief.flavors.length > 1) files.add('skills/create-flavor');
|
||||
if (brief.cicd.isNotEmpty) files.add('skills/deploy');
|
||||
|
||||
// ── Agents ────────────────────────────────────────────────────────
|
||||
files.addAll([
|
||||
'agents/code-reviewer',
|
||||
'agents/test-writer',
|
||||
'agents/ui-validator',
|
||||
]);
|
||||
if (brief.backends.contains('rest')) files.add('agents/api-client-gen');
|
||||
|
||||
// Pillar 5: Security agent as ADDITIONAL layer (rules are primary)
|
||||
if (brief.scale == 'large' || brief.auth != 'none') {
|
||||
files.add('agents/security-agent');
|
||||
}
|
||||
if (brief.stateManagement == 'getx') {
|
||||
files.add('agents/migration-agent');
|
||||
}
|
||||
|
||||
// ── Hooks ─────────────────────────────────────────────────────────
|
||||
files.addAll([
|
||||
'hooks/hooks-json',
|
||||
'hooks/flutter-analyze',
|
||||
'hooks/grind-tests',
|
||||
'hooks/arch-guard',
|
||||
]);
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/// Returns human-readable description of why each file was included
|
||||
static Map<String, String> resolveWithReasons(ProjectBrief brief) {
|
||||
final resolved = resolve(brief);
|
||||
final reasons = <String, String>{};
|
||||
for (final f in resolved) {
|
||||
reasons[f] = _reason(f, brief);
|
||||
}
|
||||
return reasons;
|
||||
}
|
||||
|
||||
static String _reason(String key, ProjectBrief brief) {
|
||||
if (key.contains('universal')) return 'Always included';
|
||||
if (key.contains('security')) return 'Always included — Pillar 5';
|
||||
if (key.contains('error-handling')) return 'Always included';
|
||||
if (key.contains('state-management')) return 'Matches stack.state_management: ${brief.stateManagement}';
|
||||
if (key.contains('architecture')) return 'Matches stack.architecture: ${brief.architecture}';
|
||||
if (key.contains('routing')) return 'Matches stack.routing: ${brief.routing}';
|
||||
if (key.contains('testing-e2e')) return 'testing.depth includes e2e';
|
||||
if (key.contains('testing')) return 'Matches state_management testing patterns';
|
||||
if (key.contains('platform')) return 'Matches stack.platforms';
|
||||
if (key.contains('codegen')) return 'Matches stack.codegen';
|
||||
if (key.contains('i18n')) return 'localization.enabled: true';
|
||||
if (key.contains('migration')) return 'state_management is GetX — migration guidance included';
|
||||
if (key.contains('security-agent')) return 'scale: ${brief.scale} or auth is configured';
|
||||
if (key.contains('api-client')) return 'api_docs.format is set';
|
||||
if (key.contains('realtime')) return 'features.special contains realtime';
|
||||
return 'Included';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user