Skip to content

fix(editor,kite3d): Resources headers match the panel, and the CLI keeps its execute bit - #44

Closed
pythonlearner1025 wants to merge 1 commit into
mainfrom
fix/resources-header-cli-bit
Closed

pythonlearner1025 wants to merge 1 commit into
mainfrom
fix/resources-header-cli-bit

Conversation

@pythonlearner1025

Copy link
Copy Markdown
Member

What part this touches

Two small things, one in the editor and one in the CLI package.

The editor's left panel holds two tabs, Objects and Resources. The Resources tab draws three
sections: Materials, Textures and Geometries. Each section has a header row you click to open or
close it. The header sticks to the top of the panel while you scroll the list under it. Its styles
live in packages/editor/src/renderer.scss at .resources-section-header. The markup lives in
packages/editor/src/components/BPResourcesTreeComponent.tsx.

The second thing is the kite3d package build. packages/kite3d/package.json builds dist/cli.js
with tsc. That file is the kite3d command. A project that lists the package as a path
dependency gets a symlink at node_modules/.bin/kite3d pointing straight at it.

The bug

Two separate faults.

One, the headers read as selected. In the dark theme the three headers drew a light grey band
across the panel. Nothing was selected. The owner's words: "the colors are inverted - selected
should show light gray, not de-selected."

The rule was background: var(--pt-app-background-color). That variable is rgb(47, 52, 60) in
the dark theme. The panel behind it is rgb(28, 33, 38), which the editor defines itself as
--main-app-background and paints on .editorSplitContainer. So the header was two shades lighter
than the panel it sat on.

The hover rule was dead too. It named --pt-minimal-button-background-color-hover. No stylesheet
defines that name. Blueprint's variable is --minimal-button-background-color-hover, with no pt.
An undefined custom property makes the whole background shorthand invalid, so hover fell back to
transparent. I measured it in the browser: hover computed to rgba(0, 0, 0, 0). The screenshot
before-left-panel-hover.png shows the result. The hovered header went dark and the two headers
next to it stayed light grey.

Two, the CLI loses its execute bit. tsc writes dist/cli.js with mode 644. npm install
does set the bit, once, on the file the bin link resolves to. The failure comes after that. A
rebuild of this repo deletes dist and writes a fresh 644 file. The bin link in the linked project
still points at it. The next command fails:

sh: /private/tmp/.../linkcheck/node_modules/.bin/kite3d: Permission denied
exit 126

That is the loop the terminator project hits: install once, rebuild the editor, run
npx kite3d dev, get permission denied, run chmod +x, repeat.

The fix

  • .resources-section-header draws on var(--main-app-background), the variable the left panel
    already draws on, so the two can never drift apart.
  • .resources-section-header:hover draws on var(--pt-app-background-color), which is opaque and
    one step lighter than the panel. A translucent hover would let scrolled rows show through the
    sticky header.
  • Two short comments say why each colour is what it is.
  • packages/kite3d/package.json build script appends
    node -e "require('fs').chmodSync('dist/cli.js', 0o755)" after tsc.
  • One test, packages/kite3d/test/cli-bin.test.ts, asserts dist/cli.js has the execute bit.

Nothing else changed. No TypeScript, no new file in scripts/, no lockfile change.

The risk trade

The header no longer stands out from the rows. That is the point of the change, but it costs some
separation on a long list. The caret, the uppercase bold title and the count badge still mark a
header, and the hover lift marks it as clickable. The screenshots show it reads fine.

I changed the hover colour, which the brief asked me to keep. I kept the hover, not the broken
variable. The old rule painted nothing. Left alone, the header would have had no hover feedback at
all once the base matched the panel. The colour I chose blends to within 3 per channel of what a
Blueprint tree row shows on hover, and it is opaque, so the sticky header keeps hiding the rows
under it.

The rejected alternative for the hover was the real Blueprint variable,
--minimal-button-background-color-hover. It is hsla(216, 13%, 61%, .15), 15 percent opaque.
On a sticky header that would let scrolled rows bleed through while the pointer is on it.

For the CLI, the rejected alternative was a script file under scripts/. A one-line node -e in
the build script needs no new file and runs on every platform. fs.chmodSync does not throw on
Windows, it just cannot set an execute bit there, which matches how Windows runs the .cmd
shim instead.

Tests

All runs are headless Google Chrome 153.0.8010.48, viewport 1512 by 982, device pixel ratio 2, a
fresh profile each run. Nothing took focus. The server ran with CI=1 and --no-open. I never ran
kite3d install.

cd /Users/minjunes/games/terminator-next && CI=1 node \
  /Users/minjunes/kite3d-worktrees/resources-header/packages/kite3d/dist/cli.js dev --port 4472 --no-open

I confirmed both times that the served editor was my build. I fetched each bundle from the server
and matched its sha256 against packages/editor/dist/assets. All three matched in both runs:
served-is-my-build-before.txt (index-BrtAewVw.css) and served-is-my-build-after.txt
(index-nlFnOqG8.css). The measure script also reads the served rule back. Before it returned
background: var(--pt-app-background-color), after it returned background: var(--main-app-background).

The colours I read, dark theme, all three sections collapsed

what before after
header background rgb(47, 52, 60) rgb(28, 33, 38)
panel background rgb(28, 33, 38) rgb(28, 33, 38)
header on hover rgba(0, 0, 0, 0) rgb(47, 52, 60)
selected row rgb(45, 114, 210) rgb(45, 114, 210)

All three headers read the same value in both runs.

One correction to the report. A selected resource row is Blueprint blue, rgb(45, 114, 210), not
light grey. The grey the owner saw was the header's own background. A hovered row blends to about
rgb(45, 51, 57), which is close to the old header colour, so the headers looked permanently
hovered or selected. Selection is unchanged by this PR.

Screenshots I looked at

  • /private/tmp/claude-501/-Users-minjunes-blitz/278f5f97-7e16-4722-b1bc-c061014966db/scratchpad/evidence/resources-header/shots/before-left-panel-collapsed.png
  • /private/tmp/claude-501/-Users-minjunes-blitz/278f5f97-7e16-4722-b1bc-c061014966db/scratchpad/evidence/resources-header/shots/after-left-panel-collapsed.png
  • /private/tmp/claude-501/-Users-minjunes-blitz/278f5f97-7e16-4722-b1bc-c061014966db/scratchpad/evidence/resources-header/shots/before-left-panel-hover.png
  • /private/tmp/claude-501/-Users-minjunes-blitz/278f5f97-7e16-4722-b1bc-c061014966db/scratchpad/evidence/resources-header/shots/after-left-panel-hover.png
  • /private/tmp/claude-501/-Users-minjunes-blitz/278f5f97-7e16-4722-b1bc-c061014966db/scratchpad/evidence/resources-header/shots/after-left-panel-selected.png
  • /private/tmp/claude-501/-Users-minjunes-blitz/278f5f97-7e16-4722-b1bc-c061014966db/scratchpad/evidence/resources-header/shots/after-left-panel-scrolled.png
  • /private/tmp/claude-501/-Users-minjunes-blitz/278f5f97-7e16-4722-b1bc-c061014966db/scratchpad/evidence/resources-header/edge-shots/after-light-bpx-default.png

Before: the three headers are one light grey band. After: they sit on the panel colour and only
the caret, the title and the count differ. Hovering one header lifts only that header. With
Materials open and the first material clicked, the row is blue and the header is not.

The sticky header

I scrolled the open Materials list to scrollTop 220 of 4044. document.elementFromPoint on the
middle of the header returned the header, its opacity was 1, and its background was
rgb(28, 33, 38). No row shows through. See after-left-panel-scrolled.png.

The edges

edges.mjs walked six combinations: dark and light, times the bpx-default, bpx-flat and
bpx-carbon Blueprint styler themes the settings menu offers. The header equalled the panel in all
six, and every hover colour was opaque and different from the panel.

dark  bpx-default  header rgb(28, 33, 38)    panel rgb(28, 33, 38)    match true hover rgb(47, 52, 60)
dark  bpx-flat     header rgb(26, 26, 26)    panel rgb(26, 26, 26)    match true hover rgb(54, 54, 54)
dark  bpx-carbon   header rgb(23, 23, 23)    panel rgb(23, 23, 23)    match true hover rgb(33, 33, 33)
light bpx-default  header rgb(237, 239, 242) panel rgb(237, 239, 242) match true hover rgb(246, 247, 249)
light bpx-flat     header rgb(240, 240, 240) panel rgb(240, 240, 240) match true hover rgb(247, 247, 247)
light bpx-carbon   header rgb(217, 217, 217) panel rgb(217, 217, 217) match true hover rgb(242, 242, 242)

Zero page errors in every run.

The execute bit

In a throwaway project whose only dependency is
"kite3d": "file:/Users/minjunes/kite3d-worktrees/resources-header/packages/kite3d":

Failing, on a build made with the old script:

$ ls -l packages/kite3d/dist/cli.js
-rw-r--r--  1 minjunes  staff  10361 Sep 16 16:27 dist/cli.js
$ npx kite3d --help
sh: .../linkcheck/node_modules/.bin/kite3d: Permission denied
exit 126

Passing, after npm run build -w packages/kite3d with the new script, with no chmod and no
reinstall:

$ ls -l packages/kite3d/dist/cli.js
-rwxr-xr-x  1 minjunes  staff  10361 Sep 16 16:27 dist/cli.js
$ npx kite3d --help
Kite3D 0.21.0-alpha.4 builds browser 3D games with an agent and a local editor.
exit 0

I also packed the package and read the tar entry, so the published tarball carries the bit:

$ tar -tvf kite3d-0.21.0-alpha.4.tgz | grep dist/cli.js
-rwxr-xr-x  0 0 0 10361 package/dist/cli.js

Suites

  • npm run typecheck, exit 0.
  • npm run lint, exit 0.
  • npm test -w packages/kite3d, 5 files, 8 tests, all pass. It was 4 files and 7 tests before.
  • npm run test:scripts, 2 tests, both pass.

What fails without the fix: I ran the old build line verbatim,
rimraf dist && tsc -p tsconfig.build.json, then npm test -w packages/kite3d. The new test
failed, 1 failed and 7 passed, exit 1, on expect(mode & 0o111).toBe(0o111). I rebuilt with the
new script and it passed again.

There is no test for the colour. packages/editor has no test setup, so a CSS test would mean a
new harness for one assertion. The headless run with the measured colours is the proof.

Deploy

The editor bundle ships in the next kite3d npm release, and the build script change ships with
the same release. The release runs npm run build then publishes, so dist/cli.js gets the bit on
the release machine.

npm run release:patch

Rollback: publish the previous version again, or npm dist-tag add kite3d@0.21.0-alpha.4 latest.
A user on a broken build can also run chmod +x node_modules/kite3d/dist/cli.js, which is what the
change removes the need for.

The five questions

  1. Did I run it? Yes. Headless Chrome against a real project on port 4472, before and after, plus
    the linked-project CLI runs above.
  2. Do the types tell the truth? Yes. No TypeScript changed. The one new test reads a file mode and
    asserts on it.
  3. Is the naming honest? Yes. The header now names the variable the panel uses. The old rule named
    a variable that does not exist.
  4. Did I test the edges? Yes. Six theme combinations, the scrolled sticky header, a selected row,
    hover, light mode, and a rebuild after install for the CLI.
  5. Would I walk a colleague through it? Yes. Two declarations and one build step.

Anti-slop pass

I read my own diff against S1 to S10. I deleted the dead variable reference, which was S10, a patch
on a bad premise. I wrote no helper, no options object and no fallback. The comments say why, not
what. rg "pt-minimal-button-background-color-hover" outside node_modules and dist returns no
hits.

…eps its execute bit

The Resources tab's three section headers drew on var(--pt-app-background-color). In the dark
theme that colour is lighter than the panel, so a collapsed header read as a selected row. The
headers now draw on var(--main-app-background), the same variable the left panel draws on, so a
collapsed header looks like any other row. Their hover rule named
--pt-minimal-button-background-color-hover, which no stylesheet defines, so hover painted nothing.
Hover now uses var(--pt-app-background-color): opaque, one step lighter, the lift a tree row
shows.

tsc writes dist/cli.js without the execute bit. A project that links the package by path keeps its
bin symlink across rebuilds, so the next npx kite3d dev failed with "Permission denied" (exit 126)
until someone ran chmod +x. The build script now chmods dist/cli.js to 755 after tsc.

Proof: headless Chrome 153 on the terminator-next project, port 4472, CI=1, --no-open. Header and
panel both read rgb(28, 33, 38) after the fix; the header read rgb(47, 52, 60) before it. Six
theme combinations match. The sticky header stays opaque over scrolled rows. npm run typecheck,
npm run lint, npm test -w packages/kite3d (5 files, 8 tests) and npm run test:scripts (2 tests)
all pass. The new test fails on a build made with the old script.
@pythonlearner1025
pythonlearner1025 deleted the fix/resources-header-cli-bit branch September 16, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant