Repository navigation
Conversation
Tchips46
left a comment
There was a problem hiding this comment.
Review: project adoption (87432eb) and plugin themes (1504f82)
Line numbers are at the commit named in each section.
Must fix
1. CI fails: pnpm-lock.yaml has no entry for tooling/example-theme (1504f82)
pnpm install --frozen-lockfilestops withERR_PNPM_PACKAGE_MANAGER_NO_IMPORTER(seen in this PR's failed CI runs), so every job fails.- Fix:
pnpm install --lockfile-onlyand commit the lockfile.
2. Workspace operations overwrite and save unsaved edits (87432eb, apps/editor/src/lib/workspace/workspace-actions.ts:309-316)
- For an open document,
writereplaces the whole buffer withtext, then saves. But operations buildtextfrom disk:editor-library.ts:39andlibrary-config.ts:75callio.read. - Example:
main.tsis open with unsaved edits, and the user clicks "Add the editor library" (the notification fromfollow-project-runtime.ts:208). The buffer becomes the disk text plus the library lines, and it is saved, so the edits are gone. The same happens with "Used by" (setUseonnanoforge.config.ts) and app renames. Only Ctrl+Z in that tab brings them back. - Fix: in
write, throwWorkspaceError('<path> has unsaved changes: save it first', [path])whendocuments.dirtyUrishas the path.Changes.runrolls back, and AdoptionService's own check (adoption-service.ts:125-132) can go.
3. The adoption rewrites produce broken code (87432eb)
- Registry rename by text (
plugins/scene/src/worker/main-to-scene.ts:217-218):text.split(`${registryText}.`).join('registry.'). Withconst r = ecs.registry,Vector.zero()becomesVectoregistry.zero(), and the same goes forplayer.,layer., and matches in strings and comments. Fix: replace only the identifiers whose symbol is the registry's, by position. - Exported helpers move without their importers (
plugins/ecs/src/worker/split-items.ts:156-168, 311): an exportedclampused only byVelocitymoves tovelocity.ts,components.tsis deleted, andsystems/move.tsstill imports it from there. Fix: addisExported(helper) ||to thecontinueat line 159. - Pruning deletes comments and side-effect imports (
split-items.ts:249-251, 266-272,main-to-scene.ts:290-296): the edit starts atgetFullStart(), so a file's header comment or a// @ts-expect-errorabove a pruned import is deleted. A file with only items andimport "./register"is deleted, and no new file carries that import. Fix: start atgetStart(), and count imports without bindings as kept.
Should fix
4. "Install for me" is offered in untrusted folders (87432eb, apps/editor/src/lib/plugin/follow-project-plugins.ts:115-165)
- The project's package manifests choose the suggested names, and
suggestruns whether or not the folder is trusted. One click installs a plugin for the user, and it then runs in every project, which goes around folder trust. - Fix: add the install actions only when the project is trusted.
5. The duplicate check treats different copies as equal, then deletes them (87432eb, plugins/ecs/src/adoption/duplicate-checks.ts:29-35, 120-131)
essencestrips all imports and all whitespace, even inside strings, and onlycopies[0]is checked for app imports. A clientVector2from graphics-2d and a serverVector2from./math/vector2compare equal, so the server copy is deleted and the server uses the client's library."Big ball"equals"Bigball".- Fix: keep imports in the comparison, collapse whitespace to one space, and check every copy.
6. Moving items out of main makes the new files import main (87432eb, split-items.ts:197-217, also main-to-scene.ts:178-186)
- A moved system that uses
export const layerfrommain.tsgetsimport { layer } from "../main", whilemainimports it: a cycle thatecs-checks.ts:97-105then flags. A movedconst HALF = WIDTH / 2readingWIDTHfrommaincan throw a ReferenceError at start (plausible). - Fix: for the entry file, throw a
CodeErrornaming each binding it would import back.
7. /* in a theme value comments out the rest of the sheet (1504f82, packages/ui/src/theme/theme-contribution.ts:17)
UNSAFElets/*through, so"bg": "#000 /*"drops every later declaration, includingSHARED_TOKENS(z-order, spacing, control height).- Fix: add
\/\*(not a bare/, whichrgb(0 0 0 / 50%)needs), and add the case to the test.
8. A plugin can replace the default theme, and the panel shows duplicate cards (1504f82, theme-contribution.ts:72, 99-101, AppearancePanel.svelte:56)
byIdkeeps the last contribution. A plugin theme withid: "nanoforge-dark"replaces the default for everyone on it, the panel shows two cards (and Svelte's keyed each throws in dev), and_checkchecks contrast on core's copy, not the plugin's.- Fix: in
resolveThemes, keep the first contribution of each id and report the rest. Same forICON_THEMES.
9. parseColor returns black for var() values (1504f82, packages/ui/src/theme/theme-colors.ts:19-25, used by plugins/code-editor/src/monaco/monaco-theme.ts:13-16; plausible)
CSS.supports('color', 'var(--x)')is true, but the canvas ignoresfillStyle = 'var(…)'and keeps#000. A theme with"surface": "var(--nf-color-bg)"renders fine, but Monaco gets a black background and the contrast warnings are computed against black.- Fix: return
undefinedwhen the value containsvar(.
Nice to have
- Theme fallback is untested (
packages/ui/test/style.svelte.spec.ts:47-60,icon-theme.svelte.spec.ts:56-79): no test disposes the selected theme's contribution, which is what happens when a plugin is uninstalled or a project closes. entrytypos are now accepted (packages/kernel/src/plugin/plugin-manifest.ts:51-57):"entry": { "clinet": "index.js" }parses to{}, and the plugin shows as active and does nothing. Usez.strictObject.- "Get more themes" sticks (
plugins/settings-ui/src/dialogs/settings/SettingsDialog.svelte:126, 288-291):marketQueryis never reset, so Plugins reopens on Marketplace withkeywords:theme. Reset it when leaving the page. - Shared library name (
duplicate-checks.ts:111): a root named@acme/ponggives@-acme-pong/shared. Reuse the root's scope, and runnameTaken. - Scene package version (
plugins/scene/src/adoption/scene-check.ts:26): copying core's spec gives@nanoforge-dev/scenealink:../engine/packages/corepath. Use'*'when it isn't a semver range. - Lean:
split-items.ts:24copiesprojectPathfromplugins/ecs/src/worker/refactor.ts:6, andmain-to-scene.ts:27redefines the oneplugins/scene/src/worker/scenes.ts:28exports.bindingsOf,importLine(s),BindingandapplyEditsare near-copies between the two files, both over 300 lines (339 and 351).registerIconFiles,ICON_THEMESandThemeContribution(packages/sdk/src/ui.ts:87-96) andresolveIconhave no users, andregisterIconFilesskips theiconFileUrlcheck. Drop them before they become public API.
1504f82 to
c9c7d28
Compare
c9c7d28 to
3378257
Compare
- lockfile: add tooling/example-theme - workspace operations refuse documents with unsaved changes - install actions for suggested plugins only in trusted folders - main to scene: no text rename of the registry, comments kept, entities using what main exports are refused - split items: exported helpers stay, header comments and side-effect imports kept, items moved out of the entry never import it back - duplicate check compares every copy with its imports - shared library takes the project's scope and a free name - scene dependency follows the project's own spec - themes: values that run into the next one are refused, the first theme of an id wins, colors the canvas cannot draw are not read - plugin manifest: unknown entry keys are refused - sdk: drop unused ui exports, export nameTaken - adoption helpers split into their own files
3378257 to
7444d9f
Compare
What does this PR do?
Add a project adaptator to import non editor projects
How do you test this PR?