From 13dcd8bb5a1b607158dd05afccd895d0746f885d Mon Sep 17 00:00:00 2001 From: Mateusz Tymek Date: Sat, 3 Jan 2026 20:35:40 +0000 Subject: [PATCH] Use proper OpenCode icon --- main.js | 72 +++++++++++++++++++++++++++------------------ src/OpenCodeView.ts | 5 ++-- src/icons.ts | 14 +++++++++ src/main.ts | 6 +++- 4 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 src/icons.ts diff --git a/main.js b/main.js index aa925aa..3e83a5d 100644 --- a/main.js +++ b/main.js @@ -27,7 +27,7 @@ __export(main_exports, { default: () => OpenCodePlugin }); module.exports = __toCommonJS(main_exports); -var import_obsidian4 = require("obsidian"); +var import_obsidian5 = require("obsidian"); // src/types.ts var DEFAULT_SETTINGS = { @@ -40,8 +40,21 @@ var DEFAULT_SETTINGS = { var OPENCODE_VIEW_TYPE = "opencode-view"; // src/OpenCodeView.ts +var import_obsidian2 = require("obsidian"); + +// src/icons.ts var import_obsidian = require("obsidian"); -var OpenCodeView = class extends import_obsidian.ItemView { +var OPENCODE_ICON_NAME = "opencode-logo"; +var OPENCODE_LOGO_SVG = ` + + +`; +function registerOpenCodeIcons() { + (0, import_obsidian.addIcon)(OPENCODE_ICON_NAME, OPENCODE_LOGO_SVG); +} + +// src/OpenCodeView.ts +var OpenCodeView = class extends import_obsidian2.ItemView { constructor(leaf, plugin) { super(leaf); this.iframeEl = null; @@ -55,7 +68,7 @@ var OpenCodeView = class extends import_obsidian.ItemView { return "OpenCode"; } getIcon() { - return "terminal"; + return OPENCODE_ICON_NAME; } async onOpen() { this.contentEl.empty(); @@ -98,7 +111,7 @@ var OpenCodeView = class extends import_obsidian.ItemView { cls: "opencode-status-container" }); const iconEl = statusContainer.createDiv({ cls: "opencode-status-icon" }); - (0, import_obsidian.setIcon)(iconEl, "power-off"); + (0, import_obsidian2.setIcon)(iconEl, "power-off"); statusContainer.createEl("h3", { text: "OpenCode is stopped" }); statusContainer.createEl("p", { text: "Click the button below to start the OpenCode server.", @@ -130,27 +143,27 @@ var OpenCodeView = class extends import_obsidian.ItemView { const headerEl = this.contentEl.createDiv({ cls: "opencode-header" }); const titleSection = headerEl.createDiv({ cls: "opencode-header-title" }); const iconEl = titleSection.createSpan(); - (0, import_obsidian.setIcon)(iconEl, "terminal"); + (0, import_obsidian2.setIcon)(iconEl, OPENCODE_ICON_NAME); titleSection.createSpan({ text: "OpenCode" }); const actionsEl = headerEl.createDiv({ cls: "opencode-header-actions" }); const reloadButton = actionsEl.createEl("button", { attr: { "aria-label": "Reload" } }); - (0, import_obsidian.setIcon)(reloadButton, "refresh-cw"); + (0, import_obsidian2.setIcon)(reloadButton, "refresh-cw"); reloadButton.addEventListener("click", () => { this.reloadIframe(); }); const externalButton = actionsEl.createEl("button", { attr: { "aria-label": "Open in browser" } }); - (0, import_obsidian.setIcon)(externalButton, "external-link"); + (0, import_obsidian2.setIcon)(externalButton, "external-link"); externalButton.addEventListener("click", () => { window.open(this.plugin.getServerUrl(), "_blank"); }); const stopButton = actionsEl.createEl("button", { attr: { "aria-label": "Stop server" } }); - (0, import_obsidian.setIcon)(stopButton, "square"); + (0, import_obsidian2.setIcon)(stopButton, "square"); stopButton.addEventListener("click", () => { this.plugin.stopServer(); }); @@ -175,7 +188,7 @@ var OpenCodeView = class extends import_obsidian.ItemView { cls: "opencode-status-container opencode-error" }); const iconEl = statusContainer.createDiv({ cls: "opencode-status-icon" }); - (0, import_obsidian.setIcon)(iconEl, "alert-circle"); + (0, import_obsidian2.setIcon)(iconEl, "alert-circle"); statusContainer.createEl("h3", { text: "Failed to start OpenCode" }); statusContainer.createEl("p", { text: "There was an error starting the OpenCode server. Please check that OpenCode is installed and try again.", @@ -210,7 +223,7 @@ var OpenCodeView = class extends import_obsidian.ItemView { }; // src/SettingsTab.ts -var import_obsidian2 = require("obsidian"); +var import_obsidian3 = require("obsidian"); var import_fs = require("fs"); var import_os = require("os"); function expandTilde(path) { @@ -222,7 +235,7 @@ function expandTilde(path) { } return path; } -var OpenCodeSettingTab = class extends import_obsidian2.PluginSettingTab { +var OpenCodeSettingTab = class extends import_obsidian3.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.validateTimeout = null; @@ -233,7 +246,7 @@ var OpenCodeSettingTab = class extends import_obsidian2.PluginSettingTab { containerEl.empty(); containerEl.createEl("h2", { text: "OpenCode Settings" }); containerEl.createEl("h3", { text: "Server Configuration" }); - new import_obsidian2.Setting(containerEl).setName("Port").setDesc("Port number for the OpenCode web server").addText( + new import_obsidian3.Setting(containerEl).setName("Port").setDesc("Port number for the OpenCode web server").addText( (text) => text.setPlaceholder("14096").setValue(this.plugin.settings.port.toString()).onChange(async (value) => { const port = parseInt(value, 10); if (!isNaN(port) && port > 0 && port < 65536) { @@ -242,13 +255,13 @@ var OpenCodeSettingTab = class extends import_obsidian2.PluginSettingTab { } }) ); - new import_obsidian2.Setting(containerEl).setName("Hostname").setDesc("Hostname to bind the server to (usually 127.0.0.1)").addText( + new import_obsidian3.Setting(containerEl).setName("Hostname").setDesc("Hostname to bind the server to (usually 127.0.0.1)").addText( (text) => text.setPlaceholder("127.0.0.1").setValue(this.plugin.settings.hostname).onChange(async (value) => { this.plugin.settings.hostname = value || "127.0.0.1"; await this.plugin.saveSettings(); }) ); - new import_obsidian2.Setting(containerEl).setName("OpenCode path").setDesc( + new import_obsidian3.Setting(containerEl).setName("OpenCode path").setDesc( "Path to the OpenCode executable. Leave as 'opencode' if it's in your PATH." ).addText( (text) => text.setPlaceholder("opencode").setValue(this.plugin.settings.opencodePath).onChange(async (value) => { @@ -256,7 +269,7 @@ var OpenCodeSettingTab = class extends import_obsidian2.PluginSettingTab { await this.plugin.saveSettings(); }) ); - new import_obsidian2.Setting(containerEl).setName("Project directory").setDesc( + new import_obsidian3.Setting(containerEl).setName("Project directory").setDesc( "Override the starting directory for OpenCode. Leave empty to use the vault root. Supports ~ for home directory." ).addText( (text) => text.setPlaceholder("/path/to/project or ~/project").setValue(this.plugin.settings.projectDirectory).onChange((value) => { @@ -269,7 +282,7 @@ var OpenCodeSettingTab = class extends import_obsidian2.PluginSettingTab { }) ); containerEl.createEl("h3", { text: "Behavior" }); - new import_obsidian2.Setting(containerEl).setName("Auto-start server").setDesc( + new import_obsidian3.Setting(containerEl).setName("Auto-start server").setDesc( "Automatically start the OpenCode server when Obsidian opens (not recommended for faster startup)" ).addToggle( (toggle) => toggle.setValue(this.plugin.settings.autoStart).onChange(async (value) => { @@ -288,22 +301,22 @@ var OpenCodeSettingTab = class extends import_obsidian2.PluginSettingTab { return; } if (!trimmed.startsWith("/") && !trimmed.startsWith("~") && !trimmed.match(/^[A-Za-z]:\\/)) { - new import_obsidian2.Notice("Project directory must be an absolute path (or start with ~)"); + new import_obsidian3.Notice("Project directory must be an absolute path (or start with ~)"); return; } const expanded = expandTilde(trimmed); try { if (!(0, import_fs.existsSync)(expanded)) { - new import_obsidian2.Notice("Project directory does not exist"); + new import_obsidian3.Notice("Project directory does not exist"); return; } const stat = (0, import_fs.statSync)(expanded); if (!stat.isDirectory()) { - new import_obsidian2.Notice("Project directory path is not a directory"); + new import_obsidian3.Notice("Project directory path is not a directory"); return; } } catch (error) { - new import_obsidian2.Notice(`Failed to validate path: ${error.message}`); + new import_obsidian3.Notice(`Failed to validate path: ${error.message}`); return; } await this.plugin.updateProjectDirectory(expanded); @@ -381,7 +394,7 @@ var OpenCodeSettingTab = class extends import_obsidian2.PluginSettingTab { // src/ProcessManager.ts var import_child_process = require("child_process"); -var import_obsidian3 = require("obsidian"); +var import_obsidian4 = require("obsidian"); var ProcessManager = class { constructor(settings, workingDirectory, projectDirectory, onStateChange) { this.process = null; @@ -416,7 +429,7 @@ var ProcessManager = class { if (!this.projectDirectory) { const error = "Project directory (vault) not configured"; console.error("[OpenCode Error]", error); - new import_obsidian3.Notice(`Failed to start OpenCode: ${error}`); + new import_obsidian4.Notice(`Failed to start OpenCode: ${error}`); this.setState("error"); return false; } @@ -468,7 +481,7 @@ var ProcessManager = class { }); this.process.on("error", (err) => { console.error("Failed to start OpenCode process:", err); - new import_obsidian3.Notice(`Failed to start OpenCode: ${err.message}`); + new import_obsidian4.Notice(`Failed to start OpenCode: ${err.message}`); this.process = null; this.setState("error"); }); @@ -479,7 +492,7 @@ var ProcessManager = class { } else { this.stop(); this.setState("error"); - new import_obsidian3.Notice("OpenCode server failed to start within timeout"); + new import_obsidian4.Notice("OpenCode server failed to start within timeout"); return false; } } catch (error) { @@ -544,7 +557,7 @@ var ProcessManager = class { }; // src/main.ts -var OpenCodePlugin = class extends import_obsidian4.Plugin { +var OpenCodePlugin = class extends import_obsidian5.Plugin { constructor() { super(...arguments); this.settings = DEFAULT_SETTINGS; @@ -553,6 +566,7 @@ var OpenCodePlugin = class extends import_obsidian4.Plugin { } async onload() { console.log("Loading OpenCode plugin"); + registerOpenCodeIcons(); await this.loadSettings(); const vaultPath = this.getVaultPath(); const projectDirectory = this.getProjectDirectory(); @@ -564,7 +578,7 @@ var OpenCodePlugin = class extends import_obsidian4.Plugin { ); console.log("[OpenCode] Configured with project directory:", projectDirectory); this.registerView(OPENCODE_VIEW_TYPE, (leaf) => new OpenCodeView(leaf, this)); - this.addRibbonIcon("terminal", "OpenCode", () => { + this.addRibbonIcon(OPENCODE_ICON_NAME, "OpenCode", () => { this.activateView(); }); this.addCommand({ @@ -667,12 +681,12 @@ var OpenCodePlugin = class extends import_obsidian4.Plugin { // Start the OpenCode server async startServer() { if (!this.processManager) { - new import_obsidian4.Notice("OpenCode: Process manager not initialized"); + new import_obsidian5.Notice("OpenCode: Process manager not initialized"); return false; } const success = await this.processManager.start(); if (success) { - new import_obsidian4.Notice("OpenCode server started"); + new import_obsidian5.Notice("OpenCode server started"); } return success; } @@ -680,7 +694,7 @@ var OpenCodePlugin = class extends import_obsidian4.Plugin { stopServer() { if (this.processManager) { this.processManager.stop(); - new import_obsidian4.Notice("OpenCode server stopped"); + new import_obsidian5.Notice("OpenCode server stopped"); } } // Get the current process state diff --git a/src/OpenCodeView.ts b/src/OpenCodeView.ts index 9ed5507..e8d2366 100644 --- a/src/OpenCodeView.ts +++ b/src/OpenCodeView.ts @@ -1,5 +1,6 @@ import { ItemView, WorkspaceLeaf, setIcon } from "obsidian"; import { OPENCODE_VIEW_TYPE } from "./types"; +import { OPENCODE_ICON_NAME } from "./icons"; import type OpenCodePlugin from "./main"; import { ProcessState } from "./ProcessManager"; @@ -22,7 +23,7 @@ export class OpenCodeView extends ItemView { } getIcon(): string { - return "terminal"; + return OPENCODE_ICON_NAME; } async onOpen(): Promise { @@ -120,7 +121,7 @@ export class OpenCodeView extends ItemView { const titleSection = headerEl.createDiv({ cls: "opencode-header-title" }); const iconEl = titleSection.createSpan(); - setIcon(iconEl, "terminal"); + setIcon(iconEl, OPENCODE_ICON_NAME); titleSection.createSpan({ text: "OpenCode" }); const actionsEl = headerEl.createDiv({ cls: "opencode-header-actions" }); diff --git a/src/icons.ts b/src/icons.ts new file mode 100644 index 0000000..3f9de07 --- /dev/null +++ b/src/icons.ts @@ -0,0 +1,14 @@ +import { addIcon } from "obsidian"; + +export const OPENCODE_ICON_NAME = "opencode-logo"; + +// Monochrome OpenCode "O" logo mark derived from the official brand assets +// Uses currentColor for theme compatibility +const OPENCODE_LOGO_SVG = ` + + +`; + +export function registerOpenCodeIcons(): void { + addIcon(OPENCODE_ICON_NAME, OPENCODE_LOGO_SVG); +} diff --git a/src/main.ts b/src/main.ts index 15d5c7f..70ecba2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,6 +3,7 @@ import { OpenCodeSettings, DEFAULT_SETTINGS, OPENCODE_VIEW_TYPE } from "./types" import { OpenCodeView } from "./OpenCodeView"; import { OpenCodeSettingTab } from "./SettingsTab"; import { ProcessManager, ProcessState } from "./ProcessManager"; +import { registerOpenCodeIcons, OPENCODE_ICON_NAME } from "./icons"; export default class OpenCodePlugin extends Plugin { settings: OpenCodeSettings = DEFAULT_SETTINGS; @@ -12,6 +13,9 @@ export default class OpenCodePlugin extends Plugin { async onload(): Promise { console.log("Loading OpenCode plugin"); + // Register custom icons + registerOpenCodeIcons(); + await this.loadSettings(); // Get the vault directory path to pass to OpenCode @@ -33,7 +37,7 @@ export default class OpenCodePlugin extends Plugin { this.registerView(OPENCODE_VIEW_TYPE, (leaf) => new OpenCodeView(leaf, this)); // Add ribbon icon - this.addRibbonIcon("terminal", "OpenCode", () => { + this.addRibbonIcon(OPENCODE_ICON_NAME, "OpenCode", () => { this.activateView(); });