implosive-origin-utac 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,4 @@
1
+ """Diamond Setup — universal Python project scaffold."""
2
+
3
+ __version__ = "1.0.0"
4
+ __author__ = "GenesisAeon"
@@ -0,0 +1,13 @@
1
+ """Shared type definitions for diamond-setup."""
2
+
3
+ from typing import TypedDict
4
+
5
+
6
+ class TemplateDict(TypedDict):
7
+ """Structure of a diamond-setup project template."""
8
+
9
+ name: str
10
+ description: str
11
+ variables: list[str]
12
+ defaults: dict[str, str]
13
+ files: dict[str, str]
diamond_setup/cli.py ADDED
@@ -0,0 +1,183 @@
1
+ """Diamond Setup CLI — scaffold, validate and inspect project templates."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from typing import Annotated
7
+
8
+ import typer
9
+ from rich.console import Console
10
+ from rich.panel import Panel
11
+ from rich.table import Table
12
+
13
+ from . import __version__
14
+ from .preset import scaffold as _scaffold
15
+ from .templates import REGISTRY
16
+ from .validator import validate as _validate
17
+
18
+ app = typer.Typer(
19
+ name="diamond",
20
+ help="Universal Python project scaffold — create professional skeletons in seconds.",
21
+ add_completion=True,
22
+ rich_markup_mode="rich",
23
+ )
24
+ console = Console()
25
+ err_console = Console(stderr=True)
26
+
27
+
28
+ # ---------------------------------------------------------------------------
29
+ # scaffold
30
+ # ---------------------------------------------------------------------------
31
+
32
+
33
+ @app.command()
34
+ def scaffold(
35
+ project_name: Annotated[
36
+ str, typer.Argument(help="Name of the new project (kebab-case recommended)")
37
+ ],
38
+ template: Annotated[str, typer.Option("--template", "-t", help="Template to use")] = "minimal",
39
+ output_dir: Annotated[
40
+ Path | None, typer.Option("--output-dir", "-o", help="Parent directory for the new project")
41
+ ] = None,
42
+ author: Annotated[str | None, typer.Option(help="Author name")] = None,
43
+ description: Annotated[str | None, typer.Option(help="Short project description")] = None,
44
+ python_version: Annotated[
45
+ str | None, typer.Option(help="Minimum Python version (e.g. 3.11)")
46
+ ] = None,
47
+ dry_run: Annotated[
48
+ bool, typer.Option("--dry-run", help="Preview files without writing them")
49
+ ] = False,
50
+ ) -> None:
51
+ """[bold]Scaffold a new project[/bold] from a template.
52
+
53
+ Examples:
54
+
55
+ diamond scaffold my-tool
56
+
57
+ diamond scaffold my-tool --template genesis --author "Ada Lovelace"
58
+
59
+ diamond scaffold my-tool --dry-run
60
+ """
61
+ if template not in REGISTRY:
62
+ err_console.print(
63
+ f"[red]Unknown template '[bold]{template}[/bold]'. "
64
+ f"Run [bold]diamond list-templates[/bold] to see available options.[/red]"
65
+ )
66
+ raise typer.Exit(code=1)
67
+
68
+ dest = output_dir or Path.cwd()
69
+ project_path = dest / project_name
70
+
71
+ if project_path.exists() and not dry_run:
72
+ err_console.print(
73
+ f"[red]Directory [bold]{project_path}[/bold] already exists. "
74
+ "Use a different name or [bold]--output-dir[/bold].[/red]"
75
+ )
76
+ raise typer.Exit(code=1)
77
+
78
+ overrides = {
79
+ "author": author,
80
+ "description": description,
81
+ "python_version": python_version,
82
+ }
83
+
84
+ tmpl = REGISTRY[template]
85
+ mode = "[yellow]DRY RUN[/yellow] — " if dry_run else ""
86
+ console.print(
87
+ Panel(
88
+ f"{mode}[bold green]Scaffolding[/bold green] [cyan]{project_name}[/cyan] "
89
+ f"with template [magenta]{template}[/magenta]",
90
+ expand=False,
91
+ )
92
+ )
93
+
94
+ written = _scaffold(project_name, tmpl, dest, overrides=overrides, dry_run=dry_run)
95
+
96
+ table = Table(show_header=False, box=None, padding=(0, 2))
97
+ for path in written:
98
+ rel = path.relative_to(dest)
99
+ icon = "📄" if dry_run else "✅"
100
+ table.add_row(icon, str(rel))
101
+ console.print(table)
102
+
103
+ if dry_run:
104
+ console.print("\n[yellow]Dry run — no files were written.[/yellow]")
105
+ else:
106
+ console.print(
107
+ f"\n[bold green]Done![/bold green] Project created at [cyan]{project_path}[/cyan]\n"
108
+ f"\nNext steps:\n"
109
+ f" [dim]cd[/dim] {project_name}\n"
110
+ f" [dim]uv sync --dev[/dim]\n"
111
+ f" [dim]pre-commit install[/dim]\n"
112
+ f" [dim]uv run pytest[/dim]"
113
+ )
114
+
115
+
116
+ # ---------------------------------------------------------------------------
117
+ # list-templates
118
+ # ---------------------------------------------------------------------------
119
+
120
+
121
+ @app.command(name="list-templates")
122
+ def list_templates() -> None:
123
+ """List all available templates."""
124
+ table = Table(title="Available Templates", show_lines=True)
125
+ table.add_column("Name", style="magenta bold", no_wrap=True)
126
+ table.add_column("Description")
127
+ table.add_column("Extra variables", style="dim")
128
+
129
+ for name, tmpl in REGISTRY.items():
130
+ base_vars = {"name", "description", "author", "python_version"}
131
+ extras = sorted(set(tmpl.get("variables", [])) - base_vars)
132
+ table.add_row(name, tmpl["description"], ", ".join(extras) or "—")
133
+
134
+ console.print(table)
135
+
136
+
137
+ # ---------------------------------------------------------------------------
138
+ # validate
139
+ # ---------------------------------------------------------------------------
140
+
141
+
142
+ @app.command()
143
+ def validate(
144
+ path: Annotated[Path | None, typer.Argument(help="Project directory to validate")] = None,
145
+ ) -> None:
146
+ """Validate a project directory against diamond-setup best practices."""
147
+ target = path or Path.cwd()
148
+ result = _validate(target)
149
+
150
+ console.print(f"\nValidating [cyan]{target}[/cyan]\n")
151
+
152
+ for msg in result.passed:
153
+ console.print(f" [green]✔[/green] {msg}")
154
+ for msg in result.warnings:
155
+ console.print(f" [yellow]⚠[/yellow] {msg}")
156
+ for msg in result.errors:
157
+ console.print(f" [red]✘[/red] {msg}")
158
+
159
+ console.print()
160
+ if result.ok:
161
+ console.print("[bold green]All checks passed.[/bold green]")
162
+ else:
163
+ console.print(f"[bold red]{len(result.errors)} error(s) found.[/bold red]")
164
+ raise typer.Exit(code=1)
165
+
166
+
167
+ # ---------------------------------------------------------------------------
168
+ # version
169
+ # ---------------------------------------------------------------------------
170
+
171
+
172
+ @app.command()
173
+ def version() -> None:
174
+ """Show the diamond-setup version."""
175
+ console.print(f"diamond-setup [bold]{__version__}[/bold]")
176
+
177
+
178
+ # ---------------------------------------------------------------------------
179
+ # entry point
180
+ # ---------------------------------------------------------------------------
181
+
182
+ if __name__ == "__main__":
183
+ app()
@@ -0,0 +1,84 @@
1
+ """Preset engine — resolves templates and renders project files."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from pathlib import Path
7
+ from string import Template
8
+
9
+ from ._types import TemplateDict
10
+
11
+
12
+ class TemplateError(Exception):
13
+ """Raised when template rendering fails."""
14
+
15
+
16
+ def _to_snake(name: str) -> str:
17
+ """Convert a project name (kebab or space) to snake_case."""
18
+ return re.sub(r"[-\s]+", "_", name).lower()
19
+
20
+
21
+ def _python_version_nodot(version: str) -> str:
22
+ """Turn '3.11' into '311' for ruff target-version."""
23
+ return version.replace(".", "")
24
+
25
+
26
+ def _build_context(
27
+ project_name: str, template: TemplateDict, overrides: dict[str, str | None]
28
+ ) -> dict[str, str]:
29
+ """Merge defaults, user overrides and derived variables into a render context."""
30
+ ctx: dict[str, str] = {
31
+ "name": project_name,
32
+ "name_snake": _to_snake(project_name),
33
+ **template.get("defaults", {}),
34
+ **{k: v for k, v in overrides.items() if v is not None},
35
+ }
36
+ ctx["python_version_nodot"] = _python_version_nodot(ctx.get("python_version", "3.11"))
37
+ return ctx
38
+
39
+
40
+ def _render(content: str, ctx: dict[str, str]) -> str:
41
+ """Render a template string using Python's string.Template (safe_substitute)."""
42
+ # First pass: render path-embedded variables (e.g. ${name_snake} in file keys)
43
+ return Template(content).safe_substitute(ctx)
44
+
45
+
46
+ def scaffold(
47
+ project_name: str,
48
+ template: TemplateDict,
49
+ output_dir: Path,
50
+ overrides: dict[str, str | None] | None = None,
51
+ dry_run: bool = False,
52
+ ) -> list[Path]:
53
+ """
54
+ Render a template into a new project directory.
55
+
56
+ Args:
57
+ project_name: The name of the new project.
58
+ template: A template dict from the registry.
59
+ output_dir: Parent directory where the project folder will be created.
60
+ overrides: Optional variable overrides (e.g. author, description).
61
+ dry_run: If True, return planned paths without writing any files.
62
+
63
+ Returns:
64
+ List of paths that were (or would be) written.
65
+ """
66
+ overrides = overrides or {}
67
+ ctx = _build_context(project_name, template, overrides)
68
+ project_root = output_dir / project_name
69
+ written: list[Path] = []
70
+
71
+ for raw_path, raw_content in template["files"].items():
72
+ # Render the path itself (e.g. src/${name_snake}/__init__.py)
73
+ rel_path = Path(_render(raw_path, ctx))
74
+ abs_path = project_root / rel_path
75
+
76
+ rendered_content = _render(raw_content, ctx)
77
+
78
+ if not dry_run:
79
+ abs_path.parent.mkdir(parents=True, exist_ok=True)
80
+ abs_path.write_text(rendered_content, encoding="utf-8")
81
+
82
+ written.append(abs_path)
83
+
84
+ return written
@@ -0,0 +1,15 @@
1
+ """Template registry — add a new module here to register a new template."""
2
+
3
+ from diamond_setup._types import TemplateDict
4
+
5
+ from .genesis import TEMPLATE as GENESIS_TEMPLATE
6
+ from .implosive_origin import TEMPLATE as IMPLOSIVE_ORIGIN_TEMPLATE
7
+ from .minimal import TEMPLATE as MINIMAL_TEMPLATE
8
+
9
+ REGISTRY: dict[str, TemplateDict] = {
10
+ "minimal": MINIMAL_TEMPLATE,
11
+ "genesis": GENESIS_TEMPLATE,
12
+ "implosive-origin": IMPLOSIVE_ORIGIN_TEMPLATE,
13
+ }
14
+
15
+ __all__ = ["REGISTRY"]
@@ -0,0 +1,84 @@
1
+ """Genesis template — superset of minimal, adds domain/metrics YAML and entropy-table bridge."""
2
+
3
+ import copy
4
+
5
+ from diamond_setup._types import TemplateDict
6
+
7
+ from .minimal import TEMPLATE as MINIMAL_TEMPLATE
8
+
9
+ _extra_files = {
10
+ "domains.yaml": """\
11
+ # Domain configuration for ${name}
12
+ # Compatible with entropy-table bridge format
13
+ domains:
14
+ primary:
15
+ name: "${name}"
16
+ metrics: ${metrics}
17
+ description: "${description}"
18
+
19
+ relations: []
20
+
21
+ metadata:
22
+ project: "${name}"
23
+ author: "${author}"
24
+ version: "0.1.0"
25
+ """,
26
+ "config/entropy.yaml": """\
27
+ # entropy-table bridge configuration
28
+ bridge:
29
+ source_project: "${name}"
30
+ export_format: "entropy-table-v1"
31
+ domains_file: "domains.yaml"
32
+ output: "exports/entropy-table.yaml"
33
+
34
+ options:
35
+ sort_keys: false
36
+ allow_unicode: true
37
+ """,
38
+ "src/${name_snake}/bridge.py": """\
39
+ \"\"\"entropy-table YAML bridge for ${name}.\"\"\"
40
+
41
+ from __future__ import annotations
42
+
43
+ from pathlib import Path
44
+
45
+ import yaml
46
+
47
+
48
+ def export_to_entropy_table(
49
+ input_path: str | Path = "domains.yaml",
50
+ output_path: str | Path = "exports/entropy-table.yaml",
51
+ ) -> Path:
52
+ \"\"\"Export domain YAML to entropy-table compatible format.\"\"\"
53
+ input_path = Path(input_path)
54
+ output_path = Path(output_path)
55
+
56
+ with input_path.open() as f:
57
+ data = yaml.safe_load(f)
58
+
59
+ entropy_data = {
60
+ "domains": data.get("domains", {}),
61
+ "relations": data.get("relations", []),
62
+ "metadata": {
63
+ **data.get("metadata", {}),
64
+ "generated_by": "${name} (diamond-setup v1.0.0)",
65
+ },
66
+ }
67
+
68
+ output_path.parent.mkdir(parents=True, exist_ok=True)
69
+ output_path.write_text(yaml.dump(entropy_data, sort_keys=False, allow_unicode=True))
70
+ return output_path
71
+ """,
72
+ }
73
+
74
+ _genesis: TemplateDict = copy.deepcopy(MINIMAL_TEMPLATE)
75
+ _genesis["name"] = "genesis"
76
+ _genesis["description"] = "GenesisAeon project with domain/metrics YAML and entropy-table bridge"
77
+ _genesis["variables"] = MINIMAL_TEMPLATE["variables"] + ["metrics"]
78
+ _genesis["defaults"] = {
79
+ **MINIMAL_TEMPLATE["defaults"],
80
+ "metrics": "crep",
81
+ }
82
+ _genesis["files"] = {**MINIMAL_TEMPLATE["files"], **_extra_files}
83
+
84
+ TEMPLATE: TemplateDict = _genesis
@@ -0,0 +1,87 @@
1
+ """implosive-origin template — UTAC Type-6 pre-inflationary cosmology scaffold."""
2
+
3
+ import copy
4
+
5
+ from diamond_setup._types import TemplateDict
6
+
7
+ from .genesis import TEMPLATE as GENESIS_TEMPLATE
8
+
9
+ _extra_files = {
10
+ "DISCLAIMER.md": """\
11
+ # DISCLAIMER — Speculative Cosmological Module
12
+
13
+ **Status: SPECULATIVE**
14
+
15
+ This module implements UTAC Type-6 (Implosive Origin Fields) — a speculative
16
+ cosmological framework. All predictions are hypotheses, not established physics.
17
+
18
+ See the parent package README for full falsification conditions.
19
+ """,
20
+ "data/bicep_keck_r_bounds.yaml": """\
21
+ # BICEP/Keck 2021 r < 0.036 — placeholder
22
+ # Replace with actual data from arXiv:2110.00483
23
+ reference: "BICEP/Keck 2021"
24
+ r_upper_95pct: 0.036
25
+ utac_prediction:
26
+ r_frame_principle: 0.003906
27
+ status: "SPECULATIVE"
28
+ """,
29
+ "src/${name_snake}/constants.py": """\
30
+ \"\"\"Physical constants for ${name}.\"\"\"
31
+ import math
32
+
33
+ PHI: float = (1.0 + math.sqrt(5.0)) / 2.0
34
+ SIGMA_PHI: float = 1.0 / 16.0
35
+ ALPHA: float = 1.0 / 137.035999084
36
+ C_KM_S: float = 299_792.458
37
+ V_RIG_KM_S: float = C_KM_S / (137.035999084 * PHI)
38
+ R_PREDICTED: float = SIGMA_PHI ** 2
39
+ K_RIG_MPC: float = (V_RIG_KM_S / C_KM_S) * 67.4
40
+ """,
41
+ "src/${name_snake}/type6_ode.py": """\
42
+ \"\"\"UTAC Type-6: reversed logistic ODE.\"\"\"
43
+ import math
44
+ from dataclasses import dataclass
45
+
46
+
47
+ @dataclass
48
+ class Type6ODEParams:
49
+ r: float = 1.0
50
+ K_min: float = 0.01
51
+ sigma: float = 0.0625
52
+ gamma: float = 0.309
53
+
54
+
55
+ class Type6ODE:
56
+ \"\"\"dH/dt = -r·H·(1 - H/K_min)·tanh(σΓ)\"\"\"
57
+
58
+ def __init__(self, params: Type6ODEParams | None = None) -> None:
59
+ self.p = params or Type6ODEParams()
60
+
61
+ def dHdt(self, H: float) -> float:
62
+ return -self.p.r * H * (1.0 - H / self.p.K_min) * math.tanh(self.p.sigma * self.p.gamma)
63
+
64
+ def fixed_point(self) -> float:
65
+ return self.p.K_min * math.tanh(self.p.sigma * self.p.gamma)
66
+
67
+ def efolds(self, H0: float = 1.0) -> float:
68
+ H_star = self.fixed_point()
69
+ return math.log(H0 / H_star) if H_star > 0 else float("nan")
70
+ """,
71
+ }
72
+
73
+ _implosive: TemplateDict = copy.deepcopy(GENESIS_TEMPLATE)
74
+ _implosive["name"] = "implosive-origin"
75
+ _implosive["description"] = (
76
+ "UTAC Type-6 Implosive Origin Fields — pre-inflationary cosmology scaffold "
77
+ "(GenesisAeon Package 33, SPECULATIVE)"
78
+ )
79
+ _implosive["variables"] = GENESIS_TEMPLATE["variables"] + ["zenodo_doi"]
80
+ _implosive["defaults"] = {
81
+ **GENESIS_TEMPLATE["defaults"],
82
+ "metrics": "crep,type6",
83
+ "zenodo_doi": "10.5281/zenodo.17472834",
84
+ }
85
+ _implosive["files"] = {**GENESIS_TEMPLATE["files"], **_extra_files}
86
+
87
+ TEMPLATE: TemplateDict = _implosive
@@ -0,0 +1,171 @@
1
+ """Minimal template — clean, modern Python project for anyone."""
2
+
3
+ from diamond_setup._types import TemplateDict
4
+
5
+ TEMPLATE: TemplateDict = {
6
+ "name": "minimal",
7
+ "description": "Clean, modern Python project with uv, ruff, pytest and CI",
8
+ "variables": ["name", "description", "author", "python_version"],
9
+ "defaults": {
10
+ "description": "A Python project",
11
+ "author": "Your Name",
12
+ "python_version": "3.11",
13
+ },
14
+ "files": {
15
+ "pyproject.toml": """\
16
+ [project]
17
+ name = "${name}"
18
+ version = "0.1.0"
19
+ description = "${description}"
20
+ readme = "README.md"
21
+ license = { text = "MIT" }
22
+ authors = [{ name = "${author}" }]
23
+ requires-python = ">=${python_version}"
24
+ dependencies = []
25
+
26
+ [project.optional-dependencies]
27
+ dev = ["ruff>=0.6.0", "pytest>=8.0.0", "pytest-cov>=5.0.0"]
28
+
29
+ [build-system]
30
+ requires = ["hatchling"]
31
+ build-backend = "hatchling.build"
32
+
33
+ [tool.hatch.build.targets.wheel]
34
+ packages = ["src/${name_snake}"]
35
+
36
+ [tool.ruff]
37
+ line-length = 100
38
+ target-version = "py${python_version_nodot}"
39
+
40
+ [tool.ruff.lint]
41
+ select = ["E", "F", "B", "I", "W", "UP"]
42
+
43
+ [tool.pytest.ini_options]
44
+ testpaths = ["tests"]
45
+ addopts = "--cov=${name_snake} --cov-report=term-missing -v"
46
+ """,
47
+ "README.md": """\
48
+ # ${name}
49
+
50
+ ${description}
51
+
52
+ ## Quickstart
53
+
54
+ ```bash
55
+ uv sync
56
+ uv run pytest
57
+ ```
58
+
59
+ ## Development
60
+
61
+ ```bash
62
+ uv sync --dev
63
+ pre-commit install
64
+ uv run ruff check .
65
+ uv run pytest
66
+ ```
67
+ """,
68
+ ".gitignore": """\
69
+ # Python
70
+ __pycache__/
71
+ *.py[cod]
72
+ *.egg-info/
73
+ .eggs/
74
+ dist/
75
+ build/
76
+ .venv/
77
+ .uv/
78
+
79
+ # Testing
80
+ .coverage
81
+ htmlcov/
82
+ .pytest_cache/
83
+
84
+ # Docs
85
+ site/
86
+
87
+ # Editors
88
+ .vscode/
89
+ .idea/
90
+ *.swp
91
+ """,
92
+ ".pre-commit-config.yaml": """\
93
+ repos:
94
+ - repo: https://github.com/astral-sh/ruff-pre-commit
95
+ rev: v0.6.0
96
+ hooks:
97
+ - id: ruff
98
+ args: [--fix]
99
+ - id: ruff-format
100
+ - repo: https://github.com/pre-commit/pre-commit-hooks
101
+ rev: v4.6.0
102
+ hooks:
103
+ - id: trailing-whitespace
104
+ - id: end-of-file-fixer
105
+ - id: check-yaml
106
+ - id: check-toml
107
+ """,
108
+ ".github/workflows/ci.yml": """\
109
+ name: CI
110
+
111
+ on:
112
+ push:
113
+ branches: [main, master]
114
+ pull_request:
115
+
116
+ jobs:
117
+ test:
118
+ runs-on: ubuntu-latest
119
+ strategy:
120
+ matrix:
121
+ python-version: ["3.11", "3.12"]
122
+ steps:
123
+ - uses: actions/checkout@v4
124
+ - uses: astral-sh/setup-uv@v5
125
+ with:
126
+ python-version: $${{ matrix.python-version }}
127
+ - run: uv sync --dev
128
+ - run: uv run ruff check .
129
+ - run: uv run pytest
130
+ """,
131
+ "AGENT.md": """\
132
+ # AGENT.md – GenesisAeon Release & Metadata Rules
133
+
134
+ ## Bei jeder relevanten Änderung (Version Bump, Feature, Bugfix, Docs):
135
+
136
+ 1. **.zenodo.json**
137
+ - Aktualisiere `version`, `description`, `keywords`, `related_identifiers`
138
+ - Beschreibung muss die aktuelle Funktion des Packages klar beschreiben
139
+ - Immer den Whitepaper-DOI (10.5281/zenodo.19645351) als `isPartOf` oder
140
+ `isDocumentedBy` eintragen
141
+
142
+ 2. **README.md**
143
+ - Aktualisiere Whitepaper-Badge auf aktuelle Version
144
+ - Aktualisiere @software BibTeX-Eintrag (version, publisher=Zenodo, DOI)
145
+ - Füge Package-Number-Badge ein (z.B. Package 17)
146
+
147
+ 3. **Versionierung**
148
+ - pyproject.toml und __init__.py müssen synchron auf dieselbe Version sein
149
+ - Tags immer als annotated Tag (`git tag -a vX.Y.Z`)
150
+
151
+ 4. **Commit-Message**
152
+ - Beginne mit "release:", "feat:", "fix:", "docs:" oder "chore:"
153
+
154
+ 5. **Nach jedem neuen Tag**
155
+ - Release-Pipeline (PyPI + Zenodo) wird automatisch ausgelöst
156
+
157
+ Diese Regeln sind bindend für alle Claude-Code-Runs und zukünftige Agents in GenesisAeon-Repos.
158
+ """,
159
+ "src/${name_snake}/__init__.py": ('"""${name}."""\n\n__version__ = "0.1.0"\n'),
160
+ "tests/__init__.py": "",
161
+ "tests/test_main.py": """\
162
+ \"\"\"Tests for ${name}.\"\"\"
163
+
164
+ from ${name_snake} import __version__
165
+
166
+
167
+ def test_version():
168
+ assert __version__ == "0.1.0"
169
+ """,
170
+ },
171
+ }