@@ -129,12 +129,16 @@ export class ObjectQLPlugin implements Plugin {
129129 // object registered by plugins (e.g., sys_user from plugin-auth).
130130 await this . syncRegisteredSchemas ( ctx ) ;
131131
132+ // Bridge all SchemaRegistry objects to metadata service
133+ // This ensures AI tools and other IMetadataService consumers can see all objects
134+ await this . bridgeObjectsToMetadataService ( ctx ) ;
135+
132136 // Register built-in audit hooks
133137 this . registerAuditHooks ( ctx ) ;
134138
135139 // Register tenant isolation middleware
136140 this . registerTenantMiddleware ( ctx ) ;
137-
141+
138142 ctx . logger . info ( 'ObjectQL engine started' , {
139143 driversRegistered : this . ql ?. [ 'drivers' ] ?. size || 0 ,
140144 objectsRegistered : this . ql ?. registry ?. getAllObjects ?.( ) ?. length || 0
@@ -387,12 +391,12 @@ export class ObjectQLPlugin implements Plugin {
387391 return ;
388392 }
389393
390- // Phase 2: DB hydration
394+ // Phase 2: DB hydration (loads into SchemaRegistry)
391395 try {
392396 const { loaded, errors } = await protocol . loadMetaFromDb ( ) ;
393397
394398 if ( loaded > 0 || errors > 0 ) {
395- ctx . logger . info ( 'Metadata restored from database' , { loaded, errors } ) ;
399+ ctx . logger . info ( 'Metadata restored from database to SchemaRegistry ' , { loaded, errors } ) ;
396400 } else {
397401 ctx . logger . debug ( 'No persisted metadata found in database' ) ;
398402 }
@@ -404,6 +408,63 @@ export class ObjectQLPlugin implements Plugin {
404408 }
405409 }
406410
411+ /**
412+ * Bridge all SchemaRegistry objects to the metadata service.
413+ *
414+ * This ensures objects registered by plugins and loaded from sys_metadata
415+ * are visible to AI tools and other consumers that query IMetadataService.
416+ *
417+ * Runs after both restoreMetadataFromDb() and syncRegisteredSchemas() to
418+ * catch all objects in the SchemaRegistry regardless of their source.
419+ */
420+ private async bridgeObjectsToMetadataService ( ctx : PluginContext ) : Promise < void > {
421+ try {
422+ const metadataService = ctx . getService < any > ( 'metadata' ) ;
423+ if ( ! metadataService || typeof metadataService . register !== 'function' ) {
424+ ctx . logger . debug ( 'Metadata service unavailable for bridging, skipping' ) ;
425+ return ;
426+ }
427+
428+ if ( ! this . ql ?. registry ) {
429+ ctx . logger . debug ( 'SchemaRegistry unavailable for bridging, skipping' ) ;
430+ return ;
431+ }
432+
433+ const objects = this . ql . registry . getAllObjects ( ) ;
434+ let bridged = 0 ;
435+
436+ for ( const obj of objects ) {
437+ try {
438+ // Check if object is already in metadata service to avoid duplicates
439+ const existing = await metadataService . getObject ( obj . name ) ;
440+ if ( ! existing ) {
441+ // Register object that exists in SchemaRegistry but not in metadata service
442+ await metadataService . register ( 'object' , obj . name , obj ) ;
443+ bridged ++ ;
444+ }
445+ } catch ( e : unknown ) {
446+ ctx . logger . debug ( 'Failed to bridge object to metadata service' , {
447+ object : obj . name ,
448+ error : e instanceof Error ? e . message : String ( e ) ,
449+ } ) ;
450+ }
451+ }
452+
453+ if ( bridged > 0 ) {
454+ ctx . logger . info ( 'Bridged objects from SchemaRegistry to metadata service' , {
455+ count : bridged ,
456+ total : objects . length
457+ } ) ;
458+ } else {
459+ ctx . logger . debug ( 'No objects needed bridging (all already in metadata service)' ) ;
460+ }
461+ } catch ( e : unknown ) {
462+ ctx . logger . debug ( 'Failed to bridge objects to metadata service' , {
463+ error : e instanceof Error ? e . message : String ( e ) ,
464+ } ) ;
465+ }
466+ }
467+
407468 /**
408469 * Load metadata from external metadata service into ObjectQL registry
409470 * This enables ObjectQL to use file-based or remote metadata
0 commit comments