| import { definePluginEntry } from 'openclaw/plugin-sdk/plugin-entry'; |
| import { execFile } from 'node:child_process'; |
| import { promisify } from 'node:util'; |
|
|
| const execFileAsync = promisify(execFile); |
|
|
| async function run(command, args = []) { |
| const { stdout, stderr } = await execFileAsync(command, args, { encoding: 'utf8' }); |
| return { stdout, stderr }; |
| } |
|
|
| async function obsidianStatus() { |
| const { stdout } = await run(process.env.OBSIDIAN_BIN || 'obsidian', ['status']); |
| return JSON.parse(stdout); |
| } |
|
|
| async function obsidianOpen(vaultPath) { |
| const args = ['open']; |
| if (vaultPath) args.push(`path=${vaultPath}`); |
| const { stdout } = await run(process.env.OBSIDIAN_BIN || 'obsidian', args); |
| return stdout ? JSON.parse(stdout) : { launched: true }; |
| } |
|
|
| export default definePluginEntry({ |
| id: 'obsidian-bridge', |
| name: 'Obsidian Bridge', |
| description: 'Minimal OpenClaw-owned Obsidian bridge for Paperclip and local callers.', |
| register(api) { |
| api.registerGatewayMethod('obsidian.bridge.status', async ({ respond }) => { |
| try { |
| respond({ ok: true, status: await obsidianStatus() }); |
| } catch (error) { |
| respond({ ok: false, error: String(error?.message || error) }); |
| } |
| }); |
| api.registerGatewayMethod('obsidian.bridge.open', async ({ params, respond }) => { |
| try { |
| respond({ ok: true, result: await obsidianOpen(params?.path || null) }); |
| } catch (error) { |
| respond({ ok: false, error: String(error?.message || error) }); |
| } |
| }); |
| api.registerHttpRoute({ |
| path: '/hooks/obsidian-bridge', |
| auth: 'plugin', |
| match: 'exact', |
| replaceExisting: true, |
| async handler(req, res) { |
| try { |
| const body = req.body && typeof req.body === 'object' ? req.body : {}; |
| const action = body.action || 'status'; |
| if (action === 'status') { |
| res.status(200).json({ ok: true, status: await obsidianStatus() }); |
| return; |
| } |
| if (action === 'open') { |
| res.status(200).json({ ok: true, result: await obsidianOpen(body.path || null) }); |
| return; |
| } |
| res.status(400).json({ ok: false, error: 'unsupported action' }); |
| } catch (error) { |
| res.status(500).json({ ok: false, error: String(error?.message || error) }); |
| } |
| } |
| }); |
| } |
| }); |
|
|