diff --git a/main.js b/main.js index 09d45bf..bbcefa3 100644 --- a/main.js +++ b/main.js @@ -209,9 +209,8 @@ class ManexStudyRoomPlugin extends Plugin { throw new Error("Python installed but still not found — restart Obsidian and try again."); } - throw new Error( - "Python 3 is required but not installed. Install it from https://python.org or via Homebrew (brew install python), then restart Obsidian." - ); + new PythonSetupModal(this.app).open(); + throw new Error("Python 3 not found. See the setup instructions in the Manex Brain dialog."); } getVenvPath() { @@ -1013,6 +1012,48 @@ class ManexStudyRoomView extends ItemView { } } +class PythonSetupModal extends Modal { + onOpen() { + const { contentEl } = this; + contentEl.empty(); + contentEl.createEl("h2", { text: "Python 3 Required" }); + contentEl.createEl("p", { + text: "Manex Brain needs Python 3 to run the local AI model. Follow the steps below to get set up." + }); + + contentEl.createEl("h3", { text: "Step 1 — Install Homebrew" }); + contentEl.createEl("p", { text: "Homebrew is a package manager for macOS. Paste this into Terminal:" }); + const brewCmd = `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`; + this._codeRow(contentEl, brewCmd, "Copy Homebrew install command"); + + contentEl.createEl("h3", { text: "Step 2 — Install Python" }); + contentEl.createEl("p", { text: "Once Homebrew is installed, run this in Terminal:" }); + this._codeRow(contentEl, "brew install python3", "Copy Python install command"); + + contentEl.createEl("h3", { text: "Step 3 — Restart Obsidian" }); + contentEl.createEl("p", { text: "After Python is installed, restart Obsidian and Manex Brain will start automatically." }); + + const buttonRow = contentEl.createDiv({ cls: "manex-entitlement-actions" }); + buttonRow.createEl("button", { text: "Open brew.sh" }).addEventListener("click", () => { + window.open("https://brew.sh", "_blank"); + }); + buttonRow.createEl("button", { text: "Close" }).addEventListener("click", () => this.close()); + } + + _codeRow(container, cmd, label) { + const wrap = container.createDiv({ cls: "manex-code-row" }); + wrap.createEl("code", { text: cmd }); + const btn = wrap.createEl("button", { text: label }); + btn.addEventListener("click", () => { + navigator.clipboard.writeText(cmd); + btn.setText("Copied!"); + setTimeout(() => btn.setText(label), 2000); + }); + } + + onClose() { this.contentEl.empty(); } +} + class MemoryModal extends Modal { constructor(app, options) { super(app); diff --git a/manifest.json b/manifest.json index ac0342a..d28ea98 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "manex-brain", "name": "Manex Brain", - "version": "1.0.2", + "version": "1.0.3", "minAppVersion": "1.5.0", "description": "Local AI brain for your vault. Indexes all your notes and answers questions privately using a local Apple Silicon MLX model — no cloud, no API keys.", "author": "Manex", diff --git a/styles.css b/styles.css index 59bb01c..477664a 100644 --- a/styles.css +++ b/styles.css @@ -334,3 +334,21 @@ width: 100%; min-height: 160px; } + +.manex-code-row { + display: flex; + align-items: center; + gap: 10px; + margin: 6px 0 14px; + padding: 8px 12px; + border: 1px solid var(--background-modifier-border); + border-radius: 8px; + background: var(--background-secondary); +} + +.manex-code-row code { + flex: 1; + font-size: var(--font-ui-smaller); + word-break: break-all; + background: none; +} diff --git a/versions.json b/versions.json index 43d4f38..c80be4c 100644 --- a/versions.json +++ b/versions.json @@ -1,5 +1,6 @@ { "1.0.0": "1.5.0", "1.0.1": "1.5.0", - "1.0.2": "1.5.0" + "1.0.2": "1.5.0", + "1.0.3": "1.5.0" }