公开记录
软件健康报告模式 0.26.0 · 指标 1.13.0 · 2026-07-22 12:19 UTC

stellarshenson / jupyterlab_claude_code_extension

JupyterLab 4 extension - Claude Code session management side panel

Python · TypeScriptBSD-3-Clause★ 1 星标⑂ 0 复刻始于 2026年4月在 GitHub 上查看 ↗

stellarshenson/jupyterlab_claude_code_extension 的健康指数为 100 分中的 39 分,处于「存在风险」区间。 其得分最高的类别是AI Readiness(72/100),最低的是Security(23/100)。 最近一次更新在 5 天前。 近期的大部分工作由 1 位贡献者完成。

39
总分 / 100
存在风险

软件健康指数

指标归入加权类别,统一采用 1–100 量表。总体分先取类别加权平均;当公开证据触发高风险司法辖区政策时,评级会按政策调整,并设置 49(有风险)的上限。AI 就绪度不计入总体分。

39
优秀85-100堪称典范;基本满足所有检验标准
良好70-84健康;仅有轻微不足
中等50-69可接受,但存在明显不足;建议进行审查
存在风险30-49存在重大薄弱环节;采用时应保持审慎
危急1-29问题严重(项目被弃置、仅有单一维护者、缺乏基本工程规范)
活力社区与采用可持续性与治理工程质量安全AI 就绪度

评分画像

每条轴代表一个类别。形状比平均值更重要——健康的对象会填满整个图形,而“一峰一谷”式画像意味着某一维度的优势正掩盖另一维度的风险。

所有权

Konrad Jeleń个人账户
9 关注者119 个公开仓库始于 2016年4月Kolomolo, Ai4Process, PMR

该仓库由个人账户拥有。相较于组织支持的项目,单一所有者项目的延续性风险更高。

软件包生态系统

注册表软件包版本月下载量版本数最近发布标签
npmjupyterlab_claude_code_extension1.2.503,328775 天前jupyterjupyterlabjupyterlab-extension
PyPIjupyterlab_claude_code_extension1.2.50-775 天前jupyterjupyterlabjupyterlab-extension

按类别列示的指标

活力

项目是否仍有生命——是否仍在编写代码,是否仍在发布版本?

38存在风险 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 5 天前
7.6/36提交节奏 — 52 周中有 11 周有提交
18/18提交量 — 最近一年 178 次提交
0/10OpenSSF Scorecard:Maintained — project was created within the last 90 days. Please review its contents carefully
所用输入
commits_last_year178
human_commit_share1
days_since_last_push5
active_weeks_last_year11
评分方式
0/27有发布版本 — 未发布任何发布版本
0/36发布时效 — 没有发布版本
0/27发布节奏 — 没有发布版本
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count0
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

项目是否拥有用户、下载量与关注度,并具备欢迎贡献者参与的配置?

33存在风险 · 占总体的 18%
评分方式
0/60星标 — 1 个星标
0/25复刻 — 0 个复刻
0/15关注者 — 0 位关注者
所用输入
forks0
stars1
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

社区健康

50中等
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(BSD-3-Clause)
0/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template
评分方式
47/80月度下载量 — npm, pypi 合计每月 3,328 次下载
0/20注册表被依赖数 — 该生态系统不报告此项
所用输入
packagesjupyterlab_claude_code_extension, jupyterlab_claude_code_extension
dependents
ecosystemsnpm, pypi
total_downloads
monthly_downloads3,328
已排除计分(无数据或不适用):注册表被依赖数。 其余权重已重新归一化。

可持续性与治理

项目能否在其成员之外延续——巴士系数、响应能力、由谁支持,以及软件包的维护状况?

37存在风险 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
0/22.5提交分布 — 头号贡献者编写了 100% 的提交
1.4/13.5贡献者广度 — 1 位贡献者
3/10OpenSSF Scorecard:Contributors — project has 1 contributing companies or organizations -- score normalized to 3
所用输入
bus_factor1
contributors_sampled1
top_contributor_share1
评分方式
0/46.8议题解决 — 没有议题或无数据
0/38.3PR 接受 — 没有已裁定的拉取请求或无数据
0/15OpenSSF Scorecard:Code-Review — Found 0/30 approved changesets -- score normalized to 0
所用输入
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
已排除计分(无数据或不适用):议题解决, PR 接受。 其余权重已重新归一化。
评分方式
10/30所有权背书 — 个人(用户)账户
0/20已验证域名 — 不适用于个人账户
7.2/25所有者影响力 — stellarshenson 有 9 位关注者
25/25既往记录 — 119 个公开仓库,账户约 10 年
所用输入
followers9
owner_typeUser
is_verified
owner_loginstellarshenson
public_repos119
account_age_days3,752
已排除计分(无数据或不适用):已验证域名。 其余权重已重新归一化。
评分方式
25/25已发布且可解析 — npm, pypi 上有 2 个软件包
35/35发布时效 — 最近一次发布于 5 天前
20/20版本历史 — 77 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagesjupyterlab_claude_code_extension, jupyterlab_claude_code_extension
ecosystemsnpm, pypi
any_deprecated
min_days_since_publish5

工程质量

基础的工程与文档实践是否到位?

62中等 · 占总体的 20%

工程实践

60中等
评分方式
24/24CI 工作流 — 6 个工作流
24/24存在测试
0/16Linter 配置
0/9.6Pre-commit 钩子
0/6.4.editorconfig
0/20OpenSSF Scorecard:CI-Tests — 无数据
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config
已排除计分(无数据或不适用):OpenSSF Scorecard:CI-Tests。 其余权重已重新归一化。

文档

65中等
评分方式
30/30README
25/25文档目录
0/15文档 / 主页站点
10/10仓库描述
0/10主题标签
0/10Wiki
所用输入
topics
has_wiki
homepage
has_readme
has_docs_dir
has_description

安全

可见的安全与供应链实践是否稳固,且不存在未解决的高风险司法辖区暴露?

23危急 · 占总体的 16%

安全态势

23危急
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 无数据
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — 无数据
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — 无数据
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 31 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated15
scorecard_versionv5.5.0
checks_inconclusive3
scorecard_aggregate2.3
已排除计分(无数据或不适用):ci_tests, packaging, signed_releases。 其余权重已重新归一化。

AI 就绪度

该仓库在多大程度上具备与 AI 编码代理协同开发与维护的条件?这是一枚独立的实验性徽章——权重为 0.0,因此单独呈现,不影响总体健康评分。

72良好 · 占总体的 0%
评分方式
45/45代理指令 — .claude/CLAUDE.md
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 100 次人类提交中有 100 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share1
agent_instruction_files.claude/CLAUDE.md
agent_instruction_max_bytes7,612
评分方式
18/18一条命令的引导启动 — Makefile
22/22自动化测试
0/11Lint / 格式化配置
11/11静态类型检查 — tsconfig.json
10/10可复现环境 — lockfile
0/10已体现的代理实践 — 最近 100 次提交中没有代理编写的提交
0/8自动化维护 — 未观察到自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
所用输入
has_nix
has_tests
lockfilespackage-lock.json, yarn.lock
has_dockerfile
typed_language
bootstrap_filesMakefile
has_devcontainer
has_linter_config
typecheck_configstsconfig.json
agent_commit_share0
toolchain_manifests
dependency_bot_commit_share0
评分方式
27/45可类型检查的代码 — Python,已配置类型检查(tsconfig.json)
50/55可控的文件大小 — 采样的 22 个源文件中有 2 个超过 60KB
所用输入
primary_languagePython
largest_source_bytes85,186
source_files_sampled22
oversized_source_files2

关键数据

1GitHub 星标
1贡献者
178最近 12 个月提交数
5距最近推送天数
0发布版本数
1巴士系数(bus factor)
0开放议题
npm, PyPI软件包生态系统数

数据采集警告

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index npm:jupyterlab_claude_code_extension@1.2.50; advisories assessed against the repository dependency graph instead

更多细节

OpenSSF Scorecard 2.3 / 10
2.3综合

来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。Scorecard v5.5.0 · 2026-07-22 12:19 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
不适用CI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
不适用Packagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
不适用Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities31 existing vulnerabilities detected
直接依赖 10
注册表软件包版本约束清单文件
npm@jupyterlab/apputils^4.0.0package.json
npm@jupyterlab/coreutils^6.0.0package.json
npm@jupyterlab/filebrowser^4.0.0package.json
npm@jupyterlab/services^7.0.0package.json
npm@jupyterlab/settingregistry^4.0.0package.json
npm@jupyterlab/terminal^4.0.0package.json
npm@jupyterlab/ui-components^4.0.0package.json
npm@lumino/commands^2.0.0package.json
npm@lumino/widgets^2.0.0package.json
npmjupyterlab_colourful_tab_extension^1.0.19package.json
全部依赖 未采集

本报告未能采集到解析后的依赖集合:GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 3432,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "CSS": 18409,
        "Python": 148393,
        "Makefile": 6184,
        "JavaScript": 1427,
        "TypeScript": 141964
      },
      "pushed_at": "2026-07-17T12:01:41Z",
      "created_at": "2026-04-30T10:20:01Z",
      "owner_type": "User",
      "updated_at": "2026-07-17T12:02:05Z",
      "description": "JupyterLab 4 extension - Claude Code session management side panel",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "BSD-3-Clause",
      "default_branch": "main",
      "license_spdx_raw": "BSD-3-Clause",
      "primary_language": "Python",
      "significant_languages": [
        "Python",
        "TypeScript"
      ]
    },
    "owner": {
      "blog": "https://www.linkedin.com/in/konradjelen/",
      "name": "Konrad Jeleń",
      "type": "User",
      "login": "stellarshenson",
      "company": "Kolomolo, Ai4Process, PMR",
      "location": "Krakow, Poland",
      "followers": 9,
      "avatar_url": "https://avatars.githubusercontent.com/u/18424023?v=4",
      "created_at": "2016-04-12T15:32:51Z",
      "is_verified": null,
      "public_repos": 119,
      "account_age_days": 3752
    },
    "license": {
      "state": "standard",
      "spdx_id": "BSD-3-Clause",
      "raw_spdx": "BSD-3-Clause",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [],
      "recent_commits": [
        {
          "oid": "efaf37a3fb5d0896a2c992fd937aa6be1fec9a75",
          "body": "Tab tinting had no off switch - it was unconditionally on whenever\njupyterlab_colourful_tab_extension supplied the IColourfulTabs token.\n\n- new `colouredTabs` boolean in schema/plugin.json, default true, so the\n  behaviour is unchanged unless it is turned off\n- read in index.ts inside the existing l\n[…]\ned into\n  _eachClaudeTerminal(apply) rather than duplicated\n\nThe gate itself has no executable coverage - it lives in widget.ts, which\nremains at 0%.\n\ntsc, prettier, eslint clean; pytest 111, jest 64.",
          "is_bot": false,
          "headline": "feat: add a setting to turn coloured terminal tabs off",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-17T12:01:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "774f3f0bb0896d54f85fdf5a65d8f5daa1d75f1d",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.50 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-17T12:01:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6d4cc1b93141372d001fefb966891a61e8da2687",
          "body": "…DEF-11)\n\nA session's terminal tab was tinted, then lost its colour after some time -\na regression introduced in 1.2.45.\n\nReading the true session id from the pidfile made a bare `claude -c` report\nits real conversation, which moved it out of the cwd fallback (that had been\ntinting it by accident) a\n[…]\neting it reproduced DEF-11 with\n  pytest green) and on the new jest tests being exact-text pins that went red\n  on a correct refactor; both fixed, round 2 clean\n\npytest 111, jest 64, tsc + lint clean.",
          "is_bot": false,
          "headline": "fix: tint a terminal from its own conversation, not the project row (…",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-16T11:11:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "780c462f9fe2baef457c78a61ca74c96dd8644ab",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.49 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-16T11:09:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9dffe931dbbef39b561510b489e33d633ca1fa76",
          "body": "No functional change - the extension code is identical to the released\n1.2.45. Versions 1.2.46 and 1.2.47 were local make install increments and\nwere never published; 1.2.48 brings the registry back in line.\n\nJournal entry 78 records the diagnosis behind the drift: the singleuser\ncontainer was recreated and /opt/conda lives in the container layer, so\nthe 1.2.45 install was silently reverted to the image's 1.2.44, and tab\ncolours no-op while the colourful-tab extension was mid-swap.",
          "is_bot": false,
          "headline": "chore: realign published version with local install lineage",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-16T08:31:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "557dbf32930afb89b7849727d71667ecc65181d2",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.48 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-16T08:31:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ccbb7ef233008655c66afea262e5d41d6f10762",
          "body": "Clicking a project row that already had a user-opened `claude -c` or bare\nterminal spawned a duplicate instead of focusing the running one. The reuse\ngate read the conversation id only from process argv (--session-id /\n--resume), which the panel injects but a self-opened terminal never carries,\nso t\n[…]\nion_id_from_pidfile, _claude_session_id)\n- frontend _findTerminalForSession matches on the session id alone, dropping\n  the cwd sanity-gate as itself an overfit\n- pytest 107, jest 58, tsc + lint clean",
          "is_bot": false,
          "headline": "fix: reuse a Claude terminal by its true session id (DEF-9 case c)",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-15T21:38:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cdfaad982bc3cd30dcff45174b26ef99ab4467ed",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.45 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-15T21:37:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "72fdb37a19e244a7efcb28c5400cb1eb00b4c93c",
          "body": "…ree clean",
          "is_bot": false,
          "headline": "docs: brace checkpoint - session-only usage limit, 1.2.44 released, t…",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-15T12:41:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bf51c44f0338c9f426ce9c9aedf8f20923c3e126",
          "body": "Disposing a JupyterLab dialog rejects its launch() promise with\nundefined; the panel launched the spinner and branch-popup dialogs\nfire-and-forget and then disposed them, so every terminal launch and\nbranch action emitted an \"Uncaught (in promise) undefined\" to the\nbrowser console.\n\n- guard both dia\n[…]\nd)\n- stop _switchBranch's finally fetch from rejecting its void callers\n- route the two commands.execute calls (terminal:create-new,\n  filebrowser:go-to-path) through _showError instead of a bare void",
          "is_bot": false,
          "headline": "fix: catch fire-and-forget promise rejections spilling to the console",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-15T11:10:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "458a9b4728cba4f98d0f3575c1042fa3aa465af5",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.44 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-15T11:09:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2410a5b3082b4bdd420dc17627a4429bf1e8d644",
          "body": "The tab-colour reconcile iterated `_terminalsByPath` (only terminals the\nplugin itself launched), so a Claude session opened outside the panel kept its\nterminal tab uncoloured even though the backend already resolved its colour.\n\n- reconcile now walks JupyterLab's terminal tracker (every open termin\n[…]\nst-prefix cwd fallback covers bare `claude`\n- fix a pre-existing jest compile break (test factory missing `color: null`,\n  latent since the 1.2.42 colour feature)\n- sync the Makefile to canonical 1.34",
          "is_bot": false,
          "headline": "fix: tint every open Claude terminal, not only panel-launched (DEF-10)",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-15T10:47:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c7917b1fe3b893b530b14230745c330746f71d63",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.43 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-15T10:46:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "441d8d9784db2ecce1f50308e880ee93414fbed7",
          "body": "- read the Claude session colour (set via /color, else auto-assigned) from the\n  session JSONL and surface it as a per-row `color` field\n  (`_scan_jsonl_for_agent_color` tail-scan in `sessions.py`)\n- delegate the tab tint to `jupyterlab_colourful_tab_extension` via its new\n  `IColourfulTabs.setColou\n[…]\nnals on fetch and the 30s poll (`_reconcileTerminalColours`)\n- record DEF-9 (opening an already-open session can spawn a duplicate resume)\n  in docs/defects.md with root cause and deferred fix options",
          "is_bot": false,
          "headline": "feat: tint each Claude terminal tab with its session colour",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-13T13:14:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c167481af5e602b170ba15b3e3048c18d5d11589",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.42 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-13T13:11:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8d3ccf73fdaa4c3f64972587a5a12b1130edb28f",
          "body": "The green \"remote control active\" dot stayed lit for a bridged session that\nhad gone idle - e.g. a project last active 17 days ago still showed it.\n\nClaude leaves bridgeSessionId set in ~/.claude/sessions/<pid>.json after the\nbridge disconnects while the interactive process keeps running, so the DEF\n[…]\nriven now.\n\n- session_state_by_cwd now also requires the record to be active within\n  REMOTE_CONTROL_FRESH_MS (1 hour)\n- test updated with a stale-but-bridged case; DEF-8 registered in docs/defects.md",
          "is_bot": false,
          "headline": "fix: gate the remote-control indicator on session freshness (DEF-8)",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-03T08:50:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3c3aa21f3be7a41fdf4e23d4b76999d4562d5928",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.41 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-03T08:50:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb421d1f9fcec977c984953c1e3bdce5bf7b5d52",
          "body": "The separator under \"Copy Session ID\" rendered as two misaligned segments -\nthe line under the icon column sat at a different height than under the text.\n\n- style/base.css: the Lumino menu is a display:table and JupyterLab draws a\n  separator as a border-top on an ::after inside every cell of the ro\n[…]\ne='separator']) so the separator cells realign\n- src/widget.ts: give the toggle-favourite command icon: starFilledIcon, the\n  same star used on starred rows, so the item matches the other menu actions",
          "is_bot": false,
          "headline": "fix: align the context-menu divider and add a favourites icon",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-01T17:47:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5159453a71cb041e473bbac6823aedc4588815de",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.40 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-01T17:46:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "02979403f56560a3999e053098de0b1f7f7a5160",
          "body": "The panel docked to the left sidebar by default, next to the file browser.\nDefault it to the right so it no longer crowds the file browser.\n\n- schema/plugin.json: sidebar.default left -> right, description reworded\n- src/index.ts: currentSidebar fallback (used when settings fail to load)\n  left -> right so the code default agrees with the schema\n\nThe setting still offers both sides; an existing explicit choice is untouched.",
          "is_bot": false,
          "headline": "feat: dock the panel to the right sidebar by default",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-01T16:01:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d33c4c4421e551c8b3608b2906d19a4054e11a31",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.39 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-01T16:01:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb0ab04f8773f206a654ae6dfd4707b6ef88f088",
          "body": "The presentation-mode setting's default option was labelled `folder`, but\nsince 1.1.8 it has shown the session name Claude records for a project (the\nfolder name is only the initial fallback), so the label misdescribed the\nbehaviour.\n\n- schema/plugin.json: enum [\"folder\", \"path\"] -> [\"name\", \"path\"]\n[…]\nT_PRESENTATION_MODE are now\n  'name'; doc comments updated\n- src/index.ts: any non-'path' value maps to 'name', so an existing user's\n  saved 'folder' still resolves to the name mode with no migration",
          "is_bot": false,
          "headline": "feat: rename the 'folder' presentation mode to 'name'",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-01T15:50:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c2dd19b2c6e3fcce6f8a7a7ee87c55c8f71d4577",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.38 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-01T15:49:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f102dbd403b038899150d229bc6280bd72dd51af",
          "body": "…F-7)\n\nThe panel's green \"remote control active\" dot lit for any session with a\nlive claude process registered for its cwd. But claude 2.x writes a\n~/.claude/sessions/<pid>.json for every interactive session; the\nremote-control (\"bridge\") link is signalled by a non-null bridgeSessionId.\nA plain inte\n[…]\nd-bridged both False)\n- README: describe the dot as remote-control, not merely running\n- docs: consolidate defects into the lean master docs/defects.md, register\n  DEF-7 (fixed), update acc-crit links",
          "is_bot": false,
          "headline": "fix: only light the remote-control indicator for bridged sessions (DE…",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-01T13:20:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "506c9f0d579b5170915d9c417a66ea77a8d0651a",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.37 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-07-01T13:20:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67c418e6b6b1139ad5652842dc61e5674eb82f03",
          "body": "The favourite star beside starred rows was a bright gold marker\n(--jp-warn-color1) that competed with the row text for attention. Revert\nto the stock jp-icon3 star (theme-driven gray) and dim it with\nopacity: 0.5 so the favourite marker reads as a quiet accent rather than\nan alarm.\n\n- icons.ts: favourite star back to the standard jp-icon3 icon\n- base.css: drop the warn-colour override, dim with opacity 0.5\n- CHANGELOG + JOURNAL for 1.2.36",
          "is_bot": false,
          "headline": "fix: dim the favourite star marker to lower its visual weight",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-25T18:04:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1890d41510a05814b3013d6d7b03e9a99e8c091a",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.36 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-25T18:04:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1abdbe1ad5ca975ddb66f66d510f77f952bd9c75",
          "body": "…rebuild\n\n- CHANGELOG: 1.2.35 - design-language rebuild of the Manage Sessions popup,\n  theme-driven; Delete is now an outline in every state; legible time/current\n- journal: stamp entry 67 with v1.2.35\n- gitignore reference design-asset zips dropped into .resources",
          "is_bot": false,
          "headline": "docs: changelog + journal for 1.2.35 Manage Sessions design-language …",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-24T15:16:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7b1e3e932da98dbcbb345df6008956d14f75f896",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.35 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-24T15:16:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9a08e3bc441f09e8a0a78bee926849beb228290d",
          "body": "Restyle the Manage Sessions popup to the Duoptimum Hub design system, driven\nby the current JupyterLab theme so a theme flip restyles the whole screen.\n\n- add a scoped --ccs-* token layer on .jp-ClaudeSessionsPanel-branchPopup\n  that maps the design tokens onto JupyterLab --jp-* theme variables\n- li\n[…]\nxt-subtle to --jp-ui-font-color2 so times and the \"current\"\n  marker stay legible (font-color3 washes out in dark themes)\n- DOM and behaviour unchanged; all acceptance criteria and jest contracts hold",
          "is_bot": false,
          "headline": "feat: rebuild Manage Sessions screen in the Duoptimum design language",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-24T15:09:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a2d99e9bec9759bcd4b4d5e5a4de064aedbba538",
          "body": "A freshly forked branch appeared in the panel after its first turn but the\nrow stayed on the parent it was forked from. Branch creation relied on\nrecency to make the fork current, but the parent is the conversation the\nuser is actively in, so its JSONL keeps being appended and its mtime\novertakes th\n[…]\n the _branchSession docstring (no longer recency-based)\n- pytest 102 (+4), jest 58, lint clean\n- acc-crit \"Becomes current\" reworked, \"Edge: parent stays active after a\n  fork\" added; DEF-6 registered",
          "is_bot": false,
          "headline": "fix: pin a created branch as the row's current conversation (DEF-6)",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-23T11:04:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7b65ce001da76d2b4a35383c798239ae31603c9e",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.34 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-23T11:03:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c0f235713c4f16c1d60617c91dbb57113d181d01",
          "body": "- DEF-4: terminal reuse requires a positive conversation-id match; an\n  unidentified terminal (claude started with -c/--continue or bare claude,\n  reporting no session id) is never reused. New Session launches\n  claude --session-id <uuid> so every extension terminal is identifiable\n- DEF-5: switchin\n[…]\nmode switch), plus menu-timeout and submenu-selector fixes\n- pytest 98, jest 58, Galata 7/7; DEF-4/DEF-5 survived a 5-round adversarial\n  review, the current-marker change a 2-round ux-designer review",
          "is_bot": false,
          "headline": "fix: conversation-aware reuse, durable switch pin, plain current marker",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-22T16:14:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d29fff103becb6fee92c72ca8c9407bef4fe63fd",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.33 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-22T16:12:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fa257a2c12f73cc3179002609fc11784e1044ef3",
          "body": "- fix (DEF-3): clicking a row after switching to another conversation\n  resumed the original one - terminal reuse was keyed purely by project\n  cwd, so the still-open claude --resume <original> terminal was refocused\n  regardless of the switched branch (a running claude is pinned to one\n  conversati\n[…]\nranched Conversation section and DEF-3\n\nSurvived /adversarial-review (2 rounds): fixed the microcache storing the wanted not observed id and a strict 'already in use' on the current row; round 2 SHIP.",
          "is_bot": false,
          "headline": "feat: conversation-aware terminal reuse and Open Branched Conversation",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-22T07:44:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ff341156a71cdfe51af8ab5e86563c88f47038c5",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.26 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-22T07:44:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cfe3a83683262d9a8563e15cf144e775b42784f9",
          "body": "- Manage Sessions popup is now a scrollable table with the current\n  conversation pinned at the top and accented (brand left bar + CURRENT chip)\n  instead of dimmed\n- popup delete is a single click to trash (reports N moved to trash),\n  removing the second Lumino dialog that rendered detached from t\n[…]\nete reads the conversation list back from disk so the table stays accurate\n- accessibility: per-checkbox aria-labels, aria-live status, 24px hit targets,\n  focus management, and an in-flight busy lock",
          "is_bot": false,
          "headline": "feat: redesign Manage Sessions popup as an accented table",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-22T05:46:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "940462c094bcb58c1b925b0c4c6d646f81badeca",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.25 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-22T05:45:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ddf4d2bd7ab8ea121fee55fd1532386fb7267c92",
          "body": "- reformat docs/defects-branch-session.md to a Contents TOC over flat\n  ### DEF-N sections, [ ]/[x] marked in place; drop the Open/Fixed split\n  and the move-on-resolve ceremony\n- changelog + journal entry 58 for v1.2.24 (docs-only, no packaged change)",
          "is_bot": false,
          "headline": "docs: simplify defect-tracking format to TOC over flat DEF sections",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-21T20:03:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a3a1139cf03bff70721099a340c6ea41abeec22",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.24 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-21T20:02:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "08c478679411b9a6dbad0d5d27e391e86567f81c",
          "body": "- add \"Copy Session ID\" context-menu item and a per-row copy button in the\n  Manage Sessions popup, both via Clipboard.copyToSystem\n- forced refresh now shows a spinner veil over the panel; the 30s background\n  poll stays silent. The veil lives on the panel root so a concurrent render\n  (which wipes\n[…]\nthe seven per-feature acc-crit docs into one plugin-wide\n  docs/acc-crit-jupyterlab_claude_code_extension.md; add docs/defects-branch-session.md\n- tests: jest 43, pytest 79 (removed 5 set-title tests)",
          "is_bot": false,
          "headline": "feat: copy session id, forced-refresh spinner, branch-name warning fix",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-21T19:22:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7892dc6a53b78d248b31d855dba73aea997a3d87",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.23 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-21T19:21:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ebe7225bc66021bdf2bb78b8dbfda5882a1c96ac",
          "body": "Branch sessions reverted to the parent conversation's name because\nclaude --fork-session copies the parent JSONL (inheriting its\ncustom-title) and re-stamps that title every turn, burying the single\ncustom-title record appended after the fork. The fork now launches with\nclaude -n <name>, so claude owns the display name and re-stamps the\nchosen name itself - it sticks. launch-terminal accepts and validates\nan optional name and appends -n <name> to the argv.",
          "is_bot": false,
          "headline": "fix: force branch session name via claude -n",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-17T21:13:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5789c6a722f0a8f305598c5ee4a58ad660577714",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.22 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-17T21:13:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b24f2ea47eec96d40240b69ae0a03414ff5d01b1",
          "body": "Clean Up Parallel Sessions removed on click with no prompt, and the\nManage Sessions popup used an inline two-step Delete button. Both now\nopen a confirmation dialog naming the project and the count, with\nCancel and a red Remove/Delete button; removal proceeds only on\nconfirm. The orphaned confirmArmed two-step state was dropped.",
          "is_bot": false,
          "headline": "feat: confirm parallel and individual session removal",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-17T16:37:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "649e68158d1cf23dcafb8b35aee4f8e74dc9cd7a",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.21 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-17T16:36:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4171f0152d3c4e157bfd413dc1e368b9e554eff9",
          "body": "Remove from Claude deleted the entire Claude project and every\nconversation in it on a single click with no prompt. _remove now opens\na confirmation dialog naming the project and warning the whole project\nand all its conversations are removed irreversibly, with Cancel and a\nred Remove button; removal proceeds only on confirm.",
          "is_bot": false,
          "headline": "feat: confirm before removing a Claude project",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-17T16:10:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "639078770a87258874529d4182b58b47a6179ce8",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.20 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-17T16:10:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e5ef8ea282eabb56d73b79b55c48921f23a6711",
          "body": null,
          "is_bot": false,
          "headline": "chore: yarn.lock refresh from 1.2.19 release build",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T13:01:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "97f3cbe3a6ea99476762ccb002f5c21f8345512c",
          "body": null,
          "is_bot": false,
          "headline": "docs: changelog for 1.2.19 switch-icon release",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T13:00:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9258104f57c60f5790ea5e75a6adec422cee21b",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.19 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T13:00:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d53bb5b2be849ef6b700b45d8990b0f23090c453",
          "body": "- new switchIcon in icons.ts (Octicons arrow-switch-16, jp-icon3 themed\n  fill) set as the submenu's title icon, matching the Branch Session\n  submenu's icon treatment",
          "is_bot": false,
          "headline": "feat: switch icon on Switch and Manage Sessions submenu",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T12:56:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "73f8856d71364a86b2a21e356221d199b45ca836",
          "body": "… column\n\n- collapse the two Branch Session menu items into one submenu (Normal /\n  Skip Permissions, shield icon), drop the ellipsis from the labels\n- time column fixed at 4em with nowrap - removes the dead space between\n  star and time without wrapping two-digit day labels into the next row\n- stars line up vertically across the whole panel: time slot always\n  rendered (empty without an mtime) and section lists reserve the\n  scrollbar gutter so a scrolling section does not shift its columns",
          "is_bot": false,
          "headline": "feat: branch-session submenu, panel-wide star alignment, tighter time…",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T11:52:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "254cdaeaf2cc4772d092f652418fbbfb57cc5d6f",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.17 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T11:52:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c564c47d06f446dc6ea4706151091a20b2938dc4",
          "body": "- jupyterlab_claude_code console script (project.scripts) with the\n  install-claude-statusline subcommand: confirmation prompt, download\n  from stellarshenson/claude-code-statusline (nothing vendored), script\n  written executable to ~/.claude, statusLine merged into settings.json\n  preserving other \n[…]\n untouched on invalid existing settings JSON or a non-script\n  download response; --yes for non-interactive, --claude-dir override\n- acc-crit doc, README statusline section, 8 CLI tests (pytest 82/82)",
          "is_bot": false,
          "headline": "feat: install-claude-statusline companion CLI",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T11:25:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "07e71f3fe0f0fdabf3287a9830ce3c59c9a80a72",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.12 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T11:25:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "66b36fe2aee7881633202ac4933d487245b83cc5",
          "body": "…design language\n\n- Branch Session context-menu items (normal + skip permissions) fork the\n  current conversation via claude --fork-session with a known session id;\n  name stamped through new POST sessions/set-title without bumping mtime\n- fix _resolve_latest rejecting subdirectory tail cwds - same-\n[…]\nes design language; rules\n  distilled into the jupyterlab-extension skill design-language.md\n- README repositioned as a full Claude Code launcher and manager\n- pytest 74/74 (7 new), jest 37/37 (7 new)",
          "is_bot": false,
          "headline": "feat: branch session fork, subdir-cwd switch fix, row columns, popup …",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T11:05:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1c4af6d9b5998e0650e83a0e688f137447a8da92",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.9 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T11:04:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "46081cf145c2f493cbd9c7736b257522bb258d36",
          "body": "- submenu retitled 'Switch and Manage Sessions (N)'; 'Manage Sessions...'\n  popup entry always present (was gated behind >5 branches, leaving 2-5\n  branch projects without management access)\n- popup leads with the badged, untouchable current conversation; checkbox\n  selection in its own click zone, \n[…]\nring\n- row age emphasis: <1m active rows in brand colour, >7d idle rows dimmed\n- acc crit: branch-switching doc fully checked, new acc-crit-row-age-emphasis\n- tests: pytest 65 (9 new), jest 30 (8 new)",
          "is_bot": false,
          "headline": "feat: manage sessions popup with multi-select delete, row age emphasis",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T10:05:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "213e13553d07e140fe7cf73e985b046f0b0c5bbb",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.7 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T10:05:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "509007e746a474fc18e55446800994eda3f06008",
          "body": "…riteria\n\n- branch submenu and More... popup entries render the conversation name\n  plus short session id in brackets via _branchDisplayName; branches share\n  the project path so name and id are the distinguishing display\n- suffix skipped when the label already is the short-id fallback\n- acceptance \n[…]\nklist format with per-criterion\n  append-only log lines; Names and Id criteria added\n- journal archived (entries 1-27 to JOURNAL_ARCHIVE.md)\n- jest contract test for the branch display name (22 total)",
          "is_bot": false,
          "headline": "feat: show short session id on branch entries, checklist acceptance c…",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T09:28:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "21aba3bec7d1f6da46e3cd6f8d16506361ff334a",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.5 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T09:28:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0b29de11bd1281280e7c3f1babb388b58f218c9b",
          "body": "Each row shows when the session was last worked on, right of the\nname: now (within the last minute), then <n>m / <n>h / <n>d ago.\n\n- _formatRelativeTime reworked to the simple buckets: 'just now'\n  became 'now', the >30-day locale-date fallback dropped for plain\n  <n>d ago - branch submenu, More popup and tooltip inherit it\n- new jp-ClaudeSessionsPanel-rowTime style (dim, size0, flex none)\n- two jest contract tests (jest 21/21)",
          "is_bot": false,
          "headline": "feat: last-activity relative time on session rows",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T08:46:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5ce85c20c4e8120a1fbeb6f213012376fda91346",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.4 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T08:45:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e1dbfa1263a29833f70b9e248e759355fb57d12c",
          "body": "A project's other conversation JSONLs (branches) are now switchable\nfrom the row context menu. Selection persists by touching the chosen\nJSONL's mtime so recency resolution, parallel-session cleanup and\nclaude's own --resume picker agree without extra state.\n\n- backend list_branches (all branches ne\n[…]\nns a\n  search-filtered popup over the full list\n- rows show the conversation count in brackets, e.g. workspace (2)\n- acceptance criteria in docs/acc-crit-branch-switching.md\n- pytest 58/58, jest 19/19",
          "is_bot": false,
          "headline": "feat: switch conversation branch submenu with searchable More popup",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T08:39:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "948bb306ddae013fae876ce2a1f5d3a3bb102d47",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.2.2 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T08:38:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e1b3983602b6ae2af652cff07982c5cce9659b58",
          "body": "Current Claude Code persists /rename as a {\"type\": \"custom-title\"}\nrecord appended to the session JSONL; the pid files in\n~/.claude/sessions/ keep name null, so the panel fell back to the\nfolder basename for renamed sessions.\n\n- add _scan_jsonl_for_custom_title: 128 KiB tail read with a\n  custom-tit\n[…]\nname priority: JSONL customTitle -> pid-record name\n  (legacy fallback) -> folder basename\n- three backend tests: title honoured, title beats stale pid name,\n  tail scan of a large file (pytest 48/48)",
          "is_bot": false,
          "headline": "fix: honour /rename via JSONL custom-title record",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T08:08:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "84ef86d3741b8b596ad238abc31e2960527caa31",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.31 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-12T08:07:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5f77e151e684d3a83daddd751a4acb1f640f6e4d",
          "body": "- replace the two header buttons with one plus button that opens a\n  Lumino menu offering New Claude Session and New Claude Session\n  (Skip Permissions) with the shield icon, styled like the row\n  context menu\n- drop the composite addShieldIcon; commands live in the shared\n  CommandRegistry and delegate to the existing _newSession\n- Galata specs drive the dropdown and verify the launched terminal",
          "is_bot": false,
          "headline": "feat: single plus button with new-session dropdown menu (v1.1.29)",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-10T22:11:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d33af28f2f57a499a0055442b0997828b6283ccb",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.29 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-10T22:10:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21e0331e089db01e0a47fcda1401d5f55a69f49f",
          "body": "…der (v1.1.27)\n\n- plus and plus-with-shield header buttons launch a fresh claude session\n  in the file browser's current folder, the shield variant with\n  --dangerously-skip-permissions; same no-shell launch path as resume\n- launch-terminal endpoint's session_id is now optional (absent = new\n  sessi\n[…]\nand the click-to-terminal\n  flow, JLAB_TEST_PORT override for machines where 8888 is busy\n- new addIcon/addShieldIcon, optional IDefaultFileBrowser wiring, and\n  the @jupyterlab/filebrowser dependency",
          "is_bot": false,
          "headline": "feat: header buttons to start a new Claude session in the current fol…",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-10T21:50:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6ea58609654858a494181096ab4101ab84b3147e",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.27 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-10T21:50:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a8ae2d24d710199572c17ded6eb93d93f27ad0b",
          "body": "- cleanup now runs inside a Dialog with an indeterminate progress bar\n  while the POST is in flight, filling with a removed-count message on\n  success or a red failure message on error; Close button appears once\n  the outcome is shown\n- three new CSS rules for the popup body, bar, and error styling\n- five jest contract tests guard the popup behaviour (progress element,\n  footer toggle, success fill, error class, post-success refresh)",
          "is_bot": false,
          "headline": "feat: progress popup for parallel-session cleanup (v1.1.25)",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-10T14:03:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ee6b359ecc4d3df3a9d4a763b59ea4f281c72de",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.25 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-10T14:03:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8099ad29d66773661d66731addd0c533a129efa7",
          "body": "- sessions.py: extra_sessions count per row; cleanup_parallel_sessions()\n  keeps the main session and removes other JSONLs plus their subagent\n  dirs, to trash when configured (same semantics as remove_session)\n- routes.py: POST sessions/cleanup endpoint honouring delete_to_trash\n- widget.ts: 'Clean\n[…]\nsions; refreshes counts after cleanup\n- README: cleanup feature bullet; search and presentation-mode bullets\n  brought current\n- tests: 7 new pytest cases (42 total), jest fixture gains extra_sessions",
          "is_bot": false,
          "headline": "feat: context menu item to clean up parallel sessions (v1.1.23)",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-10T10:26:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "984a0ffd65a9da98f1fa9d2c7969893df18d3015",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.23 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-06-10T10:25:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "abb114381d3bc44d7500466ada339dbe19a94948",
          "body": "A session renamed in Claude (e.g. /rename scandi) still displayed the\nfolder basename. The latest-wins picker already resolved the cwd to the\nrenamed record, but since v1.1.8 session_state_by_cwd dropped the name\nfield and list_sessions hard-coded name = basename.\n\n- sessions.py: session_state_by_cw\n[…]\n\n\nTradeoff: folders where Claude auto-derived a topic now show that topic\nrather than the bare folder name - the field carries both with no flag.\n\npytest 35/35, jest 6/6, build:lib + lint:check clean.",
          "is_bot": false,
          "headline": "feat: honour Claude session name so /rename shows in the panel (v1.1.21)",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-29T19:21:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5cd7e3817cdc9ec7f51db2b6a4b7eb34099532ea",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.21 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-29T19:21:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd96462c3fe932e66a17d0f74fcaa59b429dfcbb",
          "body": "…fier (v1.1.20)\n\nThe v1.1.19 swap picked the magnifying glass from\n@jupyterlab/ui-components/style/icons/toolbar/search.svg, but that\nicon is what FilenameSearcher renders inside its input box - the file\nbrowser's actual external filter toggle uses the funnel from\nsearch/filter.svg. Replace filterIcon's SVG with a verbatim copy of\nsearch/filter.svg so the two readouts finally match.\n\nLabIcon registration name unchanged; class=\"jp-icon3\" lets the\nJupyterLab theme drive the colour as before.",
          "is_bot": false,
          "headline": "fix: filter button uses the file browser's funnel icon, not its magni…",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-29T08:02:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "64f064966440f8a723697edbde4506183c4d66ca",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.20 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-29T08:01:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cbc848af9e0c1e791b6de6b144fcf47494b0bbbe",
          "body": "….1.19)\n\nThe v1.1.18 filter toggle used a Material FilterList (three horizontal\nbars) but JupyterLab's file browser uses a magnifying glass for its\nfilter box, so the two readouts were visually inconsistent. Swap the\nfilterIcon SVG in src/icons.ts to a verbatim copy of\n@jupyterlab/ui-components/style/icons/toolbar/search.svg - the same\nicon FilenameSearcher renders.\n\nLabIcon registration name (jupyterlab_claude_code_extension:filter) is\nunchanged, so no widget wiring touches needed.",
          "is_bot": false,
          "headline": "feat: filter button uses the file browser's magnifying-glass icon (v1…",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-29T07:58:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bcd18cf8a8a053aa040a7c3e2ccb7597b3109d5a",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.19 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-29T07:58:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d7009f347fc7020c75c527f7c2625a634872c9b",
          "body": "The \"Filter sessions...\" input occupied permanent vertical real estate\nabove the row list even when unused. Hide it by default and reveal it\nvia a new filter button next to the refresh button in the header.\n\n- src/icons.ts: new Material FilterList icon matching the existing\n  refreshIcon / removeIco\n[…]\nctive. On hide: clears the active\n  filter and re-renders so a stashed-away filter does not silently\n  narrow rows next time the bar is opened\n- style/base.css: jp-mod-active state for the icon button",
          "is_bot": false,
          "headline": "feat: collapse search bar by default, toggle via filter icon (v1.1.18)",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T22:49:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6b415616fc89c65f67efe1e96c11aed9cc6f99b6",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.18 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T22:49:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "354c329dfb7349374fd3c6904230e370883091ad",
          "body": "Records entry 36. Release content: YouTube URLs added to the CI\nlink-checker ignore list because YouTube's 429 rate-limit was making\nCheck Release Build red non-deterministically. CI-only change, no\npackage bytes affected; release exists purely to verify the fix on a\nfresh CI run.",
          "is_bot": false,
          "headline": "docs: journal v1.1.17 - CI link checker ignores YouTube URLs",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T16:38:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f53749923ffa062e598d80dc0079d9bd4a021df7",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.17 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T16:38:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b78e6c0914259926d342c54c98e82c0eb5c6f0bb",
          "body": "ui-tests/README.md links to a YouTube video that explains Playwright UI\nmode. YouTube rate-limits the link checker with 429 Too Many Requests\nintermittently, breaking the Check Links job for reasons unrelated to\nthe repo's actual link health.\n\nAdd https://www.youtube.com/.* and https://youtu.be/.* to ignore_links\nin .github/workflows/build.yml, alongside the existing npmjs and pepy\nignores.",
          "is_bot": false,
          "headline": "ci: ignore YouTube URLs in link checker",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T16:33:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "52e9ae19d7d9312b2e5b83c871e58c2398113eeb",
          "body": "…-grep\n\nRecords entry 35 with the v1.1.16 release stamp. Release content: the\nbrittle Galata spinner test was swapped for a deterministic Jest\nsource-level invariant that asserts _doResumeInTerminal dismisses via\ndispose() and never resolve(), and that _showLaunchSpinner constructs\na Dialog with buttons:[]. The .claude/scheduled_tasks.lock runtime\nartifact was also untracked and gitignored along the way.",
          "is_bot": false,
          "headline": "docs: journal v1.1.16 - Galata spinner test replaced with Jest source…",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T16:28:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "92f3ab8be49550cd3809f3e799bf5901923cbf91",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.16 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T16:28:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "14c614f250e1e08a2f0a4b10e6cd2dc918743806",
          "body": "The lock file at .claude/scheduled_tasks.lock holds the current Claude\nCode session's pid + sessionId. It changes every invocation and should\nnever have been committed - it was being staged in unrelated commits\nbecause git status kept reporting it as dirty.",
          "is_bot": false,
          "headline": "chore: untrack and gitignore Claude Code scheduled_tasks.lock",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T16:25:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a97dc8cf3f77845724f4998a289aad6b6d532172",
          "body": "Three iterations of the Galata test (row-click, waitForFunction,\nwaitForSelector by id) all timed out in CI with no usable telemetry.\nThe regression we want to prevent is purely about\nDialog({buttons:[]}).resolve() being a no-op vs .dispose() working, so\na source-level invariant captures it more rel\n[…]\nsent\n    * _showLaunchSpinner constructs Dialog with buttons:[]\n- Local declare for require + __dirname (tsconfig pins types:['jest'])\n- Guard verified: flipping dispose() -> resolve() makes Jest fail",
          "is_bot": false,
          "headline": "test: swap brittle Galata spinner test for a Jest source-level guard",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T16:12:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a9f97b3a78d5289897564cbdc60222cd109795c3",
          "body": "Records entry 34 with the version stamp for the 1.1.15 release:\n- waitForSelector('#jupyterlab-claude-code-extension') replaces brittle\n  app.shell.widgets() polling in the Galata spinner regression test\n- _showLaunchSpinner no longer renders a label below the spinner; title\n  bar + rotating spinner only",
          "is_bot": false,
          "headline": "docs: journal v1.1.15 - test fix follow-up + spinner UI minimisation",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T15:45:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3d7cd299c7023b0468e710794477e6bfecc4460b",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.15 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T15:45:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3634c6c4b9bef39457004a8a9eb4e88dd4999d73",
          "body": "The spinner Dialog body used to render \"Opening <project>...\" below the\nspinner icon. Drop that label - the title bar already says \"Opening\nClaude Code session\" and a few seconds of a rotating spinner is enough\nvisual feedback that something is happening.\n\nChanges:\n- src/widget.ts: _showLaunchSpinne\n[…]\naller in\n  _doResumeInTerminal no longer interpolates the session name\n- style/base.css: drop the unused .jp-ClaudeSessionsPanel-launchLabel rule\n- ui-tests test: call _showLaunchSpinner() with no arg",
          "is_bot": false,
          "headline": "feat: strip label text from launch spinner, keep title and spinner only",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T15:43:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dc68c4c156f9419371b94537cd13f26204f0918b",
          "body": "Last attempt at the Galata spinner test still timed out because the\ncustom waitForFunction tried to access widgets before the extension's\nasync activate() had finished awaiting /status and called labShell.add.\n\nReplace the polling loop with waitForSelector('#jupyterlab-claude-code-extension')\n- Lumi\n[…]\nk container the moment\nlabShell.add runs, so it is a stable readiness signal for the panel\nbeing registered. Only then walk app.shell.widgets() to grab the panel\ninstance and drive _showLaunchSpinner.",
          "is_bot": false,
          "headline": "test: wait for panel id selector instead of polling app.shell.widgets",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T15:38:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a4454d904638fda0dd2e0667599ebb5f24dbb10e",
          "body": "The test added in 63b3a60 timed out in CI on .jp-ClaudeSessionsPanel-row\nbecause the mocked /status payload used {has_claude} while the frontend\nreads status.enabled (src/types.ts::IStatusResponse, src/index.ts:44).\nWith enabled undefined the activate branch logged \"panel disabled\" and\nnever constru\n[…]\nner() from page.evaluate, stash the Dialog\n  handle on window, then dispose() it - the same try/finally pattern as\n  _doResumeInTerminal\n- assert the Dialog attaches and then detaches under .dispose()",
          "is_bot": false,
          "headline": "test: fix Galata spinner test mocks to actually pass CI",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T14:47:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "63b3a60720f9a4476711d3b43c5613431a8b9513",
          "body": "The launch-spinner Dialog in _showLaunchSpinner is constructed with\nbuttons: [] (the \"Run in background\" cancel button was dropped in\n1.1.13). With no buttons, Dialog.resolve() has no default to \"click\" and\nis a no-op - the modal hung over the panel forever after the terminal\nopened. Switch the dism\n[…]\now, clicks it to drive\n_doResumeInTerminal end-to-end, and asserts the \"Opening Claude Code\nsession\" Dialog both appears and dismisses. The detached-wait fails if\nsomeone reintroduces .resolve() here.",
          "is_bot": false,
          "headline": "fix: close launch spinner via dispose() and cover with a Galata test",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T12:44:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2741ca7a2df0371b507997d861787e92f8f79b21",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.14 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T12:40:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e4f0200cbc11efed362267fc03ab95a3112d4119",
          "body": "The launch-spinner modal (_showLaunchSpinner in src/widget.ts) carried\na Dialog.cancelButton({ label: 'Run in background' }) that suggested\nthe terminal spawn was a long background job. In practice the spawn is\na single POST to /launch-terminal followed by JL's terminal:open and\ncompletes in well under a second, so the button added noise without\nvalue. Set buttons: [] - the modal now shows just the spinner + label\nand auto-dismisses via dialog.resolve() when the spawn completes.",
          "is_bot": false,
          "headline": "fix: drop \"Run in background\" button from launch spinner",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T12:34:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8e0fa42d7d6502212bb19d00f7bb07bd28b327e6",
          "body": null,
          "is_bot": false,
          "headline": "chore: post-publish 1.1.13 package metadata",
          "author_name": "stellarshenson",
          "author_login": "stellarshenson",
          "committed_at": "2026-05-28T12:34:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 0,
      "commits_last_year": 178,
      "latest_release_at": null,
      "latest_release_tag": null,
      "releases_from_tags": false,
      "days_since_last_push": 5,
      "active_weeks_last_year": 11,
      "days_since_latest_release": null,
      "mean_days_between_releases": null
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "jupyterlab_claude_code_extension",
          "exists": true,
          "license": "BSD-3-Clause",
          "keywords": [
            "jupyter",
            "jupyterlab",
            "jupyterlab-extension"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/jupyterlab_claude_code_extension",
          "is_deprecated": false,
          "latest_version": "1.2.50",
          "repository_url": "https://github.com/stellarshenson/jupyterlab_claude_code_extension",
          "versions_count": 77,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 3328,
          "first_published_at": "2026-04-30T11:01:18.340000Z",
          "latest_published_at": "2026-07-17T12:01:15.333000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 5
        },
        {
          "name": "jupyterlab_claude_code_extension",
          "exists": true,
          "license": null,
          "keywords": [
            "jupyter",
            "jupyterlab",
            "jupyterlab-extension",
            "Framework :: Jupyter",
            "Framework :: Jupyter :: JupyterLab",
            "Framework :: Jupyter :: JupyterLab :: 4",
            "Framework :: Jupyter :: JupyterLab :: Extensions",
            "Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt",
            "License :: OSI Approved :: BSD License",
            "Programming Language :: Python",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.10",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Programming Language :: Python :: 3.13",
            "Programming Language :: Python :: 3.14"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/jupyterlab_claude_code_extension/",
          "is_deprecated": false,
          "latest_version": "1.2.50",
          "repository_url": "https://github.com/stellarshenson/jupyterlab_claude_code_extension.git",
          "versions_count": 77,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2026-04-30T11:01:20.328523Z",
          "latest_published_at": "2026-07-17T12:01:18.577473Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 5
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 1,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 85186,
      "source_files_sampled": 22,
      "oversized_source_files": 2,
      "agent_instruction_files": [
        ".claude/CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 7612
    },
    "dependencies": {
      "manifests": [
        "package.json",
        "pyproject.toml",
        "setup.py",
        "ui-tests/package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm",
        "pypi"
      ],
      "dependencies": [
        {
          "name": "@jupyterlab/apputils",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.0.0"
        },
        {
          "name": "@jupyterlab/coreutils",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^6.0.0"
        },
        {
          "name": "@jupyterlab/filebrowser",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.0.0"
        },
        {
          "name": "@jupyterlab/services",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^7.0.0"
        },
        {
          "name": "@jupyterlab/settingregistry",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.0.0"
        },
        {
          "name": "@jupyterlab/terminal",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.0.0"
        },
        {
          "name": "@jupyterlab/ui-components",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.0.0"
        },
        {
          "name": "@lumino/commands",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.0"
        },
        {
          "name": "@lumino/widgets",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.0"
        },
        {
          "name": "jupyterlab_colourful_tab_extension",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.0.19"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 0,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "stellarshenson",
          "commits": 178,
          "avatar_url": "https://avatars.githubusercontent.com/u/18424023?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "build.yml",
        "check-release.yml",
        "enforce-label.yml",
        "prep-release.yml",
        "publish-release.yml",
        "update-integration-tests.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json",
        "yarn.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "31 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "efaf37a3fb5d0896a2c992fd937aa6be1fec9a75",
        "ran_at": "2026-07-22T12:19:47Z",
        "aggregate_score": 2.3,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-17T12:04:37Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": null,
      "ci_last_conclusion": "FAILURE",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/stellarshenson/jupyterlab_claude_code_extension",
    "host": "github.com",
    "name": "jupyterlab_claude_code_extension",
    "owner": "stellarshenson"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 39,
      "inputs": {
        "security": 23,
        "vitality": 38,
        "community": 33,
        "governance": 37,
        "engineering": 62
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "at_risk",
        "name": "Vitality",
        "value": 38,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 62,
            "inputs": {
              "commits_last_year": 178,
              "human_commit_share": 1,
              "days_since_last_push": 5,
              "active_weeks_last_year": 11
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "11/52 weeks with commits",
                "points": 7.6,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 11
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "178 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 178
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "critical",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "releases_count": 0
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "no releases published",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases_published",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "no releases",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases",
                    "params": {}
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "no releases",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 33,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 1,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "1 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (BSD-3-Clause)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "BSD-3-Clause"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 59,
            "inputs": {
              "packages": [
                "jupyterlab_claude_code_extension",
                "jupyterlab_claude_code_extension"
              ],
              "dependents": null,
              "ecosystems": "npm, pypi",
              "total_downloads": null,
              "monthly_downloads": 3328
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "3,328 downloads/month across npm, pypi",
                "points": 47,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 3328,
                      "ecosystems": "npm, pypi"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 37,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 13,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution, PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution",
                    "pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "merged_prs": 0,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "no decided pull requests or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_decided_prs_or_data",
                    "params": {}
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 53,
            "inputs": {
              "followers": 9,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "stellarshenson",
              "public_repos": 119,
              "account_age_days": 3752
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "9 followers of stellarshenson",
                "points": 7.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 9,
                      "login": "stellarshenson"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "119 public repos, account ~10 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 119
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 10
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "jupyterlab_claude_code_extension",
                "jupyterlab_claude_code_extension"
              ],
              "ecosystems": "npm, pypi",
              "any_deprecated": false,
              "min_days_since_publish": 5
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "2 package(s) on npm, pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 2,
                      "ecosystems": "npm, pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 5 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "77 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 77
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 62,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "6 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "critical",
        "name": "Security",
        "value": 23,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 23,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 15,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 3,
              "scorecard_aggregate": 2.3
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "31 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 2
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 72,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                ".claude/CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 7612
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": ".claude/CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".claude/CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 61,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json",
                "yarn.lock"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [
                "Makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "tsconfig.json"
              ],
              "agent_commit_share": 0,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Makefile"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 77,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 85186,
              "source_files_sampled": 22,
              "oversized_source_files": 2
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python with type-check config (tsconfig.json)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "tsconfig.json",
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "2/22 source files over 60KB",
                "points": 50,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 22,
                      "oversized": 2
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index npm:jupyterlab_claude_code_extension@1.2.50; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-22T12:19:51.894684Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/s/stellarshenson/jupyterlab_claude_code_extension.svg",
  "full_name": "stellarshenson/jupyterlab_claude_code_extension",
  "license_state": "standard",
  "license_spdx": "BSD-3-Clause"
}

评分是信号,而非担保。 评分反映的是 GitHub 上公开可见的实践——不是代码审计,也不是安全保证。

缺失数据将被剔除并重新归一化权重,绝不按零分计。方法论已版本化并公开:指标 v1.13.0、模式 v0.26.0—— 完整方法论 · 指标知识库.

单项结果在整体记录中的位置: 汇总统计npm, PyPI.