calkit-python 0.41.14__tar.gz → 0.41.15__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.
- {calkit_python-0.41.14 → calkit_python-0.41.15}/AGENTS.md +3 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/PKG-INFO +1 -1
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/check.py +5 -2
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/main/core.py +14 -1
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/new.py +1 -1
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/notebooks.py +17 -10
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/update.py +1 -1
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/core.py +7 -3
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/julia.py +29 -2
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/notebooks.py +1 -3
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/pipeline.py +32 -8
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_core.py +15 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_julia.py +46 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_pipeline.py +49 -0
- calkit_python-0.41.15/vscode-ext/README.md +148 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/package.json +47 -4
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/src/extension.ts +272 -494
- calkit_python-0.41.15/vscode-ext/src/figures/core.ts +93 -0
- calkit_python-0.41.15/vscode-ext/src/figures/view.ts +474 -0
- calkit_python-0.41.15/vscode-ext/src/pipeline/core.ts +81 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/src/sidebar.ts +244 -78
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/src/test/figures.test.ts +41 -1
- calkit_python-0.41.15/vscode-ext/src/test/pipeline.test.ts +61 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/src/types.ts +30 -1
- calkit_python-0.41.14/vscode-ext/README.md +0 -66
- calkit_python-0.41.14/vscode-ext/src/figures.ts +0 -40
- {calkit_python-0.41.14 → calkit_python-0.41.15}/.claude-plugin/marketplace.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/.gitattributes +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/.gitignore +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/.pre-commit-config.yaml +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/.prettierignore +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/.python-version +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/.vscode/launch.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/.vscode/tasks.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/.yarnrc.yml +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/CITATION.cff +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/CODE_OF_CONDUCT.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/CONTRIBUTING.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/LICENSE +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/Makefile +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/README.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/agent-plugin/.claude-plugin/plugin.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/agent-plugin/skills/add-pipeline-stage/SKILL.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/agent-plugin/skills/conventions/SKILL.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/agent-plugin/skills/create-pipeline/SKILL.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/babel.config.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/__main__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/calc.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/check.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/cloud.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/config.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/core.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/delete.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/describe.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/dev.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/import_.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/latex.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/list.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/main/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/main/xr.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/office.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/overleaf.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cli/scheduler.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/cloud.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/conda.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/config.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/datasets.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/dependencies.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/detect.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/docker.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/dvc/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/dvc/core.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/dvc/zip.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/environments.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/fs.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/git.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/github.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/gui.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/install.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/invenio.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/jupyter.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/jupyterlab/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/jupyterlab/routes.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/package.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/schemas/calkit/package.json.orig +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/schemas/calkit/plugin.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/909.e3f9cc3408834a7fdcc3.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/remoteEntry.65469af996e7a96aa983.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/style.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/labextension/static/third-party-licenses.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/licenses.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/magics.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/matlab.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/models/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/models/core.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/models/io.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/models/iteration.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/models/pipeline.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/office.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/ops.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/overleaf.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/releases.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/server.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/core.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/main/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/main/test_core.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/main/test_lock.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/main/test_subprojects.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/main/test_xr.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_check.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_cloud.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_config.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_delete.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_import.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_latex.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_new.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_notebooks.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_overleaf.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_scheduler.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/cli/test_update.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/dvc/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/dvc/test_core.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/dvc/test_zip.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/jupyterlab/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/jupyterlab/test_routes.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/models/__init__.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/models/test_core.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/models/test_iteration.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/models/test_pipeline.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_check.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_cloud.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_conda.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_dependencies.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_detect.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_docker.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_environments.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_fs.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_git.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_install.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_invenio.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_licenses.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_matlab.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_notebooks.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_releases.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/conftest.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/CNAME +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/ai-tools.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/apps.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/calculations.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/calkit-yaml.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/cli-reference.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/cloud-integration.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/datasets.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/dependencies.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/environments.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/examples.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/governance.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/help.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/hpc.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/c-to-the-k-white.svg +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/calkit-fragmentation-compendium.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/calkit-no-bg.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/connect-zenodo.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/jupyterlab/all-green.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/jupyterlab/collect-data-stale.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/jupyterlab/new-env.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/jupyterlab/new-notebook.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/jupyterlab/pipeline-badge.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/jupyterlab-params.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/plos-osi-code-2024-03.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/img/vscode-nb-params.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/index.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/installation.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/jupyterlab.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/local-server.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/notebooks.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/overleaf.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/pipeline/index.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/pipeline/manual-steps.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/pipeline/running-and-logging.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/quickstart.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/references.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/releases.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/reproducibility.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/subprojects.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/ai-agents.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/existing-project.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/first-project.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/github-actions.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/actions-repo-secrets.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/push.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/chart-more-rows.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/create-project.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/excel-chart.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/excel-data.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/needs-clone.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/new-stage.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/status-more-rows.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/untracked-data.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/updated-publication.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/office/workflow-page.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/clone.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/create-project.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/new-token.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/reclone.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/quick-actions.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/create-calkit-env.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/create-inner-env.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/create-new-calkit-env.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/select-calkit-env.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/slurm-job-running.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/slurm-launch-options.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/starting-slurm-job.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/index.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/jupyterlab.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/latex-codespaces.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/matlab.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/notebook-pipeline.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/office.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/openfoam.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/tutorials/vscode-slurm-notebook.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/docs/version-control.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/flake.lock +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/flake.nix +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/install.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/jest.config.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/jupyter-config/server-config/calkit.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/mkdocs.yml +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/package.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/pyproject.toml +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/schema/plugin.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/scripts/generate-docs-references.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/scripts/install.ps1 +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/scripts/install.sh +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/scripts/make-calk9.sh +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/scripts/sync-docs.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/__tests__/useQueries.spec.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/calkit-config.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/cell-output-marker.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/components/commit-dialog.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/components/environment-editor.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/components/notebook-registration.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/components/notebook-toolbar.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/components/pipeline-status-bar.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/components/project-info-editor.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/components/sidebar-settings.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/components/sidebar.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/components/stage-editor.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/feature-flags.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/file-browser-menu.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/hooks/__tests__/useQueries.test.tsx +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/hooks/useQueries.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/icons.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/index.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/io-tracker.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/pipeline-state.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/queryClient.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/request.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/src/shims-mainmenu.d.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/base.css +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/cell-output-marker.css +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/environment-editor.css +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/environment-selector.css +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/img/calkit-no-bg.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/index.css +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/index.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/notebook-toolbar.css +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/pipeline-status-bar.css +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/style/sidebar.css +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/test/dvc-md5-dir/osx-arm64.txt +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/test/nb-julia.ipynb +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/test/nb-params.ipynb +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/test/nb-subdir.ipynb +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/test/pipeline.ipynb +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/test/script.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/test/test-log.log +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/tsconfig.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/tsconfig.test.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/ui-tests/.gitignore +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/ui-tests/README.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/ui-tests/jupyter_server_test_config.py +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/ui-tests/package.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/ui-tests/playwright.config.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/ui-tests/tests/calkit.spec.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/ui-tests/yarn.lock +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/uv.lock +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/.gitignore +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/.vscodeignore +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/CHANGELOG.md +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/LICENSE +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/images/calkit-icon.svg +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/images/calkit-no-bg.png +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/package-lock.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/scripts/set-proposed-api.js +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/src/environments.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/src/notebooks.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/src/test/environments.test.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/src/test/kernel-selection.test.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/src/test/notebooks.test.ts +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/vscode-ext/tsconfig.json +0 -0
- {calkit_python-0.41.14 → calkit_python-0.41.15}/yarn.lock +0 -0
|
@@ -43,3 +43,6 @@ The only exception here is if splitting up a function makes it easier to
|
|
|
43
43
|
write meaningful unit tests.
|
|
44
44
|
If a function is only used inside one other function, nest it inside the
|
|
45
45
|
caller at the top.
|
|
46
|
+
|
|
47
|
+
No spaces on either side of en or em dashes used for ranges or pauses in prose,
|
|
48
|
+
respectively.
|
|
@@ -180,7 +180,8 @@ def _check_julia_env(
|
|
|
180
180
|
try:
|
|
181
181
|
subprocess.check_call(
|
|
182
182
|
cmd,
|
|
183
|
-
env=os.environ.copy()
|
|
183
|
+
env=os.environ.copy()
|
|
184
|
+
| {"JULIA_LOAD_PATH": calkit.julia.load_path()},
|
|
184
185
|
)
|
|
185
186
|
except subprocess.CalledProcessError:
|
|
186
187
|
calkit.environments.save_cache(
|
|
@@ -206,7 +207,9 @@ def _check_julia_env(
|
|
|
206
207
|
cmd = calkit.julia.ensure_startup_file_disabled_in_command(cmd)
|
|
207
208
|
try:
|
|
208
209
|
subprocess.check_call(
|
|
209
|
-
cmd,
|
|
210
|
+
cmd,
|
|
211
|
+
env=os.environ.copy()
|
|
212
|
+
| {"JULIA_LOAD_PATH": calkit.julia.load_path()},
|
|
210
213
|
)
|
|
211
214
|
except subprocess.CalledProcessError:
|
|
212
215
|
calkit.environments.save_cache(
|
|
@@ -581,6 +581,18 @@ def get_status(
|
|
|
581
581
|
if pipeline_status and not pipeline_status.has_pipeline:
|
|
582
582
|
typer.echo("This project has no pipeline.")
|
|
583
583
|
return
|
|
584
|
+
# A failed environment check makes get_status bail out before computing
|
|
585
|
+
# staleness, leaving stale_stages empty. Don't let that masquerade as an
|
|
586
|
+
# up-to-date pipeline---say plainly that the status is unknown.
|
|
587
|
+
elif pipeline_status and pipeline_status.failed_environment_checks:
|
|
588
|
+
# The failing environments were already named in the warning emitted
|
|
589
|
+
# right after computing pipeline_status, so keep this explanatory
|
|
590
|
+
# only rather than repeating the list.
|
|
591
|
+
typer.echo(
|
|
592
|
+
"Pipeline status unavailable until the failed environment "
|
|
593
|
+
"checks above are resolved."
|
|
594
|
+
)
|
|
595
|
+
return
|
|
584
596
|
elif pipeline_status and pipeline_status.is_stale:
|
|
585
597
|
typer.echo("Stale stages:")
|
|
586
598
|
for stage_name in pipeline_status.stale_stage_names:
|
|
@@ -2586,7 +2598,8 @@ def run_in_env(
|
|
|
2586
2598
|
subprocess.check_call(
|
|
2587
2599
|
julia_cmd,
|
|
2588
2600
|
cwd=wdir,
|
|
2589
|
-
env=os.environ.copy()
|
|
2601
|
+
env=os.environ.copy()
|
|
2602
|
+
| {"JULIA_LOAD_PATH": calkit.julia.load_path()},
|
|
2590
2603
|
)
|
|
2591
2604
|
except subprocess.CalledProcessError:
|
|
2592
2605
|
raise_error("Failed to run in julia environment")
|
|
@@ -2108,7 +2108,7 @@ def new_julia_env(
|
|
|
2108
2108
|
except subprocess.CalledProcessError:
|
|
2109
2109
|
raise_error(f"Failed to install Julia version {julia_version}")
|
|
2110
2110
|
cmd = ["julia", f"+{julia_version}", f"--project={env_dir}", "-e"]
|
|
2111
|
-
install_cmd = f'using Pkg; Pkg.activate("{env_dir}");'
|
|
2111
|
+
install_cmd = f'using Pkg; Pkg.activate("{calkit.julia.escape_string(env_dir)}");'
|
|
2112
2112
|
for package in packages or []:
|
|
2113
2113
|
install_cmd += f' Pkg.add("{package}");'
|
|
2114
2114
|
cmd.append(install_cmd)
|
|
@@ -310,14 +310,18 @@ def check_env_kernel(
|
|
|
310
310
|
"still failed."
|
|
311
311
|
)
|
|
312
312
|
# Don't include version in display_name; IJulia appends it automatically
|
|
313
|
+
# Escape interpolated values for the Julia string literals---notably the
|
|
314
|
+
# Windows project path, whose backslashes are otherwise read as invalid
|
|
315
|
+
# unicode escapes.
|
|
316
|
+
esc = calkit.julia.escape_string
|
|
313
317
|
julia_cmd = (
|
|
314
318
|
"import IJulia;"
|
|
315
319
|
"kp=IJulia.installkernel("
|
|
316
|
-
f'"{kernel_name}",'
|
|
317
|
-
f'"--project={env_dir_abs}",'
|
|
320
|
+
f'"{esc(kernel_name)}",'
|
|
321
|
+
f'"--project={esc(env_dir_abs)}",'
|
|
318
322
|
'"--startup-file=no",'
|
|
319
|
-
f'displayname="{display_name}",'
|
|
320
|
-
'env=Dict("JULIA_LOAD_PATH" => "
|
|
323
|
+
f'displayname="{esc(display_name)}",'
|
|
324
|
+
f'env=Dict("JULIA_LOAD_PATH" => "{esc(calkit.julia.load_path())}")'
|
|
321
325
|
");"
|
|
322
326
|
"println(kp);"
|
|
323
327
|
)
|
|
@@ -474,8 +478,7 @@ def execute_notebook(
|
|
|
474
478
|
# Create this environment and write it to file
|
|
475
479
|
envs[res.name] = res.env
|
|
476
480
|
ck_info["environments"] = envs
|
|
477
|
-
|
|
478
|
-
calkit.ryaml.dump(ck_info, f)
|
|
481
|
+
calkit.save_calkit_info(ck_info)
|
|
479
482
|
# Detect language from environment
|
|
480
483
|
if language is None:
|
|
481
484
|
detected_language = language_from_notebook(path)
|
|
@@ -501,16 +504,20 @@ def execute_notebook(
|
|
|
501
504
|
raise ValueError(
|
|
502
505
|
"Language must be one of 'python', 'matlab', 'julia', or 'r'"
|
|
503
506
|
)
|
|
504
|
-
# Try to set kernelspec metadata so execution uses the expected kernel
|
|
507
|
+
# Try to set kernelspec metadata so execution uses the expected kernel.
|
|
508
|
+
# Always read/write as UTF-8: notebooks routinely contain non-ASCII (e.g.,
|
|
509
|
+
# Greek letters such as "ν" in code), and on Windows the default open()
|
|
510
|
+
# encoding is cp1252, which mangles UTF-8 content into mojibake ("ν" ->
|
|
511
|
+
# "ν") and breaks execution.
|
|
505
512
|
try:
|
|
506
|
-
with open(path, "r") as f:
|
|
513
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
507
514
|
nb_json = json.load(f)
|
|
508
515
|
metadata = nb_json.setdefault("metadata", {})
|
|
509
516
|
kernelspec = metadata.setdefault("kernelspec", {})
|
|
510
517
|
kernelspec["name"] = kernel_name
|
|
511
518
|
kernelspec["display_name"] = display_name
|
|
512
|
-
kernelspec
|
|
513
|
-
with open(path, "w") as f:
|
|
519
|
+
kernelspec["language"] = language.lower()
|
|
520
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
514
521
|
json.dump(nb_json, f, indent=1)
|
|
515
522
|
except Exception as e:
|
|
516
523
|
if verbose:
|
|
@@ -746,7 +746,7 @@ def update_julia_env(
|
|
|
746
746
|
env_dir = os.path.dirname(spec_path) or "."
|
|
747
747
|
julia_version = env.get("julia")
|
|
748
748
|
julia_bin = ["julia", f"+{julia_version}"] if julia_version else ["julia"]
|
|
749
|
-
cmds = [f'Pkg.activate("{env_dir}")']
|
|
749
|
+
cmds = [f'Pkg.activate("{calkit.julia.escape_string(env_dir)}")']
|
|
750
750
|
if add:
|
|
751
751
|
pkg_list = "[" + ", ".join(f'"{p}"' for p in add) + "]"
|
|
752
752
|
cmds.append(f"Pkg.add({pkg_list})")
|
|
@@ -144,7 +144,9 @@ def load_calkit_info(
|
|
|
144
144
|
if wdir is not None:
|
|
145
145
|
fpath = os.path.join(wdir, fpath)
|
|
146
146
|
if os.path.isfile(fpath):
|
|
147
|
-
|
|
147
|
+
# Always read as UTF-8; on Windows the default open() encoding is
|
|
148
|
+
# cp1252, which mangles non-ASCII content (e.g., Greek letters).
|
|
149
|
+
with open(fpath, encoding="utf-8") as f:
|
|
148
150
|
info = ryaml.load(f)
|
|
149
151
|
if info is None:
|
|
150
152
|
info = {}
|
|
@@ -166,7 +168,7 @@ def load_calkit_info(
|
|
|
166
168
|
if wdir is not None:
|
|
167
169
|
include_fpath = os.path.join(wdir, include_fpath)
|
|
168
170
|
if os.path.isfile(include_fpath):
|
|
169
|
-
with open(include_fpath) as f:
|
|
171
|
+
with open(include_fpath, encoding="utf-8") as f:
|
|
170
172
|
include_data = ryaml.load(f)
|
|
171
173
|
info[kind][obj_name] |= include_data
|
|
172
174
|
return info
|
|
@@ -180,7 +182,9 @@ def save_calkit_info(
|
|
|
180
182
|
fpath = "calkit.yaml"
|
|
181
183
|
if wdir is not None:
|
|
182
184
|
fpath = os.path.join(wdir, fpath)
|
|
183
|
-
|
|
185
|
+
# Always write as UTF-8; on Windows the default open() encoding is cp1252,
|
|
186
|
+
# which mangles non-ASCII content (e.g., Greek letters) into mojibake.
|
|
187
|
+
with open(fpath, "w", encoding="utf-8") as f:
|
|
184
188
|
ryaml.dump(info, f)
|
|
185
189
|
|
|
186
190
|
|
|
@@ -27,9 +27,36 @@ def get_julia_exe() -> str:
|
|
|
27
27
|
return "julia"
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
def load_path() -> str:
|
|
31
|
+
"""Return the ``JULIA_LOAD_PATH`` scoping resolution to the active project
|
|
32
|
+
and stdlib.
|
|
33
|
+
|
|
34
|
+
Julia splits ``JULIA_LOAD_PATH`` on the platform path separator---``;`` on
|
|
35
|
+
Windows and ``:`` elsewhere---so a hardcoded ``:`` leaves ``@stdlib`` off
|
|
36
|
+
the load path on Windows and even stdlib packages (e.g. ``Pkg``) fail to
|
|
37
|
+
resolve. ``os.pathsep`` matches Julia's rule on every platform.
|
|
38
|
+
"""
|
|
39
|
+
return os.pathsep.join(["@", "@stdlib"])
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def escape_string(value: str) -> str:
|
|
43
|
+
"""Escape ``value`` for embedding in a Julia double-quoted string literal.
|
|
44
|
+
|
|
45
|
+
Julia treats ``\\``, ``"`` and ``$`` specially inside double quotes. In
|
|
46
|
+
particular a Windows path like ``C:\\Users\\...`` is otherwise read as an
|
|
47
|
+
invalid ``\\U`` unicode escape, so any value interpolated into Julia source
|
|
48
|
+
(e.g., a ``--project`` path passed via ``julia -e``) must be escaped.
|
|
49
|
+
"""
|
|
50
|
+
return value.replace("\\", "\\\\").replace('"', '\\"').replace("$", "\\$")
|
|
51
|
+
|
|
52
|
+
|
|
30
53
|
def _is_julia_command(arg: str) -> bool:
|
|
31
|
-
"""Whether ``arg`` is a Julia executable (julia or the juliaup launcher).
|
|
32
|
-
|
|
54
|
+
"""Whether ``arg`` is a Julia executable (julia or the juliaup launcher).
|
|
55
|
+
|
|
56
|
+
The comparison is case-insensitive so Windows paths like ``julia.EXE``
|
|
57
|
+
(e.g. the ``WindowsApps`` execution-alias shim) are recognized.
|
|
58
|
+
"""
|
|
59
|
+
base = os.path.basename(arg).lower()
|
|
33
60
|
if base.endswith(".exe"):
|
|
34
61
|
base = base[: -len(".exe")]
|
|
35
62
|
return base in ("julia", "julialauncher")
|
|
@@ -242,11 +242,9 @@ def declare_notebook(
|
|
|
242
242
|
}
|
|
243
243
|
)
|
|
244
244
|
# Write calkit.yaml
|
|
245
|
-
fpath = os.path.join(wdir, "calkit.yaml")
|
|
246
245
|
ck_info["pipeline"] = pipeline_dict
|
|
247
246
|
ck_info["notebooks"] = notebooks
|
|
248
|
-
|
|
249
|
-
calkit.ryaml.dump(ck_info, f)
|
|
247
|
+
calkit.save_calkit_info(ck_info, wdir=wdir)
|
|
250
248
|
if must_be_rerun:
|
|
251
249
|
raise RuntimeError(
|
|
252
250
|
f"Notebook stage '{stage_name}' was modified while the pipeline "
|
|
@@ -1011,6 +1011,35 @@ def get_output_storage_map(
|
|
|
1011
1011
|
return result
|
|
1012
1012
|
|
|
1013
1013
|
|
|
1014
|
+
def _dump_yaml_if_changed(data, fpath: str, verbose: bool = False) -> bool:
|
|
1015
|
+
"""Write ``data`` to ``fpath`` as YAML only if it changes the file.
|
|
1016
|
+
|
|
1017
|
+
``calkit status`` recompiles the pipeline to DVC on every call, and the VS
|
|
1018
|
+
Code extension polls status continuously. Blindly rewriting an identical
|
|
1019
|
+
file causes two problems: (1) bumping ``dvc.yaml``'s mtime wakes the
|
|
1020
|
+
extension's file watcher, which triggers yet another status poll---an
|
|
1021
|
+
endless loop that keeps re-taking DVC's lock; and (2) the serializer formats
|
|
1022
|
+
slightly differently across platforms and ruamel versions, so the file
|
|
1023
|
+
churns in Git for no real change. Comparison is on the parsed structure, so
|
|
1024
|
+
trivial reformatting is not treated as a change. DVC keys stage staleness on
|
|
1025
|
+
``dvc.lock`` (not on ``dvc.yaml``'s mtime), so skipping a no-op write is
|
|
1026
|
+
safe. Returns whether the file was written.
|
|
1027
|
+
"""
|
|
1028
|
+
if os.path.isfile(fpath):
|
|
1029
|
+
try:
|
|
1030
|
+
with open(fpath) as f:
|
|
1031
|
+
if (calkit.ryaml.load(f) or {}) == data:
|
|
1032
|
+
return False
|
|
1033
|
+
except Exception:
|
|
1034
|
+
# Unreadable or invalid existing YAML: fall through and overwrite.
|
|
1035
|
+
pass
|
|
1036
|
+
if verbose:
|
|
1037
|
+
typer.echo(f"Writing to {os.path.basename(fpath)}")
|
|
1038
|
+
with open(fpath, "w") as f:
|
|
1039
|
+
calkit.ryaml.dump(data, f)
|
|
1040
|
+
return True
|
|
1041
|
+
|
|
1042
|
+
|
|
1014
1043
|
def to_dvc(
|
|
1015
1044
|
ck_info: dict | None = None,
|
|
1016
1045
|
wdir: str | None = None,
|
|
@@ -1099,8 +1128,7 @@ def to_dvc(
|
|
|
1099
1128
|
with open(dvc_yaml_fpath) as f:
|
|
1100
1129
|
existing = calkit.ryaml.load(f) or {}
|
|
1101
1130
|
existing.setdefault("stages", {}).update(wrapper_stages)
|
|
1102
|
-
|
|
1103
|
-
calkit.ryaml.dump(existing, f)
|
|
1131
|
+
_dump_yaml_if_changed(existing, dvc_yaml_fpath)
|
|
1104
1132
|
return wrapper_stages
|
|
1105
1133
|
# Detect stages with the old ``slurm:`` field before model validation
|
|
1106
1134
|
# because model_validate pops it in place.
|
|
@@ -1194,8 +1222,7 @@ def to_dvc(
|
|
|
1194
1222
|
for sname in slurm_field_stages:
|
|
1195
1223
|
stage_data = ck_yaml_data["pipeline"]["stages"][sname]
|
|
1196
1224
|
stage_data["scheduler"] = stage_data.pop("slurm")
|
|
1197
|
-
|
|
1198
|
-
calkit.ryaml.dump(ck_yaml_data, _f)
|
|
1225
|
+
_dump_yaml_if_changed(ck_yaml_data, ck_yaml_path)
|
|
1199
1226
|
# Validate and initialize scheduler options (SLURM/PBS) for stages
|
|
1200
1227
|
# whose outer environment is a job scheduler. Env defaults are applied
|
|
1201
1228
|
# at job-submission time, not here.
|
|
@@ -1372,10 +1399,7 @@ def to_dvc(
|
|
|
1372
1399
|
dvc_stages[stage_name] = stage
|
|
1373
1400
|
dvc_yaml["stages"] = dvc_stages
|
|
1374
1401
|
dvc_yaml_fpath = os.path.join(wdir, "dvc.yaml") if wdir else "dvc.yaml"
|
|
1375
|
-
|
|
1376
|
-
if verbose:
|
|
1377
|
-
typer.echo("Writing to dvc.yaml")
|
|
1378
|
-
calkit.ryaml.dump(dvc_yaml, f)
|
|
1402
|
+
_dump_yaml_if_changed(dvc_yaml, dvc_yaml_fpath, verbose=verbose)
|
|
1379
1403
|
# DVC errors out (FileIsGitIgnored) if dvc.lock is Git-ignored, so make
|
|
1380
1404
|
# sure it isn't---this keeps both status and pipeline runs working
|
|
1381
1405
|
calkit.dvc.ensure_dvc_lock_not_ignored(wdir)
|
|
@@ -43,6 +43,21 @@ def test_detect_project_name(tmp_dir):
|
|
|
43
43
|
assert calkit.detect_project_name() == "someone-else/some-project"
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
def test_save_calkit_info_preserves_unicode(tmp_dir):
|
|
47
|
+
# Regression: on Windows, opening calkit.yaml without encoding="utf-8"
|
|
48
|
+
# writes as cp1252, which either errors or corrupts non-ASCII content
|
|
49
|
+
# (e.g., the Greek letter "ν") into mojibake ("ν"). ruamel dumps raw
|
|
50
|
+
# unicode (allow_unicode=True), so the encoding of the file handle matters.
|
|
51
|
+
info = {"name": "p", "owner": "o", "title": "viscosity ν"}
|
|
52
|
+
calkit.save_calkit_info(info)
|
|
53
|
+
# The value must survive the round-trip intact.
|
|
54
|
+
assert calkit.load_calkit_info()["title"] == "viscosity ν"
|
|
55
|
+
# Raw bytes must be the UTF-8 encoding of "ν", not cp1252 mojibake.
|
|
56
|
+
raw = open("calkit.yaml", "rb").read()
|
|
57
|
+
assert "ν".encode("utf-8") in raw
|
|
58
|
+
assert "ν".encode("utf-8") not in raw
|
|
59
|
+
|
|
60
|
+
|
|
46
61
|
def test_load_calkit_info(tmp_dir, monkeypatch):
|
|
47
62
|
subpath = "some/project"
|
|
48
63
|
os.makedirs(subpath)
|
|
@@ -1,16 +1,40 @@
|
|
|
1
1
|
"""Tests for ``calkit.julia``"""
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
from unittest import mock
|
|
4
5
|
|
|
5
6
|
import pytest
|
|
6
7
|
|
|
7
8
|
from calkit.julia import (
|
|
9
|
+
_is_julia_command,
|
|
8
10
|
check_version_in_command,
|
|
9
11
|
ensure_startup_file_disabled_in_command,
|
|
12
|
+
escape_string,
|
|
10
13
|
get_julia_exe,
|
|
14
|
+
load_path,
|
|
11
15
|
)
|
|
12
16
|
|
|
13
17
|
|
|
18
|
+
def test_escape_string_windows_path():
|
|
19
|
+
# A Windows path embedded in a Julia string literal must have its
|
|
20
|
+
# backslashes escaped, otherwise "C:\\Users" is read as an invalid \\U
|
|
21
|
+
# unicode escape (ParseError).
|
|
22
|
+
assert escape_string("C:\\Users\\peteb") == "C:\\\\Users\\\\peteb"
|
|
23
|
+
# Double quotes and dollar signs are the other special characters.
|
|
24
|
+
assert escape_string('a"b') == 'a\\"b'
|
|
25
|
+
assert escape_string("a$b") == "a\\$b"
|
|
26
|
+
# Plain values (e.g. the load path) are unchanged.
|
|
27
|
+
assert escape_string("@;@stdlib") == "@;@stdlib"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_load_path_uses_platform_separator():
|
|
31
|
+
# Julia splits JULIA_LOAD_PATH on the platform path separator, so the
|
|
32
|
+
# value must use ';' on Windows and ':' elsewhere (== os.pathsep).
|
|
33
|
+
assert load_path() == f"@{os.pathsep}@stdlib"
|
|
34
|
+
assert "@" in load_path()
|
|
35
|
+
assert "@stdlib" in load_path()
|
|
36
|
+
|
|
37
|
+
|
|
14
38
|
def test_get_julia_exe(monkeypatch, tmp_path):
|
|
15
39
|
# Prefer julia on the PATH when present
|
|
16
40
|
def which_julia(name):
|
|
@@ -44,6 +68,28 @@ def test_get_julia_exe(monkeypatch, tmp_path):
|
|
|
44
68
|
assert get_julia_exe() == "julia"
|
|
45
69
|
|
|
46
70
|
|
|
71
|
+
def test_is_julia_command_case_insensitive():
|
|
72
|
+
# Windows resolves the execution-alias shim to an uppercase extension
|
|
73
|
+
# (e.g. ``julia.EXE``); the check must still recognize it.
|
|
74
|
+
assert _is_julia_command("C:/x/julia.EXE")
|
|
75
|
+
assert _is_julia_command("C:/x/Julia.Exe")
|
|
76
|
+
assert _is_julia_command("C:/x/julialauncher.EXE")
|
|
77
|
+
assert _is_julia_command("/usr/bin/julia")
|
|
78
|
+
assert _is_julia_command("julialauncher")
|
|
79
|
+
assert not _is_julia_command("python")
|
|
80
|
+
assert not _is_julia_command("C:/x/python.exe")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_disable_startup_file_accepts_uppercase_exe():
|
|
84
|
+
# Regression: julia.EXE (Windows execution alias) was rejected as not a
|
|
85
|
+
# Julia command, failing the env check and masking real pipeline status.
|
|
86
|
+
cmd = ensure_startup_file_disabled_in_command(
|
|
87
|
+
["C:/x/julia.EXE", "--version"]
|
|
88
|
+
)
|
|
89
|
+
assert cmd[0] == "C:/x/julia.EXE"
|
|
90
|
+
assert "--startup-file=no" in cmd
|
|
91
|
+
|
|
92
|
+
|
|
47
93
|
def test_check_version_in_command():
|
|
48
94
|
cmd = ["julia", "+1.11", "--project", "whatever"]
|
|
49
95
|
# Case 1: juliaup is available
|
|
@@ -521,6 +521,55 @@ def test_to_dvc_unignores_dvc_lock(tmp_dir):
|
|
|
521
521
|
assert not repo.ignored("dvc.lock")
|
|
522
522
|
|
|
523
523
|
|
|
524
|
+
def test_to_dvc_skips_no_op_writes(tmp_dir):
|
|
525
|
+
# Compiling to DVC happens on every `calkit status` (which the VS Code
|
|
526
|
+
# extension polls continuously). Rewriting an unchanged dvc.yaml churns Git
|
|
527
|
+
# across platforms (trivial reformatting) and wakes the extension's dvc.yaml
|
|
528
|
+
# watcher into another status poll, an endless loop that keeps re-taking
|
|
529
|
+
# DVC's lock. The write must be skipped unless the parsed content changes.
|
|
530
|
+
subprocess.check_call(["calkit", "init"])
|
|
531
|
+
ck_info = {
|
|
532
|
+
"pipeline": {
|
|
533
|
+
"stages": {
|
|
534
|
+
"s1": {
|
|
535
|
+
"kind": "command",
|
|
536
|
+
"environment": "_system",
|
|
537
|
+
"command": "echo a > a.txt",
|
|
538
|
+
"outputs": ["a.txt"],
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
}
|
|
543
|
+
with open("calkit.yaml", "w") as f:
|
|
544
|
+
calkit.ryaml.dump(ck_info, f)
|
|
545
|
+
# First compile creates dvc.yaml.
|
|
546
|
+
calkit.pipeline.to_dvc(ck_info=ck_info, write=True)
|
|
547
|
+
assert os.path.isfile("dvc.yaml")
|
|
548
|
+
# Pin an old mtime; a no-op recompile of identical content must leave it.
|
|
549
|
+
pinned = 1000000000.0
|
|
550
|
+
os.utime("dvc.yaml", (pinned, pinned))
|
|
551
|
+
calkit.pipeline.to_dvc(ck_info=ck_info, write=True)
|
|
552
|
+
assert os.path.getmtime("dvc.yaml") == pinned
|
|
553
|
+
# A semantically-equal but reformatted/commented file is also left as-is, so
|
|
554
|
+
# trivial cross-platform reformatting doesn't churn the file in Git.
|
|
555
|
+
with open("dvc.yaml") as f:
|
|
556
|
+
original = f.read()
|
|
557
|
+
with open("dvc.yaml", "w") as f:
|
|
558
|
+
f.write("# hand-written comment\n" + original)
|
|
559
|
+
with open("dvc.yaml") as f:
|
|
560
|
+
reformatted = f.read()
|
|
561
|
+
os.utime("dvc.yaml", (pinned, pinned))
|
|
562
|
+
calkit.pipeline.to_dvc(ck_info=ck_info, write=True)
|
|
563
|
+
with open("dvc.yaml") as f:
|
|
564
|
+
assert f.read() == reformatted
|
|
565
|
+
assert os.path.getmtime("dvc.yaml") == pinned
|
|
566
|
+
# A real change, though, is written.
|
|
567
|
+
ck_info["pipeline"]["stages"]["s1"]["command"] = "echo b > a.txt"
|
|
568
|
+
calkit.pipeline.to_dvc(ck_info=ck_info, write=True)
|
|
569
|
+
with open("dvc.yaml") as f:
|
|
570
|
+
assert f.read() != reformatted
|
|
571
|
+
|
|
572
|
+
|
|
524
573
|
def test_sbatch_stage_to_dvc(tmp_dir):
|
|
525
574
|
"""Cover the SLURM stage compilation paths.
|
|
526
575
|
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Calkit for VS Code
|
|
2
|
+
|
|
3
|
+
Turn a research or analytical project into a navigable, reproducible
|
|
4
|
+
system.
|
|
5
|
+
|
|
6
|
+
Most projects where the output artifacts (figures, datasets, results,
|
|
7
|
+
papers, presentations) are what matter accumulate a tangle of scripts,
|
|
8
|
+
notebooks, environments, and data. Calkit gives that tangle a structure: every
|
|
9
|
+
artifact is traceable to the pipeline stage that produced it, every stage to its
|
|
10
|
+
code and environment. This extension is the integration layer on top—it
|
|
11
|
+
surfaces the whole system in one place, lets you traverse between layers
|
|
12
|
+
(artifact → stage → environment → source), and lets you make changes at any
|
|
13
|
+
layer and re-run to keep everything in sync.
|
|
14
|
+
|
|
15
|
+
## The Calkit sidebar: a holistic view of the project
|
|
16
|
+
|
|
17
|
+
The **Calkit** activity-bar view presents the project as connected sections:
|
|
18
|
+
|
|
19
|
+
- **Questions**: The research questions the project sets out to answer.
|
|
20
|
+
- **Environments**: Every computational environment (uv, Pixi, venv, conda,
|
|
21
|
+
renv, Docker, Julia, MATLAB, SSH, SLURM/PBS, and nested combinations).
|
|
22
|
+
- **Pipeline**: The stages that produce the project's artifacts, each showing
|
|
23
|
+
live status (up to date, **stale**, or running).
|
|
24
|
+
- **Notebooks**: Jupyter notebooks and the environments/stages they belong to.
|
|
25
|
+
- **Figures**, **Datasets**, **Results**, **Publications**, and
|
|
26
|
+
**Presentations**: The output artifacts, each annotated with the stage (or
|
|
27
|
+
import source) it came from.
|
|
28
|
+
|
|
29
|
+
Items are cross-linked, so you can traverse the system in any direction:
|
|
30
|
+
expand a figure to jump to the stage that made it, jump from a stage to its
|
|
31
|
+
environment, open the stage's script/notebook, or open an output file—then run
|
|
32
|
+
the stage again. A badge and per-section warnings flag anything that needs
|
|
33
|
+
attention (stale outputs, artifacts with no defined source, notebooks with no
|
|
34
|
+
environment).
|
|
35
|
+
|
|
36
|
+
Use the toolbar to filter the tree across all sections, refresh status,
|
|
37
|
+
hide/show sections, open `calkit.yaml`, or initialize a new Calkit
|
|
38
|
+
project in a plain folder.
|
|
39
|
+
|
|
40
|
+
## Provenance & traceability
|
|
41
|
+
|
|
42
|
+
- **Show Source**: From an open figure, PDF, dataset, or other pipeline output,
|
|
43
|
+
jump straight to the producing stage in the sidebar (and into its source).
|
|
44
|
+
- **Figure source links**: In Quarto (`.qmd`) and LaTeX (`.tex`) documents, a
|
|
45
|
+
"Source: \<stage\>" CodeLens appears above each `` / `\includegraphics{…}`
|
|
46
|
+
that references a pipeline output; right-click also offers **Go to Figure
|
|
47
|
+
Source**. (From a compiled PDF, LaTeX Workshop's reverse-SyncTeX takes you to
|
|
48
|
+
the `\includegraphics` line, where these actions take over.)
|
|
49
|
+
- **Stale-output awareness**: Outputs whose stage needs re-running are flagged
|
|
50
|
+
in the sidebar and in the file explorer.
|
|
51
|
+
- **File history**: View a tracked file's history from the sidebar or explorer.
|
|
52
|
+
- **Scheduler logs**: Stages that run under SLURM/PBS surface their log file in
|
|
53
|
+
the tree so you can open it with a click.
|
|
54
|
+
|
|
55
|
+
## Pipeline
|
|
56
|
+
|
|
57
|
+
- Run the whole pipeline, an individual stage, or the stage for the file
|
|
58
|
+
you're editing.
|
|
59
|
+
- Define new stages graphically, including turning a notebook, script, or an
|
|
60
|
+
existing artifact into a reproducible stage; edit existing stages.
|
|
61
|
+
- Visualize the pipeline DAG.
|
|
62
|
+
- Open the rendered PDF of a LaTeX/Quarto stage from its source.
|
|
63
|
+
|
|
64
|
+
## Environments
|
|
65
|
+
|
|
66
|
+
- Create and edit environments graphically (package lists, spec files, base
|
|
67
|
+
images, etc.) for uv, Pixi, venv, conda, renv, Docker, Julia, MATLAB, SSH, and
|
|
68
|
+
SLURM/PBS.
|
|
69
|
+
- Select a notebook's environment and let the extension register/select the
|
|
70
|
+
matching Jupyter kernel—or edit that environment right from the notebook
|
|
71
|
+
toolbar.
|
|
72
|
+
- Use nested environments like `slurm:main` for notebook jobs that need to,
|
|
73
|
+
e.g., to reserve GPUs on a cluster.
|
|
74
|
+
- Start, stop, and restart notebook server sessions for SLURM- and
|
|
75
|
+
Docker-backed workflows from the notebook toolbar.
|
|
76
|
+
|
|
77
|
+
## Figures & artifacts
|
|
78
|
+
|
|
79
|
+
- Browse figures in a gallery and carousel, including interactive Plotly
|
|
80
|
+
figures (`.json`), with per-figure provenance and a one-click jump to the
|
|
81
|
+
producing stage.
|
|
82
|
+
- Preview Plotly JSON files in a dedicated **Plotly Preview** editor.
|
|
83
|
+
- Open a notebook's executed HTML output.
|
|
84
|
+
|
|
85
|
+
## Getting started
|
|
86
|
+
|
|
87
|
+
1. Open a project folder. If it isn't a Calkit project yet, the sidebar offers
|
|
88
|
+
**Initialize Calkit Project**.
|
|
89
|
+
2. Explore the Calkit sidebar to see environments, the pipeline, and
|
|
90
|
+
artifacts.
|
|
91
|
+
3. From a notebook, run **Calkit: Select Notebook Environment**, pick or create
|
|
92
|
+
an environment (providing SLURM options like `--gpus`/`--time` if needed), and
|
|
93
|
+
the extension registers/selects the kernel and connects the session.
|
|
94
|
+
|
|
95
|
+
## Requirements
|
|
96
|
+
|
|
97
|
+
- VS Code with the Jupyter extension installed.
|
|
98
|
+
- The Calkit CLI available on your `PATH`. If it's missing or too old, the
|
|
99
|
+
extension prompts with install/upgrade options.
|
|
100
|
+
|
|
101
|
+
## How environments are stored in `calkit.yaml`
|
|
102
|
+
|
|
103
|
+
Selecting an environment for a notebook writes it to `calkit.yaml`, updating
|
|
104
|
+
either `notebooks` or `pipeline.stages` depending on whether the notebook is part
|
|
105
|
+
of a pipeline stage.
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
# Standalone notebook
|
|
109
|
+
notebooks:
|
|
110
|
+
- path: my-notebook.ipynb
|
|
111
|
+
environment: my-env
|
|
112
|
+
|
|
113
|
+
# Notebook that is a pipeline stage
|
|
114
|
+
pipeline:
|
|
115
|
+
stages:
|
|
116
|
+
my-notebook:
|
|
117
|
+
kind: jupyter-notebook
|
|
118
|
+
notebook_path: my-notebook.ipynb
|
|
119
|
+
environment: my-env
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Settings
|
|
123
|
+
|
|
124
|
+
- `calkit.autoRefreshStatus`: Automatically run `calkit status` to refresh
|
|
125
|
+
pipeline staleness when project files change (disable if frequent status
|
|
126
|
+
checks interfere with Git operations; you can still refresh manually).
|
|
127
|
+
- `calkit.notebook.defaultJupyterPort`: Default port for Calkit-backed Jupyter
|
|
128
|
+
servers.
|
|
129
|
+
- `calkit.sidebar.hiddenSections`: Sidebar sections to hide (managed via the
|
|
130
|
+
sidebar's **Manage Sections** action).
|
|
131
|
+
|
|
132
|
+
## Commands
|
|
133
|
+
|
|
134
|
+
Most actions are available from the sidebar, notebook toolbar, and editor
|
|
135
|
+
context menus. Highlights, all under the **Calkit** category in the command
|
|
136
|
+
palette:
|
|
137
|
+
|
|
138
|
+
- Project: **Initialize Calkit Project**, **Open calkit.yaml**, **Save**,
|
|
139
|
+
**Refresh**, **Filter** / **Clear Filter**, **Manage Sections**
|
|
140
|
+
- Pipeline: **Run Pipeline**, **Run Stage**, **New Stage**, **Edit Stage**,
|
|
141
|
+
**Show Pipeline DAG**, **Open Rendered PDF**, **Show Source**, **Go to Figure
|
|
142
|
+
Source**
|
|
143
|
+
- Environments: **Create Environment**, **Edit Environment**, **Select Notebook
|
|
144
|
+
Environment**, **Edit Notebook Environment**
|
|
145
|
+
- Notebook sessions: **Start Jupyter SLURM Job**, **Stop Jupyter SLURM Job**,
|
|
146
|
+
**Restart Notebook Server**, **Open Executed HTML**
|
|
147
|
+
- Figures: **Browse Figures**, **Open Plotly Preview**
|
|
148
|
+
- Artifacts: **Define Pipeline Stage**, **Define Import**, **View File History**
|