calkit-python 0.40.0__tar.gz → 0.40.1__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.
Files changed (328) hide show
  1. {calkit_python-0.40.0 → calkit_python-0.40.1}/PKG-INFO +1 -1
  2. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/jupyterlab/routes.py +7 -1
  3. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/models/pipeline.py +6 -0
  4. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/pipeline.py +77 -1
  5. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/server.py +7 -1
  6. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_pipeline.py +81 -0
  7. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/pipeline/index.md +1 -0
  8. {calkit_python-0.40.0 → calkit_python-0.40.1}/.claude-plugin/marketplace.json +0 -0
  9. {calkit_python-0.40.0 → calkit_python-0.40.1}/.gitignore +0 -0
  10. {calkit_python-0.40.0 → calkit_python-0.40.1}/.pre-commit-config.yaml +0 -0
  11. {calkit_python-0.40.0 → calkit_python-0.40.1}/.prettierignore +0 -0
  12. {calkit_python-0.40.0 → calkit_python-0.40.1}/.python-version +0 -0
  13. {calkit_python-0.40.0 → calkit_python-0.40.1}/.vscode/launch.json +0 -0
  14. {calkit_python-0.40.0 → calkit_python-0.40.1}/.vscode/tasks.json +0 -0
  15. {calkit_python-0.40.0 → calkit_python-0.40.1}/.yarnrc.yml +0 -0
  16. {calkit_python-0.40.0 → calkit_python-0.40.1}/AGENTS.md +0 -0
  17. {calkit_python-0.40.0 → calkit_python-0.40.1}/CITATION.cff +0 -0
  18. {calkit_python-0.40.0 → calkit_python-0.40.1}/CODE_OF_CONDUCT.md +0 -0
  19. {calkit_python-0.40.0 → calkit_python-0.40.1}/CONTRIBUTING.md +0 -0
  20. {calkit_python-0.40.0 → calkit_python-0.40.1}/LICENSE +0 -0
  21. {calkit_python-0.40.0 → calkit_python-0.40.1}/Makefile +0 -0
  22. {calkit_python-0.40.0 → calkit_python-0.40.1}/README.md +0 -0
  23. {calkit_python-0.40.0 → calkit_python-0.40.1}/agent-plugin/.claude-plugin/plugin.json +0 -0
  24. {calkit_python-0.40.0 → calkit_python-0.40.1}/agent-plugin/skills/add-pipeline-stage/SKILL.md +0 -0
  25. {calkit_python-0.40.0 → calkit_python-0.40.1}/agent-plugin/skills/conventions/SKILL.md +0 -0
  26. {calkit_python-0.40.0 → calkit_python-0.40.1}/agent-plugin/skills/create-pipeline/SKILL.md +0 -0
  27. {calkit_python-0.40.0 → calkit_python-0.40.1}/babel.config.js +0 -0
  28. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/__init__.py +0 -0
  29. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/__main__.py +0 -0
  30. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/calc.py +0 -0
  31. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/check.py +0 -0
  32. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/__init__.py +0 -0
  33. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/check.py +0 -0
  34. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/cloud.py +0 -0
  35. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/config.py +0 -0
  36. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/core.py +0 -0
  37. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/describe.py +0 -0
  38. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/dev.py +0 -0
  39. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/import_.py +0 -0
  40. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/latex.py +0 -0
  41. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/list.py +0 -0
  42. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/main/__init__.py +0 -0
  43. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/main/core.py +0 -0
  44. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/main/xr.py +0 -0
  45. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/new.py +0 -0
  46. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/notebooks.py +0 -0
  47. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/office.py +0 -0
  48. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/overleaf.py +0 -0
  49. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/scheduler.py +0 -0
  50. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cli/update.py +0 -0
  51. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/cloud.py +0 -0
  52. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/conda.py +0 -0
  53. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/config.py +0 -0
  54. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/core.py +0 -0
  55. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/datasets.py +0 -0
  56. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/detect.py +0 -0
  57. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/docker.py +0 -0
  58. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/dvc/__init__.py +0 -0
  59. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/dvc/core.py +0 -0
  60. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/dvc/zip.py +0 -0
  61. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/environments.py +0 -0
  62. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/fs.py +0 -0
  63. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/git.py +0 -0
  64. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/github.py +0 -0
  65. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/gui.py +0 -0
  66. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/invenio.py +0 -0
  67. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/julia.py +0 -0
  68. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/jupyter.py +0 -0
  69. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/jupyterlab/__init__.py +0 -0
  70. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/package.json +0 -0
  71. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/schemas/calkit/package.json.orig +0 -0
  72. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/schemas/calkit/plugin.json +0 -0
  73. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
  74. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
  75. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
  76. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/909.e3f9cc3408834a7fdcc3.js +0 -0
  77. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
  78. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
  79. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
  80. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/remoteEntry.65469af996e7a96aa983.js +0 -0
  81. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/style.js +0 -0
  82. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/labextension/static/third-party-licenses.json +0 -0
  83. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/licenses.py +0 -0
  84. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/magics.py +0 -0
  85. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/matlab.py +0 -0
  86. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/models/__init__.py +0 -0
  87. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/models/core.py +0 -0
  88. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/models/io.py +0 -0
  89. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/models/iteration.py +0 -0
  90. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/notebooks.py +0 -0
  91. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/office.py +0 -0
  92. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/ops.py +0 -0
  93. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/overleaf.py +0 -0
  94. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/releases.py +0 -0
  95. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/__init__.py +0 -0
  96. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/core.py +0 -0
  97. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/latex/__init__.py +0 -0
  98. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/latex/article/paper.tex +0 -0
  99. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/latex/core.py +0 -0
  100. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/latex/jfm/jfm.bst +0 -0
  101. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/latex/jfm/jfm.cls +0 -0
  102. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
  103. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/latex/jfm/paper.tex +0 -0
  104. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/templates/latex/jfm/upmath.sty +0 -0
  105. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/__init__.py +0 -0
  106. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/__init__.py +0 -0
  107. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/main/__init__.py +0 -0
  108. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/main/test_core.py +0 -0
  109. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/main/test_subprojects.py +0 -0
  110. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/main/test_xr.py +0 -0
  111. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_check.py +0 -0
  112. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_cloud.py +0 -0
  113. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_config.py +0 -0
  114. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_import.py +0 -0
  115. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_latex.py +0 -0
  116. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_list.py +0 -0
  117. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_new.py +0 -0
  118. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_notebooks.py +0 -0
  119. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_overleaf.py +0 -0
  120. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/cli/test_update.py +0 -0
  121. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/dvc/__init__.py +0 -0
  122. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/dvc/test_core.py +0 -0
  123. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/dvc/test_zip.py +0 -0
  124. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/jupyterlab/__init__.py +0 -0
  125. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/jupyterlab/test_routes.py +0 -0
  126. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/models/__init__.py +0 -0
  127. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/models/test_iteration.py +0 -0
  128. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/models/test_pipeline.py +0 -0
  129. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_calc.py +0 -0
  130. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_check.py +0 -0
  131. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_cloud.py +0 -0
  132. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_conda.py +0 -0
  133. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_core.py +0 -0
  134. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_detect.py +0 -0
  135. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_docker.py +0 -0
  136. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_environments.py +0 -0
  137. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_fs.py +0 -0
  138. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_git.py +0 -0
  139. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_invenio.py +0 -0
  140. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_julia.py +0 -0
  141. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_jupyter.py +0 -0
  142. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_magics.py +0 -0
  143. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_matlab.py +0 -0
  144. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_notebooks.py +0 -0
  145. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_releases.py +0 -0
  146. {calkit_python-0.40.0 → calkit_python-0.40.1}/calkit/tests/test_templates.py +0 -0
  147. {calkit_python-0.40.0 → calkit_python-0.40.1}/conftest.py +0 -0
  148. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/CNAME +0 -0
  149. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/ai-tools.md +0 -0
  150. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/apps.md +0 -0
  151. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/calculations.md +0 -0
  152. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/calkit-yaml.md +0 -0
  153. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/cli-reference.md +0 -0
  154. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/cloud-integration.md +0 -0
  155. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/datasets.md +0 -0
  156. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/dependencies.md +0 -0
  157. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/environments.md +0 -0
  158. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/examples.md +0 -0
  159. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/governance.md +0 -0
  160. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/help.md +0 -0
  161. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/hpc.md +0 -0
  162. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/c-to-the-k-white.svg +0 -0
  163. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/calkit-fragmentation-compendium.png +0 -0
  164. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/calkit-no-bg.png +0 -0
  165. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/connect-zenodo.png +0 -0
  166. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/jupyterlab/all-green.png +0 -0
  167. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/jupyterlab/collect-data-stale.png +0 -0
  168. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/jupyterlab/new-env.png +0 -0
  169. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/jupyterlab/new-notebook.png +0 -0
  170. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/jupyterlab/pipeline-badge.png +0 -0
  171. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/jupyterlab-params.png +0 -0
  172. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/plos-osi-code-2024-03.png +0 -0
  173. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/img/vscode-nb-params.png +0 -0
  174. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/index.md +0 -0
  175. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/installation.md +0 -0
  176. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/jupyterlab.md +0 -0
  177. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/local-server.md +0 -0
  178. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/notebooks.md +0 -0
  179. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/overleaf.md +0 -0
  180. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/pipeline/manual-steps.md +0 -0
  181. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/pipeline/running-and-logging.md +0 -0
  182. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/quickstart.md +0 -0
  183. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/references.md +0 -0
  184. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/releases.md +0 -0
  185. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/reproducibility.md +0 -0
  186. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/subprojects.md +0 -0
  187. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/adding-latex-pub-docker.md +0 -0
  188. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/conda-envs.md +0 -0
  189. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/existing-project.md +0 -0
  190. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/first-project.md +0 -0
  191. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/github-actions.md +0 -0
  192. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/actions-repo-secrets.png +0 -0
  193. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
  194. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
  195. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
  196. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
  197. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
  198. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
  199. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
  200. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
  201. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
  202. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
  203. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/push.png +0 -0
  204. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
  205. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
  206. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/chart-more-rows.png +0 -0
  207. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/create-project.png +0 -0
  208. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
  209. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/excel-chart.png +0 -0
  210. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/excel-data.png +0 -0
  211. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
  212. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/needs-clone.png +0 -0
  213. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/new-stage.png +0 -0
  214. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
  215. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
  216. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/status-more-rows.png +0 -0
  217. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
  218. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/untracked-data.png +0 -0
  219. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/updated-publication.png +0 -0
  220. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
  221. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/office/workflow-page.png +0 -0
  222. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/openfoam/clone.png +0 -0
  223. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/openfoam/create-project.png +0 -0
  224. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
  225. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
  226. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
  227. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/openfoam/new-token.png +0 -0
  228. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/openfoam/reclone.png +0 -0
  229. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
  230. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/quick-actions.png +0 -0
  231. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/run-proc.png +0 -0
  232. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/vscode-slurm-notebook/create-calkit-env.png +0 -0
  233. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/vscode-slurm-notebook/create-inner-env.png +0 -0
  234. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/vscode-slurm-notebook/create-new-calkit-env.png +0 -0
  235. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/vscode-slurm-notebook/select-calkit-env.png +0 -0
  236. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/vscode-slurm-notebook/slurm-job-running.png +0 -0
  237. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/vscode-slurm-notebook/slurm-launch-options.png +0 -0
  238. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/img/vscode-slurm-notebook/starting-slurm-job.png +0 -0
  239. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/index.md +0 -0
  240. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/jupyterlab.md +0 -0
  241. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/latex-codespaces.md +0 -0
  242. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/matlab.md +0 -0
  243. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/notebook-pipeline.md +0 -0
  244. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/office.md +0 -0
  245. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/openfoam.md +0 -0
  246. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/procedures.md +0 -0
  247. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/tutorials/vscode-slurm-notebook.md +0 -0
  248. {calkit_python-0.40.0 → calkit_python-0.40.1}/docs/version-control.md +0 -0
  249. {calkit_python-0.40.0 → calkit_python-0.40.1}/install.json +0 -0
  250. {calkit_python-0.40.0 → calkit_python-0.40.1}/jest.config.js +0 -0
  251. {calkit_python-0.40.0 → calkit_python-0.40.1}/jupyter-config/server-config/calkit.json +0 -0
  252. {calkit_python-0.40.0 → calkit_python-0.40.1}/mkdocs.yml +0 -0
  253. {calkit_python-0.40.0 → calkit_python-0.40.1}/package.json +0 -0
  254. {calkit_python-0.40.0 → calkit_python-0.40.1}/pyproject.toml +0 -0
  255. {calkit_python-0.40.0 → calkit_python-0.40.1}/schema/plugin.json +0 -0
  256. {calkit_python-0.40.0 → calkit_python-0.40.1}/scripts/generate-docs-references.py +0 -0
  257. {calkit_python-0.40.0 → calkit_python-0.40.1}/scripts/install.ps1 +0 -0
  258. {calkit_python-0.40.0 → calkit_python-0.40.1}/scripts/install.sh +0 -0
  259. {calkit_python-0.40.0 → calkit_python-0.40.1}/scripts/make-calk9.sh +0 -0
  260. {calkit_python-0.40.0 → calkit_python-0.40.1}/scripts/sync-docs.py +0 -0
  261. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/__tests__/useQueries.spec.ts +0 -0
  262. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/calkit-config.ts +0 -0
  263. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/cell-output-marker.ts +0 -0
  264. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/components/commit-dialog.tsx +0 -0
  265. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/components/environment-editor.tsx +0 -0
  266. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/components/notebook-registration.tsx +0 -0
  267. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/components/notebook-toolbar.tsx +0 -0
  268. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/components/pipeline-status-bar.tsx +0 -0
  269. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/components/project-info-editor.tsx +0 -0
  270. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/components/sidebar-settings.tsx +0 -0
  271. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/components/sidebar.tsx +0 -0
  272. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/components/stage-editor.tsx +0 -0
  273. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/feature-flags.ts +0 -0
  274. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/file-browser-menu.ts +0 -0
  275. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/hooks/__tests__/useQueries.test.tsx +0 -0
  276. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/hooks/useQueries.ts +0 -0
  277. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/icons.ts +0 -0
  278. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/index.ts +0 -0
  279. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/io-tracker.ts +0 -0
  280. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/pipeline-state.ts +0 -0
  281. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/queryClient.ts +0 -0
  282. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/request.ts +0 -0
  283. {calkit_python-0.40.0 → calkit_python-0.40.1}/src/shims-mainmenu.d.ts +0 -0
  284. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/base.css +0 -0
  285. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/cell-output-marker.css +0 -0
  286. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/environment-editor.css +0 -0
  287. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/environment-selector.css +0 -0
  288. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/img/calkit-no-bg.png +0 -0
  289. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/index.css +0 -0
  290. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/index.js +0 -0
  291. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/notebook-toolbar.css +0 -0
  292. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/pipeline-status-bar.css +0 -0
  293. {calkit_python-0.40.0 → calkit_python-0.40.1}/style/sidebar.css +0 -0
  294. {calkit_python-0.40.0 → calkit_python-0.40.1}/test/dvc-md5-dir/osx-arm64.txt +0 -0
  295. {calkit_python-0.40.0 → calkit_python-0.40.1}/test/nb-julia.ipynb +0 -0
  296. {calkit_python-0.40.0 → calkit_python-0.40.1}/test/nb-params.ipynb +0 -0
  297. {calkit_python-0.40.0 → calkit_python-0.40.1}/test/nb-subdir.ipynb +0 -0
  298. {calkit_python-0.40.0 → calkit_python-0.40.1}/test/pipeline.ipynb +0 -0
  299. {calkit_python-0.40.0 → calkit_python-0.40.1}/test/script.py +0 -0
  300. {calkit_python-0.40.0 → calkit_python-0.40.1}/test/test-log.log +0 -0
  301. {calkit_python-0.40.0 → calkit_python-0.40.1}/tsconfig.json +0 -0
  302. {calkit_python-0.40.0 → calkit_python-0.40.1}/tsconfig.test.json +0 -0
  303. {calkit_python-0.40.0 → calkit_python-0.40.1}/ui-tests/.gitignore +0 -0
  304. {calkit_python-0.40.0 → calkit_python-0.40.1}/ui-tests/README.md +0 -0
  305. {calkit_python-0.40.0 → calkit_python-0.40.1}/ui-tests/jupyter_server_test_config.py +0 -0
  306. {calkit_python-0.40.0 → calkit_python-0.40.1}/ui-tests/package.json +0 -0
  307. {calkit_python-0.40.0 → calkit_python-0.40.1}/ui-tests/playwright.config.js +0 -0
  308. {calkit_python-0.40.0 → calkit_python-0.40.1}/ui-tests/tests/calkit.spec.ts +0 -0
  309. {calkit_python-0.40.0 → calkit_python-0.40.1}/ui-tests/yarn.lock +0 -0
  310. {calkit_python-0.40.0 → calkit_python-0.40.1}/uv.lock +0 -0
  311. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/.gitignore +0 -0
  312. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/.vscodeignore +0 -0
  313. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/CHANGELOG.md +0 -0
  314. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/LICENSE +0 -0
  315. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/README.md +0 -0
  316. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/images/calkit-no-bg.png +0 -0
  317. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/package-lock.json +0 -0
  318. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/package.json +0 -0
  319. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/scripts/set-proposed-api.js +0 -0
  320. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/src/environments.ts +0 -0
  321. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/src/extension.ts +0 -0
  322. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/src/notebooks.ts +0 -0
  323. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/src/test/environments.test.ts +0 -0
  324. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/src/test/kernel-selection.test.ts +0 -0
  325. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/src/test/notebooks.test.ts +0 -0
  326. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/src/types.ts +0 -0
  327. {calkit_python-0.40.0 → calkit_python-0.40.1}/vscode-ext/tsconfig.json +0 -0
  328. {calkit_python-0.40.0 → calkit_python-0.40.1}/yarn.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: calkit-python
3
- Version: 0.40.0
3
+ Version: 0.40.1
4
4
  Summary: Reproducibility simplified.
5
5
  Project-URL: Homepage, https://calkit.org
6
6
  Project-URL: Issues, https://github.com/calkit/calkit/issues
@@ -896,10 +896,16 @@ class PipelineStatusRouteHandler(APIHandler):
896
896
  calkit.notebooks.clean_all_in_pipeline(ck_info=ck_info)
897
897
  dvc_repo = get_dvc_repo(os.getcwd())
898
898
  raw_status = dvc_repo.status()
899
+ # Frozen stages are intentionally pinned and hidden from status
900
+ frozen_stages = calkit.pipeline.frozen_stage_base_names(
901
+ ck_info=ck_info
902
+ )
899
903
  pipeline_status = {
900
904
  k.split("dvc.yaml:")[-1]: v
901
905
  for k, v in raw_status.items()
902
- if v != ["always changed"] and not k.endswith(".dvc")
906
+ if v != ["always changed"]
907
+ and not k.endswith(".dvc")
908
+ and k.split("dvc.yaml:")[-1].split("@")[0] not in frozen_stages
903
909
  }
904
910
  is_outdated = len(pipeline_status) > 0
905
911
  self.finish(
@@ -189,6 +189,7 @@ class Stage(BaseModel):
189
189
  always_run: bool = False
190
190
  iterate_over: list[StageIteration] | None = None
191
191
  description: str | None = None
192
+ frozen: bool = False
192
193
  scheduler: StageSchedulerOptions | None = None
193
194
  # Do not allow extra keys
194
195
  model_config = ConfigDict(extra="forbid")
@@ -418,6 +419,8 @@ class Stage(BaseModel):
418
419
  stage["wdir"] = self.wdir
419
420
  if self.always_run:
420
421
  stage["always_changed"] = True
422
+ if self.frozen:
423
+ stage["frozen"] = True
421
424
  return stage
422
425
 
423
426
 
@@ -1182,6 +1185,7 @@ class Pipeline(BaseModel):
1182
1185
  always_run=stage.always_run,
1183
1186
  iterate_over=stage.iterate_over,
1184
1187
  description=stage.description,
1188
+ frozen=stage.frozen,
1185
1189
  scheduler=StageSchedulerOptions(**sched_opts)
1186
1190
  if sched_opts
1187
1191
  else StageSchedulerOptions(),
@@ -1216,6 +1220,8 @@ class Pipeline(BaseModel):
1216
1220
  calkit_yaml_stage["always_run"] = True
1217
1221
  if stage.description is not None:
1218
1222
  calkit_yaml_stage["description"] = stage.description
1223
+ if stage.frozen:
1224
+ calkit_yaml_stage["frozen"] = True
1219
1225
  if stage.iterate_over is not None:
1220
1226
  calkit_yaml_stage["iterate_over"] = [
1221
1227
  it.model_dump() for it in stage.iterate_over
@@ -1,6 +1,7 @@
1
1
  """Pipeline-related functionality."""
2
2
 
3
3
  import itertools
4
+ import logging
4
5
  import os
5
6
  from pathlib import Path
6
7
 
@@ -16,6 +17,54 @@ from calkit.models.pipeline import (
16
17
  )
17
18
 
18
19
 
20
+ class _FrozenStageWarningFilter(logging.Filter):
21
+ """Drop only DVC's "stage is frozen" status warning.
22
+
23
+ Frozen stages are intentionally hidden from Calkit status output, so this
24
+ warning is noise; all other ``dvc.repo.status`` diagnostics pass through.
25
+ """
26
+
27
+ def filter(self, record: logging.LogRecord) -> bool:
28
+ return "is frozen. Its dependencies are" not in record.getMessage()
29
+
30
+
31
+ def _coerce_frozen(value: object) -> bool:
32
+ """Interpret a raw ``frozen`` value the same way the Stage model would.
33
+
34
+ ``ck_info`` holds unvalidated YAML, so a quoted ``frozen: "false"`` is a
35
+ truthy string here; defer to Pydantic's bool parsing so status filtering
36
+ matches the compiled pipeline's behavior.
37
+ """
38
+ from pydantic import TypeAdapter, ValidationError
39
+
40
+ try:
41
+ return TypeAdapter(bool).validate_python(value)
42
+ except ValidationError:
43
+ return bool(value)
44
+
45
+
46
+ def frozen_stage_base_names(
47
+ ck_info: dict | None = None, wdir: str | None = None
48
+ ) -> set[str]:
49
+ """Return the base names of root pipeline stages marked ``frozen``.
50
+
51
+ Shared by the various status paths so frozen stages are consistently
52
+ hidden. Iterated stages use a ``name@param`` key in DVC status, so callers
53
+ should compare against the part before ``@``.
54
+ """
55
+ if ck_info is None:
56
+ ck_info = calkit.load_calkit_info(wdir=wdir)
57
+ names: set[str] = set()
58
+ stages = ck_info.get("pipeline", {}).get("stages", {})
59
+ if isinstance(stages, dict):
60
+ for name, cfg in stages.items():
61
+ if isinstance(cfg, dict) and _coerce_frozen(
62
+ cfg.get("frozen", False)
63
+ ):
64
+ names.add(name)
65
+ return names
66
+
67
+
19
68
  class PipelineStatus(BaseModel):
20
69
  """Current status of the project pipeline."""
21
70
 
@@ -537,7 +586,19 @@ def get_status(
537
586
  return PipelineStatus.model_validate(result)
538
587
  try:
539
588
  dvc_repo = calkit.dvc.get_dvc_repo()
540
- raw_status = dvc_repo.status(targets=targets)
589
+ # Frozen stages emit a "stage is frozen. Its dependencies are not
590
+ # going to be shown in the status output." warning from DVC's
591
+ # status module; suppress just that message since we intentionally
592
+ # hide frozen stages from the Calkit status output entirely.
593
+ # A targeted filter is used (rather than raising the logger level)
594
+ # so unrelated DVC diagnostics are still emitted.
595
+ dvc_status_logger = logging.getLogger("dvc.repo.status")
596
+ frozen_filter = _FrozenStageWarningFilter()
597
+ dvc_status_logger.addFilter(frozen_filter)
598
+ try:
599
+ raw_status = dvc_repo.status(targets=targets)
600
+ finally:
601
+ dvc_status_logger.removeFilter(frozen_filter)
541
602
  except Exception as e:
542
603
  result["errors"].append(
543
604
  "Failed to get pipeline status from DVC: "
@@ -666,6 +727,21 @@ def get_status(
666
727
  raw_stale_stages.keys(), key=_stage_sort_key
667
728
  ):
668
729
  bare_name, subproject, status_data = raw_stale_stages[display_name]
730
+ # Frozen stages are intentionally pinned: never report them as
731
+ # stale (and they are never reproduced). Iterated stages have a
732
+ # "name@param" bare name, so look up config by the base name too.
733
+ base_name = bare_name.split("@")[0]
734
+ if subproject is None:
735
+ frozen_cfg = root_stages_config.get(
736
+ bare_name, root_stages_config.get(base_name, {})
737
+ )
738
+ else:
739
+ sp_cfg = sp_stages_config.get(subproject, {})
740
+ frozen_cfg = sp_cfg.get(bare_name, sp_cfg.get(base_name, {}))
741
+ if isinstance(frozen_cfg, dict) and _coerce_frozen(
742
+ frozen_cfg.get("frozen", False)
743
+ ):
744
+ continue
669
745
  if subproject is None:
670
746
  stage_cfg = root_stages_config.get(bare_name, {})
671
747
  else:
@@ -306,10 +306,16 @@ def get_status(
306
306
  # Remove any always changed entries so the pipeline doesn't look
307
307
  # out of date
308
308
  logger.info(f"Raw DVC pipeline status: {dvc_pipeline_status}")
309
+ # Frozen stages are intentionally pinned and hidden from status
310
+ frozen_stages = calkit.pipeline.frozen_stage_base_names(
311
+ wdir=project.wdir
312
+ )
309
313
  dvc_pipeline_status = {
310
314
  k.split("dvc.yaml:")[-1]: v
311
315
  for k, v in dvc_pipeline_status.items()
312
- if v != ["always changed"] and not k.endswith(".dvc")
316
+ if v != ["always changed"]
317
+ and not k.endswith(".dvc")
318
+ and k.split("dvc.yaml:")[-1].split("@")[0] not in frozen_stages
313
319
  }
314
320
  logger.info(
315
321
  f"DVC pipeline status after filtering: {dvc_pipeline_status}"
@@ -1209,6 +1209,34 @@ def test_slurm_field_renamed_to_scheduler(tmp_dir):
1209
1209
  assert stage["scheduler"]["options"] == ["--time=01:00:00"]
1210
1210
 
1211
1211
 
1212
+ def test_frozen_preserved_through_sbatch_conversion(tmp_dir):
1213
+ """A frozen legacy ``sbatch`` stage stays frozen after conversion."""
1214
+ subprocess.check_call(["calkit", "init"])
1215
+ ck_yaml = {
1216
+ "environments": {"mycluster": {"kind": "slurm"}},
1217
+ "pipeline": {
1218
+ "stages": {
1219
+ "run": {
1220
+ "kind": "sbatch",
1221
+ "script_path": "scripts/run.sh",
1222
+ "environment": "mycluster",
1223
+ "frozen": True,
1224
+ }
1225
+ }
1226
+ },
1227
+ }
1228
+ with open("calkit.yaml", "w") as _f:
1229
+ calkit.ryaml.dump(ck_yaml, _f)
1230
+ dvc_stages = calkit.pipeline.to_dvc(write=True)
1231
+ # The converted shell-script stage and the rewritten calkit.yaml entry
1232
+ # must both still be frozen, and DVC must not reproduce it
1233
+ assert dvc_stages["run"]["frozen"] is True
1234
+ updated = calkit.load_calkit_info()
1235
+ converted = updated["pipeline"]["stages"]["run"]
1236
+ assert converted["kind"] == "shell-script"
1237
+ assert converted["frozen"] is True
1238
+
1239
+
1212
1240
  def test_gitignore_updated_when_stage_output_renamed(tmp_dir):
1213
1241
  """When a stage output path is renamed, stale .gitignore entries are
1214
1242
  replaced.
@@ -1383,6 +1411,59 @@ def test_get_status(tmp_dir):
1383
1411
  assert status.stale_stages["get-data"].modified_outputs == []
1384
1412
 
1385
1413
 
1414
+ def test_get_status_excludes_frozen_stage(tmp_dir):
1415
+ subprocess.check_call(["calkit", "init"])
1416
+ ck_info = {
1417
+ "environments": {
1418
+ "py": {
1419
+ "kind": "uv-venv",
1420
+ "path": "requirements.txt",
1421
+ "prefix": ".venv",
1422
+ }
1423
+ },
1424
+ "pipeline": {
1425
+ "stages": {
1426
+ "get-data": {
1427
+ "kind": "python-script",
1428
+ "environment": "py",
1429
+ "script_path": "something/my-cool-script.py",
1430
+ "outputs": ["my-output.out"],
1431
+ "frozen": True,
1432
+ }
1433
+ }
1434
+ },
1435
+ }
1436
+ with open("calkit.yaml", "w") as f:
1437
+ calkit.ryaml.dump(ck_info, f)
1438
+ with open("requirements.txt", "w") as f:
1439
+ f.write("requests\n")
1440
+ os.makedirs("something", exist_ok=True)
1441
+ with open("something/my-cool-script.py", "w") as f:
1442
+ f.write(
1443
+ "with open('my-output.out', 'w') as f:\n"
1444
+ " f.write('Hello, world!')\n"
1445
+ )
1446
+ # The compiled DVC stage must carry frozen: true so DVC itself never
1447
+ # reproduces it (this is what actually prevents it from running)
1448
+ dvc_stages = calkit.pipeline.to_dvc(ck_info=ck_info)
1449
+ assert dvc_stages["get-data"]["frozen"] is True
1450
+ # A frozen stage is never reported as stale, even though it has never
1451
+ # been run and its outputs do not exist yet
1452
+ status = calkit.pipeline.get_status(ck_info=ck_info)
1453
+ assert not status.failed_environment_checks
1454
+ assert not status.is_stale
1455
+ assert "get-data" not in status.stale_stage_names
1456
+ # Modifying the script must not make the frozen stage stale either
1457
+ with open("something/my-cool-script.py", "w") as f:
1458
+ f.write(
1459
+ "with open('my-output.out', 'w') as f:\n"
1460
+ " f.write('Changed!')\n"
1461
+ )
1462
+ status = calkit.pipeline.get_status(ck_info=ck_info)
1463
+ assert not status.is_stale
1464
+ assert "get-data" not in status.stale_stage_names
1465
+
1466
+
1386
1467
  def test_stale_stage_detects_changed_command():
1387
1468
  stale_stage = calkit.pipeline.StaleStage.from_status_data(
1388
1469
  status_data=[{"changed command": "python src/new-script.py"}],
@@ -286,6 +286,7 @@ Common stage parameters:
286
286
  | `always_run` | bool | no | False |
287
287
  | `iterate_over` | list[StageIteration] \| None | no | null |
288
288
  | `description` | str \| None | no | null |
289
+ | `frozen` | bool | no | False |
289
290
  | `scheduler` | StageSchedulerOptions \| None | no | null |
290
291
 
291
292
  ### `command`
File without changes
File without changes
File without changes
File without changes