calkit-python 0.41.15__tar.gz → 0.41.16__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 (350) hide show
  1. {calkit_python-0.41.15 → calkit_python-0.41.16}/.gitignore +2 -0
  2. {calkit_python-0.41.15 → calkit_python-0.41.16}/.pre-commit-config.yaml +0 -2
  3. {calkit_python-0.41.15 → calkit_python-0.41.16}/.prettierignore +0 -1
  4. calkit_python-0.41.16/.prettierrc.json +6 -0
  5. {calkit_python-0.41.15 → calkit_python-0.41.16}/Makefile +12 -10
  6. {calkit_python-0.41.15 → calkit_python-0.41.16}/PKG-INFO +1 -1
  7. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/config.py +53 -6
  8. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/detect.py +64 -0
  9. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/environments.py +18 -2
  10. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/package.json +3 -23
  11. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/schemas/calkit/package.json.orig +2 -22
  12. calkit_python-0.41.15/calkit/labextension/static/remoteEntry.65469af996e7a96aa983.js → calkit_python-0.41.16/calkit/labextension/static/remoteEntry.ac9035764d5b2adbb542.js +1 -1
  13. {calkit_python-0.41.15 → calkit_python-0.41.16/calkit/tests/jupyterlab}/conftest.py +1 -2
  14. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_detect.py +49 -0
  15. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/package.json +2 -22
  16. {calkit_python-0.41.15 → calkit_python-0.41.16}/pyproject.toml +9 -7
  17. {calkit_python-0.41.15 → calkit_python-0.41.16}/.claude-plugin/marketplace.json +0 -0
  18. {calkit_python-0.41.15 → calkit_python-0.41.16}/.gitattributes +0 -0
  19. {calkit_python-0.41.15 → calkit_python-0.41.16}/.python-version +0 -0
  20. {calkit_python-0.41.15 → calkit_python-0.41.16}/.vscode/launch.json +0 -0
  21. {calkit_python-0.41.15 → calkit_python-0.41.16}/.vscode/tasks.json +0 -0
  22. {calkit_python-0.41.15 → calkit_python-0.41.16}/AGENTS.md +0 -0
  23. {calkit_python-0.41.15 → calkit_python-0.41.16}/CITATION.cff +0 -0
  24. {calkit_python-0.41.15 → calkit_python-0.41.16}/CODE_OF_CONDUCT.md +0 -0
  25. {calkit_python-0.41.15 → calkit_python-0.41.16}/CONTRIBUTING.md +0 -0
  26. {calkit_python-0.41.15 → calkit_python-0.41.16}/LICENSE +0 -0
  27. {calkit_python-0.41.15 → calkit_python-0.41.16}/README.md +0 -0
  28. {calkit_python-0.41.15 → calkit_python-0.41.16}/agent-plugin/.claude-plugin/plugin.json +0 -0
  29. {calkit_python-0.41.15 → calkit_python-0.41.16}/agent-plugin/skills/add-pipeline-stage/SKILL.md +0 -0
  30. {calkit_python-0.41.15 → calkit_python-0.41.16}/agent-plugin/skills/conventions/SKILL.md +0 -0
  31. {calkit_python-0.41.15 → calkit_python-0.41.16}/agent-plugin/skills/create-pipeline/SKILL.md +0 -0
  32. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/__init__.py +0 -0
  33. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/__main__.py +0 -0
  34. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/calc.py +0 -0
  35. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/check.py +0 -0
  36. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/__init__.py +0 -0
  37. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/check.py +0 -0
  38. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/cloud.py +0 -0
  39. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/core.py +0 -0
  40. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/delete.py +0 -0
  41. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/describe.py +0 -0
  42. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/dev.py +0 -0
  43. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/import_.py +0 -0
  44. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/latex.py +0 -0
  45. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/list.py +0 -0
  46. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/main/__init__.py +0 -0
  47. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/main/core.py +0 -0
  48. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/main/xr.py +0 -0
  49. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/new.py +0 -0
  50. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/notebooks.py +0 -0
  51. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/office.py +0 -0
  52. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/overleaf.py +0 -0
  53. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/scheduler.py +0 -0
  54. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cli/update.py +0 -0
  55. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/cloud.py +0 -0
  56. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/conda.py +0 -0
  57. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/config.py +0 -0
  58. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/core.py +0 -0
  59. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/datasets.py +0 -0
  60. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/dependencies.py +0 -0
  61. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/docker.py +0 -0
  62. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/dvc/__init__.py +0 -0
  63. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/dvc/core.py +0 -0
  64. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/dvc/zip.py +0 -0
  65. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/fs.py +0 -0
  66. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/git.py +0 -0
  67. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/github.py +0 -0
  68. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/gui.py +0 -0
  69. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/install.py +0 -0
  70. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/invenio.py +0 -0
  71. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/julia.py +0 -0
  72. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/jupyter.py +0 -0
  73. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/jupyterlab/__init__.py +0 -0
  74. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/jupyterlab/routes.py +0 -0
  75. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/schemas/calkit/plugin.json +0 -0
  76. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
  77. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
  78. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
  79. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/static/909.e3f9cc3408834a7fdcc3.js +0 -0
  80. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
  81. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
  82. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
  83. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/static/style.js +0 -0
  84. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/labextension/static/third-party-licenses.json +0 -0
  85. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/licenses.py +0 -0
  86. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/magics.py +0 -0
  87. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/matlab.py +0 -0
  88. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/models/__init__.py +0 -0
  89. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/models/core.py +0 -0
  90. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/models/io.py +0 -0
  91. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/models/iteration.py +0 -0
  92. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/models/pipeline.py +0 -0
  93. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/notebooks.py +0 -0
  94. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/office.py +0 -0
  95. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/ops.py +0 -0
  96. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/overleaf.py +0 -0
  97. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/pipeline.py +0 -0
  98. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/releases.py +0 -0
  99. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/server.py +0 -0
  100. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/__init__.py +0 -0
  101. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/core.py +0 -0
  102. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/latex/__init__.py +0 -0
  103. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/latex/article/paper.tex +0 -0
  104. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/latex/core.py +0 -0
  105. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/latex/jfm/jfm.bst +0 -0
  106. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/latex/jfm/jfm.cls +0 -0
  107. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
  108. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/latex/jfm/paper.tex +0 -0
  109. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/templates/latex/jfm/upmath.sty +0 -0
  110. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/__init__.py +0 -0
  111. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/__init__.py +0 -0
  112. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/main/__init__.py +0 -0
  113. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/main/test_core.py +0 -0
  114. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/main/test_lock.py +0 -0
  115. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/main/test_subprojects.py +0 -0
  116. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/main/test_xr.py +0 -0
  117. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_check.py +0 -0
  118. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_cloud.py +0 -0
  119. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_config.py +0 -0
  120. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_delete.py +0 -0
  121. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_import.py +0 -0
  122. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_latex.py +0 -0
  123. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_list.py +0 -0
  124. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_new.py +0 -0
  125. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_notebooks.py +0 -0
  126. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_overleaf.py +0 -0
  127. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_scheduler.py +0 -0
  128. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/cli/test_update.py +0 -0
  129. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/dvc/__init__.py +0 -0
  130. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/dvc/test_core.py +0 -0
  131. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/dvc/test_zip.py +0 -0
  132. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/jupyterlab/__init__.py +0 -0
  133. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/jupyterlab/test_routes.py +0 -0
  134. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/models/__init__.py +0 -0
  135. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/models/test_core.py +0 -0
  136. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/models/test_iteration.py +0 -0
  137. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/models/test_pipeline.py +0 -0
  138. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_calc.py +0 -0
  139. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_check.py +0 -0
  140. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_cloud.py +0 -0
  141. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_conda.py +0 -0
  142. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_core.py +0 -0
  143. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_dependencies.py +0 -0
  144. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_docker.py +0 -0
  145. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_environments.py +0 -0
  146. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_fs.py +0 -0
  147. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_git.py +0 -0
  148. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_install.py +0 -0
  149. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_invenio.py +0 -0
  150. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_julia.py +0 -0
  151. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_jupyter.py +0 -0
  152. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_licenses.py +0 -0
  153. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_magics.py +0 -0
  154. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_matlab.py +0 -0
  155. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_notebooks.py +0 -0
  156. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_pipeline.py +0 -0
  157. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_releases.py +0 -0
  158. {calkit_python-0.41.15 → calkit_python-0.41.16}/calkit/tests/test_templates.py +0 -0
  159. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/CNAME +0 -0
  160. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/ai-tools.md +0 -0
  161. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/apps.md +0 -0
  162. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/calculations.md +0 -0
  163. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/calkit-yaml.md +0 -0
  164. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/cli-reference.md +0 -0
  165. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/cloud-integration.md +0 -0
  166. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/datasets.md +0 -0
  167. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/dependencies.md +0 -0
  168. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/environments.md +0 -0
  169. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/examples.md +0 -0
  170. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/governance.md +0 -0
  171. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/help.md +0 -0
  172. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/hpc.md +0 -0
  173. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/c-to-the-k-white.svg +0 -0
  174. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/calkit-fragmentation-compendium.png +0 -0
  175. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/calkit-no-bg.png +0 -0
  176. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/connect-zenodo.png +0 -0
  177. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/jupyterlab/all-green.png +0 -0
  178. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/jupyterlab/collect-data-stale.png +0 -0
  179. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/jupyterlab/new-env.png +0 -0
  180. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/jupyterlab/new-notebook.png +0 -0
  181. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/jupyterlab/pipeline-badge.png +0 -0
  182. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/jupyterlab-params.png +0 -0
  183. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/plos-osi-code-2024-03.png +0 -0
  184. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/img/vscode-nb-params.png +0 -0
  185. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/index.md +0 -0
  186. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/installation.md +0 -0
  187. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/jupyterlab.md +0 -0
  188. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/local-server.md +0 -0
  189. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/notebooks.md +0 -0
  190. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/overleaf.md +0 -0
  191. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/pipeline/index.md +0 -0
  192. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/pipeline/manual-steps.md +0 -0
  193. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/pipeline/running-and-logging.md +0 -0
  194. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/quickstart.md +0 -0
  195. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/references.md +0 -0
  196. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/releases.md +0 -0
  197. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/reproducibility.md +0 -0
  198. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/subprojects.md +0 -0
  199. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/adding-latex-pub-docker.md +0 -0
  200. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/ai-agents.md +0 -0
  201. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/conda-envs.md +0 -0
  202. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/existing-project.md +0 -0
  203. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/first-project.md +0 -0
  204. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/github-actions.md +0 -0
  205. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/actions-repo-secrets.png +0 -0
  206. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
  207. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
  208. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
  209. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
  210. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
  211. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
  212. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
  213. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
  214. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
  215. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
  216. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/push.png +0 -0
  217. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
  218. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
  219. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/chart-more-rows.png +0 -0
  220. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/create-project.png +0 -0
  221. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
  222. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/excel-chart.png +0 -0
  223. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/excel-data.png +0 -0
  224. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
  225. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/needs-clone.png +0 -0
  226. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/new-stage.png +0 -0
  227. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
  228. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
  229. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/status-more-rows.png +0 -0
  230. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
  231. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/untracked-data.png +0 -0
  232. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/updated-publication.png +0 -0
  233. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
  234. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/office/workflow-page.png +0 -0
  235. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/openfoam/clone.png +0 -0
  236. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/openfoam/create-project.png +0 -0
  237. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
  238. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
  239. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
  240. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/openfoam/new-token.png +0 -0
  241. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/openfoam/reclone.png +0 -0
  242. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
  243. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/quick-actions.png +0 -0
  244. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/run-proc.png +0 -0
  245. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/vscode-slurm-notebook/create-calkit-env.png +0 -0
  246. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/vscode-slurm-notebook/create-inner-env.png +0 -0
  247. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/vscode-slurm-notebook/create-new-calkit-env.png +0 -0
  248. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/vscode-slurm-notebook/select-calkit-env.png +0 -0
  249. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/vscode-slurm-notebook/slurm-job-running.png +0 -0
  250. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/vscode-slurm-notebook/slurm-launch-options.png +0 -0
  251. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/img/vscode-slurm-notebook/starting-slurm-job.png +0 -0
  252. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/index.md +0 -0
  253. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/jupyterlab.md +0 -0
  254. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/latex-codespaces.md +0 -0
  255. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/matlab.md +0 -0
  256. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/notebook-pipeline.md +0 -0
  257. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/office.md +0 -0
  258. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/openfoam.md +0 -0
  259. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/procedures.md +0 -0
  260. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/tutorials/vscode-slurm-notebook.md +0 -0
  261. {calkit_python-0.41.15 → calkit_python-0.41.16}/docs/version-control.md +0 -0
  262. {calkit_python-0.41.15 → calkit_python-0.41.16}/flake.lock +0 -0
  263. {calkit_python-0.41.15 → calkit_python-0.41.16}/flake.nix +0 -0
  264. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/.yarnrc.yml +0 -0
  265. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/babel.config.js +0 -0
  266. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/install.json +0 -0
  267. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/jest.config.js +0 -0
  268. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/jupyter-config/server-config/calkit.json +0 -0
  269. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/schema/plugin.json +0 -0
  270. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/__tests__/useQueries.spec.ts +0 -0
  271. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/calkit-config.ts +0 -0
  272. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/cell-output-marker.ts +0 -0
  273. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/components/commit-dialog.tsx +0 -0
  274. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/components/environment-editor.tsx +0 -0
  275. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/components/notebook-registration.tsx +0 -0
  276. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/components/notebook-toolbar.tsx +0 -0
  277. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/components/pipeline-status-bar.tsx +0 -0
  278. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/components/project-info-editor.tsx +0 -0
  279. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/components/sidebar-settings.tsx +0 -0
  280. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/components/sidebar.tsx +0 -0
  281. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/components/stage-editor.tsx +0 -0
  282. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/feature-flags.ts +0 -0
  283. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/file-browser-menu.ts +0 -0
  284. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/hooks/__tests__/useQueries.test.tsx +0 -0
  285. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/hooks/useQueries.ts +0 -0
  286. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/icons.ts +0 -0
  287. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/index.ts +0 -0
  288. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/io-tracker.ts +0 -0
  289. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/pipeline-state.ts +0 -0
  290. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/queryClient.ts +0 -0
  291. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/request.ts +0 -0
  292. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/src/shims-mainmenu.d.ts +0 -0
  293. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/base.css +0 -0
  294. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/cell-output-marker.css +0 -0
  295. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/environment-editor.css +0 -0
  296. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/environment-selector.css +0 -0
  297. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/img/calkit-no-bg.png +0 -0
  298. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/index.css +0 -0
  299. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/index.js +0 -0
  300. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/notebook-toolbar.css +0 -0
  301. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/pipeline-status-bar.css +0 -0
  302. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/style/sidebar.css +0 -0
  303. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/tsconfig.json +0 -0
  304. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/tsconfig.test.json +0 -0
  305. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/ui-tests/.gitignore +0 -0
  306. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/ui-tests/README.md +0 -0
  307. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/ui-tests/jupyter_server_test_config.py +0 -0
  308. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/ui-tests/package.json +0 -0
  309. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/ui-tests/playwright.config.js +0 -0
  310. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/ui-tests/tests/calkit.spec.ts +0 -0
  311. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/ui-tests/yarn.lock +0 -0
  312. {calkit_python-0.41.15 → calkit_python-0.41.16/jupyterlab-ext}/yarn.lock +0 -0
  313. {calkit_python-0.41.15 → calkit_python-0.41.16}/mkdocs.yml +0 -0
  314. {calkit_python-0.41.15 → calkit_python-0.41.16}/scripts/generate-docs-references.py +0 -0
  315. {calkit_python-0.41.15 → calkit_python-0.41.16}/scripts/install.ps1 +0 -0
  316. {calkit_python-0.41.15 → calkit_python-0.41.16}/scripts/install.sh +0 -0
  317. {calkit_python-0.41.15 → calkit_python-0.41.16}/scripts/make-calk9.sh +0 -0
  318. {calkit_python-0.41.15 → calkit_python-0.41.16}/scripts/sync-docs.py +0 -0
  319. {calkit_python-0.41.15 → calkit_python-0.41.16}/test/dvc-md5-dir/osx-arm64.txt +0 -0
  320. {calkit_python-0.41.15 → calkit_python-0.41.16}/test/nb-julia.ipynb +0 -0
  321. {calkit_python-0.41.15 → calkit_python-0.41.16}/test/nb-params.ipynb +0 -0
  322. {calkit_python-0.41.15 → calkit_python-0.41.16}/test/nb-subdir.ipynb +0 -0
  323. {calkit_python-0.41.15 → calkit_python-0.41.16}/test/pipeline.ipynb +0 -0
  324. {calkit_python-0.41.15 → calkit_python-0.41.16}/test/script.py +0 -0
  325. {calkit_python-0.41.15 → calkit_python-0.41.16}/test/test-log.log +0 -0
  326. {calkit_python-0.41.15 → calkit_python-0.41.16}/uv.lock +0 -0
  327. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/.gitignore +0 -0
  328. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/.vscodeignore +0 -0
  329. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/CHANGELOG.md +0 -0
  330. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/LICENSE +0 -0
  331. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/README.md +0 -0
  332. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/images/calkit-icon.svg +0 -0
  333. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/images/calkit-no-bg.png +0 -0
  334. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/package-lock.json +0 -0
  335. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/package.json +0 -0
  336. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/scripts/set-proposed-api.js +0 -0
  337. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/environments.ts +0 -0
  338. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/extension.ts +0 -0
  339. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/figures/core.ts +0 -0
  340. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/figures/view.ts +0 -0
  341. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/notebooks.ts +0 -0
  342. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/pipeline/core.ts +0 -0
  343. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/sidebar.ts +0 -0
  344. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/test/environments.test.ts +0 -0
  345. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/test/figures.test.ts +0 -0
  346. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/test/kernel-selection.test.ts +0 -0
  347. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/test/notebooks.test.ts +0 -0
  348. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/test/pipeline.test.ts +0 -0
  349. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/src/types.ts +0 -0
  350. {calkit_python-0.41.15 → calkit_python-0.41.16}/vscode-ext/tsconfig.json +0 -0
@@ -12,6 +12,8 @@ tsconfig.tsbuildinfo
12
12
  lib
13
13
  node_modules
14
14
  .yarn
15
+ *.eslintcache
16
+ *.stylelintcache
15
17
  calkit/labextension
16
18
  coverage
17
19
  junit.xml
@@ -23,5 +23,3 @@ repos:
23
23
  hooks:
24
24
  - id: prettier
25
25
  exclude: calkit
26
- args:
27
- - --config=package.json
@@ -2,7 +2,6 @@ node_modules
2
2
  **/node_modules
3
3
  **/lib
4
4
  **/package.json
5
- !/package.json
6
5
  calkit
7
6
  .mypy_cache
8
7
  .pytest_cache
@@ -0,0 +1,6 @@
1
+ {
2
+ "singleQuote": false,
3
+ "trailingComma": "all",
4
+ "arrowParens": "always",
5
+ "endOfLine": "auto"
6
+ }
@@ -53,19 +53,21 @@ import-profile: ## Profile the import time of the CLI.
53
53
 
54
54
  .PHONY: jlab-dev
55
55
  jlab-dev: ## Develop the JupyterLab extension.
56
- uv run jlpm run watch
56
+ cd jupyterlab-ext && uv run jlpm run watch
57
57
 
58
58
  .PHONY: jlab
59
59
  jlab: ## Build the JupyterLab extension.
60
- uv run jlpm run build:prod
60
+ cd jupyterlab-ext && uv run jlpm run build:prod
61
61
 
62
- .PHONY: test-frontend
63
- test-frontend: ## Run frontend unit tests with Jest.
64
- @echo "🚀 Running frontend unit tests"
65
- @uv run jlpm test
62
+ .PHONY: test-jlab
63
+ test-jlab: ## Run JupyterLab extension unit tests with Jest.
64
+ @echo "🚀 Running JupyterLab extension unit tests"
65
+ @cd jupyterlab-ext && uv run jlpm test
66
66
 
67
- .PHONY: test-ui
68
- test-ui: ## Run the JupyterLab UI integration tests.
67
+ .PHONY: test-jlab-ui
68
+ test-jlab-ui: ## Run the JupyterLab UI integration tests.
69
69
  @echo "🚀 Running JupyterLab UI tests with Playwright"
70
- @uv run npm run build
71
- @uv run --directory=ui-tests jlpm playwright test -u --reporter=list
70
+ @cd jupyterlab-ext && uv run jlpm run build:prod
71
+ @uv run --directory=jupyterlab-ext/ui-tests jlpm install
72
+ @uv run --directory=jupyterlab-ext/ui-tests jlpm playwright install
73
+ @uv run --directory=jupyterlab-ext/ui-tests jlpm playwright test -u --reporter=list
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: calkit-python
3
- Version: 0.41.15
3
+ Version: 0.41.16
4
4
  Summary: Reproducibility simplified.
5
5
  Project-URL: Homepage, https://calkit.org
6
6
  Project-URL: Issues, https://github.com/calkit/calkit/issues
@@ -4,6 +4,8 @@ from __future__ import annotations
4
4
 
5
5
  import glob
6
6
  import os
7
+ import platform
8
+ import re
7
9
  import subprocess
8
10
 
9
11
  import typer
@@ -233,12 +235,57 @@ def config_github_ssh():
233
235
  subprocess.run(keygen_cmd)
234
236
  # Start the SSH agent in the background
235
237
  typer.echo("Checking that the SSH agent is running")
236
- ssh_agent_cmd = subprocess.run(
237
- ["ssh-agent", "-s"], capture_output=True, text=True
238
- ).stdout
239
- p = subprocess.run(ssh_agent_cmd, shell=True)
240
- if p.returncode != 0:
241
- raise_error("Failed to start ssh-agent")
238
+ # Note that under git bash / MSYS (MSYSTEM is set) we get a POSIX
239
+ # ssh-agent on PATH, so we use the POSIX path even on Windows there.
240
+ native_windows = platform.system() == "Windows" and not os.environ.get(
241
+ "MSYSTEM"
242
+ )
243
+ if native_windows:
244
+ # On native Windows, OpenSSH's ssh-agent runs as a Windows service
245
+ # rather than exporting environment variables to the current shell.
246
+ # The service ships disabled by default, so ensure it's enabled
247
+ # before starting it (enabling requires administrator privileges).
248
+ p = subprocess.run(
249
+ [
250
+ "powershell",
251
+ "-NoProfile",
252
+ "-Command",
253
+ (
254
+ "if ((Get-Service ssh-agent).StartType -eq 'Disabled') "
255
+ "{ Set-Service ssh-agent -StartupType Manual }; "
256
+ "Start-Service ssh-agent"
257
+ ),
258
+ ],
259
+ capture_output=True,
260
+ text=True,
261
+ )
262
+ if p.returncode != 0:
263
+ err = (p.stderr.strip() or p.stdout.strip()).lower()
264
+ if "access" in err and "denied" in err:
265
+ raise_error(
266
+ "Failed to start ssh-agent service: access denied.\n"
267
+ "The ssh-agent service is disabled and enabling it "
268
+ "requires administrator privileges. Please run the "
269
+ "following in an elevated (Run as administrator) "
270
+ "PowerShell, then try again:\n\n"
271
+ " Set-Service ssh-agent -StartupType Manual; "
272
+ "Start-Service ssh-agent"
273
+ )
274
+ raise_error(
275
+ "Failed to start ssh-agent service: "
276
+ f"{p.stderr.strip() or p.stdout.strip()}"
277
+ )
278
+ else:
279
+ # On POSIX systems, ssh-agent -s prints shell commands that export
280
+ # SSH_AUTH_SOCK and SSH_AGENT_PID; parse them into our environment so
281
+ # the subsequent ssh-add call can find the agent
282
+ p = subprocess.run(["ssh-agent", "-s"], capture_output=True, text=True)
283
+ if p.returncode != 0:
284
+ raise_error("Failed to start ssh-agent")
285
+ for match in re.finditer(
286
+ r"(SSH_AUTH_SOCK|SSH_AGENT_PID)=([^;\n]+);", p.stdout
287
+ ):
288
+ os.environ[match.group(1)] = match.group(2)
242
289
  # Add the SSH key to the ssh-agent
243
290
  typer.echo(f"Adding SSH key to ssh-agent: {key_path}")
244
291
  cmd = ["ssh-add", key_path]
@@ -1229,6 +1229,49 @@ def _extract_r_string_assignments(code: str) -> dict[str, str]:
1229
1229
  return assignments
1230
1230
 
1231
1231
 
1232
+ def _extract_r_string_vector_assignments(code: str) -> dict[str, list[str]]:
1233
+ """Extract character-vector assignments in R code.
1234
+
1235
+ Captures assignments of the form ``x <- c("a", "b")`` so that a later
1236
+ ``pacman::p_load(char = x)`` can be resolved back to its package list.
1237
+ """
1238
+ assignments = {}
1239
+ pattern = re.compile(
1240
+ r"([A-Za-z_][A-Za-z0-9_.]*)\s*(?:<-|=)\s*c\(([^)]*)\)",
1241
+ flags=re.DOTALL,
1242
+ )
1243
+ for name, body in pattern.findall(code):
1244
+ strings = re.findall(r'["\']([a-zA-Z0-9._]+)["\']', body)
1245
+ if strings:
1246
+ assignments[name] = strings
1247
+ return assignments
1248
+
1249
+
1250
+ def _resolve_r_package_args(
1251
+ call_args: str, vector_assignments: dict[str, list[str]]
1252
+ ) -> set[str]:
1253
+ """Resolve package names from a ``pacman::p_load()`` argument list.
1254
+
1255
+ Handles quoted literals, inline ``c(...)`` vectors, bare (non-standard
1256
+ evaluation) names like ``p_load(dplyr, tidyr)``, and ``char = x`` where
1257
+ ``x`` is a character vector assigned earlier in the script.
1258
+ """
1259
+ packages = set()
1260
+ # Quoted strings are package names, whether passed directly or inside c()
1261
+ packages.update(re.findall(r'["\']([a-zA-Z0-9._]+)["\']', call_args))
1262
+ # char = <var> referencing a character-vector assignment
1263
+ for var in re.findall(r"char\s*=\s*([A-Za-z_][A-Za-z0-9_.]*)", call_args):
1264
+ packages.update(vector_assignments.get(var, []))
1265
+ # Bare names passed positionally; drop keyword arguments (install=, update=,
1266
+ # character.only=, etc.) and their values before collecting identifiers
1267
+ stripped = re.sub(r"[A-Za-z_][A-Za-z0-9_.]*\s*=\s*[^,]+", "", call_args)
1268
+ for token in re.findall(r"[A-Za-z_][A-Za-z0-9_.]*", stripped):
1269
+ # c() is the vector constructor, not a package; TRUE/FALSE are values
1270
+ if token not in {"c", "TRUE", "FALSE", "T", "F"}:
1271
+ packages.add(token)
1272
+ return packages
1273
+
1274
+
1232
1275
  def _extract_julia_string_assignments(code: str) -> dict[str, str]:
1233
1276
  """Extract simple string assignments in Julia code."""
1234
1277
  assignments = {}
@@ -1622,6 +1665,27 @@ def detect_r_dependencies(
1622
1665
  for pattern in patterns:
1623
1666
  matches = re.findall(pattern, code)
1624
1667
  dependencies.update(matches)
1668
+ # requireNamespace()/loadNamespace() take the package as a string and are
1669
+ # commonly used to guard optional installs (e.g. pacman/here bootstrapping)
1670
+ dependencies.update(
1671
+ re.findall(
1672
+ r'(?:require|load)Namespace\s*\(\s*["\']([a-zA-Z0-9._]+)["\']',
1673
+ code,
1674
+ )
1675
+ )
1676
+ # Qualified calls like pkg::fn() or pkg:::fn() reference a package without
1677
+ # ever attaching it, so the package itself is still a dependency
1678
+ dependencies.update(re.findall(r"\b([a-zA-Z][a-zA-Z0-9._]*)\s*:::?", code))
1679
+ # pacman::p_load() loads (and optionally installs) packages dynamically; its
1680
+ # arguments may be bare names, quoted strings, or a character vector passed
1681
+ # via char=, possibly referencing a variable assigned earlier in the script
1682
+ vector_assignments = _extract_r_string_vector_assignments(code)
1683
+ for call_args in re.findall(
1684
+ r"p_load\s*\(((?:[^()]|\([^()]*\))*)\)", code, flags=re.DOTALL
1685
+ ):
1686
+ dependencies.update(
1687
+ _resolve_r_package_args(call_args, vector_assignments)
1688
+ )
1625
1689
  # Filter out base R packages
1626
1690
  base_packages = {
1627
1691
  "base",
@@ -5,6 +5,7 @@ import hashlib
5
5
  import json
6
6
  import os
7
7
  import platform
8
+ import re
8
9
  import subprocess
9
10
  import tempfile
10
11
  from pathlib import Path
@@ -1454,7 +1455,9 @@ def create_julia_project_file_content(
1454
1455
  return content
1455
1456
 
1456
1457
 
1457
- def create_r_description_content(dependencies: list[str]) -> str:
1458
+ def create_r_description_content(
1459
+ dependencies: list[str], project_name: str | None = None
1460
+ ) -> str:
1458
1461
  """Generate R DESCRIPTION file content listing dependencies.
1459
1462
 
1460
1463
  This creates a minimal DESCRIPTION file that renv can work with.
@@ -1463,13 +1466,26 @@ def create_r_description_content(dependencies: list[str]) -> str:
1463
1466
  ----------
1464
1467
  dependencies : list[str]
1465
1468
  List of R package names.
1469
+ project_name : str | None
1470
+ Name for the DESCRIPTION's ``Package`` field. It is sanitized into a
1471
+ valid R package name (letters, numbers and dots, starting with a
1472
+ letter). Falls back to the detected project name, then to
1473
+ ``CalkitProject``.
1466
1474
 
1467
1475
  Returns
1468
1476
  -------
1469
1477
  str
1470
1478
  The DESCRIPTION file content.
1471
1479
  """
1472
- content = """Package: CalkitProject
1480
+ if project_name is None:
1481
+ project_name = calkit.detect_project_name(prepend_owner=False)
1482
+ # Valid R package names may only contain letters, numbers and dots, and
1483
+ # must start with a letter, so replace anything else (e.g. hyphens) with a
1484
+ # dot and prefix a letter if needed
1485
+ package_name = re.sub(r"[^A-Za-z0-9.]+", ".", project_name).strip(".")
1486
+ if not package_name or not package_name[0].isalpha():
1487
+ package_name = "Calkit." + package_name if package_name else "Calkit"
1488
+ content = f"""Package: {package_name}
1473
1489
  Version: 0.0.1
1474
1490
  Title: Auto-generated R environment
1475
1491
  """
@@ -39,7 +39,7 @@
39
39
  "clean": "jlpm clean:lib",
40
40
  "clean:lib": "rimraf lib tsconfig.tsbuildinfo",
41
41
  "clean:lintcache": "rimraf .eslintcache .stylelintcache",
42
- "clean:labextension": "rimraf calkit/labextension calkit/_version.py",
42
+ "clean:labextension": "rimraf ../calkit/labextension ../calkit/_version.py",
43
43
  "clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache",
44
44
  "eslint": "jlpm eslint:check --fix",
45
45
  "eslint:check": "eslint . --cache --ext .ts,.tsx",
@@ -128,10 +128,10 @@
128
128
  }
129
129
  },
130
130
  "extension": true,
131
- "outputDir": "calkit/labextension",
131
+ "outputDir": "../calkit/labextension",
132
132
  "schemaDir": "schema",
133
133
  "_build": {
134
- "load": "static/remoteEntry.65469af996e7a96aa983.js",
134
+ "load": "static/remoteEntry.ac9035764d5b2adbb542.js",
135
135
  "extension": "./extension",
136
136
  "style": "./style"
137
137
  }
@@ -157,20 +157,6 @@
157
157
  "project": "tsconfig.json",
158
158
  "sourceType": "module"
159
159
  },
160
- "overrides": [
161
- {
162
- "files": [
163
- "vscode-ext/**/*.ts"
164
- ],
165
- "parserOptions": {
166
- "project": "vscode-ext/tsconfig.json",
167
- "sourceType": "module"
168
- },
169
- "rules": {
170
- "@typescript-eslint/naming-convention": "off"
171
- }
172
- }
173
- ],
174
160
  "plugins": [
175
161
  "@typescript-eslint"
176
162
  ],
@@ -205,12 +191,6 @@
205
191
  "prefer-arrow-callback": "error"
206
192
  }
207
193
  },
208
- "prettier": {
209
- "singleQuote": false,
210
- "trailingComma": "all",
211
- "arrowParens": "always",
212
- "endOfLine": "auto"
213
- },
214
194
  "stylelint": {
215
195
  "extends": [
216
196
  "stylelint-config-recommended",
@@ -39,7 +39,7 @@
39
39
  "clean": "jlpm clean:lib",
40
40
  "clean:lib": "rimraf lib tsconfig.tsbuildinfo",
41
41
  "clean:lintcache": "rimraf .eslintcache .stylelintcache",
42
- "clean:labextension": "rimraf calkit/labextension calkit/_version.py",
42
+ "clean:labextension": "rimraf ../calkit/labextension ../calkit/_version.py",
43
43
  "clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache",
44
44
  "eslint": "jlpm eslint:check --fix",
45
45
  "eslint:check": "eslint . --cache --ext .ts,.tsx",
@@ -128,7 +128,7 @@
128
128
  }
129
129
  },
130
130
  "extension": true,
131
- "outputDir": "calkit/labextension",
131
+ "outputDir": "../calkit/labextension",
132
132
  "schemaDir": "schema"
133
133
  },
134
134
  "eslintIgnore": [
@@ -152,20 +152,6 @@
152
152
  "project": "tsconfig.json",
153
153
  "sourceType": "module"
154
154
  },
155
- "overrides": [
156
- {
157
- "files": [
158
- "vscode-ext/**/*.ts"
159
- ],
160
- "parserOptions": {
161
- "project": "vscode-ext/tsconfig.json",
162
- "sourceType": "module"
163
- },
164
- "rules": {
165
- "@typescript-eslint/naming-convention": "off"
166
- }
167
- }
168
- ],
169
155
  "plugins": [
170
156
  "@typescript-eslint"
171
157
  ],
@@ -200,12 +186,6 @@
200
186
  "prefer-arrow-callback": "error"
201
187
  }
202
188
  },
203
- "prettier": {
204
- "singleQuote": false,
205
- "trailingComma": "all",
206
- "arrowParens": "always",
207
- "endOfLine": "auto"
208
- },
209
189
  "stylelint": {
210
190
  "extends": [
211
191
  "stylelint-config-recommended",
@@ -1 +1 @@
1
- var _JUPYTERLAB;(()=>{"use strict";var e,r,t,a,n,o,i,l,u,f,s,d,c,p,h,b,v,m,y,g,j,w,k,S={4717(e,r,t){var a={"./index":()=>Promise.all([t.e(867),t.e(345),t.e(909)]).then(()=>()=>t(5909)),"./extension":()=>Promise.all([t.e(867),t.e(345),t.e(909)]).then(()=>()=>t(5909)),"./style":()=>t.e(502).then(()=>()=>t(502))},n=(e,r)=>(t.R=r,r=t.o(a,e)?a[e]():Promise.resolve().then(()=>{throw new Error('Module "'+e+'" does not exist in container.')}),t.R=void 0,r),o=(e,r)=>{if(t.S){var a="default",n=t.S[a];if(n&&n!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[a]=e,t.I(a,r)}};t.d(r,{get:()=>n,init:()=>o})}},P={};function E(e){var r=P[e];if(void 0!==r)return r.exports;var t=P[e]={id:e,exports:{}};return S[e](t,t.exports,E),t.exports}E.m=S,E.c=P,E.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return E.d(r,{a:r}),r},E.d=(e,r)=>{for(var t in r)E.o(r,t)&&!E.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},E.f={},E.e=e=>Promise.all(Object.keys(E.f).reduce((r,t)=>(E.f[t](e,r),r),[])),E.u=e=>e+"."+{502:"9a2c5772a15466e923ef",695:"2c41003a452d43d2b358",867:"a42a046aa5108f54f8fb",909:"e3f9cc3408834a7fdcc3",946:"050af2abf7845cfbdbd2"}[e]+".js?v="+{502:"9a2c5772a15466e923ef",695:"2c41003a452d43d2b358",867:"a42a046aa5108f54f8fb",909:"e3f9cc3408834a7fdcc3",946:"050af2abf7845cfbdbd2"}[e],E.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),E.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),e={},r="calkit:",E.l=(t,a,n,o)=>{if(e[t])e[t].push(a);else{var i,l;if(void 0!==n)for(var u=document.getElementsByTagName("script"),f=0;f<u.length;f++){var s=u[f];if(s.getAttribute("src")==t||s.getAttribute("data-webpack")==r+n){i=s;break}}i||(l=!0,(i=document.createElement("script")).charset="utf-8",E.nc&&i.setAttribute("nonce",E.nc),i.setAttribute("data-webpack",r+n),i.src=t),e[t]=[a];var d=(r,a)=>{i.onerror=i.onload=null,clearTimeout(c);var n=e[t];if(delete e[t],i.parentNode&&i.parentNode.removeChild(i),n&&n.forEach(e=>e(a)),r)return r(a)},c=setTimeout(d.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=d.bind(null,i.onerror),i.onload=d.bind(null,i.onload),l&&document.head.appendChild(i)}},E.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{E.S={};var e={},r={};E.I=(t,a)=>{a||(a=[]);var n=r[t];if(n||(n=r[t]={}),!(a.indexOf(n)>=0)){if(a.push(n),e[t])return e[t];E.o(E.S,t)||(E.S[t]={});var o=E.S[t],i="calkit",l=(e,r,t,a)=>{var n=o[e]=o[e]||{},l=n[r];(!l||!l.loaded&&(!a!=!l.eager?a:i>l.from))&&(n[r]={get:t,from:i,eager:!!a})},u=[];return"default"===t&&(l("@tanstack/react-query-devtools","5.91.1",()=>E.e(695).then(()=>()=>E(6695))),l("@tanstack/react-query","5.90.12",()=>Promise.all([E.e(946),E.e(345)]).then(()=>()=>E(5946))),l("calkit","0.1.0",()=>Promise.all([E.e(867),E.e(345),E.e(909)]).then(()=>()=>E(5909)))),e[t]=u.length?Promise.all(u).then(()=>e[t]=1):1}}})(),(()=>{var e;E.g.importScripts&&(e=E.g.location+"");var r=E.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var a=t.length-1;a>-1&&(!e||!/^http(s?):/.test(e));)e=t[a--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),E.p=e})(),t=e=>{var r=e=>e.split(".").map(e=>+e==e?+e:e),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),a=t[1]?r(t[1]):[];return t[2]&&(a.length++,a.push.apply(a,r(t[2]))),t[3]&&(a.push([]),a.push.apply(a,r(t[3]))),a},a=(e,r)=>{e=t(e),r=t(r);for(var a=0;;){if(a>=e.length)return a<r.length&&"u"!=(typeof r[a])[0];var n=e[a],o=(typeof n)[0];if(a>=r.length)return"u"==o;var i=r[a],l=(typeof i)[0];if(o!=l)return"o"==o&&"n"==l||"s"==l||"u"==o;if("o"!=o&&"u"!=o&&n!=i)return n<i;a++}},n=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var a=1,o=1;o<e.length;o++)a--,t+="u"==(typeof(l=e[o]))[0]?"-":(a>0?".":"")+(a=2,l);return t}var i=[];for(o=1;o<e.length;o++){var l=e[o];i.push(0===l?"not("+u()+")":1===l?"("+u()+" || "+u()+")":2===l?i.pop()+" "+i.pop():n(l))}return u();function u(){return i.pop().replace(/^\((.+)\)$/,"$1")}},o=(e,r)=>{if(0 in e){r=t(r);var a=e[0],n=a<0;n&&(a=-a-1);for(var i=0,l=1,u=!0;;l++,i++){var f,s,d=l<e.length?(typeof e[l])[0]:"";if(i>=r.length||"o"==(s=(typeof(f=r[i]))[0]))return!u||("u"==d?l>a&&!n:""==d!=n);if("u"==s){if(!u||"u"!=d)return!1}else if(u)if(d==s)if(l<=a){if(f!=e[l])return!1}else{if(n?f>e[l]:f<e[l])return!1;f!=e[l]&&(u=!1)}else if("s"!=d&&"n"!=d){if(n||l<=a)return!1;u=!1,l--}else{if(l<=a||s<d!=n)return!1;u=!1}else"s"!=d&&"n"!=d&&(u=!1,l--)}}var c=[],p=c.pop.bind(c);for(i=1;i<e.length;i++){var h=e[i];c.push(1==h?p()|p():2==h?p()&p():h?o(h,r):!p())}return!!p()},i=(e,r)=>e&&E.o(e,r),l=e=>(e.loaded=1,e.get()),u=e=>Object.keys(e).reduce((r,t)=>(e[t].eager&&(r[t]=e[t]),r),{}),f=(e,r,t,n)=>{var i=n?u(e[r]):e[r];return(r=Object.keys(i).reduce((e,r)=>!o(t,r)||e&&!a(e,r)?e:r,0))&&i[r]},s=(e,r,t)=>{var n=t?u(e[r]):e[r];return Object.keys(n).reduce((e,r)=>!e||!n[e].loaded&&a(e,r)?r:e,0)},d=(e,r,t,a)=>"Unsatisfied version "+t+" from "+(t&&e[r][t].from)+" of shared singleton module "+r+" (required "+n(a)+")",c=(e,r,t,a,o)=>{var i=e[t];return"No satisfying version ("+n(a)+")"+(o?" for eager consumption":"")+" of shared module "+t+" found in shared scope "+r+".\nAvailable versions: "+Object.keys(i).map(e=>e+" from "+i[e].from).join(", ")},p=e=>{throw new Error(e)},h=e=>{"undefined"!=typeof console&&console.warn&&console.warn(e)},v=(e,r,t)=>t?t():((e,r)=>p("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),m=(b=e=>function(r,t,a,n,o){var i=E.I(r);return i&&i.then&&!a?i.then(e.bind(e,r,E.S[r],t,!1,n,o)):e(r,E.S[r],t,a,n,o)})((e,r,t,a,n,o)=>{if(!i(r,t))return v(e,t,o);var u=f(r,t,n,a);return u?l(u):o?o():void p(c(r,e,t,n,a))}),y=b((e,r,t,a,n,u)=>{if(!i(r,t))return v(e,t,u);var f=s(r,t,a);return o(n,f)||h(d(r,t,f,n)),l(r[t][f])}),g={},j={3345:()=>y("default","react",!1,[1,18,2,0]),520:()=>y("default","@jupyterlab/coreutils",!1,[1,6,5,5]),1247:()=>y("default","@lumino/widgets",!1,[1,2,3,1,,"alpha",1]),1650:()=>y("default","@jupyterlab/launcher",!1,[1,4,5,5]),3476:()=>y("default","@jupyterlab/application",!1,[1,4,5,5]),3539:()=>y("default","@jupyterlab/settingregistry",!1,[1,4,5,5]),3712:()=>m("default","@tanstack/react-query",!1,[1,5,32,0],()=>E.e(946).then(()=>()=>E(5946))),3895:()=>y("default","@jupyterlab/statusbar",!1,[1,4,5,5]),6167:()=>y("default","@lumino/commands",!1,[1,2,0,1]),6200:()=>y("default","@jupyterlab/filebrowser",!1,[1,4,5,5]),6511:()=>y("default","@jupyterlab/apputils",!1,[1,4,6,5]),6641:()=>y("default","@jupyterlab/notebook",!1,[1,4,5,5]),6911:()=>y("default","@jupyterlab/statedb",!1,[1,4,5,5]),6965:()=>y("default","@jupyterlab/ui-components",!1,[1,4,5,5]),6979:()=>y("default","@jupyterlab/translation",!1,[1,4,5,5]),7034:()=>m("default","@tanstack/react-query-devtools",!1,[1,5,32,0],()=>E.e(695).then(()=>()=>E(6695))),7628:()=>y("default","react-dom",!1,[1,18,2,0]),9080:()=>y("default","@jupyterlab/mainmenu",!1,[1,4,5,5]),9519:()=>y("default","@jupyterlab/services",!1,[1,7,5,5])},w={345:[3345],909:[520,1247,1650,3476,3539,3712,3895,6167,6200,6511,6641,6911,6965,6979,7034,7628,9080,9519]},k={},E.f.consumes=(e,r)=>{E.o(w,e)&&w[e].forEach(e=>{if(E.o(g,e))return r.push(g[e]);if(!k[e]){var t=r=>{g[e]=0,E.m[e]=t=>{delete E.c[e],t.exports=r()}};k[e]=!0;var a=r=>{delete g[e],E.m[e]=t=>{throw delete E.c[e],r}};try{var n=j[e]();n.then?r.push(g[e]=n.then(t).catch(a)):t(n)}catch(e){a(e)}}})},(()=>{E.b="undefined"!=typeof document&&document.baseURI||self.location.href;var e={371:0};E.f.j=(r,t)=>{var a=E.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[2]);else if(345!=r){var n=new Promise((t,n)=>a=e[r]=[t,n]);t.push(a[2]=n);var o=E.p+E.u(r),i=new Error;E.l(o,t=>{if(E.o(e,r)&&(0!==(a=e[r])&&(e[r]=void 0),a)){var n=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+n+": "+o+")",i.name="ChunkLoadError",i.type=n,i.request=o,a[1](i)}},"chunk-"+r,r)}else e[r]=0};var r=(r,t)=>{var a,n,[o,i,l]=t,u=0;if(o.some(r=>0!==e[r])){for(a in i)E.o(i,a)&&(E.m[a]=i[a]);l&&l(E)}for(r&&r(t);u<o.length;u++)n=o[u],E.o(e,n)&&e[n]&&e[n][0](),e[n]=0},t=self.webpackChunkcalkit=self.webpackChunkcalkit||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),E.nc=void 0;var T=E(4717);(_JUPYTERLAB=void 0===_JUPYTERLAB?{}:_JUPYTERLAB).calkit=T})();
1
+ var _JUPYTERLAB;(()=>{"use strict";var e,r,t,a,n,o,i,l,u,f,s,d,c,p,h,b,v,m,y,g,j,w,k,S={1336(e,r,t){var a={"./index":()=>Promise.all([t.e(867),t.e(345),t.e(909)]).then(()=>()=>t(5909)),"./extension":()=>Promise.all([t.e(867),t.e(345),t.e(909)]).then(()=>()=>t(5909)),"./style":()=>t.e(502).then(()=>()=>t(502))},n=(e,r)=>(t.R=r,r=t.o(a,e)?a[e]():Promise.resolve().then(()=>{throw new Error('Module "'+e+'" does not exist in container.')}),t.R=void 0,r),o=(e,r)=>{if(t.S){var a="default",n=t.S[a];if(n&&n!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[a]=e,t.I(a,r)}};t.d(r,{get:()=>n,init:()=>o})}},P={};function E(e){var r=P[e];if(void 0!==r)return r.exports;var t=P[e]={id:e,exports:{}};return S[e](t,t.exports,E),t.exports}E.m=S,E.c=P,E.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return E.d(r,{a:r}),r},E.d=(e,r)=>{for(var t in r)E.o(r,t)&&!E.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},E.f={},E.e=e=>Promise.all(Object.keys(E.f).reduce((r,t)=>(E.f[t](e,r),r),[])),E.u=e=>e+"."+{502:"9a2c5772a15466e923ef",695:"2c41003a452d43d2b358",867:"a42a046aa5108f54f8fb",909:"e3f9cc3408834a7fdcc3",946:"050af2abf7845cfbdbd2"}[e]+".js?v="+{502:"9a2c5772a15466e923ef",695:"2c41003a452d43d2b358",867:"a42a046aa5108f54f8fb",909:"e3f9cc3408834a7fdcc3",946:"050af2abf7845cfbdbd2"}[e],E.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),E.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),e={},r="calkit:",E.l=(t,a,n,o)=>{if(e[t])e[t].push(a);else{var i,l;if(void 0!==n)for(var u=document.getElementsByTagName("script"),f=0;f<u.length;f++){var s=u[f];if(s.getAttribute("src")==t||s.getAttribute("data-webpack")==r+n){i=s;break}}i||(l=!0,(i=document.createElement("script")).charset="utf-8",E.nc&&i.setAttribute("nonce",E.nc),i.setAttribute("data-webpack",r+n),i.src=t),e[t]=[a];var d=(r,a)=>{i.onerror=i.onload=null,clearTimeout(c);var n=e[t];if(delete e[t],i.parentNode&&i.parentNode.removeChild(i),n&&n.forEach(e=>e(a)),r)return r(a)},c=setTimeout(d.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=d.bind(null,i.onerror),i.onload=d.bind(null,i.onload),l&&document.head.appendChild(i)}},E.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{E.S={};var e={},r={};E.I=(t,a)=>{a||(a=[]);var n=r[t];if(n||(n=r[t]={}),!(a.indexOf(n)>=0)){if(a.push(n),e[t])return e[t];E.o(E.S,t)||(E.S[t]={});var o=E.S[t],i="calkit",l=(e,r,t,a)=>{var n=o[e]=o[e]||{},l=n[r];(!l||!l.loaded&&(!a!=!l.eager?a:i>l.from))&&(n[r]={get:t,from:i,eager:!!a})},u=[];return"default"===t&&(l("@tanstack/react-query-devtools","5.91.1",()=>E.e(695).then(()=>()=>E(6695))),l("@tanstack/react-query","5.90.12",()=>Promise.all([E.e(946),E.e(345)]).then(()=>()=>E(5946))),l("calkit","0.1.0",()=>Promise.all([E.e(867),E.e(345),E.e(909)]).then(()=>()=>E(5909)))),e[t]=u.length?Promise.all(u).then(()=>e[t]=1):1}}})(),(()=>{var e;E.g.importScripts&&(e=E.g.location+"");var r=E.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var a=t.length-1;a>-1&&(!e||!/^http(s?):/.test(e));)e=t[a--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),E.p=e})(),t=e=>{var r=e=>e.split(".").map(e=>+e==e?+e:e),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),a=t[1]?r(t[1]):[];return t[2]&&(a.length++,a.push.apply(a,r(t[2]))),t[3]&&(a.push([]),a.push.apply(a,r(t[3]))),a},a=(e,r)=>{e=t(e),r=t(r);for(var a=0;;){if(a>=e.length)return a<r.length&&"u"!=(typeof r[a])[0];var n=e[a],o=(typeof n)[0];if(a>=r.length)return"u"==o;var i=r[a],l=(typeof i)[0];if(o!=l)return"o"==o&&"n"==l||"s"==l||"u"==o;if("o"!=o&&"u"!=o&&n!=i)return n<i;a++}},n=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var a=1,o=1;o<e.length;o++)a--,t+="u"==(typeof(l=e[o]))[0]?"-":(a>0?".":"")+(a=2,l);return t}var i=[];for(o=1;o<e.length;o++){var l=e[o];i.push(0===l?"not("+u()+")":1===l?"("+u()+" || "+u()+")":2===l?i.pop()+" "+i.pop():n(l))}return u();function u(){return i.pop().replace(/^\((.+)\)$/,"$1")}},o=(e,r)=>{if(0 in e){r=t(r);var a=e[0],n=a<0;n&&(a=-a-1);for(var i=0,l=1,u=!0;;l++,i++){var f,s,d=l<e.length?(typeof e[l])[0]:"";if(i>=r.length||"o"==(s=(typeof(f=r[i]))[0]))return!u||("u"==d?l>a&&!n:""==d!=n);if("u"==s){if(!u||"u"!=d)return!1}else if(u)if(d==s)if(l<=a){if(f!=e[l])return!1}else{if(n?f>e[l]:f<e[l])return!1;f!=e[l]&&(u=!1)}else if("s"!=d&&"n"!=d){if(n||l<=a)return!1;u=!1,l--}else{if(l<=a||s<d!=n)return!1;u=!1}else"s"!=d&&"n"!=d&&(u=!1,l--)}}var c=[],p=c.pop.bind(c);for(i=1;i<e.length;i++){var h=e[i];c.push(1==h?p()|p():2==h?p()&p():h?o(h,r):!p())}return!!p()},i=(e,r)=>e&&E.o(e,r),l=e=>(e.loaded=1,e.get()),u=e=>Object.keys(e).reduce((r,t)=>(e[t].eager&&(r[t]=e[t]),r),{}),f=(e,r,t,n)=>{var i=n?u(e[r]):e[r];return(r=Object.keys(i).reduce((e,r)=>!o(t,r)||e&&!a(e,r)?e:r,0))&&i[r]},s=(e,r,t)=>{var n=t?u(e[r]):e[r];return Object.keys(n).reduce((e,r)=>!e||!n[e].loaded&&a(e,r)?r:e,0)},d=(e,r,t,a)=>"Unsatisfied version "+t+" from "+(t&&e[r][t].from)+" of shared singleton module "+r+" (required "+n(a)+")",c=(e,r,t,a,o)=>{var i=e[t];return"No satisfying version ("+n(a)+")"+(o?" for eager consumption":"")+" of shared module "+t+" found in shared scope "+r+".\nAvailable versions: "+Object.keys(i).map(e=>e+" from "+i[e].from).join(", ")},p=e=>{throw new Error(e)},h=e=>{"undefined"!=typeof console&&console.warn&&console.warn(e)},v=(e,r,t)=>t?t():((e,r)=>p("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),m=(b=e=>function(r,t,a,n,o){var i=E.I(r);return i&&i.then&&!a?i.then(e.bind(e,r,E.S[r],t,!1,n,o)):e(r,E.S[r],t,a,n,o)})((e,r,t,a,n,o)=>{if(!i(r,t))return v(e,t,o);var u=f(r,t,n,a);return u?l(u):o?o():void p(c(r,e,t,n,a))}),y=b((e,r,t,a,n,u)=>{if(!i(r,t))return v(e,t,u);var f=s(r,t,a);return o(n,f)||h(d(r,t,f,n)),l(r[t][f])}),g={},j={3345:()=>y("default","react",!1,[1,18,2,0]),520:()=>y("default","@jupyterlab/coreutils",!1,[1,6,5,5]),1247:()=>y("default","@lumino/widgets",!1,[1,2,3,1,,"alpha",1]),1650:()=>y("default","@jupyterlab/launcher",!1,[1,4,5,5]),3476:()=>y("default","@jupyterlab/application",!1,[1,4,5,5]),3539:()=>y("default","@jupyterlab/settingregistry",!1,[1,4,5,5]),3712:()=>m("default","@tanstack/react-query",!1,[1,5,32,0],()=>E.e(946).then(()=>()=>E(5946))),3895:()=>y("default","@jupyterlab/statusbar",!1,[1,4,5,5]),6167:()=>y("default","@lumino/commands",!1,[1,2,0,1]),6200:()=>y("default","@jupyterlab/filebrowser",!1,[1,4,5,5]),6511:()=>y("default","@jupyterlab/apputils",!1,[1,4,6,5]),6641:()=>y("default","@jupyterlab/notebook",!1,[1,4,5,5]),6911:()=>y("default","@jupyterlab/statedb",!1,[1,4,5,5]),6965:()=>y("default","@jupyterlab/ui-components",!1,[1,4,5,5]),6979:()=>y("default","@jupyterlab/translation",!1,[1,4,5,5]),7034:()=>m("default","@tanstack/react-query-devtools",!1,[1,5,32,0],()=>E.e(695).then(()=>()=>E(6695))),7628:()=>y("default","react-dom",!1,[1,18,2,0]),9080:()=>y("default","@jupyterlab/mainmenu",!1,[1,4,5,5]),9519:()=>y("default","@jupyterlab/services",!1,[1,7,5,5])},w={345:[3345],909:[520,1247,1650,3476,3539,3712,3895,6167,6200,6511,6641,6911,6965,6979,7034,7628,9080,9519]},k={},E.f.consumes=(e,r)=>{E.o(w,e)&&w[e].forEach(e=>{if(E.o(g,e))return r.push(g[e]);if(!k[e]){var t=r=>{g[e]=0,E.m[e]=t=>{delete E.c[e],t.exports=r()}};k[e]=!0;var a=r=>{delete g[e],E.m[e]=t=>{throw delete E.c[e],r}};try{var n=j[e]();n.then?r.push(g[e]=n.then(t).catch(a)):t(n)}catch(e){a(e)}}})},(()=>{E.b="undefined"!=typeof document&&document.baseURI||self.location.href;var e={371:0};E.f.j=(r,t)=>{var a=E.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[2]);else if(345!=r){var n=new Promise((t,n)=>a=e[r]=[t,n]);t.push(a[2]=n);var o=E.p+E.u(r),i=new Error;E.l(o,t=>{if(E.o(e,r)&&(0!==(a=e[r])&&(e[r]=void 0),a)){var n=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+n+": "+o+")",i.name="ChunkLoadError",i.type=n,i.request=o,a[1](i)}},"chunk-"+r,r)}else e[r]=0};var r=(r,t)=>{var a,n,[o,i,l]=t,u=0;if(o.some(r=>0!==e[r])){for(a in i)E.o(i,a)&&(E.m[a]=i[a]);l&&l(E)}for(r&&r(t);u<o.length;u++)n=o[u],E.o(e,n)&&e[n]&&e[n][0](),e[n]=0},t=self.webpackChunkcalkit=self.webpackChunkcalkit||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),E.nc=void 0;var T=E(1336);(_JUPYTERLAB=void 0===_JUPYTERLAB?{}:_JUPYTERLAB).calkit=T})();
@@ -1,8 +1,7 @@
1
1
  import pytest
2
2
 
3
- pytest_plugins = ("pytest_jupyter.jupyter_server",)
4
-
5
3
 
6
4
  @pytest.fixture
7
5
  def jp_server_config(jp_server_config):
6
+ # Load the Calkit server extension in the test Jupyter server.
8
7
  return {"ServerApp": {"jpserver_extensions": {"calkit": True}}}
@@ -863,6 +863,41 @@ data <- read.csv("data.csv")
863
863
  assert "tidyr" in deps
864
864
  # Base packages should not be included
865
865
  assert "base" not in deps
866
+ # Qualified calls (pkg::fn), requireNamespace/loadNamespace, and
867
+ # pacman::p_load with a character vector should all be detected
868
+ pacman_content = """
869
+ if (!requireNamespace("here", quietly = TRUE)) install.packages("here")
870
+ here::i_am("code/master.R")
871
+ loadNamespace("withr")
872
+ pkgs <- c(
873
+ "haven", "readxl",
874
+ "dplyr", "ggplot2"
875
+ )
876
+ pacman::p_load(char = pkgs, install = TRUE, character.only = TRUE)
877
+ pacman::p_load(stringr, tidyr)
878
+ pacman::p_load("forcats", c("janitor", "lubridate"))
879
+ """
880
+ deps = detect_r_dependencies(code=pacman_content)
881
+ # Qualified call and the requireNamespace/loadNamespace guards
882
+ assert "here" in deps
883
+ assert "pacman" in deps
884
+ assert "withr" in deps
885
+ # Vector resolved via char =
886
+ assert "haven" in deps
887
+ assert "readxl" in deps
888
+ assert "ggplot2" in deps
889
+ # Bare non-standard-evaluation names
890
+ assert "stringr" in deps
891
+ assert "tidyr" in deps
892
+ # Quoted names and inline c() vectors
893
+ assert "forcats" in deps
894
+ assert "janitor" in deps
895
+ assert "lubridate" in deps
896
+ # The vector constructor and keyword-argument values are not packages
897
+ assert "c" not in deps
898
+ assert "TRUE" not in deps
899
+ assert "install" not in deps
900
+ assert "character.only" not in deps
866
901
 
867
902
 
868
903
  def test_detect_r_dependencies_from_code():
@@ -1064,6 +1099,20 @@ def test_create_r_description_file(tmp_dir):
1064
1099
  assert "dplyr" in content
1065
1100
  assert "tidyr" in content
1066
1101
  assert "Imports:" in content
1102
+ # The Package field reflects the project name (sanitized to a valid R
1103
+ # package name), not a hard-coded placeholder
1104
+ from calkit.environments import create_r_description_content
1105
+
1106
+ content = create_r_description_content(deps, project_name="AI-Games")
1107
+ assert "Package: AI.Games" in content
1108
+ assert "CalkitProject" not in content
1109
+ # Names that don't start with a letter get a valid prefix
1110
+ content = create_r_description_content(deps, project_name="2023-study")
1111
+ package_line = [
1112
+ ln for ln in content.splitlines() if ln.startswith("Package:")
1113
+ ][0]
1114
+ package_name = package_line.split(":", 1)[1].strip()
1115
+ assert package_name[0].isalpha()
1067
1116
 
1068
1117
 
1069
1118
  def test_create_files_in_subdirectory(tmp_dir):
@@ -39,7 +39,7 @@
39
39
  "clean": "jlpm clean:lib",
40
40
  "clean:lib": "rimraf lib tsconfig.tsbuildinfo",
41
41
  "clean:lintcache": "rimraf .eslintcache .stylelintcache",
42
- "clean:labextension": "rimraf calkit/labextension calkit/_version.py",
42
+ "clean:labextension": "rimraf ../calkit/labextension ../calkit/_version.py",
43
43
  "clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache",
44
44
  "eslint": "jlpm eslint:check --fix",
45
45
  "eslint:check": "eslint . --cache --ext .ts,.tsx",
@@ -128,7 +128,7 @@
128
128
  }
129
129
  },
130
130
  "extension": true,
131
- "outputDir": "calkit/labextension",
131
+ "outputDir": "../calkit/labextension",
132
132
  "schemaDir": "schema"
133
133
  },
134
134
  "eslintIgnore": [
@@ -152,20 +152,6 @@
152
152
  "project": "tsconfig.json",
153
153
  "sourceType": "module"
154
154
  },
155
- "overrides": [
156
- {
157
- "files": [
158
- "vscode-ext/**/*.ts"
159
- ],
160
- "parserOptions": {
161
- "project": "vscode-ext/tsconfig.json",
162
- "sourceType": "module"
163
- },
164
- "rules": {
165
- "@typescript-eslint/naming-convention": "off"
166
- }
167
- }
168
- ],
169
155
  "plugins": [
170
156
  "@typescript-eslint"
171
157
  ],
@@ -200,12 +186,6 @@
200
186
  "prefer-arrow-callback": "error"
201
187
  }
202
188
  },
203
- "prettier": {
204
- "singleQuote": false,
205
- "trailingComma": "all",
206
- "arrowParens": "always",
207
- "endOfLine": "auto"
208
- },
209
189
  "stylelint": {
210
190
  "extends": [
211
191
  "stylelint-config-recommended",
@@ -117,8 +117,8 @@ exclude = [".github"]
117
117
 
118
118
  [tool.hatch.build.targets.wheel.shared-data]
119
119
  "calkit/labextension" = "share/jupyter/labextensions/calkit"
120
- "install.json" = "share/jupyter/labextensions/calkit/install.json"
121
- "jupyter-config/server-config" = "etc/jupyter/jupyter_server_config.d"
120
+ "jupyterlab-ext/install.json" = "share/jupyter/labextensions/calkit/install.json"
121
+ "jupyterlab-ext/jupyter-config/server-config" = "etc/jupyter/jupyter_server_config.d"
122
122
 
123
123
  [tool.hatch.build.hooks.jupyter-builder]
124
124
  dependencies = ["hatch-jupyter-builder>=0.5"]
@@ -132,11 +132,13 @@ skip-if-exists = ["calkit/labextension/static/style.js"]
132
132
  [tool.hatch.build.hooks.jupyter-builder.build-kwargs]
133
133
  build_cmd = "build:prod"
134
134
  npm = ["jlpm"]
135
+ path = "jupyterlab-ext"
135
136
 
136
137
  [tool.hatch.build.hooks.jupyter-builder.editable-build-kwargs]
137
138
  build_cmd = "install:extension"
138
139
  npm = ["jlpm"]
139
- source_dir = "src"
140
+ path = "jupyterlab-ext"
141
+ source_dir = "jupyterlab-ext/src"
140
142
  build_dir = "calkit/labextension"
141
143
 
142
144
  [tool.jupyter-releaser.options]
@@ -145,10 +147,10 @@ version_cmd = "hatch version"
145
147
  [tool.jupyter-releaser.hooks]
146
148
  before-build-npm = [
147
149
  "python -m pip install 'jupyterlab>=4.0.0,<5'",
148
- "jlpm",
149
- "jlpm build:prod",
150
+ "cd jupyterlab-ext && jlpm",
151
+ "cd jupyterlab-ext && jlpm build:prod",
150
152
  ]
151
- before-build-python = ["jlpm clean:all"]
153
+ before-build-python = ["cd jupyterlab-ext && jlpm clean:all"]
152
154
 
153
155
  [tool.check-wheel-contents]
154
156
  ignore = ["W002"]
@@ -187,4 +189,4 @@ extend-select = ["I"] # Import sorting (isort compatibility)
187
189
 
188
190
  [tool.pytest.ini_options]
189
191
  env = ["CALKIT_ENV=test", "CALKIT_TEST_OVERLEAF_TOKEN=none"]
190
- addopts = "-n auto"
192
+ addopts = "-n auto -p pytest_jupyter.jupyter_server"
File without changes