From 11f119555d0959a65670cc54f885aafe515c8d76 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 12 Jul 2025 16:30:45 +0200 Subject: [PATCH] feat(plugins): pass Log class through plugin system to sync-md - Add log property to PluginAPI interface and implementation - Extend PluginBridgeService to provide Log.withContext for each plugin - Create simplified logger helper for sync-md plugin with fallback - Replace console.log statements in sync-md with centralized logging - All plugin logs now integrate with main app's Log class and history --- packages/plugin-api/src/types.ts | 13 +++++++++++++ .../sync-md/src/background/background.ts | 7 ++++--- .../sync-md/src/background/sync/sync-manager.ts | 3 ++- .../plugin-dev/sync-md/src/shared/logger.ts | 17 +++++++++++++++++ src/app/plugins/plugin-api.ts | 10 ++++++++++ src/app/plugins/plugin-bridge.service.ts | 6 +++++- 6 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 packages/plugin-dev/sync-md/src/shared/logger.ts diff --git a/packages/plugin-api/src/types.ts b/packages/plugin-api/src/types.ts index cfb907df2d..6fb6336887 100644 --- a/packages/plugin-api/src/types.ts +++ b/packages/plugin-api/src/types.ts @@ -354,6 +354,19 @@ export interface PluginAPI { contextType: 'project' | 'task', ): Promise; + // logging + log: { + critical: (...args: unknown[]) => void; + err: (...args: unknown[]) => void; + log: (...args: unknown[]) => void; + info: (...args: unknown[]) => void; + verbose: (...args: unknown[]) => void; + debug: (...args: unknown[]) => void; + error: (...args: unknown[]) => void; + normal: (...args: unknown[]) => void; + warn: (...args: unknown[]) => void; + }; + // persistence persistDataSynced(dataStr: string): Promise; diff --git a/packages/plugin-dev/sync-md/src/background/background.ts b/packages/plugin-dev/sync-md/src/background/background.ts index 12cf02b37e..16e0960ce2 100644 --- a/packages/plugin-dev/sync-md/src/background/background.ts +++ b/packages/plugin-dev/sync-md/src/background/background.ts @@ -1,17 +1,18 @@ import { initSyncManager } from './sync/sync-manager'; import { initUiBridge } from './ui-bridge'; import { loadLocalConfig } from './local-config'; +import { log } from '../shared/logger'; export const initPlugin = (): void => { - console.log('[sync-md] initPlugin called'); + log.log('initPlugin called'); // Initialize UI bridge to handle messages initUiBridge(); - console.log('[sync-md] UI bridge initialized'); + log.log('UI bridge initialized'); // Load saved config from local storage and start sync if enabled const config = loadLocalConfig(); - console.log('[sync-md] Loaded config:', config); + log.log('Loaded config:', config); if (config?.filePath) { // Transform config to match sync-manager expectations diff --git a/packages/plugin-dev/sync-md/src/background/sync/sync-manager.ts b/packages/plugin-dev/sync-md/src/background/sync/sync-manager.ts index 2ef4a28a6c..aedfc075ff 100644 --- a/packages/plugin-dev/sync-md/src/background/sync/sync-manager.ts +++ b/packages/plugin-dev/sync-md/src/background/sync/sync-manager.ts @@ -10,6 +10,7 @@ import { import { PluginHooks } from '@super-productivity/plugin-api'; import { LocalUserCfg } from '../local-config'; import { logSyncVerification, verifySyncState } from './verify-sync'; +import { log } from '../../shared/logger'; let syncInProgress = false; let mdToSpDebounceTimer: number | null = null; @@ -25,7 +26,7 @@ export const initSyncManager = (config: LocalUserCfg): void => { setupWindowFocusTracking(); // Perform initial sync - performInitialSync(config).then((r) => console.log('[sync-md] SyncMD initial sync', r)); + performInitialSync(config).then((r) => log.log('SyncMD initial sync', r)); // Set up file watcher for ongoing sync startFileWatcher(config.filePath, () => { diff --git a/packages/plugin-dev/sync-md/src/shared/logger.ts b/packages/plugin-dev/sync-md/src/shared/logger.ts new file mode 100644 index 0000000000..28e7bf57c8 --- /dev/null +++ b/packages/plugin-dev/sync-md/src/shared/logger.ts @@ -0,0 +1,17 @@ +// Simple logger helper for sync-md plugin +// Just use PluginAPI.log directly + +export const log = + typeof PluginAPI !== 'undefined' + ? PluginAPI.log + : { + critical: (...args: unknown[]) => console.error('[sync-md]', ...args), + err: (...args: unknown[]) => console.error('[sync-md]', ...args), + error: (...args: unknown[]) => console.error('[sync-md]', ...args), + log: (...args: unknown[]) => console.log('[sync-md]', ...args), + normal: (...args: unknown[]) => console.log('[sync-md]', ...args), + info: (...args: unknown[]) => console.info('[sync-md]', ...args), + verbose: (...args: unknown[]) => console.log('[sync-md]', ...args), + debug: (...args: unknown[]) => console.debug('[sync-md]', ...args), + warn: (...args: unknown[]) => console.warn('[sync-md]', ...args), + }; diff --git a/src/app/plugins/plugin-api.ts b/src/app/plugins/plugin-api.ts index 1853451a97..775957bf09 100644 --- a/src/app/plugins/plugin-api.ts +++ b/src/app/plugins/plugin-api.ts @@ -47,6 +47,13 @@ export class PluginAPI implements PluginAPIInterface { private _boundMethods: ReturnType< typeof PluginBridgeService.prototype.createBoundMethods >; + + /** + * Logger instance for this plugin + */ + readonly log: ReturnType< + typeof PluginBridgeService.prototype.createBoundMethods + >['log']; executeNodeScript?: ( request: PluginNodeScriptRequest, ) => Promise; @@ -67,6 +74,9 @@ export class PluginAPI implements PluginAPIInterface { if (this._boundMethods.executeNodeScript) { this.executeNodeScript = this._boundMethods.executeNodeScript; } + + // Set up logging for this plugin + this.log = this._boundMethods.log; } registerHook(hook: T, fn: PluginHookHandler): void { diff --git a/src/app/plugins/plugin-bridge.service.ts b/src/app/plugins/plugin-bridge.service.ts index 10f5f020b6..56a29e5be8 100644 --- a/src/app/plugins/plugin-bridge.service.ts +++ b/src/app/plugins/plugin-bridge.service.ts @@ -46,7 +46,7 @@ import { isAllowedPluginAction } from './allowed-plugin-actions.const'; import { TranslateService } from '@ngx-translate/core'; import { T } from '../t.const'; import { SyncWrapperService } from '../imex/sync/sync-wrapper.service'; -import { PluginLog } from '../core/log'; +import { PluginLog, Log } from '../core/log'; import { TaskCopy } from '../features/tasks/task.model'; import { ProjectCopy } from '../features/project/project.model'; import { TagCopy } from '../features/tag/tag.model'; @@ -119,6 +119,7 @@ export class PluginBridgeService implements OnDestroy { executeNodeScript: ( request: PluginNodeScriptRequest, ) => Promise; + log: ReturnType; } { return { // Data persistence @@ -147,6 +148,9 @@ export class PluginBridgeService implements OnDestroy { // Node execution executeNodeScript: (request: PluginNodeScriptRequest) => this._executeNodeScript(pluginId, manifest || null, request), + + // Logging + log: () => Log.withContext(`${pluginId}`), }; }