simple-module-cli 0.0.24__tar.gz → 0.0.26__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 (96) hide show
  1. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/PKG-INFO +1 -1
  2. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/pyproject.toml +1 -1
  3. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-conventions/SKILL.md +6 -3
  4. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-creating/SKILL.md +3 -2
  5. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-database/SKILL.md +4 -3
  6. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-inertia-pages/SKILL.md +2 -0
  7. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-locales/SKILL.md +2 -0
  8. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-migrations/SKILL.md +3 -3
  9. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-registries/SKILL.md +22 -13
  10. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-testing/SKILL.md +2 -0
  11. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/.gitignore +0 -0
  12. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/LICENSE +0 -0
  13. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/README.md +0 -0
  14. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/__init__.py +0 -0
  15. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/_env.py +0 -0
  16. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/app_project.py +0 -0
  17. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/case.py +0 -0
  18. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/catalog.py +0 -0
  19. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/cli.py +0 -0
  20. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/new.py +0 -0
  21. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/package_update.py +0 -0
  22. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/pins.py +0 -0
  23. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/plugins.py +0 -0
  24. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/recipes.py +0 -0
  25. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/scaffolding.py +0 -0
  26. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/README.md +0 -0
  27. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-cli/SKILL.md +0 -0
  28. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills/simple-module-doctor/SKILL.md +0 -0
  29. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/skills_cmd.py +0 -0
  30. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/.env.example +0 -0
  31. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/.gitignore +0 -0
  32. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/Makefile +0 -0
  33. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/README.md.tpl +0 -0
  34. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/_optional/background_tasks/Makefile.snippet +0 -0
  35. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/_optional/background_tasks/docker-compose.yml +0 -0
  36. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/_optional/background_tasks/host.Dockerfile +0 -0
  37. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/_optional/background_tasks/run_worker.py +0 -0
  38. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/_optional/background_tasks/worker.Dockerfile +0 -0
  39. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/alembic.ini +0 -0
  40. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/client_app/app.tsx +0 -0
  41. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/client_app/main.tsx +0 -0
  42. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/client_app/package.json.tpl +0 -0
  43. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/client_app/pages/Error.tsx +0 -0
  44. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/client_app/pages/Landing.tsx +0 -0
  45. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/client_app/pages.ts +0 -0
  46. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/client_app/styles.css +0 -0
  47. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/client_app/tsconfig.json +0 -0
  48. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/client_app/vite.config.ts +0 -0
  49. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/main.py +0 -0
  50. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/migrations/env.py +0 -0
  51. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/migrations/script.py.mako +0 -0
  52. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/migrations/versions/.gitkeep +0 -0
  53. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/pyproject.toml.tpl +0 -0
  54. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/routes.py +0 -0
  55. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/host/templates/index.html +0 -0
  56. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/.github/workflows/ci.yml +0 -0
  57. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/.github/workflows/publish.yml.tpl +0 -0
  58. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/.gitignore +0 -0
  59. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/README.md.tpl +0 -0
  60. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/__PACKAGE__/__init__.py +0 -0
  61. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/__PACKAGE__/endpoints/__init__.py +0 -0
  62. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/__PACKAGE__/endpoints/api.py.tpl +0 -0
  63. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/__PACKAGE__/module.py.tpl +0 -0
  64. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/__PACKAGE__/pages/.gitkeep +0 -0
  65. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/__PACKAGE__/services.py.tpl +0 -0
  66. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/__PACKAGE__/settings.py.tpl +0 -0
  67. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/package.json.tpl +0 -0
  68. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/pyproject.toml.tpl +0 -0
  69. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/tests/test_module.py.tpl +0 -0
  70. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/module/tsconfig.json.tpl +0 -0
  71. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/workspace/.env.example +0 -0
  72. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/workspace/.gitignore +0 -0
  73. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/workspace/Makefile +0 -0
  74. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/workspace/README.md.tpl +0 -0
  75. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/workspace/package.json.tpl +0 -0
  76. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/templates/workspace/pyproject.toml.tpl +0 -0
  77. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/simple_module_cli/wizard.py +0 -0
  78. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_build_packaging.py +0 -0
  79. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_case.py +0 -0
  80. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_cli_catalog.py +0 -0
  81. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_cli_new.py +0 -0
  82. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_cli_new_dest_tolerance.py +0 -0
  83. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_cli_new_regressions.py +0 -0
  84. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_cli_new_scaffold_layout.py +0 -0
  85. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_cli_package_update.py +0 -0
  86. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_cli_recipes.py +0 -0
  87. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_cli_wizard.py +0 -0
  88. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_create_module_ci_skip.py +0 -0
  89. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_env_helper.py +0 -0
  90. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_module_pages_manifest.py +0 -0
  91. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_no_framework_deps.py +0 -0
  92. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_plugin_discovery.py +0 -0
  93. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_scaffold_rollback.py +0 -0
  94. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_scaffolding_host.py +0 -0
  95. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_scaffolding_module.py +0 -0
  96. {simple_module_cli-0.0.24 → simple_module_cli-0.0.26}/tests/test_skills_cmd.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simple_module_cli
3
- Version: 0.0.24
3
+ Version: 0.0.26
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.24"
3
+ version = "0.0.26"
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"
@@ -17,12 +17,14 @@ from simple_module_db.base import create_module_base
17
17
 
18
18
  Base = create_module_base("orders")
19
19
 
20
- class Order(Base, AuditMixin, table=True): # table
20
+
21
+ class Order(Base, AuditMixin, table=True): # table
21
22
  __tablename__ = "orders_order"
22
23
  id: int | None = Field(default=None, primary_key=True)
23
24
  name: str = Field(max_length=200)
24
25
 
25
- class OrderOut(SQLModel): # DTO — plain SQLModel, no table=True
26
+
27
+ class OrderOut(SQLModel): # DTO — plain SQLModel, no table=True
26
28
  model_config = ConfigDict(from_attributes=True)
27
29
  id: int
28
30
  name: str
@@ -39,8 +41,9 @@ Treat 300 lines as the design pressure on every `.py`, `.ts`, and `.tsx` file (t
39
41
  ```python
40
42
  class UsersModule(ModuleBase):
41
43
  def register_settings(self, app: FastAPI) -> None:
42
- from users.settings import UsersSettings # reads SM_USERS_* env
44
+ from users.settings import UsersSettings # reads SM_USERS_* env
43
45
  from users.state import UsersState
46
+
44
47
  app.state.users = UsersState(settings=UsersSettings())
45
48
  ```
46
49
 
@@ -72,12 +72,13 @@ orders = "orders.module:OrdersModule"
72
72
  # modules/orders/orders/module.py
73
73
  from simple_module_core.module import ModuleBase, ModuleMeta
74
74
 
75
+
75
76
  class OrdersModule(ModuleBase):
76
77
  meta = ModuleMeta(
77
- name="Orders", # PascalCase, must be unique
78
+ name="Orders", # PascalCase, must be unique
78
79
  route_prefix="/api/orders",
79
80
  view_prefix="/orders",
80
- depends_on=[], # other module names (PascalCase)
81
+ depends_on=[], # other module names (PascalCase)
81
82
  )
82
83
  ```
83
84
 
@@ -17,8 +17,9 @@ from simple_module_db.mixins import AuditMixin
17
17
 
18
18
  Base = create_module_base("orders")
19
19
 
20
+
20
21
  class Order(Base, AuditMixin, table=True):
21
- __tablename__ = "orders_order" # module-name prefix; required
22
+ __tablename__ = "orders_order" # module-name prefix; required
22
23
  id: int | None = Field(default=None, primary_key=True)
23
24
  name: str = Field(max_length=200)
24
25
  ```
@@ -70,9 +71,9 @@ A pending-writes flag is set by an `after_flush` listener and by inspecting `ses
70
71
  async def create_order(session: AsyncSession, payload: OrderCreate) -> Order:
71
72
  order = Order(name=payload.name)
72
73
  session.add(order)
73
- await session.flush() # order.id is now populated
74
+ await session.flush() # order.id is now populated
74
75
  audit_log.record(order_id=order.id)
75
- return order # the dependency commits when the request returns
76
+ return order # the dependency commits when the request returns
76
77
  ```
77
78
 
78
79
  ## Pitfalls
@@ -43,6 +43,7 @@ Boot regenerates it too; mid-session adds need the manual call before HMR sees t
43
43
  def _serialize_principal(user: UserContext) -> dict:
44
44
  return {"id": user.id, "name": user.name, "email": user.email, "roles": user.roles}
45
45
 
46
+
46
47
  class AuthModule(ModuleBase):
47
48
  def register_settings(self, app: FastAPI) -> None:
48
49
  app.state.principal_serializer = _serialize_principal
@@ -59,6 +60,7 @@ from simple_module_hosting.inertia_deps import InertiaDep
59
60
 
60
61
  router = APIRouter()
61
62
 
63
+
62
64
  @router.get("/")
63
65
  async def list_orders(inertia: InertiaDep, service: OrdersServiceDep):
64
66
  return await inertia.render("Orders/List", {"orders": await service.list()})
@@ -22,6 +22,7 @@ modules/orders/orders/
22
22
  import importlib.resources
23
23
  from pathlib import Path
24
24
 
25
+
25
26
  class OrdersModule(ModuleBase):
26
27
  def locale_dirs(self) -> dict[str, Path]:
27
28
  # key = namespace, value = directory holding <lang>.json files
@@ -101,6 +102,7 @@ Inject `TranslatorDep` (from `simple_module_hosting.i18n_deps`) into an endpoint
101
102
  ```python
102
103
  from simple_module_hosting.i18n_deps import TranslatorDep
103
104
 
105
+
104
106
  async def create(t: TranslatorDep):
105
107
  raise HTTPException(404, t.t("orders.errors.not_found", id=order_id))
106
108
  ```
@@ -37,8 +37,8 @@ from simple_module_db import (
37
37
  render_item,
38
38
  )
39
39
 
40
- target_metadata = build_module_metadata() # imports every installed module's <pkg>.models
41
- include_object = make_include_object(target_metadata)
40
+ target_metadata = build_module_metadata() # imports every installed module's <pkg>.models
41
+ include_object = make_include_object(target_metadata)
42
42
  process_revision_directives = make_process_revision_directives(target_metadata)
43
43
  # context.configure(..., render_item=render_item)
44
44
  ```
@@ -74,7 +74,7 @@ Each new module's first revision should set a `branch_labels` tuple matching the
74
74
  # host/migrations/versions/70786227af4c_add_audit_log_tables.py
75
75
  revision = "70786227af4c"
76
76
  down_revision = "41cf2c53660e"
77
- branch_labels = ("audit_log",) # ← add by hand on this first revision
77
+ branch_labels = ("audit_log",) # ← add by hand on this first revision
78
78
  depends_on = None
79
79
  ```
80
80
 
@@ -14,6 +14,7 @@ All four are populated in **Phase 5** of `app_builder.build_app`, in this per-mo
14
14
  ```python
15
15
  from simple_module_core.menu import MenuItem, MenuRegistry, MenuSection
16
16
 
17
+
17
18
  class OrdersModule(ModuleBase):
18
19
  def register_menu_items(self, registry: MenuRegistry) -> None:
19
20
  registry.add(
@@ -23,7 +24,7 @@ class OrdersModule(ModuleBase):
23
24
  icon="shopping-cart",
24
25
  order=10,
25
26
  section=MenuSection.SIDEBAR,
26
- roles=["admin", "staff"], # empty list = all authenticated users
27
+ roles=["admin", "staff"], # empty list = all authenticated users
27
28
  )
28
29
  )
29
30
  ```
@@ -35,13 +36,17 @@ class OrdersModule(ModuleBase):
35
36
  ```python
36
37
  from simple_module_core.permissions import PermissionRegistry
37
38
 
39
+
38
40
  class OrdersModule(ModuleBase):
39
41
  def register_permissions(self, registry: PermissionRegistry) -> None:
40
- registry.add_group("Orders", [
41
- "orders.view",
42
- "orders.create",
43
- "orders.delete",
44
- ])
42
+ registry.add_group(
43
+ "Orders",
44
+ [
45
+ "orders.view",
46
+ "orders.create",
47
+ "orders.delete",
48
+ ],
49
+ )
45
50
  registry.map_role("staff", ["orders.view", "orders.create"])
46
51
  ```
47
52
 
@@ -56,13 +61,16 @@ To check inside an endpoint, depend on `RequiresPermission("<module>.<action>")`
56
61
  ```python
57
62
  from simple_module_core.feature_flags import FeatureFlagDefinition, FeatureFlagRegistry
58
63
 
64
+
59
65
  class OrdersModule(ModuleBase):
60
66
  def register_feature_flags(self, registry: FeatureFlagRegistry) -> None:
61
- registry.add(FeatureFlagDefinition(
62
- name="orders.bulk_import",
63
- description="Enables the CSV bulk-import UI on /orders/import",
64
- default_enabled=False,
65
- ))
67
+ registry.add(
68
+ FeatureFlagDefinition(
69
+ name="orders.bulk_import",
70
+ description="Enables the CSV bulk-import UI on /orders/import",
71
+ default_enabled=False,
72
+ )
73
+ )
66
74
  ```
67
75
 
68
76
  **Resolution order at request time:** tenant override > system override > `default_enabled`. Per-tenant overrides come from the multi-tenant context (`request.state.tenant_id` from `TenantMiddleware`); system overrides come from the settings module's persisted overrides table.
@@ -101,6 +109,7 @@ The event bus is async and in-process (backed by `pyee`'s `AsyncIOEventEmitter`)
101
109
  from dataclasses import dataclass
102
110
  from simple_module_core.events import Event
103
111
 
112
+
104
113
  @dataclass
105
114
  class OrderPlaced(Event):
106
115
  order_id: int
@@ -113,12 +122,12 @@ class OrderPlaced(Event):
113
122
  from simple_module_core.events import EventBus
114
123
  from orders.contracts.events import OrderPlaced
115
124
 
125
+
116
126
  class NotificationsModule(ModuleBase):
117
127
  def register_event_handlers(self, bus: EventBus, app: FastAPI | None = None) -> None:
118
128
  bus.subscribe(OrderPlaced, self._send_receipt)
119
129
 
120
- async def _send_receipt(self, event: OrderPlaced) -> None:
121
- ...
130
+ async def _send_receipt(self, event: OrderPlaced) -> None: ...
122
131
  ```
123
132
 
124
133
  ```python
@@ -30,11 +30,13 @@ async def test_service_creates_order(db_session):
30
30
  order = await OrdersService(db_session).create(name="x")
31
31
  assert order.id is not None
32
32
 
33
+
33
34
  # API test — JSON endpoint
34
35
  async def test_api_lists_orders(authenticated_client):
35
36
  resp = await authenticated_client.get("/api/orders")
36
37
  assert resp.status_code == 200
37
38
 
39
+
38
40
  # View test — Inertia endpoint (X-Inertia header)
39
41
  async def test_view_renders_index(authenticated_client):
40
42
  resp = await authenticated_client.get("/orders/", headers={"X-Inertia": "true"})