calkit-python 0.41.13__tar.gz → 0.41.14__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 (346) hide show
  1. {calkit_python-0.41.13 → calkit_python-0.41.14}/PKG-INFO +1 -1
  2. calkit_python-0.41.14/calkit/cli/delete.py +33 -0
  3. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/list.py +56 -1
  4. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/main/core.py +24 -5
  5. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/new.py +97 -0
  6. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/scheduler.py +20 -0
  7. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/detect.py +103 -2
  8. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/dvc/core.py +133 -57
  9. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/models/core.py +58 -5
  10. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/pipeline.py +25 -0
  11. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/main/test_core.py +103 -45
  12. calkit_python-0.41.14/calkit/tests/cli/main/test_lock.py +274 -0
  13. calkit_python-0.41.14/calkit/tests/cli/test_delete.py +23 -0
  14. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_list.py +46 -0
  15. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_new.py +48 -0
  16. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_scheduler.py +4 -0
  17. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/dvc/test_core.py +17 -36
  18. calkit_python-0.41.14/calkit/tests/models/test_core.py +25 -0
  19. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_detect.py +67 -0
  20. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/cli-reference.md +160 -14
  21. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/package.json +157 -2
  22. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/src/extension.ts +783 -127
  23. calkit_python-0.41.14/vscode-ext/src/figures.ts +40 -0
  24. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/src/sidebar.ts +255 -89
  25. calkit_python-0.41.14/vscode-ext/src/test/figures.test.ts +56 -0
  26. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/src/types.ts +14 -0
  27. {calkit_python-0.41.13 → calkit_python-0.41.14}/.claude-plugin/marketplace.json +0 -0
  28. {calkit_python-0.41.13 → calkit_python-0.41.14}/.gitattributes +0 -0
  29. {calkit_python-0.41.13 → calkit_python-0.41.14}/.gitignore +0 -0
  30. {calkit_python-0.41.13 → calkit_python-0.41.14}/.pre-commit-config.yaml +0 -0
  31. {calkit_python-0.41.13 → calkit_python-0.41.14}/.prettierignore +0 -0
  32. {calkit_python-0.41.13 → calkit_python-0.41.14}/.python-version +0 -0
  33. {calkit_python-0.41.13 → calkit_python-0.41.14}/.vscode/launch.json +0 -0
  34. {calkit_python-0.41.13 → calkit_python-0.41.14}/.vscode/tasks.json +0 -0
  35. {calkit_python-0.41.13 → calkit_python-0.41.14}/.yarnrc.yml +0 -0
  36. {calkit_python-0.41.13 → calkit_python-0.41.14}/AGENTS.md +0 -0
  37. {calkit_python-0.41.13 → calkit_python-0.41.14}/CITATION.cff +0 -0
  38. {calkit_python-0.41.13 → calkit_python-0.41.14}/CODE_OF_CONDUCT.md +0 -0
  39. {calkit_python-0.41.13 → calkit_python-0.41.14}/CONTRIBUTING.md +0 -0
  40. {calkit_python-0.41.13 → calkit_python-0.41.14}/LICENSE +0 -0
  41. {calkit_python-0.41.13 → calkit_python-0.41.14}/Makefile +0 -0
  42. {calkit_python-0.41.13 → calkit_python-0.41.14}/README.md +0 -0
  43. {calkit_python-0.41.13 → calkit_python-0.41.14}/agent-plugin/.claude-plugin/plugin.json +0 -0
  44. {calkit_python-0.41.13 → calkit_python-0.41.14}/agent-plugin/skills/add-pipeline-stage/SKILL.md +0 -0
  45. {calkit_python-0.41.13 → calkit_python-0.41.14}/agent-plugin/skills/conventions/SKILL.md +0 -0
  46. {calkit_python-0.41.13 → calkit_python-0.41.14}/agent-plugin/skills/create-pipeline/SKILL.md +0 -0
  47. {calkit_python-0.41.13 → calkit_python-0.41.14}/babel.config.js +0 -0
  48. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/__init__.py +0 -0
  49. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/__main__.py +0 -0
  50. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/calc.py +0 -0
  51. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/check.py +0 -0
  52. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/__init__.py +0 -0
  53. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/check.py +0 -0
  54. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/cloud.py +0 -0
  55. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/config.py +0 -0
  56. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/core.py +0 -0
  57. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/describe.py +0 -0
  58. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/dev.py +0 -0
  59. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/import_.py +0 -0
  60. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/latex.py +0 -0
  61. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/main/__init__.py +0 -0
  62. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/main/xr.py +0 -0
  63. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/notebooks.py +0 -0
  64. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/office.py +0 -0
  65. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/overleaf.py +0 -0
  66. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cli/update.py +0 -0
  67. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/cloud.py +0 -0
  68. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/conda.py +0 -0
  69. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/config.py +0 -0
  70. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/core.py +0 -0
  71. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/datasets.py +0 -0
  72. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/dependencies.py +0 -0
  73. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/docker.py +0 -0
  74. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/dvc/__init__.py +0 -0
  75. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/dvc/zip.py +0 -0
  76. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/environments.py +0 -0
  77. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/fs.py +0 -0
  78. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/git.py +0 -0
  79. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/github.py +0 -0
  80. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/gui.py +0 -0
  81. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/install.py +0 -0
  82. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/invenio.py +0 -0
  83. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/julia.py +0 -0
  84. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/jupyter.py +0 -0
  85. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/jupyterlab/__init__.py +0 -0
  86. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/jupyterlab/routes.py +0 -0
  87. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/package.json +0 -0
  88. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/schemas/calkit/package.json.orig +0 -0
  89. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/schemas/calkit/plugin.json +0 -0
  90. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
  91. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
  92. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
  93. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/909.e3f9cc3408834a7fdcc3.js +0 -0
  94. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
  95. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
  96. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
  97. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/remoteEntry.65469af996e7a96aa983.js +0 -0
  98. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/style.js +0 -0
  99. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/labextension/static/third-party-licenses.json +0 -0
  100. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/licenses.py +0 -0
  101. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/magics.py +0 -0
  102. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/matlab.py +0 -0
  103. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/models/__init__.py +0 -0
  104. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/models/io.py +0 -0
  105. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/models/iteration.py +0 -0
  106. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/models/pipeline.py +0 -0
  107. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/notebooks.py +0 -0
  108. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/office.py +0 -0
  109. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/ops.py +0 -0
  110. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/overleaf.py +0 -0
  111. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/releases.py +0 -0
  112. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/server.py +0 -0
  113. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/__init__.py +0 -0
  114. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/core.py +0 -0
  115. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/latex/__init__.py +0 -0
  116. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/latex/article/paper.tex +0 -0
  117. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/latex/core.py +0 -0
  118. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/latex/jfm/jfm.bst +0 -0
  119. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/latex/jfm/jfm.cls +0 -0
  120. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
  121. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/latex/jfm/paper.tex +0 -0
  122. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/templates/latex/jfm/upmath.sty +0 -0
  123. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/__init__.py +0 -0
  124. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/__init__.py +0 -0
  125. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/main/__init__.py +0 -0
  126. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/main/test_subprojects.py +0 -0
  127. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/main/test_xr.py +0 -0
  128. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_check.py +0 -0
  129. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_cloud.py +0 -0
  130. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_config.py +0 -0
  131. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_import.py +0 -0
  132. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_latex.py +0 -0
  133. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_notebooks.py +0 -0
  134. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_overleaf.py +0 -0
  135. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/cli/test_update.py +0 -0
  136. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/dvc/__init__.py +0 -0
  137. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/dvc/test_zip.py +0 -0
  138. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/jupyterlab/__init__.py +0 -0
  139. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/jupyterlab/test_routes.py +0 -0
  140. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/models/__init__.py +0 -0
  141. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/models/test_iteration.py +0 -0
  142. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/models/test_pipeline.py +0 -0
  143. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_calc.py +0 -0
  144. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_check.py +0 -0
  145. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_cloud.py +0 -0
  146. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_conda.py +0 -0
  147. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_core.py +0 -0
  148. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_dependencies.py +0 -0
  149. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_docker.py +0 -0
  150. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_environments.py +0 -0
  151. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_fs.py +0 -0
  152. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_git.py +0 -0
  153. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_install.py +0 -0
  154. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_invenio.py +0 -0
  155. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_julia.py +0 -0
  156. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_jupyter.py +0 -0
  157. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_licenses.py +0 -0
  158. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_magics.py +0 -0
  159. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_matlab.py +0 -0
  160. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_notebooks.py +0 -0
  161. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_pipeline.py +0 -0
  162. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_releases.py +0 -0
  163. {calkit_python-0.41.13 → calkit_python-0.41.14}/calkit/tests/test_templates.py +0 -0
  164. {calkit_python-0.41.13 → calkit_python-0.41.14}/conftest.py +0 -0
  165. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/CNAME +0 -0
  166. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/ai-tools.md +0 -0
  167. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/apps.md +0 -0
  168. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/calculations.md +0 -0
  169. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/calkit-yaml.md +0 -0
  170. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/cloud-integration.md +0 -0
  171. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/datasets.md +0 -0
  172. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/dependencies.md +0 -0
  173. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/environments.md +0 -0
  174. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/examples.md +0 -0
  175. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/governance.md +0 -0
  176. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/help.md +0 -0
  177. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/hpc.md +0 -0
  178. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/c-to-the-k-white.svg +0 -0
  179. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/calkit-fragmentation-compendium.png +0 -0
  180. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/calkit-no-bg.png +0 -0
  181. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/connect-zenodo.png +0 -0
  182. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/jupyterlab/all-green.png +0 -0
  183. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/jupyterlab/collect-data-stale.png +0 -0
  184. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/jupyterlab/new-env.png +0 -0
  185. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/jupyterlab/new-notebook.png +0 -0
  186. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/jupyterlab/pipeline-badge.png +0 -0
  187. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/jupyterlab-params.png +0 -0
  188. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/plos-osi-code-2024-03.png +0 -0
  189. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/img/vscode-nb-params.png +0 -0
  190. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/index.md +0 -0
  191. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/installation.md +0 -0
  192. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/jupyterlab.md +0 -0
  193. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/local-server.md +0 -0
  194. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/notebooks.md +0 -0
  195. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/overleaf.md +0 -0
  196. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/pipeline/index.md +0 -0
  197. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/pipeline/manual-steps.md +0 -0
  198. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/pipeline/running-and-logging.md +0 -0
  199. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/quickstart.md +0 -0
  200. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/references.md +0 -0
  201. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/releases.md +0 -0
  202. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/reproducibility.md +0 -0
  203. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/subprojects.md +0 -0
  204. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/adding-latex-pub-docker.md +0 -0
  205. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/ai-agents.md +0 -0
  206. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/conda-envs.md +0 -0
  207. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/existing-project.md +0 -0
  208. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/first-project.md +0 -0
  209. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/github-actions.md +0 -0
  210. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/actions-repo-secrets.png +0 -0
  211. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
  212. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
  213. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
  214. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
  215. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
  216. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
  217. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
  218. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
  219. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
  220. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
  221. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/push.png +0 -0
  222. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
  223. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
  224. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/chart-more-rows.png +0 -0
  225. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/create-project.png +0 -0
  226. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
  227. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/excel-chart.png +0 -0
  228. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/excel-data.png +0 -0
  229. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
  230. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/needs-clone.png +0 -0
  231. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/new-stage.png +0 -0
  232. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
  233. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
  234. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/status-more-rows.png +0 -0
  235. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
  236. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/untracked-data.png +0 -0
  237. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/updated-publication.png +0 -0
  238. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
  239. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/office/workflow-page.png +0 -0
  240. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/openfoam/clone.png +0 -0
  241. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/openfoam/create-project.png +0 -0
  242. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
  243. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
  244. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
  245. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/openfoam/new-token.png +0 -0
  246. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/openfoam/reclone.png +0 -0
  247. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
  248. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/quick-actions.png +0 -0
  249. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/run-proc.png +0 -0
  250. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/vscode-slurm-notebook/create-calkit-env.png +0 -0
  251. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/vscode-slurm-notebook/create-inner-env.png +0 -0
  252. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/vscode-slurm-notebook/create-new-calkit-env.png +0 -0
  253. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/vscode-slurm-notebook/select-calkit-env.png +0 -0
  254. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/vscode-slurm-notebook/slurm-job-running.png +0 -0
  255. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/vscode-slurm-notebook/slurm-launch-options.png +0 -0
  256. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/img/vscode-slurm-notebook/starting-slurm-job.png +0 -0
  257. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/index.md +0 -0
  258. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/jupyterlab.md +0 -0
  259. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/latex-codespaces.md +0 -0
  260. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/matlab.md +0 -0
  261. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/notebook-pipeline.md +0 -0
  262. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/office.md +0 -0
  263. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/openfoam.md +0 -0
  264. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/procedures.md +0 -0
  265. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/tutorials/vscode-slurm-notebook.md +0 -0
  266. {calkit_python-0.41.13 → calkit_python-0.41.14}/docs/version-control.md +0 -0
  267. {calkit_python-0.41.13 → calkit_python-0.41.14}/flake.lock +0 -0
  268. {calkit_python-0.41.13 → calkit_python-0.41.14}/flake.nix +0 -0
  269. {calkit_python-0.41.13 → calkit_python-0.41.14}/install.json +0 -0
  270. {calkit_python-0.41.13 → calkit_python-0.41.14}/jest.config.js +0 -0
  271. {calkit_python-0.41.13 → calkit_python-0.41.14}/jupyter-config/server-config/calkit.json +0 -0
  272. {calkit_python-0.41.13 → calkit_python-0.41.14}/mkdocs.yml +0 -0
  273. {calkit_python-0.41.13 → calkit_python-0.41.14}/package.json +0 -0
  274. {calkit_python-0.41.13 → calkit_python-0.41.14}/pyproject.toml +0 -0
  275. {calkit_python-0.41.13 → calkit_python-0.41.14}/schema/plugin.json +0 -0
  276. {calkit_python-0.41.13 → calkit_python-0.41.14}/scripts/generate-docs-references.py +0 -0
  277. {calkit_python-0.41.13 → calkit_python-0.41.14}/scripts/install.ps1 +0 -0
  278. {calkit_python-0.41.13 → calkit_python-0.41.14}/scripts/install.sh +0 -0
  279. {calkit_python-0.41.13 → calkit_python-0.41.14}/scripts/make-calk9.sh +0 -0
  280. {calkit_python-0.41.13 → calkit_python-0.41.14}/scripts/sync-docs.py +0 -0
  281. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/__tests__/useQueries.spec.ts +0 -0
  282. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/calkit-config.ts +0 -0
  283. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/cell-output-marker.ts +0 -0
  284. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/components/commit-dialog.tsx +0 -0
  285. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/components/environment-editor.tsx +0 -0
  286. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/components/notebook-registration.tsx +0 -0
  287. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/components/notebook-toolbar.tsx +0 -0
  288. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/components/pipeline-status-bar.tsx +0 -0
  289. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/components/project-info-editor.tsx +0 -0
  290. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/components/sidebar-settings.tsx +0 -0
  291. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/components/sidebar.tsx +0 -0
  292. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/components/stage-editor.tsx +0 -0
  293. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/feature-flags.ts +0 -0
  294. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/file-browser-menu.ts +0 -0
  295. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/hooks/__tests__/useQueries.test.tsx +0 -0
  296. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/hooks/useQueries.ts +0 -0
  297. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/icons.ts +0 -0
  298. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/index.ts +0 -0
  299. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/io-tracker.ts +0 -0
  300. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/pipeline-state.ts +0 -0
  301. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/queryClient.ts +0 -0
  302. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/request.ts +0 -0
  303. {calkit_python-0.41.13 → calkit_python-0.41.14}/src/shims-mainmenu.d.ts +0 -0
  304. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/base.css +0 -0
  305. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/cell-output-marker.css +0 -0
  306. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/environment-editor.css +0 -0
  307. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/environment-selector.css +0 -0
  308. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/img/calkit-no-bg.png +0 -0
  309. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/index.css +0 -0
  310. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/index.js +0 -0
  311. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/notebook-toolbar.css +0 -0
  312. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/pipeline-status-bar.css +0 -0
  313. {calkit_python-0.41.13 → calkit_python-0.41.14}/style/sidebar.css +0 -0
  314. {calkit_python-0.41.13 → calkit_python-0.41.14}/test/dvc-md5-dir/osx-arm64.txt +0 -0
  315. {calkit_python-0.41.13 → calkit_python-0.41.14}/test/nb-julia.ipynb +0 -0
  316. {calkit_python-0.41.13 → calkit_python-0.41.14}/test/nb-params.ipynb +0 -0
  317. {calkit_python-0.41.13 → calkit_python-0.41.14}/test/nb-subdir.ipynb +0 -0
  318. {calkit_python-0.41.13 → calkit_python-0.41.14}/test/pipeline.ipynb +0 -0
  319. {calkit_python-0.41.13 → calkit_python-0.41.14}/test/script.py +0 -0
  320. {calkit_python-0.41.13 → calkit_python-0.41.14}/test/test-log.log +0 -0
  321. {calkit_python-0.41.13 → calkit_python-0.41.14}/tsconfig.json +0 -0
  322. {calkit_python-0.41.13 → calkit_python-0.41.14}/tsconfig.test.json +0 -0
  323. {calkit_python-0.41.13 → calkit_python-0.41.14}/ui-tests/.gitignore +0 -0
  324. {calkit_python-0.41.13 → calkit_python-0.41.14}/ui-tests/README.md +0 -0
  325. {calkit_python-0.41.13 → calkit_python-0.41.14}/ui-tests/jupyter_server_test_config.py +0 -0
  326. {calkit_python-0.41.13 → calkit_python-0.41.14}/ui-tests/package.json +0 -0
  327. {calkit_python-0.41.13 → calkit_python-0.41.14}/ui-tests/playwright.config.js +0 -0
  328. {calkit_python-0.41.13 → calkit_python-0.41.14}/ui-tests/tests/calkit.spec.ts +0 -0
  329. {calkit_python-0.41.13 → calkit_python-0.41.14}/ui-tests/yarn.lock +0 -0
  330. {calkit_python-0.41.13 → calkit_python-0.41.14}/uv.lock +0 -0
  331. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/.gitignore +0 -0
  332. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/.vscodeignore +0 -0
  333. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/CHANGELOG.md +0 -0
  334. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/LICENSE +0 -0
  335. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/README.md +0 -0
  336. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/images/calkit-icon.svg +0 -0
  337. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/images/calkit-no-bg.png +0 -0
  338. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/package-lock.json +0 -0
  339. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/scripts/set-proposed-api.js +0 -0
  340. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/src/environments.ts +0 -0
  341. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/src/notebooks.ts +0 -0
  342. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/src/test/environments.test.ts +0 -0
  343. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/src/test/kernel-selection.test.ts +0 -0
  344. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/src/test/notebooks.test.ts +0 -0
  345. {calkit_python-0.41.13 → calkit_python-0.41.14}/vscode-ext/tsconfig.json +0 -0
  346. {calkit_python-0.41.13 → calkit_python-0.41.14}/yarn.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: calkit-python
3
- Version: 0.41.13
3
+ Version: 0.41.14
4
4
  Summary: Reproducibility simplified.
5
5
  Project-URL: Homepage, https://calkit.org
6
6
  Project-URL: Issues, https://github.com/calkit/calkit/issues
@@ -0,0 +1,33 @@
1
+ """CLI for deleting objects."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import typer
6
+
7
+ import calkit
8
+ from calkit.cli import AliasGroup, raise_error
9
+ from calkit.core import ryaml
10
+
11
+ delete_app = typer.Typer(cls=AliasGroup, no_args_is_help=True)
12
+
13
+
14
+ @delete_app.command(name="question")
15
+ def delete_question(
16
+ index: int = typer.Argument(
17
+ ...,
18
+ help="1-based index of the question to remove (see `calkit list questions`).",
19
+ ),
20
+ ):
21
+ """Remove a question by its 1-based index."""
22
+ ck_info = calkit.load_calkit_info()
23
+ questions = ck_info.get("questions", []) or []
24
+ if index < 1 or index > len(questions):
25
+ raise_error(
26
+ f"Invalid question index {index}; "
27
+ f"there are {len(questions)} question(s)."
28
+ )
29
+ removed = questions.pop(index - 1)
30
+ ck_info["questions"] = questions
31
+ with open("calkit.yaml", "w") as f:
32
+ ryaml.dump(ck_info, f)
33
+ typer.echo(f"Removed question: {removed}")
@@ -55,7 +55,7 @@ def _list_objects(
55
55
 
56
56
 
57
57
  def _list_artifacts(
58
- kind: Literal["figures", "datasets"],
58
+ kind: Literal["figures", "datasets", "results", "presentations"],
59
59
  json_output: bool,
60
60
  declared_only: bool,
61
61
  ):
@@ -134,6 +134,61 @@ def list_datasets(
134
134
  _list_artifacts("datasets", json_output, declared_only)
135
135
 
136
136
 
137
+ @list_app.command(name="results")
138
+ def list_results(
139
+ json_output: Annotated[
140
+ bool, typer.Option("--json", help="Output result as JSON.")
141
+ ] = False,
142
+ declared_only: Annotated[
143
+ bool,
144
+ typer.Option(
145
+ "--declared-only",
146
+ help=(
147
+ "Only list results declared in calkit.yaml; "
148
+ "skip auto-detection."
149
+ ),
150
+ ),
151
+ ] = False,
152
+ ):
153
+ """List results in the project."""
154
+ _list_artifacts("results", json_output, declared_only)
155
+
156
+
157
+ @list_app.command(name="presentations|pres")
158
+ def list_presentations(
159
+ json_output: Annotated[
160
+ bool, typer.Option("--json", help="Output result as JSON.")
161
+ ] = False,
162
+ declared_only: Annotated[
163
+ bool,
164
+ typer.Option(
165
+ "--declared-only",
166
+ help=(
167
+ "Only list presentations declared in calkit.yaml; "
168
+ "skip auto-detection."
169
+ ),
170
+ ),
171
+ ] = False,
172
+ ):
173
+ """List presentations in the project."""
174
+ _list_artifacts("presentations", json_output, declared_only)
175
+
176
+
177
+ @list_app.command(name="questions")
178
+ def list_questions(
179
+ json_output: Annotated[
180
+ bool, typer.Option("--json", help="Output result as JSON.")
181
+ ] = False,
182
+ ):
183
+ """List the project's questions (1-indexed)."""
184
+ questions = calkit.load_calkit_info().get("questions", []) or []
185
+ if json_output:
186
+ typer.echo(json.dumps(questions))
187
+ return
188
+ for n, question in enumerate(questions, start=1):
189
+ typer.echo(f"{n}. {question}")
190
+
191
+
137
192
  @list_app.command(name="publications|pubs")
138
193
  def list_publications():
139
194
  """List publications in the project."""
@@ -48,6 +48,7 @@ from calkit.cli.check import (
48
48
  )
49
49
  from calkit.cli.cloud import cloud_app
50
50
  from calkit.cli.config import config_app
51
+ from calkit.cli.delete import delete_app
51
52
  from calkit.cli.describe import describe_app
52
53
  from calkit.cli.dev import dev_app
53
54
  from calkit.cli.import_ import import_app
@@ -69,6 +70,7 @@ app = typer.Typer(
69
70
  )
70
71
  app.add_typer(config_app, name="config", help="Configure Calkit.")
71
72
  app.add_typer(new_app, name="new|create", help="Create a new Calkit object.")
73
+ app.add_typer(delete_app, name="delete|rm", help="Delete a Calkit object.")
72
74
  app.add_typer(
73
75
  notebooks_app, name="notebooks|nb", help="Work with Jupyter notebooks."
74
76
  )
@@ -1172,7 +1174,10 @@ def pull(
1172
1174
  and "-R" not in dvc_args
1173
1175
  ):
1174
1176
  dvc_args.append("--recursive")
1175
- result = calkit.dvc.run_dvc_command(["pull"] + dvc_args, lock_retries=5)
1177
+ result = calkit.dvc.run_dvc_command(
1178
+ ["pull"] + dvc_args,
1179
+ lock_timeout=calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT,
1180
+ )
1176
1181
  if result != 0:
1177
1182
  raise_error("DVC pull failed")
1178
1183
  calkit.dvc.zip.sync_all(direction="to-workspace")
@@ -1187,7 +1192,9 @@ def pull(
1187
1192
  continue
1188
1193
  typer.echo(f"DVC pulling subproject: {sp_path}")
1189
1194
  sp_result = calkit.dvc.run_dvc_command(
1190
- ["pull"] + dvc_args, cwd=sp_path, lock_retries=5
1195
+ ["pull"] + dvc_args,
1196
+ cwd=sp_path,
1197
+ lock_timeout=calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT,
1191
1198
  )
1192
1199
  if sp_result != 0:
1193
1200
  raise_error(f"DVC pull failed for subproject: {sp_path}")
@@ -1225,7 +1232,8 @@ def push(
1225
1232
  if remotes:
1226
1233
  typer.echo("Pushing to DVC remote")
1227
1234
  result = calkit.dvc.run_dvc_command(
1228
- ["push"] + dvc_args, lock_retries=5
1235
+ ["push"] + dvc_args,
1236
+ lock_timeout=calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT,
1229
1237
  )
1230
1238
  if result != 0:
1231
1239
  raise_error("DVC push failed")
@@ -2035,7 +2043,10 @@ def run(
2035
2043
  original_dir = os.getcwd()
2036
2044
  try:
2037
2045
  os.chdir(sp_path)
2038
- sp_res = dvc_cli_main(["repro"] + sp_args)
2046
+ with calkit.dvc.dvc_lock_timeout(
2047
+ calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT
2048
+ ):
2049
+ sp_res = dvc_cli_main(["repro"] + sp_args)
2039
2050
  finally:
2040
2051
  os.chdir(original_dir)
2041
2052
  if sp_res != 0:
@@ -2104,7 +2115,15 @@ def run(
2104
2115
  if force:
2105
2116
  os.environ["CALKIT_FORCE"] = "1"
2106
2117
  try:
2107
- res = dvc_cli_main(["repro"] + args)
2118
+ # Wait generously for the repo lock instead of failing after DVC's 3s
2119
+ # default. Brief contention is common and benign: a background
2120
+ # `calkit status` poller (e.g. the VS Code extension), a stage whose
2121
+ # command is itself `calkit run`, or DVC's own per-stage re-lock (DVC
2122
+ # releases the repo lock while a stage command runs and re-acquires it
2123
+ # the instant it finishes) can all hold it momentarily. Without this,
2124
+ # such a collision aborts the whole run with "Unable to acquire lock".
2125
+ with calkit.dvc.dvc_lock_timeout(calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT):
2126
+ res = dvc_cli_main(["repro"] + args)
2108
2127
  finally:
2109
2128
  os.environ.pop("CALKIT_FORCE", None)
2110
2129
  failed = failed or res != 0
@@ -9,6 +9,7 @@ import shutil
9
9
  import subprocess
10
10
  import time
11
11
  from enum import Enum
12
+ from typing import Literal
12
13
 
13
14
  import typer
14
15
  from typing_extensions import Annotated
@@ -591,6 +592,102 @@ def new_figure(
591
592
  repo.git.commit(["-m", f"Add figure {path}"])
592
593
 
593
594
 
595
+ def _new_simple_artifact(
596
+ kind: Literal["results", "presentations"],
597
+ path: str,
598
+ title: str,
599
+ description: str | None,
600
+ stage_name: str | None,
601
+ no_commit: bool,
602
+ overwrite: bool,
603
+ ) -> None:
604
+ """Declare a simple artifact (path/title/description/stage) in calkit.yaml."""
605
+ singular = kind.rstrip("s")
606
+ ck_info = calkit.load_calkit_info()
607
+ objects = ck_info.get(kind, [])
608
+ paths = [o.get("path") for o in objects]
609
+ if not overwrite and path in paths:
610
+ raise_error(f"{singular.capitalize()} at path {path} already exists")
611
+ if overwrite and path in paths:
612
+ objects = [o for o in objects if o.get("path") != path]
613
+ obj = dict(path=path, title=title)
614
+ if description is not None:
615
+ obj["description"] = description
616
+ if stage_name is not None:
617
+ obj["stage"] = stage_name
618
+ objects.append(obj)
619
+ ck_info[kind] = objects
620
+ with open("calkit.yaml", "w") as f:
621
+ ryaml.dump(ck_info, f)
622
+ if not no_commit:
623
+ repo = calkit.git.get_repo()
624
+ repo.git.add("calkit.yaml")
625
+ if repo.git.diff("--staged"):
626
+ repo.git.commit(["-m", f"Add {singular} {path}"])
627
+
628
+
629
+ @new_app.command(name="result")
630
+ def new_result(
631
+ path: str,
632
+ title: Annotated[str, typer.Option("--title")],
633
+ description: Annotated[str | None, typer.Option("--description")] = None,
634
+ stage_name: Annotated[
635
+ str | None,
636
+ typer.Option(
637
+ "--stage",
638
+ help="Name of the pipeline stage that generates this result.",
639
+ ),
640
+ ] = None,
641
+ no_commit: Annotated[bool, typer.Option("--no-commit")] = False,
642
+ overwrite: Annotated[
643
+ bool,
644
+ typer.Option(
645
+ "--overwrite",
646
+ "-f",
647
+ help="Overwrite existing result if one exists.",
648
+ ),
649
+ ] = False,
650
+ ):
651
+ """Declare a new result."""
652
+ _new_simple_artifact(
653
+ "results", path, title, description, stage_name, no_commit, overwrite
654
+ )
655
+
656
+
657
+ @new_app.command(name="presentation|pres")
658
+ def new_presentation(
659
+ path: str,
660
+ title: Annotated[str, typer.Option("--title")],
661
+ description: Annotated[str | None, typer.Option("--description")] = None,
662
+ stage_name: Annotated[
663
+ str | None,
664
+ typer.Option(
665
+ "--stage",
666
+ help="Name of the pipeline stage that generates this presentation.",
667
+ ),
668
+ ] = None,
669
+ no_commit: Annotated[bool, typer.Option("--no-commit")] = False,
670
+ overwrite: Annotated[
671
+ bool,
672
+ typer.Option(
673
+ "--overwrite",
674
+ "-f",
675
+ help="Overwrite existing presentation if one exists.",
676
+ ),
677
+ ] = False,
678
+ ):
679
+ """Declare a new presentation."""
680
+ _new_simple_artifact(
681
+ "presentations",
682
+ path,
683
+ title,
684
+ description,
685
+ stage_name,
686
+ no_commit,
687
+ overwrite,
688
+ )
689
+
690
+
594
691
  @new_app.command("question")
595
692
  def new_question(
596
693
  question: str,
@@ -77,6 +77,23 @@ def _record_job(name: str, info: dict) -> None:
77
77
  jobs[name] = info
78
78
 
79
79
 
80
+ def _delete_job(name: str) -> None:
81
+ """Remove a job record from the database.
82
+
83
+ Used when a job is canceled (e.g. the user hits Ctrl+C while waiting for
84
+ it). Without this the record would linger, and the next ``calkit run``
85
+ would find the job gone from the queue with no exit status and wrongly
86
+ treat it as successful instead of resubmitting it.
87
+ """
88
+ if not os.path.isfile(JOBS_DB_PATH):
89
+ return
90
+ with SqliteDict(
91
+ JOBS_DB_PATH, autocommit=True, timeout=JOBS_DB_TIMEOUT
92
+ ) as jobs:
93
+ if name in jobs:
94
+ del jobs[name]
95
+
96
+
80
97
  def _mock_enabled() -> bool:
81
98
  """Whether scheduler commands should run jobs locally.
82
99
 
@@ -390,6 +407,9 @@ def _wait_until_done(kind: str, job_id: str, name: str) -> int | None:
390
407
  ok, stderr = _cancel(kind, job_id)
391
408
  if not ok:
392
409
  typer.echo(f"Failed to cancel job '{name}' ({job_id}): {stderr}")
410
+ # Drop the record so the next run resubmits this job instead of
411
+ # mistaking the canceled job (which has no exit status) for a success.
412
+ _delete_job(name)
393
413
  raise typer.Exit(130)
394
414
 
395
415
 
@@ -1837,6 +1837,31 @@ DATASET_EXTENSIONS = {
1837
1837
  ".ndjson",
1838
1838
  }
1839
1839
  DATA_DIRS = {"data", "datasets", "dataset"}
1840
+ RESULT_DIRS = {"results", "result"}
1841
+ RESULT_EXTENSIONS = {
1842
+ ".json",
1843
+ ".csv",
1844
+ ".tsv",
1845
+ ".yaml",
1846
+ ".yml",
1847
+ ".parquet",
1848
+ ".h5",
1849
+ ".hdf5",
1850
+ ".txt",
1851
+ ".html",
1852
+ }
1853
+ PRESENTATION_DIRS = {"presentations", "presentation", "slides", "talks"}
1854
+ PRESENTATION_EXTENSIONS = {".pdf", ".pptx", ".key"}
1855
+ # Files that look like a presentation regardless of which directory they live in.
1856
+ PRESENTATION_NAMES = {
1857
+ "slides.pdf",
1858
+ "slides.pptx",
1859
+ "slides.key",
1860
+ "presentation.pdf",
1861
+ "presentation.pptx",
1862
+ "presentation.key",
1863
+ "talk.pdf",
1864
+ }
1840
1865
 
1841
1866
 
1842
1867
  def _ancestor_dir_names(rel_path: str) -> set[str]:
@@ -1871,6 +1896,37 @@ def is_dataset_path(rel_path: str) -> bool:
1871
1896
  )
1872
1897
 
1873
1898
 
1899
+ def is_result_path(rel_path: str) -> bool:
1900
+ """Whether a repo-relative path looks like an auto-detectable result.
1901
+
1902
+ A result is a data-like file (JSON, CSV, etc.) under a ``results``-style
1903
+ directory. Anything already detected as a figure or dataset is excluded.
1904
+ """
1905
+ return (
1906
+ _path_ext(rel_path) in RESULT_EXTENSIONS
1907
+ and bool(_ancestor_dir_names(rel_path) & RESULT_DIRS)
1908
+ and not is_figure_path(rel_path)
1909
+ and not is_dataset_path(rel_path)
1910
+ )
1911
+
1912
+
1913
+ def is_presentation_path(rel_path: str) -> bool:
1914
+ """Whether a repo-relative path looks like an auto-detectable presentation.
1915
+
1916
+ Either a slide-deck file (PDF/PPTX/KEY) under a ``slides``/``presentations``
1917
+ directory, or a file with a presentation-like name (e.g. ``slides.pdf``,
1918
+ ``presentation.pdf``) anywhere. Figures are excluded.
1919
+ """
1920
+ if is_figure_path(rel_path):
1921
+ return False
1922
+ name = rel_path.rsplit("/", 1)[-1].lower()
1923
+ if name in PRESENTATION_NAMES:
1924
+ return True
1925
+ return _path_ext(rel_path) in PRESENTATION_EXTENSIONS and bool(
1926
+ _ancestor_dir_names(rel_path) & PRESENTATION_DIRS
1927
+ )
1928
+
1929
+
1874
1930
  def _is_hidden_path(rel_path: str) -> bool:
1875
1931
  return any(part.startswith(".") for part in rel_path.split("/"))
1876
1932
 
@@ -1949,6 +2005,44 @@ def detect_datasets(
1949
2005
  return _collapse_dataset_folders(sorted(files))
1950
2006
 
1951
2007
 
2008
+ def detect_results(
2009
+ candidate_paths: list[str],
2010
+ reserved_paths: list[str] | tuple[str, ...] = (),
2011
+ ) -> list[str]:
2012
+ """Auto-detected result paths among ``candidate_paths``.
2013
+
2014
+ Paths under a dot-directory or under one of ``reserved_paths`` (declared
2015
+ artifacts) are skipped.
2016
+ """
2017
+ reserved = list(reserved_paths)
2018
+ return sorted(
2019
+ {
2020
+ p
2021
+ for p in candidate_paths
2022
+ if not _is_hidden_path(p)
2023
+ and not _is_under_any_dir(p, reserved)
2024
+ and is_result_path(p)
2025
+ }
2026
+ )
2027
+
2028
+
2029
+ def detect_presentations(
2030
+ candidate_paths: list[str],
2031
+ reserved_paths: list[str] | tuple[str, ...] = (),
2032
+ ) -> list[str]:
2033
+ """Auto-detected presentation paths among ``candidate_paths``."""
2034
+ reserved = list(reserved_paths)
2035
+ return sorted(
2036
+ {
2037
+ p
2038
+ for p in candidate_paths
2039
+ if not _is_hidden_path(p)
2040
+ and not _is_under_any_dir(p, reserved)
2041
+ and is_presentation_path(p)
2042
+ }
2043
+ )
2044
+
2045
+
1952
2046
  def list_repo_files(wdir: str | None = None) -> list[str]:
1953
2047
  """Repo-relative paths of files Git does not ignore.
1954
2048
 
@@ -2014,7 +2108,7 @@ def _reserved_artifact_paths(
2014
2108
  if ck_info is None:
2015
2109
  ck_info = calkit.load_calkit_info(wdir=wdir)
2016
2110
  paths: list[str] = []
2017
- for kind in ("figures", "datasets"):
2111
+ for kind in ("figures", "datasets", "results", "presentations"):
2018
2112
  for obj in ck_info.get(kind, []) or []:
2019
2113
  if isinstance(obj, dict) and isinstance(obj.get("path"), str):
2020
2114
  paths.append(obj["path"])
@@ -2044,4 +2138,11 @@ def detect_project_artifacts(
2044
2138
  datasets = detect_datasets(
2045
2139
  candidates, reserved_paths=reserved, figure_paths=figures
2046
2140
  )
2047
- return {"figures": figures, "datasets": datasets}
2141
+ results = detect_results(candidates, reserved_paths=reserved)
2142
+ presentations = detect_presentations(candidates, reserved_paths=reserved)
2143
+ return {
2144
+ "figures": figures,
2145
+ "datasets": datasets,
2146
+ "results": results,
2147
+ "presentations": presentations,
2148
+ }