Skip to content

Add project plugin management and extract Nature - #501

Merged
wass08 merged 1 commit into
mainfrom
feat/plugin-management-nature-extraction
Jul 16, 2026
Merged

Add project plugin management and extract Nature#501
wass08 merged 1 commit into
mainfrom
feat/plugin-management-nature-extraction

Conversation

@wass08

@wass08 wass08 commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add a Plugins list-to-detail sidebar with project-level install and uninstall controls
  • persist installed plugin IDs through scene loading, cloning, autosave, validation, and MCP paths
  • gate plugin panels and rendering while preserving plugin nodes for later reinstall
  • consume Nature from the public pascalorg/plugin-trees repository at a reviewed commit and remove the in-tree package
  • update plugin authoring documentation and links

Test plan

  • bun run typecheck from private-editor
  • bun run build from private-editor
  • editor package and standalone app type checks
  • standalone editor production build
  • 85 focused registry, scene plugin state, cloning, and MCP tests
  • frozen Bun installs in both repositories

Related


Note

Medium Risk
Changes scene document shape and rendering gating across core, editor, and viewer; legacy scenes rely on omitted installedPlugins meaning “show loaded plugins,” which must stay correct on load/save round-trips.

Overview
Adds per-project plugin installation: scenes carry installedPlugins, with install/uninstall in a new Plugins sidebar (list + detail). Uninstall hides plugin panels, tools, renderers, systems, and floorplan output via isNodeKindEnabled, but plugin nodes stay in the graph and come back when the plugin is reinstalled.

Persistence threads installedPlugins through autosave, API graph validation, import/export, cloning/forking, scene load signatures, undo, and MCP export/load (legacy graphs without the field keep backward-compatible behavior).

Nature (@pascal-app/plugin-trees) moves out of the monorepo to pascalorg/plugin-trees at a pinned GitHub commit; the in-tree package is removed. Docs and CONTRIBUTING/README now point at the hosted plugin guide and external example repo. EditorHostPanel gains optional metadata (pluginId, defaultInstalled, creator URLs) for the manager UI.

Reviewed by Cursor Bugbot for commit 24016ad. Bugbot is set up for automated code reviews on this repo. Configure here.

@wass08
wass08 merged commit 9ca3eaa into main Jul 16, 2026
3 checks passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 4 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 24016ad. Configure here.

obj.installedPlugins.filter((id): id is string => typeof id === 'string'),
{ explicit: true },
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MCP legacy load hides plugins

High Severity

Calling SceneBridge.setScene (e.g., from loadJSON) implicitly resets the store's installedPlugins state, as it only updates nodes and root IDs. This causes plugin nodes in loaded scenes (especially legacy graphs without explicit plugin data) to be treated as disabled by the new gating logic, making them invisible or non-functional in MCP.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 24016ad. Configure here.

installedPlugins: parsed.installedPlugins ?? currentScene.installedPlugins,
hasExplicitPluginInstallState:
parsed.installedPlugins !== undefined || currentScene.hasExplicitPluginInstallState,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Import inherits project plugins

Medium Severity

When importing a build JSON file, handleConfirmImport uses parsed.installedPlugins ?? currentScene.installedPlugins. This causes files that omit installedPlugins to inherit the current project's plugin state, rather than applying default or legacy rules as cloud load does. Consequently, imported plugin nodes may be incorrectly hidden, visible, or disabled.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 24016ad. Configure here.

? installedPlugins.filter((id) => id !== pluginId)
: [...installedPlugins, pluginId]
setInstalledPlugins(next, { explicit: true })
}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Uninstall leaves active placement tool

Medium Severity

Uninstalling a plugin updates its installed status but fails to deactivate any active placement tools. This allows users to create invisible nodes in the scene, as the plugin's rendering and systems are no longer active.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 24016ad. Configure here.

const { nodes, rootNodeIds, collections, materials } = state
return { nodes, rootNodeIds, collections, materials }
const { nodes, rootNodeIds, collections, materials, installedPlugins } = state
return { nodes, rootNodeIds, collections, materials, installedPlugins }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Undo skips explicit plugin flag

Medium Severity

Temporal undo/redo tracks installedPlugins but not hasExplicitPluginInstallState. Restoring an older plugin list after install changes can leave the explicit flag out of sync with the undone list, so default-install merging and export semantics no longer match user expectation.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 24016ad. Configure here.

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