demolab-cli 2.1.0__tar.gz → 2.2.0__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.
Potentially problematic release.
This version of demolab-cli might be problematic. Click here for more details.
- demolab_cli-2.2.0/.gitattributes +1 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/.github/workflows/publish.yml +2 -2
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/PKG-INFO +1 -1
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/AGENT.md +2 -1
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/CHANGELOG.md +27 -0
- demolab_cli-2.2.0/demolab_cli/VERSION +1 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/build.py +46 -8
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/cli.py +5 -1
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/devserver.py +1 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/guides/RULES.md +6 -1
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/guides/STRUCTURE.md +1 -1
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/UPDATE.md +20 -0
- demolab_cli-2.2.0/demolab_cli/scaffold/skeleton/.gitattributes +1 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/test_cli.py +6 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/test_devserver.py +13 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/test_engine_build.py +34 -3
- demolab_cli-2.2.0/demolab_cli/typ/entry.typ +11 -0
- demolab_cli-2.1.0/demolab_cli/VERSION +0 -1
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/.github/workflows/landing-preview.yml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/.github/workflows/landing.yml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/.github/workflows/tests.yml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/.gitignore +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/AGENTS.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/CLAUDE.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/DEVELOPING.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/LICENSE +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/README.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/__init__.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/_paths.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/deploy/deploy.yml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/deploy/preview.yml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/guides/AUTORESEARCH-RULES.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/guides/GLOSSARY.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/guides/HOUSESTYLE.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/guides/SLIDES.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/guides/SUPPORT.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/overlay.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/AUTORESEARCH.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/DOCTOR.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/EMBED-DOCS.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/FROM-JUPYTER.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/FROM-PAPER.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/GETTING-STARTED.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/GROUND-CLAIMS.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/LINT.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/LITERATURE-SEARCH.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/MIGRATE-CODE.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/MIGRATE-STACK.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/NEXT.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/RED-TEAM.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/STEELMAN.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/runbooks/TOUR.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/data/ar018/swe-bench.svg +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar004.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar005.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar010.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar011.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar012.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar013.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar014.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar015.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar016.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar017.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar018.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar019.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar020.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar021.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar022.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar023.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar024.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar025.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/ar026.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/pdfs/book.pdf +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/demolab.yaml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/site/CNAME +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/site/landing.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar004.slide.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar005.slide.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar010.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar011.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar012.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar013.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar014.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar015.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar016.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar017.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar018.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar019.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar020.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar021.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar022.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar023.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar024.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar025.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/writings/ar026.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/root/AGENTS.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/root/CLAUDE.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/root/README.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/root/github/workflows/tests.yml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/root/gitignore +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/root/pyproject.toml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/HOUSESTYLE.local.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/artifacts/data/.gitkeep +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/artifacts/pdfs/.gitkeep +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/demolab.yaml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/experiments/helpers/__init__.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/experiments/helpers/provenance.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/experiments/helpers/style.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/experiments/helpers/test_provenance.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/tools/.gitkeep +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/writings/.gitkeep +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/starters/monte-carlo-pi/README.md +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/starters/monte-carlo-pi/exp000.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/starters/monte-carlo-pi/exp000.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/slides.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/test_build_resilience.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/test_command_catalog.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/test_init_and_staging.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/test_overlay.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/test_slide_catalog.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/test_slides.py +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/typ/cite-popover.js +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/typ/favicon.svg +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/typ/lib.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/typ/main.typ +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/typ/style.css +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/pyproject.toml +0 -0
- {demolab_cli-2.1.0 → demolab_cli-2.2.0}/uv.lock +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*.pdf binary
|
|
@@ -45,8 +45,8 @@ jobs:
|
|
|
45
45
|
env:
|
|
46
46
|
TAG: v${{ steps.version.outputs.version }}
|
|
47
47
|
run: |
|
|
48
|
-
if git
|
|
49
|
-
echo "$TAG already exists — skipping tag."
|
|
48
|
+
if git ls-remote --exit-code --tags origin "refs/tags/$TAG" >/dev/null 2>&1; then
|
|
49
|
+
echo "$TAG already exists on origin — skipping tag."
|
|
50
50
|
else
|
|
51
51
|
git tag "$TAG"
|
|
52
52
|
git push origin "$TAG"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: demolab-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Lab notebook for computational science: Python tools produce per-run artifacts; Typst publishes them as a web bundle, per-entry PDFs, and a book.
|
|
5
5
|
Project-URL: Homepage, https://github.com/eoinmurray/demolab
|
|
6
6
|
Project-URL: Changelog, https://github.com/eoinmurray/demolab/blob/main/demolab_cli/CHANGELOG.md
|
|
@@ -71,7 +71,8 @@ guide covers it, ground your answer in it — cite it or offer to start it.
|
|
|
71
71
|
`demolab` lists them all. The loop: `uv run python experiments/expNNN.py` (run an experiment
|
|
72
72
|
end-to-end — run the runner directly, there's no `demolab run` wrapper) · `demolab dev`
|
|
73
73
|
(live-preview server — have the *user* run it in their own terminal) · `demolab build`
|
|
74
|
-
(site + PDFs) · `demolab
|
|
74
|
+
(complete site + PDFs) · `demolab build <id>` (one entry PDF) · `demolab test`. Preview
|
|
75
|
+
PDFs stay in the ignored site tree; run the complete build before publishing. Reference data ships in the package:
|
|
75
76
|
`demolab docs STARTERS` (canonical first experiments — model file shapes on them, never copy
|
|
76
77
|
blindly; `monte-carlo-pi` is the default) and `demolab docs DEMO` (the published docs site's
|
|
77
78
|
source).
|
|
@@ -13,6 +13,33 @@ the runbook shows the entries between your version and the latest.
|
|
|
13
13
|
|
|
14
14
|
## [Unreleased]
|
|
15
15
|
|
|
16
|
+
## [2.2.0] — 2026-08-07
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- **Build one entry PDF with `demolab build <id>`.** The targeted build uses the same page
|
|
20
|
+
surface, branding, root, and artifact paths as the complete publication, while deliberately
|
|
21
|
+
leaving the website and combined book untouched.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- **PDF builds are reproducible instead of changing metadata on every run.** Every Typst compile
|
|
25
|
+
now uses a documented `2000-01-01T00:00:00Z` creation timestamp by default and respects an
|
|
26
|
+
explicit `SOURCE_DATE_EPOCH` override. PDFs are marked binary in new labs and this source repo.
|
|
27
|
+
- **`demolab dev` no longer dirties committed publication PDFs.** Live preview still builds the
|
|
28
|
+
complete ignored website, including its PDF links, but no longer mirrors those preview PDFs into
|
|
29
|
+
`artifacts/pdfs/`; an explicit `demolab build` remains the publication step.
|
|
30
|
+
|
|
31
|
+
## [2.1.1] — 2026-07-18
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- **UPDATE now verifies the project environment after upgrading `demolab-cli`.** The runbook
|
|
35
|
+
explains that uv's package upgrade already refreshes targeted cache metadata, compares the
|
|
36
|
+
active `uv run demolab` version with the lock, and uses a targeted package reinstall when they
|
|
37
|
+
disagree. It explicitly avoids global cache deletion and `uvx` verification, which operate at
|
|
38
|
+
the wrong scope for an existing lab.
|
|
39
|
+
- **Release tagging is idempotent against remote tags.** The publish workflow checks the remote
|
|
40
|
+
before pushing its release tag, avoiding a false-red release when the documented manual tag was
|
|
41
|
+
already pushed.
|
|
42
|
+
|
|
16
43
|
## [2.1.0] — 2026-07-18
|
|
17
44
|
|
|
18
45
|
### Added
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.2.0
|
|
@@ -42,6 +42,7 @@ ROOT = Path(os.environ.get("DEMOLAB_ROOT") or _paths.find_lab_root() or Path.cwd
|
|
|
42
42
|
WRITINGS = ROOT / "writings"
|
|
43
43
|
BUILD = ROOT / "temp" / "bundle" # scratch: staged main.typ + manifest + deck PDFs
|
|
44
44
|
MAIN = BUILD / "main.typ" # staged copy of the packaged typ/main.typ
|
|
45
|
+
ENTRY_MAIN = BUILD / "entry.typ" # staged single-entry PDF wrapper
|
|
45
46
|
MANIFEST = BUILD / "index.json" # scratch: id/asset lists main.typ reads
|
|
46
47
|
DECKS = BUILD / "decks" # scratch: compiled deck PDFs, embedded as assets
|
|
47
48
|
SITE = ROOT / "artifacts" / "site" # bundle output (HTML + mp4 + pdfs/), gitignored
|
|
@@ -60,6 +61,13 @@ def _find_typst() -> str:
|
|
|
60
61
|
|
|
61
62
|
|
|
62
63
|
TYPST = _find_typst()
|
|
64
|
+
DEFAULT_CREATION_TIMESTAMP = "946684800" # 2000-01-01T00:00:00Z
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def typst_compile(*args: str) -> list[str]:
|
|
68
|
+
"""A reproducible Typst compile command shared by every PDF-producing path."""
|
|
69
|
+
timestamp = os.environ.get("SOURCE_DATE_EPOCH", DEFAULT_CREATION_TIMESTAMP)
|
|
70
|
+
return [TYPST, "compile", "--creation-timestamp", timestamp, *args]
|
|
63
71
|
|
|
64
72
|
|
|
65
73
|
def stage() -> None:
|
|
@@ -69,6 +77,7 @@ def stage() -> None:
|
|
|
69
77
|
_paths.stage(ROOT)
|
|
70
78
|
BUILD.mkdir(parents=True, exist_ok=True)
|
|
71
79
|
shutil.copy2(_paths.TYP / "main.typ", MAIN)
|
|
80
|
+
shutil.copy2(_paths.TYP / "entry.typ", ENTRY_MAIN)
|
|
72
81
|
|
|
73
82
|
|
|
74
83
|
def discover():
|
|
@@ -141,8 +150,8 @@ def compile_decks(deck_ids: list[str]) -> list[str]:
|
|
|
141
150
|
good = []
|
|
142
151
|
for d in deck_ids:
|
|
143
152
|
proc = subprocess.run(
|
|
144
|
-
|
|
145
|
-
|
|
153
|
+
typst_compile("--root", str(ROOT),
|
|
154
|
+
str(WRITINGS / f"{d}.slide.typ"), str(DECKS / f"{d}.pdf")),
|
|
146
155
|
capture_output=True, text=True,
|
|
147
156
|
)
|
|
148
157
|
if proc.returncode == 0:
|
|
@@ -179,8 +188,8 @@ def compile_bundle(ids: list[str], deck_ids: list[str]) -> dict:
|
|
|
179
188
|
while True:
|
|
180
189
|
write_manifest(ids, deck_ids, broken=broken)
|
|
181
190
|
proc = subprocess.run(
|
|
182
|
-
|
|
183
|
-
|
|
191
|
+
typst_compile("--format", "bundle", "--features", "bundle,html",
|
|
192
|
+
"--root", str(ROOT), str(MAIN), str(SITE) + "/"),
|
|
184
193
|
capture_output=True, text=True,
|
|
185
194
|
)
|
|
186
195
|
if proc.returncode == 0:
|
|
@@ -230,6 +239,26 @@ def _warn_if_content_misplaced(ids: list[str]) -> None:
|
|
|
230
239
|
file=sys.stderr)
|
|
231
240
|
|
|
232
241
|
|
|
242
|
+
def compile_entry(entry_id: str, ids: list[str]) -> None:
|
|
243
|
+
"""Compile one ordinary writing directly to its committed standalone PDF."""
|
|
244
|
+
if entry_id not in ids:
|
|
245
|
+
slide = WRITINGS / f"{entry_id}.slide.typ"
|
|
246
|
+
detail = " (it is a slide deck; use `demolab slides`)" if slide.exists() else ""
|
|
247
|
+
raise SystemExit(f"error: no buildable entry named {entry_id!r}{detail}")
|
|
248
|
+
PDFS.mkdir(parents=True, exist_ok=True)
|
|
249
|
+
proc = subprocess.run(
|
|
250
|
+
typst_compile("--root", str(ROOT), "--input", f"entry={entry_id}",
|
|
251
|
+
"--input", f"has-brand={str((ROOT / 'demolab.yaml').exists()).lower()}",
|
|
252
|
+
str(ENTRY_MAIN), str(PDFS / f"{entry_id}.pdf")),
|
|
253
|
+
capture_output=True, text=True,
|
|
254
|
+
)
|
|
255
|
+
if proc.returncode != 0:
|
|
256
|
+
sys.stderr.write(proc.stdout + proc.stderr)
|
|
257
|
+
raise subprocess.CalledProcessError(proc.returncode, proc.args, proc.stdout, proc.stderr)
|
|
258
|
+
print(f"built {entry_id} -> {PDFS.relative_to(ROOT)}/{entry_id}.pdf"
|
|
259
|
+
" (site and book not updated)", flush=True)
|
|
260
|
+
|
|
261
|
+
|
|
233
262
|
def main() -> None:
|
|
234
263
|
# --generate-only writes the manifest + deck PDFs without compiling the bundle: a hand
|
|
235
264
|
# tool for inspecting what the compiler will see. (Dev serving is devserver.py, which runs
|
|
@@ -240,9 +269,16 @@ def main() -> None:
|
|
|
240
269
|
# prose/CSS/lib edit doesn't pay for deck compilation it can't have affected. Safe only when
|
|
241
270
|
# those PDFs exist (a full build ran first); a bare `demolab build` never skips.
|
|
242
271
|
skip_decks = "--skip-decks" in sys.argv
|
|
272
|
+
no_mirror = "--no-mirror" in sys.argv
|
|
273
|
+
entry_args = [arg for arg in sys.argv[1:] if not arg.startswith("--")]
|
|
274
|
+
if len(entry_args) > 1:
|
|
275
|
+
raise SystemExit("error: build accepts at most one entry id")
|
|
243
276
|
stage()
|
|
244
277
|
ids = discover()
|
|
245
278
|
_warn_if_content_misplaced(ids)
|
|
279
|
+
if entry_args:
|
|
280
|
+
compile_entry(entry_args[0], ids)
|
|
281
|
+
return
|
|
246
282
|
deck_ids = discover_decks()
|
|
247
283
|
# Zero writings is a valid state (a freshly `demolab scaffold`-ed repo): main.typ renders
|
|
248
284
|
# a friendly empty-state homepage, so we build rather than error.
|
|
@@ -263,9 +299,10 @@ def main() -> None:
|
|
|
263
299
|
broken = compile_bundle(ids, good_decks)
|
|
264
300
|
good = [i for i in ids if i not in broken]
|
|
265
301
|
# mirror the compiled PDFs (entries, book, and decks) to the committed artifacts/pdfs/
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
302
|
+
if not no_mirror:
|
|
303
|
+
PDFS.mkdir(parents=True, exist_ok=True)
|
|
304
|
+
for pdf in sorted((SITE / "pdfs").glob("*.pdf")):
|
|
305
|
+
shutil.copy(pdf, PDFS / pdf.name)
|
|
269
306
|
# The verbose detail (which ids built / stubbed, where the PDFs mirror) goes on its own line;
|
|
270
307
|
# the CONCISE summary is printed LAST, because the dev-server watch loop echoes only build.py's
|
|
271
308
|
# final stdout line on each rebuild. So a `demolab dev` session shows a terse one-liner, while a
|
|
@@ -273,7 +310,8 @@ def main() -> None:
|
|
|
273
310
|
print(f" entries: {', '.join(good)}"
|
|
274
311
|
+ (f" · decks: {', '.join(good_decks)}" if good_decks else "")
|
|
275
312
|
+ (f" · ⚠ stubbed: {', '.join(sorted(broken))}" if broken else "")
|
|
276
|
-
+ f" · pdfs -> {PDFS.relative_to(ROOT)}/"
|
|
313
|
+
+ (f" · pdfs -> {PDFS.relative_to(ROOT)}/" if not no_mirror
|
|
314
|
+
else " · preview PDFs left untracked"))
|
|
277
315
|
summary = f"built {len(good)} entries" + (f" + {len(good_decks)} decks" if good_decks else "")
|
|
278
316
|
if broken:
|
|
279
317
|
summary += f", {len(broken)} stubbed"
|
|
@@ -303,7 +303,8 @@ def cmd_dev(args: argparse.Namespace) -> int:
|
|
|
303
303
|
|
|
304
304
|
|
|
305
305
|
def cmd_build(args: argparse.Namespace) -> int:
|
|
306
|
-
|
|
306
|
+
entry_args = [args.entry] if args.entry else []
|
|
307
|
+
return _mod("build", *entry_args, cwd=_paths.require_lab_root())
|
|
307
308
|
|
|
308
309
|
|
|
309
310
|
def cmd_slides(args: argparse.Namespace) -> int:
|
|
@@ -379,6 +380,9 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
379
380
|
sp.add_argument("--demo", action="store_true", help="serve the shipped demo instead of your lab")
|
|
380
381
|
sp.add_argument("--landing", action="store_true",
|
|
381
382
|
help="with --demo: preview the upstream landing page too")
|
|
383
|
+
elif name == "build":
|
|
384
|
+
sp.add_argument("entry", nargs="?",
|
|
385
|
+
help="build only this entry PDF; omit for the complete publication")
|
|
382
386
|
return p
|
|
383
387
|
|
|
384
388
|
|
|
@@ -172,6 +172,7 @@ def build(skip_decks: bool = False) -> tuple[bool, str]:
|
|
|
172
172
|
DEMOLAB_ROOT pins the child to this server's ROOT (which may itself be an override —
|
|
173
173
|
`demolab dev --demo` serves a materialised scratch lab)."""
|
|
174
174
|
cmd = [sys.executable, "-m", "demolab_cli.build"]
|
|
175
|
+
cmd.append("--no-mirror")
|
|
175
176
|
if skip_decks:
|
|
176
177
|
cmd.append("--skip-decks")
|
|
177
178
|
try:
|
|
@@ -13,7 +13,7 @@ defined in [`GLOSSARY.md`](GLOSSARY.md).
|
|
|
13
13
|
|
|
14
14
|
**1.1 — Python via `uv`.** Never call `python` / `python3` directly. Deps are pinned in the root `pyproject.toml` / `uv.lock`; run scripts with `uv run python <script>` (e.g. `uv run python tools/neuron/tool.py lif`); `uv sync` after pulling.
|
|
15
15
|
|
|
16
|
-
**1.2 — Publishing via `typst`.** Use the `typst` CLI (an installed prerequisite, alongside `uv`). It compiles the site + PDFs (`demolab build` / `demolab dev`); the bundle build passes `--features bundle,html` (experimental, deliberately used here). No Node/`bun` — demolab publishes entirely with Typst.
|
|
16
|
+
**1.2 — Publishing via `typst`.** Use the `typst` CLI (an installed prerequisite, alongside `uv`). It compiles the site + PDFs (`demolab build` / `demolab dev`); the bundle build passes `--features bundle,html` (experimental, deliberately used here). Typst receives a deterministic creation timestamp (`SOURCE_DATE_EPOCH` overrides the engine default), so unchanged PDFs stay byte-identical within a stable toolchain. No Node/`bun` — demolab publishes entirely with Typst.
|
|
17
17
|
|
|
18
18
|
**1.3 — Prefer `demolab`.** Common commands are exposed through the `demolab` CLI — prefer `demolab <name>` (run `demolab` to list them). To check the toolchain *and* that the repo obeys these conventions, run the *Doctor the repo* runbook (*"doctor the repo"*).
|
|
19
19
|
|
|
@@ -77,6 +77,11 @@ The concrete annotated file tree is in [`STRUCTURE.md`](STRUCTURE.md); this sect
|
|
|
77
77
|
- **Per-entry PDFs** — `artifacts/site/pdfs/<id>.pdf`.
|
|
78
78
|
- **Book** — `artifacts/site/pdfs/book.pdf`: every entry, with a table of contents.
|
|
79
79
|
|
|
80
|
+
For a PDF-only editing loop, `demolab build <id>` updates just
|
|
81
|
+
`artifacts/pdfs/<id>.pdf`; it deliberately leaves the site and `book.pdf` untouched.
|
|
82
|
+
`demolab dev` refreshes the complete ignored preview site without mirroring preview PDFs into
|
|
83
|
+
the tracked publication directory. Run bare `demolab build` before publishing.
|
|
84
|
+
|
|
80
85
|
**5.3 — What's committed.** PDFs are mirrored to the committed, shareable `artifacts/pdfs/`. `artifacts/site/` is a gitignored build output (CI regenerates + deploys it to Pages). CI does **not** run the experiments, so `artifacts/data/` **must** be committed — that record, not the ephemeral `temp/`, is what reaches the site.
|
|
81
86
|
|
|
82
87
|
**5.4 — Numbers can't drift.** Each `writings/<id>.typ` reads its own bundle natively — `json("/artifacts/data/<id>/numbers.json")`, `#image("/artifacts/data/<id>/fig.png")` (compiled with `--root` at the repo root) — so the numbers and figures come straight from the run.
|
|
@@ -67,7 +67,7 @@ lives in the installed `demolab-cli` package (site-packages), reached via `demol
|
|
|
67
67
|
|
|
68
68
|
**S5 — The package vs your stuff.** The engine is the installed `demolab-cli` package — you never hand-edit it, and updating it is a dependency bump (§3.1). The gitignored `.demolab/` staging dir is the CLI's, not yours (§3.2). Everything else in the tree is yours: `tools/`, `experiments/`, `writings/`, `artifacts/`, `demolab.yaml`, and the root stubs `demolab init` laid down (§3.3).
|
|
69
69
|
|
|
70
|
-
**S6 — Where the build goes.** `demolab build` globs `writings/*.typ` into `temp/bundle/index.json`, stages the engine's `main.typ` beside it, and compiles it to three targets in one pass: the web site → `artifacts/site/`, per-entry PDFs + `book.pdf` → `artifacts/site/pdfs/` (mirrored to `artifacts/pdfs/`). On an empty (freshly-initialised) tree the build still succeeds — it emits a single `index.html` with a friendly empty state, and skips `all.html`/collection pages/`book.pdf`. CI deploys `artifacts/site/` to GitHub Pages (§5.2, §5.3).
|
|
70
|
+
**S6 — Where the build goes.** `demolab build` globs `writings/*.typ` into `temp/bundle/index.json`, stages the engine's `main.typ` beside it, and compiles it to three targets in one pass: the web site → `artifacts/site/`, per-entry PDFs + `book.pdf` → `artifacts/site/pdfs/` (mirrored to `artifacts/pdfs/`). `demolab build <id>` instead updates only `artifacts/pdfs/<id>.pdf`; `demolab dev` keeps preview PDFs in the ignored site tree and never mirrors them. On an empty (freshly-initialised) tree the complete build still succeeds — it emits a single `index.html` with a friendly empty state, and skips `all.html`/collection pages/`book.pdf`. CI deploys `artifacts/site/` to GitHub Pages (§5.2, §5.3).
|
|
71
71
|
|
|
72
72
|
## Scaffolding
|
|
73
73
|
|
|
@@ -36,6 +36,26 @@ updating the engine can't touch the user's identity — that's the point.
|
|
|
36
36
|
uv lock --upgrade-package demolab-cli && uv sync
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
`--upgrade-package demolab-cli` already implies uv's targeted
|
|
40
|
+
`--refresh-package demolab-cli`; do not clear uv's whole cache. After syncing, verify that the
|
|
41
|
+
project environment, not a globally cached or `uvx`-managed copy, is active:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
uv run demolab version
|
|
45
|
+
uv tree --locked | rg 'demolab-cli'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The versions must agree. If they do not, repair only this package and verify again:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
uv sync --reinstall-package demolab-cli
|
|
52
|
+
uv run demolab version
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Stop and report the mismatch if it persists; never paper over it with `uv cache clean`, and do
|
|
56
|
+
not use `uvx demolab-cli` to verify an existing lab because that is a separate ephemeral
|
|
57
|
+
environment.
|
|
58
|
+
|
|
39
59
|
4. **Rebuild.** `demolab build` — the CLI notices the version change, refreshes `.demolab/`,
|
|
40
60
|
and prints a one-line notice pointing at the changelog. `demolab test` for good measure.
|
|
41
61
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*.pdf binary
|
|
@@ -38,6 +38,12 @@ def test_dev_arguments():
|
|
|
38
38
|
assert bare_dev.port is None and bare_dev.demo is False and bare_dev.landing is False
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
def test_build_accepts_optional_entry():
|
|
42
|
+
parser = cli._build_parser()
|
|
43
|
+
assert parser.parse_args(["build"]).entry is None
|
|
44
|
+
assert parser.parse_args(["build", "exp007"]).entry == "exp007"
|
|
45
|
+
|
|
46
|
+
|
|
41
47
|
def test_demo_landing_passes_live_source_to_devserver(tmp_path, monkeypatch):
|
|
42
48
|
scaffold = tmp_path / "package-scaffold"
|
|
43
49
|
(scaffold / "skeleton").mkdir(parents=True)
|
|
@@ -7,6 +7,7 @@ HTTP request, no build) that an IPv4-only server gets wrong on Windows.
|
|
|
7
7
|
"""
|
|
8
8
|
import socket
|
|
9
9
|
import threading
|
|
10
|
+
from types import SimpleNamespace
|
|
10
11
|
|
|
11
12
|
from demolab_cli import devserver
|
|
12
13
|
|
|
@@ -84,6 +85,18 @@ def test_deck_affecting_triggers_on_slide_and_data():
|
|
|
84
85
|
assert not devserver.deck_affecting(set())
|
|
85
86
|
|
|
86
87
|
|
|
88
|
+
def test_dev_build_never_mirrors_preview_pdfs(monkeypatch):
|
|
89
|
+
captured = {}
|
|
90
|
+
|
|
91
|
+
def run(cmd, **kwargs):
|
|
92
|
+
captured["cmd"] = cmd
|
|
93
|
+
return SimpleNamespace(returncode=0, stdout="built\n", stderr="")
|
|
94
|
+
|
|
95
|
+
monkeypatch.setattr(devserver.subprocess, "run", run)
|
|
96
|
+
assert devserver.build() == (True, "built")
|
|
97
|
+
assert "--no-mirror" in captured["cmd"]
|
|
98
|
+
|
|
99
|
+
|
|
87
100
|
def test_sync_landing_source_copies_updates_and_removal(tmp_path):
|
|
88
101
|
source = tmp_path / "package" / "site" / "landing.typ"
|
|
89
102
|
target = tmp_path / "preview" / "landing.typ"
|
|
@@ -9,6 +9,7 @@ empty-state homepage rather than erroring.
|
|
|
9
9
|
|
|
10
10
|
Needs the `typst` CLI on PATH (same as `demolab build`); skipped if it's missing.
|
|
11
11
|
"""
|
|
12
|
+
import hashlib
|
|
12
13
|
import os
|
|
13
14
|
import re
|
|
14
15
|
import shutil
|
|
@@ -18,7 +19,7 @@ from pathlib import Path
|
|
|
18
19
|
|
|
19
20
|
import pytest
|
|
20
21
|
|
|
21
|
-
from demolab_cli import _paths
|
|
22
|
+
from demolab_cli import _paths, build
|
|
22
23
|
|
|
23
24
|
SCAFFOLD = _paths.SCAFFOLD
|
|
24
25
|
|
|
@@ -40,14 +41,44 @@ def _assemble(root: Path, *, demo: bool) -> None:
|
|
|
40
41
|
ignore=shutil.ignore_patterns("landing.typ", "temp", "site"))
|
|
41
42
|
|
|
42
43
|
|
|
43
|
-
def _build(root: Path) -> None:
|
|
44
|
+
def _build(root: Path, entry: str | None = None) -> None:
|
|
44
45
|
subprocess.run(
|
|
45
|
-
[sys.executable, "-m", "demolab_cli.build"],
|
|
46
|
+
[sys.executable, "-m", "demolab_cli.build", *([entry] if entry else [])],
|
|
46
47
|
env={**os.environ, "DEMOLAB_ROOT": str(root)},
|
|
47
48
|
check=True,
|
|
48
49
|
)
|
|
49
50
|
|
|
50
51
|
|
|
52
|
+
def _sha256(path: Path) -> str:
|
|
53
|
+
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_complete_build_is_pdf_reproducible(tmp_path: Path) -> None:
|
|
57
|
+
root = tmp_path / "repo"
|
|
58
|
+
root.mkdir()
|
|
59
|
+
_assemble(root, demo=True)
|
|
60
|
+
_build(root)
|
|
61
|
+
first = {p.name: _sha256(p) for p in (root / "artifacts" / "pdfs").glob("*.pdf")}
|
|
62
|
+
_build(root)
|
|
63
|
+
second = {p.name: _sha256(p) for p in (root / "artifacts" / "pdfs").glob("*.pdf")}
|
|
64
|
+
assert second == first
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_targeted_build_writes_only_selected_pdf(tmp_path: Path) -> None:
|
|
68
|
+
root = tmp_path / "repo"
|
|
69
|
+
root.mkdir()
|
|
70
|
+
_assemble(root, demo=True)
|
|
71
|
+
shutil.rmtree(root / "artifacts" / "pdfs", ignore_errors=True)
|
|
72
|
+
_build(root, "ar018")
|
|
73
|
+
assert sorted(p.name for p in (root / "artifacts" / "pdfs").glob("*.pdf")) == ["ar018.pdf"]
|
|
74
|
+
assert not (root / "artifacts" / "site").exists()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_source_date_epoch_overrides_default(tmp_path: Path, monkeypatch) -> None:
|
|
78
|
+
monkeypatch.setenv("SOURCE_DATE_EPOCH", "1234567890")
|
|
79
|
+
assert build.typst_compile("input.typ")[3] == "1234567890"
|
|
80
|
+
|
|
81
|
+
|
|
51
82
|
def test_demo_fixture_builds_full_site(tmp_path: Path) -> None:
|
|
52
83
|
root = tmp_path / "repo"
|
|
53
84
|
root.mkdir()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Standalone entry-PDF root used by `demolab build <id>`.
|
|
2
|
+
#import "/.demolab/lib.typ": *
|
|
3
|
+
|
|
4
|
+
#let entry-id = sys.inputs.entry
|
|
5
|
+
#let has-brand = sys.inputs.at("has-brand", default: "false") == "true"
|
|
6
|
+
#let config = if has-brand { yaml("/demolab.yaml") } else { (:) }
|
|
7
|
+
#let brand = default-brand + config
|
|
8
|
+
#import "/writings/" + entry-id + ".typ" as writing
|
|
9
|
+
|
|
10
|
+
#set document(title: writing.meta.title)
|
|
11
|
+
#numbered-pages(entry-page(writing.meta, writing.body, id: entry-id, brand: brand))
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.1.0
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/demo/artifacts/data/ar018/swe-bench.svg
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
|
|
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
|
|
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
|
|
File without changes
|
{demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/root/github/workflows/tests.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/artifacts/data/.gitkeep
RENAMED
|
File without changes
|
{demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/artifacts/pdfs/.gitkeep
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/skeleton/experiments/helpers/style.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/starters/monte-carlo-pi/README.md
RENAMED
|
File without changes
|
{demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/starters/monte-carlo-pi/exp000.py
RENAMED
|
File without changes
|
{demolab_cli-2.1.0 → demolab_cli-2.2.0}/demolab_cli/scaffold/starters/monte-carlo-pi/exp000.typ
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
|