jupyterlab-claude-code-extension 1.0.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 (56) hide show
  1. jupyterlab_claude_code_extension-1.0.16/.claude/CLAUDE.md +116 -0
  2. jupyterlab_claude_code_extension-1.0.16/.claude/JOURNAL.md +14 -0
  3. jupyterlab_claude_code_extension-1.0.16/.claude/scheduled_tasks.lock +1 -0
  4. jupyterlab_claude_code_extension-1.0.16/.copier-answers.yml +20 -0
  5. jupyterlab_claude_code_extension-1.0.16/.gitignore +131 -0
  6. jupyterlab_claude_code_extension-1.0.16/.prettierignore +6 -0
  7. jupyterlab_claude_code_extension-1.0.16/.resources/screenshot.png +0 -0
  8. jupyterlab_claude_code_extension-1.0.16/.yarnrc.yml +2 -0
  9. jupyterlab_claude_code_extension-1.0.16/CHANGELOG.md +5 -0
  10. jupyterlab_claude_code_extension-1.0.16/LICENSE +29 -0
  11. jupyterlab_claude_code_extension-1.0.16/Makefile +130 -0
  12. jupyterlab_claude_code_extension-1.0.16/PKG-INFO +115 -0
  13. jupyterlab_claude_code_extension-1.0.16/README.md +51 -0
  14. jupyterlab_claude_code_extension-1.0.16/RELEASE.md +80 -0
  15. jupyterlab_claude_code_extension-1.0.16/babel.config.js +1 -0
  16. jupyterlab_claude_code_extension-1.0.16/conftest.py +8 -0
  17. jupyterlab_claude_code_extension-1.0.16/install.json +5 -0
  18. jupyterlab_claude_code_extension-1.0.16/jest.config.js +28 -0
  19. jupyterlab_claude_code_extension-1.0.16/jupyter-config/server-config/jupyterlab_claude_code_extension.json +7 -0
  20. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/__init__.py +36 -0
  21. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/_version.py +4 -0
  22. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/labextension/package.json +222 -0
  23. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/labextension/schemas/jupyterlab_claude_code_extension/package.json.orig +217 -0
  24. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/labextension/schemas/jupyterlab_claude_code_extension/plugin.json +16 -0
  25. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/labextension/static/661.3d2427cf22d047c65b0b.js +1 -0
  26. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/labextension/static/728.b3f09b233b1080f7e0ed.js +1 -0
  27. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/labextension/static/remoteEntry.43d0d3f9617e6fe765d7.js +1 -0
  28. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/labextension/static/style.js +4 -0
  29. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/labextension/static/third-party-licenses.json +16 -0
  30. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/routes.py +213 -0
  31. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/sessions.py +331 -0
  32. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/tests/__init__.py +1 -0
  33. jupyterlab_claude_code_extension-1.0.16/jupyterlab_claude_code_extension/tests/test_routes.py +376 -0
  34. jupyterlab_claude_code_extension-1.0.16/package-lock.json +12055 -0
  35. jupyterlab_claude_code_extension-1.0.16/package.json +217 -0
  36. jupyterlab_claude_code_extension-1.0.16/pyproject.toml +91 -0
  37. jupyterlab_claude_code_extension-1.0.16/schema/plugin.json +16 -0
  38. jupyterlab_claude_code_extension-1.0.16/setup.py +1 -0
  39. jupyterlab_claude_code_extension-1.0.16/src/__tests__/jupyterlab_claude_code_extension.spec.ts +62 -0
  40. jupyterlab_claude_code_extension-1.0.16/src/icons.ts +52 -0
  41. jupyterlab_claude_code_extension-1.0.16/src/index.ts +95 -0
  42. jupyterlab_claude_code_extension-1.0.16/src/request.ts +51 -0
  43. jupyterlab_claude_code_extension-1.0.16/src/types.ts +42 -0
  44. jupyterlab_claude_code_extension-1.0.16/src/widget.ts +764 -0
  45. jupyterlab_claude_code_extension-1.0.16/style/base.css +246 -0
  46. jupyterlab_claude_code_extension-1.0.16/style/index.css +1 -0
  47. jupyterlab_claude_code_extension-1.0.16/style/index.js +1 -0
  48. jupyterlab_claude_code_extension-1.0.16/tsconfig.json +25 -0
  49. jupyterlab_claude_code_extension-1.0.16/tsconfig.test.json +3 -0
  50. jupyterlab_claude_code_extension-1.0.16/ui-tests/README.md +167 -0
  51. jupyterlab_claude_code_extension-1.0.16/ui-tests/jupyter_server_test_config.py +12 -0
  52. jupyterlab_claude_code_extension-1.0.16/ui-tests/package.json +15 -0
  53. jupyterlab_claude_code_extension-1.0.16/ui-tests/playwright.config.js +14 -0
  54. jupyterlab_claude_code_extension-1.0.16/ui-tests/tests/jupyterlab_claude_code_extension.spec.ts +25 -0
  55. jupyterlab_claude_code_extension-1.0.16/ui-tests/yarn.lock +0 -0
  56. jupyterlab_claude_code_extension-1.0.16/yarn.lock +10891 -0
@@ -0,0 +1,116 @@
1
+ <!-- @import /home/lab/workspace/.claude/CLAUDE.md -->
2
+
3
+ # Project-Specific Configuration
4
+
5
+ This file imports workspace-level configuration from `/home/lab/workspace/.claude/CLAUDE.md`.
6
+ All workspace rules apply. Project-specific rules below strengthen or extend them.
7
+
8
+ The workspace `/home/lab/workspace/.claude/` directory contains additional instruction files
9
+ referenced by CLAUDE.md. Consult workspace CLAUDE.md and the .claude directory to discover
10
+ all applicable standards.
11
+
12
+ ## Mandatory Bans (Reinforced)
13
+
14
+ The following workspace rules are STRICTLY ENFORCED for this project:
15
+
16
+ - **No automatic git tags** - only create tags when user explicitly requests
17
+ - **No automatic version changes** - only modify version in package.json/pyproject.toml/etc. when user explicitly requests
18
+ - **No automatic publishing** - never run `make publish`, `npm publish`, `twine upload`, or similar without explicit user request
19
+ - **No manual package installs if Makefile exists** - use `make install` or equivalent Makefile targets, not direct `pip install`/`uv install`/`npm install`
20
+ - **No automatic git commits or pushes** - only when user explicitly requests
21
+
22
+ ## Project Context
23
+
24
+ `jupyterlab_claude_code_extension` is a JupyterLab 4 extension that adds a Claude Code session
25
+ management panel to the JupyterLab UI. It exposes recent, all, and favourite Claude Code sessions,
26
+ indicates whether a session is enabled for remote control, allows session removal via context menu,
27
+ and opens Claude Code in a terminal at the session's directory when clicked.
28
+
29
+ **Technology Stack**:
30
+
31
+ - TypeScript + Lumino frontend (`src/`) packaged as an `npm` labextension
32
+ - Python `jupyter_server` extension (`jupyterlab_claude_code_extension/`) providing the backend API
33
+ - `hatchling` + `hatch-nodejs-version` + `hatch-jupyter-builder` for build orchestration
34
+ - `jlpm` (JupyterLab's pinned yarn) for JavaScript dependency management
35
+ - `pytest` for server tests, `jest` for frontend unit tests, `Playwright` + Galata for UI integration tests
36
+
37
+ **Runtime requirements**:
38
+
39
+ - Python `>= 3.10`
40
+ - JupyterLab `>= 4.0.0`
41
+ - `jupyter_server >= 2.4.0, < 3`
42
+
43
+ ## Required Workspace Skills
44
+
45
+ The following skills MUST be referenced and applied to relevant work in this project. They live
46
+ under `/home/lab/workspace/.claude/skills/` and are also auto-discovered globally by Claude Code:
47
+
48
+ - **`jupyterlab-extension`** at `/home/lab/workspace/.claude/skills/jupyterlab-extension/` -
49
+ JupyterLab extension development guidelines, testing strategy, jupyter-releaser CI/CD workflows,
50
+ TypeScript compatibility caveats, syntax-highlighting integration, and local development
51
+ patterns. MUST be consulted for any change to `src/`, `schema/`, `style/`, `package.json`,
52
+ `pyproject.toml`, `.github/workflows/`, or anything affecting build / install / release flow
53
+
54
+ - **`playwright`** at `/home/lab/workspace/.claude/skills/playwright/` - Playwright MCP browser
55
+ automation for inspecting web UIs, serving and viewing local files, testing SVGs/HTML, and
56
+ connecting to authenticated services like JupyterHub. MUST be used when validating UI changes,
57
+ capturing README screenshots, reproducing UI bugs, or running ad-hoc visual regression checks
58
+
59
+ ## Makefile Version Pin
60
+
61
+ The local `Makefile` is sourced from a canonical workspace template:
62
+
63
+ - Canonical path: `/home/lab/workspace/private/jupyterlab/@utils/jupyterlab-extensions/Makefile`
64
+ - Current pinned version: **1.31** (matches local Makefile as of project initialization)
65
+
66
+ **MANDATORY**: At the start of any session that touches build, install, release, or CI workflow
67
+ work, check the canonical Makefile's version header (line 1: `# Makefile for Jupyterlab extensions
68
+ version X.YZ`) against the local Makefile's version. If the canonical version is newer, update
69
+ the local Makefile to match before doing any other build-related work, and reflect the new
70
+ version in this section.
71
+
72
+ Quick check:
73
+
74
+ ```bash
75
+ diff <(head -1 Makefile) <(head -1 /home/lab/workspace/private/jupyterlab/@utils/jupyterlab-extensions/Makefile)
76
+ ```
77
+
78
+ If the headers differ, replace the local Makefile with the canonical one (preserving any
79
+ project-specific targets if they exist - currently there are none).
80
+
81
+ ## Package Manifest Tracking
82
+
83
+ Both `package.json` AND `package-lock.json` MUST always be committed together:
84
+
85
+ - `package-lock.json` is **never** added to `.gitignore`
86
+ - The `Makefile` `build` target runs `npx prettier --write package-lock.json package.json` to
87
+ keep both files formatted - any commit touching dependencies must stage both files
88
+ - When bumping a dependency or running `jlpm install`, always `git add package.json package-lock.json`
89
+
90
+ ## Install Discipline
91
+
92
+ All package installation in this project MUST go through `make install`:
93
+
94
+ - `make install` orchestrates the correct sequence: `clean` -> `increment_version` -> `build`
95
+ (`npm install`, `jlpm install`, `prettier`, `python -m build`) -> `pip install dist/*.whl --force-reinstall`
96
+ - Direct `pip install`, `jlpm install`, `npm install`, `yarn install` are **forbidden** for routine
97
+ install work in this project - they bypass the version increment, the prettier pass, and the
98
+ wheel-based reinstall that the Makefile guarantees
99
+ - `make install_dependencies` is the only hook for first-time tooling setup (nodeenv, twine, yarn, rimraf)
100
+ - Run `make help` to see all available targets
101
+
102
+ ## Journal Rules (Project-Specific)
103
+
104
+ - **APPEND ONLY**: New journal entries MUST be appended at the end of the file, never inserted between existing entries
105
+ - Entries maintain strict chronological order by position - the last entry in the file is always the most recent work
106
+ - Never reorder, move, or insert entries out of sequence
107
+ - The Stellars **journal plugin** is the canonical tool for this file: create via `/journal:create`, append via `/journal:update`, archive via `/journal:archive`. The `journal:journal` skill auto-triggers on any mention of "journal" and runs `journal-tools check` after every write
108
+ - Direct edits to `JOURNAL.md` are a last resort - prefer the plugin so modus secundis format, continuous numbering and append-only order are enforced automatically
109
+
110
+ ## Strengthened Rules
111
+
112
+ - **No emojis** anywhere in this project (workspace rule strictly enforced - extension UI text, README, code comments, journal entries)
113
+ - **No em-dashes, no arrow symbols** in any markdown - use `-` and `->` per workspace typography rules
114
+ - **`make install` is the only blessed install path** (see Install Discipline above)
115
+ - **Skills `jupyterlab-extension` and `playwright` are mandatory references** for source / UI / CI work (see Required Workspace Skills above)
116
+ - **Makefile version pin** must be re-checked every session touching build flow (see Makefile Version Pin above)
@@ -0,0 +1,14 @@
1
+ # Claude Code Journal
2
+
3
+ This journal tracks substantive work on documents, diagrams, and documentation content.
4
+
5
+ ---
6
+
7
+ 1. **Task - Project initialization** (v0.1.0): Bootstrapped `jupyterlab_claude_code_extension` as a new JupyterLab 4 extension with Stellars workspace conventions<br>
8
+ **Result**: Cookiecutter-scaffolded project (TypeScript `src/`, Python `jupyter_server` extension, `hatchling` + `hatch-jupyter-builder`, Python `>= 3.10`, JupyterLab `>= 4.0.0`) had no git repo, no journal, no badges, and an inline-rules `.claude/CLAUDE.md`. Replaced `.claude/CLAUDE.md` with the canonical `@import` template plus project-specific sections: Mandatory Bans, Project Context, Required Workspace Skills (`jupyterlab-extension`, `playwright`), Makefile Version Pin (canonical at `private/jupyterlab/@utils/jupyterlab-extensions/Makefile`, v1.31), Package Manifest Tracking (`package.json` and `package-lock.json` always committed together), Install Discipline (`make install` only), and Journal Rules. Rewrote `README.md` mirroring `jupyterlab_terminal_show_in_file_browser_extension`: full Stellars badge stack, five-bullet Features section, truncated everything below Uninstall. Verified `.gitignore` keeps `package-lock.json` tracked. Local Makefile byte-identical to canonical v1.31. Repo initialised with `git init -b main` and a single `chore: initial import` commit.
9
+
10
+ 2. **Task - Sessions panel implementation** (v0.1.1): Replaced cookiecutter `hello` stub with the full Claude Code Sessions side panel<br>
11
+ **Result**: Added `jupyterlab_claude_code_extension/sessions.py` with `list_sessions`, `remote_control_pids`, `toggle_favourite`, `remove_session`. Sessions dedupe to one row per `~/.claude/projects/<encoded>/` (most-recent JSONL by `fileMtime` wins); name comes from Claude's `summary`, falling back to a JSONL `cwd` scan + basename. Remote-control flag scans `~/.claude/sessions/*.json` and confirms each PID via `os.kill(pid, 0)`. Favourites persist atomically to `~/.claude/jupyterlab_claude_code_extension.json`. Tornado handlers in `routes.py` expose `/status`, `/sessions`, `/sessions/favourite`, `/sessions/remove` with traversal protection (15 pytest tests pass). Frontend gates activation on `/status`, adds `src/widget.ts` (Lumino `Widget`, three accordion sections, 10s polling, optimistic favourite toggle, Lumino `Menu`, `terminal:create-new`-driven resume injecting `claude --resume <id>` over stdin), `src/icons.ts` with the Claude logo, `src/types.ts`, `style/base.css`. `make install` registers `v0.1.1 enabled OK`; jest 4/4; live enumeration finds 66 sessions.
12
+
13
+ 3. **Task - Panel UX iteration** (v0.6.15): Hardened naming, terminal reuse, layout, and settings across many follow-up rounds<br>
14
+ **Result**: Renames now read from `~/.claude/sessions/<pid>.json` `name` field and survive disambiguation by minimum trailing path-segments (frontend); auto-derived names are filtered via two heuristics - same `sessionId` carrying multiple distinct names is volatile, plus a format check (`_looks_auto_named`) flagging 3+ token lowercase-kebab strings. `routes.py` `StatusHandler` now also returns `server_root_dir` so the widget renders relative tooltip paths. Terminal reuse persists `path -> terminalSessionName` in `localStorage` and walks `app.shell.widgets('main')` on click - no duplicate tabs across reloads. JL `ISettingRegistry` plugin (`schema/plugin.json`) exposes `resolveSessionNames` (default true). Other landings: `ILayoutRestorer` registration, scroll-position preservation across the 10s poll, `ContextMenu` class scoping for centered trash icon, JL menu-spec row sizing (24 px / `--jp-ui-font-size1`), body `overflow: hidden` with All-section `flex: 1 1 0`, Material refresh + trash icons mirrored from `jupyterlab_trash_mgmt_extension`, star-as-indicator (no inline button), aboutToClose timing fix so menu commands actually run. 27 pytest pass; jest 4/4; build green at `v0.6.15 enabled OK`.
@@ -0,0 +1 @@
1
+ {"sessionId":"303ebd38-8ec8-4632-9e31-52eaed07c298","pid":2877,"procStart":"25111612","acquiredAt":1777546738882}
@@ -0,0 +1,20 @@
1
+ # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
2
+ _commit: v4.5.2
3
+ _src_path: https://github.com/jupyterlab/extension-template
4
+ author_email: konrad.jelen@gmail.com
5
+ author_name: Stellars Henson
6
+ has_ai_rules: false
7
+ has_binder: false
8
+ has_settings: false
9
+ kind: frontend-and-server
10
+ labextension_name: jupyterlab_claude_code_extension
11
+ project_short_description: Jupyterlab extension to help with ai assisted coding with
12
+ Claude Code. It implements a tool panel (like jupyterlab_trash_mgmt_extension)
13
+ with recent, all and favourite claude code sessions, it also shows if a session
14
+ is currently enabled for remote control; It also allows to remove sessions (using
15
+ context menu); When sesison is clicked - opens claude code in terminal in that
16
+ folder and continues
17
+ python_name: jupyterlab_claude_code_extension
18
+ repository: ''
19
+ test: true
20
+
@@ -0,0 +1,131 @@
1
+ *.bundle.*
2
+ lib/
3
+ node_modules/
4
+ *.log
5
+ .eslintcache
6
+ .stylelintcache
7
+ *.egg-info/
8
+ .ipynb_checkpoints
9
+ *.tsbuildinfo
10
+ jupyterlab_claude_code_extension/labextension
11
+ # Version file is handled by hatchling
12
+ jupyterlab_claude_code_extension/_version.py
13
+
14
+ # Integration tests
15
+ ui-tests/test-results/
16
+ ui-tests/playwright-report/
17
+
18
+ # Created by https://www.gitignore.io/api/python
19
+ # Edit at https://www.gitignore.io/?templates=python
20
+
21
+ ### Python ###
22
+ # Virtual environments
23
+ .venv
24
+
25
+ # Byte-compiled / optimized / DLL files
26
+ __pycache__/
27
+ *.py[cod]
28
+ *$py.class
29
+
30
+ # C extensions
31
+ *.so
32
+
33
+ # Distribution / packaging
34
+ .Python
35
+ build/
36
+ develop-eggs/
37
+ dist/
38
+ downloads/
39
+ eggs/
40
+ .eggs/
41
+ lib/
42
+ lib64/
43
+ parts/
44
+ sdist/
45
+ var/
46
+ wheels/
47
+ pip-wheel-metadata/
48
+ share/python-wheels/
49
+ .installed.cfg
50
+ *.egg
51
+ MANIFEST
52
+
53
+ # PyInstaller
54
+ # Usually these files are written by a python script from a template
55
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
56
+ *.manifest
57
+ *.spec
58
+
59
+ # Installer logs
60
+ pip-log.txt
61
+ pip-delete-this-directory.txt
62
+
63
+ # Unit test / coverage reports
64
+ htmlcov/
65
+ .tox/
66
+ .nox/
67
+ .coverage
68
+ .coverage.*
69
+ .cache
70
+ nosetests.xml
71
+ coverage/
72
+ coverage.xml
73
+ *.cover
74
+ .hypothesis/
75
+ .pytest_cache/
76
+
77
+ # Translations
78
+ *.mo
79
+ *.pot
80
+
81
+ # Scrapy stuff:
82
+ .scrapy
83
+
84
+ # Sphinx documentation
85
+ docs/_build/
86
+
87
+ # PyBuilder
88
+ target/
89
+
90
+ # pyenv
91
+ .python-version
92
+
93
+ # celery beat schedule file
94
+ celerybeat-schedule
95
+
96
+ # SageMath parsed files
97
+ *.sage.py
98
+
99
+ # Spyder project settings
100
+ .spyderproject
101
+ .spyproject
102
+
103
+ # Rope project settings
104
+ .ropeproject
105
+
106
+ # Mr Developer
107
+ .mr.developer.cfg
108
+ .project
109
+ .pydevproject
110
+
111
+ # mkdocs documentation
112
+ /site
113
+
114
+ # mypy
115
+ .mypy_cache/
116
+ .dmypy.json
117
+ dmypy.json
118
+
119
+ # Pyre type checker
120
+ .pyre/
121
+
122
+ # End of https://www.gitignore.io/api/python
123
+
124
+ # OSX files
125
+ .DS_Store
126
+
127
+ # Yarn cache
128
+ .yarn/
129
+
130
+ # pytest artefacts
131
+ junit.xml
@@ -0,0 +1,6 @@
1
+ node_modules
2
+ **/node_modules
3
+ **/lib
4
+ **/package.json
5
+ !/package.json
6
+ jupyterlab_claude_code_extension
@@ -0,0 +1,2 @@
1
+ nodeLinker: node-modules
2
+ enableScripts: false
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ <!-- <START NEW CHANGELOG ENTRY> -->
4
+
5
+ <!-- <END NEW CHANGELOG ENTRY> -->
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Stellars Henson
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,130 @@
1
+ # Makefile for Jupyterlab extensions version 1.31
2
+ # changelog:
3
+ # 1.31 - mrproper now removes ui-tests/node_modules (Playwright browser binaries)
4
+ # 1.30 - check twine in check_dependencies, ensure publish doesn't fail on missing twine
5
+ # 1.29 - replace yarn with jlpm, add prettier format, auto-commit and push after publish
6
+ # 1.28 - initial versioned Makefile
7
+ # author: Stellars Henson <konrad.jelen@gmail.com>
8
+ # License: MIT Open Source License
9
+
10
+ .PHONY: build install clean uninstall publish dependencies mrproper increment_version install_dependencies check_dependencies upgrade help test
11
+ .DEFAULT_GOAL := help
12
+
13
+ # Read current version from package.json (only if node is available)
14
+ VERSION := $(shell command -v node >/dev/null 2>&1 && node -p "require('./package.json').version" || echo "0.0.0")
15
+
16
+ ## increment project version
17
+ increment_version:
18
+ @echo "Current version: $(VERSION)"
19
+ @bash -c 'CURRENT_VERSION=$(VERSION); \
20
+ IFS="." read -r major minor patch <<< "$$CURRENT_VERSION"; \
21
+ NEW_PATCH=$$((patch + 1)); \
22
+ NEW_VERSION="$$major.$$minor.$$NEW_PATCH"; \
23
+ echo "New version: $$NEW_VERSION"; \
24
+ sed -i "s/\"version\": \"$$CURRENT_VERSION\"/\"version\": \"$$NEW_VERSION\"/" package.json; '
25
+
26
+ ## build packages
27
+ build: clean increment_version check_dependencies
28
+ npm install
29
+ jlpm install
30
+ npx prettier --write package-lock.json package.json
31
+ python -m build
32
+
33
+ ## install package
34
+ install: build
35
+ pip install dist/*.whl --force-reinstall
36
+
37
+ ## run tests
38
+ test: check_dependencies
39
+ jlpm test
40
+
41
+ ## clean builds and installables
42
+ clean: uninstall check_dependencies
43
+ @command -v npm >/dev/null 2>&1 && npm run clean || true
44
+ @command -v npm >/dev/null 2>&1 && npm run clean:labextension || true
45
+ rm -rf dist lib || true
46
+
47
+ ## uninstall package
48
+ uninstall: check_dependencies
49
+ pip uninstall -y dist/*.whl 2>/dev/null || true
50
+
51
+ ## check if required dependencies are installed
52
+ check_dependencies:
53
+ @echo "Checking dependencies..."
54
+ @MISSING=""; \
55
+ command -v node >/dev/null 2>&1 || MISSING="$$MISSING node"; \
56
+ command -v npm >/dev/null 2>&1 || MISSING="$$MISSING npm"; \
57
+ python -m twine --version >/dev/null 2>&1 || MISSING="$$MISSING twine"; \
58
+ if [ -n "$$MISSING" ]; then \
59
+ echo "Missing dependencies:$$MISSING"; \
60
+ echo "Installing missing dependencies..."; \
61
+ $(MAKE) install_dependencies; \
62
+ else \
63
+ echo "All dependencies are installed."; \
64
+ fi
65
+
66
+ ## publish package to public repository
67
+ publish: check_dependencies install
68
+ npm publish --access public
69
+ python -m twine upload dist/*
70
+ git add package.json package-lock.json
71
+ git commit -m "chore: post-publish $$(node -p "require('./package.json').version") package metadata"
72
+ git push
73
+
74
+ ## install all required build dependencies
75
+ install_dependencies:
76
+ pip install nodeenv twine
77
+ nodeenv --node=lts --prebuilt -p
78
+ npm install -g yarn rimraf
79
+
80
+ ## upgrade all npm and yarn dependencies
81
+ upgrade: check_dependencies
82
+ jlpm up
83
+
84
+ ## cleanup all build and metabuild artefacts
85
+ mrproper: clean uninstall
86
+ rm -rf node_modules .yarn ui-tests/node_modules || true
87
+
88
+ ## prints the list of available commands
89
+ help:
90
+ @echo ""
91
+ @echo "$$(tput bold)Available rules:$$(tput sgr0)"
92
+ @sed -n -e "/^## / { \
93
+ h; \
94
+ s/.*//; \
95
+ :doc" \
96
+ -e "H; \
97
+ n; \
98
+ s/^## //; \
99
+ t doc" \
100
+ -e "s/:.*//; \
101
+ G; \
102
+ s/\\n## /---/; \
103
+ s/\\n/ /g; \
104
+ p; \
105
+ }" ${MAKEFILE_LIST} \
106
+ | LC_ALL='C' sort --ignore-case \
107
+ | awk -F '---' \
108
+ -v ncol=$$(tput cols) \
109
+ -v indent=19 \
110
+ -v col_on="$$(tput setaf 6)" \
111
+ -v col_off="$$(tput sgr0)" \
112
+ '{ \
113
+ printf "%s%*s%s ", col_on, -indent, $$1, col_off; \
114
+ n = split($$2, words, " "); \
115
+ line_length = ncol - indent; \
116
+ for (i = 1; i <= n; i++) { \
117
+ line_length -= length(words[i]) + 1; \
118
+ if (line_length <= 0) { \
119
+ line_length = ncol - indent - length(words[i]) - 1; \
120
+ printf "\n%*s ", -indent, " "; \
121
+ } \
122
+ printf "%s ", words[i]; \
123
+ } \
124
+ printf "\n"; \
125
+ }'
126
+ @echo ""
127
+
128
+
129
+ # EOF
130
+
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: jupyterlab_claude_code_extension
3
+ Version: 1.0.16
4
+ Summary: Browse, resume, and manage your Claude Code CLI sessions from a JupyterLab side panel. One click reactivates the right terminal - no duplicate tabs, live remote-control indicator, and favourites for the projects you keep coming back to.
5
+ Project-URL: Homepage, https://github.com/stellarshenson/jupyterlab_claude_code_extension
6
+ Project-URL: Bug Tracker, https://github.com/stellarshenson/jupyterlab_claude_code_extension/issues
7
+ Project-URL: Repository, https://github.com/stellarshenson/jupyterlab_claude_code_extension.git
8
+ Author-email: Stellars Henson <konrad.jelen@gmail.com>
9
+ License: BSD 3-Clause License
10
+
11
+ Copyright (c) 2026, Stellars Henson
12
+ All rights reserved.
13
+
14
+ Redistribution and use in source and binary forms, with or without
15
+ modification, are permitted provided that the following conditions are met:
16
+
17
+ 1. Redistributions of source code must retain the above copyright notice, this
18
+ list of conditions and the following disclaimer.
19
+
20
+ 2. Redistributions in binary form must reproduce the above copyright notice,
21
+ this list of conditions and the following disclaimer in the documentation
22
+ and/or other materials provided with the distribution.
23
+
24
+ 3. Neither the name of the copyright holder nor the names of its
25
+ contributors may be used to endorse or promote products derived from
26
+ this software without specific prior written permission.
27
+
28
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
32
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
+ License-File: LICENSE
39
+ Keywords: jupyter,jupyterlab,jupyterlab-extension
40
+ Classifier: Framework :: Jupyter
41
+ Classifier: Framework :: Jupyter :: JupyterLab
42
+ Classifier: Framework :: Jupyter :: JupyterLab :: 4
43
+ Classifier: Framework :: Jupyter :: JupyterLab :: Extensions
44
+ Classifier: Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
45
+ Classifier: License :: OSI Approved :: BSD License
46
+ Classifier: Programming Language :: Python
47
+ Classifier: Programming Language :: Python :: 3
48
+ Classifier: Programming Language :: Python :: 3.10
49
+ Classifier: Programming Language :: Python :: 3.11
50
+ Classifier: Programming Language :: Python :: 3.12
51
+ Classifier: Programming Language :: Python :: 3.13
52
+ Classifier: Programming Language :: Python :: 3.14
53
+ Requires-Python: >=3.10
54
+ Requires-Dist: jupyter-server<3,>=2.4.0
55
+ Provides-Extra: dev
56
+ Requires-Dist: jupyterlab>=4; extra == 'dev'
57
+ Provides-Extra: test
58
+ Requires-Dist: coverage; extra == 'test'
59
+ Requires-Dist: pytest; extra == 'test'
60
+ Requires-Dist: pytest-asyncio; extra == 'test'
61
+ Requires-Dist: pytest-cov; extra == 'test'
62
+ Requires-Dist: pytest-jupyter[server]>=0.6.0; extra == 'test'
63
+ Description-Content-Type: text/markdown
64
+
65
+ # jupyterlab_claude_code_extension
66
+
67
+ [![GitHub Actions](https://github.com/stellarshenson/jupyterlab_claude_code_extension/actions/workflows/build.yml/badge.svg)](https://github.com/stellarshenson/jupyterlab_claude_code_extension/actions/workflows/build.yml)
68
+ [![npm version](https://img.shields.io/npm/v/jupyterlab_claude_code_extension.svg)](https://www.npmjs.com/package/jupyterlab_claude_code_extension)
69
+ [![PyPI version](https://img.shields.io/pypi/v/jupyterlab_claude_code_extension.svg)](https://pypi.org/project/jupyterlab_claude_code_extension/)
70
+ [![Total PyPI downloads](https://static.pepy.tech/badge/jupyterlab_claude_code_extension)](https://pepy.tech/project/jupyterlab_claude_code_extension)
71
+ [![JupyterLab 4](https://img.shields.io/badge/JupyterLab-4-orange.svg)](https://jupyterlab.readthedocs.io/en/stable/)
72
+ [![Brought To You By KOLOMOLO](https://img.shields.io/badge/Brought%20To%20You%20By-KOLOMOLO-00ffff?style=flat)](https://kolomolo.com)
73
+ [![Donate PayPal](https://img.shields.io/badge/Donate-PayPal-blue?style=flat)](https://www.paypal.com/donate/?hosted_button_id=B4KPBJDLLXTSA)
74
+
75
+ Manage Claude Code CLI sessions from inside JupyterLab. A left-sidebar panel lists every project under `~/.claude/projects/` deduplicated to one row per folder, marks live remote-control sessions with a green dot, and lets you jump back into any session by opening (or reactivating) a terminal pwd'd to that project and auto-running `claude --resume <id>`.
76
+
77
+ ![Claude Code Sessions panel](.resources/screenshot.png)
78
+
79
+ ## Features
80
+
81
+ - **Three-section side panel** - Favourites, Recent (top 10 by activity), and All. Each section scrolls independently; Favourites disappears when empty
82
+ - **Live remote-control indicator** - green dot on rows whose `~/.claude/sessions/<pid>.json` is alive (verified via `os.kill(pid, 0)`)
83
+ - **One-click resume** - click a row to find an existing terminal pwd'd to that project (queried server-side from the pty's process tree) and reactivate its tab; only spawns a fresh terminal if none matches. Concurrent rapid clicks are coalesced
84
+ - **Smart name resolution** - shows the user-set `/rename` name when available; auto-detected names (volatile across the same `sessionId` or 3+ token lowercase-kebab) fall back to the folder basename. Toggle the behaviour via the `resolveSessionNames` setting
85
+ - **Path-segment disambiguation** - when two sessions share the same display name, the row reveals the minimum number of trailing path segments needed for each to be unique
86
+ - **Favourites** - star a session via the right-click menu; persisted server-side at `~/.claude/jupyterlab_claude_code_extension.json`
87
+ - **Layout restorer** - panel visibility persists across JupyterLab reloads
88
+ - **Auto-disabled** when the `claude` binary is not on `PATH`
89
+ - **Hover tooltip** with relative path (vs JL root), last activity, message count, branch, first prompt, session id
90
+
91
+ ## Requirements
92
+
93
+ - JupyterLab >= 4.0.0
94
+ - Python >= 3.10
95
+ - `claude` CLI on `PATH`
96
+
97
+ ## Install
98
+
99
+ Developers must install via the project `Makefile` (which orchestrates clean, build, and pip install of the resulting wheel):
100
+
101
+ ```bash
102
+ make install
103
+ ```
104
+
105
+ End-users can install the published package from PyPI:
106
+
107
+ ```bash
108
+ pip install jupyterlab_claude_code_extension
109
+ ```
110
+
111
+ ## Uninstall
112
+
113
+ ```bash
114
+ pip uninstall jupyterlab_claude_code_extension
115
+ ```
@@ -0,0 +1,51 @@
1
+ # jupyterlab_claude_code_extension
2
+
3
+ [![GitHub Actions](https://github.com/stellarshenson/jupyterlab_claude_code_extension/actions/workflows/build.yml/badge.svg)](https://github.com/stellarshenson/jupyterlab_claude_code_extension/actions/workflows/build.yml)
4
+ [![npm version](https://img.shields.io/npm/v/jupyterlab_claude_code_extension.svg)](https://www.npmjs.com/package/jupyterlab_claude_code_extension)
5
+ [![PyPI version](https://img.shields.io/pypi/v/jupyterlab_claude_code_extension.svg)](https://pypi.org/project/jupyterlab_claude_code_extension/)
6
+ [![Total PyPI downloads](https://static.pepy.tech/badge/jupyterlab_claude_code_extension)](https://pepy.tech/project/jupyterlab_claude_code_extension)
7
+ [![JupyterLab 4](https://img.shields.io/badge/JupyterLab-4-orange.svg)](https://jupyterlab.readthedocs.io/en/stable/)
8
+ [![Brought To You By KOLOMOLO](https://img.shields.io/badge/Brought%20To%20You%20By-KOLOMOLO-00ffff?style=flat)](https://kolomolo.com)
9
+ [![Donate PayPal](https://img.shields.io/badge/Donate-PayPal-blue?style=flat)](https://www.paypal.com/donate/?hosted_button_id=B4KPBJDLLXTSA)
10
+
11
+ Manage Claude Code CLI sessions from inside JupyterLab. A left-sidebar panel lists every project under `~/.claude/projects/` deduplicated to one row per folder, marks live remote-control sessions with a green dot, and lets you jump back into any session by opening (or reactivating) a terminal pwd'd to that project and auto-running `claude --resume <id>`.
12
+
13
+ ![Claude Code Sessions panel](.resources/screenshot.png)
14
+
15
+ ## Features
16
+
17
+ - **Three-section side panel** - Favourites, Recent (top 10 by activity), and All. Each section scrolls independently; Favourites disappears when empty
18
+ - **Live remote-control indicator** - green dot on rows whose `~/.claude/sessions/<pid>.json` is alive (verified via `os.kill(pid, 0)`)
19
+ - **One-click resume** - click a row to find an existing terminal pwd'd to that project (queried server-side from the pty's process tree) and reactivate its tab; only spawns a fresh terminal if none matches. Concurrent rapid clicks are coalesced
20
+ - **Smart name resolution** - shows the user-set `/rename` name when available; auto-detected names (volatile across the same `sessionId` or 3+ token lowercase-kebab) fall back to the folder basename. Toggle the behaviour via the `resolveSessionNames` setting
21
+ - **Path-segment disambiguation** - when two sessions share the same display name, the row reveals the minimum number of trailing path segments needed for each to be unique
22
+ - **Favourites** - star a session via the right-click menu; persisted server-side at `~/.claude/jupyterlab_claude_code_extension.json`
23
+ - **Layout restorer** - panel visibility persists across JupyterLab reloads
24
+ - **Auto-disabled** when the `claude` binary is not on `PATH`
25
+ - **Hover tooltip** with relative path (vs JL root), last activity, message count, branch, first prompt, session id
26
+
27
+ ## Requirements
28
+
29
+ - JupyterLab >= 4.0.0
30
+ - Python >= 3.10
31
+ - `claude` CLI on `PATH`
32
+
33
+ ## Install
34
+
35
+ Developers must install via the project `Makefile` (which orchestrates clean, build, and pip install of the resulting wheel):
36
+
37
+ ```bash
38
+ make install
39
+ ```
40
+
41
+ End-users can install the published package from PyPI:
42
+
43
+ ```bash
44
+ pip install jupyterlab_claude_code_extension
45
+ ```
46
+
47
+ ## Uninstall
48
+
49
+ ```bash
50
+ pip uninstall jupyterlab_claude_code_extension
51
+ ```