Metadata-Version: 2.4
Name: jupyterlab_workspace_manager_extension
Version: 1.0.2
Summary: Workspace-driven Running panel: workspaces as coloured accordion sections with their tabs, terminals and kernels
Project-URL: Homepage, https://github.com/stellarshenson/jupyterlab_workspace_manager_extension
Project-URL: Bug Tracker, https://github.com/stellarshenson/jupyterlab_workspace_manager_extension/issues
Project-URL: Repository, https://github.com/stellarshenson/jupyterlab_workspace_manager_extension.git
Author-email: Stellars Henson <konrad.jelen@gmail.com>
License-Expression: BSD-3-Clause
License-File: LICENSE
Keywords: jupyter,jupyterlab,jupyterlab-extension
Classifier: Framework :: Jupyter
Classifier: Framework :: Jupyter :: JupyterLab
Classifier: Framework :: Jupyter :: JupyterLab :: 4
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.10
Requires-Dist: jupyter-server<3,>=2.21
Requires-Dist: psutil<8,>=7.2
Provides-Extra: dev
Requires-Dist: coverage<8,>=7.16; extra == 'dev'
Requires-Dist: jupyter-builder<2,>=1.2; extra == 'dev'
Requires-Dist: jupyterlab<5,>=4.6; extra == 'dev'
Requires-Dist: pytest-asyncio<2,>=1.4; extra == 'dev'
Requires-Dist: pytest-cov<8,>=7.1; extra == 'dev'
Requires-Dist: pytest-jupyter[server]<1,>=0.11; extra == 'dev'
Requires-Dist: pytest<10,>=9.1; extra == 'dev'
Provides-Extra: test
Requires-Dist: coverage<8,>=7.16; extra == 'test'
Requires-Dist: jupyterlab<5,>=4.6; extra == 'test'
Requires-Dist: pytest-asyncio<2,>=1.4; extra == 'test'
Requires-Dist: pytest-cov<8,>=7.1; extra == 'test'
Requires-Dist: pytest-jupyter[server]<1,>=0.11; extra == 'test'
Requires-Dist: pytest<10,>=9.1; extra == 'test'
Description-Content-Type: text/markdown

# Workspace panel for JupyterLab

[![GitHub Actions](https://github.com/stellarshenson/jupyterlab_workspace_manager_extension/actions/workflows/build.yml/badge.svg)](https://github.com/stellarshenson/jupyterlab_workspace_manager_extension/actions/workflows/build.yml)
[![npm version](https://img.shields.io/npm/v/@stellarshenson/jupyterlab-workspace-manager-extension.svg)](https://www.npmjs.com/package/@stellarshenson/jupyterlab-workspace-manager-extension)
[![PyPI version](https://img.shields.io/pypi/v/jupyterlab-workspace-manager-extension.svg?cache=20261025)](https://pypi.org/project/jupyterlab-workspace-manager-extension/)
[![Total PyPI downloads](https://static.pepy.tech/badge/jupyterlab-workspace-manager-extension)](https://pepy.tech/project/jupyterlab-workspace-manager-extension)
[![JupyterLab 4](https://img.shields.io/badge/JupyterLab-4-orange.svg)](https://jupyterlab.readthedocs.io/en/stable/)
[![Brought To You By KOLOMOLO](https://img.shields.io/badge/Brought%20To%20You%20By-KOLOMOLO-00ffff?style=flat)](https://kolomolo.com)
[![Donate PayPal](https://img.shields.io/badge/Donate-PayPal-blue?style=flat)](https://www.paypal.com/donate/?hosted_button_id=B4KPBJDLLXTSA)

This extension replaces the built-in Running Terminals and Kernels sidebar with a panel organised by workspace: a WORKSPACES section with one card per workspace, then KERNELS, TERMINALS and LANGUAGE SERVERS sections listing everything that runs. One section at a time is open: the three lab sections stand at the bottom of the panel only while WORKSPACES is open and fills the height above them, and otherwise they follow WORKSPACES from the top.

![The workspace panel](docs/images/panel-full-window.png)

_Fig 1 - The workspace panel beside a notebook of the workspace this window shows_

## Why a workspace panel

Developers and data scientists now run several projects at once: they start an agent on one project and work on another while it runs. Each project holds its own tabs, terminals and kernels in a JupyterLab workspace, and the built-in Running panel lists all of them in one flat list, so a terminal from one project sits beside a kernel from another with nothing to tell them apart.

The panel groups them by workspace: what each project holds, what is running in it, and how long ago it was used, with one click to switch to it.

## Features

- **Workspace section** - an edge tab at the panel's left edge with the colour strip, the name and its row count in brackets, the age and, while the card is open, the purpose; the header and the rows carry the workspace colour, and this window's card has an outline
- **Triangle** - opens or closes a section
- **Several cards** - any number of workspace cards stay open at once, and closing one leaves the others open
- **Tab rows** - an open card lists its tabs in one list, each marked by its icon; a document with a running kernel shows the kernel icon beside its own icon and the kernel's state, and a right-click offers Close tab, Detach from workspace, Move to workspace, and Stop terminal or Shut down kernel; Detach from workspace takes the tab out and leaves its terminal or kernel running, and Move to workspace sends the tab to another workspace; the row of this window's current tab carries a pale tint
- **Header** - a click on the name of another workspace switches this window to it, a click on this window's workspace opens its card or closes it, and a header carries the eye that hides the workspace
- **Menu** - a right-click on the header, or the context-menu key on the focused header, opens it: open, open in a new browser tab, clear workspace, set description, colour, hide, move up, move down, delete
- **Card order** - the cards keep one fixed order that switching workspaces does not change, a drag or Move up and Move down moves a card, and a new workspace goes last
- **Hide** - a hidden workspace leaves the panel, and the number of hidden workspaces sits under the last card of WORKSPACES
- **Kernels, terminals and language servers** - three sections docked below the workspaces, always in view, for every running kernel and terminal, in a workspace or not, and the running language servers, each section with its count; the KERNELS and TERMINALS bands carry a shut down menu with Shut down all and Shut down detached, detached meaning no workspace holds the item, and the LANGUAGE SERVERS band a single shut down all, so a background terminal or a headless kernel with no tab stays listed; the WORKSPACES band carries a clean up button that removes the other workspaces after a confirmation
- **One section at a time** - opening a section closes the others, an open WORKSPACES takes the height above the three lab bands, any other open section is as tall as its rows, every open section scrolls when its rows exceed the height, and a reload keeps the same section open
- **Kernel rows** - a KERNELS row shows the status dot, the name, the memory and the time; select it for the kernel type, the document and the CPU use
- **Terminal rows** - a TERMINALS row of a numbered terminal shows its number in a small rectangle badge, in the colour of the first workspace that holds the terminal, or in an empty box when no workspace does, and a named terminal its name; a card row drops that label and shows the name of its tab, or the process running in it while the tab has no name of its own; the path of that process stands in the free width with its end in view, and the time since its last activity follows, all without selection
- **Tooltips** - hover a tab, terminal, kernel or language server for its details on several lines; a terminal's shows its number, tab, process, command, path, memory, last activity with the exact time, and a Workspaces line naming every workspace that holds it or none; a kernel's adds a memory line
- **Filter** - shows the workspaces whose name, purpose or rows match, and opens each of them
- **New workspace** - the + button on the WORKSPACES band, left of the clean up button, creates a workspace and asks for its name and an optional description
- **Command line** - the `jupyterlab-workspace` tool drives the same workspaces, terminals and kernels from a shell, switches a window to a workspace and activates a tab
- **Lab pages** - the `workspace-page:open` command takes the arguments of `server-proxy:open`, `{url, title?, id?, newBrowserTab?}`, beside `icon?` and `policy?`, and shows a locally served page in a main-area tab; a page under the lab's `/proxy/<port>/` gets the sandbox `server-proxy:open` gives, so it keeps the lab session, storage, cookies and POSTs, and any other URL is sandboxed to `allow-scripts`, so its scripts run but it has no lab session, storage or cookies; `policy.sandbox` replaces either sandbox, `null` removes it, and `allow`, `referrerPolicy` and `csp` set their iframe attributes; `newBrowserTab: true` opens the URL in a new browser tab instead, and `id` becomes the id of the tab's content; opening a page on the port of an open page tab, or with its `id`, reuses that tab and loads the URL again; a page document on the lab's origin is fetched past the browser cache first, so a page the server rewrote shows its new content, while the scripts, styles and data the page loads follow their server's caching headers, so a page with separate files needs a server that sends `Cache-Control: no-store`; the tab takes the given title, or the page's own while it keeps the lab origin, and `icon` sets its icon from an image URL (svg or png), while without it the tab shows the standard page icon (a comment bubble); a malformed argument is refused before any tab opens

## Requirements

The extension needs JupyterLab 4.6 or later.

## Install

Install the package from PyPI.

```bash
pip install jupyterlab-workspace-manager-extension
```

## Command line

`jupyterlab-workspace` manages a running lab from a shell: `workspaces list`, `add`, `open`, `describe`, `remove`, `clean` and `switch`, `tabs list` and `tabs activate`, `windows list`, and `terminals` and `kernels`, each with `list` and `kill`.

Run `jupyterlab-workspace --help` for the commands, the environment variables that name the lab, and the exit codes.

## Agent skill

The `jupyterlab-workspace` command ships an agent skill at
`.agents/skills/jupyterlab-workspace-manager-extension/SKILL.md`. Link it where your agents
read skills.

After `pip install`, with the Python that runs the lab:

```bash
mkdir -p ~/.agents/skills && ln -s "$(python -c 'import sys; print(sys.prefix)')/share/jupyter/agents/skills/jupyterlab-workspace-manager-extension" ~/.agents/skills/jupyterlab-workspace-manager-extension
```

From a clone:

```bash
ln -s "$PWD/.agents/skills/jupyterlab-workspace-manager-extension" ~/.claude/skills/jupyterlab-workspace-manager-extension
```

## Uninstall

Remove the package.

```bash
pip uninstall jupyterlab-workspace-manager-extension
```
