jupyterlab-workshop 0.1.13__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.
- jupyterlab_workshop-0.1.13/.gitignore +58 -0
- jupyterlab_workshop-0.1.13/.prettierignore +15 -0
- jupyterlab_workshop-0.1.13/.python-version +1 -0
- jupyterlab_workshop-0.1.13/.readthedocs.yaml +15 -0
- jupyterlab_workshop-0.1.13/.yarnrc.yml +2 -0
- jupyterlab_workshop-0.1.13/AGENTS.md +293 -0
- jupyterlab_workshop-0.1.13/CLAUDE.md +1 -0
- jupyterlab_workshop-0.1.13/CONTRIBUTING.md +128 -0
- jupyterlab_workshop-0.1.13/Justfile +130 -0
- jupyterlab_workshop-0.1.13/LICENSE +202 -0
- jupyterlab_workshop-0.1.13/PKG-INFO +104 -0
- jupyterlab_workshop-0.1.13/README.md +69 -0
- jupyterlab_workshop-0.1.13/TESTING.md +96 -0
- jupyterlab_workshop-0.1.13/binder/postBuild +32 -0
- jupyterlab_workshop-0.1.13/binder/requirements.txt +8 -0
- jupyterlab_workshop-0.1.13/binder/runtime.txt +1 -0
- jupyterlab_workshop-0.1.13/collections/catalog.json +23 -0
- jupyterlab_workshop-0.1.13/collections/examples/collection.json +84 -0
- jupyterlab_workshop-0.1.13/collections/examples/icon.svg +6 -0
- jupyterlab_workshop-0.1.13/dev/overrides.json +9 -0
- jupyterlab_workshop-0.1.13/docs/_static/author-mode.png +0 -0
- jupyterlab_workshop-0.1.13/docs/_static/browser.png +0 -0
- jupyterlab_workshop-0.1.13/docs/_static/collections-dialog.png +0 -0
- jupyterlab_workshop-0.1.13/docs/_static/finish-dialog.png +0 -0
- jupyterlab_workshop-0.1.13/docs/_static/panel.png +0 -0
- jupyterlab_workshop-0.1.13/docs/_static/trust-dialog.png +0 -0
- jupyterlab_workshop-0.1.13/docs/actions.md +121 -0
- jupyterlab_workshop-0.1.13/docs/analytics.md +66 -0
- jupyterlab_workshop-0.1.13/docs/authoring.md +135 -0
- jupyterlab_workshop-0.1.13/docs/checks.md +245 -0
- jupyterlab_workshop-0.1.13/docs/cli.md +237 -0
- jupyterlab_workshop-0.1.13/docs/collections.md +404 -0
- jupyterlab_workshop-0.1.13/docs/concepts.md +141 -0
- jupyterlab_workshop-0.1.13/docs/conf.py +40 -0
- jupyterlab_workshop-0.1.13/docs/demo.md +59 -0
- jupyterlab_workshop-0.1.13/docs/deploying.md +204 -0
- jupyterlab_workshop-0.1.13/docs/environment.md +73 -0
- jupyterlab_workshop-0.1.13/docs/getting-started.md +187 -0
- jupyterlab_workshop-0.1.13/docs/index.md +178 -0
- jupyterlab_workshop-0.1.13/docs/layouts.md +113 -0
- jupyterlab_workshop-0.1.13/docs/lite.md +68 -0
- jupyterlab_workshop-0.1.13/docs/pages.md +229 -0
- jupyterlab_workshop-0.1.13/docs/platforms.md +156 -0
- jupyterlab_workshop-0.1.13/docs/publishing.md +187 -0
- jupyterlab_workshop-0.1.13/docs/settings.md +62 -0
- jupyterlab_workshop-0.1.13/docs/troubleshooting.md +125 -0
- jupyterlab_workshop-0.1.13/docs/trust.md +128 -0
- jupyterlab_workshop-0.1.13/docs/tutorial.md +358 -0
- jupyterlab_workshop-0.1.13/docs/using.md +176 -0
- jupyterlab_workshop-0.1.13/docs/variables.md +188 -0
- jupyterlab_workshop-0.1.13/eslint.config.mjs +70 -0
- jupyterlab_workshop-0.1.13/examples/git-basics/README.md +8 -0
- jupyterlab_workshop-0.1.13/examples/git-basics/pages/01-create-a-repository.md +73 -0
- jupyterlab_workshop-0.1.13/examples/git-basics/pages/02-first-commit.md +109 -0
- jupyterlab_workshop-0.1.13/examples/git-basics/pages/03-edit-and-diff.md +65 -0
- jupyterlab_workshop-0.1.13/examples/git-basics/pages/04-branch-and-merge.md +75 -0
- jupyterlab_workshop-0.1.13/examples/git-basics/pages/05-resolve-a-conflict.md +139 -0
- jupyterlab_workshop-0.1.13/examples/git-basics/verify/merged.py +22 -0
- jupyterlab_workshop-0.1.13/examples/git-basics/workshop.yaml +51 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/README.md +8 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/files/notes.md +3 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/pages/01-welcome.md +57 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/pages/02-notebooks.md +71 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/pages/03-kernels.md +49 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/pages/04-files.md +88 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/pages/05-variables.md +57 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/pages/06-conda.md +16 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/pages/06-pip.md +17 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/pages/07-automation.md +47 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/pages/08-finish.md +18 -0
- jupyterlab_workshop-0.1.13/examples/hello-jupyterlab/workshop.yaml +41 -0
- jupyterlab_workshop-0.1.13/examples/workshop-authoring/.gitignore +5 -0
- jupyterlab_workshop-0.1.13/examples/workshop-authoring/pages/01-what-a-workshop-is.md +52 -0
- jupyterlab_workshop-0.1.13/examples/workshop-authoring/pages/02-scaffold.md +62 -0
- jupyterlab_workshop-0.1.13/examples/workshop-authoring/pages/03-write-a-page.md +81 -0
- jupyterlab_workshop-0.1.13/examples/workshop-authoring/pages/04-lint.md +115 -0
- jupyterlab_workshop-0.1.13/examples/workshop-authoring/pages/05-test-and-publish.md +65 -0
- jupyterlab_workshop-0.1.13/examples/workshop-authoring/workshop.yaml +34 -0
- jupyterlab_workshop-0.1.13/github-pages/index.html +147 -0
- jupyterlab_workshop-0.1.13/install.json +5 -0
- jupyterlab_workshop-0.1.13/jupyter-config/server-config/jupyterlab_workshop.json +7 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/__init__.py +37 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/_version.py +4 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/analytics.py +130 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/bridge.py +159 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/catalog.py +300 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/checks.py +412 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/cli.py +892 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/collection.py +531 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/environment.py +323 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/fetch.py +584 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/handlers.py +583 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/harness.py +626 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/package.json +107 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/schemas/@jupyterlab-workshop/labextension/package.json.orig +102 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/schemas/@jupyterlab-workshop/labextension/panel.json +140 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/static/232.dfaa373fb7aa8044.js +1475 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/static/338.df6d26e0a8dc72bc.js +3 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/static/504.c2ade8e76866b88c.js +16 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/static/57.bb504983081811aa.js +1 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/static/980.5a55f6a96241b720.js +38 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/static/remoteEntry.6e0d9fe79bf4ac85.js +1 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/static/style.js +4 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/labextension/static/third-party-licenses.json +34 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/lite.py +344 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/mcp.py +638 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/nodejs/workshop-cli.cjs +16886 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/platform.py +194 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/publish.py +158 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/py.typed +0 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/scaffold.py +486 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/schema/catalog.schema.json +114 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/schema/collection.schema.json +154 -0
- jupyterlab_workshop-0.1.13/jupyterlab_workshop/schema/workshop.schema.json +279 -0
- jupyterlab_workshop-0.1.13/package.json +110 -0
- jupyterlab_workshop-0.1.13/pyproject.toml +146 -0
- jupyterlab_workshop-0.1.13/scripts/generate_manifest_reference.py +168 -0
- jupyterlab_workshop-0.1.13/scripts/screenshots.py +431 -0
- jupyterlab_workshop-0.1.13/skills/jupyterlab-workshop-authoring/SKILL.md +380 -0
- jupyterlab_workshop-0.1.13/skills/jupyterlab-workshop-authoring/references/actions.md +121 -0
- jupyterlab_workshop-0.1.13/skills/jupyterlab-workshop-authoring/references/page-template.md +82 -0
- jupyterlab_workshop-0.1.13/skills/jupyterlab-workshop-authoring/references/pages.md +229 -0
- jupyterlab_workshop-0.1.13/skills/jupyterlab-workshop-authoring/references/style-guide.md +93 -0
- jupyterlab_workshop-0.1.13/tsconfig.base.json +23 -0
- jupyterlab_workshop-0.1.13/uv.lock +2939 -0
- jupyterlab_workshop-0.1.13/yarn.lock +8939 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
scratch/
|
|
2
|
+
|
|
3
|
+
# JavaScript
|
|
4
|
+
node_modules/
|
|
5
|
+
.yarn/
|
|
6
|
+
*.bundle.*
|
|
7
|
+
*.log
|
|
8
|
+
*.tsbuildinfo
|
|
9
|
+
.eslintcache
|
|
10
|
+
.stylelintcache
|
|
11
|
+
packages/*/lib/
|
|
12
|
+
packages/core/coverage/
|
|
13
|
+
|
|
14
|
+
# Built labextension, Node CLI bundle, schema copy and generated version file
|
|
15
|
+
jupyterlab_workshop/labextension/
|
|
16
|
+
jupyterlab_workshop/nodejs/
|
|
17
|
+
jupyterlab_workshop/schema/
|
|
18
|
+
jupyterlab_workshop/_version.py
|
|
19
|
+
|
|
20
|
+
# Documentation build outputs and the assembled GitHub Pages site
|
|
21
|
+
docs/_build/
|
|
22
|
+
docs/reference/
|
|
23
|
+
site/
|
|
24
|
+
|
|
25
|
+
# Integration tests
|
|
26
|
+
tests/ui-tests/test-results/
|
|
27
|
+
tests/ui-tests/playwright-report/
|
|
28
|
+
|
|
29
|
+
# Python
|
|
30
|
+
.venv/
|
|
31
|
+
__pycache__/
|
|
32
|
+
*.py[cod]
|
|
33
|
+
*.egg-info/
|
|
34
|
+
build/
|
|
35
|
+
dist/
|
|
36
|
+
.pytest_cache/
|
|
37
|
+
.mypy_cache/
|
|
38
|
+
.ruff_cache/
|
|
39
|
+
.coverage
|
|
40
|
+
htmlcov/
|
|
41
|
+
.ipynb_checkpoints/
|
|
42
|
+
|
|
43
|
+
# Editors and OS
|
|
44
|
+
.DS_Store
|
|
45
|
+
|
|
46
|
+
# Files created by running the example workshops
|
|
47
|
+
examples/*/demo/
|
|
48
|
+
examples/*/_workshop/
|
|
49
|
+
examples/*/scratch/
|
|
50
|
+
|
|
51
|
+
# Workshops downloaded through the extension
|
|
52
|
+
workshops/
|
|
53
|
+
|
|
54
|
+
# JupyterLite site built by `just lite`
|
|
55
|
+
lite-site/
|
|
56
|
+
|
|
57
|
+
# JupyterLite build state written next to a build
|
|
58
|
+
.jupyterlite.doit.db
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
node_modules
|
|
2
|
+
**/node_modules
|
|
3
|
+
**/lib
|
|
4
|
+
**/package.json
|
|
5
|
+
!/package.json
|
|
6
|
+
jupyterlab_workshop
|
|
7
|
+
eslint.config.mjs
|
|
8
|
+
.venv
|
|
9
|
+
scratch
|
|
10
|
+
tests/ui-tests/test-results
|
|
11
|
+
tests/ui-tests/playwright-report
|
|
12
|
+
site
|
|
13
|
+
lite-site
|
|
14
|
+
docs/_build
|
|
15
|
+
docs/reference
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Read the Docs build. The project itself is not installed (that would need
|
|
2
|
+
# Node.js to build the extension); only the docs dependency group is synced
|
|
3
|
+
# with uv, matching `just docs`.
|
|
4
|
+
version: 2
|
|
5
|
+
|
|
6
|
+
build:
|
|
7
|
+
os: ubuntu-24.04
|
|
8
|
+
tools:
|
|
9
|
+
python: "3.12"
|
|
10
|
+
commands:
|
|
11
|
+
- asdf plugin add uv
|
|
12
|
+
- asdf install uv latest
|
|
13
|
+
- asdf global uv latest
|
|
14
|
+
- uv sync --only-group docs --no-install-project
|
|
15
|
+
- uv run --no-sync sphinx-build -W --keep-going -b html docs $READTHEDOCS_OUTPUT/html
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# Agent guidance for jupyterlab-workshop
|
|
2
|
+
|
|
3
|
+
## Project
|
|
4
|
+
|
|
5
|
+
jupyterlab-workshop is a JupyterLab extension for running guided,
|
|
6
|
+
interactive workshops inside JupyterLab. Workshop instructions are shown in
|
|
7
|
+
a side panel and contain clickable actions that drive the live JupyterLab
|
|
8
|
+
session: terminals, the file browser, the editor, notebooks, kernels and
|
|
9
|
+
layout. Workshops can verify learner progress, gate pages on that progress,
|
|
10
|
+
and include forms and quizzes. The concept comes from the Educates Training
|
|
11
|
+
Platform (educates.dev), re-imagined so that a single workshop runs wherever
|
|
12
|
+
JupyterLab runs, without Kubernetes or containers. See README.md for the
|
|
13
|
+
project goals.
|
|
14
|
+
|
|
15
|
+
A workshop is a directory containing a `workshop.yaml` manifest and
|
|
16
|
+
MyST-flavoured Markdown pages. The format is text based and git friendly.
|
|
17
|
+
|
|
18
|
+
The repository is a monorepo with three main parts:
|
|
19
|
+
|
|
20
|
+
- `packages/core/` is `@jupyterlab-workshop/core`, pure TypeScript with no
|
|
21
|
+
JupyterLab dependencies: workshop format parsing, action definitions,
|
|
22
|
+
variable substitution, lint rules and JSON schemas. Keep it free of
|
|
23
|
+
JupyterLab imports so the CLI and other tooling can reuse it under Node.
|
|
24
|
+
|
|
25
|
+
- `packages/labextension/` is `@jupyterlab-workshop/labextension`, the
|
|
26
|
+
JupyterLab frontend extension: instructions panel, renderer, action
|
|
27
|
+
implementations, verify engine, trust manager, loader and state.
|
|
28
|
+
|
|
29
|
+
- `jupyterlab_workshop/` is the Python package: the
|
|
30
|
+
`jupyter_server` extension (platform detection, fetching, script
|
|
31
|
+
verifies, checkpoints) and the `jupyter workshop` CLI.
|
|
32
|
+
|
|
33
|
+
README.md is the long description shown on PyPI, so it stays short and
|
|
34
|
+
user facing and links to the documentation site; development setup and
|
|
35
|
+
workflow belong in CONTRIBUTING.md, and the full documentation is under
|
|
36
|
+
`docs/` and published on Read the Docs.
|
|
37
|
+
|
|
38
|
+
Example workshops live in `examples/` and double as test fixtures. Tests
|
|
39
|
+
live in `tests/` (Python and Galata UI tests) and alongside the source in
|
|
40
|
+
`packages/core/`. See TESTING.md for where tests are, how to run them, and
|
|
41
|
+
conventions for adding new ones.
|
|
42
|
+
|
|
43
|
+
The scratch/ directory is not part of the git repo. It holds temporary
|
|
44
|
+
working files, such as reference material given to an agent or plans an
|
|
45
|
+
agent is asked to generate. Its contents come and go, so never reference
|
|
46
|
+
scratch/ files by name from code or documentation that will be committed.
|
|
47
|
+
|
|
48
|
+
## Tooling: always use uv and jlpm
|
|
49
|
+
|
|
50
|
+
All Python environment and package management in this project is done with
|
|
51
|
+
[uv](https://docs.astral.sh/uv/). Never use the Python venv module, bare
|
|
52
|
+
pip, or python -m build directly.
|
|
53
|
+
|
|
54
|
+
- Run commands in the project environment: `uv run <command>`
|
|
55
|
+
(e.g. `uv run pytest`, `uv run jupyter lab`)
|
|
56
|
+
|
|
57
|
+
- Run a Python interpreter: `uv run python`
|
|
58
|
+
|
|
59
|
+
- Build sdist and wheel: `uv build`
|
|
60
|
+
|
|
61
|
+
- Add or remove dependencies (updates pyproject.toml): `uv add <package>`,
|
|
62
|
+
`uv remove <package>`
|
|
63
|
+
|
|
64
|
+
- Sync the environment from pyproject.toml: `uv sync`
|
|
65
|
+
|
|
66
|
+
All JavaScript and TypeScript package management is done with `jlpm`, the
|
|
67
|
+
pinned Yarn that ships with JupyterLab. Never use npm or a system yarn
|
|
68
|
+
directly, and never commit a lockfile produced by them. jlpm is installed
|
|
69
|
+
into the project environment with JupyterLab, so run it as `uv run jlpm`.
|
|
70
|
+
|
|
71
|
+
- Install workspace dependencies: `uv run jlpm install`
|
|
72
|
+
|
|
73
|
+
- Add a dependency to one workspace package: run `uv run jlpm add <package>`
|
|
74
|
+
from inside that package's directory (for example `packages/core`)
|
|
75
|
+
|
|
76
|
+
- Build all packages: `uv run jlpm build`
|
|
77
|
+
|
|
78
|
+
## Common tasks: use the Justfile
|
|
79
|
+
|
|
80
|
+
The Justfile defines targets for the common development tasks, wrapping
|
|
81
|
+
the correct uv and jlpm invocations (including details like linking the
|
|
82
|
+
labextension into JupyterLab in development mode and running the Galata
|
|
83
|
+
tests against a live server). Prefer these targets over synthesizing the
|
|
84
|
+
underlying commands yourself; run `just --list` to see everything.
|
|
85
|
+
|
|
86
|
+
- `just install` sets up the development environment: syncs the Python
|
|
87
|
+
environment, installs JavaScript dependencies and links the extension
|
|
88
|
+
into JupyterLab in development mode.
|
|
89
|
+
|
|
90
|
+
- `just build` builds the TypeScript packages and the labextension bundle.
|
|
91
|
+
`just watch` rebuilds on change; run it alongside `just lab`.
|
|
92
|
+
|
|
93
|
+
- `just lab` starts JupyterLab from the repository root with the extension
|
|
94
|
+
loaded, so the example workshops are reachable through the contents API.
|
|
95
|
+
|
|
96
|
+
- `just test` runs the fast test suites: the Jest tests for `packages/core`
|
|
97
|
+
and the pytest suite for the Python package. Extra arguments pass
|
|
98
|
+
through to pytest, so a specific file or test is
|
|
99
|
+
`just test tests/python/test_fetch.py` or `just test -k pattern`.
|
|
100
|
+
|
|
101
|
+
- `just test-core` runs only the Jest tests; `just test-python` runs only
|
|
102
|
+
pytest; `just test-ui` runs the Galata browser tests against a real
|
|
103
|
+
JupyterLab (slow; run before finishing frontend work, not on every edit).
|
|
104
|
+
|
|
105
|
+
- `just lint` checks TypeScript with eslint and prettier and Python with
|
|
106
|
+
the ruff linter and formatter; `just format` reformats and applies
|
|
107
|
+
auto-fixes in both.
|
|
108
|
+
|
|
109
|
+
- `just typecheck` runs tsc for the TypeScript packages and mypy for
|
|
110
|
+
Python.
|
|
111
|
+
|
|
112
|
+
- `just docs` builds the documentation with Sphinx into `docs/_build/html`
|
|
113
|
+
(the pages are MyST Markdown under `docs/`, and the manifest reference is
|
|
114
|
+
generated from the JSON schema on every build); `just docs-serve` rebuilds
|
|
115
|
+
on change; `just docs-clean` clears a stale build after structural changes
|
|
116
|
+
such as renamed or removed pages.
|
|
117
|
+
|
|
118
|
+
- `just pages` assembles the GitHub Pages site into `site/`: the landing
|
|
119
|
+
page from `github-pages/`, the JSON schemas under `schemas/v1alpha1/`,
|
|
120
|
+
and the example workshop as a JupyterLite site under `demo/`.
|
|
121
|
+
|
|
122
|
+
- `just clean` removes build outputs only. `just clean-examples` removes
|
|
123
|
+
what running the example workshops leaves behind (`_workshop` state,
|
|
124
|
+
`scratch` and `demo` directories) so a later run starts fresh.
|
|
125
|
+
`just distclean` does both and also removes `node_modules`, `.venv`,
|
|
126
|
+
caches, built docs and sites, returning the tree to a fresh checkout;
|
|
127
|
+
run `just install` afterwards.
|
|
128
|
+
|
|
129
|
+
## Style
|
|
130
|
+
|
|
131
|
+
- Do not use emdashes in any files in this project. Rephrase with commas,
|
|
132
|
+
parentheses, colons, or separate sentences instead.
|
|
133
|
+
|
|
134
|
+
- In bulleted lists where items run to multiple lines, put a blank
|
|
135
|
+
line between the bullets: in docstrings, markdown files, and any
|
|
136
|
+
other prose. This is about the raw file being readable, not the
|
|
137
|
+
rendered form, which can look fine either way. Be consistent within
|
|
138
|
+
a list: if one item needs the spacing, space every item in that
|
|
139
|
+
list, never a mix.
|
|
140
|
+
|
|
141
|
+
- Python code must always use type hints. Add them to all function
|
|
142
|
+
and method signatures (parameters and return types), and to attributes
|
|
143
|
+
and variables where the type is not obvious from the assignment. When
|
|
144
|
+
adding or modifying code that lacks type hints, add them.
|
|
145
|
+
|
|
146
|
+
- TypeScript code must be explicitly typed at its boundaries: every
|
|
147
|
+
exported function, method, class member and module-level constant has
|
|
148
|
+
an explicit type or return type. Never use `any`; use `unknown` and
|
|
149
|
+
narrow it. Do not disable strict compiler options.
|
|
150
|
+
|
|
151
|
+
- Use vertical white space liberally inside function and method bodies,
|
|
152
|
+
in both Python and TypeScript. Write code in paragraphs: group the
|
|
153
|
+
statements that together perform one step, and separate each group
|
|
154
|
+
from the next with a blank line. Natural paragraph boundaries include
|
|
155
|
+
setup versus the main work versus the result, before and after a
|
|
156
|
+
conditional or loop, and around a with or try block. Do not cram a body
|
|
157
|
+
into one contiguous blob, and equally do not put a blank line between
|
|
158
|
+
every single statement; the blank lines should mark where one thought
|
|
159
|
+
ends and the next begins.
|
|
160
|
+
|
|
161
|
+
- Where it helps the reader, start a paragraph of code with a short
|
|
162
|
+
comment saying what that step does or why it is needed. Prefer one
|
|
163
|
+
comment per logical block over line-by-line commentary, and skip the
|
|
164
|
+
comment entirely when the code already says it plainly.
|
|
165
|
+
|
|
166
|
+
- Put a blank line between such a block comment and the code below it:
|
|
167
|
+
the comment introduces the paragraph rather than sitting flush against
|
|
168
|
+
its first line.
|
|
169
|
+
|
|
170
|
+
- Put a blank line between a function or method docstring and the first
|
|
171
|
+
line of code in the body.
|
|
172
|
+
|
|
173
|
+
- Every function, method or property that is part of the public API must
|
|
174
|
+
have a docstring (Python) or a TSDoc comment (TypeScript) saying what it
|
|
175
|
+
does. The exceptions are cases that are truly trivial and obvious, such
|
|
176
|
+
as an accessor property named for the attribute it returns, and dunder
|
|
177
|
+
methods implementing standard protocols.
|
|
178
|
+
|
|
179
|
+
- Every directive, action type or option added to the workshop format must
|
|
180
|
+
be reflected in the JSON schema, the lint rules and the format
|
|
181
|
+
documentation in the same change.
|
|
182
|
+
|
|
183
|
+
- Verify JupyterLab API names against the installed version's TypeScript
|
|
184
|
+
definitions (under `node_modules/@jupyterlab/*/lib/`) before using them.
|
|
185
|
+
Use only public tokens and APIs.
|
|
186
|
+
|
|
187
|
+
## Git
|
|
188
|
+
|
|
189
|
+
- Git commit messages must never include a co-authored-by agent message or
|
|
190
|
+
any similar agent attribution trailer.
|
|
191
|
+
|
|
192
|
+
- An AI agent must never commit changes on its own initiative. Finish the
|
|
193
|
+
piece of work, summarize it, and wait to be told to commit. Permission to
|
|
194
|
+
commit applies only to the work it was given for; it does not carry
|
|
195
|
+
forward to later steps of a multi-step plan, each of which needs its own
|
|
196
|
+
review and its own instruction to commit. Uncommitted changes are how the
|
|
197
|
+
review happens: once work is committed it can no longer be reviewed as
|
|
198
|
+
the pending diff, so committing early makes review harder, not easier.
|
|
199
|
+
|
|
200
|
+
- `develop` is the default and working branch; `main` holds released
|
|
201
|
+
code and is what GitHub Pages and the Binder link build from. Never tag
|
|
202
|
+
from develop.
|
|
203
|
+
|
|
204
|
+
- A release bumps the version in four files together, in one commit on
|
|
205
|
+
develop: the root `package.json` (the Python package reads its version
|
|
206
|
+
from it), `packages/core/package.json`,
|
|
207
|
+
`packages/labextension/package.json`, and the
|
|
208
|
+
`jupyterlab-workshop==<version>` pin in `binder/requirements.txt`. The
|
|
209
|
+
pin matters because mybinder caches the image it builds for a commit of
|
|
210
|
+
main, so an unpinned install would freeze whichever release PyPI served
|
|
211
|
+
at the first launch. Then fast-forward main, wait for CI, and push the
|
|
212
|
+
bare version tag; the release workflow refuses a tag that does not
|
|
213
|
+
match `package.json`. Version numbers cannot be reused on PyPI, so a
|
|
214
|
+
failed publish means moving on to the next patch number.
|
|
215
|
+
|
|
216
|
+
- The release steps in full, for a release of `X.Y.Z`. Each step waits
|
|
217
|
+
for the previous one to finish; never chain the tag push behind a CI
|
|
218
|
+
check in one command, read the CI result first and then tag.
|
|
219
|
+
|
|
220
|
+
1. On develop with a clean tree, set `"version": "X.Y.Z"` in the three
|
|
221
|
+
`package.json` files and `jupyterlab-workshop==X.Y.Z` in
|
|
222
|
+
`binder/requirements.txt`, then commit them together:
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
git commit -am "Bump version to X.Y.Z"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
2. Push develop and wait for its CI run to pass. A push starts the
|
|
229
|
+
`ci` workflow only:
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
git push origin develop
|
|
233
|
+
gh run list --branch develop --workflow ci --limit 1
|
|
234
|
+
gh run watch <run-id> --exit-status
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
3. Fast-forward main to develop and push it. A push to main starts two
|
|
238
|
+
workflows, `ci` and `pages`, so select each run by workflow name
|
|
239
|
+
rather than taking the first id listed, and wait for both:
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
git checkout main
|
|
243
|
+
git merge --ff-only develop
|
|
244
|
+
git push origin main
|
|
245
|
+
gh run list --branch main --workflow ci --limit 1
|
|
246
|
+
gh run list --branch main --workflow pages --limit 1
|
|
247
|
+
gh run watch <run-id> --exit-status
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
4. Only once both are green, push the bare version tag (no `v`
|
|
251
|
+
prefix) from main. This starts the `release` workflow: build, PyPI
|
|
252
|
+
publish and GitHub release:
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
git tag X.Y.Z
|
|
256
|
+
git push origin X.Y.Z
|
|
257
|
+
gh run list --workflow release --limit 1
|
|
258
|
+
gh run watch <run-id> --exit-status
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
5. Confirm the release landed, then go back to develop:
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
gh release view X.Y.Z
|
|
265
|
+
git checkout develop
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
PyPI's JSON API lags a fresh upload; check the simple index at
|
|
269
|
+
`https://pypi.org/simple/jupyterlab-workshop/` instead. Locally,
|
|
270
|
+
`uv sync --reinstall-package jupyterlab-workshop` is needed before
|
|
271
|
+
the Python side reports the new version.
|
|
272
|
+
|
|
273
|
+
Three self-test flakes are known in CI and are not regressions: the
|
|
274
|
+
browser job's hello-jupyterlab hidden-kernel execute-capture step;
|
|
275
|
+
the lite job's terminal `execute` with `wait: prompt` timing out at
|
|
276
|
+
120s on a trivial command; and the windows job failing only in
|
|
277
|
+
temporary directory cleanup, with `PermissionError: [WinError 32]`
|
|
278
|
+
on the `workshop-test-*` root because the server still holds it,
|
|
279
|
+
after the self-test itself has reported its passes. Rerun the failed
|
|
280
|
+
jobs with `gh run rerun <run-id> --failed` and wait for the rerun to
|
|
281
|
+
pass before going on; a rerun that fails again is a real problem, so
|
|
282
|
+
stop and report it. Read the result with
|
|
283
|
+
`gh run view <run-id> --json conclusion,jobs` rather than trusting
|
|
284
|
+
the exit status of `gh run watch`, which has reported success for a
|
|
285
|
+
failed run.
|
|
286
|
+
|
|
287
|
+
- When merging a feature branch back to main and pushing to the remote,
|
|
288
|
+
do not treat the work as landed until the CI workflow on GitHub has run
|
|
289
|
+
against the pushed merge and passed. Check the run (for example with
|
|
290
|
+
`gh run list --branch main` and `gh run watch`), and only once it is
|
|
291
|
+
green report that the changes are on the remote and clean up the feature
|
|
292
|
+
branch. If CI fails, leave the feature branch in place, report the
|
|
293
|
+
failure, and wait for instructions rather than deleting anything.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Development setup and workflow for jupyterlab-workshop. The user-facing
|
|
4
|
+
documentation is under `docs/` and published at
|
|
5
|
+
<https://jupyterlab-workshop.readthedocs.io/>; this file is about working
|
|
6
|
+
on the project itself.
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
Requires [uv](https://docs.astral.sh/uv/), [just](https://just.systems/),
|
|
11
|
+
Node.js and git.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
just install
|
|
15
|
+
just lab
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`just install` creates the Python environment, installs the JavaScript
|
|
19
|
+
workspace, builds the extension and links it into JupyterLab in
|
|
20
|
+
development mode. `just lab` starts JupyterLab with the repository root
|
|
21
|
+
as its root directory, which is where the example workshops live, and
|
|
22
|
+
with the settings in `dev/overrides.json`: it opens in the workshop
|
|
23
|
+
browser with the three examples listed as installed, the examples
|
|
24
|
+
collection under `collections/examples/` and the checkout's
|
|
25
|
+
`collections/catalog.json` subscribed to, so the collection and catalog
|
|
26
|
+
code paths have something local to work on. Open the Workshop panel in the
|
|
27
|
+
right sidebar (the `panelSide` setting, or dragging the tab, moves it to
|
|
28
|
+
the left).
|
|
29
|
+
|
|
30
|
+
To rebuild while editing the TypeScript, run `just watch` in a second
|
|
31
|
+
terminal and refresh the browser after each rebuild. `just --list` shows
|
|
32
|
+
every task.
|
|
33
|
+
|
|
34
|
+
## Running the examples from a checkout
|
|
35
|
+
|
|
36
|
+
With `just lab` running, open Git from the command line from the
|
|
37
|
+
Installed section of the browser. The folder button in the panel header
|
|
38
|
+
picks any other workshop directory, and right-clicking a directory in
|
|
39
|
+
the file browser and choosing "Open as Workshop" does the same.
|
|
40
|
+
|
|
41
|
+
1. On page one, click each command block in turn. The first click starts
|
|
42
|
+
a terminal named `git` in a split beneath the main area and runs the
|
|
43
|
+
command there. Every block shows exactly the text sent to the
|
|
44
|
+
terminal.
|
|
45
|
+
|
|
46
|
+
2. On page two, the first action writes `README.md` into the `demo`
|
|
47
|
+
directory and opens it in the editor above the terminal. The final
|
|
48
|
+
action highlights the terminal with a short callout.
|
|
49
|
+
|
|
50
|
+
3. Page three appends a line to the open file through the editor and
|
|
51
|
+
saves it, then opens a second terminal named `log` beside the first.
|
|
52
|
+
|
|
53
|
+
4. Pages four and five branch, merge, create a conflict, open the file at
|
|
54
|
+
the conflict marker and resolve it by rewriting the file. The last
|
|
55
|
+
action shows a success notification.
|
|
56
|
+
|
|
57
|
+
5. Use the arrows or the page dropdown to move between pages. Reload the
|
|
58
|
+
browser tab: the panel reopens on the same page.
|
|
59
|
+
|
|
60
|
+
`examples/hello-jupyterlab` exercises notebooks, kernels, the interface,
|
|
61
|
+
files, variables, tracks and automatic runs, and writes its files into
|
|
62
|
+
`examples/hello-jupyterlab/scratch`. The git example creates
|
|
63
|
+
`examples/git-basics/demo`, and every example keeps its progress under
|
|
64
|
+
its `_workshop` directory. All of these are ignored by git; the Restart
|
|
65
|
+
button in the panel header puts a workshop back, and `just
|
|
66
|
+
clean-examples` removes what every example left behind.
|
|
67
|
+
|
|
68
|
+
## Layout
|
|
69
|
+
|
|
70
|
+
- `packages/core/` is `@jupyterlab-workshop/core`, pure TypeScript with no
|
|
71
|
+
JupyterLab dependencies: the workshop format, actions, variables, lint
|
|
72
|
+
rules and JSON schemas.
|
|
73
|
+
|
|
74
|
+
- `packages/labextension/` is `@jupyterlab-workshop/labextension`, the
|
|
75
|
+
JupyterLab frontend extension.
|
|
76
|
+
|
|
77
|
+
- `jupyterlab_workshop/` is the Python package: the `jupyter_server`
|
|
78
|
+
extension and the `jupyter workshop` command line.
|
|
79
|
+
|
|
80
|
+
- `examples/` holds the example workshops, which double as test fixtures.
|
|
81
|
+
|
|
82
|
+
- `docs/` is the Sphinx documentation and `github-pages/` the landing page
|
|
83
|
+
of the project site.
|
|
84
|
+
|
|
85
|
+
## Checks and tests
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
just lint
|
|
89
|
+
just typecheck
|
|
90
|
+
just test
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`just test` runs the Jest tests for `packages/core` and the pytest suite.
|
|
94
|
+
`just test-ui` runs the Galata browser tests against a real JupyterLab,
|
|
95
|
+
`just selftest` runs every action of the example workshops in JupyterLab,
|
|
96
|
+
and `just selftest-lite` does the same in a JupyterLite build. See
|
|
97
|
+
TESTING.md for where the tests live and how to add more.
|
|
98
|
+
|
|
99
|
+
Python is managed with uv and JavaScript with `jlpm`, the Yarn that ships
|
|
100
|
+
with JupyterLab, run as `uv run jlpm`. Do not use pip, npm or a system
|
|
101
|
+
yarn directly. AGENTS.md records the coding conventions the project
|
|
102
|
+
follows.
|
|
103
|
+
|
|
104
|
+
## Documentation and the project site
|
|
105
|
+
|
|
106
|
+
`just docs` builds the documentation into `docs/_build/html`, and
|
|
107
|
+
`just docs-serve` rebuilds it on change. The manifest reference page is
|
|
108
|
+
generated from the JSON schema on every build. The screenshots under
|
|
109
|
+
`docs/_static` are committed; `just screenshots` retakes them from a
|
|
110
|
+
throwaway JupyterLab after an interface change, and needs the `test`
|
|
111
|
+
extra and a Chromium for Playwright.
|
|
112
|
+
|
|
113
|
+
`just pages` assembles the GitHub Pages site into `site/`: the landing
|
|
114
|
+
page, the JSON schemas and the example workshop built as a JupyterLite
|
|
115
|
+
site under `demo/`. Building the JupyterLite terminal needs `node`, `npm`
|
|
116
|
+
and `micromamba` on the path; pass `--no-terminal` to leave it out.
|
|
117
|
+
|
|
118
|
+
## Releases
|
|
119
|
+
|
|
120
|
+
The version is read from the root `package.json` by the Python build, so
|
|
121
|
+
bump it there, in the two workspace `package.json` files, and in the
|
|
122
|
+
`jupyterlab-workshop==<version>` pin of `binder/requirements.txt`
|
|
123
|
+
together (mybinder caches the image built for a commit, so the pin keeps
|
|
124
|
+
the Binder image on the matching release).
|
|
125
|
+
Releases are made by pushing a tag that is the bare version string, such
|
|
126
|
+
as `0.1.0`, with no `v` prefix. The release workflow refuses to build if
|
|
127
|
+
the tag does not match the version in `package.json`, then builds the
|
|
128
|
+
wheel and sdist, attaches them to a GitHub release and publishes to PyPI.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Development tasks for jupyterlab-workshop.
|
|
2
|
+
#
|
|
3
|
+
# Python is managed with uv, JavaScript with jlpm (the Yarn that ships with
|
|
4
|
+
# JupyterLab, installed into the project environment). Run `just --list`
|
|
5
|
+
# to see the available targets.
|
|
6
|
+
|
|
7
|
+
set positional-arguments
|
|
8
|
+
|
|
9
|
+
# List the available targets.
|
|
10
|
+
default:
|
|
11
|
+
@just --list
|
|
12
|
+
|
|
13
|
+
# Set up the development environment and link the extension into JupyterLab.
|
|
14
|
+
install:
|
|
15
|
+
uv sync --no-install-project
|
|
16
|
+
uv run --no-sync jlpm install
|
|
17
|
+
uv run --no-sync jlpm build
|
|
18
|
+
uv sync
|
|
19
|
+
uv run jupyter labextension develop . --overwrite
|
|
20
|
+
uv run jupyter server extension enable jupyterlab_workshop
|
|
21
|
+
|
|
22
|
+
# Build the TypeScript packages and the labextension bundle.
|
|
23
|
+
build:
|
|
24
|
+
uv run jlpm build
|
|
25
|
+
|
|
26
|
+
# Rebuild the TypeScript packages and labextension on change (run alongside `just lab`).
|
|
27
|
+
watch:
|
|
28
|
+
uv run jlpm watch
|
|
29
|
+
|
|
30
|
+
# Start JupyterLab from the repository root with the extension loaded.
|
|
31
|
+
# The settings in dev/overrides.json make it start in the workshop browser with the examples installed.
|
|
32
|
+
lab *args:
|
|
33
|
+
uv run jupyter lab --notebook-dir=. --LabApp.app_settings_dir=dev "$@"
|
|
34
|
+
|
|
35
|
+
# Run the fast test suites: Jest for packages/core and pytest for the Python package.
|
|
36
|
+
test *args:
|
|
37
|
+
uv run jlpm test
|
|
38
|
+
uv run pytest "$@"
|
|
39
|
+
|
|
40
|
+
# Run only the Jest tests for packages/core.
|
|
41
|
+
test-core *args:
|
|
42
|
+
uv run jlpm test "$@"
|
|
43
|
+
|
|
44
|
+
# Run only the pytest suite for the Python package.
|
|
45
|
+
test-python *args:
|
|
46
|
+
uv run pytest "$@"
|
|
47
|
+
|
|
48
|
+
# Run the Galata browser tests against a real JupyterLab on port 8890 (slow).
|
|
49
|
+
test-ui *args:
|
|
50
|
+
cd tests/ui-tests && uv run jlpm install && JUPYTER_PORT=8890 uv run jlpm playwright test "$@"
|
|
51
|
+
|
|
52
|
+
# Check TypeScript with eslint and prettier, and Python with ruff.
|
|
53
|
+
lint:
|
|
54
|
+
uv run jlpm lint:check
|
|
55
|
+
uv run ruff check .
|
|
56
|
+
uv run ruff format --check .
|
|
57
|
+
|
|
58
|
+
# Reformat and apply auto-fixes for TypeScript and Python.
|
|
59
|
+
format:
|
|
60
|
+
uv run jlpm lint
|
|
61
|
+
uv run ruff check --fix .
|
|
62
|
+
uv run ruff format .
|
|
63
|
+
|
|
64
|
+
# Type check the TypeScript packages with tsc and the Python package with mypy.
|
|
65
|
+
typecheck:
|
|
66
|
+
uv run jlpm typecheck
|
|
67
|
+
uv run mypy
|
|
68
|
+
|
|
69
|
+
# Retake the screenshots in docs/_static from a throwaway JupyterLab (needs the test extra and a Chromium for Playwright).
|
|
70
|
+
screenshots:
|
|
71
|
+
uv run python scripts/screenshots.py
|
|
72
|
+
|
|
73
|
+
# Build the documentation with Sphinx into docs/_build/html (generates the manifest reference first).
|
|
74
|
+
docs:
|
|
75
|
+
uv run sphinx-build -W --keep-going -b html docs docs/_build/html
|
|
76
|
+
|
|
77
|
+
# Serve the documentation with live reload.
|
|
78
|
+
docs-serve:
|
|
79
|
+
uv run sphinx-autobuild docs docs/_build/html
|
|
80
|
+
|
|
81
|
+
# Clear generated documentation outputs.
|
|
82
|
+
docs-clean:
|
|
83
|
+
rm -rf docs/_build docs/reference
|
|
84
|
+
|
|
85
|
+
# Assemble the GitHub Pages site into site/: landing page, JSON schemas and the JupyterLite demo.
|
|
86
|
+
pages *args:
|
|
87
|
+
rm -rf site
|
|
88
|
+
mkdir -p site/schemas/v1alpha1
|
|
89
|
+
cp github-pages/index.html site/index.html
|
|
90
|
+
touch site/.nojekyll
|
|
91
|
+
cp packages/core/src/schema/workshop.schema.json packages/core/src/schema/collection.schema.json packages/core/src/schema/catalog.schema.json site/schemas/v1alpha1/
|
|
92
|
+
uv run jupyter workshop lite examples/hello-jupyterlab --out site/demo "$@"
|
|
93
|
+
|
|
94
|
+
# Self-test a workshop directory in a real JupyterLab (default: every example).
|
|
95
|
+
selftest *args:
|
|
96
|
+
#!/usr/bin/env bash
|
|
97
|
+
set -euo pipefail
|
|
98
|
+
if [ "$#" -eq 0 ]; then set -- examples/git-basics examples/hello-jupyterlab examples/workshop-authoring; fi
|
|
99
|
+
for dir in "$@"; do uv run jupyter workshop test "$dir"; done
|
|
100
|
+
|
|
101
|
+
# Self-test a workshop in a static JupyterLite build (default: hello-jupyterlab).
|
|
102
|
+
selftest-lite *args:
|
|
103
|
+
#!/usr/bin/env bash
|
|
104
|
+
set -euo pipefail
|
|
105
|
+
if [ "$#" -eq 0 ]; then set -- examples/hello-jupyterlab; fi
|
|
106
|
+
for dir in "$@"; do uv run jupyter workshop test "$dir" --lite; done
|
|
107
|
+
|
|
108
|
+
# Build a JupyterLite site with the example workshop into lite-site/ and serve it.
|
|
109
|
+
lite *args:
|
|
110
|
+
uv run jupyter workshop lite examples/hello-jupyterlab --out lite-site --serve "$@"
|
|
111
|
+
|
|
112
|
+
# Remove build outputs (compiled TypeScript, the labextension bundle, lint caches).
|
|
113
|
+
clean:
|
|
114
|
+
uv run jlpm clean
|
|
115
|
+
uv run jlpm clean:lintcache
|
|
116
|
+
|
|
117
|
+
# Remove what running the example workshops leaves behind (_workshop state, scratch and demo directories).
|
|
118
|
+
clean-examples:
|
|
119
|
+
rm -rf examples/*/_workshop examples/*/scratch examples/*/demo
|
|
120
|
+
|
|
121
|
+
# Return to a fresh checkout: also removes node_modules, .venv, caches, built docs and sites.
|
|
122
|
+
distclean: clean-examples
|
|
123
|
+
rm -rf packages/core/lib packages/labextension/lib packages/*/tsconfig.tsbuildinfo
|
|
124
|
+
rm -rf jupyterlab_workshop/labextension jupyterlab_workshop/nodejs jupyterlab_workshop/schema
|
|
125
|
+
rm -rf .eslintcache .stylelintcache packages/core/coverage
|
|
126
|
+
rm -rf node_modules packages/*/node_modules tests/ui-tests/node_modules .venv
|
|
127
|
+
rm -rf site docs/_build docs/reference build dist lite-site .jupyterlite.doit.db .coverage htmlcov
|
|
128
|
+
rm -rf tests/ui-tests/test-results tests/ui-tests/playwright-report
|
|
129
|
+
rm -rf workshops
|
|
130
|
+
find . -type d \( -name __pycache__ -o -name .ipynb_checkpoints -o -name '*.egg-info' -o -name .yarn -o -name .mypy_cache -o -name .ruff_cache -o -name .pytest_cache \) -prune -exec rm -rf {} +
|