From af247326b3454ecfe98a3e1a201614cab1f5250b Mon Sep 17 00:00:00 2001 From: meels Date: Tue, 28 Jul 2026 13:01:52 +0200 Subject: [PATCH] feat: scaffold webinar-dash plugin with config block --- .obsidian/plugins/webinar-dash/main.js | 48 ++++++++++++++++++++ .obsidian/plugins/webinar-dash/manifest.json | 9 ++++ dashboard.md | 6 +++ 3 files changed, 63 insertions(+) create mode 100644 .obsidian/plugins/webinar-dash/main.js create mode 100644 .obsidian/plugins/webinar-dash/manifest.json create mode 100644 dashboard.md diff --git a/.obsidian/plugins/webinar-dash/main.js b/.obsidian/plugins/webinar-dash/main.js new file mode 100644 index 0000000..6ef0af9 --- /dev/null +++ b/.obsidian/plugins/webinar-dash/main.js @@ -0,0 +1,48 @@ +"use strict"; + +// Obsidian injects its own module resolver. Under plain `node --test` it is +// absent, so guard the require and fall back to an empty base class. This is +// what keeps the pure helpers below unit-testable without an Obsidian runtime. +let OB = null; +try { + OB = require("obsidian"); +} catch (_) { + OB = null; +} +const PluginBase = OB ? OB.Plugin : class {}; + +const STATIONS = ["Chat box", "ReAct", "Tools", "Memory", "Skills", "Process", "OS"]; + +const DEFAULTS = { + script: "raw/sources/Webinar script.md", + coverage: "wiki/script-coverage.md", + rawDir: "raw/sources", + wikiSourceDir: "wiki/sources", + conceptDir: "wiki/concepts", +}; + +function parseConfig(source) { + const cfg = Object.assign({}, DEFAULTS); + for (const line of String(source).split(/\r?\n/)) { + const m = line.match(/^\s*([A-Za-z][A-Za-z0-9_]*)\s*:\s*(.+?)\s*$/); + if (m && Object.prototype.hasOwnProperty.call(DEFAULTS, m[1])) { + cfg[m[1]] = m[2]; + } + } + return cfg; +} + +class WebinarDashPlugin extends PluginBase { + async onload() { + this.registerMarkdownCodeBlockProcessor("webinar-dash", (source, el, ctx) => { + const cfg = parseConfig(source); + const root = el.createDiv({ cls: "webinar-dash" }); + root.createDiv({ cls: "wd-eyebrow", text: "Webinar dashboard" }); + root.createEl("p", { text: `Reading coverage from ${cfg.coverage}` }); + }); + } +} + +module.exports = WebinarDashPlugin; +module.exports.default = WebinarDashPlugin; +module.exports.__test__ = { parseConfig, STATIONS, DEFAULTS }; diff --git a/.obsidian/plugins/webinar-dash/manifest.json b/.obsidian/plugins/webinar-dash/manifest.json new file mode 100644 index 0000000..de1ae92 --- /dev/null +++ b/.obsidian/plugins/webinar-dash/manifest.json @@ -0,0 +1,9 @@ +{ + "id": "webinar-dash", + "name": "Webinar dashboard", + "version": "0.1.0", + "minAppVersion": "1.5.0", + "description": "Source pipeline and script coverage for the webinar vault.", + "author": "meels", + "isDesktopOnly": true +} diff --git a/dashboard.md b/dashboard.md new file mode 100644 index 0000000..8c3c191 --- /dev/null +++ b/dashboard.md @@ -0,0 +1,6 @@ +# Webinar dashboard + +```webinar-dash +script: raw/sources/Webinar script.md +coverage: wiki/script-coverage.md +```