Skip to content

refactor(settings): move refresh_open_files toggle to NBI config#339

Merged
mbektas merged 1 commit into
plmbr:mainfrom
pjdoland:refactor/337-refresh-setting-nbi-config
May 22, 2026
Merged

refactor(settings): move refresh_open_files toggle to NBI config#339
mbektas merged 1 commit into
plmbr:mainfrom
pjdoland:refactor/337-refresh-setting-nbi-config

Conversation

@pjdoland
Copy link
Copy Markdown
Collaborator

Summary

Issue #337 asks that the refresh_open_files_on_disk_change setting (introduced in #330) live in NBI's own config and Settings dialog rather than JupyterLab's Settings Editor, for consistency with the other user-toggleable booleans (enable_explain_error, enable_output_followup, enable_output_toolbar). This PR relocates it.

Solution

The setting now lives in ~/.jupyter/nbi/config.json (read via NBIConfig.refresh_open_files_on_disk_change) and renders as a checkbox in a new External changes section of the NBI Settings dialog. It is wired through the standard admin-policy triad: a FEATURE_POLICY_SPEC entry, a TraitletEnum, and a NBI_REFRESH_OPEN_FILES_ON_DISK_CHANGE_POLICY env var, so deployments can pin it force-on/force-off without touching code.

Key changes:

  • notebook_intelligence/extension.py: FEATURE_POLICY_SPEC entry, new refresh_open_files_on_disk_change_policy TraitletEnum, _build_feature_policies_response user value, ConfigHandler.valid_keys + locked_keys gating.
  • notebook_intelligence/config.py: refresh_open_files_on_disk_change property (default True).
  • src/api.ts: extends FeaturePolicyName union, the featurePolicies getter, and the defaultOpen set so the watcher's boot-window read survives until capabilities land.
  • src/index.ts: the watcher's isEnabled callback now re-reads NBI capabilities every tick, so toggling in the Settings dialog applies without a Lab restart.
  • src/components/settings-panel.tsx: new "External changes" section with a CheckBoxItem that honors featurePolicies.refresh_open_files_on_disk_change.locked.
  • schema/plugin.json: removed the orphan property (the schema retains jupyter.lab.toolbars and jupyter.lab.shortcuts blocks).
  • Docs: README "Admin policies" table row and a new docs/admin-guide.md section.

Note that the prior home for this setting was only exposed in 5.0.0-alpha, so a runtime migration of stale JL Settings Registry values is not included; an alpha user who toggled it false will revert to the default true and can opt out again in the new dialog.

Testing

  • pytest tests/ --ignore=tests/test_claude_client.py -q: 1066 passed.
  • jlpm tsc --noEmit: clean.
  • jlpm lint:check: clean.
  • jlpm jest: 281 passed.
  • Three new pytest cases in tests/test_cell_output_features_response.py pin the capabilities-response shape across user-choice, force-on, and force-off.
  • Playwright verification in a local Lab session: confirmed the dialog renders the new section, the toggle round-trips to ~/.jupyter/nbi/config.json and the capabilities response, and NBI_REFRESH_OPEN_FILES_ON_DISK_CHANGE_POLICY=force-off correctly disables the checkbox and returns {enabled: false, locked: true}.

Two reviewer rounds (six agents each: three /simplify and three persona reviewers covering JL extension lifecycle, frontend a11y, and API contract). All fix-before-merge findings were applied in round 2; remaining notes are scoped as follow-ups.

Risks / follow-ups

  • The featurePolicies getter in src/api.ts allocates per call; the watcher tick reads it every 3 s. Round 2 efficiency review confirmed this is sub-microsecond and dwarfed by the watcher's own filesystem fan-out. A future pass could memoize the getter against this.capabilities identity for broader benefit, but it isn't load-bearing for this change.
  • model-config-section-header is a styled <div> rather than a semantic heading; this is pre-existing across the whole Settings dialog and out of scope here.

Screenshots

Default (unlocked, checked) and force-off (locked, disabled) attached locally at nbi-settings-external-changes.png and nbi-settings-force-off-locked.png; will drop into this description via the web UI.

Closes #337.

Relocates the open-files refresh watcher's user toggle from JupyterLab's
ISettingRegistry into NBI's own config.json + Settings dialog. Adds a new
"External changes" section to the General tab with a Refresh-on-disk-change
checkbox alongside the other NBI user preferences (explain-error,
output-followup, output-toolbar). Wires the value through the standard
admin-policy triad so deployments can pin it via
NBI_REFRESH_OPEN_FILES_ON_DISK_CHANGE_POLICY or the matching traitlet.

The watcher's isEnabled callback now reads NBIAPI.config.featurePolicies on
every tick, so a user toggle in the Settings dialog takes effect without a
Lab restart (capabilities refetch after each setConfig).

Closes plmbr#337.
@pjdoland pjdoland added the enhancement New feature or request label May 22, 2026
@mbektas mbektas merged commit c0ea8a3 into plmbr:main May 22, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move refresh_open_files_on_disk_change setting to NBI config and NBI settings dialog

2 participants