MOD-320: Project structure#242
Conversation
artahian
left a comment
There was a problem hiding this comment.
Structure looks good - only remaining question is how do client modules handle this. Leaving this in a comment state until we figure it out.
|
|
||
| seen.set(baseName, path.join(dirPath, entry.name)); | ||
| } | ||
| } |
There was a problem hiding this comment.
Scanner crashes on .d.ts files in module folders
Low Severity
The scanFolder function matches .d.ts files because path.extname('types.d.ts') returns '.ts'. This produces a baseName of 'types.d', which fails the VALID_MODULE_NAME regex due to the dot, throwing a confusing error telling the user the filename is an invalid JS identifier. TypeScript declaration files (.d.ts) are common and valid in any directory; the scanner could silently skip them instead of crashing.
Reviewed by Cursor Bugbot for commit 3d1e96a. Configure here.
|
@artahian, after many attempts, client modules are working as expected. Demo is here: modelence/examples#28 |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ff14ab5. Configure here.
artahian
left a comment
There was a problem hiding this comment.
So it seems like there is no way to avoid generating types manually?
Do you think we should just keep the explicit imports but add an automated/lint check based on scanning so if you add something but forget to add it shows a warning for the App Builder?
Since this makes the type checking so complicated, I'm starting to doubt whether the structure has to be implicit like this or we should still have the same structure but with explicit imports.
|
We can actually avoid generating anything and just add ESLint rules to project tempalte |
|
Closing for now since we decided to chagne the direction |


File-based auto-loading for modules and migrations
Summary
Adds convention-based auto-discovery of modules and migrations from the file system, so you don't need to manually wire everything into startApp()
The CLI (modelence dev / modelence build) scans /modules/ and /migrations/, generates a TypeScript entry wrapper with static imports, and feeds it to tsx/tsup
Fully backward compatible — existing startApp({ modules: [...], migrations: [...] }) works unchanged, auto-discovered items are merged in
Convention
How it works
Before launching dev/build, the CLI scans the file system and generates .modelence/generated/autoModules.ts (static imports + setAutoLoadedModules/setAutoLoadedMigrations calls) and .modelence/generated/entry.ts (imports autoModules then user's app.ts)
entry.ts becomes the actual entry point for tsx (dev) and tsup (build)
startApp merges auto-loaded modules/migrations with any explicitly passed ones
Duplicate module names or migration versions throw at startup
Note
Medium Risk
Introduces a new code-generation + startup path that changes dev/build entrypoints and merges additional modules/migrations at runtime; failures in scanning, name/version collisions, or generated imports could break app startup/builds.
Overview
Adds a file-based auto-loading system: the CLI now scans
<serverDir>/modulesand<serverDir>/migrations, generates.modelence/generated/autoModules.ts+.modelence/generated/entry.ts, and uses the generated entry as the dev (tsx watch) and build (tsup) entrypoint.startApp()now merges auto-discovered modules/migrations with explicitly provided ones, validates duplicate module names and duplicate migration versions, and sorts migrations by version before running.Also generates an optional typed client helper at
.modelence/generated/clientModules.ts(and attempts to add a@modelence/modulestsconfig path alias), and updates deployment to use the built server filename instead of a hardcodedapp.mjs.Reviewed by Cursor Bugbot for commit 73c7793. Bugbot is set up for automated code reviews on this repo. Configure here.