Enhanced Inspector: automated install, classic fallback, and GT-style miller columns (#39)#137
Merged
Merged
Conversation
Add server-side install of the enhanced inspector support and offer it automatically when connecting to a stone that lacks it. - enhancedInspectorInstall.ts: file the .gs payload in server-side via GsFileIn (one call per file, dependency order), commit once, verify. - enhancedInspectorCommand.ts: Command Palette install over a transient SystemUser session, plus maybeOfferEnhancedInspectorInstall driven by the new gemstone.enhancedInspector.autoInstall tri-state (ask|always|never); the modal's buttons set the setting. - gtAvailability.ts: shared refreshGtAvailable() latch used at login and after an install refresh. - Post-install refresh is silent when the session has no pending work, and prompts (or when the probe can't tell) before discarding uncommitted work; aborts tolerate a session logged out mid-install. - docs/gtSupport: retarget the payload to the Published dictionary, add per-file attribution headers, and an idempotent apply_jasper_transforms.sh wired into update_gemstone_gt_support.sh. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Packaging (ship blocker): move the 7 payload .gs files from docs/gtSupport/ to resources/enhancedInspector/ so they bundle into the VSIX (docs/** is .vscodeignore'd). Repoint PAYLOAD_SUBDIR and the three dev scripts (which stay in docs/gtSupport/) at the new location. Discoverability: add the "GemStone: Enhanced Inspector Auto-Install…" command (configureEnhancedInspectorAutoInstall) — a QuickPick that writes the tri-state gemstone.enhancedInspector.autoInstall preference from anywhere, before login too. It confirms the choice by flashing it in place (createQuickPick), since notification toasts can be suppressed. Add a walkthrough step that links to it and teaches the Command Palette shortcut. Skip an install button / first-inspect offer: the connect-time modal already covers the install action. Robustness (code review): guard the picker against re-entry, clear the flash timer on early dismiss, and surface an error if the settings write fails. Docs: rename "GT" prose to "Enhanced Inspector" (title case) / "enhanced inspector" (in sentences); filenames unchanged. Tests: cover runInstallEnhancedInspector (no session, default-password install, password prompt success/failure/cancel), the missing-payload branch, and the auto-install picker. Full suite green (client 2334, server 320, mcp 95). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… (Stage 5) Rename the symbols, files, directories, config, commands, and comments we own from GT* to Enhanced Inspector. Leave upstream Gt*/Rsr*/STON* classes, the .gs payload filenames, and external Glamorous-Toolkit behavior references untouched. - Class GtInspector -> EnhancedInspector; gtInspector.ts, gtAvailability.ts, gtPerfTracker.ts, queries/getGtViewSpecs.ts and 11 test files renamed to enhancedInspector*. - Context key gemstone.gtAvailable -> gemstone.enhancedInspectorAvailable; webview panel viewType gemstoneSuperInspector -> gemstoneEnhancedInspector. - docs/gtSupport/ -> docs/enhancedInspectorSupport/; loader/updater scripts and the perf-tracker .st renamed. - Breaking: config key gtPerfTracking -> enhancedInspectorPerfTracking (no migration); perf commands, category, titles, output channel de-GT'd. Fix a wire-value half-rename: cellHtml compared __typeLabel against the server's 'gtPhlowRunBasedText' value, which the rename wrongly changed on the client side only, silently dropping run-based-text styling. Reverted, guarded with a do-not-rename note, and covered by a new regression test for the previously untested webview render path. The deferred "GT Inspect It"/superInspectIt command is intentionally left for the "one inspect to rule them all" work. Unit suite green (client 2337, server 320, mcp 95). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fallback Collapse "Inspect It" and "GT Inspect It" into a single "Inspect It" that routes through a shared inspectRouter.routeInspect: the Enhanced Inspector webview when the session has the support installed, else the classic Inspector tree view in the sidebar. Removes the separate gemstone.superInspectIt command, its editor-context menu entry, and the ctrl+k o keybinding. - codeExecutor: inspectIt / inspectExpression / executeAndInspect now route via routeInspect; superInspectIt / executeAndSuperInspect deleted. - debuggerPanel: the variable context menu is now "Inspect" and uses the same routeInspect (enhanced beside the debugger, tracked to close with it; else the sidebar tree via the injected DebuggerPanel.inspectorProvider). - extension: inspectGlobal only does its tree reveal/dedup when the classic inspector is in use (the webview path can't be found by findRootByLabel). - enhancedInspector: open the panel with preserveFocus so a rapid repeat Inspect It doesn't lose the active editor. - Remove the now-dead gemstone.enhancedInspectorAvailable context key (no when-clause consumers remain); routing reads the session flag directly. - Tests: unit coverage for both routing branches (editor + debugger); new on-demand GCI smoke test asserting the lightweight availability probe agrees with the deep install check, plus the classic-inspector fallback queries. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the shrinking-panels behavior (each drill spawned a new VS Code panel Beside, shrinking the others) with one webview holding N miller columns in a horizontal-scroll strip — #39's last bullet. Behavior (all settled interactively with Eric): - Drilling is additive and never replaces: a drilled row opens its own column immediately to the right of its source, pushing later columns rightward, so the parent->child lineage reads left-to-right. Siblings drilled from the same column both stay open. - Each column is independent: closing one removes only that column (not its neighbors); closing the last one disposes the whole panel. - Focus tracks the focused column and drives the panel title. - Columns have a minimum width and grow to fill spare space (a single column spans the tab, no dead space); a manual edge-drag pins a column to an exact width while the rest keep filling. Below the minimum the strip scrolls horizontally. - Pronounced editorGroup-border dividers plus a gutter between columns; a long OOP no longer pushes the close button past the header edge. Host protocol is now columnId-tagged end to end: drilling posts addColumn (with sourceColumnId) instead of creating a new panel; every fetch response echoes its columnId; setTitle/closePanel added. The column-strip model is extracted to enhancedInspectorColumns.js (injected as a <script>, not bundled — same pattern as listFilter.js/methodListView.js/debuggerView.js) so the display/business decisions are unit-testable in jsdom. Re-included in .vscodeignore since it is read at module load. Tests: enhancedInspectorColumns.test.ts (17, jsdom — insert-right order, independent close, focus->title, width inherit/pin/min-clamp); enhancedInspectorPanel.test.ts updated for the addColumn/columnId/ setTitle/closePanel protocol (31). Full unit suite 2591 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR turns the existing GT (Glamorous Toolkit) inspector into a first-class,
self-installing Enhanced Inspector feature. It automates the server-side
support that previously required a hand-run Topaz script, renames the
GT/Feenk-derived surface to a neutral "Enhanced Inspector" name (while keeping
upstream attribution), unifies inspection into a single command that gracefully
falls back to the classic tree inspector, and reworks the panel into a GT-style
miller-column layout.
Work item: #39 "Glamorous Toolkit Inspector Changes" (umbrella/epic).
What's included
enhancedInspectorCommand.ts,enhancedInspectorInstall.ts) — aGemStone: Install Enhanced Inspector Supportcommand plus an opt-in auto-install-on-connect offer, replacing theexternal
load_gemstone_gt_support.shTopaz loader.docs, and file names (
gtInspector.ts→enhancedInspector.ts,getGtViewSpecs.ts→getEnhancedInspectorViewSpecs.ts,docs/gtSupport/→docs/enhancedInspectorSupport/), with upstreamattribution preserved.
inspectRouter.ts,codeExecutor.ts) — one commandeverywhere that routes to the Enhanced Inspector when available, else the
classic
gemstoneInspectortree view. Removes the separate "GT Inspect It"command, its menu entry, and the
ctrl+k okeybinding.enhancedInspectorColumns.js,enhancedInspector.ts) — one webview with N min-width/grow columns andhorizontal scroll; drilling inserts a column additively to the right, columns
close independently, and the title tracks the focused column.
resources/enhancedInspector/*.gs)with developer scripts to refresh it from upstream
(
docs/enhancedInspectorSupport/).Commands, keybindings & settings changes
New commands
gemstone.installEnhancedInspectorgemstone.configureEnhancedInspectorAutoInstallRemoved commands
gemstone.superInspectItgemstone.inspectIt; its editor-context-menu entry andctrl+k o/cmd+k okeybinding were removed too.Renamed commands (GT → Enhanced Inspector; category
GemStone GT→GemStone)gemstone.enableGtPerfTrackinggemstone.enableEnhancedInspectorPerfTrackinggemstone.disableGtPerfTrackinggemstone.disableEnhancedInspectorPerfTrackinggemstone.resetGtPerfCountergemstone.resetEnhancedInspectorPerfCountergemstone.showGtPerfDetailsgemstone.showEnhancedInspectorPerfDetailsKeybindings
ctrl+k o/cmd+k o(was "GT Inspect It").ctrl+k i/cmd+k istill runs Inspect It — but it is nowungated. Previously the GT variant was gated on a
gemstone.gtAvailablecontext; the single Inspect It now works everywhere and decides enhanced-vs-classic
at runtime.
Settings
gemstone.gtPerfTracking→gemstone.enhancedInspectorPerfTrackingfalsegemstone.enhancedInspector.autoInstallask|always|never, defaultaskLogin / connect behavior
gemstone.enhancedInspector.autoInstall:ask(default) — offer to install; the prompt's buttons write the chosen modeback into this setting.
always— install automatically using the SystemUser default password; if thatpassword isn't accepted, a non-blocking notification explains how to install manually.
never— no offer.Inspect It opens the Enhanced Inspector or the classic tree view.
Context keys
gemstone.gtPerfTracking(menuwhenclauses) →gemstone.enhancedInspectorPerfTracking.gemstone.gtAvailableis no longer used to gate any command (the unified Inspect Itroutes at runtime instead).
Walkthrough
configuration command.
Key design decisions (for posterity)
Install model: one-time, idempotent, committed — not session/transient
A transient/session-method install was investigated and ruled out. The payload
is ~523 persistent class definitions plus ~279 kernel-class extension methods;
persistent classes cannot be session-scoped, and GemStone session methods can
only override existing selectors (never add new ones) and still require write
access to the class. So the install is a one-time, idempotent, committed
file-in, re-runnable at will (presence is not a gate).
SystemUser is required, obtained via a transient co-session
Adding the ~279 kernel-class extension methods requires write access to kernel
classes — i.e. SystemUser. The user is normally logged in as DataCurator,
so the install opens a short-lived, unregistered SystemUser session on the
same connection, files in, commits, and drops it.
swordfish) is tried first.SystemUser password; a wrong entry reports an error, cancel is a no-op.
didn't initiate it) — it degrades to "not installed" with a non-blocking hint
to run the manual command, and inspection falls back to the classic tree.
password, so a hardened stone requires re-entering it on each manual install.
Dictionary placement:
Published, notGlobals(and notUserGlobals)Vendored classes are filed into the
Publisheddictionary rather thanGlobals.Publishedis already on every current and future user's symbollist, so the classes are visible to everyone without polluting
Globals.UserGlobals(per-user) was considered and rejected: the kernel extensionmethods are compiled into shared kernel classes and reference GT's own classes
by literal name, so those references must resolve through a shared dictionary —
per-user classes would be invisible to the shared kernel methods.
Vendoring: copy upstream verbatim + two deterministic transforms
The payload is refreshed from upstream verbatim
(
update_enhanced_inspector_support.sh), then two idempotent transforms areapplied (
apply_jasper_transforms.sh):inDictionary: Globals→inDictionary: Published, andBoth transforms are re-appliable to any future upstream text, so we can always
pull the latest upstream by script.
"Minimal-subset refactor" (bullet 2 of #39): intentionally dropped
The idea of trimming the vendored code to a minimal subset (or splitting an
"ours" superclass from a "theirs" subclass) was explored and dropped. A
local structural refactor is fundamentally incompatible with the
"re-vendor upstream verbatim by script" model — any hand-edit would be
overwritten on the next refresh. The only vendoring-compatible version would be
to contribute the split upstream to Feenk, which is a large effort on a
third-party repo with uncertain acceptance; upstream marked it optional. We keep
the attribution/MIT headers (which satisfy the licensing intent) and defer any
minimal-subset work as an optional future upstream contribution.
Cosmetics
"enhanced inspector" style applies to prose/docs only).
CHANGELOG.mdhistory is left unchanged — it records what shipped under thenames live at the time.
Attribution & licensing
Each vendored
.gsfile carries an origin (GitHub URL) + MIT license header:gt4gemstone,gtoolkit-remote,gtoolkit-wireencoding,STON.gs,patch-gemstone.gs,Announcements.gs— © feenk gmbh (MIT)RemoteServiceReplication.gs— © GemTalk Systems, Inc (MIT)Testing
mainmerged in;npm run compileclean.(
gciEnhancedInspectorRouting.smoke.test.ts).enhancedInspectorColumns).