Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cli/SimpleModule.Cli/Commands/New/NewProjectCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ private static string StarterViteConfig() =>
"""
import { defineModuleConfig } from '@simplemodule/client/module';

export default defineModuleConfig(__dirname);
export default defineModuleConfig(import.meta.dirname);
""";

private static string StarterPackageJson(string projectName) =>
Expand All @@ -501,9 +501,9 @@ private static string StarterPackageJson(string projectName) =>
"name": "@{{projectName.ToLowerInvariant()}}/items",
"version": "0.0.0",
"scripts": {
"build": "vite build",
"build:dev": "cross-env VITE_MODE=dev vite build",
"watch": "cross-env VITE_MODE=dev vite build --watch"
"build": "cross-env VITE_MODE=prod vite build --configLoader runner",
"build:dev": "cross-env VITE_MODE=dev vite build --configLoader runner",
"watch": "cross-env VITE_MODE=dev vite build --configLoader runner --watch"
},
"peerDependencies": {
"react": "^19.0.0",
Expand Down
28 changes: 17 additions & 11 deletions cli/SimpleModule.Cli/Templates/ProjectTemplates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -707,34 +707,38 @@ private static string GenerateRootPackageJson(
string frameworkVersion
)
{
var name = projectName.ToLowerInvariant();
// npm 'name' field must be lowercase; workspace glob uses actual project casing.
var npmName = projectName.ToLowerInvariant();

string clientDep;
string uiDep;
string themeDep;
string tsconfigDep;

if (frameworkPackagesPath is not null)
{
var pkgPath = frameworkPackagesPath.Replace('\\', '/');
clientDep = $"\"file:{pkgPath}/SimpleModule.Client\"";
uiDep = $"\"file:{pkgPath}/SimpleModule.UI\"";
themeDep = $"\"file:{pkgPath}/SimpleModule.Theme.Default\"";
tsconfigDep = $"\"file:{pkgPath}/SimpleModule.TsConfig\"";
}
else
{
clientDep = $"\"^{frameworkVersion}\"";
uiDep = $"\"^{frameworkVersion}\"";
themeDep = $"\"^{frameworkVersion}\"";
tsconfigDep = $"\"^{frameworkVersion}\"";
}

return $$"""
{
"private": true,
"name": "{{name}}",
"name": "{{npmName}}",
"version": "0.0.0",
"workspaces": [
"src/modules/*/src/*",
"src/{{name}}.Host/ClientApp"
"src/{{projectName}}.Host/ClientApp"
],
"scripts": {
"lint": "biome lint .",
Expand All @@ -745,23 +749,25 @@ string frameworkVersion
"build:dev": "cross-env VITE_MODE=dev npm run build --workspaces --if-present"
},
"devDependencies": {
"@biomejs/biome": "^2.4.6",
"@tailwindcss/vite": "^4.2.1",
"@biomejs/biome": "^2.4.10",
"@tailwindcss/vite": "^4.2.2",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.4.0",
"cross-env": "^7.0.3",
"typescript": "^5.8.0",
"vite": "^6.2.0"
"@vitejs/plugin-react": "^6.0.1",
"cross-env": "^10.1.0",
"typescript": "^6.0.2",
"vite": "^8.0.3"
},
"dependencies": {
"@inertiajs/react": "^2.0.0",
"@inertiajs/react": "^3.0.0",
"@simplemodule/client": {{clientDep}},
"@simplemodule/ui": {{uiDep}},
"@simplemodule/theme-default": {{themeDep}},
"@simplemodule/tsconfig": {{tsconfigDep}},
"esbuild": "^0.27.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"tailwindcss": "^4.2.1"
"tailwindcss": "^4.2.2"
}
}
""";
Expand Down
7 changes: 6 additions & 1 deletion framework/SimpleModule.Generator/Discovery/CoreSymbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ internal readonly record struct CoreSymbols(
INamedTypeSymbol? ModuleFeatures,
INamedTypeSymbol? SaveChangesInterceptor,
INamedTypeSymbol? ModuleOptions,
bool HasAgentsAssembly
bool HasAgentsAssembly,
bool HasRagAssembly
)
{
/// <summary>
Expand Down Expand Up @@ -81,6 +82,10 @@ bool HasAgentsAssembly
ModuleOptions: compilation.GetTypeByMetadataName("SimpleModule.Core.IModuleOptions"),
HasAgentsAssembly: compilation.GetTypeByMetadataName(
"SimpleModule.Agents.SimpleModuleAgentExtensions"
)
is not null,
HasRagAssembly: compilation.GetTypeByMetadataName(
"SimpleModule.Rag.RagSettingsDefinitions"
)
is not null
);
Expand Down
4 changes: 4 additions & 0 deletions framework/SimpleModule.Generator/Discovery/DiscoveryData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ internal readonly record struct DiscoveryData(
ImmutableArray<KnowledgeSourceRecord> KnowledgeSources,
ImmutableArray<string> ContractsAssemblyNames,
bool HasAgentsAssembly,
bool HasRagAssembly,
string HostAssemblyName
)
{
Expand Down Expand Up @@ -80,6 +81,7 @@ string HostAssemblyName
ImmutableArray<KnowledgeSourceRecord>.Empty,
ImmutableArray<string>.Empty,
false,
false,
""
);

Expand All @@ -103,6 +105,7 @@ public bool Equals(DiscoveryData other)
&& KnowledgeSources.SequenceEqual(other.KnowledgeSources)
&& ContractsAssemblyNames.SequenceEqual(other.ContractsAssemblyNames)
&& HasAgentsAssembly == other.HasAgentsAssembly
&& HasRagAssembly == other.HasRagAssembly
&& HostAssemblyName == other.HostAssemblyName;
}

Expand All @@ -127,6 +130,7 @@ public override int GetHashCode()
hash = HashHelper.HashArray(hash, KnowledgeSources);
hash = HashHelper.HashArray(hash, ContractsAssemblyNames);
hash = HashHelper.Combine(hash, HasAgentsAssembly.GetHashCode());
hash = HashHelper.Combine(hash, HasRagAssembly.GetHashCode());
hash = HashHelper.Combine(hash, (HostAssemblyName ?? "").GetHashCode());
return hash;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ internal static DiscoveryData Build(
List<DiscoveredTypeInfo> knowledgeSources,
Dictionary<string, string> contractsAssemblyMap,
bool hasAgentsAssembly,
bool hasRagAssembly,
string hostAssemblyName
)
{
Expand Down Expand Up @@ -175,6 +176,7 @@ string hostAssemblyName
.ToImmutableArray(),
contractsAssemblyMap.Keys.ToImmutableArray(),
hasAgentsAssembly,
hasRagAssembly,
hostAssemblyName
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ CancellationToken cancellationToken
knowledgeSources,
contractsAssemblyMap,
s.HasAgentsAssembly,
s.HasRagAssembly,
hostAssemblyName
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ public void Emit(SourceProductionContext context, DiscoveryData data)
);
sb.AppendLine(" {");

if (!data.HasAgentsAssembly)
{
sb.AppendLine(" return services;");
sb.AppendLine(" }");
sb.AppendLine("}");
context.AddSource(
"AgentExtensions.g.cs",
SourceText.From(sb.ToString(), Encoding.UTF8)
);
return;
}

// Register agent definitions
foreach (var agent in data.AgentDefinitions)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ public void Emit(SourceProductionContext context, DiscoveryData data)
);
}

sb.AppendLine();
sb.AppendLine(" // RAG settings definitions");
sb.AppendLine(
" global::SimpleModule.Rag.RagSettingsDefinitions.Register(settings);"
);
if (data.HasRagAssembly)
{
sb.AppendLine();
sb.AppendLine(" // RAG settings definitions");
sb.AppendLine(
" global::SimpleModule.Rag.RagSettingsDefinitions.Register(settings);"
);
}

sb.AppendLine();
sb.AppendLine(
Expand Down
17 changes: 14 additions & 3 deletions framework/SimpleModule.Hosting/SimpleModuleHostExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,23 @@ public static async Task UseSimpleModuleInfrastructure(this WebApplication app)

foreach (var info in infos)
{
if (info.ModuleName != DatabaseConstants.HostModuleName)
if (scope.ServiceProvider.GetService(info.DbContextType) is not DbContext db)
continue;

if (scope.ServiceProvider.GetService(info.DbContextType) is DbContext db)
// DbContexts with EF migrations use MigrateAsync; those without (e.g. scaffolded
// module contexts that ship no migrations) fall back to EnsureCreatedAsync so
// their tables exist on first run. Only the Host context typically ships
// migrations; module contexts rely on the unified HostDbContext for schema.
if (info.ModuleName == DatabaseConstants.HostModuleName)
{
await db.Database.MigrateAsync();
if (db.Database.GetMigrations().Any())
{
await db.Database.MigrateAsync();
}
else
{
await db.Database.EnsureCreatedAsync();
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions tests/SimpleModule.Generator.Tests/TopologicalSortTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ public void SortModules_WithDependencies_ReordersByDependency()
ImmutableArray<KnowledgeSourceRecord>.Empty,
ImmutableArray<string>.Empty,
false,
false,
"SimpleModule.Host"
);

Expand Down Expand Up @@ -324,6 +325,7 @@ public void SortModules_WithCycle_ReturnsOriginalOrder()
ImmutableArray<KnowledgeSourceRecord>.Empty,
ImmutableArray<string>.Empty,
false,
false,
"SimpleModule.Host"
);

Expand Down Expand Up @@ -415,6 +417,7 @@ public void SortModules_NoDependencies_PreservesOriginalOrder()
ImmutableArray<KnowledgeSourceRecord>.Empty,
ImmutableArray<string>.Empty,
false,
false,
"SimpleModule.Host"
);

Expand Down
Loading