calkit-python 0.38.1__tar.gz → 0.38.2__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 (326) hide show
  1. {calkit_python-0.38.1 → calkit_python-0.38.2}/AGENTS.md +2 -0
  2. {calkit_python-0.38.1 → calkit_python-0.38.2}/PKG-INFO +1 -1
  3. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/dvc/zip.py +17 -0
  4. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/releases.py +39 -2
  5. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_releases.py +24 -0
  6. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/governance.md +20 -6
  7. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/src/environments.ts +11 -0
  8. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/src/extension.ts +8 -3
  9. calkit_python-0.38.2/vscode-ext/src/test/kernel-selection.test.ts +88 -0
  10. {calkit_python-0.38.1 → calkit_python-0.38.2}/.claude-plugin/marketplace.json +0 -0
  11. {calkit_python-0.38.1 → calkit_python-0.38.2}/.gitignore +0 -0
  12. {calkit_python-0.38.1 → calkit_python-0.38.2}/.pre-commit-config.yaml +0 -0
  13. {calkit_python-0.38.1 → calkit_python-0.38.2}/.prettierignore +0 -0
  14. {calkit_python-0.38.1 → calkit_python-0.38.2}/.python-version +0 -0
  15. {calkit_python-0.38.1 → calkit_python-0.38.2}/.vscode/launch.json +0 -0
  16. {calkit_python-0.38.1 → calkit_python-0.38.2}/.vscode/tasks.json +0 -0
  17. {calkit_python-0.38.1 → calkit_python-0.38.2}/.yarnrc.yml +0 -0
  18. {calkit_python-0.38.1 → calkit_python-0.38.2}/CITATION.cff +0 -0
  19. {calkit_python-0.38.1 → calkit_python-0.38.2}/CODE_OF_CONDUCT.md +0 -0
  20. {calkit_python-0.38.1 → calkit_python-0.38.2}/CONTRIBUTING.md +0 -0
  21. {calkit_python-0.38.1 → calkit_python-0.38.2}/LICENSE +0 -0
  22. {calkit_python-0.38.1 → calkit_python-0.38.2}/Makefile +0 -0
  23. {calkit_python-0.38.1 → calkit_python-0.38.2}/README.md +0 -0
  24. {calkit_python-0.38.1 → calkit_python-0.38.2}/agent-plugin/.claude-plugin/plugin.json +0 -0
  25. {calkit_python-0.38.1 → calkit_python-0.38.2}/agent-plugin/skills/add-pipeline-stage/SKILL.md +0 -0
  26. {calkit_python-0.38.1 → calkit_python-0.38.2}/agent-plugin/skills/conventions/SKILL.md +0 -0
  27. {calkit_python-0.38.1 → calkit_python-0.38.2}/agent-plugin/skills/create-pipeline/SKILL.md +0 -0
  28. {calkit_python-0.38.1 → calkit_python-0.38.2}/babel.config.js +0 -0
  29. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/__init__.py +0 -0
  30. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/__main__.py +0 -0
  31. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/calc.py +0 -0
  32. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/check.py +0 -0
  33. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/__init__.py +0 -0
  34. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/check.py +0 -0
  35. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/cloud.py +0 -0
  36. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/config.py +0 -0
  37. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/core.py +0 -0
  38. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/describe.py +0 -0
  39. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/dev.py +0 -0
  40. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/import_.py +0 -0
  41. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/latex.py +0 -0
  42. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/list.py +0 -0
  43. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/main/__init__.py +0 -0
  44. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/main/core.py +0 -0
  45. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/main/xr.py +0 -0
  46. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/new.py +0 -0
  47. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/notebooks.py +0 -0
  48. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/office.py +0 -0
  49. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/overleaf.py +0 -0
  50. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/slurm.py +0 -0
  51. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cli/update.py +0 -0
  52. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/cloud.py +0 -0
  53. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/conda.py +0 -0
  54. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/config.py +0 -0
  55. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/core.py +0 -0
  56. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/datasets.py +0 -0
  57. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/detect.py +0 -0
  58. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/docker.py +0 -0
  59. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/dvc/__init__.py +0 -0
  60. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/dvc/core.py +0 -0
  61. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/environments.py +0 -0
  62. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/fs.py +0 -0
  63. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/git.py +0 -0
  64. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/github.py +0 -0
  65. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/gui.py +0 -0
  66. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/invenio.py +0 -0
  67. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/julia.py +0 -0
  68. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/jupyter.py +0 -0
  69. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/jupyterlab/__init__.py +0 -0
  70. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/jupyterlab/routes.py +0 -0
  71. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/package.json +0 -0
  72. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/schemas/calkit/package.json.orig +0 -0
  73. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/schemas/calkit/plugin.json +0 -0
  74. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
  75. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
  76. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
  77. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/909.e3f9cc3408834a7fdcc3.js +0 -0
  78. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
  79. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
  80. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
  81. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/remoteEntry.65469af996e7a96aa983.js +0 -0
  82. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/style.js +0 -0
  83. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/labextension/static/third-party-licenses.json +0 -0
  84. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/licenses.py +0 -0
  85. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/magics.py +0 -0
  86. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/matlab.py +0 -0
  87. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/models/__init__.py +0 -0
  88. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/models/core.py +0 -0
  89. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/models/io.py +0 -0
  90. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/models/iteration.py +0 -0
  91. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/models/pipeline.py +0 -0
  92. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/notebooks.py +0 -0
  93. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/office.py +0 -0
  94. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/ops.py +0 -0
  95. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/overleaf.py +0 -0
  96. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/pipeline.py +0 -0
  97. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/server.py +0 -0
  98. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/__init__.py +0 -0
  99. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/core.py +0 -0
  100. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/latex/__init__.py +0 -0
  101. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/latex/article/paper.tex +0 -0
  102. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/latex/core.py +0 -0
  103. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/latex/jfm/jfm.bst +0 -0
  104. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/latex/jfm/jfm.cls +0 -0
  105. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
  106. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/latex/jfm/paper.tex +0 -0
  107. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/templates/latex/jfm/upmath.sty +0 -0
  108. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/__init__.py +0 -0
  109. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/__init__.py +0 -0
  110. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/main/__init__.py +0 -0
  111. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/main/test_core.py +0 -0
  112. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/main/test_xr.py +0 -0
  113. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_check.py +0 -0
  114. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_cloud.py +0 -0
  115. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_config.py +0 -0
  116. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_import.py +0 -0
  117. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_latex.py +0 -0
  118. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_list.py +0 -0
  119. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_new.py +0 -0
  120. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_notebooks.py +0 -0
  121. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_overleaf.py +0 -0
  122. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/cli/test_update.py +0 -0
  123. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/dvc/__init__.py +0 -0
  124. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/dvc/test_core.py +0 -0
  125. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/dvc/test_zip.py +0 -0
  126. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/jupyterlab/__init__.py +0 -0
  127. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/jupyterlab/test_routes.py +0 -0
  128. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/models/__init__.py +0 -0
  129. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/models/test_iteration.py +0 -0
  130. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/models/test_pipeline.py +0 -0
  131. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_calc.py +0 -0
  132. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_check.py +0 -0
  133. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_cloud.py +0 -0
  134. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_conda.py +0 -0
  135. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_core.py +0 -0
  136. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_detect.py +0 -0
  137. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_docker.py +0 -0
  138. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_environments.py +0 -0
  139. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_fs.py +0 -0
  140. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_git.py +0 -0
  141. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_invenio.py +0 -0
  142. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_julia.py +0 -0
  143. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_jupyter.py +0 -0
  144. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_magics.py +0 -0
  145. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_matlab.py +0 -0
  146. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_notebooks.py +0 -0
  147. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_pipeline.py +0 -0
  148. {calkit_python-0.38.1 → calkit_python-0.38.2}/calkit/tests/test_templates.py +0 -0
  149. {calkit_python-0.38.1 → calkit_python-0.38.2}/conftest.py +0 -0
  150. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/CNAME +0 -0
  151. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/ai-tools.md +0 -0
  152. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/apps.md +0 -0
  153. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/calculations.md +0 -0
  154. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/calkit-yaml.md +0 -0
  155. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/cli-reference.md +0 -0
  156. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/cloud-integration.md +0 -0
  157. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/datasets.md +0 -0
  158. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/dependencies.md +0 -0
  159. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/environments.md +0 -0
  160. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/examples.md +0 -0
  161. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/help.md +0 -0
  162. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/c-to-the-k-white.svg +0 -0
  163. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/calkit-fragmentation-compendium.png +0 -0
  164. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/calkit-no-bg.png +0 -0
  165. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/connect-zenodo.png +0 -0
  166. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/jupyterlab/all-green.png +0 -0
  167. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/jupyterlab/collect-data-stale.png +0 -0
  168. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/jupyterlab/new-env.png +0 -0
  169. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/jupyterlab/new-notebook.png +0 -0
  170. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/jupyterlab/pipeline-badge.png +0 -0
  171. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/jupyterlab-params.png +0 -0
  172. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/plos-osi-code-2024-03.png +0 -0
  173. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/img/vscode-nb-params.png +0 -0
  174. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/index.md +0 -0
  175. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/installation.md +0 -0
  176. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/jupyterlab.md +0 -0
  177. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/local-server.md +0 -0
  178. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/notebooks.md +0 -0
  179. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/overleaf.md +0 -0
  180. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/pipeline/index.md +0 -0
  181. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/pipeline/manual-steps.md +0 -0
  182. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/pipeline/running-and-logging.md +0 -0
  183. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/pipeline/slurm.md +0 -0
  184. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/quickstart.md +0 -0
  185. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/references.md +0 -0
  186. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/releases.md +0 -0
  187. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/reproducibility.md +0 -0
  188. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/adding-latex-pub-docker.md +0 -0
  189. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/conda-envs.md +0 -0
  190. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/existing-project.md +0 -0
  191. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/first-project.md +0 -0
  192. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/github-actions.md +0 -0
  193. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/actions-repo-secrets.png +0 -0
  194. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
  195. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
  196. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
  197. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
  198. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
  199. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
  200. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
  201. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
  202. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
  203. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
  204. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/push.png +0 -0
  205. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
  206. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
  207. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/chart-more-rows.png +0 -0
  208. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/create-project.png +0 -0
  209. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
  210. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/excel-chart.png +0 -0
  211. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/excel-data.png +0 -0
  212. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
  213. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/needs-clone.png +0 -0
  214. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/new-stage.png +0 -0
  215. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
  216. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
  217. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/status-more-rows.png +0 -0
  218. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
  219. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/untracked-data.png +0 -0
  220. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/updated-publication.png +0 -0
  221. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
  222. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/office/workflow-page.png +0 -0
  223. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/openfoam/clone.png +0 -0
  224. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/openfoam/create-project.png +0 -0
  225. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
  226. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
  227. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
  228. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/openfoam/new-token.png +0 -0
  229. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/openfoam/reclone.png +0 -0
  230. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
  231. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/quick-actions.png +0 -0
  232. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/run-proc.png +0 -0
  233. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/vscode-slurm-notebook/create-calkit-env.png +0 -0
  234. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/vscode-slurm-notebook/create-inner-env.png +0 -0
  235. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/vscode-slurm-notebook/create-new-calkit-env.png +0 -0
  236. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/vscode-slurm-notebook/select-calkit-env.png +0 -0
  237. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/vscode-slurm-notebook/slurm-job-running.png +0 -0
  238. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/vscode-slurm-notebook/slurm-launch-options.png +0 -0
  239. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/img/vscode-slurm-notebook/starting-slurm-job.png +0 -0
  240. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/index.md +0 -0
  241. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/jupyterlab.md +0 -0
  242. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/latex-codespaces.md +0 -0
  243. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/matlab.md +0 -0
  244. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/notebook-pipeline.md +0 -0
  245. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/office.md +0 -0
  246. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/openfoam.md +0 -0
  247. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/procedures.md +0 -0
  248. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/tutorials/vscode-slurm-notebook.md +0 -0
  249. {calkit_python-0.38.1 → calkit_python-0.38.2}/docs/version-control.md +0 -0
  250. {calkit_python-0.38.1 → calkit_python-0.38.2}/install.json +0 -0
  251. {calkit_python-0.38.1 → calkit_python-0.38.2}/jest.config.js +0 -0
  252. {calkit_python-0.38.1 → calkit_python-0.38.2}/jupyter-config/server-config/calkit.json +0 -0
  253. {calkit_python-0.38.1 → calkit_python-0.38.2}/mkdocs.yml +0 -0
  254. {calkit_python-0.38.1 → calkit_python-0.38.2}/package.json +0 -0
  255. {calkit_python-0.38.1 → calkit_python-0.38.2}/pyproject.toml +0 -0
  256. {calkit_python-0.38.1 → calkit_python-0.38.2}/schema/plugin.json +0 -0
  257. {calkit_python-0.38.1 → calkit_python-0.38.2}/scripts/generate-docs-references.py +0 -0
  258. {calkit_python-0.38.1 → calkit_python-0.38.2}/scripts/install.ps1 +0 -0
  259. {calkit_python-0.38.1 → calkit_python-0.38.2}/scripts/install.sh +0 -0
  260. {calkit_python-0.38.1 → calkit_python-0.38.2}/scripts/make-calk9.sh +0 -0
  261. {calkit_python-0.38.1 → calkit_python-0.38.2}/scripts/sync-docs.py +0 -0
  262. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/__tests__/useQueries.spec.ts +0 -0
  263. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/calkit-config.ts +0 -0
  264. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/cell-output-marker.ts +0 -0
  265. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/components/commit-dialog.tsx +0 -0
  266. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/components/environment-editor.tsx +0 -0
  267. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/components/notebook-registration.tsx +0 -0
  268. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/components/notebook-toolbar.tsx +0 -0
  269. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/components/pipeline-status-bar.tsx +0 -0
  270. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/components/project-info-editor.tsx +0 -0
  271. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/components/sidebar-settings.tsx +0 -0
  272. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/components/sidebar.tsx +0 -0
  273. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/components/stage-editor.tsx +0 -0
  274. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/feature-flags.ts +0 -0
  275. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/file-browser-menu.ts +0 -0
  276. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/hooks/__tests__/useQueries.test.tsx +0 -0
  277. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/hooks/useQueries.ts +0 -0
  278. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/icons.ts +0 -0
  279. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/index.ts +0 -0
  280. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/io-tracker.ts +0 -0
  281. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/pipeline-state.ts +0 -0
  282. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/queryClient.ts +0 -0
  283. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/request.ts +0 -0
  284. {calkit_python-0.38.1 → calkit_python-0.38.2}/src/shims-mainmenu.d.ts +0 -0
  285. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/base.css +0 -0
  286. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/cell-output-marker.css +0 -0
  287. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/environment-editor.css +0 -0
  288. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/environment-selector.css +0 -0
  289. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/img/calkit-no-bg.png +0 -0
  290. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/index.css +0 -0
  291. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/index.js +0 -0
  292. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/notebook-toolbar.css +0 -0
  293. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/pipeline-status-bar.css +0 -0
  294. {calkit_python-0.38.1 → calkit_python-0.38.2}/style/sidebar.css +0 -0
  295. {calkit_python-0.38.1 → calkit_python-0.38.2}/test/dvc-md5-dir/osx-arm64.txt +0 -0
  296. {calkit_python-0.38.1 → calkit_python-0.38.2}/test/nb-julia.ipynb +0 -0
  297. {calkit_python-0.38.1 → calkit_python-0.38.2}/test/nb-params.ipynb +0 -0
  298. {calkit_python-0.38.1 → calkit_python-0.38.2}/test/nb-subdir.ipynb +0 -0
  299. {calkit_python-0.38.1 → calkit_python-0.38.2}/test/pipeline.ipynb +0 -0
  300. {calkit_python-0.38.1 → calkit_python-0.38.2}/test/script.py +0 -0
  301. {calkit_python-0.38.1 → calkit_python-0.38.2}/test/test-log.log +0 -0
  302. {calkit_python-0.38.1 → calkit_python-0.38.2}/tsconfig.json +0 -0
  303. {calkit_python-0.38.1 → calkit_python-0.38.2}/tsconfig.test.json +0 -0
  304. {calkit_python-0.38.1 → calkit_python-0.38.2}/ui-tests/.gitignore +0 -0
  305. {calkit_python-0.38.1 → calkit_python-0.38.2}/ui-tests/README.md +0 -0
  306. {calkit_python-0.38.1 → calkit_python-0.38.2}/ui-tests/jupyter_server_test_config.py +0 -0
  307. {calkit_python-0.38.1 → calkit_python-0.38.2}/ui-tests/package.json +0 -0
  308. {calkit_python-0.38.1 → calkit_python-0.38.2}/ui-tests/playwright.config.js +0 -0
  309. {calkit_python-0.38.1 → calkit_python-0.38.2}/ui-tests/tests/calkit.spec.ts +0 -0
  310. {calkit_python-0.38.1 → calkit_python-0.38.2}/ui-tests/yarn.lock +0 -0
  311. {calkit_python-0.38.1 → calkit_python-0.38.2}/uv.lock +0 -0
  312. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/.gitignore +0 -0
  313. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/.vscodeignore +0 -0
  314. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/CHANGELOG.md +0 -0
  315. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/LICENSE +0 -0
  316. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/README.md +0 -0
  317. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/images/calkit-no-bg.png +0 -0
  318. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/package-lock.json +0 -0
  319. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/package.json +0 -0
  320. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/scripts/set-proposed-api.js +0 -0
  321. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/src/notebooks.ts +0 -0
  322. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/src/test/environments.test.ts +0 -0
  323. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/src/test/notebooks.test.ts +0 -0
  324. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/src/types.ts +0 -0
  325. {calkit_python-0.38.1 → calkit_python-0.38.2}/vscode-ext/tsconfig.json +0 -0
  326. {calkit_python-0.38.1 → calkit_python-0.38.2}/yarn.lock +0 -0
@@ -16,3 +16,5 @@ To sync the docs and format all the code, run `make format`.
16
16
 
17
17
  Wrap prose at natural breakpoints in phrases or punctuation to keep max
18
18
  line length below 80 characters.
19
+
20
+ Agents should never make commits to Git.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: calkit-python
3
- Version: 0.38.1
3
+ Version: 0.38.2
4
4
  Summary: Reproducibility simplified.
5
5
  Project-URL: Homepage, https://calkit.org
6
6
  Project-URL: Issues, https://github.com/calkit/calkit/issues
@@ -10,6 +10,7 @@ efficient.
10
10
  import json
11
11
  import os
12
12
  import shutil
13
+ import stat
13
14
  import subprocess
14
15
  import zipfile
15
16
  from pathlib import Path
@@ -376,9 +377,25 @@ def unzip(workspace_path: str, zip_path: str):
376
377
  "System unzip failed; falling back to Python zipfile.",
377
378
  err=True,
378
379
  )
380
+ workspace_abs = os.path.realpath(workspace_path)
379
381
  with ZipFile(zip_path, "r") as zip_file:
380
382
  members = zip_file.infolist()
381
383
  for member in tqdm(members, desc="Unzipping", unit="file"):
384
+ target = os.path.normpath(
385
+ os.path.join(workspace_abs, member.filename)
386
+ )
387
+ if not os.path.realpath(target).startswith(workspace_abs + os.sep):
388
+ raise ValueError(
389
+ f"Zip entry {member.filename!r} would extract outside "
390
+ "the workspace directory"
391
+ )
392
+ if os.path.isfile(target) and not os.access(target, os.W_OK):
393
+ # File may be read-only (e.g. created by Docker as root or by
394
+ # DVC). Try chmod first; if that fails, remove and re-extract.
395
+ try:
396
+ os.chmod(target, stat.S_IWRITE | stat.S_IREAD)
397
+ except OSError:
398
+ os.remove(target)
382
399
  zip_file.extract(member, workspace_path)
383
400
 
384
401
 
@@ -10,11 +10,13 @@ import subprocess
10
10
  import sys
11
11
  import tempfile
12
12
  import zipfile
13
+ from pathlib import Path
13
14
  from typing import Literal
14
15
 
15
16
  import git
16
17
 
17
18
  import calkit
19
+ import calkit.dvc.zip
18
20
 
19
21
  SERVICES = {
20
22
  "caltechdata": {"name": "CaltechDATA", "url": "https://data.caltech.edu"},
@@ -165,7 +167,42 @@ def ls_files() -> list[str]:
165
167
  fpath = os.path.join(root, filename)
166
168
  if os.path.isfile(fpath):
167
169
  cache_files.append(fpath)
168
- return list(dict.fromkeys(git_files + dvc_files + cache_files))
170
+ # Include files from unzipped dvc-zip workspace folders, which are
171
+ # ignored by both Git and DVC and would otherwise be missing from the
172
+ # release archive
173
+ dvc_zip_files: list[str] = []
174
+ repo_root = Path(repo.working_dir).resolve()
175
+ zip_path_map = calkit.dvc.zip.get_zip_path_map()
176
+ for workspace_path in zip_path_map:
177
+ abs_workspace = (repo_root / workspace_path).resolve()
178
+ if not abs_workspace.is_relative_to(repo_root):
179
+ raise ValueError(
180
+ f"dvc-zip workspace path {workspace_path!r} is not within "
181
+ "the repository root; this may indicate a bug or tampering "
182
+ "with .calkit/zip/paths.json"
183
+ )
184
+ if abs_workspace.is_dir():
185
+ for root, _, files in os.walk(abs_workspace):
186
+ for filename in files:
187
+ abs_fpath = Path(root) / filename
188
+ if abs_fpath.is_file():
189
+ dvc_zip_files.append(
190
+ str(abs_fpath.relative_to(repo_root))
191
+ )
192
+ elif abs_workspace.exists():
193
+ raise ValueError(
194
+ f"dvc-zip workspace path {workspace_path!r} exists but is "
195
+ "not a directory; this may indicate a bug or tampering with "
196
+ ".calkit/zip/paths.json"
197
+ )
198
+ zip_files = {Path(p).as_posix() for p in zip_path_map.values()}
199
+ return [
200
+ f
201
+ for f in dict.fromkeys(
202
+ git_files + dvc_files + cache_files + dvc_zip_files
203
+ )
204
+ if Path(f).as_posix() not in zip_files
205
+ ]
169
206
 
170
207
 
171
208
  def make_dvc_md5s(
@@ -205,7 +242,7 @@ def populate_dvc_cache():
205
242
  """Populate DVC cache from releases."""
206
243
  ck_info = calkit.load_calkit_info()
207
244
  releases = ck_info.get("releases", {})
208
- for name, release in releases.items():
245
+ for name, _ in releases.items():
209
246
  md5s_fpath = f".calkit/releases/{name}/dvc-md5s.yaml"
210
247
  with open(md5s_fpath) as f:
211
248
  md5s = calkit.ryaml.load(f)
@@ -9,6 +9,7 @@ import bibtexparser
9
9
  import git
10
10
  import pytest
11
11
 
12
+ from calkit.dvc.zip import write_zip_path_map
12
13
  from calkit.releases import (
13
14
  check_project_release_archive,
14
15
  create_bibtex,
@@ -66,6 +67,29 @@ def test_ls_files(tmp_dir):
66
67
  assert ".dvc/cache/aa/legacy" in files
67
68
  assert ".dvc/cache/files/md5/bb/modern" in files
68
69
  assert ".dvc/cache/runs/cc/hash/run" in files
70
+ # Ensure files from unzipped dvc-zip workspace folders are included;
71
+ # these folders are ignored by both Git and DVC
72
+ (tmp_dir / "my-zip-workspace" / "sub").mkdir(parents=True, exist_ok=True)
73
+ (tmp_dir / "my-zip-workspace" / "data.txt").write_text("data")
74
+ (tmp_dir / "my-zip-workspace" / "sub" / "nested.txt").write_text("nested")
75
+ # Create the zip file and DVC-track it so the exclusion filter is exercised
76
+ zip_dir = tmp_dir / ".calkit" / "zip" / "files"
77
+ zip_dir.mkdir(parents=True, exist_ok=True)
78
+ zip_fpath = zip_dir / "my-zip-workspace.zip"
79
+ with zipfile.ZipFile(zip_fpath, "w") as zf:
80
+ zf.writestr("data.txt", "data")
81
+ zf.writestr("sub/nested.txt", "nested")
82
+ subprocess.run(
83
+ ["calkit", "dvc", "add", str(zip_fpath.relative_to(tmp_dir))],
84
+ check=True,
85
+ )
86
+ write_zip_path_map(
87
+ {"my-zip-workspace": ".calkit/zip/files/my-zip-workspace.zip"}
88
+ )
89
+ files = ls_files()
90
+ assert "my-zip-workspace/data.txt" in files
91
+ assert "my-zip-workspace/sub/nested.txt" in files
92
+ assert ".calkit/zip/files/my-zip-workspace.zip" not in files
69
93
 
70
94
 
71
95
  def test_check_project_release_archive_passes_when_pipeline_is_current(
@@ -16,7 +16,9 @@ and our code of conduct can be found
16
16
 
17
17
  ## Vision
18
18
 
19
- We envision a future where nearly every research article is delivered as part
19
+ We envision a future where reliable and impactful knowledge is created
20
+ 10x faster than it is today.
21
+ In this future nearly every research article is delivered as part
20
22
  of a [single-button](https://petebachant.me/single-button/)
21
23
  reproducible
22
24
  [compendium](https://book.the-turing-way.org/reproducible-research/compendia/)
@@ -46,6 +48,10 @@ by enabling faster:
46
48
  making it easier to find something similar to a desired workflow to start
47
49
  from and adapt to new questions.
48
50
 
51
+ Most importantly,
52
+ full automation speeds up iteration cycle time,
53
+ and more iterations means greater likelihood of success.
54
+
49
55
  ### The status quo
50
56
 
51
57
  The figure below from the PLOS Open Science Indicators dataset
@@ -63,10 +69,15 @@ Code sharing rates from
63
69
 
64
70
  ## Strategy
65
71
 
66
- We believe one major hurdle preventing researchers from working reproducibly is
67
- the expectation that they become software engineering experts,
68
- choose and integrate multiple tools,
69
- and assemble a custom workflow.
72
+ Telling researchers they need to work reproducibly is like telling them
73
+ they need to eat their vegetables.
74
+ In other words, reproducibility needs to be a side effect of a process
75
+ that is more productive and more enjoyable than the status quo.
76
+
77
+ The current "gold standard"
78
+ requires researchers to become de facto software engineers,
79
+ choosing and integrating multiple tools,
80
+ designing bespoke project layouts and workflows.
70
81
  We want to provide a vertically-integrated, purpose-built,
71
82
  and user-friendly project format and toolset that reduces the required
72
83
  expertise and decision fatigue.
@@ -75,7 +86,7 @@ solution—they certainly are—but we are focused on improving
75
86
  tooling and infrastructure.
76
87
 
77
88
  - **Path of least resistance:**
78
- Make it faster to work in a clean,
89
+ Make it faster to work in a clean, automated,
79
90
  reproducible way than it is to work in an ad-hoc, disorganized way.
80
91
  - **Intuitive tooling:**
81
92
  Simplify the "hard parts" of modern scientific computing:
@@ -88,6 +99,9 @@ tooling and infrastructure.
88
99
  - **Builder's pride:**
89
100
  Enable researchers to take pride in what they create so
90
101
  they will be more likely to share their projects openly.
102
+ - **Continuous delivery:** Continuous delivery (CD) practices have greatly
103
+ enhanced the quality and speed at which software products are created.
104
+ These same principles can be applied to research.
91
105
 
92
106
  ## Objective and key results (OKRs)
93
107
 
@@ -223,3 +223,14 @@ export function findCalkitEnvKernelSourceCandidate(
223
223
  (candidate) => candidate.environmentName === environmentName,
224
224
  );
225
225
  }
226
+
227
+ // Environment kinds that can have their Jupyter kernel registered and selected
228
+ // natively in VS Code — no Jupyter server launch required.
229
+ export const kernelRegistrationKinds: ReadonlySet<EnvKind> = new Set<EnvKind>([
230
+ "uv",
231
+ "uv-venv",
232
+ "venv",
233
+ "conda",
234
+ "pixi",
235
+ "julia",
236
+ ]);
@@ -10,6 +10,7 @@ import {
10
10
  compactSlurmOptions,
11
11
  findCalkitEnvKernelSourceCandidate,
12
12
  getDefaultSlurmOptions,
13
+ kernelRegistrationKinds,
13
14
  makeCalkitEnvKernelSourceCandidates,
14
15
  slurmOptionsToOptionList,
15
16
  type CalkitEnvNotebookKernelSource,
@@ -440,6 +441,7 @@ async function selectCalkitEnvironment(
440
441
  picked.innerEnvironment,
441
442
  "-e",
442
443
  targetNotebookUri,
444
+ picked.innerKind,
443
445
  );
444
446
  await refreshNotebookToolbarContext(context);
445
447
  return kernelId;
@@ -472,7 +474,7 @@ async function selectCalkitEnvironment(
472
474
  slurmAutoStartSuppressedThisSession.delete(targetNotebookUri);
473
475
  }
474
476
 
475
- // For uv/julia in a non-nested setup, only register/check the kernel and
477
+ // For local/non-nested environments, only register/check the kernel and
476
478
  // then select it in VS Code. No server launch is needed here.
477
479
  if (
478
480
  !picked.outerSlurmEnvironment &&
@@ -483,6 +485,7 @@ async function selectCalkitEnvironment(
483
485
  picked.innerEnvironment,
484
486
  "-e",
485
487
  targetNotebookUri,
488
+ picked.innerKind,
486
489
  );
487
490
  await refreshNotebookToolbarContext(context);
488
491
  return kernelId;
@@ -1870,6 +1873,7 @@ async function autoSelectEnvironmentForActiveNotebook(
1870
1873
  configuredCandidate.innerEnvironment,
1871
1874
  "-e",
1872
1875
  notebookUri,
1876
+ configuredCandidate.innerKind,
1873
1877
  );
1874
1878
  if (kernelId) {
1875
1879
  log(
@@ -2225,7 +2229,7 @@ function buildDockerRunCommand(
2225
2229
  }
2226
2230
 
2227
2231
  function needsKernelRegistration(kind: EnvKind): boolean {
2228
- return kind === "uv" || kind === "julia";
2232
+ return kernelRegistrationKinds.has(kind);
2229
2233
  }
2230
2234
 
2231
2235
  function createServerToken(): string {
@@ -2389,8 +2393,9 @@ async function registerAndSelectKernel(
2389
2393
  envName: string,
2390
2394
  envFlag: "-n" | "-e",
2391
2395
  expectedNotebookUri?: string,
2396
+ kind?: EnvKind,
2392
2397
  ): Promise<string | undefined> {
2393
- log(`Registering and selecting kernel for env: ${envName}`);
2398
+ log(`Registering and selecting kernel for env: ${envName} (kind=${kind})`);
2394
2399
 
2395
2400
  return await withKernelProgress(
2396
2401
  "Checking environment and setting kernel...",
@@ -0,0 +1,88 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import {
4
+ kernelRegistrationKinds,
5
+ makeCalkitEnvKernelSourceCandidates,
6
+ type EnvKind,
7
+ } from "../environments";
8
+
9
+ const REGISTRATION_KINDS: EnvKind[] = [
10
+ "uv",
11
+ "uv-venv",
12
+ "venv",
13
+ "conda",
14
+ "pixi",
15
+ "julia",
16
+ ];
17
+
18
+ const SERVER_KINDS: EnvKind[] = ["docker", "slurm", "ssh", "_system"];
19
+
20
+ test("kernelRegistrationKinds includes all local env types", () => {
21
+ for (const kind of REGISTRATION_KINDS) {
22
+ assert.ok(
23
+ kernelRegistrationKinds.has(kind),
24
+ `expected '${kind}' to be in kernelRegistrationKinds`,
25
+ );
26
+ }
27
+ });
28
+
29
+ test("kernelRegistrationKinds excludes server-launch env types", () => {
30
+ for (const kind of SERVER_KINDS) {
31
+ assert.ok(
32
+ !kernelRegistrationKinds.has(kind),
33
+ `expected '${kind}' to NOT be in kernelRegistrationKinds`,
34
+ );
35
+ }
36
+ });
37
+
38
+ test("non-nested local env candidate has no outerSlurmEnvironment", () => {
39
+ // A standalone uv-venv env should produce a candidate with no outer
40
+ // SLURM environment, which is the signal that no server launch is needed.
41
+ const candidates = makeCalkitEnvKernelSourceCandidates({
42
+ main: { kind: "uv-venv", path: "pyproject.toml" },
43
+ });
44
+ assert.equal(candidates.length, 1);
45
+ assert.equal(candidates[0].innerKind, "uv-venv");
46
+ assert.equal(candidates[0].outerSlurmEnvironment, undefined);
47
+ assert.ok(kernelRegistrationKinds.has(candidates[0].innerKind));
48
+ });
49
+
50
+ test("nested slurm+uv-venv candidate has outerSlurmEnvironment set", () => {
51
+ // A SLURM-wrapped uv-venv env must still launch a server — the outer
52
+ // SLURM environment is what triggers that path. The guard in extension.ts
53
+ // is: !outerSlurmEnvironment && needsKernelRegistration(innerKind)
54
+ const candidates = makeCalkitEnvKernelSourceCandidates({
55
+ cluster: { kind: "slurm", host: "cluster.example.edu" },
56
+ main: { kind: "uv-venv", path: "pyproject.toml" },
57
+ });
58
+ const nested = candidates.find((c) => c.outerSlurmEnvironment === "cluster");
59
+ assert.ok(nested, "expected a nested slurm:uv-venv candidate");
60
+ assert.equal(nested.innerKind, "uv-venv");
61
+ assert.equal(nested.outerSlurmEnvironment, "cluster");
62
+ assert.ok(kernelRegistrationKinds.has(nested.innerKind));
63
+ assert.ok(nested.outerSlurmEnvironment !== undefined);
64
+ });
65
+
66
+ test("nested slurm+docker candidate has outerSlurmEnvironment set and docker does not use kernel registration", () => {
67
+ const candidates = makeCalkitEnvKernelSourceCandidates({
68
+ cluster: { kind: "slurm", host: "cluster.example.edu" },
69
+ myContainer: { kind: "docker", image: "jupyter/minimal-notebook:latest" },
70
+ });
71
+ const nested = candidates.find((c) => c.outerSlurmEnvironment === "cluster");
72
+ assert.ok(nested);
73
+ assert.equal(nested.innerKind, "docker");
74
+ assert.ok(!kernelRegistrationKinds.has(nested.innerKind));
75
+ });
76
+
77
+ test("all standalone registration-kind envs produce candidates with no outer env", () => {
78
+ const envs: Record<string, { kind: EnvKind }> = {};
79
+ for (const kind of REGISTRATION_KINDS) {
80
+ envs[kind] = { kind };
81
+ }
82
+ const candidates = makeCalkitEnvKernelSourceCandidates(envs);
83
+ for (const kind of REGISTRATION_KINDS) {
84
+ const c = candidates.find((x) => x.environmentName === kind);
85
+ assert.ok(c, `expected standalone candidate for kind '${kind}'`);
86
+ assert.equal(c.outerSlurmEnvironment, undefined);
87
+ }
88
+ });
File without changes
File without changes
File without changes