{"id":51061182,"url":"https://github.com/jtpio/xtralab","last_synced_at":"2026-06-23T02:02:05.789Z","repository":{"id":355686323,"uuid":"1229210803","full_name":"jtpio/xtralab","owner":"jtpio","description":"Agent-ready JupyterLab with opinionated extras","archived":false,"fork":false,"pushed_at":"2026-06-17T17:14:50.000Z","size":1657,"stargazers_count":11,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-17T19:16:30.157Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jtpio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-04T20:15:23.000Z","updated_at":"2026-06-17T16:53:07.000Z","dependencies_parsed_at":"2026-06-02T19:02:36.381Z","dependency_job_id":null,"html_url":"https://github.com/jtpio/xtralab","commit_stats":null,"previous_names":["jtpio/xtralab"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/jtpio/xtralab","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtpio%2Fxtralab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtpio%2Fxtralab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtpio%2Fxtralab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtpio%2Fxtralab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jtpio","download_url":"https://codeload.github.com/jtpio/xtralab/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtpio%2Fxtralab/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34672250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-23T02:00:07.161Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-23T02:02:05.130Z","updated_at":"2026-06-23T02:02:05.782Z","avatar_url":"https://github.com/jtpio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![xtralab-logo](./logo.png)\n\nAn opinionated JupyterLab meta-package for use with coding agents.\n\nIt bundles a curated set of JupyterLab extensions, a path-first file browser,\nrich git diffs for text, notebooks, and images, an agent launcher, and a\nquieter default workspace.\n\n![xtralab screenshot](./screenshot.png)\n\n## Install\n\n```bash\npip install xtralab\n```\n\n## Usage\n\n### As a JupyterLab package\n\nOnce installed, start JupyterLab the usual way:\n\n```bash\njupyter lab\n```\n\n### As a desktop app\n\nA standalone Electron build is also available, packaged as a DMG on macOS and\nan AppImage on Linux. Each tagged release ships installers on the\n[releases page](https://github.com/jtpio/xtralab/releases/latest), and builds\nfrom `main` are uploaded as workflow artifacts on the\n[Actions tab](https://github.com/jtpio/xtralab/actions). See\n[CONTRIBUTING.md](./CONTRIBUTING.md) for the desktop app architecture and local\nbuild instructions.\n\nOn macOS the build is not notarized yet (it has no Apple Developer ID), so\nGatekeeper blocks it on first launch, and agent notifications fall back to\n`osascript`, appearing as \"Script Editor\". In the meantime you can self-sign it\nfor free: this lets it launch and gives native notifications instead, branded as\nxtralab and clickable to jump to the terminal that fired them. Create a\ncode-signing certificate once in Keychain Access (Certificate Assistant, Create\na Certificate, with Identity Type \"Self Signed Root\" and Certificate Type \"Code\nSigning\") named `xtralab-selfsign`, then sign the app you copied out of the DMG:\n\n```bash\ncodesign --force --deep --sign \"xtralab-selfsign\" --timestamp=none \"/Applications/xtralab.app\"\nxattr -dr com.apple.quarantine \"/Applications/xtralab.app\"\n```\n\nmacOS prompts once to let `codesign` use the key; choose Always Allow. None of\nthis will be needed once the app ships with a Developer ID signature.\n\n## What's included\n\nxtralab builds on [`ajlab`](https://github.com/jtpio/ajlab), the agent-ready\nJupyterLab base. On top of it, xtralab pulls in JupyterLab 4.6+ with\n`jupyterlab-git`, `jupyterlab-lsp`, `jupyterlab-quickopen`,\n`jupyterlab-search-replace`, `jupyterlab-vim`, and a set of light and dark\nthemes (`jupyterlab-cursor-light`, `jupyterlab-cursor-dark`,\n`jupyterlab-day`, `jupyterlab-night`). See\n[`pyproject.toml`](./pyproject.toml) for the full list and pinned versions.\n\nThe bundled xtralab labextension then adds:\n\n- A path-first file browser in the left sidebar, with `@pierre/trees`\n  file-type icons that also carry over to document tabs and the `jupyterlab-git`\n  panel.\n- Rich git diffs in the `jupyterlab-git` panel, using `@pierre/diffs` for text\n  and notebooks and a 2-up / swipe / onion-skin view for images.\n- An agent launcher with a prompt box, buttons for the agents installed on your\n  machine (Claude, Codex, Antigravity, Copilot, Goose, OpenCode, Kiro, Mistral\n  Vibe), a collapsible list of changed files, and an Open row for a terminal,\n  notebook, console, or your terminal editor (Neovim or Vim).\n- A Terminals panel listing the running terminal sessions, each badged with the\n  agent or editor detected inside it. Open terminal tabs in the main area carry\n  the same icon.\n- Sidebar toggle buttons in the top bar for the left and right areas.\n\nxtralab also ships a set of opinionated defaults: unused UI is hidden for a\nquieter workspace, the activity bar sits at the top, and autocompletion,\ncontinuous LSP hinting, code folding, and gitignore-aware quick open are on by\ndefault. See [the bundled labconfig overrides](./jupyter-config/labconfig) for\nthe full set.\n\n## Connecting agents to Jupyter (MCP)\n\nxtralab runs a [Model Context Protocol][mcp-spec] server inside JupyterLab,\nprovided by [`jupyter-server-mcp`][mcp]. To let a coding agent drive JupyterLab\nthrough it, register the bundled `jupyter-server-mcp-proxy` console script with\nthe agent:\n\n```bash\nclaude mcp add jupyter -- jupyter-server-mcp-proxy\ncodex mcp add jupyter -- jupyter-server-mcp-proxy\ncopilot mcp add jupyter -- jupyter-server-mcp-proxy\n```\n\nRun this from a terminal inside xtralab, so the proxy inherits the server\nenvironment and discovers the running server automatically. No port is needed,\nand a single registration keeps working across restarts. The launcher also\nsurfaces these commands with copy buttons, filtered to the agents you have\ninstalled.\n\nSee the [`jupyter-server-mcp` README][mcp] for other MCP clients.\n\n[mcp]: https://github.com/jupyter-ai-contrib/jupyter-server-mcp\n[mcp-spec]: https://modelcontextprotocol.io\n\n## Agent skill\n\nxtralab ships an [Agent Skills][skills] entry at [`agent-skill/`](./agent-skill)\nthat teaches any coding agent how to customize JupyterLab from plain-English\nrequests like \"hide the status bar\", \"change the theme\", or \"add a language\nserver\". The same SKILL.md file works with Claude Code, Codex CLI, Gemini CLI,\nGitHub Copilot, and other tools that read the Agent Skills format.\n\nFor Claude Code, this repository doubles as a one-plugin marketplace. Inside a\nClaude Code session:\n\n```text\n/plugin marketplace add jtpio/xtralab\n/plugin install xtralab-skills@xtralab\n```\n\nFor agents that read from `~/.agents/skills/`, such as Codex CLI or Gemini CLI,\nclone and copy the skill directory:\n\n```bash\ngit clone --depth=1 https://github.com/jtpio/xtralab.git /tmp/xtralab\nmkdir -p ~/.agents/skills\ncp -r /tmp/xtralab/agent-skill/skills/customize-jupyterlab ~/.agents/skills/\n```\n\nSee [`agent-skill/README.md`](./agent-skill/README.md) for additional install\npaths, the list of supported agents, and what the skill knows.\n\n[skills]: https://agentskills.io\n\n## Language servers\n\nxtralab ships [`jupyterlab-lsp`][lsp] with two language servers pre-registered:\n\n- Python, using [`ty`](https://github.com/astral-sh/ty), which is bundled and\n  works out of the box.\n- TypeScript and JavaScript, using `typescript-language-server`, which you\n  install yourself:\n\n  ```bash\n  npm install -g typescript-language-server typescript\n  ```\n\n  Restart JupyterLab afterwards to pick it up.\n\nTo enable another server (bash, yaml, json, pyright, and more), install its\nbinary and drop a JSON spec into a `jupyter_server_config.d/` directory. For\n`pip install xtralab`, run `jupyter --paths` to find one (typically\n`~/.jupyter/jupyter_server_config.d/`). For the desktop app, use\n`~/Library/Application Support/xtralab/jupyter/config/jupyter_server_config.d/`\non macOS or `~/.config/xtralab/jupyter/config/jupyter_server_config.d/` on\nLinux.\n\n```json\n{\n  \"LanguageServerManager\": {\n    \"language_servers\": {\n      \"bash-language-server\": {\n        \"version\": 2,\n        \"argv\": [\"bash-language-server\", \"start\"],\n        \"languages\": [\"bash\", \"sh\"],\n        \"mime_types\": [\"text/x-sh\", \"application/x-sh\"],\n        \"display_name\": \"bash-language-server\"\n      }\n    }\n  }\n}\n```\n\nSee the [`jupyterlab-lsp` documentation][lsp-config] for the full spec.\n\n[lsp]: https://github.com/jupyter-lsp/jupyterlab-lsp\n[lsp-config]: https://jupyterlab-lsp.readthedocs.io/en/latest/Configuring.html\n\n## Customizing the launcher\n\nOpen `Settings → Settings Editor → xtralab launcher` to override, hide, or add\nlauncher entries. The editor shows xtralab's full built-in list as the default\nfor both the agents and editors settings, so you can read every shipped entry\nand copy one into your user preferences to tweak in place. Both lists merge with\nxtralab's defaults by `id`, so an override only needs the `id` plus the fields\nyou want to change.\n\n### Agents\n\nEdit the `agents` array:\n\n```jsonc\n{\n  \"agents\": [\n    // Hide an agent\n    { \"id\": \"kiro\", \"enabled\": false },\n\n    // Override an agent's command (e.g. point Claude at a shell alias)\n    { \"id\": \"claude\", \"command\": \"cl\", \"requireAvailable\": false },\n\n    // Add a new agent; promptArgs: [] appends the prompt as a positional arg\n    { \"id\": \"aider\", \"label\": \"Aider\", \"command\": \"aider\", \"promptArgs\": [] }\n  ]\n}\n```\n\nFields: `id` (required), `label`, `caption`, `command`, `promptArgs` (how the\nprompt is spliced: `[]` for positional, `[\"--flag\"]` for flagged, `null` to opt\nout), `iconSvg`, `rank`, `enabled`, `requireAvailable`.\n\n### Editors\n\nThe **Open** section's terminal-editor tile (Neovim, falling back to Vim) is\nconfigured the same way through an `editors` array:\n\n```jsonc\n{\n  \"editors\": [\n    // Hide Neovim so the tile falls back to Vim (or disappears if Vim\n    // isn't installed either)\n    { \"id\": \"nvim\", \"enabled\": false },\n\n    // Add Helix, preferred over the built-ins\n    {\n      \"id\": \"helix\",\n      \"label\": \"Helix\",\n      \"command\": \"hx\",\n      \"rank\": -1,\n      \"iconSvg\": \"\u003csvg\u003e…\u003c/svg\u003e\"\n    }\n  ]\n}\n```\n\nThe launcher shows a single tile: the first editor, by `rank`, whose `command`\nis on `PATH`. Disable both built-ins (`nvim`, `vim`) to remove the tile\nentirely. Fields: `id` (required), `label`, `caption`, `command`, `iconSvg`,\n`rank`, `enabled`, `requireAvailable`.\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for the development setup, the Electron\ndesktop app architecture, and the build pipeline.\n\n## License\n\nBSD-3-Clause\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjtpio%2Fxtralab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjtpio%2Fxtralab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjtpio%2Fxtralab/lists"}