simple-module-cli 0.0.34__tar.gz → 0.0.35__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/PKG-INFO +1 -1
  2. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/pyproject.toml +1 -1
  3. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/app_project.py +15 -4
  4. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/docker/host-flat.Dockerfile +2 -2
  5. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/docker/host.Dockerfile +2 -2
  6. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/app.tsx +8 -4
  7. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/package.json.tpl +5 -5
  8. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/pages.ts +8 -1
  9. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/routes.py +1 -1
  10. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/templates/index.html +1 -1
  11. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/.github/workflows/ci.yml +6 -6
  12. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/.github/workflows/publish.yml.tpl +2 -2
  13. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/__PACKAGE__/endpoints/views.py.tpl +1 -1
  14. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/_optional/standalone/package.json.tpl +5 -3
  15. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/package.json.tpl +1 -1
  16. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_new_regressions.py +44 -3
  17. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_scaffolding_host.py +11 -0
  18. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_scaffolding_module_js.py +31 -0
  19. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/.gitignore +0 -0
  20. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/LICENSE +0 -0
  21. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/README.md +0 -0
  22. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/__init__.py +0 -0
  23. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/_env.py +0 -0
  24. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/_module_build.py +0 -0
  25. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/_module_host.py +0 -0
  26. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/_templating.py +0 -0
  27. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/add_cmd.py +0 -0
  28. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/case.py +0 -0
  29. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/catalog.py +0 -0
  30. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/cli.py +0 -0
  31. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/docker_assets.py +0 -0
  32. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/git_source.py +0 -0
  33. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/module_cmd.py +0 -0
  34. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/new.py +0 -0
  35. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/package_update.py +0 -0
  36. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/pins.py +0 -0
  37. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/plugins.py +0 -0
  38. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/pypi.py +0 -0
  39. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/pyproject_edit.py +0 -0
  40. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/recipes.py +0 -0
  41. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/requirements.py +0 -0
  42. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/scaffolding.py +0 -0
  43. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/README.md +0 -0
  44. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-cli/SKILL.md +0 -0
  45. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-conventions/SKILL.md +0 -0
  46. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-creating/SKILL.md +0 -0
  47. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-database/SKILL.md +0 -0
  48. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-doctor/SKILL.md +0 -0
  49. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-inertia-pages/SKILL.md +0 -0
  50. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-locales/SKILL.md +0 -0
  51. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-migrations/SKILL.md +0 -0
  52. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-registries/SKILL.md +0 -0
  53. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills/simple-module-testing/SKILL.md +0 -0
  54. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/skills_cmd.py +0 -0
  55. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/docker/Makefile.snippet +0 -0
  56. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/docker/compose-base-postgres.yml.tpl +0 -0
  57. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/docker/compose-base-sqlite.yml.tpl +0 -0
  58. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/docker/compose-tasks-postgres.yml.tpl +0 -0
  59. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/docker/compose-tasks-sqlite.yml.tpl +0 -0
  60. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/docker/dockerignore +0 -0
  61. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/.env.example +0 -0
  62. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/.gitignore +0 -0
  63. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/Makefile +0 -0
  64. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/README.md.tpl +0 -0
  65. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/_optional/background_tasks/Makefile.snippet +0 -0
  66. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/_optional/background_tasks/run_worker.py +0 -0
  67. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/alembic.ini +0 -0
  68. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/main.tsx +0 -0
  69. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/module-assets.ts +0 -0
  70. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/pages/Error.tsx +0 -0
  71. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/pages/Landing.tsx +0 -0
  72. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/styles.css +0 -0
  73. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/tsconfig.json +0 -0
  74. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/vite.config.ts +0 -0
  75. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/client_app/vite.dev-url.ts +0 -0
  76. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/main.py +0 -0
  77. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/migrations/env.py +0 -0
  78. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/migrations/script.py.mako +0 -0
  79. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/migrations/versions/.gitkeep +0 -0
  80. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/host/pyproject.toml.tpl +0 -0
  81. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/.gitignore +0 -0
  82. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/README.md.tpl +0 -0
  83. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/__PACKAGE__/__init__.py +0 -0
  84. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/__PACKAGE__/endpoints/__init__.py +0 -0
  85. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/__PACKAGE__/endpoints/api.py.tpl +0 -0
  86. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/__PACKAGE__/module.py.tpl +0 -0
  87. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/__PACKAGE__/pages/Index.tsx.tpl +0 -0
  88. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/__PACKAGE__/services.py.tpl +0 -0
  89. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/__PACKAGE__/settings.py.tpl +0 -0
  90. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/_optional/standalone/tsconfig.json.tpl +0 -0
  91. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/pyproject.toml.tpl +0 -0
  92. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/tests/test___PACKAGE__.py.tpl +0 -0
  93. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/module/tsconfig.json.tpl +0 -0
  94. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/workspace/.env.example +0 -0
  95. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/workspace/.gitignore +0 -0
  96. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/workspace/Makefile +0 -0
  97. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/workspace/README.md.tpl +0 -0
  98. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/workspace/package.json.tpl +0 -0
  99. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/templates/workspace/pyproject.toml.tpl +0 -0
  100. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/update_cmd.py +0 -0
  101. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/simple_module_cli/wizard.py +0 -0
  102. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/conftest.py +0 -0
  103. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_build_packaging.py +0 -0
  104. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_case.py +0 -0
  105. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_add_cmd.py +0 -0
  106. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_add_spec_parse.py +0 -0
  107. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_catalog.py +0 -0
  108. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_docker_assets.py +0 -0
  109. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_git_scan.py +0 -0
  110. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_new.py +0 -0
  111. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_new_dest_tolerance.py +0 -0
  112. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_new_git_module.py +0 -0
  113. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_new_migration_bootstrap.py +0 -0
  114. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_new_scaffold_layout.py +0 -0
  115. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_package_update.py +0 -0
  116. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_package_update_pins.py +0 -0
  117. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_pyproject_edit.py +0 -0
  118. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_recipes.py +0 -0
  119. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_update_sources.py +0 -0
  120. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_vite_port_env.py +0 -0
  121. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_wizard.py +0 -0
  122. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_cli_wizard_git.py +0 -0
  123. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_create_module_ci_skip.py +0 -0
  124. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_env_helper.py +0 -0
  125. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_module_cmd_build.py +0 -0
  126. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_module_cmd_e2e.py +0 -0
  127. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_module_cmd_verify.py +0 -0
  128. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_module_css_assets.py +0 -0
  129. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_module_css_build.py +0 -0
  130. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_module_npm_aliases.py +0 -0
  131. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_module_pages_manifest.py +0 -0
  132. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_no_framework_deps.py +0 -0
  133. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_plugin_discovery.py +0 -0
  134. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_scaffold_rollback.py +0 -0
  135. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_scaffolding_module.py +0 -0
  136. {simple_module_cli-0.0.34 → simple_module_cli-0.0.35}/tests/test_skills_cmd.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: simple_module_cli
3
- Version: 0.0.34
3
+ Version: 0.0.35
4
4
  Summary: Standalone scaffolder for the SimpleModule framework — `smpy new`, `smpy create-module`, plugin host.
5
5
  Project-URL: Homepage, https://github.com/antosubash/simple_module_python
6
6
  Project-URL: Repository, https://github.com/antosubash/simple_module_python
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "simple_module_cli"
3
- version = "0.0.34"
3
+ version = "0.0.35"
4
4
  description = "Standalone scaffolder for the SimpleModule framework — `smpy new`, `smpy create-module`, plugin host."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -61,13 +61,24 @@ _APP_NPM_DEPS = {
61
61
  "@simple-module-py/i18n": _FRAMEWORK_VERSION,
62
62
  "react": "^19.0.0",
63
63
  "react-dom": "^19.0.0",
64
- "@inertiajs/react": "^2.0.0",
64
+ "@inertiajs/react": "^3.7.0",
65
65
  }
66
+ # Flat mode has no npm workspaces, so `client_app/package.json` is never
67
+ # installed — the root package.json seeded from these two dicts is the only
68
+ # manifest npm reads. It must therefore cover everything client_app needs to
69
+ # build, not just the framework pins: `vite.config.ts` imports
70
+ # `@tailwindcss/vite`, and `tsc` needs the @types packages. Keep this in step
71
+ # with templates/host/client_app/package.json.tpl.
66
72
  _APP_NPM_DEV_DEPS = {
67
73
  "@simple-module-py/tsconfig": _FRAMEWORK_VERSION,
68
- "@vitejs/plugin-react": "^5.0.0",
69
- "typescript": "^5.6.0",
70
- "vite": "^8.0.0",
74
+ "@tailwindcss/vite": "^4.0.0",
75
+ "@types/node": "^26.5.0",
76
+ "@types/react": "^19.0.0",
77
+ "@types/react-dom": "^19.0.0",
78
+ "@vitejs/plugin-react": "^6.1.1",
79
+ "tailwindcss": "^4.0.0",
80
+ "typescript": "^7.0.2",
81
+ "vite": "^8.2.2",
71
82
  }
72
83
 
73
84
  # Files the host template ships that the workspace template re-emits at
@@ -15,8 +15,8 @@ ENV UV_LINK_MODE=copy \
15
15
 
16
16
  WORKDIR /app
17
17
 
18
- # Node 22 for the Vite build.
19
- RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
18
+ # Node 24 for the Vite build.
19
+ RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
20
20
  && apt-get install -y --no-install-recommends nodejs \
21
21
  && rm -rf /var/lib/apt/lists/*
22
22
 
@@ -15,8 +15,8 @@ ENV UV_LINK_MODE=copy \
15
15
 
16
16
  WORKDIR /app
17
17
 
18
- # Node 22 for the Vite build.
19
- RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
18
+ # Node 24 for the Vite build.
19
+ RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
20
20
  && apt-get install -y --no-install-recommends nodejs \
21
21
  && rm -rf /var/lib/apt/lists/*
22
22
 
@@ -20,13 +20,17 @@ createInertiaApp({
20
20
  locale: initial?.locale ?? 'en',
21
21
  messages: initial?.messages ?? {},
22
22
  });
23
- let activeLocale = initial?.locale ?? null;
24
23
  router.on('success', (event) => {
25
24
  const block = (event.detail.page.props as { i18n?: I18nBlock }).i18n;
26
- if (!block) return;
27
- if (block.locale !== activeLocale && block.messages) {
25
+ // A non-null `messages` payload IS the server's signal that the client
26
+ // needs it — the backend sends `null` whenever the catalog the client
27
+ // already holds is still good. Gating on a locale change instead drops
28
+ // the catalog that arrives when the *audience* changes: signing in swaps
29
+ // the anonymous snapshot for one including admin-only modules, at the
30
+ // same locale, so every admin screen rendered raw keys
31
+ // ("dashboard.home.title") until a hard refresh.
32
+ if (block?.messages) {
28
33
  updateI18n({ locale: block.locale, messages: block.messages });
29
- activeLocale = block.locale;
30
34
  }
31
35
  });
32
36
  // Authored content (pagebuilder widgets, markdown and rich-text fields)
@@ -8,7 +8,7 @@
8
8
  "preview": "vite preview"
9
9
  },
10
10
  "dependencies": {
11
- "@inertiajs/react": "^2.0.0",
11
+ "@inertiajs/react": "^3.7.0",
12
12
  "@simple-module-py/i18n": "{{FRAMEWORK_VERSION}}",
13
13
  "@simple-module-py/ui": "{{FRAMEWORK_VERSION}}",
14
14
  "react": "^19.0.0",
@@ -17,12 +17,12 @@
17
17
  "devDependencies": {
18
18
  "@simple-module-py/tsconfig": "{{FRAMEWORK_VERSION}}",
19
19
  "@tailwindcss/vite": "^4.0.0",
20
- "@types/node": "^22.0.0",
20
+ "@types/node": "^26.5.0",
21
21
  "@types/react": "^19.0.0",
22
22
  "@types/react-dom": "^19.0.0",
23
- "@vitejs/plugin-react": "^5.0.0",
23
+ "@vitejs/plugin-react": "^6.1.1",
24
24
  "tailwindcss": "^4.0.0",
25
- "typescript": "^5.7.0",
26
- "vite": "^6.0.0"
25
+ "typescript": "^7.0.2",
26
+ "vite": "^8.2.2"
27
27
  }
28
28
  }
@@ -15,7 +15,14 @@ import { moduleGlobs } from './modules.generated';
15
15
  type PageModule = { default: React.ComponentType<Record<string, unknown>> };
16
16
  type PageLoader = () => Promise<PageModule>;
17
17
 
18
- const hostPages = import.meta.glob<PageModule>('./pages/**/*.tsx');
18
+ // A `*.test.tsx` beside a page is a test, not a page — without these
19
+ // negations it registers as a phantom page and Vite follows the import into
20
+ // the production bundle.
21
+ const hostPages = import.meta.glob<PageModule>([
22
+ './pages/**/*.tsx',
23
+ '!./pages/**/*.test.tsx',
24
+ '!./pages/**/*.spec.tsx',
25
+ ]);
19
26
 
20
27
  const pages: Record<string, PageLoader> = {};
21
28
 
@@ -10,8 +10,8 @@ module is installed.
10
10
  from __future__ import annotations
11
11
 
12
12
  from fastapi import APIRouter, Request
13
- from inertia import InertiaResponse
14
13
  from simple_module_hosting.inertia_deps import InertiaDep
14
+ from simple_module_inertia import InertiaResponse
15
15
 
16
16
  router = APIRouter()
17
17
 
@@ -7,7 +7,7 @@
7
7
  crawlers and link previews see the configured site name before React
8
8
  hydrates; Inertia's <Head> takes over per-page titles after that. #}
9
9
  {% set brand = branding_head(request) %}
10
- <title>{{ brand.app_name }}</title>
10
+ <title data-inertia="">{{ brand.app_name }}</title>
11
11
  {% if brand.theme_color %}<meta name="theme-color" content="{{ brand.theme_color }}" />{% endif %}
12
12
  <link rel="preconnect" href="https://fonts.googleapis.com" />
13
13
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
@@ -12,10 +12,10 @@ jobs:
12
12
  test:
13
13
  runs-on: ubuntu-latest
14
14
  steps:
15
- - uses: actions/checkout@v4
15
+ - uses: actions/checkout@v7
16
16
 
17
17
  - name: Install uv
18
- uses: astral-sh/setup-uv@v3
18
+ uses: astral-sh/setup-uv@v9.0.0
19
19
  with:
20
20
  version: latest
21
21
 
@@ -34,14 +34,14 @@ jobs:
34
34
  frontend:
35
35
  runs-on: ubuntu-latest
36
36
  steps:
37
- - uses: actions/checkout@v4
37
+ - uses: actions/checkout@v7
38
38
 
39
- - uses: actions/setup-node@v4
39
+ - uses: actions/setup-node@v7
40
40
  with:
41
- node-version: '22'
41
+ node-version: '24'
42
42
 
43
43
  - name: Install uv
44
- uses: astral-sh/setup-uv@v3
44
+ uses: astral-sh/setup-uv@v9.0.0
45
45
  with:
46
46
  version: latest
47
47
 
@@ -29,10 +29,10 @@ jobs:
29
29
  contents: read
30
30
 
31
31
  steps:
32
- - uses: actions/checkout@v4
32
+ - uses: actions/checkout@v7
33
33
 
34
34
  - name: Install uv
35
- uses: astral-sh/setup-uv@v3
35
+ uses: astral-sh/setup-uv@v9.0.0
36
36
  with:
37
37
  version: latest
38
38
 
@@ -3,8 +3,8 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from fastapi import APIRouter
6
- from inertia import InertiaResponse
7
6
  from simple_module_hosting.inertia_deps import InertiaDep
7
+ from simple_module_inertia import InertiaResponse
8
8
 
9
9
  router = APIRouter()
10
10
 
@@ -9,19 +9,21 @@
9
9
  "peerDependencies": {
10
10
  "react": "^19.0.0",
11
11
  "react-dom": "^19.0.0",
12
- "@inertiajs/react": "^2.0.0",
12
+ "@inertiajs/react": "^3.7.0",
13
13
  "@simple-module-py/ui": "*"
14
14
  },
15
15
  "devDependencies": {
16
- "@inertiajs/react": "^2.0.0",
16
+ "@inertiajs/react": "^3.7.0",
17
17
  "@simple-module-py/i18n": "{{FRAMEWORK_VERSION}}",
18
18
  "@simple-module-py/tsconfig": "{{FRAMEWORK_VERSION}}",
19
19
  "@simple-module-py/ui": "{{FRAMEWORK_VERSION}}",
20
+ "@types/node": "^26.5.0",
20
21
  "@types/react": "^19.0.0",
21
22
  "@types/react-dom": "^19.0.0",
22
23
  "react": "^19.0.0",
23
24
  "react-dom": "^19.0.0",
24
- "typescript": "^5.7.0"
25
+ "typescript": "^7.0.2",
26
+ "vite": "^8.2.2"
25
27
  },
26
28
  "dependencies": {}
27
29
  }
@@ -6,7 +6,7 @@
6
6
  "peerDependencies": {
7
7
  "react": "^19.0.0",
8
8
  "react-dom": "^19.0.0",
9
- "@inertiajs/react": "^2.0.0",
9
+ "@inertiajs/react": "^3.7.0",
10
10
  "@simple-module-py/ui": "*"
11
11
  },
12
12
  "devDependencies": {
@@ -13,9 +13,9 @@ from simple_module_cli.cli import app
13
13
  from typer.testing import CliRunner
14
14
 
15
15
 
16
- def test_sm_new_flat_pins_inertia_react_to_v2(tmp_path: Path) -> None:
16
+ def test_sm_new_flat_pins_inertia_react_to_v3(tmp_path: Path) -> None:
17
17
  """Issue #128: flat scaffold's root package.json must peer-match
18
- @simple-module-py/ui's ``@inertiajs/react: ^2.0.0`` peer dep."""
18
+ @simple-module-py/ui's ``@inertiajs/react: ^3.0.0`` peer dep."""
19
19
  runner = CliRunner()
20
20
  target = tmp_path / "demo"
21
21
  runner.invoke(
@@ -25,7 +25,7 @@ def test_sm_new_flat_pins_inertia_react_to_v2(tmp_path: Path) -> None:
25
25
  data = json.loads((target / "package.json").read_text())
26
26
  inertia = data.get("dependencies", {}).get("@inertiajs/react")
27
27
  assert inertia is not None
28
- assert inertia.startswith("^2."), f"expected ^2.x, got {inertia!r}"
28
+ assert inertia.startswith("^3."), f"expected ^3.x, got {inertia!r}"
29
29
 
30
30
 
31
31
  def test_sm_new_sample_module_pins_match_framework_version(tmp_path: Path) -> None:
@@ -211,6 +211,25 @@ def test_sm_new_rejects_mixed_separators(tmp_path: Path) -> None:
211
211
  assert result.exit_code != 0
212
212
 
213
213
 
214
+ def test_scaffold_adopts_every_locale_catalog_the_server_sends(tmp_path: Path) -> None:
215
+ """Issue #321: the scaffold gated ``updateI18n`` on a locale *change*, which
216
+ drops the catalog that arrives when the audience changes instead. Signing in
217
+ swaps the anonymous snapshot for one including admin-only modules at the same
218
+ locale, so every admin screen rendered raw keys ("dashboard.home.title")
219
+ until a hard refresh. A non-null ``messages`` payload is itself the server's
220
+ signal that the client needs it."""
221
+ from simple_module_cli.scaffolding import create_host
222
+
223
+ dest = tmp_path / "demo"
224
+ create_host(dest, name="demo-host", modules=["Dashboard", "Auth"])
225
+
226
+ app_tsx = (dest / "client_app" / "app.tsx").read_text()
227
+ assert "updateI18n" in app_tsx
228
+ assert "activeLocale" not in app_tsx, (
229
+ "the locale gate is back — a same-locale catalog would be dropped again"
230
+ )
231
+
232
+
214
233
  def test_sm_new_no_install_next_steps_include_initial_migration(tmp_path: Path) -> None:
215
234
  """Issue #135: ``host/migrations/versions/`` ships empty, so a fresh
216
235
  ``make migrate`` is a no-op. The printed next-steps must therefore
@@ -224,3 +243,25 @@ def test_sm_new_no_install_next_steps_include_initial_migration(tmp_path: Path)
224
243
  assert result.exit_code == 0, result.output
225
244
  assert 'make migration msg="initial schema"' in result.output
226
245
  assert "make migrate" in result.output
246
+
247
+
248
+ def test_sm_new_flat_root_covers_client_app_build_deps(tmp_path: Path) -> None:
249
+ """Flat scaffolds have no npm workspaces, so ``client_app/package.json`` is
250
+ never installed and the root manifest is the only one npm reads. It must
251
+ therefore carry everything the client build imports — ``vite.config.ts``
252
+ pulls in ``@tailwindcss/vite``, so a root missing it failed ``vite build``
253
+ with ``Could not resolve '@tailwindcss/vite'``."""
254
+ runner = CliRunner()
255
+ target = tmp_path / "demo"
256
+ runner.invoke(
257
+ app,
258
+ ["new", "demo", "--yes", "--flat", "--no-install", "--dest", str(target)],
259
+ )
260
+ root = json.loads((target / "package.json").read_text())
261
+ client_app = json.loads((target / "client_app" / "package.json").read_text())
262
+ assert "workspaces" not in root, "flat mode must stay workspace-free"
263
+
264
+ installed = {**root.get("dependencies", {}), **root.get("devDependencies", {})}
265
+ required = {**client_app.get("dependencies", {}), **client_app.get("devDependencies", {})}
266
+ missing = sorted(set(required) - set(installed))
267
+ assert not missing, f"flat root package.json is missing client_app deps: {missing}"
@@ -41,6 +41,17 @@ class TestCreateHost:
41
41
  ]:
42
42
  assert (dest / relpath).exists(), f"missing: {relpath}"
43
43
 
44
+ async def test_pages_ts_excludes_colocated_test_files(self, tmp_path):
45
+ """Guards template drift from host/client_app/pages.ts: without these
46
+ negations a colocated test file ships to the production bundle."""
47
+ from simple_module_cli.scaffolding import create_host
48
+
49
+ dest = tmp_path / "demo"
50
+ create_host(dest, name="demo-host", modules=[])
51
+ pages_ts = (dest / "client_app" / "pages.ts").read_text(encoding="utf-8")
52
+ assert "'!./pages/**/*.test.tsx'" in pages_ts
53
+ assert "'!./pages/**/*.spec.tsx'" in pages_ts
54
+
44
55
  async def test_package_json_carries_host_name(self, tmp_path):
45
56
  """client_app/package.json has its `name` prefixed with the host name."""
46
57
  from simple_module_cli.scaffolding import create_host
@@ -92,6 +92,37 @@ class TestStandaloneOverlay:
92
92
  assert '"@simple-module-py/tsconfig": "0.0.27"' in pkg
93
93
  assert '"typescript"' in pkg
94
94
 
95
+ async def test_standalone_ships_the_types_its_tsconfig_declares(self, tmp_path):
96
+ """The shared base.json sets ``types: ["vite/client", "node"]``, so a
97
+ standalone module that doesn't depend on `vite` and `@types/node` fails
98
+ its own CI `npm run typecheck` with TS2688 "Cannot find type definition
99
+ file for 'node'/'vite/client'" on the very first run."""
100
+ import json
101
+ from pathlib import Path
102
+
103
+ from simple_module_cli.scaffolding import create_module
104
+
105
+ dest = tmp_path / "simple-module-my-feature"
106
+ create_module(dest, name="MyFeature", standalone=True)
107
+
108
+ base = json.loads(
109
+ (Path(__file__).parents[3] / "packages" / "tsconfig" / "base.json").read_text(
110
+ encoding="utf-8"
111
+ )
112
+ )
113
+ declared = base.get("compilerOptions", {}).get("types", [])
114
+ # "vite/client" is shipped by `vite`; "node" by `@types/node`.
115
+ providers = {"vite/client": "vite", "node": "@types/node"}
116
+ pkg = json.loads((dest / "package.json").read_text(encoding="utf-8"))
117
+ dev_deps = pkg.get("devDependencies", {})
118
+ for entry in declared:
119
+ provider = providers.get(entry)
120
+ assert provider is not None, f"no known provider for tsconfig type {entry!r}"
121
+ assert provider in dev_deps, (
122
+ f"base.json declares types {entry!r} but the standalone module "
123
+ f"scaffold does not depend on {provider!r}"
124
+ )
125
+
95
126
  async def test_in_repo_keeps_workspace_configs(self, tmp_path):
96
127
  from simple_module_cli.scaffolding import create_module
97
128