CSS / JS API
Manage custom CSS and JavaScript plugins.
dmn.css
Global custom CSS state is { path: string | null, content: string }.
dmn.css.get(): Promise<CustomCss>
Returns the current custom CSS (source file path and content).
const { path, content } = await dmn.css.get();dmn.css.getUse(): Promise<boolean>
Returns whether custom CSS is enabled.
dmn.css.toggle(enabled: boolean): Promise<{ enabled: boolean }>
Enables or disables custom CSS.
dmn.css.load(): Promise<CssLoadResult>
Opens a file dialog and imports the selected CSS file. The file must be a
regular .css file, UTF-8 encoded, and at most 1 MiB. Successfully imported
files are added to the history (up to 10 entries).
type CssLoadResult = {
success: boolean;
error?: string; // error code on failure (see table below)
content?: string;
path?: string;
};If the user cancels the dialog, success is false and error is omitted.
dmn.css.setContent(content: string): Promise<CssSetContentResult>
Replaces the CSS content directly (the source path is unchanged). Content is limited to 1 MiB.
dmn.css.reset(): Promise<void>
Disables custom CSS and clears the content. The history is preserved.
dmn.css.onUse(callback): Unsubscribe
Subscribes to enable/disable changes. The callback receives
{ enabled: boolean }.
dmn.css.onContent(callback): Unsubscribe
Subscribes to content changes (imports, hot reload, direct edits). The
callback receives CustomCss.
const unsub = dmn.css.onContent(({ path, content }) => {
console.log("CSS updated:", path);
});dmn.css history
The app keeps up to 10 previously imported CSS files. Only paths in this
history can be re-activated; arbitrary paths are rejected with
PATH_NOT_AUTHORIZED.
dmn.css.historyGet(): Promise<CustomCssHistoryItem[]>
type CustomCssHistoryItem = {
path: string;
lastUsedAt: number; // unix millis
status: "available" | "missing" | "invalid" | "tooLarge";
};status is advisory: it reflects a quick file check at query time, and the
authoritative validation happens on activation.
dmn.css.historyActivate(path: string): Promise<CssActivateResult>
Switches the global custom CSS to a history entry without a file dialog.
type CssActivateResult = {
success: boolean;
code?: CssHistoryErrorCode; // on failure
content?: string;
path?: string;
};dmn.css.historyRemove(path: string): Promise<CustomCssHistoryItem[]>
Removes an entry from the history (the file itself is not touched) and returns the updated list.
Error codes
| Code | Meaning |
|---|---|
PATH_NOT_AUTHORIZED | The path is not in the history |
NOT_FOUND | File does not exist |
NOT_REGULAR_FILE | Not a regular file |
INVALID_EXTENSION | Not a .css file |
TOO_LARGE | Over 1 MiB |
INVALID_UTF8 | Not valid UTF-8 |
IO_ERROR | Other I/O failure |
dmn.css.tab
Per-tab CSS overrides the global CSS for a single key tab. A tab override is
{ path: string | null, content: string, enabled: boolean }. Tab CSS is
rendered only while the global custom CSS toggle is on.
dmn.css.tab.getAll(): Promise<TabCssOverrides>
Returns all overrides as a Record<tabId, TabCss>.
dmn.css.tab.get(tabId: string): Promise<TabCssResponse>
Returns { tabId, css: TabCss | null }.
dmn.css.tab.load(tabId: string): Promise<TabCssLoadResult>
Opens a file dialog and imports a CSS file for the tab. The same constraints
as dmn.css.load() apply; on failure error carries an error code string.
dmn.css.tab.activateHistory(tabId: string, path: string): Promise<TabCssActivateResult>
Applies a global history entry to the tab. The path must be in the history
(PATH_NOT_AUTHORIZED otherwise).
type TabCssActivateResult = {
success: boolean;
code?: CssHistoryErrorCode;
tabId: string;
css?: TabCss;
};dmn.css.tab.export(tabId: string): Promise<TabCssExportResult>
Opens a save dialog and writes the tab’s registered CSS content to a .css
file.
type TabCssExportResult = {
success: boolean;
code?: "NO_TAB_CSS" | "IO_ERROR";
error?: string; // details for IO_ERROR
path?: string; // saved location on success
};If the user cancels the dialog, success is false and code is omitted.
dmn.css.tab.set(tabId: string, css: TabCss | null): Promise<TabCssSetResult>
Sets or removes (with null) the tab override directly. Only paths
previously authorized through a file dialog or history activation are
accepted: an unauthorized path is dropped and the override is stored as
content-only (path: null in the stored state and response).
dmn.css.tab.toggle(tabId: string, enabled: boolean): Promise<TabCssToggleResult>
Enables or disables the tab override without removing it.
dmn.css.tab.clear(tabId: string): Promise<TabCssClearResult>
Removes the tab override, falling back to the global CSS.
dmn.css.tab.onChanged(callback): Unsubscribe
Subscribes to tab override changes. The callback receives
{ tabId, css: TabCss | null }.
dmn.js
JavaScript plugin state is { plugins: JsPlugin[] } where each plugin is
{ id, name, path, content, enabled }.
dmn.js.get(): Promise<CustomJs>
Returns the current plugin list.
dmn.js.getUse(): Promise<boolean>
Returns whether JS plugins are enabled.
dmn.js.toggle(enabled: boolean): Promise<{ enabled: boolean }>
Enables or disables JS plugins globally.
dmn.js.load(): Promise<JsLoadResult>
Opens a file dialog and adds the selected plugin files.
type JsLoadResult = {
success: boolean;
added: JsPlugin[];
errors?: { path: string; error: string }[];
};dmn.js.reload(): Promise<JsReloadResult>
Re-reads all plugin files from disk and returns { updated, errors? }.
Plugins are always torn down and re-run, even if the file contents are
unchanged, so an explicit reload can be used to reset plugin state.
dmn.js.remove(id: string): Promise<JsRemoveResult>
Removes a plugin by id.
dmn.js.setPluginEnabled(id: string, enabled: boolean): Promise<JsPluginUpdateResult>
Enables or disables a single plugin.
dmn.js.setContent(content: string): Promise<JsSetContentResult>
Replaces the inline JS content.
dmn.js.reset(): Promise<void>
Disables JS plugins and clears the plugin list.
dmn.js.onUse(callback): Unsubscribe
Subscribes to enable/disable changes ({ enabled: boolean }).
dmn.js.onState(callback): Unsubscribe
Subscribes to plugin list changes. The callback receives CustomJs.
const unsub = dmn.js.onState(({ plugins }) => {
console.log(
"plugins:",
plugins.map((p) => `${p.name}(${p.enabled ? "on" : "off"})`),
);
});