jupyterlab-advanced-code-viewer-extension 0.1.2__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_advanced_code_viewer_extension-0.1.2/.agents/JOURNAL.md +20 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/.claude/CLAUDE.md +194 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/.claude/JOURNAL.md +1 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/.claude/settings.json +5 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/.copier-answers.yml +18 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/.gitignore +137 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/.prettierignore +14 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/.yarnrc.yml +2 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/CHANGELOG.md +15 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/CONTRIBUTING.md +113 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/LICENSE +29 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/Makefile +386 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/PKG-INFO +122 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/README.md +80 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/RELEASE.md +88 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/babel.config.js +1 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/conftest.py +14 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/docs/acc-crit-advanced-code-viewer.md +1239 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/docs/brief.md +166 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/eslint.config.mjs +70 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/install.json +5 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jest.config.js +28 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyter-config/server-config/jupyterlab_advanced_code_viewer_extension.json +7 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/__init__.py +36 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/_version.py +4 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/labextension/package.json +158 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/labextension/schemas/@stellarshenson/jupyterlab-advanced-code-viewer-extension/package.json.orig +153 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/labextension/schemas/@stellarshenson/jupyterlab-advanced-code-viewer-extension/plugin.json +8 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/labextension/static/232.ba615dd6803b2beb.js +6 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/labextension/static/571.ea54f6c6bb484b45.js +2 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/labextension/static/remoteEntry.430b6c2ebff20df0.js +1 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/labextension/static/style.js +4 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/labextension/static/third-party-licenses.json +16 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/routes.py +29 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/tests/__init__.py +1 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/jupyterlab_advanced_code_viewer_extension/tests/test_routes.py +30 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/package.json +153 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/pyproject.toml +93 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/schema/plugin.json +8 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/src/__tests__/request.spec.ts +70 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/src/index.ts +56 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/src/request.ts +51 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/style/base.css +5 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/style/index.css +1 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/style/index.js +1 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/tsconfig.json +25 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/tsconfig.test.json +3 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/ui-tests/README.md +167 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/ui-tests/jupyter_server_test_config.py +33 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/ui-tests/package.json +15 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/ui-tests/playwright.config.js +34 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/ui-tests/tests/jupyterlab_advanced_code_viewer_extension.spec.ts +64 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/ui-tests/yarn.lock +4393 -0
- jupyterlab_advanced_code_viewer_extension-0.1.2/yarn.lock +10371 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Claude Code Journal
|
|
2
|
+
|
|
3
|
+
This journal tracks substantive work on documents, diagrams, and documentation content.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
1. **Task - Project creation** (v0.1.0): Created `jupyterlab_advanced_code_viewer_extension` as new JupyterLab extension<br>
|
|
8
|
+
**Result**: Scaffolded by `new-jupyterlab-extension.sh --headless` from copier template `jupyterlab/extension-template` v4.6.5, `kind: frontend-and-server`, settings and tests enabled. Purpose per `docs/brief.md`: bring follow-the-file, change display, marks, comments and notes panel of siblings `jupyterlab_advanced_markdown_viewer_extension` and `jupyterlab_advanced_html_viewer_extension` to notebooks and source files, inside the editor while the user types, no viewer mode. Repository initialised with `git init -b main` and initial import commit. Added `.claude/CLAUDE.md` overlay importing user and workspace layers without copying them: Makefile-only lifecycle, lockfile trio rule, Makefile version check (1.45, identical to canonical), pm-tools-only trackers, CLI agent-skill rule, graphify scope control, Required Skills table. Added `.claude/settings.json` with `worktree.bgIsolation: none`, as HTML viewer sibling. README rewritten: seven template badges, features and limitations from the brief, sections below Uninstall dropped. Tests on three tiers: pytest (hello route, 403 without token), Jest `request.spec.ts` (`requestAPI` against mocked `ServerConnection`), Galata (activation, settings load, hello route) with port from `JUPYTER_TEST_PORT` and own settings folder.
|
|
9
|
+
|
|
10
|
+
2. **Task - Dependency floors raised to installed toolchain** (v0.1.0): raised ranges in `package.json`, `pyproject.toml` and `ui-tests/package.json` to installed major.minor before first build<br>
|
|
11
|
+
**Result**: Copier template v4.6.5 declares ranges from JupyterLab 4.0; jupyterlab-extension skill rule: floor at installed and tested major.minor, ceiling next major, floors read from installed packages. `@jupyterlab/*` from lab 4.6.4 (application ^4.6.0, coreutils ^6.6.0, services ^7.6.0), dev tools from `node_modules` after `make check_dependencies` (eslint 9.39, prettier 3.9, jest 29.7; typescript stays ~5.5.4), Python from `pip list` (jupyter_server>=2.21,<3, pytest>=9.1,<10); `dev` extra pulls `test`. Galata ^5.6.0, Playwright ^1.64.0, browser build 1248 in image. CI: jupyterlab>=4.6,<5, Python 3.13, badge URLs skipped by link check. Test server sets `c.GalaxaHubMotd.open_on_start = False`: MOTD startup tab hangs Galata. `make build`, `make test` green: jest 6, pytest 2, auth gate. Galata 3 of 3 against built labextension through scratch `JUPYTER_CONFIG_PATH`, no `make install`; 3 of 3 red without the extension. `package.json` committed with `yarn.lock`; Makefile 1.45 writes no `package-lock.json`.
|
|
12
|
+
|
|
13
|
+
3. **Task - Acceptance criteria proposed, INTENT.md folded in** (v0.1.0): filed 278 open criteria through pm-tools, updated README from `INTENT.md`, removed that file<br>
|
|
14
|
+
**Result**: Star Colonel ordered `INTENT.md` consumed into README and criteria, then removed, criteria fairly granular. Read both siblings' trackers through pm-tools (Markdown viewer 199 items, HTML viewer 78), started from the categories the brief maps. `docs/acc-crit-advanced-code-viewer.md`: 23 categories, each description naming its release; release 1 99, release 2 47, release 3 93, release 4 36, README 3; 80 CRITICAL; every criterion names its test file. INTENT decision origins kept as body clause: user 10, plan 13, proposed and unanswered 11, new in this proposal 35. ACC-APPLY-29 and ACC-CELLS-123 log why Markdown viewer's rejected ACC-APPLY-15 (undo) returns: editor in scope here. README gained INTENT lead, Sibling extensions and Releases tables (all Not built), three limits. Both siblings installed in this lab (1.0.31, 1.0.36), observable live. `pm-tools check docs --strict` clean; handle @kj as sibling rosters.
|
|
15
|
+
|
|
16
|
+
4. **Task - GitHub repository created** (v0.1.0): created public repository `stellarshenson/jupyterlab_advanced_code_viewer_extension`, set as `origin`<br>
|
|
17
|
+
**Result**: Star Colonel ordered project created on git host through my-vault and my-git. Host and visibility taken from siblings: both viewers public on GitHub under `stellarshenson`, and `package.json` URLs plus README badges already name that address. Vault was locked; `jupyterlab-passkey vault exec --env GITHUB_TOKEN=github/api` unlocked by passkey and passed token in environment only, so it reached neither transcript, argv nor disk. No `gh` CLI, so REST `POST /user/repos` from a short Python script: description from `package.json`, `auto_init` false to keep local history, other settings GitHub defaults. `git ls-remote origin` exit 0 with stored credentials. Not registered as `~/workspace` submodule.
|
|
18
|
+
|
|
19
|
+
5. **Task - Template upgrade and scoped npm name** (v0.1.1): refreshed at template v4.6.5 with Makefile 1.46, labextension renamed to `@stellarshenson/jupyterlab-advanced-code-viewer-extension`<br>
|
|
20
|
+
**Result**: Fleet campaign `tmp/workflows/scoped-npm-names` in the jupyterlab folder. Template stays v4.6.5, Makefile 1.45 → 1.46. Floors moved: `@jupyter/eslint-plugin` ^1.4.0, `typescript` ~5.8.0, `typescript-eslint` ^8.72.0, `coverage>=7.17,<8`, `pytest>=9.2,<10`. Rename because npm refuses unscoped dashed name whose underscored form is published, and JupyterLab URI parser refuses underscore in unscoped plugin id. Settings id and labextension path follow new name; Python module and PyPI distribution keep theirs, so `pip install` unchanged. Journal moved to `.agents/JOURNAL.md` by `journal-tools layout`, `.claude/JOURNAL.md` is link. Verified by `build_test.py`: Jest 6, pytest 2, Galata 3, browser check, labextension. One lint warning stays: unused `error` variable.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
<!-- @import /home/lab/.claude/CLAUDE.md -->
|
|
2
|
+
<!-- @import /home/lab/workspace/.claude/CLAUDE.md -->
|
|
3
|
+
|
|
4
|
+
# Project-Specific Configuration
|
|
5
|
+
|
|
6
|
+
This file is an overlay. It imports two layers and copies neither:
|
|
7
|
+
|
|
8
|
+
- **User layer** - `/home/lab/.claude/CLAUDE.md`, applies to every project on this machine
|
|
9
|
+
- **Workspace layer** - `/home/lab/workspace/.claude/CLAUDE.md`, applies to everything under `~/workspace`
|
|
10
|
+
|
|
11
|
+
Both layers apply in full. Rules below extend or strengthen them; where they overlap, the stricter
|
|
12
|
+
wording wins. The workspace `/home/lab/workspace/.claude/` directory and the skills the two layers
|
|
13
|
+
name carry every standard not restated here.
|
|
14
|
+
|
|
15
|
+
## Mandatory Bans (Reinforced)
|
|
16
|
+
|
|
17
|
+
The following workspace rules are STRICTLY ENFORCED for this project:
|
|
18
|
+
|
|
19
|
+
- **No automatic git tags** - only create tags when user explicitly requests
|
|
20
|
+
- **No automatic version changes** - only modify version in package.json/pyproject.toml/etc. when user explicitly requests
|
|
21
|
+
- **No automatic publishing** - never run `make publish`, `npm publish`, `twine upload`, or similar without explicit user request
|
|
22
|
+
- **No manual package installs if Makefile exists** - use `make install` or equivalent Makefile targets, not direct `pip install`/`uv install`/`npm install`
|
|
23
|
+
- **No automatic git commits or pushes** - only when user explicitly requests
|
|
24
|
+
|
|
25
|
+
## Project Context
|
|
26
|
+
|
|
27
|
+
JupyterLab 4 extension, `kind: frontend-and-server`, scaffolded from the official copier template
|
|
28
|
+
`jupyterlab/extension-template` v4.6.5. The brief is `docs/brief.md`; read it in full before any
|
|
29
|
+
design or code work, its section "Sibling records to read" included.
|
|
30
|
+
|
|
31
|
+
The extension brings the functions of the two read-only viewers, `jupyterlab_advanced_markdown_viewer_extension`
|
|
32
|
+
and `jupyterlab_advanced_html_viewer_extension`, to notebooks and to every text file the file editor
|
|
33
|
+
opens. The open document follows the file while an AI agent or another program writes it and shows
|
|
34
|
+
each change; the user's unsaved edits are kept; the user and the agent mark passages and write
|
|
35
|
+
comment threads that are stored in the file.
|
|
36
|
+
|
|
37
|
+
**The rule that shapes this project**: it works while the user edits. It adds no viewer widget, no
|
|
38
|
+
viewer mode and no review mode. Every function is active in a notebook's command mode and edit mode,
|
|
39
|
+
in a rendered and an unrendered Markdown cell, and in the file editor while the user types. Functions
|
|
40
|
+
are switched on and off by settings, under the Markdown viewer's setting names.
|
|
41
|
+
|
|
42
|
+
**Read first**, as the brief orders: the two siblings beside this project,
|
|
43
|
+
`../jupyterlab_advanced_markdown_viewer_extension` and `../jupyterlab_advanced_html_viewer_extension`
|
|
44
|
+
- their README, `docs/`, `.claude/CLAUDE.md`, `.claude/JOURNAL.md`, `src/`, `ui-tests/tests/` and
|
|
45
|
+
the agent skill under `.agents/skills/`. Their trackers are read through `pm-tools` only. A rejected
|
|
46
|
+
criterion or defect there records a decision already refused; do not propose it again without a new
|
|
47
|
+
reason. No sibling extension becomes an install dependency without the Star Colonel's word.
|
|
48
|
+
|
|
49
|
+
**Architecture at creation** (the scaffold; the brief's releases replace it):
|
|
50
|
+
|
|
51
|
+
- **Frontend** (TypeScript, `src/`) - `index.ts` the plugin with the settings load, `request.ts` the
|
|
52
|
+
call to the server namespace `jupyterlab-advanced-code-viewer-extension`
|
|
53
|
+
- **Server** (Python, `jupyterlab_advanced_code_viewer_extension/`) - `routes.py` the `hello` route,
|
|
54
|
+
every handler under `@tornado.web.authenticated`; `.github/scripts/check_auth.py` is the gate
|
|
55
|
+
- **Schema** (`schema/plugin.json`) - the settings; the names follow the Markdown viewer where the
|
|
56
|
+
function is the same
|
|
57
|
+
- **Notes code** - copied from the two viewers into this project and kept in modules separate from
|
|
58
|
+
the editor and notebook code, so a shared package can be taken out later; the two viewers are not
|
|
59
|
+
changed from here
|
|
60
|
+
- **Tests** - pytest in `jupyterlab_advanced_code_viewer_extension/tests/`, Jest in `src/__tests__/`,
|
|
61
|
+
Playwright/Galata in `ui-tests/`
|
|
62
|
+
- **CI/CD** - GitHub Actions plus jupyter-releaser under `.github/workflows/`
|
|
63
|
+
|
|
64
|
+
**Feature specification** - criteria in `docs/acc-crit*.md`, defects in `docs/defects*.md`, both
|
|
65
|
+
written and read only through `pm-tools`.
|
|
66
|
+
|
|
67
|
+
## Build Lifecycle - Makefile Only
|
|
68
|
+
|
|
69
|
+
The Makefile owns the whole build lifecycle. Never run `pip`, `jlpm`, `yarn`, `npm`,
|
|
70
|
+
`python -m build`, `twine`, or any build, publish or clean command directly - those bypass the
|
|
71
|
+
project-local `.nodeenv/` toolchain the Makefile pins.
|
|
72
|
+
|
|
73
|
+
| Target | Effect |
|
|
74
|
+
| --------------- | --------------------------------------------------------------------------------------- |
|
|
75
|
+
| `make install` | build and install the extension (raises the patch version, by design of Makefile 1.42+) |
|
|
76
|
+
| `make publish` | release to npm and PyPI - needs explicit approval every time |
|
|
77
|
+
| `make clean` | remove build artefacts |
|
|
78
|
+
| `make mrproper` | remove all build and virtual-environment artefacts |
|
|
79
|
+
| `make build` | re-resolve `yarn.lock`, format, build the wheel and the sdist into `dist/` |
|
|
80
|
+
| `make test` | Jest, pytest and the endpoint authentication gate |
|
|
81
|
+
|
|
82
|
+
**Makefile version check**: the local Makefile declares its version on line 1. Compare it against
|
|
83
|
+
`/home/lab/workspace/private/jupyterlab/@utils/jupyterlab-extensions/Makefile` and copy the canonical
|
|
84
|
+
file over the local one as soon as a newer version is found. Check at the start of any build work.
|
|
85
|
+
Local version at project creation: 1.45, identical to canonical.
|
|
86
|
+
|
|
87
|
+
**The Galata suite has no Makefile target**, so it is the one lifecycle step outside the Makefile:
|
|
88
|
+
`jlpm install` and `jlpm playwright install chromium` in `ui-tests/`, then
|
|
89
|
+
`JUPYTER_TEST_PORT=<free port> jlpm playwright test`. Port 8888 belongs to this workstation's own
|
|
90
|
+
lab. Redirect output to a file instead of `| tee`, which reports tee's exit status. The suite runs
|
|
91
|
+
against the extension that `make install` put into the lab.
|
|
92
|
+
|
|
93
|
+
## Dependency Ranges
|
|
94
|
+
|
|
95
|
+
The rule is the jupyterlab-extension skill's: floor at the installed and tested `major.minor`,
|
|
96
|
+
ceiling at the next major, in `pyproject.toml`, `package.json` and `ui-tests/package.json` alike.
|
|
97
|
+
Floors are read from the installed packages (`pip list`, `node_modules/<pkg>/package.json`), never
|
|
98
|
+
from PyPI or the npm registry. `typescript` keeps its tilde; `lib0` and `webpack` stay exact under
|
|
99
|
+
`resolutions`. A range edit is followed by `make build`, which re-resolves `yarn.lock`.
|
|
100
|
+
|
|
101
|
+
## Git Rules (Project-Specific)
|
|
102
|
+
|
|
103
|
+
- The repository was initialised with `git init -b main` and an initial import of every artefact
|
|
104
|
+
- **Always commit `package.json`, `package-lock.json` and `yarn.lock` together** - a lockfile left
|
|
105
|
+
behind makes CI fail with YN0028 on an immutable install. Makefile 1.41+ produces no
|
|
106
|
+
`package-lock.json`, so in practice this is `package.json` with `yarn.lock`, and
|
|
107
|
+
`ui-tests/package.json` with `ui-tests/yarn.lock`
|
|
108
|
+
|
|
109
|
+
## Journal Rules (Project-Specific)
|
|
110
|
+
|
|
111
|
+
- **APPEND ONLY**: New journal entries MUST be appended at the end of the file, never inserted between existing entries
|
|
112
|
+
- Entries maintain strict chronological order by position - the last entry in the file is always the most recent work
|
|
113
|
+
- Never reorder, move, or insert entries out of sequence
|
|
114
|
+
- 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
|
|
115
|
+
- 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
|
|
116
|
+
|
|
117
|
+
## Acceptance Criteria and Defects
|
|
118
|
+
|
|
119
|
+
- Criteria live in `docs/acc-crit*.md` and defects in `docs/defects*.md`, written **only** through
|
|
120
|
+
the project-management plugin (the `pm-tools` CLI), never by a hand edit of either file:
|
|
121
|
+
`/project-management:acc-crit` adds, closes, rejects or relates a criterion,
|
|
122
|
+
`/project-management:defect` files, triages, logs or closes a defect, `/project-management:report`
|
|
123
|
+
gives status and coverage
|
|
124
|
+
- **Every feature gets its acceptance criteria before the code**, and every criterion names the test
|
|
125
|
+
that proves it
|
|
126
|
+
- **Functional tests under `ui-tests/` are part of every feature**, not an afterthought, and run
|
|
127
|
+
green before a release
|
|
128
|
+
- Each release of the brief is complete by itself: criteria, tests, README, agent skill where it
|
|
129
|
+
applies
|
|
130
|
+
- Close a criterion only on evidence - the test that ran and what it showed
|
|
131
|
+
|
|
132
|
+
## Tests
|
|
133
|
+
|
|
134
|
+
All three tiers of the jupyterlab-extension skill's testing strategy, written to its
|
|
135
|
+
`references/galata-testing.md`:
|
|
136
|
+
|
|
137
|
+
- **pytest** under `jupyterlab_advanced_code_viewer_extension/tests/` for the server code
|
|
138
|
+
- **Jest** under `src/__tests__/` for frontend logic
|
|
139
|
+
- **Playwright/Galata** under `ui-tests/` for everything visible in the browser: the port through
|
|
140
|
+
the one variable `JUPYTER_TEST_PORT`, the test server on its own settings folder, no snapshot-only
|
|
141
|
+
assertions, and a suite that can fail - mutate what a test guards and watch it go red before
|
|
142
|
+
trusting its green
|
|
143
|
+
- Galata tests act as the agent: they write the file on disk while the test types in the same
|
|
144
|
+
document, then assert the text, the cursor, the undo history and the absence of the File Changed
|
|
145
|
+
dialog
|
|
146
|
+
|
|
147
|
+
## Command-Line Tools and Their Agent Skill
|
|
148
|
+
|
|
149
|
+
A command-line tool the extension ships (an entry point under `[project.scripts]` in
|
|
150
|
+
`pyproject.toml`) gets the `--help` and the agent skill that the jupyterlab-extension skill's section
|
|
151
|
+
"Agent Skill for a Shipped CLI" prescribes.
|
|
152
|
+
|
|
153
|
+
- **Name** - the extension's name in kebab-case, `jupyterlab-advanced-code-viewer-extension`, for
|
|
154
|
+
the directory and the `name:` field alike
|
|
155
|
+
- **Location** - `.agents/skills/jupyterlab-advanced-code-viewer-extension/SKILL.md` in the
|
|
156
|
+
repository root, and in the wheel through one line in the `shared-data` table of `pyproject.toml`
|
|
157
|
+
- **Same commit** - the skill and the `--help` text change in the commit that changes the CLI
|
|
158
|
+
- **Never inside the Python package** - the CI link check imports the package for every link in a
|
|
159
|
+
Markdown file inside it, and fails without `jupyter_server`
|
|
160
|
+
- **Reference implementation** -
|
|
161
|
+
`/home/lab/workspace/private/jupyterlab/jupyterlab_notifications_extension`
|
|
162
|
+
|
|
163
|
+
## Scope Control - graphify
|
|
164
|
+
|
|
165
|
+
- Run `/graphify` once the first source is in place to build `tmp/graphify-out/`
|
|
166
|
+
- Run `graphify affected` before editing existing code to learn its callers and dependents; that
|
|
167
|
+
affected set is the change budget, and an edit outside it needs the Star Colonel's word
|
|
168
|
+
- Run `graphify update` after every edit
|
|
169
|
+
- `tmp/` is gitignored, so the graph never ships
|
|
170
|
+
|
|
171
|
+
## Required Skills
|
|
172
|
+
|
|
173
|
+
| Skill | Use |
|
|
174
|
+
| --------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
175
|
+
| `jupyterlab-extension` | extension development guidelines, testing strategy, CI/CD, caveats |
|
|
176
|
+
| `my-browser` | browser automation for screenshots and UI verification against the running JupyterLab |
|
|
177
|
+
| `project-management:project-management` | acceptance criteria and defects through the `pm-tools` CLI |
|
|
178
|
+
| `graphify` | the codebase graph and the impact analysis that bounds every change |
|
|
179
|
+
| `journal:journal` | the project journal through the `journal-tools` CLI |
|
|
180
|
+
|
|
181
|
+
## Strengthened Rules
|
|
182
|
+
|
|
183
|
+
- **No mode** - no viewer mode, no review mode, no separate viewer widget; a function that needs a
|
|
184
|
+
mode to be entered is a design error, not a setting
|
|
185
|
+
- **The user's document is sacred** - a change from disk never moves the cursor or the selection,
|
|
186
|
+
never takes the focus, never enters the user's undo history, and never shows the File Changed
|
|
187
|
+
dialog once applied; a save never overwrites a disk change the extension has not applied
|
|
188
|
+
- **A marker never changes what the program does** - a marker inside a string, a here-document or a
|
|
189
|
+
template literal is refused or placed outside; a file kind without a comment syntax takes no mark
|
|
190
|
+
- **No kernel execution** - the extension starts none
|
|
191
|
+
- **Styling through JupyterLab CSS variables only** - no literal colours, so every theme renders the
|
|
192
|
+
change display and the marks; verify on stock light and stock dark with `my-browser`
|
|
193
|
+
- **No screenshot claim without a render** - a statement about visible behaviour needs a real
|
|
194
|
+
browser session behind it
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../.agents/JOURNAL.md
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
|
|
2
|
+
_commit: v4.6.5
|
|
3
|
+
_src_path: https://github.com/jupyterlab/extension-template
|
|
4
|
+
advanced: false
|
|
5
|
+
author_email: konrad.jelen@gmail.com
|
|
6
|
+
author_name: Stellars Henson
|
|
7
|
+
has_ai_rules: false
|
|
8
|
+
has_binder: false
|
|
9
|
+
has_settings: true
|
|
10
|
+
kind: frontend-and-server
|
|
11
|
+
labextension_name: '@stellarshenson/jupyterlab-advanced-code-viewer-extension'
|
|
12
|
+
project_short_description: Follow a notebook or a source file while an AI agent writes
|
|
13
|
+
it, see each change in the editor as you work, and mark and comment on code with
|
|
14
|
+
notes stored in the file
|
|
15
|
+
python_name: jupyterlab_advanced_code_viewer_extension
|
|
16
|
+
repository: https://github.com/stellarshenson/jupyterlab_advanced_code_viewer_extension
|
|
17
|
+
test: true
|
|
18
|
+
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
*.bundle.*
|
|
2
|
+
lib/
|
|
3
|
+
node_modules/
|
|
4
|
+
*.log
|
|
5
|
+
.eslintcache
|
|
6
|
+
.stylelintcache
|
|
7
|
+
*.egg-info/
|
|
8
|
+
.ipynb_checkpoints
|
|
9
|
+
*.tsbuildinfo
|
|
10
|
+
jupyterlab_advanced_code_viewer_extension/labextension
|
|
11
|
+
# Version file is handled by hatchling
|
|
12
|
+
jupyterlab_advanced_code_viewer_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
|
+
.nodeenv/
|
|
131
|
+
|
|
132
|
+
logs/
|
|
133
|
+
|
|
134
|
+
tmp/
|
|
135
|
+
|
|
136
|
+
# Jest JUnit report
|
|
137
|
+
junit.xml
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
<!-- <START NEW CHANGELOG ENTRY> -->
|
|
4
|
+
|
|
5
|
+
## [0.1.2] - 2026-10-30
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Upgrade to extension template v4.6.5 and Makefile 1.46
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Take the scoped @stellarshenson/jupyterlab-advanced-code-viewer-extension npm name
|
|
14
|
+
|
|
15
|
+
<!-- <END NEW CHANGELOG ENTRY> -->
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Development install
|
|
4
|
+
|
|
5
|
+
Note: You will need Node.js to build the extension package.
|
|
6
|
+
You may install it from [nodejs.org](https://nodejs.org/en/download). We
|
|
7
|
+
recommend using the latest LTS version of Node.js.
|
|
8
|
+
|
|
9
|
+
The `jlpm` command is JupyterLab's pinned version of
|
|
10
|
+
[yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use
|
|
11
|
+
`yarn` or `npm` in lieu of `jlpm` below.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Clone the repo to your local environment
|
|
15
|
+
# Change directory to the jupyterlab_advanced_code_viewer_extension directory
|
|
16
|
+
|
|
17
|
+
# Set up a virtual environment and install package in development mode
|
|
18
|
+
python -m venv .venv
|
|
19
|
+
source .venv/bin/activate
|
|
20
|
+
pip install --editable ".[dev,test]"
|
|
21
|
+
|
|
22
|
+
# Link your development version of the extension with JupyterLab
|
|
23
|
+
jupyter-builder develop . --overwrite
|
|
24
|
+
# Server extension must be manually installed in develop mode
|
|
25
|
+
jupyter server extension enable jupyterlab_advanced_code_viewer_extension
|
|
26
|
+
|
|
27
|
+
# Rebuild extension Typescript source after making changes
|
|
28
|
+
# IMPORTANT: Unlike the steps above which are performed only once, do this step
|
|
29
|
+
# every time you make a change.
|
|
30
|
+
jlpm build
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Watch the source directory in one terminal, automatically rebuilding when needed
|
|
37
|
+
jlpm watch
|
|
38
|
+
# Run JupyterLab in another terminal
|
|
39
|
+
jupyter lab
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt).
|
|
43
|
+
|
|
44
|
+
By default, the `jlpm build` command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
jupyter lab build --minimize=False
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Development uninstall
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Server extension must be manually disabled in develop mode
|
|
54
|
+
jupyter server extension disable jupyterlab_advanced_code_viewer_extension
|
|
55
|
+
pip uninstall jupyterlab_advanced_code_viewer_extension
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
In development mode, you will also need to remove the symlink created by `jupyter-builder develop`
|
|
59
|
+
command. To find its location, you can run `jupyter labextension list` to figure out where the `labextensions`
|
|
60
|
+
folder is located. Then you can remove the symlink named `@stellarshenson/jupyterlab-advanced-code-viewer-extension` within that folder.
|
|
61
|
+
|
|
62
|
+
## Endpoint authentication
|
|
63
|
+
|
|
64
|
+
Every verb method of every handler must carry a `@tornado.web.authenticated`
|
|
65
|
+
decorator, or, if the endpoint is meant to be public, an explicit
|
|
66
|
+
`@allow_unauthenticated`/`@ws_authenticated` decorator from
|
|
67
|
+
`jupyter_server.auth.decorator`. The `build` workflow enforces this by running:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
python .github/scripts/check_auth.py
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Testing the extension
|
|
74
|
+
|
|
75
|
+
### Server tests
|
|
76
|
+
|
|
77
|
+
This extension is using [Pytest](https://docs.pytest.org/) for Python code testing.
|
|
78
|
+
|
|
79
|
+
Install test dependencies (needed only once):
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
pip install -e ".[test]"
|
|
83
|
+
# Each time you install the Python package, you need to restore the front-end extension link
|
|
84
|
+
jupyter-builder develop . --overwrite
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
To execute them, run:
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
pytest -vv -r ap --cov jupyterlab_advanced_code_viewer_extension
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### Frontend tests
|
|
94
|
+
|
|
95
|
+
This extension is using [Jest](https://jestjs.io/) for JavaScript code testing.
|
|
96
|
+
|
|
97
|
+
To execute them, execute:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
jlpm
|
|
101
|
+
jlpm test
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Integration tests
|
|
105
|
+
|
|
106
|
+
This extension uses [Playwright](https://playwright.dev/docs/intro) for the integration tests (aka user level tests).
|
|
107
|
+
More precisely, the JupyterLab helper [Galata](https://github.com/jupyterlab/jupyterlab/tree/master/galata) is used to handle testing the extension in JupyterLab.
|
|
108
|
+
|
|
109
|
+
More information is provided within the [ui-tests](./ui-tests/README.md) README.
|
|
110
|
+
|
|
111
|
+
## Packaging the extension
|
|
112
|
+
|
|
113
|
+
See [RELEASE](RELEASE.md)
|
|
@@ -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.
|