Repository navigation
fix: improve plugin ecosystem and possibilities - #219
Conversation
cd3d3d7 to
bef0ebd
Compare
bef0ebd to
9fc110f
Compare
9fc110f to
1b5dfa0
Compare
1b5dfa0 to
4871d19
Compare
4871d19 to
120a22e
Compare
120a22e to
b4f7667
Compare
Tchips46
left a comment
There was a problem hiding this comment.
Review: plugin ecosystem (b4f7667)
Line numbers are at this PR's head. Checked and fine: layout diagnostics (generation guard and dispose), stashes keyed by hash in the client, the Problems roving tabindex, template file creation (expectedHash: null, nothing overwritten), the system theme following the OS, and the SDK index snapshot. The PR body says little, so the points below are worth reading before merge.
Must fix
1. The published /ui stub can't be mocked, contrary to the README (packages/sdk/scripts/build-ui-stub.ts:29-30)
- Every export of the published
@nanoforge-dev/editor-sdk/uiis a Proxy whosegettrap returns another proxy for any key, including_isMockFunction, which vitest's automocker reads. Vitest then takes the export for a mock already and keeps it. - Reproduced with vitest 4.1.11 on a copy of the stub: after
vi.mock('./ui.js'),vi.isMockFunction(saveAsFile)isfalse, and calling the export still throws "…provided by the NanoForge editor…". The README's recipe,vi.mock('@nanoforge-dev/editor-sdk/ui'), fails for every plugin author. - Fix: delete the
gettrap and keep onlyapply/construct.
2. The IntelliJ preset blocks keyboard context menus (plugins/command-palette/nanoforge.manifest.json:97)
- It binds
Shift+F10toruntime.playwhen no game runs. Shift+F10 is the keyboard context-menu key the kit relies on (packages/ui/src/components/menu-event.ts), andKeybindingService.handlematches it on keydown in the capture phase and callspreventDefault. - With this preset, a keyboard user gets no context menu in Files, Hierarchy, Changes or Problems while the game is stopped.
- Fix: drop the binding (F5 already plays).
3. The CSV export allows formula injection (plugins/inspectors/src/export/inspector-export.ts:4)
fieldonly quotes" , \n \r. Thepayload textcolumn ofpacketsCsvis data sent by game clients, possibly other players.- Example: a chat packet
=HYPERLINK("http://…",…)runs when the developer opens the export in Excel or LibreOffice. - Fix: for string values only, prefix
'when the text starts with= + - @ \t \r(numbers such as-1stay as they are), with one test.
Should fix
4. Clear in one inspector wipes the other (plugins/inspectors/src/recorder/recorder.ts:142)
clear(source)replaces the whole record withemptyRecord()(keeping onlyworld), and the Profiler and Network panels share that record.- Example: Clear in Network also empties the Profiler's history, and the other way round. The spec only checks that the record empties.
- Fix: clear only the fields of the inspector that asks (frames for the Profiler; packets, network and untraced for Network), and test that the other fields survive.
5. The asset field no longer accepts typed paths (plugins/ecs/src/widgets/inspector/ParamField.svelte:57, 131)
- Once the app has any asset of an accepted type, an
@assetparam uses the kitCombobox, which only commits a listed item (oninputonly filters). - Example: a URL, an asset of a shared library or a file not added yet can't be entered, and the field can't be cleared. The list comes from
project.fs.entries, which Svelte does not track, so a png dropped intoassets/while the Inspector is open never shows up. - Fix: keep the
Inputand offer the paths through a<datalist>, refreshed fromproject.fs.onDidChange.
6. The IntelliJ preset binds Mod+K as a single stroke (plugins/command-palette/nanoforge.manifest.json:81)
- CLAUDE.md forbids single-stroke chord starters:
handle()runs an exact match at once, so every chord starting withMod+K(the user's own, Monaco'sCtrl+K Ctrl+C) becomes unreachable, with no conflict shown. - The new CLAUDE.md rule (no Alt+1…9 "even in a preset",
CLAUDE.md:212-213) also contradicts this preset, which binds Alt+1/4/6/9. - Fix: make it a chord or drop it, and align the rules with the preset one way or the other.
7. Two quick Shift+clicks open the palette (packages/ui/src/workbench/keybinding/keybinding-service.ts:107-118, 150-180)
_heldand_tapare reset only by the keydown of a non-modifier key.- Example: with the IntelliJ preset, Shift+click a row, then Shift+click another within 500 ms (range select in Files or Hierarchy). The second Shift release counts as a double tap and the palette opens over the selection.
- Fix: in
attach, also listen topointerdown(capture) andblur, and clear_heldand_tapon both.
8. Mod Mod, Ctrl Ctrl, Cmd Cmd never fire (packages/ui/src/workbench/keybinding/keystroke.ts:37-54)
- A bare modifier stroke goes through
normalizeKey, which only capitalises it:parseKeybinding('Mod Mod')gives['Mod', 'Mod'], whilehandleKeyUpcompares withCtrl/Meta/Alt. OnlyShift Shiftworks, and the others fail silently. - Fix: in
normalizeStroke, map a lone modifier name with the same table the modifier loop uses.
9. The SDK and the vite-plugin are published to npm on every merge (packages/sdk/package.json, tooling/vite-plugin/package.json:72, .github/workflows/release.yml:86-133)
private: trueis dropped, and the beta matrix publishes a public@nanoforge-dev/editor-sdk@0.0.0-beta.Nfor every merged PR touchingpackages/. CLAUDE.md says nothing is published until the owner decides.0.0.0-betaversions also don't satisfyexamples/counter-plugin's^1.0.0.- Fix: needs an explicit go-ahead before merge, or betas wait for the first SDK release.
Nice to have
release-single-package(release.yml:56-76) accepts anyreleases/<x>@…branch: a misnamed branch runs a release job with publish secrets on a private or nonexistent package. Fix: an allowlist (contains(fromJSON('["editor-sdk","editor-vite-plugin"]'), …)).- Stash lookup by prefix (
packages/server-core/src/git/git-service.ts:388-393):startsWith(hash)with a short hash drops the first stash sharing the prefix. The client always sends the full hash. Fix:===. - Entity actions (
plugins/ecs/src/widgets/hierarchy/entity-action-entries.ts:42):void run(...)turns a missing command or a throwing handler into an unhandled rejection: no message for the user, and the e2e fixture fails on it. Fix:.catchand report through notifications. - "Remove anyway" (
plugins/scene/src/widgets/vars/Vars.svelte:126) adds a sticky notification per Remove, and an old one can still remove the var later. Fix: a confirm dialog, like git'sConfirmDialog. - Git log (
plugins/git/src/widgets/log/LogView.svelte:28): the effect reads$git.logBranch, so it reruns and saves the layout state on every git refresh. Fix:const branch = $derived($git.logBranch)and readbranchin the effect. - Loading screen (
apps/editor/src/routes/+layout.svelte:14-15) has dark fallbacks; withsystemas the new default, light-mode users see a dark flash. Fix: aprefers-color-scheme: lightblock. - Alt shortcuts and keyboard layouts: strokes use
event.key, so on macOS Option+1 gives¡(the preset's Alt+1/4/6/9/0 never fire), and on AZERTY/QWERTZ under Windows or Linux Ctrl+Alt is AltGr, so the console'sMod+Alt+Egives€. Fix: fall back toevent.codefor strokes holding Alt. (Known browser behaviour, not observed.)
Not checked: nothing was run; I didn't build or pack the SDK (svelte2tsx emitDts, what dist/index.js inlines).
- sdk: the ui stub has no get trap, so vi.mock automocks it - command-palette: the IntelliJ preset drops Shift+F10 and Alt+1/4/6/9 (kept by browsers); its description and the docs follow - inspectors: csv export defuses text read as a formula; clearing an inspector keeps the other's data - ecs: asset params are a free text input with a datalist, refreshed when project files change - ui: a click or the window losing focus breaks a double tap; a lone Mod or Cmd stroke is a modifier - git: the log view's effect reads the branch only Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
b4f7667 to
42bab22
Compare
|
Thanks for the review. Addressed in 42bab22 ( Fixed
Not changed
Checked at the top of the stack: lint, typecheck and unit tests pass, and e2e passed 109/109, including the updated |
What does this PR do?
improve plugin ecosystem
How do you test this PR?