From 87c988eb54fa5e7111693396d1401c4b9d3c9bf4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 06:29:04 +0000 Subject: [PATCH 1/2] Initial plan From 125bdb28fbf2d2d6b84084475758258b3b0dd6ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 06:42:03 +0000 Subject: [PATCH 2/2] feat(crm): add console plugin integration and dev mode for standalone debugging - Add ConsolePlugin to objectstack.config.ts plugins array for CLI-based serving - Add `dev` script for development mode with hot-reload and Studio UI - Add `plugin.ts` with CRMPlugin class for importing as a plugin in other projects - Add `./plugin` export path in package.json for plugin consumption - Update server.ts to import ConsolePlugin directly from @object-ui/console - Add `type: module` to package.json for ESM compatibility Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- examples/crm/objectstack.config.ts | 8 +++-- examples/crm/package.json | 5 ++- examples/crm/plugin.ts | 58 ++++++++++++++++++++++++++++++ examples/crm/server.ts | 2 +- examples/crm/tsconfig.json | 2 +- 5 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 examples/crm/plugin.ts diff --git a/examples/crm/objectstack.config.ts b/examples/crm/objectstack.config.ts index 2cbf6ec7d..23644b4d6 100644 --- a/examples/crm/objectstack.config.ts +++ b/examples/crm/objectstack.config.ts @@ -8,6 +8,7 @@ import { OrderObject } from './src/objects/order.object'; import { UserObject } from './src/objects/user.object'; import { ProjectObject } from './src/objects/project.object'; import { EventObject } from './src/objects/event.object'; +import { ConsolePlugin } from '@object-ui/console'; export default defineStack({ objects: [ @@ -686,5 +687,8 @@ export default defineStack({ } ] - } -}); + }, + plugins: [ + new ConsolePlugin(), + ], +} as any); diff --git a/examples/crm/package.json b/examples/crm/package.json index f91eb209d..3fae7d940 100644 --- a/examples/crm/package.json +++ b/examples/crm/package.json @@ -3,13 +3,16 @@ "version": "1.0.0", "description": "CRM Metadata Example using ObjectStack Protocol", "private": true, + "type": "module", "main": "dist/objectstack.json", "types": "src/index.ts", "exports": { ".": "./src/index.ts", - "./objectstack.config": "./objectstack.config.ts" + "./objectstack.config": "./objectstack.config.ts", + "./plugin": "./plugin.ts" }, "scripts": { + "dev": "objectstack serve --dev objectstack.config.ts", "serve": "objectstack serve objectstack.config.ts", "build": "objectstack compile objectstack.config.ts", "start": "tsx server.ts" diff --git a/examples/crm/plugin.ts b/examples/crm/plugin.ts new file mode 100644 index 000000000..7b971144d --- /dev/null +++ b/examples/crm/plugin.ts @@ -0,0 +1,58 @@ +/** + * CRM Example Plugin + * + * Exports the CRM configuration as an ObjectStack plugin that can be + * loaded by any ObjectStack application. Other projects can import + * the CRM metadata (objects, apps, dashboards, manifest) without + * needing to know the internal structure. + * + * Usage in another project: + * + * import { CRMPlugin } from '@object-ui/example-crm/plugin'; + * + * const kernel = new ObjectKernel(); + * kernel.use(new CRMPlugin()); + * + * Or import the raw config for merging: + * + * import { crmConfig } from '@object-ui/example-crm/plugin'; + */ + +import config from './objectstack.config'; + +/** Raw CRM stack configuration for direct merging */ +export const crmConfig = config; + +/** + * CRM Plugin — wraps the CRM metadata as a kernel-compatible plugin. + * + * When loaded via `kernel.use(new CRMPlugin())`, ObjectStack's AppPlugin + * will register all CRM objects, apps, dashboards, and seed data. + */ +export class CRMPlugin { + readonly name = '@object-ui/example-crm'; + readonly version = '1.0.0'; + readonly type = 'app-metadata' as const; + readonly description = 'CRM application metadata (objects, apps, dashboards, seed data)'; + + async init() { + // No initialization needed + } + + async start(ctx: any) { + const logger = ctx.logger || console; + + try { + // Dynamically import AppPlugin to keep plugin.ts dependency-light + const { AppPlugin } = await import('@objectstack/runtime'); + const appPlugin = new AppPlugin(config); + await ctx.kernel?.use?.(appPlugin); + logger.info('[CRM] Metadata loaded: objects, apps, dashboards, seed data'); + } catch (e: any) { + logger.warn(`[CRM] Could not auto-register via AppPlugin: ${e.message}`); + logger.info('[CRM] Config is available via crmConfig export for manual merging'); + } + } +} + +export default CRMPlugin; diff --git a/examples/crm/server.ts b/examples/crm/server.ts index 60082937d..dbd09b534 100644 --- a/examples/crm/server.ts +++ b/examples/crm/server.ts @@ -7,7 +7,7 @@ import { InMemoryDriver } from '@objectstack/driver-memory'; import { AuthPlugin } from '@objectstack/plugin-auth'; import config from './objectstack.config'; import { pino } from 'pino'; -import { ConsolePlugin } from './console-plugin'; +import { ConsolePlugin } from '@object-ui/console'; async function startServer() { const logger = pino({ diff --git a/examples/crm/tsconfig.json b/examples/crm/tsconfig.json index 7734892fc..421f11202 100644 --- a/examples/crm/tsconfig.json +++ b/examples/crm/tsconfig.json @@ -6,5 +6,5 @@ "strict": true, "skipLibCheck": true }, - "include": ["src/**/*", "objectstack.config.ts", "server.ts", "console-plugin.ts"] + "include": ["src/**/*", "objectstack.config.ts", "server.ts", "console-plugin.ts", "plugin.ts"] }