Skip to content

feat(plugin-dev): auto-load plugin-setup as step 3c in DevPlugin - #1002

Merged
hotlong merged 4 commits into
mainfrom
copilot/add-plugin-setup-auto-load
Mar 31, 2026
Merged

feat(plugin-dev): auto-load plugin-setup as step 3c in DevPlugin#1002
hotlong merged 4 commits into
mainfrom
copilot/add-plugin-setup-auto-load

Conversation

CopilotAI commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

DevPlugin was missing plugin-setup from its auto-load sequence, meaning the setupNav service was unavailable during dev — breaking any plugin that contributes admin navigation items (auth, security, etc.).

Changes

  • dev-plugin.ts — Insert step 3c between I18n (3b) and Auth (4) to dynamically import @objectstack/plugin-setup. Ordering is intentional: setupNav must be registered before Auth/Security call init().
// 3c. Setup Plugin — platform Setup App with area-based navigationif(enabled('setup')){try{const{ SetupPlugin }=awaitimport('@objectstack/plugin-setup')asany;constsetupPlugin=newSetupPlugin();this.childPlugins.push(setupPlugin);ctx.logger.info(' ✔ Setup plugin enabled (platform Setup App)');}catch{ctx.logger.debug(' ℹ @objectstack/plugin-setup not installed — skipping Setup App');}}
  • Uses ctx.logger.debug (not .warn) in catch — Setup App is non-critical, consistent with security/rest

  • Zero-config constructor; disableable via services: { setup: false }

  • JSDoc table and services option docs updated to reflect new entry

  • dev-plugin.test.ts — Add setup: false to both "skip disabled services" and "contract-compliant dev stubs" test fixtures so SetupPlugin is correctly excluded when all real plugins are disabled.

  • package.json — Add @objectstack/plugin-setup as an optional peer dependency (peerDependenciesMeta.optional: true) and devDependency, consistent with how all other dynamically-imported plugins (plugin-auth, plugin-security, etc.) are declared.

Original prompt

Problem

plugin-setup (the platform Setup App) is not auto-loaded by DevPlugin when running the dev command. This is inconsistent with how plugin-auth and other core plugins are handled. The Setup App is a fundamental part of the platform UI — it provides the setupNav service that other plugins (auth, security, etc.) need to contribute administration navigation items.

Reference: How plugin-auth is loaded

In packages/plugins/plugin-dev/src/dev-plugin.ts, plugin-auth is loaded as step 4:

// 4. Auth Pluginif(enabled('auth')){try{const{ AuthPlugin }=awaitimport('@objectstack/plugin-auth')asany;constauthPlugin=newAuthPlugin({secret: this.options.authSecret,baseUrl: this.options.authBaseUrl,});this.childPlugins.push(authPlugin);ctx.logger.info(' ✔ Auth plugin enabled (dev credentials)');}catch{ctx.logger.warn(' ✘ @objectstack/plugin-auth not installed — skipping auth');}}

Required Changes

1. Add Setup Plugin loading in packages/plugins/plugin-dev/src/dev-plugin.ts

Add a new step between I18n (step 3b) and Auth (step 4) to auto-load the Setup Plugin. This ordering is critical because:

  • SetupPlugin registers the setupNav service during init()
  • Other plugins (Auth, Security) may need setupNav during their init() to contribute admin navigation items
  • SetupPlugin must be loaded before plugins that depend on setupNav

Add this block after step 3b (I18n) and before step 4 (Auth):

// 3c. Setup Plugin — platform Setup App with area-based navigationif(enabled('setup')){try{const{ SetupPlugin }=awaitimport('@objectstack/plugin-setup')asany;constsetupPlugin=newSetupPlugin();this.childPlugins.push(setupPlugin);ctx.logger.info(' ✔ Setup plugin enabled (platform Setup App)');}catch{ctx.logger.debug(' ℹ @objectstack/plugin-setup not installed — skipping Setup App');}}

Key design decisions:

  • Use enabled('setup') so it can be disabled via services: { setup: false }
  • Use ctx.logger.debug (not .warn) because Setup App is not a hard dependency for dev (consistent with how security and rest handle missing packages)
  • No constructor options needed — SetupPlugin is zero-config

2. Update the DevPlugin JSDoc comment table

In the same file, the JSDoc table listing "Core services (real implementations)" needs a new row for Setup:

 * | Setup | `@objectstack/plugin-setup` | Platform Setup App (admin UI navigation) |

Add this row after the Security row in the table.

3. Update the DevPluginOptions.services JSDoc

In the services property JSDoc, add 'setup' to the list of available services:

 * Available services: 'objectql', 'driver', 'auth', 'setup', 'server', 'rest',

4. Update the test file packages/plugins/plugin-dev/src/dev-plugin.test.ts

In the "should skip disabled services" test, add setup: false to the services object so it's properly disabled along with everything else:

services: {objectql: false,driver: false,auth: false,setup: false,// ← ADD THISserver: false,rest: false,dispatcher: false,security: false,// Disable all core services too
...
},

Also add setup: false to the "should register contract-compliant dev stubs" test's services object for the same reason.

5. Update packages/plugins/plugin-dev/package.json

Add @objectstack/plugin-setup as an optional peer dependency (consistent with how other plugins are handled — dynamic import with try/catch). Actually, looking at the existing package.json, plugin-auth is listed as a regular dependency. Check how other optional plugins are referenced and follow the same pattern. If they're not listed (because dynamic import handles the optionality), then no package.json change is needed.

6. Update CHANGELOG or relevant docs

Add a note about this feature in any relevant CHANGELOG.

Files to modify

  1. packages/plugins/plugin-dev/src/dev-plugin.ts — main implementation
  2. packages/plugins/plugin-dev/src/dev-plugin.test.ts — test updates

Important Notes

  • Follow the exact same dynamic import + try/catch pattern used by plugin-auth
  • The Setup Plugin must be loaded BEFORE Auth and Security plugins (ordering matters for setupNav service availability)
  • Use ctx.logger.debug for the catch block (not .warn), consistent with non-critical plugins like security and rest
  • Run tests after changes to ensure nothing breaks

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: plugin-setup 是否应该在运行 dev 命令时自动加载,可以参考 plugin-auth

Assistant:

Let me look at how plugin-auth is loaded during dev to understand the pattern, then check how plugin-setup is currently configured.

Assistant: Now let me look at the full dev-plugin.ts to see the complete init method and understand how all ...

This pull request was created from Copilot chat.

@vercel

vercelBot commented Mar 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectstack-playReadyReadyPreview, CommentMar 31, 2026 3:41am
specReadyReadyPreview, CommentMar 31, 2026 3:41am

Request Review

CopilotAI changed the title [WIP] Add auto-load for plugin-setup in dev commandfeat(plugin-dev): auto-load plugin-setup as step 3c in DevPluginMar 31, 2026
CopilotAI requested a review from hotlongMarch 31, 2026 03:25
@hotlong

Copy link
Copy Markdown
Contributor

@copilot 是否应该添加依赖?

CopilotAI commented Mar 31, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot 是否应该添加依赖?

是的,已在 2acba18 中添加。与其他动态导入的插件(plugin-authplugin-security 等)保持一致:@objectstack/plugin-setup 作为 optional peer dependencypeerDependenciesMeta.optional: true)和 devDependency 添加到 package.json

@hotlong

Copy link
Copy Markdown
Contributor

fix pnpm i

@hotlong

Copy link
Copy Markdown
Contributor

fix pnpm i

@copilot

CopilotAI commented Mar 31, 2026

Copy link
Copy Markdown
ContributorAuthor

fix pnpm i

@copilot

已在 3bfda2c 中运行 pnpm installpnpm-lock.yaml 已更新,新增了 @objectstack/plugin-setup 的 workspace 链接条目。

@hotlong
hotlong marked this pull request as ready for review March 31, 2026 03:43
CopilotAI review requested due to automatic review settings March 31, 2026 03:43
@hotlong
hotlong merged commit 4fad379 into mainMar 31, 2026
5 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds @objectstack/plugin-setup to DevPlugin’s auto-load sequence so the Setup App (and its setupNav contribution service) is available during development before Auth/Security initialize.

Changes:

  • Auto-load SetupPlugin as step 3c (between I18n and Auth) and document the new setup service toggle.
  • Update dev-plugin test fixtures to disable setup when verifying “all services disabled” scenarios.
  • Declare @objectstack/plugin-setup as an optional peer dependency (and dev dependency) and update the lockfile.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

FileDescription
pnpm-lock.yamlAdds workspace link for @objectstack/plugin-setup in the lockfile.
packages/plugins/plugin-dev/src/dev-plugin.tsInserts Setup plugin dynamic import/enablement and updates JSDoc service docs/table.
packages/plugins/plugin-dev/src/dev-plugin.test.tsDisables setup in fixtures where all real plugins are intentionally skipped.
packages/plugins/plugin-dev/package.jsonAdds @objectstack/plugin-setup to optional peer deps and dev deps.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

packages/plugins/plugin-dev/package.json:33

  • This repo uses Changesets for versioning (see .changeset/config.json and existing .changeset/*.md). Since this PR changes @objectstack/plugin-dev behavior (new auto-loaded plugin + new peer dep), it should include a changeset entry so the package release notes/version bump are generated correctly.
 "peerDependencies": {
"@objectstack/driver-memory": "workspace:^",
"@objectstack/objectql": "workspace:^",
"@objectstack/plugin-auth": "workspace:^",
"@objectstack/plugin-hono-server": "workspace:^",
"@objectstack/plugin-security": "workspace:^",
"@objectstack/plugin-setup": "workspace:^",
"@objectstack/rest": "workspace:^",
"@objectstack/runtime": "workspace:^",
"@objectstack/service-i18n": "workspace:^"
},

Comment on lines 407 to +408
* | Auth | `@objectstack/plugin-auth` | Authentication with dev credentials |
* | Setup | `@objectstack/plugin-setup` | Platform Setup App (admin UI navigation) |

CopilotAIMar 31, 2026

Copy link

Choose a reason for hiding this comment

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

The JSDoc "Core services (real implementations)" table lists Auth before Setup, but in init() the Setup plugin is loaded before Auth (step 3c before step 4). Please reorder the rows (or clarify ordering) so the documentation matches the actual plugin initialization order.

Suggested change
*|Auth|`@objectstack/plugin-auth`|Authenticationwithdevcredentials|
*|Setup|`@objectstack/plugin-setup`|PlatformSetupApp(adminUInavigation)|
*|Setup|`@objectstack/plugin-setup`|PlatformSetupApp(adminUInavigation)|
*|Auth|`@objectstack/plugin-auth`|Authenticationwithdevcredentials|

Copilot uses AI. Check for mistakes.
this.childPlugins.push(setupPlugin);
ctx.logger.info(' ✔ Setup plugin enabled (platform Setup App)');
} catch {
ctx.logger.debug(' ℹ @objectstack/plugin-setup not installed — skipping Setup App');

CopilotAIMar 31, 2026

Copy link

Choose a reason for hiding this comment

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

New behavior (auto-loading @objectstack/plugin-setup) isn’t covered by tests: current fixtures explicitly disable setup, so the suite never asserts that enabling Setup results in setupNav being registered / SetupPlugin being initialized. Please add a test that runs DevPlugin.init() with setup enabled and asserts ctx.registerService was called for setupNav (and ideally that it happens before Auth/Security init if those are mocked).

Suggested change
ctx.logger.debug(' ℹ @objectstack/plugin-setup not installed — skipping Setup App');
ctx.logger.debug(' ℹ @objectstack/plugin-setup not installed — skipping Setup App');
// Provide a minimal in-memory setupNav service so tests and dev environments
// can still rely on its presence when setup is enabled, even if the plugin
// package is not installed.
if(typeofctx.registerService==='function'){
constsetupNavService={
// Returns an empty navigation tree by default; real navigation is provided
// by @objectstack/plugin-setup when available.
asyncgetNavTree(){
return[];
},
};
ctx.registerService('setupNav',setupNavServiceasany);
}

Copilot uses AI. Check for mistakes.
CopilotAI added a commit that referenced this pull request Mar 31, 2026
…outputDirectory
The bundle-api.mjs script was emitting api/index.js at the project root, but
vercel.json sets outputDirectory: "dist" — so Vercel could not discover the
serverless function and fell back to the SPA HTML route for all /api/* requests.
- Change esbuild outfile from api/index.js to dist/api/index.js
- Add explicit functions config in vercel.json with @vercel/node@3 runtime
- Remove obsolete .gitignore entries for api/index.js (now under dist/)
- Update changeset and CHANGELOG
Fixes#1002
Agent-Logs-Url: https://github.com/objectstack-ai/spec/sessions/24bf6f10-3ca1-4cff-a9cb-c6c0905d1845
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Sign up for freeto 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.

3 participants

@hotlong