Skip to content

fix: improve plugin ecosystem and possibilities - #219

Merged
Exeloo merged 2 commits into
test/improve-testsfrom
fix/improve-plugin-ecosysteme
Nov 5, 2026
Merged

Exeloo merged 2 commits into
test/improve-testsfrom
fix/improve-plugin-ecosysteme

Conversation

@Exeloo

@Exeloo Exeloo commented Oct 30, 2026

Copy link
Copy Markdown
Member

What does this PR do?

improve plugin ecosystem

How do you test this PR?

@Exeloo
Exeloo requested a review from Tchips46 as a code owner October 30, 2026 14:12
@github-actions github-actions Bot added documentation Improvements or additions to documentation apps:editor Related to Editor app labels Oct 30, 2026
@Exeloo
Exeloo added this pull request to stack #212 October 30, 2026 14:12
@github-actions github-actions Bot added packages:protocol Related to Protocol package packages:sdk Related to SDK package packages:server-core Related to Server core package packages:settings Related to Settings package packages:ui Related to UI package plugins:code-editor Related to Code editor plugin plugins:command-palette Related to Command palette plugin plugins:console Related to Console plugin plugins:ecs Related to ECS plugin plugins:file-manager Related to File manager plugin plugins:git Related to Git plugin plugins:inspectors Related to Inspectors plugin plugins:scene Related to Scene plugin plugins:settings-ui Related to Settings ui plugin tooling:example-plugin Related to Example plugin tooling tooling:vite-plugin Related to Vite plugin tooling labels Oct 30, 2026
@Exeloo
Exeloo force-pushed the fix/improve-plugin-ecosysteme branch from cd3d3d7 to bef0ebd Compare November 1, 2026 13:21
@Exeloo
Exeloo force-pushed the fix/improve-plugin-ecosysteme branch from bef0ebd to 9fc110f Compare November 1, 2026 14:27
@Exeloo
Exeloo force-pushed the fix/improve-plugin-ecosysteme branch from 9fc110f to 1b5dfa0 Compare November 1, 2026 14:52
@Exeloo
Exeloo force-pushed the fix/improve-plugin-ecosysteme branch from 1b5dfa0 to 4871d19 Compare November 1, 2026 15:39
@Exeloo
Exeloo force-pushed the fix/improve-plugin-ecosysteme branch from 4871d19 to 120a22e Compare November 5, 2026 11:41
@Exeloo
Exeloo force-pushed the fix/improve-plugin-ecosysteme branch from 120a22e to b4f7667 Compare November 5, 2026 11:55

@Tchips46 Tchips46 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/ui is a Proxy whose get trap 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) is false, 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 get trap and keep only apply / construct.

2. The IntelliJ preset blocks keyboard context menus (plugins/command-palette/nanoforge.manifest.json:97)

  • It binds Shift+F10 to runtime.play when no game runs. Shift+F10 is the keyboard context-menu key the kit relies on (packages/ui/src/components/menu-event.ts), and KeybindingService.handle matches it on keydown in the capture phase and calls preventDefault.
  • 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)

  • field only quotes " , \n \r. The payload text column of packetsCsv is 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 -1 stay 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 with emptyRecord() (keeping only world), 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 @asset param uses the kit Combobox, which only commits a listed item (oninput only 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 into assets/ while the Inspector is open never shows up.
  • Fix: keep the Input and offer the paths through a <datalist>, refreshed from project.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 with Mod+K (the user's own, Monaco's Ctrl+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)

  • _held and _tap are 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 to pointerdown (capture) and blur, and clear _held and _tap on 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'], while handleKeyUp compares with Ctrl / Meta / Alt. Only Shift Shift works, 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: true is dropped, and the beta matrix publishes a public @nanoforge-dev/editor-sdk@0.0.0-beta.N for every merged PR touching packages/. CLAUDE.md says nothing is published until the owner decides.
  • 0.0.0-beta versions also don't satisfy examples/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 any releases/<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: .catch and 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's ConfirmDialog.
  • 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 read branch in the effect.
  • Loading screen (apps/editor/src/routes/+layout.svelte:14-15) has dark fallbacks; with system as the new default, light-mode users see a dark flash. Fix: a prefers-color-scheme: light block.
  • 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's Mod+Alt+E gives €. Fix: fall back to event.code for 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).

Exeloo and others added 2 commits November 5, 2026 15:24
- 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>
@Exeloo
Exeloo force-pushed the fix/improve-plugin-ecosysteme branch from b4f7667 to 42bab22 Compare November 5, 2026 14:47
@Exeloo

Exeloo commented Nov 5, 2026

Copy link
Copy Markdown
Member Author

Thanks for the review. Addressed in 42bab22 (fix: address the plugin ecosystem review).

Fixed

  • 1. The get trap is gone from the /ui stub. I reproduced the automock failure with vitest 4.1.11 before fixing it.
  • 2. Shift+F10 → Play is removed from the IntelliJ preset.
  • 3. Strings starting with = + - @ \t \r get a leading ' (numbers are untouched), with a test.
  • 4. clear(source, inspector) clears only the frames (Profiler) or the packets, network and untraced (Network). A test checks that the other inspector's data survives.
  • 5. The field is back to Input with a <datalist>, so free text works and it can be cleared. The list refreshes through a revision bumped by project.fs.onDidChange.
  • 6. Alt+1/4/6/9 are removed from the preset, which now matches CLAUDE.md; the preset description and settings.mdx are updated. Mod+K stays: it is IntelliJ's commit key, in an opt-in preset. User chords starting with Mod+K are shown as conflicts (bindingsConflict checks prefixes), so they don't fail silently. It does hide Monaco's Ctrl+K chords while the preset is on.
  • 7. Capture-phase pointerdown and window blur clear _held/_tap, with a test (tap, click, tap fires nothing).
  • 8. One modifierOf() table now serves the modifier loop and lone modifier strokes: Mod Mod, Cmd Cmd, Control Control and Option Option work, with a test. (Ctrl Ctrl already worked.)
  • Git log: the effect reads a $derived branch instead of $git.

Not changed

  • 9. This is intentional: per-package betas on merge are the release setup we chose, and the SDK 1.0.0 release comes before the next editor release. The ^1.0.0 in counter-plugin is expected until then.
  • Nice to have (release allowlist, stash ===, entity action .catch, "Remove anyway", loading screen in light mode, Alt and event.code): left for a follow-up. They are small or theoretical (the client always sends the full stash hash, and only maintainers create release branches).

Checked at the top of the stack: lint, typecheck and unit tests pass, and e2e passed 109/109, including the updated command-palette and ecs specs.

@Exeloo
Exeloo merged commit c40f831 into main Nov 5, 2026
6 checks passed
@Exeloo
Exeloo deleted the fix/improve-plugin-ecosysteme branch November 5, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apps:editor Related to Editor app documentation Improvements or additions to documentation packages:protocol Related to Protocol package packages:sdk Related to SDK package packages:server-core Related to Server core package packages:settings Related to Settings package packages:ui Related to UI package plugins:code-editor Related to Code editor plugin plugins:command-palette Related to Command palette plugin plugins:console Related to Console plugin plugins:ecs Related to ECS plugin plugins:file-manager Related to File manager plugin plugins:git Related to Git plugin plugins:inspectors Related to Inspectors plugin plugins:scene Related to Scene plugin plugins:settings-ui Related to Settings ui plugin tooling:example-plugin Related to Example plugin tooling tooling:vite-plugin Related to Vite plugin tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants