From 3f1fac439b48c5d08cf4a5a61b323250c1752848 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 31 Jan 2026 06:13:43 +0000 Subject: [PATCH 1/5] Initial plan From f31af0dd6f70ff49f7060c527f8a6d00186cec72 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 31 Jan 2026 06:17:10 +0000 Subject: [PATCH 2/5] Fix Registry namespace lookup and PluginSystem tests - Add deprecation warning when registering components without namespace - Fix Registry.get() to not fallback when namespace is explicitly provided - Fix Registry.has() to not fallback when namespace is explicitly provided - Fix Registry.getConfig() to not fallback when namespace is explicitly provided - Fix PluginSystem tests to use legacy mode (useScope: false) for direct registry access - All 91 tests now passing Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- packages/core/src/registry/Registry.ts | 34 ++++++++++--------- .../registry/__tests__/PluginSystem.test.ts | 4 +-- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/core/src/registry/Registry.ts b/packages/core/src/registry/Registry.ts index d94065fa7..287fb4c31 100644 --- a/packages/core/src/registry/Registry.ts +++ b/packages/core/src/registry/Registry.ts @@ -72,6 +72,14 @@ export class Registry { register(type: string, component: ComponentRenderer, meta?: ComponentMeta) { const fullType = meta?.namespace ? `${meta.namespace}:${type}` : type; + // Warn if registering without namespace (deprecated pattern) + if (!meta?.namespace) { + console.warn( + `Registering component "${type}" without a namespace is deprecated. ` + + `Please provide a namespace in the meta parameter.` + ); + } + if (this.components.has(fullType)) { // console.warn(`Component type "${fullType}" is already registered. Overwriting.`); } @@ -84,7 +92,7 @@ export class Registry { // Also register without namespace for backward compatibility // This allows "button" to work even when registered as "ui:button" - if (meta?.namespace && !this.components.has(type)) { + if (meta?.namespace) { this.components.set(type, { type: fullType, // Keep reference to namespaced type component, @@ -113,16 +121,13 @@ export class Registry { * registry.get('button', 'ui') // Tries 'ui:button' first, then 'button' */ get(type: string, namespace?: string): ComponentRenderer | undefined { - // Try namespaced lookup first if namespace provided + // If namespace is explicitly provided, ONLY look in that namespace (no fallback) if (namespace) { const namespacedType = `${namespace}:${type}`; - const namespacedComponent = this.components.get(namespacedType); - if (namespacedComponent) { - return namespacedComponent.component; - } + return this.components.get(namespacedType)?.component; } - // Fallback to direct type lookup + // When no namespace provided, use backward compatibility lookup return this.components.get(type)?.component; } @@ -134,16 +139,13 @@ export class Registry { * @returns Component configuration or undefined */ getConfig(type: string, namespace?: string): ComponentConfig | undefined { - // Try namespaced lookup first if namespace provided + // If namespace is explicitly provided, ONLY look in that namespace (no fallback) if (namespace) { const namespacedType = `${namespace}:${type}`; - const namespacedConfig = this.components.get(namespacedType); - if (namespacedConfig) { - return namespacedConfig; - } + return this.components.get(namespacedType); } - // Fallback to direct type lookup + // When no namespace provided, use backward compatibility lookup return this.components.get(type); } @@ -155,12 +157,12 @@ export class Registry { * @returns True if component is registered */ has(type: string, namespace?: string): boolean { + // If namespace is explicitly provided, ONLY look in that namespace (no fallback) if (namespace) { const namespacedType = `${namespace}:${type}`; - if (this.components.has(namespacedType)) { - return true; - } + return this.components.has(namespacedType); } + // When no namespace provided, use backward compatibility lookup return this.components.has(type); } diff --git a/packages/core/src/registry/__tests__/PluginSystem.test.ts b/packages/core/src/registry/__tests__/PluginSystem.test.ts index 23668480a..5e5180310 100644 --- a/packages/core/src/registry/__tests__/PluginSystem.test.ts +++ b/packages/core/src/registry/__tests__/PluginSystem.test.ts @@ -28,7 +28,7 @@ describe('PluginSystem', () => { } }; - await pluginSystem.loadPlugin(plugin, registry); + await pluginSystem.loadPlugin(plugin, registry, false); expect(pluginSystem.isLoaded('test-plugin')).toBe(true); expect(pluginSystem.getLoadedPlugins()).toContain('test-plugin'); @@ -201,7 +201,7 @@ describe('PluginSystem', () => { register: registerFn }; - await pluginSystem.loadPlugin(plugin, registry); + await pluginSystem.loadPlugin(plugin, registry, false); expect(registerFn).toHaveBeenCalledWith(registry); expect(registerFn).toHaveBeenCalledTimes(1); From 080df1eb5d514c2766f427feec94986b2917e998 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 31 Jan 2026 06:22:07 +0000 Subject: [PATCH 3/5] Address code review feedback: add clarifying comments - Add comment explaining backward compatibility behavior in Registry.register() - Add comments to PluginSystem tests explaining legacy mode usage - Clarify that last registration wins for non-namespaced lookups Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- packages/core/src/registry/Registry.ts | 2 ++ packages/core/src/registry/__tests__/PluginSystem.test.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/core/src/registry/Registry.ts b/packages/core/src/registry/Registry.ts index 287fb4c31..afe2aa9e9 100644 --- a/packages/core/src/registry/Registry.ts +++ b/packages/core/src/registry/Registry.ts @@ -92,6 +92,8 @@ export class Registry { // Also register without namespace for backward compatibility // This allows "button" to work even when registered as "ui:button" + // Note: If multiple namespaced components share the same short name, + // the last registration wins for non-namespaced lookups if (meta?.namespace) { this.components.set(type, { type: fullType, // Keep reference to namespaced type diff --git a/packages/core/src/registry/__tests__/PluginSystem.test.ts b/packages/core/src/registry/__tests__/PluginSystem.test.ts index 5e5180310..d03caddc4 100644 --- a/packages/core/src/registry/__tests__/PluginSystem.test.ts +++ b/packages/core/src/registry/__tests__/PluginSystem.test.ts @@ -28,6 +28,7 @@ describe('PluginSystem', () => { } }; + // Use legacy mode (useScope: false) to test direct registry access await pluginSystem.loadPlugin(plugin, registry, false); expect(pluginSystem.isLoaded('test-plugin')).toBe(true); @@ -201,6 +202,7 @@ describe('PluginSystem', () => { register: registerFn }; + // Use legacy mode (useScope: false) to verify the raw Registry is passed await pluginSystem.loadPlugin(plugin, registry, false); expect(registerFn).toHaveBeenCalledWith(registry); From 72093f94e21199a31aa011bee014ca038254cdf9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 31 Jan 2026 06:30:32 +0000 Subject: [PATCH 4/5] Initial plan From 1f4ab89a5848661661b35e9ca02a42ff13213f1d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 31 Jan 2026 06:42:35 +0000 Subject: [PATCH 5/5] Fix CI test failures by adding passWithNoTests configuration to vitest Add passWithNoTests: true to all vitest configurations to allow packages without test files to pass CI. This affects: - Root vitest.config.mts - All package-level vite.config.ts files with test sections Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- packages/components/vite.config.ts | 1 + packages/fields/vite.config.ts | 1 + packages/layout/vite.config.ts | 3 +++ packages/plugin-aggrid/vite.config.ts | 3 +++ packages/plugin-calendar/vite.config.ts | 3 +++ packages/plugin-charts/vite.config.ts | 3 +++ packages/plugin-chatbot/vite.config.ts | 3 +++ packages/plugin-dashboard/vite.config.ts | 3 +++ packages/plugin-editor/vite.config.ts | 3 +++ packages/plugin-form/vite.config.ts | 3 +++ packages/plugin-gantt/vite.config.ts | 3 +++ packages/plugin-grid/vite.config.ts | 3 +++ packages/plugin-kanban/vite.config.ts | 3 +++ packages/plugin-map/vite.config.ts | 3 +++ packages/plugin-markdown/vite.config.ts | 3 +++ packages/plugin-timeline/vite.config.ts | 3 +++ packages/plugin-view/vite.config.ts | 3 +++ vitest.config.mts | 1 + 18 files changed, 48 insertions(+) diff --git a/packages/components/vite.config.ts b/packages/components/vite.config.ts index 2924e0a62..8db1cc6fa 100644 --- a/packages/components/vite.config.ts +++ b/packages/components/vite.config.ts @@ -46,6 +46,7 @@ export default defineConfig({ globals: true, environment: 'happy-dom', setupFiles: ['../../vitest.setup.ts'], + passWithNoTests: true, // Ensure dependencies are resolved properly for tests deps: { inline: ['@object-ui/core', '@object-ui/react'], diff --git a/packages/fields/vite.config.ts b/packages/fields/vite.config.ts index ae74dff2f..a036ae98a 100644 --- a/packages/fields/vite.config.ts +++ b/packages/fields/vite.config.ts @@ -45,5 +45,6 @@ export default defineConfig({ globals: true, environment: 'happy-dom', setupFiles: ['../../vitest.setup.ts'], + passWithNoTests: true, }, }); diff --git a/packages/layout/vite.config.ts b/packages/layout/vite.config.ts index 0e3867573..462a7bd93 100644 --- a/packages/layout/vite.config.ts +++ b/packages/layout/vite.config.ts @@ -32,4 +32,7 @@ export default defineConfig({ ], }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-aggrid/vite.config.ts b/packages/plugin-aggrid/vite.config.ts index 7e719d368..86e051e1d 100644 --- a/packages/plugin-aggrid/vite.config.ts +++ b/packages/plugin-aggrid/vite.config.ts @@ -47,4 +47,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-calendar/vite.config.ts b/packages/plugin-calendar/vite.config.ts index 229ecc1ab..06a6aba9d 100644 --- a/packages/plugin-calendar/vite.config.ts +++ b/packages/plugin-calendar/vite.config.ts @@ -47,4 +47,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-charts/vite.config.ts b/packages/plugin-charts/vite.config.ts index d1fb87719..cb6548d27 100644 --- a/packages/plugin-charts/vite.config.ts +++ b/packages/plugin-charts/vite.config.ts @@ -45,4 +45,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-chatbot/vite.config.ts b/packages/plugin-chatbot/vite.config.ts index 2fc9f0618..c04b4748d 100644 --- a/packages/plugin-chatbot/vite.config.ts +++ b/packages/plugin-chatbot/vite.config.ts @@ -46,4 +46,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-dashboard/vite.config.ts b/packages/plugin-dashboard/vite.config.ts index bfdf19d72..a84286963 100644 --- a/packages/plugin-dashboard/vite.config.ts +++ b/packages/plugin-dashboard/vite.config.ts @@ -41,4 +41,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-editor/vite.config.ts b/packages/plugin-editor/vite.config.ts index 6d99a476f..4c341bc2f 100644 --- a/packages/plugin-editor/vite.config.ts +++ b/packages/plugin-editor/vite.config.ts @@ -43,4 +43,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-form/vite.config.ts b/packages/plugin-form/vite.config.ts index 7c65371e7..37dca9ac0 100644 --- a/packages/plugin-form/vite.config.ts +++ b/packages/plugin-form/vite.config.ts @@ -36,4 +36,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-gantt/vite.config.ts b/packages/plugin-gantt/vite.config.ts index ef5dd6e27..dae77f481 100644 --- a/packages/plugin-gantt/vite.config.ts +++ b/packages/plugin-gantt/vite.config.ts @@ -47,4 +47,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-grid/vite.config.ts b/packages/plugin-grid/vite.config.ts index 8a67638cc..22c1e556e 100644 --- a/packages/plugin-grid/vite.config.ts +++ b/packages/plugin-grid/vite.config.ts @@ -36,4 +36,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-kanban/vite.config.ts b/packages/plugin-kanban/vite.config.ts index 33467eda7..60cd0933e 100644 --- a/packages/plugin-kanban/vite.config.ts +++ b/packages/plugin-kanban/vite.config.ts @@ -45,4 +45,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-map/vite.config.ts b/packages/plugin-map/vite.config.ts index f0aca58f2..76d101960 100644 --- a/packages/plugin-map/vite.config.ts +++ b/packages/plugin-map/vite.config.ts @@ -47,4 +47,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-markdown/vite.config.ts b/packages/plugin-markdown/vite.config.ts index ff1fb1f57..9e7e90f97 100644 --- a/packages/plugin-markdown/vite.config.ts +++ b/packages/plugin-markdown/vite.config.ts @@ -43,4 +43,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-timeline/vite.config.ts b/packages/plugin-timeline/vite.config.ts index b2a0cd664..ef8385514 100644 --- a/packages/plugin-timeline/vite.config.ts +++ b/packages/plugin-timeline/vite.config.ts @@ -45,4 +45,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/packages/plugin-view/vite.config.ts b/packages/plugin-view/vite.config.ts index 01ef8e54e..dc16ee069 100644 --- a/packages/plugin-view/vite.config.ts +++ b/packages/plugin-view/vite.config.ts @@ -37,4 +37,7 @@ export default defineConfig({ }, }, }, + test: { + passWithNoTests: true, + }, }); diff --git a/vitest.config.mts b/vitest.config.mts index de75f0685..2da7010e3 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -11,6 +11,7 @@ export default defineConfig({ environment: 'happy-dom', setupFiles: [path.resolve(__dirname, 'vitest.setup.ts')], exclude: ['**/node_modules/**', '**/dist/**', '**/cypress/**', '**/.{idea,git,cache,output,temp}/**'], + passWithNoTests: true, coverage: { provider: 'v8', reporter: ['text', 'json', 'html'],