simple-module-cli 0.0.11__tar.gz → 0.0.12__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.
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/PKG-INFO +11 -11
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/README.md +9 -9
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/pyproject.toml +3 -3
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/app_project.py +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/cli.py +7 -7
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/new.py +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/package_update.py +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/plugins.py +3 -3
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/recipes.py +2 -2
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/README.md +12 -12
- simple_module_cli-0.0.12/simple_module_cli/skills/simple-module-cli/SKILL.md +170 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/simple-module-creating/SKILL.md +2 -2
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/simple-module-inertia-pages/SKILL.md +2 -2
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/simple-module-migrations/SKILL.md +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/simple-module-testing/SKILL.md +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills_cmd.py +4 -4
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/client_app/pages.ts +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/main.py +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/wizard.py +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_build_packaging.py +2 -2
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_cli_new.py +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_cli_new_regressions.py +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_cli_package_update.py +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_cli_wizard.py +1 -1
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_scaffolding_host.py +2 -2
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_scaffolding_module.py +2 -2
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_skills_cmd.py +1 -1
- simple_module_cli-0.0.11/simple_module_cli/skills/simple-module-cli/SKILL.md +0 -170
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/.gitignore +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/LICENSE +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/__init__.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/_env.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/case.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/catalog.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/scaffolding.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/simple-module-conventions/SKILL.md +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/simple-module-database/SKILL.md +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/simple-module-doctor/SKILL.md +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/simple-module-locales/SKILL.md +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/skills/simple-module-registries/SKILL.md +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/.env.example +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/.gitignore +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/Makefile +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/README.md.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/_optional/background_tasks/Makefile.snippet +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/_optional/background_tasks/docker-compose.yml +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/_optional/background_tasks/host.Dockerfile +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/_optional/background_tasks/run_worker.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/_optional/background_tasks/worker.Dockerfile +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/alembic.ini +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/client_app/app.tsx +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/client_app/main.tsx +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/client_app/package.json.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/client_app/pages/Error.tsx +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/client_app/styles.css +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/client_app/tsconfig.json +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/client_app/vite.config.ts +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/migrations/env.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/migrations/script.py.mako +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/migrations/versions/.gitkeep +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/pyproject.toml.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/templates/index.html +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/.github/workflows/ci.yml +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/.github/workflows/publish.yml.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/.gitignore +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/README.md.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/__PACKAGE__/__init__.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/__PACKAGE__/endpoints/__init__.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/__PACKAGE__/endpoints/api.py.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/__PACKAGE__/module.py.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/__PACKAGE__/pages/.gitkeep +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/__PACKAGE__/services.py.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/__PACKAGE__/settings.py.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/package.json.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/pyproject.toml.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/tests/test_module.py.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/tsconfig.json.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/workspace/.env.example +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/workspace/.gitignore +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/workspace/Makefile +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/workspace/README.md.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/workspace/package.json.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/workspace/pyproject.toml.tpl +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_cli_catalog.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_cli_recipes.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_no_framework_deps.py +0 -0
- {simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/tests/test_plugin_discovery.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simple_module_cli
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary: Standalone scaffolder for the SimpleModule framework — `
|
|
3
|
+
Version: 0.0.12
|
|
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
|
|
7
7
|
Project-URL: Issues, https://github.com/antosubash/simple_module_python/issues
|
|
@@ -34,7 +34,7 @@ pip install simple_module_cli
|
|
|
34
34
|
# or, to keep the CLI in its own venv:
|
|
35
35
|
pipx install simple_module_cli
|
|
36
36
|
# or, to run it without installing:
|
|
37
|
-
uvx --from simple_module_cli
|
|
37
|
+
uvx --from simple_module_cli smpy new my-app
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
The package depends only on `typer` and `tomlkit` — installing it does **not** pull in FastAPI, SQLModel, or any other framework runtime.
|
|
@@ -42,21 +42,21 @@ The package depends only on `typer` and `tomlkit` — installing it does **not**
|
|
|
42
42
|
## Usage
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
smpy new my-app # interactive wizard
|
|
46
|
+
smpy new my-app --yes --preset full # all built-in modules + background jobs
|
|
47
|
+
smpy create-module my_feature # scaffold a publishable module package
|
|
48
|
+
smpy create-host bare-host # scaffold a bare host (no opinionated wiring)
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
Built-in commands: `
|
|
51
|
+
Built-in commands: `smpy new`, `smpy create-host`, `smpy create-module`.
|
|
52
52
|
|
|
53
53
|
When other framework packages are installed, they contribute additional subcommands via the `simple_module_cli.cli_plugins` entry-point group:
|
|
54
54
|
|
|
55
55
|
| Package | Commands |
|
|
56
56
|
|---|---|
|
|
57
|
-
| `simple_module_hosting` | `
|
|
58
|
-
| `simple_module_users` | `
|
|
59
|
-
| `simple_module_settings` | `
|
|
57
|
+
| `simple_module_hosting` | `smpy host gen-pages`, `smpy host sync-js-deps` |
|
|
58
|
+
| `simple_module_users` | `smpy users create-admin` |
|
|
59
|
+
| `simple_module_settings` | `smpy settings import-from-env` |
|
|
60
60
|
|
|
61
61
|
## License
|
|
62
62
|
|
|
@@ -9,7 +9,7 @@ pip install simple_module_cli
|
|
|
9
9
|
# or, to keep the CLI in its own venv:
|
|
10
10
|
pipx install simple_module_cli
|
|
11
11
|
# or, to run it without installing:
|
|
12
|
-
uvx --from simple_module_cli
|
|
12
|
+
uvx --from simple_module_cli smpy new my-app
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
The package depends only on `typer` and `tomlkit` — installing it does **not** pull in FastAPI, SQLModel, or any other framework runtime.
|
|
@@ -17,21 +17,21 @@ The package depends only on `typer` and `tomlkit` — installing it does **not**
|
|
|
17
17
|
## Usage
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
smpy new my-app # interactive wizard
|
|
21
|
+
smpy new my-app --yes --preset full # all built-in modules + background jobs
|
|
22
|
+
smpy create-module my_feature # scaffold a publishable module package
|
|
23
|
+
smpy create-host bare-host # scaffold a bare host (no opinionated wiring)
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Built-in commands: `
|
|
26
|
+
Built-in commands: `smpy new`, `smpy create-host`, `smpy create-module`.
|
|
27
27
|
|
|
28
28
|
When other framework packages are installed, they contribute additional subcommands via the `simple_module_cli.cli_plugins` entry-point group:
|
|
29
29
|
|
|
30
30
|
| Package | Commands |
|
|
31
31
|
|---|---|
|
|
32
|
-
| `simple_module_hosting` | `
|
|
33
|
-
| `simple_module_users` | `
|
|
34
|
-
| `simple_module_settings` | `
|
|
32
|
+
| `simple_module_hosting` | `smpy host gen-pages`, `smpy host sync-js-deps` |
|
|
33
|
+
| `simple_module_users` | `smpy users create-admin` |
|
|
34
|
+
| `simple_module_settings` | `smpy settings import-from-env` |
|
|
35
35
|
|
|
36
36
|
## License
|
|
37
37
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "simple_module_cli"
|
|
3
|
-
version = "0.0.
|
|
4
|
-
description = "Standalone scaffolder for the SimpleModule framework — `
|
|
3
|
+
version = "0.0.12"
|
|
4
|
+
description = "Standalone scaffolder for the SimpleModule framework — `smpy new`, `smpy create-module`, plugin host."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
license-files = ["LICENSE"]
|
|
@@ -25,7 +25,7 @@ dependencies = [
|
|
|
25
25
|
]
|
|
26
26
|
|
|
27
27
|
[project.scripts]
|
|
28
|
-
|
|
28
|
+
smpy = "simple_module_cli.cli:main"
|
|
29
29
|
simple-module = "simple_module_cli.cli:main"
|
|
30
30
|
|
|
31
31
|
[project.urls]
|
|
@@ -195,7 +195,7 @@ def _seed_static_dist_placeholder(static_dist: Path) -> None:
|
|
|
195
195
|
def _pin_sample_module_deps(sample_dest: Path) -> None:
|
|
196
196
|
"""Replace the module template's future-API range pins with exact pins.
|
|
197
197
|
|
|
198
|
-
The shared ``
|
|
198
|
+
The shared ``smpy create-module`` template ships ``>=1.0,<2.0`` against the
|
|
199
199
|
framework's eventual stable line, but the workspace-bundled sample has to
|
|
200
200
|
resolve against whatever the framework version actually is today (``==X``
|
|
201
201
|
in pre-1.0). Without rewriting, ``uv sync`` can't satisfy the workspace.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"""Root `
|
|
1
|
+
"""Root `smpy` Typer app — scaffolders + plugin mount.
|
|
2
2
|
|
|
3
3
|
Built-in commands:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
smpy new
|
|
5
|
+
smpy create-host
|
|
6
|
+
smpy create-module
|
|
7
|
+
smpy skills add / list / update
|
|
8
8
|
|
|
9
9
|
Plugins discovered via the ``simple_module_cli.cli_plugins`` entry-point
|
|
10
|
-
group are mounted as named subgroups (e.g. ``
|
|
10
|
+
group are mounted as named subgroups (e.g. ``smpy host gen-pages``).
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from __future__ import annotations
|
|
@@ -101,7 +101,7 @@ discover_and_mount(app)
|
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
def main() -> None:
|
|
104
|
-
"""Entry point for the `
|
|
104
|
+
"""Entry point for the `smpy` console script."""
|
|
105
105
|
app()
|
|
106
106
|
|
|
107
107
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""``
|
|
1
|
+
"""``smpy package-update`` — bump simple_module_* deps to latest PyPI versions.
|
|
2
2
|
|
|
3
3
|
Walks the project's ``pyproject.toml`` (and any ``[tool.uv.workspace]`` members),
|
|
4
4
|
finds every dependency whose distribution name starts with ``simple_module_`` /
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"""Plugin discovery for ``
|
|
1
|
+
"""Plugin discovery for ``smpy`` via the ``simple_module_cli.cli_plugins`` group.
|
|
2
2
|
|
|
3
3
|
Each entry-point's value (``module:attr``) must resolve to a
|
|
4
4
|
:class:`typer.Typer` instance. The entry-point name becomes the
|
|
5
|
-
subcommand namespace under ``
|
|
5
|
+
subcommand namespace under ``smpy`` (e.g. ``smpy host gen-pages``).
|
|
6
6
|
|
|
7
7
|
Failed loads (broken import, wrong type) print one line to stderr and
|
|
8
|
-
are skipped — ``
|
|
8
|
+
are skipped — ``smpy`` keeps working with whatever else loads.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Per-module post-scaffold recipes.
|
|
2
2
|
|
|
3
|
-
A recipe is invoked by ``
|
|
3
|
+
A recipe is invoked by ``smpy new`` after the base host scaffold lands. It
|
|
4
4
|
performs module-specific actions (write helper scripts, append Make
|
|
5
5
|
targets, drop a docker-compose stack). The framework layer is kept free
|
|
6
6
|
of devex concerns — recipes know about Makefiles and compose, framework
|
|
@@ -68,7 +68,7 @@ class BackgroundTasksRecipe:
|
|
|
68
68
|
if path.exists():
|
|
69
69
|
raise FileExistsError(
|
|
70
70
|
f"{path} already exists — refusing to clobber. "
|
|
71
|
-
"Remove the file or run `
|
|
71
|
+
"Remove the file or run `smpy new` against an empty directory."
|
|
72
72
|
)
|
|
73
73
|
|
|
74
74
|
run_worker_dest.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -6,22 +6,22 @@ Agent skills for working in a [simple_module_python](https://github.com/antosuba
|
|
|
6
6
|
|
|
7
7
|
There are two install paths — pick whichever fits your project.
|
|
8
8
|
|
|
9
|
-
### Option A — `
|
|
9
|
+
### Option A — `smpy skills` (recommended for `simple_module_cli` users)
|
|
10
10
|
|
|
11
|
-
Every project produced by `
|
|
11
|
+
Every project produced by `smpy new` already depends on `simple_module_cli`, which ships these skills inside its wheel. From the project root:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
smpy skills list # see what's available
|
|
15
|
+
smpy skills add # install ALL skills into ./.claude/skills/
|
|
16
|
+
smpy skills add simple-module-creating # install just one
|
|
17
|
+
smpy skills add -g # install into ~/.claude/skills (machine-wide)
|
|
18
|
+
smpy skills add --dest agents/skills # custom target dir
|
|
19
|
+
smpy skills add --symlink # symlink to the bundled source (good for skill devs)
|
|
20
|
+
smpy skills update # re-pull updates for skills already installed
|
|
21
|
+
smpy skills update simple-module-doctor # explicit re-pull (force-overwrites)
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
`
|
|
24
|
+
`smpy skills` resolves the bundled set against whatever version of `simple_module_cli` is installed, so upgrading the CLI ships skill updates the next time you run `smpy skills update`.
|
|
25
25
|
|
|
26
26
|
### Option B — `npx skills` (no Python install needed)
|
|
27
27
|
|
|
@@ -38,7 +38,7 @@ The CLI is [vercel-labs/skills](https://github.com/vercel-labs/skills); see its
|
|
|
38
38
|
|
|
39
39
|
| Skill | Use when |
|
|
40
40
|
|---|---|
|
|
41
|
-
| [simple-module-cli](./simple-module-cli/SKILL.md) | Invoking the `
|
|
41
|
+
| [simple-module-cli](./simple-module-cli/SKILL.md) | Invoking the `smpy` CLI — `smpy new`, `smpy create-host`, `smpy create-module`, `smpy host gen-pages`, `smpy users create-admin`, etc. |
|
|
42
42
|
| [simple-module-creating](./simple-module-creating/SKILL.md) | Adding a new feature package — scaffolding, entry-point, `ModuleMeta` |
|
|
43
43
|
| [simple-module-conventions](./simple-module-conventions/SKILL.md) | Writing or reviewing module code — the invariant list (SQLModel everywhere, settings layout, framework→plugin direction, etc.) |
|
|
44
44
|
| [simple-module-database](./simple-module-database/SKILL.md) | Adding SQLModel tables, picking a mixin, or debugging session/transaction behavior |
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: simple-module-cli
|
|
3
|
+
description: Use when invoking the `smpy` CLI for a simple_module_python project — starting a new app, scaffolding a host or a publishable module, regenerating the Inertia page manifest, importing settings overrides from env, creating an admin user, or installing the bundled agent skills. Triggers on "smpy new", "smpy create-host", "smpy create-module", "smpy host gen-pages", "smpy users create-admin", "smpy skills add", or any unfamiliar `smpy` subcommand.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# simple_module_python: the `smpy` CLI
|
|
7
|
+
|
|
8
|
+
The `smpy` command is provided by `simple_module_cli` (installed as a dep of `simple_module_hosting`). It groups four kinds of operations: scaffolding new things, project-time helpers for the host, admin shortcuts for the bundled modules, and installing the bundled agent skills.
|
|
9
|
+
|
|
10
|
+
## Top-level commands
|
|
11
|
+
|
|
12
|
+
| Command | When to use |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `smpy new <name>` | Greenfield: scaffold a complete app (host + selected modules) in one shot, with an interactive wizard for DB / tenancy / module preset |
|
|
15
|
+
| `smpy create-host <name>` | You want just a bare host project; you'll add modules later by `pip install`-ing them |
|
|
16
|
+
| `smpy create-module <name>` | You're authoring a publishable module package (separate repo, distributed via PyPI) |
|
|
17
|
+
| `smpy skills …` | Install / update the bundled agent-skill packs into a project (`add`, `list`, `update`) |
|
|
18
|
+
| `smpy host …` | Project-time helpers run from inside a host directory (page manifest, JS dep sync) |
|
|
19
|
+
| `smpy settings …` | Settings-module admin — currently `import-from-env` |
|
|
20
|
+
| `smpy users …` | Users-module admin — currently `create-admin` |
|
|
21
|
+
|
|
22
|
+
## `smpy new <name>` — the wizard
|
|
23
|
+
|
|
24
|
+
The fastest way from zero to a working app. It calls `create-host` under the hood, then installs and wires up the modules you pick.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Interactive (asks for DB, tenancy, preset, module list)
|
|
28
|
+
smpy new MyApp
|
|
29
|
+
|
|
30
|
+
# Non-interactive: take all defaults (sqlite, no tenancy, standard preset)
|
|
31
|
+
smpy new MyApp --yes
|
|
32
|
+
|
|
33
|
+
# Pick a preset and add extras
|
|
34
|
+
smpy new MyApp --preset full --tenancy --db postgres
|
|
35
|
+
smpy new MyApp --preset minimal --with background_tasks,file_storage --yes
|
|
36
|
+
|
|
37
|
+
# Scaffold only — skip uv sync / npm install / alembic upgrade head
|
|
38
|
+
smpy new MyApp --no-install
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Module presets:**
|
|
42
|
+
|
|
43
|
+
| Preset | Modules included |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `minimal` | `users` (and `auth` as a dep) |
|
|
46
|
+
| `standard` (default) | `users`, `dashboard`, `permissions` (+ deps) |
|
|
47
|
+
| `full` | every module in the catalog |
|
|
48
|
+
| `custom` | interactive — pick each module yes/no |
|
|
49
|
+
|
|
50
|
+
`--with` accepts a comma-separated list of catalog keys (`auth, users, permissions, products, dashboard, settings, feature_flags, file_storage, background_tasks, …`). Transitive `requires` are auto-added; the wizard prints `Added X (required by Y)` so you can see what got pulled in.
|
|
51
|
+
|
|
52
|
+
**Options summary:**
|
|
53
|
+
|
|
54
|
+
| Flag | Default | Meaning |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `--dest <PATH>` | `./<name>` | Where to write the project |
|
|
57
|
+
| `--db sqlite\|postgres` | `sqlite` | Backend configured in `.env.example` |
|
|
58
|
+
| `--tenancy / --no-tenancy` | `--no-tenancy` | Enable the multi-tenant middleware |
|
|
59
|
+
| `--preset minimal\|standard\|full` | wizard asks | Module bundle |
|
|
60
|
+
| `--with <names>` | none | Extra catalog keys beyond the preset |
|
|
61
|
+
| `--yes / -y` | off | Skip prompts; accept defaults |
|
|
62
|
+
| `--no-install` | off | Skip `uv sync` / `npm install` / `alembic upgrade head` |
|
|
63
|
+
|
|
64
|
+
## `smpy create-host <name>` — bare host
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
smpy create-host MyApp # empty host, no modules declared
|
|
68
|
+
smpy create-host MyApp --with Auth,Products # declare module deps in pyproject.toml
|
|
69
|
+
smpy create-host MyApp --dest ./apps/myapp # custom destination
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`--with` takes **PascalCase module names** (matching `ModuleMeta.name`), not catalog keys. Use this when you want to drive the build yourself rather than via `smpy new`'s wizard.
|
|
73
|
+
|
|
74
|
+
## `smpy create-module <name>` — module package
|
|
75
|
+
|
|
76
|
+
For module authors publishing to PyPI. Scaffolds a standalone repo containing one module.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
smpy create-module orders # writes ./simple_module_orders/
|
|
80
|
+
smpy create-module orders --dest ./packages/orders
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The result is a complete package: `pyproject.toml` with the entry point declared, `module.py` with `ModuleBase`/`ModuleMeta` skeleton, `models.py`, `contracts/`, `endpoints/{api,views}.py`, `pages/`, `locales/en.json`, plus a tests directory wired up with `simple_module_test` fixtures.
|
|
84
|
+
|
|
85
|
+
`<name>` accepts any case — `orders`, `Orders`, `ORDERS`, `blog_posts` all work. The CLI lowercases it for the directory and PascalCases it for `ModuleMeta.name`.
|
|
86
|
+
|
|
87
|
+
For the post-scaffold steps (entry point, Inertia namespace, etc.) see **simple-module-creating**.
|
|
88
|
+
|
|
89
|
+
## `smpy skills` — install the bundled agent skills
|
|
90
|
+
|
|
91
|
+
`simple_module_cli` ships a set of [SKILL.md](https://agentskills.io/specification) packs (the ones in this directory). Drop them into any project so Claude Code / Cursor / Codex / etc. find them automatically.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
smpy skills list # see what's available
|
|
95
|
+
smpy skills add # install ALL skills into ./.claude/skills/
|
|
96
|
+
smpy skills add simple-module-creating simple-module-cli # specific ones only
|
|
97
|
+
smpy skills add -g # ~/.claude/skills (machine-wide)
|
|
98
|
+
smpy skills add --dest agents/skills # explicit target dir
|
|
99
|
+
smpy skills add --symlink # symlink to bundled source (good when iterating on the skills themselves)
|
|
100
|
+
smpy skills update # re-pull whatever is already installed at the dest
|
|
101
|
+
smpy skills update simple-module-doctor # explicitly re-pull one (always force-overwrites)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Without `--force`, `smpy skills add` skips skills that already exist at the destination** — so re-running it is safe. Use `--force` (or `smpy skills update`) to overwrite.
|
|
105
|
+
|
|
106
|
+
The bundle resolves against your installed `simple_module_cli`. To get newer skills, upgrade the CLI (`uv sync` or `pip install -U simple_module_cli`) and re-run `smpy skills update`.
|
|
107
|
+
|
|
108
|
+
## `smpy host gen-pages` — regenerate the Inertia manifest
|
|
109
|
+
|
|
110
|
+
Run from a host project. Scans every installed module's `pages/*.tsx`, writes `client_app/modules.{manifest.json,generated.ts,generated.css}`, and extends Vite's `server.fs.allow`.
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
smpy host gen-pages # uses ./client_app
|
|
114
|
+
smpy host gen-pages --host-dir=apps/web/client_app
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`smpy new` runs this at scaffold time; you only need to call it manually after adding/renaming `.tsx` files mid-session, or after `pip install`-ing a new module that ships pages.
|
|
118
|
+
|
|
119
|
+
## `smpy host sync-js-deps` — install module JS deps
|
|
120
|
+
|
|
121
|
+
Wheel-installed modules ship `package.json` declarations that need to land in the host's `client_app/node_modules`. This command does that. **In-repo workspace modules don't need it** — npm workspaces resolve them automatically.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
smpy host sync-js-deps # uses ./client_app
|
|
125
|
+
smpy host sync-js-deps --host-client-app=apps/web/client_app
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Run after `pip install <module>` if the new module ships frontend code.
|
|
129
|
+
|
|
130
|
+
## `smpy settings import-from-env`
|
|
131
|
+
|
|
132
|
+
Walks the live environment for every `SM_<PREFIX>_<FIELD>` variable matching a registered settings dataclass and writes a SYSTEM-tier override into the settings module's store. Useful when promoting from environment-driven config (typical in Docker) to in-DB overrides (manageable in the admin UI) without re-keying values by hand.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
smpy settings import-from-env
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## `smpy users create-admin`
|
|
139
|
+
|
|
140
|
+
Bootstraps the first admin user, or rotates an existing admin's password.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
smpy users create-admin -e admin@example.com -p hunter2
|
|
144
|
+
smpy users create-admin -e admin@example.com -p new-password --force # rotate
|
|
145
|
+
smpy users create-admin -e admin@example.com -p hunter2 --full-name "Admin"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
| Flag | Meaning |
|
|
149
|
+
|---|---|
|
|
150
|
+
| `-e, --email` (required) | Admin email |
|
|
151
|
+
| `-p, --password` (required) | Initial password (or new password with `--force`) |
|
|
152
|
+
| `--full-name` | Display name |
|
|
153
|
+
| `--force` | Update the password if the admin already exists; without it, the command exits if the email is taken |
|
|
154
|
+
|
|
155
|
+
Don't bake `--password` literals into a script you commit; use a secrets store and pass via shell expansion.
|
|
156
|
+
|
|
157
|
+
## Pitfalls
|
|
158
|
+
|
|
159
|
+
- **Wrong shell for `--with`.** `smpy new` `--with auth,users` (catalog keys, lowercase). `smpy create-host` `--with Auth,Users` (`ModuleMeta.name`, PascalCase). They're not interchangeable.
|
|
160
|
+
- **Ran `smpy new` inside an existing project.** The default `--dest ./<name>` creates a sibling directory. If the directory already exists and is non-empty, the command errors out — pass `--dest` explicitly to disambiguate.
|
|
161
|
+
- **Ran `smpy host gen-pages` from outside the host directory.** Defaults to `./client_app`; pass `--host-dir` from elsewhere.
|
|
162
|
+
- **Forgot `smpy host sync-js-deps` after `pip install`-ing a module with pages.** Vite resolves module imports against `client_app/node_modules`; the new module's JS deps won't land until you sync.
|
|
163
|
+
- **Used `smpy create-module` to add a module to an existing host.** That command is for **publishable** packages, intended to live in their own repo. To add a module to an existing host: install it (`pip install simple_module_<name>` or add to `pyproject.toml` and `uv sync`), then autogenerate a migration. See **simple-module-creating** + **simple-module-migrations**.
|
|
164
|
+
- **Calling `smpy create-admin` before migrations have run.** The users tables don't exist yet; the command will error. Run `alembic upgrade head` first (or use `smpy new` which does it for you when `--no-install` isn't set).
|
|
165
|
+
|
|
166
|
+
## Related skills
|
|
167
|
+
|
|
168
|
+
- **simple-module-creating** — what `smpy create-module` produces and the post-scaffold contract
|
|
169
|
+
- **simple-module-inertia-pages** — what `smpy host gen-pages` regenerates and why
|
|
170
|
+
- **simple-module-migrations** — the `alembic upgrade head` step `smpy new` runs
|
|
@@ -12,13 +12,13 @@ description: Use when adding a new feature package to a simple_module_python app
|
|
|
12
12
|
```bash
|
|
13
13
|
# scaffold a publishable module package in ./orders (run in a fresh repo or
|
|
14
14
|
# inside a host's modules/ directory)
|
|
15
|
-
|
|
15
|
+
smpy create-module orders
|
|
16
16
|
|
|
17
17
|
# install the new package into the host environment
|
|
18
18
|
uv sync # or: pip install -e ./orders
|
|
19
19
|
|
|
20
20
|
# if you added a frontend page, regenerate the Inertia manifest
|
|
21
|
-
|
|
21
|
+
smpy host gen-pages --host-dir=client_app
|
|
22
22
|
|
|
23
23
|
# if you added SQLModel tables, autogenerate + apply a migration
|
|
24
24
|
uv run alembic revision --autogenerate -m "add orders module"
|
|
@@ -15,12 +15,12 @@ description: Use when adding or debugging an Inertia.js page in a simple_module_
|
|
|
15
15
|
| Module page (snake-case dir) | `inertia.render("BlogPosts/Index", ...)` | `<module_pkg>/blog_posts/pages/Index.tsx` |
|
|
16
16
|
| Host page | `inertia.render("Landing", ...)` | `<host>/client_app/pages/Landing.tsx` |
|
|
17
17
|
|
|
18
|
-
The namespace is **PascalCase of the module's directory name**, not the file system path. Directory `blog_posts` → `BlogPosts`. The framework's manifest generator (`
|
|
18
|
+
The namespace is **PascalCase of the module's directory name**, not the file system path. Directory `blog_posts` → `BlogPosts`. The framework's manifest generator (`smpy host gen-pages`) wires up Vite's `import.meta.glob` to resolve these keys at runtime.
|
|
19
19
|
|
|
20
20
|
After adding or renaming a `.tsx`, regenerate the manifest:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
|
|
23
|
+
smpy host gen-pages --host-dir=client_app
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
Boot regenerates it too; mid-session adds need the manual call before HMR sees them.
|
|
@@ -23,7 +23,7 @@ my_host/ # the host project
|
|
|
23
23
|
|
|
24
24
|
## How autogenerate sees every module
|
|
25
25
|
|
|
26
|
-
The host's `migrations/env.py` (scaffolded by `
|
|
26
|
+
The host's `migrations/env.py` (scaffolded by `smpy create-host`) calls:
|
|
27
27
|
|
|
28
28
|
```python
|
|
29
29
|
from simple_module_db import build_module_metadata, make_include_object
|
|
@@ -84,7 +84,7 @@ modules/orders/
|
|
|
84
84
|
└── test_service.py # imports orders.service
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
The directory must be listed in the root `pyproject.toml` under `[tool.pytest.ini_options].testpaths` for `make test` to pick it up. `
|
|
87
|
+
The directory must be listed in the root `pyproject.toml` under `[tool.pytest.ini_options].testpaths` for `make test` to pick it up. `smpy create-module` adds this entry; if you scaffolded a module by hand, add it.
|
|
88
88
|
|
|
89
89
|
## Pitfalls
|
|
90
90
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""``
|
|
1
|
+
"""``smpy skills`` — install or update agent skill packs in a target project.
|
|
2
2
|
|
|
3
3
|
Bundles the SKILL.md packs shipped under ``simple_module_cli/skills/`` and
|
|
4
4
|
materialises them into a project directory (default ``.claude/skills``) so any
|
|
@@ -7,9 +7,9 @@ can pick them up.
|
|
|
7
7
|
|
|
8
8
|
Three subcommands:
|
|
9
9
|
|
|
10
|
-
* ``
|
|
11
|
-
* ``
|
|
12
|
-
* ``
|
|
10
|
+
* ``smpy skills list`` — show every bundled skill and its description.
|
|
11
|
+
* ``smpy skills add`` — copy (or symlink) skills into the destination.
|
|
12
|
+
* ``smpy skills update`` — re-copy skills that are already installed at the
|
|
13
13
|
destination, overwriting them.
|
|
14
14
|
"""
|
|
15
15
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Inertia page resolver.
|
|
3
3
|
*
|
|
4
4
|
* Module pages are discovered via a generated file (modules.generated.ts)
|
|
5
|
-
* emitted by the Python host at boot, or manually via `
|
|
5
|
+
* emitted by the Python host at boot, or manually via `smpy gen-pages`. Each
|
|
6
6
|
* installed module contributes an import.meta.glob() call with an absolute
|
|
7
7
|
* path, so pages shipped inside pip-installed module wheels resolve.
|
|
8
8
|
*
|
{simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/main.py
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Host application entry point.
|
|
2
2
|
|
|
3
|
-
This file was generated by `
|
|
3
|
+
This file was generated by `smpy create-host`. Modules are discovered at boot
|
|
4
4
|
via entry_points; add them to this host's pyproject.toml to install them.
|
|
5
5
|
"""
|
|
6
6
|
|
|
@@ -40,7 +40,7 @@ def built_artifacts(tmp_path_factory) -> tuple[Path, Path]:
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
def test_wheel_contains_bundled_skills(built_artifacts: tuple[Path, Path]) -> None:
|
|
43
|
-
"""The wheel must ship the agent skill packs that ``
|
|
43
|
+
"""The wheel must ship the agent skill packs that ``smpy skills`` depends on.
|
|
44
44
|
|
|
45
45
|
Regression: ``[tool.hatch.build.targets.wheel.force-include]`` with
|
|
46
46
|
``../../skills`` made the wheel re-build from sdist crash with
|
|
@@ -61,7 +61,7 @@ def test_wheel_contains_bundled_skills(built_artifacts: tuple[Path, Path]) -> No
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
def test_wheel_contains_templates(built_artifacts: tuple[Path, Path]) -> None:
|
|
64
|
-
"""``
|
|
64
|
+
"""``smpy new`` reads from ``simple_module_cli/templates`` — must ship in the wheel."""
|
|
65
65
|
_, wheel = built_artifacts
|
|
66
66
|
with zipfile.ZipFile(wheel) as zf:
|
|
67
67
|
names = zf.namelist()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Regression tests for ``
|
|
1
|
+
"""Regression tests for ``smpy new`` scaffold bugs filed against released wheels.
|
|
2
2
|
|
|
3
3
|
Each test pins a specific issue's repro so the bug can't sneak back in
|
|
4
4
|
without a CI failure pointing at the fix.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Tests for the module-pages manifest and `
|
|
1
|
+
"""Tests for the module-pages manifest and `smpy create-host` scaffolding."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -154,7 +154,7 @@ class TestCreateHost:
|
|
|
154
154
|
assert "for mod in modules:" not in env_py
|
|
155
155
|
|
|
156
156
|
async def test_cli_create_host_runs_end_to_end(self, tmp_path):
|
|
157
|
-
"""The Click `
|
|
157
|
+
"""The Click `smpy create-host` command produces a working scaffold."""
|
|
158
158
|
from simple_module_cli.cli import app
|
|
159
159
|
from typer.testing import CliRunner
|
|
160
160
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Tests for `
|
|
1
|
+
"""Tests for `smpy create-module` scaffolding: module package, CI, static bundling."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -74,7 +74,7 @@ class TestCreateModule:
|
|
|
74
74
|
create_module(dest, name="MyFeature")
|
|
75
75
|
|
|
76
76
|
async def test_cli_create_module_runs_end_to_end(self, tmp_path):
|
|
77
|
-
"""The Click `
|
|
77
|
+
"""The Click `smpy create-module` command produces a working scaffold."""
|
|
78
78
|
from simple_module_cli.cli import app
|
|
79
79
|
from typer.testing import CliRunner
|
|
80
80
|
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: simple-module-cli
|
|
3
|
-
description: Use when invoking the `sm` CLI for a simple_module_python project — starting a new app, scaffolding a host or a publishable module, regenerating the Inertia page manifest, importing settings overrides from env, creating an admin user, or installing the bundled agent skills. Triggers on "sm new", "sm create-host", "sm create-module", "sm host gen-pages", "sm users create-admin", "sm skills add", or any unfamiliar `sm` subcommand.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# simple_module_python: the `sm` CLI
|
|
7
|
-
|
|
8
|
-
The `sm` command is provided by `simple_module_cli` (installed as a dep of `simple_module_hosting`). It groups four kinds of operations: scaffolding new things, project-time helpers for the host, admin shortcuts for the bundled modules, and installing the bundled agent skills.
|
|
9
|
-
|
|
10
|
-
## Top-level commands
|
|
11
|
-
|
|
12
|
-
| Command | When to use |
|
|
13
|
-
|---|---|
|
|
14
|
-
| `sm new <name>` | Greenfield: scaffold a complete app (host + selected modules) in one shot, with an interactive wizard for DB / tenancy / module preset |
|
|
15
|
-
| `sm create-host <name>` | You want just a bare host project; you'll add modules later by `pip install`-ing them |
|
|
16
|
-
| `sm create-module <name>` | You're authoring a publishable module package (separate repo, distributed via PyPI) |
|
|
17
|
-
| `sm skills …` | Install / update the bundled agent-skill packs into a project (`add`, `list`, `update`) |
|
|
18
|
-
| `sm host …` | Project-time helpers run from inside a host directory (page manifest, JS dep sync) |
|
|
19
|
-
| `sm settings …` | Settings-module admin — currently `import-from-env` |
|
|
20
|
-
| `sm users …` | Users-module admin — currently `create-admin` |
|
|
21
|
-
|
|
22
|
-
## `sm new <name>` — the wizard
|
|
23
|
-
|
|
24
|
-
The fastest way from zero to a working app. It calls `create-host` under the hood, then installs and wires up the modules you pick.
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
# Interactive (asks for DB, tenancy, preset, module list)
|
|
28
|
-
sm new MyApp
|
|
29
|
-
|
|
30
|
-
# Non-interactive: take all defaults (sqlite, no tenancy, standard preset)
|
|
31
|
-
sm new MyApp --yes
|
|
32
|
-
|
|
33
|
-
# Pick a preset and add extras
|
|
34
|
-
sm new MyApp --preset full --tenancy --db postgres
|
|
35
|
-
sm new MyApp --preset minimal --with background_tasks,file_storage --yes
|
|
36
|
-
|
|
37
|
-
# Scaffold only — skip uv sync / npm install / alembic upgrade head
|
|
38
|
-
sm new MyApp --no-install
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
**Module presets:**
|
|
42
|
-
|
|
43
|
-
| Preset | Modules included |
|
|
44
|
-
|---|---|
|
|
45
|
-
| `minimal` | `users` (and `auth` as a dep) |
|
|
46
|
-
| `standard` (default) | `users`, `dashboard`, `permissions` (+ deps) |
|
|
47
|
-
| `full` | every module in the catalog |
|
|
48
|
-
| `custom` | interactive — pick each module yes/no |
|
|
49
|
-
|
|
50
|
-
`--with` accepts a comma-separated list of catalog keys (`auth, users, permissions, products, dashboard, settings, feature_flags, file_storage, background_tasks, …`). Transitive `requires` are auto-added; the wizard prints `Added X (required by Y)` so you can see what got pulled in.
|
|
51
|
-
|
|
52
|
-
**Options summary:**
|
|
53
|
-
|
|
54
|
-
| Flag | Default | Meaning |
|
|
55
|
-
|---|---|---|
|
|
56
|
-
| `--dest <PATH>` | `./<name>` | Where to write the project |
|
|
57
|
-
| `--db sqlite\|postgres` | `sqlite` | Backend configured in `.env.example` |
|
|
58
|
-
| `--tenancy / --no-tenancy` | `--no-tenancy` | Enable the multi-tenant middleware |
|
|
59
|
-
| `--preset minimal\|standard\|full` | wizard asks | Module bundle |
|
|
60
|
-
| `--with <names>` | none | Extra catalog keys beyond the preset |
|
|
61
|
-
| `--yes / -y` | off | Skip prompts; accept defaults |
|
|
62
|
-
| `--no-install` | off | Skip `uv sync` / `npm install` / `alembic upgrade head` |
|
|
63
|
-
|
|
64
|
-
## `sm create-host <name>` — bare host
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
sm create-host MyApp # empty host, no modules declared
|
|
68
|
-
sm create-host MyApp --with Auth,Products # declare module deps in pyproject.toml
|
|
69
|
-
sm create-host MyApp --dest ./apps/myapp # custom destination
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
`--with` takes **PascalCase module names** (matching `ModuleMeta.name`), not catalog keys. Use this when you want to drive the build yourself rather than via `sm new`'s wizard.
|
|
73
|
-
|
|
74
|
-
## `sm create-module <name>` — module package
|
|
75
|
-
|
|
76
|
-
For module authors publishing to PyPI. Scaffolds a standalone repo containing one module.
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
sm create-module orders # writes ./simple_module_orders/
|
|
80
|
-
sm create-module orders --dest ./packages/orders
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
The result is a complete package: `pyproject.toml` with the entry point declared, `module.py` with `ModuleBase`/`ModuleMeta` skeleton, `models.py`, `contracts/`, `endpoints/{api,views}.py`, `pages/`, `locales/en.json`, plus a tests directory wired up with `simple_module_test` fixtures.
|
|
84
|
-
|
|
85
|
-
`<name>` accepts any case — `orders`, `Orders`, `ORDERS`, `blog_posts` all work. The CLI lowercases it for the directory and PascalCases it for `ModuleMeta.name`.
|
|
86
|
-
|
|
87
|
-
For the post-scaffold steps (entry point, Inertia namespace, etc.) see **simple-module-creating**.
|
|
88
|
-
|
|
89
|
-
## `sm skills` — install the bundled agent skills
|
|
90
|
-
|
|
91
|
-
`simple_module_cli` ships a set of [SKILL.md](https://agentskills.io/specification) packs (the ones in this directory). Drop them into any project so Claude Code / Cursor / Codex / etc. find them automatically.
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
sm skills list # see what's available
|
|
95
|
-
sm skills add # install ALL skills into ./.claude/skills/
|
|
96
|
-
sm skills add simple-module-creating simple-module-cli # specific ones only
|
|
97
|
-
sm skills add -g # ~/.claude/skills (machine-wide)
|
|
98
|
-
sm skills add --dest agents/skills # explicit target dir
|
|
99
|
-
sm skills add --symlink # symlink to bundled source (good when iterating on the skills themselves)
|
|
100
|
-
sm skills update # re-pull whatever is already installed at the dest
|
|
101
|
-
sm skills update simple-module-doctor # explicitly re-pull one (always force-overwrites)
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
**Without `--force`, `sm skills add` skips skills that already exist at the destination** — so re-running it is safe. Use `--force` (or `sm skills update`) to overwrite.
|
|
105
|
-
|
|
106
|
-
The bundle resolves against your installed `simple_module_cli`. To get newer skills, upgrade the CLI (`uv sync` or `pip install -U simple_module_cli`) and re-run `sm skills update`.
|
|
107
|
-
|
|
108
|
-
## `sm host gen-pages` — regenerate the Inertia manifest
|
|
109
|
-
|
|
110
|
-
Run from a host project. Scans every installed module's `pages/*.tsx`, writes `client_app/modules.{manifest.json,generated.ts,generated.css}`, and extends Vite's `server.fs.allow`.
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
sm host gen-pages # uses ./client_app
|
|
114
|
-
sm host gen-pages --host-dir=apps/web/client_app
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
`sm new` runs this at scaffold time; you only need to call it manually after adding/renaming `.tsx` files mid-session, or after `pip install`-ing a new module that ships pages.
|
|
118
|
-
|
|
119
|
-
## `sm host sync-js-deps` — install module JS deps
|
|
120
|
-
|
|
121
|
-
Wheel-installed modules ship `package.json` declarations that need to land in the host's `client_app/node_modules`. This command does that. **In-repo workspace modules don't need it** — npm workspaces resolve them automatically.
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
sm host sync-js-deps # uses ./client_app
|
|
125
|
-
sm host sync-js-deps --host-client-app=apps/web/client_app
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
Run after `pip install <module>` if the new module ships frontend code.
|
|
129
|
-
|
|
130
|
-
## `sm settings import-from-env`
|
|
131
|
-
|
|
132
|
-
Walks the live environment for every `SM_<PREFIX>_<FIELD>` variable matching a registered settings dataclass and writes a SYSTEM-tier override into the settings module's store. Useful when promoting from environment-driven config (typical in Docker) to in-DB overrides (manageable in the admin UI) without re-keying values by hand.
|
|
133
|
-
|
|
134
|
-
```bash
|
|
135
|
-
sm settings import-from-env
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## `sm users create-admin`
|
|
139
|
-
|
|
140
|
-
Bootstraps the first admin user, or rotates an existing admin's password.
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
sm users create-admin -e admin@example.com -p hunter2
|
|
144
|
-
sm users create-admin -e admin@example.com -p new-password --force # rotate
|
|
145
|
-
sm users create-admin -e admin@example.com -p hunter2 --full-name "Admin"
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
| Flag | Meaning |
|
|
149
|
-
|---|---|
|
|
150
|
-
| `-e, --email` (required) | Admin email |
|
|
151
|
-
| `-p, --password` (required) | Initial password (or new password with `--force`) |
|
|
152
|
-
| `--full-name` | Display name |
|
|
153
|
-
| `--force` | Update the password if the admin already exists; without it, the command exits if the email is taken |
|
|
154
|
-
|
|
155
|
-
Don't bake `--password` literals into a script you commit; use a secrets store and pass via shell expansion.
|
|
156
|
-
|
|
157
|
-
## Pitfalls
|
|
158
|
-
|
|
159
|
-
- **Wrong shell for `--with`.** `sm new` `--with auth,users` (catalog keys, lowercase). `sm create-host` `--with Auth,Users` (`ModuleMeta.name`, PascalCase). They're not interchangeable.
|
|
160
|
-
- **Ran `sm new` inside an existing project.** The default `--dest ./<name>` creates a sibling directory. If the directory already exists and is non-empty, the command errors out — pass `--dest` explicitly to disambiguate.
|
|
161
|
-
- **Ran `sm host gen-pages` from outside the host directory.** Defaults to `./client_app`; pass `--host-dir` from elsewhere.
|
|
162
|
-
- **Forgot `sm host sync-js-deps` after `pip install`-ing a module with pages.** Vite resolves module imports against `client_app/node_modules`; the new module's JS deps won't land until you sync.
|
|
163
|
-
- **Used `sm create-module` to add a module to an existing host.** That command is for **publishable** packages, intended to live in their own repo. To add a module to an existing host: install it (`pip install simple_module_<name>` or add to `pyproject.toml` and `uv sync`), then autogenerate a migration. See **simple-module-creating** + **simple-module-migrations**.
|
|
164
|
-
- **Calling `sm create-admin` before migrations have run.** The users tables don't exist yet; the command will error. Run `alembic upgrade head` first (or use `sm new` which does it for you when `--no-install` isn't set).
|
|
165
|
-
|
|
166
|
-
## Related skills
|
|
167
|
-
|
|
168
|
-
- **simple-module-creating** — what `sm create-module` produces and the post-scaffold contract
|
|
169
|
-
- **simple-module-inertia-pages** — what `sm host gen-pages` regenerates and why
|
|
170
|
-
- **simple-module-migrations** — the `alembic upgrade head` step `sm new` runs
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/.env.example
RENAMED
|
File without changes
|
{simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/.gitignore
RENAMED
|
File without changes
|
{simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/Makefile
RENAMED
|
File without changes
|
{simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/README.md.tpl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/host/alembic.ini
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/module/.gitignore
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_cli-0.0.11 → simple_module_cli-0.0.12}/simple_module_cli/templates/workspace/Makefile
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|