Skip to content

feat: add project adaptator to import non editor projects - #217

Open
Exeloo wants to merge 3 commits into
feat/add-tutorialfrom
feat/add-project-compatibility
Open

Exeloo wants to merge 3 commits into
feat/add-tutorialfrom
feat/add-project-compatibility

Conversation

@Exeloo

@Exeloo Exeloo commented Oct 30, 2026

Copy link
Copy Markdown
Member

What does this PR do?

Add a project adaptator to import non editor projects

How do you test this PR?

@Exeloo
Exeloo requested a review from Tchips46 as a code owner October 30, 2026 10:03
@github-actions github-actions Bot added documentation Improvements or additions to documentation apps:editor Related to Editor app packages:project Related to Project package 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:ecs Related to ECS plugin plugins:scene Related to Scene plugin labels Oct 30, 2026
@Exeloo
Exeloo added this pull request to stack #212 October 30, 2026 10:04
@github-actions github-actions Bot added packages:kernel Related to Kernel package packages:registry Related to Registry package plugins:file-manager Related to File manager plugin plugins:settings-ui Related to Settings ui plugin labels Oct 30, 2026

@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: 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-lockfile stops with ERR_PNPM_PACKAGE_MANAGER_NO_IMPORTER (seen in this PR's failed CI runs), so every job fails.
  • Fix: pnpm install --lockfile-only and 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, write replaces the whole buffer with text, then saves. But operations build text from disk: editor-library.ts:39 and library-config.ts:75 call io.read.
  • Example: main.ts is open with unsaved edits, and the user clicks "Add the editor library" (the notification from follow-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" (setUse on nanoforge.config.ts) and app renames. Only Ctrl+Z in that tab brings them back.
  • Fix: in write, throw WorkspaceError('<path> has unsaved changes: save it first', [path]) when documents.dirtyUris has the path. Changes.run rolls 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.'). With const r = ecs.registry, Vector.zero() becomes Vectoregistry.zero(), and the same goes for player., 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 exported clamp used only by Velocity moves to velocity.ts, components.ts is deleted, and systems/move.ts still imports it from there. Fix: add isExported(helper) || to the continue at 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 at getFullStart(), so a file's header comment or a // @ts-expect-error above a pruned import is deleted. A file with only items and import "./register" is deleted, and no new file carries that import. Fix: start at getStart(), 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 suggest runs 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)

  • essence strips all imports and all whitespace, even inside strings, and only copies[0] is checked for app imports. A client Vector2 from graphics-2d and a server Vector2 from ./math/vector2 compare 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 layer from main.ts gets import { layer } from "../main", while main imports it: a cycle that ecs-checks.ts:97-105 then flags. A moved const HALF = WIDTH / 2 reading WIDTH from main can throw a ReferenceError at start (plausible).
  • Fix: for the entry file, throw a CodeError naming 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)

  • UNSAFE lets /* through, so "bg": "#000 /*" drops every later declaration, including SHARED_TOKENS (z-order, spacing, control height).
  • Fix: add \/\* (not a bare /, which rgb(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)

  • byId keeps the last contribution. A plugin theme with id: "nanoforge-dark" replaces the default for everyone on it, the panel shows two cards (and Svelte's keyed each throws in dev), and _check checks contrast on core's copy, not the plugin's.
  • Fix: in resolveThemes, keep the first contribution of each id and report the rest. Same for ICON_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 ignores fillStyle = '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 undefined when the value contains var(.

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.
  • entry typos 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. Use z.strictObject.
  • "Get more themes" sticks (plugins/settings-ui/src/dialogs/settings/SettingsDialog.svelte:126, 288-291): marketQuery is never reset, so Plugins reopens on Marketplace with keywords:theme. Reset it when leaving the page.
  • Shared library name (duplicate-checks.ts:111): a root named @acme/pong gives @-acme-pong/shared. Reuse the root's scope, and run nameTaken.
  • Scene package version (plugins/scene/src/adoption/scene-check.ts:26): copying core's spec gives @nanoforge-dev/scene a link:../engine/packages/core path. Use '*' when it isn't a semver range.
  • Lean:
    • split-items.ts:24 copies projectPath from plugins/ecs/src/worker/refactor.ts:6, and main-to-scene.ts:27 redefines the one plugins/scene/src/worker/scenes.ts:28 exports.
    • bindingsOf, importLine(s), Binding and applyEdits are near-copies between the two files, both over 300 lines (339 and 351).
    • registerIconFiles, ICON_THEMES and ThemeContribution (packages/sdk/src/ui.ts:87-96) and resolveIcon have no users, and registerIconFiles skips the iconFileUrl check. Drop them before they become public API.

@Exeloo
Exeloo force-pushed the feat/add-project-compatibility branch from 1504f82 to c9c7d28 Compare November 1, 2026 13:21
@Exeloo
Exeloo force-pushed the feat/add-project-compatibility branch from c9c7d28 to 3378257 Compare November 1, 2026 14:27
- 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
@Exeloo
Exeloo force-pushed the feat/add-project-compatibility branch from 3378257 to 7444d9f Compare November 1, 2026 14:52
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:kernel Related to Kernel package packages:project Related to Project package packages:protocol Related to Protocol package packages:registry Related to Registry 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:ecs Related to ECS plugin plugins:file-manager Related to File manager plugin plugins:scene Related to Scene plugin plugins:settings-ui Related to Settings ui plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants