## Summary
Bundled plugins now persist shared runtime state in project-scoped
PostgreSQL tables instead of maintaining independent SQLite authority.
Reports, CLI Printing Press, Compound Engineering, Roadmap, Even
Realities, and WhatsApp all follow the same ownership and startup
contract as Fusion core.
## Design decisions
- Plugin schema hooks run through the host’s PostgreSQL owner and
enforce project isolation.
- The SDK exposes the host contract needed by bundled plugins without
importing engine internals.
- Legacy Roadmap ownership fixtures use the supported empty-owner
sentinel, preserving current composite primary/foreign keys while
exercising backfill behavior.
- The lockfile travels with the Even Realities PostgreSQL dependency so
packaged installs remain reproducible.
## Validation
- All six affected plugin builds pass.
- Affected plugin suites pass: 773 tests across Printing Press, Compound
Engineering, Even Realities, Reports, Roadmap, and WhatsApp.
- `pnpm test:gate` passes all 478 gate tests.
- This PR changes 40 files.
## Stack
- Depends on #2110 → #2109 → #2108.
- The documentation/release PR completes the stack.
Related: #2105
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Breaking Changes**
* PostgreSQL is now required for runtime storage; SQLite files are used
only as one-time migration inputs.
* The legacy `FUSION_NO_EMBEDDED_PG` fallback has been removed.
* **New Features**
* Added project-isolated PostgreSQL storage for plugins, reports, tasks,
notifications, and other plugin data.
* Added agent tools for reports and CLI service drafts.
* Added PostgreSQL schema initialization support for plugin authors.
* **Bug Fixes**
* Improved migration and recovery of legacy plugin state.
* Prevented cross-project data access and strengthened transactional
schema updates.
* **Documentation**
* Updated storage, migration, deployment, plugin authoring, CLI, and
dashboard guidance for PostgreSQL.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Session skill merging (collectPluginSkillNames) previously ignored per-project
Skills view enable/disable toggles and only consulted each plugin's static
default, so a user disabling a plugin skill in the Skills view would still see
it merged into live agent sessions. Extracted the effective-enablement
resolver shared by dashboard discovery and engine session assembly into
@fusion/core so both surfaces stay in sync.
- Added packages/core/src/skill-settings.ts with computeSkillId/parseSkillId/
normalizeStoredSkillPath/getSkillSettingState/resolvePluginSkillEnabled,
exported from @fusion/core's index.
- packages/dashboard/src/skills-adapter.ts now re-exports and delegates to the
shared @fusion/core resolver instead of duplicating its own
getSkillSettingState/computeSkillId/parseSkillId implementations.
- packages/engine/src/session-skill-context.ts: collectPluginSkillNames now
accepts a projectRootDir, reads project settings via skill-resolver's newly
exported readProjectSettings/resolveProjectRoot, and calls
resolvePluginSkillEnabled instead of only checking the plugin's static
skill.enabled flag; mergePluginSkills passes projectRootDir through.
- packages/engine/src/skill-resolver.ts: exported readProjectSettings and
ProjectSkillSettings for reuse by session-skill-context.
- Updated docs/plugin-management.md to document that per-project Skills view
toggles now apply to runtime agent sessions, not just discovery.
- Added unit tests for the new core resolver and updated dashboard/engine
tests to cover per-project toggle overrides in session merging.
- Added a patch changeset for @runfusion/fusion.
Files changed:
.changeset/fn-7858-plugin-skill-session-toggle.md | 7 ++
docs/plugin-management.md | 4 +-
packages/core/src/__tests__/skill-settings.test.ts | 62 +++++++++
packages/core/src/index.ts | 8 ++
packages/core/src/skill-settings.ts | 102 +++++++++++++++
.../dashboard/src/__tests__/skills-adapter.test.ts | 60 ++++++++-
packages/dashboard/src/skills-adapter.ts | 107 +++-------------
.../src/__tests__/session-skill-context.test.ts | 140 ++++++++++++++++++++-
packages/engine/src/session-skill-context.ts | 23 +++-
packages/engine/src/skill-resolver.ts | 4 +-
10 files changed, 409 insertions(+), 108 deletions(-)
Fusion-Task-Id: FN-7858
Fusion-Task-Lineage: 90e44d24-e385-4a74-b8e4-3c864ec39a95
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
- Add reports plugin to bundled plugin resolver so it can be installed from packaged assets
- Expose reports plugin in dashboard plugin manager and server routes for one-click install flows
- Add CLI and dashboard test coverage for bundled install behavior and plugin route availability
- Update reports/plugin management/settings docs and include a changeset for @runfusion/fusion
Bundled the Printing Press plugin into the dashboard by adding it as a built-in entry in `PluginManager.tsx` with corresponding tests and documentation updates, and included a changeset to publish the change under `@runfusion/fusion`.
Fusion-Task-Id: FN-4057
- Document global install vs project-scoped enablement semantics for plugins
- Add explicit scope notes for dashboard and CLI plugin install/uninstall/enable/disable flows
- Link plugin scope guidance to multi-project documentation
- Update dashboard guide Git Manager feature list with pull split-button rebase option
Fusion-Task-Id: FN-3727
Adds a WhatsApp chat plugin (`plugins/fusion-plugin-whatsapp-chat/`) as the first bundled plugin, including the plugin package with UI rendering, dashboard plugin manager integration, CLI bundling support, and plugin route runtime context. Also updates documentation to cover plugin management and ap
Fusion-Task-Id: FN-3714
Fixes a bug where plugin lifecycle operations were incorrectly gated by the setup probe state, separating the two concerns across the API, PluginManager component, routes, and tests, with updated documentation.
Fusion-Task-Id: FN-3704
The mobile composer/footer slid over the message list when the user
swiped with the keyboard up. Cause: --vv-height / --vv-offset-top were
routed through React state via useMobileKeyboard, so on iOS — which
fires visualViewport scroll/resize on the same frame as its keyboard
animation — the .chat-thread translation lagged by one paint, visible
as the composer momentarily floating over messages.
Now those two vars are written imperatively in a useLayoutEffect
directly to the .chat-thread DOM node on every visualViewport event,
mirroring the working pattern at QuickChatFAB.tsx:1032-1052 (which
already works correctly on mobile). Only --keyboard-overlap (a
structural open/close signal, not per-frame) still flows through
React state.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The merge adds a test isolation script (`scripts/check-test-isolation.mjs`) to filter runtime noise from live Fusion app paths, fixes MailboxModal spacing by replacing hardcoded values with design tokens (FN-3585), and documents post-install plugin capabilities in the plugin management guide (FN-358
Fusion-Task-Id: FN-3585
This merge adds a complete plugin management system to Fusion: a new `fn plugin` CLI command for installing/removing plugins, a plugin loader in core, a plugin runner in engine, and dashboard routes for plugin management UI, along with a plugin management guide in docs. It also documents task evalua
Fusion-Task-Id: FN-3565