alms-cli 0.1.4__tar.gz → 0.1.6__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.
- {alms_cli-0.1.4 → alms_cli-0.1.6}/.gitignore +41 -35
- {alms_cli-0.1.4 → alms_cli-0.1.6}/PKG-INFO +2 -1
- alms_cli-0.1.6/pyproject.toml +63 -0
- {alms_cli-0.1.4 → alms_cli-0.1.6}/src/alms_cli/__init__.py +1 -1
- {alms_cli-0.1.4 → alms_cli-0.1.6}/src/alms_cli/commands/info.py +17 -10
- {alms_cli-0.1.4 → alms_cli-0.1.6}/src/alms_cli/commands/init.py +87 -50
- alms_cli-0.1.6/src/alms_cli/templates/__init__.py +32 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/.env.example.j2 +51 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/.github/ISSUE_TEMPLATE/bug_report.yml.j2 +8 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/.github/ISSUE_TEMPLATE/feature_request.yml.j2 +8 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/.github/dependabot.yml.j2 +6 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/.github/pull_request_template.md.j2 +9 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/.github/workflows/ci.yml.j2 +17 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/.gitignore.j2 +36 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/Dockerfile.j2 +14 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/README.md.j2 +31 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/alembic/README.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/alembic/env.py.j2 +33 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/alembic/script.py.mako.j2 +20 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/alembic.ini.j2 +36 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/docker-compose.yml.j2 +24 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/docs/01-System-Design.md.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/docs/02-Design-Patterns.md.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/docs/03-Database-Design.md.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/docs/04-Tech-Stack.md.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/docs/05-Project-Structure.md.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/docs/06-API-Documentation.md.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/docs/07-Setup-Installation.md.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/docs/08-Contribution-Guide.md.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/pyproject.toml.j2 +29 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/pytest.ini.j2 +6 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/rules/project_rules.md.j2 +9 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/agents/agent_manager/agent.py.j2 +22 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/agents/prompts/sample_agent_prompt.py.j2 +7 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/endpoints/v1/dependencies.py.j2 +46 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/endpoints/v1/health.py.j2 +46 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/endpoints/v1/metrics.py.j2 +13 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/endpoints/v1/routers.py.j2 +14 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/endpoints/v1/sample_agent.py.j2 +15 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/endpoints/v1/sample_di.py.j2 +13 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/endpoints/v1/schemas/base.py.j2 +19 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/endpoints/v1/schemas/sample.py.j2 +12 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/main.py.j2 +79 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/middlewares/error_handler.py.j2 +49 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/middlewares/logging.py.j2 +56 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/middlewares/observability.py.j2 +46 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/middlewares/security.py.j2 +59 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/api/router/routers.py.j2 +7 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/config/logs_config.py.j2 +16 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/config/settings.py.j2 +56 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/core/exceptions.py.j2 +34 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/database/connection.py.j2 +30 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/database/repositories/base.py.j2 +28 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/database/repositories/sqlalchemy_repository.py.j2 +8 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/execution/actions/sample_action.py.j2 +17 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/execution/usecases/sample_usecase.py.j2 +16 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/observability/__init__.py.j2 +6 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/observability/metrics.py.j2 +26 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/observability/tracing.py.j2 +15 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/providers/ai/base.py.j2 +13 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/providers/ai/factory.py.j2 +10 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/providers/ai/langchain_model_loader.py.j2 +27 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/README.md.j2 +1 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/conftest.py.j2 +27 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/e2e/test_workflows.py.j2 +9 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/integration/test_full_stack.py.j2 +10 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/v1/test_agent.py.j2 +10 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/v1/test_health.py.j2 +12 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/v1/test_metrics.py.j2 +9 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/v1/test_metrics_endpoint.py.j2 +10 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/v1/test_observability_middleware.py.j2 +10 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/v1/test_sqlalchemy_repository.py.j2 +9 -0
- alms_cli-0.1.6/src/alms_cli/templates/files/src/tests/v1/test_tracing.py.j2 +9 -0
- alms_cli-0.1.6/src/alms_cli/templates/generator.py +320 -0
- alms_cli-0.1.6/src/alms_cli/templates/profiles.py +122 -0
- alms_cli-0.1.6/src/alms_cli/templates/template_renderer.py +59 -0
- {alms_cli-0.1.4 → alms_cli-0.1.6}/src/alms_cli/ui/components.py +18 -12
- alms_cli-0.1.4/pyproject.toml +0 -48
- alms_cli-0.1.4/src/alms_cli/templates/__init__.py +0 -1282
- {alms_cli-0.1.4 → alms_cli-0.1.6}/LICENSE +0 -0
- {alms_cli-0.1.4 → alms_cli-0.1.6}/README.md +0 -0
- {alms_cli-0.1.4 → alms_cli-0.1.6}/src/alms_cli/__main__.py +0 -0
- {alms_cli-0.1.4 → alms_cli-0.1.6}/src/alms_cli/commands/__init__.py +0 -0
- {alms_cli-0.1.4 → alms_cli-0.1.6}/src/alms_cli/main.py +0 -0
- {alms_cli-0.1.4 → alms_cli-0.1.6}/src/alms_cli/ui/__init__.py +0 -0
|
@@ -1,35 +1,41 @@
|
|
|
1
|
-
# Python-generated files
|
|
2
|
-
__pycache__/
|
|
3
|
-
*.py[oc]
|
|
4
|
-
build/
|
|
5
|
-
dist/
|
|
6
|
-
wheels/
|
|
7
|
-
*.egg-info
|
|
8
|
-
|
|
9
|
-
# Virtual environments
|
|
10
|
-
.venv/
|
|
11
|
-
env/
|
|
12
|
-
venv/
|
|
13
|
-
ENV/
|
|
14
|
-
|
|
15
|
-
# Configuration
|
|
16
|
-
.env
|
|
17
|
-
.python-version
|
|
18
|
-
|
|
19
|
-
# Logs
|
|
20
|
-
logs/
|
|
21
|
-
*.log
|
|
22
|
-
src/logs/
|
|
23
|
-
|
|
24
|
-
# Pytest
|
|
25
|
-
.pytest_cache/
|
|
26
|
-
.coverage
|
|
27
|
-
htmlcov/
|
|
28
|
-
|
|
29
|
-
# IDEs
|
|
30
|
-
.vscode/
|
|
31
|
-
.idea/
|
|
32
|
-
.trae/
|
|
33
|
-
|
|
34
|
-
# Docker
|
|
35
|
-
.docker/
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv/
|
|
11
|
+
env/
|
|
12
|
+
venv/
|
|
13
|
+
ENV/
|
|
14
|
+
|
|
15
|
+
# Configuration
|
|
16
|
+
.env
|
|
17
|
+
.python-version
|
|
18
|
+
|
|
19
|
+
# Logs
|
|
20
|
+
logs/
|
|
21
|
+
*.log
|
|
22
|
+
src/logs/
|
|
23
|
+
|
|
24
|
+
# Pytest
|
|
25
|
+
.pytest_cache/
|
|
26
|
+
.coverage
|
|
27
|
+
htmlcov/
|
|
28
|
+
|
|
29
|
+
# IDEs
|
|
30
|
+
.vscode/
|
|
31
|
+
.idea/
|
|
32
|
+
.trae/
|
|
33
|
+
|
|
34
|
+
# Docker
|
|
35
|
+
.docker/
|
|
36
|
+
# Internal phase reports (not for release)
|
|
37
|
+
PHASE_*_REPORT.md
|
|
38
|
+
RC_GATE_REPORT.md
|
|
39
|
+
|
|
40
|
+
# Test cache
|
|
41
|
+
.pytest_cache/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alms-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: ALMS CLI - Beautiful project scaffolding tool for AI-first backends
|
|
5
5
|
Project-URL: Homepage, https://github.com/KJ-AIML/alms
|
|
6
6
|
Project-URL: Repository, https://github.com/KJ-AIML/alms
|
|
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
18
18
|
Classifier: Topic :: Software Development :: Code Generators
|
|
19
19
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
20
20
|
Requires-Python: >=3.13
|
|
21
|
+
Requires-Dist: jinja2>=3.1.0
|
|
21
22
|
Requires-Dist: questionary>=2.0.0
|
|
22
23
|
Requires-Dist: rich>=13.7.0
|
|
23
24
|
Requires-Dist: typer>=0.12.0
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "alms-cli"
|
|
3
|
+
version = "0.1.6"
|
|
4
|
+
description = "ALMS CLI - Beautiful project scaffolding tool for AI-first backends"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.13"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [{ name = "Your Name", email = "your.email@example.com" }]
|
|
9
|
+
keywords = [
|
|
10
|
+
"cli",
|
|
11
|
+
"scaffolding",
|
|
12
|
+
"fastapi",
|
|
13
|
+
"ai",
|
|
14
|
+
"backend",
|
|
15
|
+
"starter-kit",
|
|
16
|
+
"alms",
|
|
17
|
+
]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 3 - Alpha",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Topic :: Software Development :: Code Generators",
|
|
25
|
+
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"typer>=0.12.0",
|
|
29
|
+
"rich>=13.7.0",
|
|
30
|
+
"questionary>=2.0.0",
|
|
31
|
+
"jinja2>=3.1.0",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Homepage = "https://github.com/KJ-AIML/alms"
|
|
36
|
+
Repository = "https://github.com/KJ-AIML/alms"
|
|
37
|
+
Documentation = "https://github.com/KJ-AIML/alms#readme"
|
|
38
|
+
"Bug Tracker" = "https://github.com/KJ-AIML/alms/issues"
|
|
39
|
+
|
|
40
|
+
[project.scripts]
|
|
41
|
+
alms = "alms_cli.main:app"
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["hatchling"]
|
|
45
|
+
build-backend = "hatchling.build"
|
|
46
|
+
|
|
47
|
+
[tool.hatch.build.targets.wheel]
|
|
48
|
+
packages = ["src/alms_cli"]
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build.targets.sdist]
|
|
51
|
+
include = ["/src", "/README.md", "/LICENSE"]
|
|
52
|
+
|
|
53
|
+
[dependency-groups]
|
|
54
|
+
dev = [
|
|
55
|
+
"pytest>=9.0.2",
|
|
56
|
+
"fastapi[standard]>=0.122.0",
|
|
57
|
+
"pydantic>=2.12.5",
|
|
58
|
+
"pydantic-settings>=2.12.0",
|
|
59
|
+
"uvicorn>=0.38.0",
|
|
60
|
+
"prometheus-client>=0.23.1",
|
|
61
|
+
"sqlalchemy>=2.0.0",
|
|
62
|
+
"asyncpg>=0.29.0",
|
|
63
|
+
]
|
|
@@ -23,9 +23,9 @@ console = Console()
|
|
|
23
23
|
@info_app.command()
|
|
24
24
|
def project():
|
|
25
25
|
"""Show information about the current ALMS project."""
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
project_root = Path.cwd()
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
pyproject = project_root / "pyproject.toml"
|
|
30
30
|
if not pyproject.exists():
|
|
31
31
|
print_error("Not an ALMS project (pyproject.toml not found)")
|
|
@@ -33,7 +33,7 @@ def project():
|
|
|
33
33
|
print_info("Run 'alms init <name>' to create a new project")
|
|
34
34
|
console.print()
|
|
35
35
|
raise typer.Exit(1)
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
console.print()
|
|
38
38
|
console.print(
|
|
39
39
|
Panel(
|
|
@@ -44,30 +44,37 @@ def project():
|
|
|
44
44
|
)
|
|
45
45
|
)
|
|
46
46
|
console.print()
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
table = Table(
|
|
49
49
|
box=box.ROUNDED,
|
|
50
50
|
border_style="blue",
|
|
51
51
|
title="[bold]Project Details[/bold]",
|
|
52
52
|
)
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
table.add_column("Property", style="bold blue")
|
|
55
55
|
table.add_column("Value", style="white")
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
table.add_row("Name", project_root.name)
|
|
58
58
|
table.add_row("Location", str(project_root))
|
|
59
59
|
table.add_row("Has pyproject.toml", "Yes")
|
|
60
60
|
table.add_row("Has src/", str((project_root / "src").exists()))
|
|
61
61
|
table.add_row("Has tests/", str((project_root / "src" / "tests").exists()))
|
|
62
62
|
table.add_row("Has alembic/", str((project_root / "alembic").exists()))
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
console.print(table)
|
|
65
65
|
console.print()
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
console.print("[bold]Project Structure:[/bold]")
|
|
68
68
|
console.print()
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
if (project_root / "src").exists():
|
|
71
71
|
print_tree(project_root / "src")
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
console.print()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@info_app.callback(invoke_without_command=True)
|
|
77
|
+
def info(ctx: typer.Context):
|
|
78
|
+
"""Show information about the current ALMS project."""
|
|
79
|
+
if ctx.invoked_subcommand is None:
|
|
80
|
+
project()
|
|
@@ -18,35 +18,47 @@ from alms_cli.ui.components import (
|
|
|
18
18
|
create_progress,
|
|
19
19
|
print_project_summary,
|
|
20
20
|
)
|
|
21
|
-
from alms_cli.templates import
|
|
21
|
+
from alms_cli.templates import (
|
|
22
|
+
TemplateGenerator,
|
|
23
|
+
PROFILE_CAPABILITIES,
|
|
24
|
+
resolve_capabilities,
|
|
25
|
+
)
|
|
22
26
|
|
|
23
27
|
console = Console()
|
|
24
28
|
|
|
25
29
|
custom_style = Style([
|
|
26
30
|
("qmark", "fg:#FFFFFF"),
|
|
27
|
-
("question", "fg:#FFFFFF"),
|
|
31
|
+
("question", "fg:#FFFFFF nobold"),
|
|
28
32
|
("answer", "fg:#FFFFFF"),
|
|
29
|
-
("pointer", "fg:#
|
|
30
|
-
("highlighted", "fg:#FFFFFF"),
|
|
31
|
-
("selected", "fg:#FFFFFF"),
|
|
33
|
+
("pointer", "fg:#22C55E nobold"),
|
|
34
|
+
("highlighted", "fg:#FFFFFF nobold"),
|
|
35
|
+
("selected", "fg:#FFFFFF nobold"),
|
|
32
36
|
("separator", "fg:#666666"),
|
|
33
37
|
("instruction", "fg:#888888"),
|
|
34
|
-
("text", "fg:#FFFFFF"),
|
|
38
|
+
("text", "fg:#FFFFFF nobold"),
|
|
35
39
|
("disabled", "fg:#666666 italic"),
|
|
36
|
-
("checkbox", "fg:#
|
|
37
|
-
("checkbox.selected", "fg:#
|
|
40
|
+
("checkbox", "fg:#666666 nobold"),
|
|
41
|
+
("checkbox.selected", "fg:#22C55E nobold"),
|
|
38
42
|
])
|
|
39
43
|
|
|
44
|
+
VALID_PROFILES = list(PROFILE_CAPABILITIES.keys())
|
|
45
|
+
|
|
40
46
|
|
|
41
47
|
def init_command(
|
|
42
48
|
name: str = typer.Argument(None, help="Project name"),
|
|
43
49
|
path: str = typer.Option(None, "--path", "-p", help="Path to create project"),
|
|
44
|
-
|
|
50
|
+
profile: str = typer.Option(
|
|
51
|
+
"core-api",
|
|
52
|
+
"--profile",
|
|
53
|
+
help=f"Project profile: {', '.join(VALID_PROFILES)}",
|
|
54
|
+
),
|
|
55
|
+
interactive: bool = typer.Option(
|
|
56
|
+
True, "--interactive/--no-interactive", "-i", help="Interactive mode"
|
|
57
|
+
),
|
|
45
58
|
):
|
|
46
59
|
"""Create a new ALMS project with beautiful scaffolding."""
|
|
47
|
-
|
|
48
60
|
print_header("ALMS Project Generator", "AI-First Backend Starter Kit")
|
|
49
|
-
|
|
61
|
+
|
|
50
62
|
if not name:
|
|
51
63
|
if interactive:
|
|
52
64
|
name = questionary.text(
|
|
@@ -55,16 +67,16 @@ def init_command(
|
|
|
55
67
|
style=custom_style,
|
|
56
68
|
validate=lambda x: len(x) > 0 and x.replace("-", "").replace("_", "").isalnum(),
|
|
57
69
|
).ask()
|
|
58
|
-
|
|
70
|
+
|
|
59
71
|
if not name:
|
|
60
72
|
print_error("Project name is required")
|
|
61
73
|
raise typer.Exit(1)
|
|
62
74
|
else:
|
|
63
75
|
print_error("Project name is required")
|
|
64
76
|
raise typer.Exit(1)
|
|
65
|
-
|
|
77
|
+
|
|
66
78
|
project_path = Path(path) / name if path else Path(name)
|
|
67
|
-
|
|
79
|
+
|
|
68
80
|
if project_path.exists():
|
|
69
81
|
if interactive:
|
|
70
82
|
overwrite = questionary.confirm(
|
|
@@ -72,71 +84,96 @@ def init_command(
|
|
|
72
84
|
default=False,
|
|
73
85
|
style=custom_style,
|
|
74
86
|
).ask()
|
|
75
|
-
|
|
87
|
+
|
|
76
88
|
if not overwrite:
|
|
77
89
|
print_warning("Project creation cancelled")
|
|
78
90
|
raise typer.Exit(0)
|
|
79
91
|
else:
|
|
80
92
|
print_error(f"Directory '{name}' already exists")
|
|
81
93
|
raise typer.Exit(1)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
94
|
+
|
|
95
|
+
# Resolve profile
|
|
96
|
+
if profile not in PROFILE_CAPABILITIES:
|
|
97
|
+
print_error(f"Unknown profile: {profile}. Valid: {', '.join(VALID_PROFILES)}")
|
|
98
|
+
raise typer.Exit(1)
|
|
99
|
+
|
|
100
|
+
capabilities = resolve_capabilities(profile=profile)
|
|
101
|
+
|
|
102
|
+
# Interactive feature selection (only when no profile or "core-api" selected)
|
|
103
|
+
features: list[str] = []
|
|
104
|
+
if interactive and profile == "core-api":
|
|
105
|
+
feature_choices = [
|
|
106
|
+
("Database (PostgreSQL)", False),
|
|
107
|
+
("Redis Cache", False),
|
|
108
|
+
("AI Agents (LangChain)", False),
|
|
109
|
+
("Observability (OpenTelemetry)", False),
|
|
110
|
+
("Docker Support", False),
|
|
111
|
+
("CI/CD (GitHub Actions)", False),
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
selected = questionary.checkbox(
|
|
115
|
+
"Add capabilities to core-api:",
|
|
91
116
|
choices=[
|
|
92
|
-
questionary.Choice(
|
|
93
|
-
|
|
94
|
-
questionary.Choice("AI Agents (LangChain)", checked=True),
|
|
95
|
-
questionary.Choice("Observability (OpenTelemetry)", checked=True),
|
|
96
|
-
questionary.Choice("Docker Support", checked=True),
|
|
97
|
-
questionary.Choice("CI/CD (GitHub Actions)", checked=True),
|
|
117
|
+
questionary.Choice(title=fn, checked=de)
|
|
118
|
+
for fn, de in feature_choices
|
|
98
119
|
],
|
|
99
120
|
style=custom_style,
|
|
121
|
+
instruction="(Use arrow keys to move, <space> to select)",
|
|
100
122
|
).ask()
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
123
|
+
|
|
124
|
+
if selected:
|
|
125
|
+
features = selected
|
|
126
|
+
# Merge feature selections into capabilities
|
|
127
|
+
capabilities = resolve_capabilities(profile="core-api", features=features)
|
|
128
|
+
|
|
129
|
+
display_profile = profile if not features else f"{profile}+custom"
|
|
130
|
+
|
|
104
131
|
console.print()
|
|
105
132
|
print_step(1, 4, f"Creating project structure in {project_path}")
|
|
106
|
-
|
|
133
|
+
print_info(f"Profile: {display_profile}")
|
|
134
|
+
|
|
107
135
|
with create_progress() as progress:
|
|
108
136
|
task = progress.add_task("Generating files...", total=100)
|
|
109
|
-
|
|
137
|
+
|
|
110
138
|
generator = TemplateGenerator(name, project_path)
|
|
111
|
-
files_created = generator.generate(
|
|
112
|
-
|
|
139
|
+
files_created = generator.generate(capabilities)
|
|
140
|
+
|
|
113
141
|
progress.update(task, completed=100)
|
|
114
|
-
|
|
142
|
+
|
|
115
143
|
print_success(f"Created {files_created} files")
|
|
116
144
|
console.print()
|
|
117
|
-
|
|
145
|
+
|
|
118
146
|
print_step(2, 4, "Setting up configuration")
|
|
119
147
|
print_success("Environment template created (.env.example)")
|
|
120
148
|
print_success("Git ignore created (.gitignore)")
|
|
121
|
-
|
|
149
|
+
if "docker" in capabilities:
|
|
150
|
+
print_success("Docker configuration created")
|
|
122
151
|
console.print()
|
|
123
|
-
|
|
152
|
+
|
|
124
153
|
print_step(3, 4, "Initializing project structure")
|
|
125
154
|
print_success("API layer created")
|
|
126
155
|
print_success("Execution layer created")
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
156
|
+
if "llm" in capabilities:
|
|
157
|
+
print_success("Agent layer created")
|
|
158
|
+
if "database" in capabilities:
|
|
159
|
+
print_success("Database layer created")
|
|
160
|
+
if "observability" in capabilities:
|
|
161
|
+
print_success("Observability layer created")
|
|
130
162
|
console.print()
|
|
131
|
-
|
|
163
|
+
|
|
132
164
|
print_step(4, 4, "Finalizing setup")
|
|
133
165
|
print_success("Tests scaffolded")
|
|
134
166
|
print_success("Documentation created")
|
|
135
|
-
|
|
167
|
+
if "ci" in capabilities:
|
|
168
|
+
print_success("GitHub workflows configured")
|
|
136
169
|
console.print()
|
|
137
|
-
|
|
138
|
-
print_project_summary(
|
|
139
|
-
|
|
170
|
+
|
|
171
|
+
print_project_summary(
|
|
172
|
+
project_path,
|
|
173
|
+
files_created,
|
|
174
|
+
sorted(capabilities),
|
|
175
|
+
)
|
|
176
|
+
|
|
140
177
|
console.print(
|
|
141
178
|
Panel(
|
|
142
179
|
"[bold green]Your ALMS project is ready![/bold green]\n\n"
|
|
@@ -145,4 +182,4 @@ def init_command(
|
|
|
145
182
|
border_style="green",
|
|
146
183
|
)
|
|
147
184
|
)
|
|
148
|
-
console.print()
|
|
185
|
+
console.print()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Project template generator -- capability-aware edition."""
|
|
2
|
+
|
|
3
|
+
from .profiles import (
|
|
4
|
+
ALL_CAPABILITIES,
|
|
5
|
+
CAPABILITY_TO_EXTRA,
|
|
6
|
+
FEATURE_LABEL_TO_CAPABILITY,
|
|
7
|
+
NO_EXTRA_CAPABILITIES,
|
|
8
|
+
PROFILE_CAPABILITIES,
|
|
9
|
+
resolve_capabilities,
|
|
10
|
+
resolve_extras,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"ALL_CAPABILITIES",
|
|
15
|
+
"CAPABILITY_TO_EXTRA",
|
|
16
|
+
"FEATURE_LABEL_TO_CAPABILITY",
|
|
17
|
+
"NO_EXTRA_CAPABILITIES",
|
|
18
|
+
"PROFILE_CAPABILITIES",
|
|
19
|
+
"TemplateGenerator",
|
|
20
|
+
"resolve_capabilities",
|
|
21
|
+
"resolve_extras",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def __getattr__(name: str):
|
|
26
|
+
if name == "TemplateGenerator":
|
|
27
|
+
generator_module = __import__(
|
|
28
|
+
"alms_cli.templates.generator",
|
|
29
|
+
fromlist=["TemplateGenerator"],
|
|
30
|
+
)
|
|
31
|
+
return generator_module.TemplateGenerator
|
|
32
|
+
raise AttributeError(name)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Application identity
|
|
2
|
+
APP_NAME={{ project_name }}
|
|
3
|
+
APP_DESCRIPTION=Backend API for {{ project_name }}
|
|
4
|
+
APP_VERSION=0.1.0
|
|
5
|
+
SERVICE_NAME={{ project_name | lower | replace(' ', '-') }}
|
|
6
|
+
|
|
7
|
+
# Server Configuration
|
|
8
|
+
SERVER_PORT=3000
|
|
9
|
+
SERVER_HOST=0.0.0.0
|
|
10
|
+
ALLOWED_HOSTS=["*"]
|
|
11
|
+
|
|
12
|
+
# Environment Configuration
|
|
13
|
+
DEBUG=True
|
|
14
|
+
SECRET_KEY=generate-a-secure-key-here
|
|
15
|
+
|
|
16
|
+
# Security Configuration
|
|
17
|
+
X_API_KEY=
|
|
18
|
+
|
|
19
|
+
# API Configuration
|
|
20
|
+
API_PREFIX=/api
|
|
21
|
+
|
|
22
|
+
# Logging Configuration
|
|
23
|
+
LOG_LEVEL=info
|
|
24
|
+
LOG_SAVE_TO_FILE=false
|
|
25
|
+
LOG_FILE=src/logs/app.log
|
|
26
|
+
LOG_AUTO_SETUP=true
|
|
27
|
+
{% if has_ai %}
|
|
28
|
+
# OpenAI Configuration
|
|
29
|
+
OPENAI_API_KEY=sk-...
|
|
30
|
+
OPENAI_MODEL_BASIC=gpt-4o-mini
|
|
31
|
+
OPENAI_MODEL_REASONING=gpt-4o
|
|
32
|
+
{% endif %}{% if has_db %}
|
|
33
|
+
# Database Configuration (PostgreSQL)
|
|
34
|
+
DATABASE_URL=
|
|
35
|
+
DATABASE_HOST=localhost
|
|
36
|
+
DATABASE_PORT=5432
|
|
37
|
+
DATABASE_NAME=db
|
|
38
|
+
DATABASE_USER=postgres
|
|
39
|
+
DATABASE_PASSWORD=postgres
|
|
40
|
+
{% endif %}{% if has_redis %}
|
|
41
|
+
# Redis Configuration
|
|
42
|
+
REDIS_HOST=localhost
|
|
43
|
+
REDIS_PORT=6379
|
|
44
|
+
REDIS_PASSWORD=
|
|
45
|
+
REDIS_DB=0
|
|
46
|
+
{% endif %}{% if has_obs %}
|
|
47
|
+
# Observability
|
|
48
|
+
METRICS_ENABLED=true
|
|
49
|
+
TRACING_ENABLED=true
|
|
50
|
+
OTLP_ENDPOINT=http://localhost:4317
|
|
51
|
+
{% endif %}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: astral-sh/setup-uv@v3
|
|
15
|
+
- run: uv sync{{ extra_flag }}
|
|
16
|
+
- run: uv run pytest src/tests
|
|
17
|
+
- run: uv run ruff check src/
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Virtual environments
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
|
|
10
|
+
# Distribution / packaging
|
|
11
|
+
dist/
|
|
12
|
+
build/
|
|
13
|
+
*.egg-info/
|
|
14
|
+
|
|
15
|
+
# IDE
|
|
16
|
+
.vscode/
|
|
17
|
+
.idea/
|
|
18
|
+
*.swp
|
|
19
|
+
*.swo
|
|
20
|
+
|
|
21
|
+
# Environment
|
|
22
|
+
.env
|
|
23
|
+
.env.local
|
|
24
|
+
|
|
25
|
+
# Logs
|
|
26
|
+
*.log
|
|
27
|
+
logs/
|
|
28
|
+
|
|
29
|
+
# OS
|
|
30
|
+
.DS_Store
|
|
31
|
+
Thumbs.db
|
|
32
|
+
|
|
33
|
+
# Testing
|
|
34
|
+
.pytest_cache/
|
|
35
|
+
.coverage
|
|
36
|
+
htmlcov/
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# {{ project_name }}
|
|
2
|
+
|
|
3
|
+
> **The AI-First Backend for Scalable, Intelligent Applications.**
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- Python 3.13+
|
|
10
|
+
- [uv](https://docs.astral.sh/uv/getting-started/installation/) installed
|
|
11
|
+
|
|
12
|
+
### 1. Setup
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cp .env.example .env
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### 2. Install Dependencies
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv sync
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 3. Start the Application
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
uv run -m src.api.main
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The API will be available at:
|
|
31
|
+
- API: http://localhost:3000
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Alembic migrations
|