From 378642152eb4619b9713cee76c6f9dd9c4f4cc46 Mon Sep 17 00:00:00 2001 From: Florian Egger Date: Tue, 19 May 2026 17:39:10 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20plugin=20cannot=20be=20installed=20?= =?UTF-8?q?=E2=80=94=20manifest=20path,=20deps,=20and=20install=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - manifest.json: fix 'main' from 'src/main.js' to 'dist/main.js' (TypeScript compiles to dist/, not src/ — Obsidian could not find the entry point) - manifest.json: set isDesktopOnly to true (plugin requires a local Ollama server) - package.json: remove unused node-fetch dependency (ESM-only, conflicts with CommonJS build) - src/semantic-cache.ts: use dynamic import for chromadb instead of top-level import (prevents plugin load crash when chromadb is not installed; cache defaults to disabled) - install.sh: new script that installs deps, builds, and copies the plugin into a vault - README.md: add quick install, manual install, and expanded troubleshooting sections --- README.md | 60 +++++++++++++++---- install.sh | 133 ++++++++++++++++++++++++++++++++++++++++++ manifest.json | 2 +- package.json | 1 - src/semantic-cache.ts | 19 +++--- 5 files changed, 192 insertions(+), 23 deletions(-) create mode 100755 install.sh diff --git a/README.md b/README.md index 57f43d9..7c1cda4 100755 --- a/README.md +++ b/README.md @@ -11,11 +11,6 @@ A plugin that integrates [Ollama](https://ollama.ai) with Obsidian, allowing you - Semantic response cache — repeated or similar queries are answered instantly without hitting the model (requires ChromaDB) - Customisable model, URL, and cache settings -## Installation - -1. Install the plugin via Obsidian's community plugins -2. Make sure you have Ollama installed and running - ## Prerequisites 1. **Install Ollama**: Follow the instructions at [ollama.ai](https://ollama.ai) @@ -40,14 +35,58 @@ The semantic cache stores responses in a local [ChromaDB](https://www.trychroma. ``` 4. Enable the cache in the plugin settings and configure the ChromaDB URL. +## Installation + +### Quick install (recommended) + +Use the included install script. It handles dependency installation, building, and copying the plugin into your vault: + +```bash +# Clone or download this repository, then run: +./install.sh /path/to/your/obsidian/vault +``` + +The script will: +- Install npm dependencies (excluding Ollama — you install that separately) +- Compile the TypeScript plugin +- Copy the built plugin into `/.obsidian/plugins/ollama-plugin/` + +### Manual install + +If you prefer to install manually: + +```bash +npm install +npm run build +``` + +Then copy the plugin into your vault: + +```bash +mkdir -p /path/to/vault/.obsidian/plugins/ollama-plugin +cp manifest.json /path/to/vault/.obsidian/plugins/ollama-plugin/ +cp -r dist /path/to/vault/.obsidian/plugins/ollama-plugin/ +cp -r node_modules/chromadb /path/to/vault/.obsidian/plugins/ollama-plugin/node_modules/ # optional: only needed for semantic cache +``` + +> **Note:** The `obsidian` npm package is a dev-only type stub — Obsidian provides its own API at runtime. The `chromadb` package is only needed if you enable the semantic cache feature. + +### After installation + +1. Restart Obsidian (or reload: `Ctrl+Shift+P` → "Reload app without saving") +2. Go to **Settings → Community plugins** → enable **Ollama Plugin** +3. Configure the plugin at **Settings → Ollama Settings** + ## Configuration -Open **Settings → Ollama Chat** to configure the plugin. +Open **Settings → Ollama Settings** to configure the plugin. | Setting | Default | Description | -|-----|- -- ----|-------| +|---------|---------|-------------| | Ollama URL | `http://localhost:11434` | Base URL of your Ollama instance | | Model | `llama3` | Model used for chat responses | +| Vault Search Limit | `3` | Maximum number of vault entries to include in context | +| Max Message History | `50` | Maximum number of messages kept in conversation history | | Enable Semantic Cache | Off | Cache responses for fast repeated queries | | ChromaDB URL | `http://localhost:8000` | URL of your running ChromaDB instance | | Cache Embedding Model | `nomic-embed-text` | Ollama model used to generate cache embeddings | @@ -56,7 +95,7 @@ Open **Settings → Ollama Chat** to configure the plugin. ## Usage -1. Click the ribbon icon to open the chat view +1. Open the chat view via the command palette (`Ctrl+P` → "Open Ollama Chat") or the ribbon icon 2. Type your message in the input box 3. Press **Enter** or click **Send** to send your message 4. Press **Shift+Enter** to insert a line break @@ -104,7 +143,8 @@ npm test ## Troubleshooting | Symptom | Likely cause | Fix | -|-----|- -----|---| +|---------|-------------|-----| +| Plugin doesn't appear in Obsidian | Install script was not run or failed | Run `./install.sh /path/to/vault` and reload Obsidian | | Cannot connect to Ollama | Ollama is not running | Run `ollama serve` | | Model not found | Model not pulled | Run `ollama pull ` | | Semantic cache unavailable (notice shown) | ChromaDB is not running, or the ChromaDB URL is wrong | Start ChromaDB (`chroma run`) and verify the URL in settings | @@ -141,4 +181,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..fbba997 --- /dev/null +++ b/install.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env bash +# +# install.sh — Install the Ollama Plugin into an Obsidian vault +# +# Usage: +# ./install.sh /path/to/your/vault +# +# The script will: +# 1. Install npm dependencies (excluding Ollama itself — you need that separately) +# 2. Compile the TypeScript plugin +# 3. Copy the built plugin into /.obsidian/plugins/ollama-plugin/ +# +# Prerequisites: +# - Node.js and npm +# - Ollama installed and running (https://ollama.ai) +# + +set -euo pipefail + +# ── Helpers ────────────────────────────────────────────────────────────────── + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BOLD='\033[1m' +NC='\033[0m' # No Color + +info() { printf "${GREEN}→${NC} %s\n" "$1"; } +warn() { printf "${YELLOW}⚠${NC} %s\n" "$1"; } +error() { printf "${RED}✗${NC} %s\n" "$1"; } +step() { printf "\n${BOLD}══ %s ══${NC}\n" "$1"; } + +# ── Argument validation ────────────────────────────────────────────────────── + +VAULT_PATH="${1:-}" + +if [ -z "$VAULT_PATH" ]; then + echo "Usage: ./install.sh /path/to/your/vault" + echo "" + echo " Provide the path to your Obsidian vault directory." + echo " The plugin will be installed into /.obsidian/plugins/ollama-plugin/" + exit 1 +fi + +if [ ! -d "$VAULT_PATH" ]; then + error "Vault directory does not exist: $VAULT_PATH" + exit 1 +fi + +if [ ! -d "$VAULT_PATH/.obsidian" ]; then + warn "No .obsidian folder found in $VAULT_PATH — this may not be a valid Obsidian vault." + warn "Continuing anyway, but the plugin may not load." +fi + +PLUGIN_DIR="$VAULT_PATH/.obsidian/plugins/ollama-plugin" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +# ── Check prerequisites ────────────────────────────────────────────────────── + +step "Checking prerequisites" + +if ! command -v node &> /dev/null; then + error "Node.js is required but not found. Install it from https://nodejs.org" + exit 1 +fi +info "Node.js $(node --version)" + +if ! command -v npm &> /dev/null; then + error "npm is required but not found." + exit 1 +fi +info "npm $(npm --version)" + +# ── Install dependencies ───────────────────────────────────────────────────── + +step "Installing npm dependencies" + +cd "$SCRIPT_DIR" +npm install --production +info "Dependencies installed" + +# ── Build ──────────────────────────────────────────────────────────────────── + +step "Building the plugin" + +npm run build +info "Build complete" + +# ── Install into vault ─────────────────────────────────────────────────────── + +step "Installing into vault" + +mkdir -p "$PLUGIN_DIR" + +# Copy manifest and built output +cp "$SCRIPT_DIR/manifest.json" "$PLUGIN_DIR/" +cp -r "$SCRIPT_DIR/dist" "$PLUGIN_DIR/" + +# Copy only necessary runtime dependencies (obsidian and chromadb stubs) +# The obsidian package is only used for type definitions at build time — +# at runtime Obsidian provides its own API, so we don't need it in node_modules. +# chromadb is loaded dynamically and only needed when the cache is enabled. +mkdir -p "$PLUGIN_DIR/node_modules" +if [ -d "$SCRIPT_DIR/node_modules/chromadb" ]; then + cp -r "$SCRIPT_DIR/node_modules/chromadb" "$PLUGIN_DIR/node_modules/" +fi + +info "Plugin installed to $PLUGIN_DIR" + +# ── Verify ──────────────────────────────────────────────────────────────────── + +step "Verifying installation" + +if [ -f "$PLUGIN_DIR/manifest.json" ] && [ -f "$PLUGIN_DIR/dist/main.js" ]; then + info "manifest.json ✓" + info "dist/main.js ✓" +else + error "Installation verification failed — missing files in $PLUGIN_DIR" + exit 1 +fi + +echo "" +echo " ${GREEN}${BOLD}Done!${NC} The plugin has been installed." +echo "" +echo " Next steps:" +echo " 1. Restart Obsidian (or reload plugins: Ctrl+Shift+P → 'Reload app without saving')" +echo " 2. Go to Settings → Community plugins → enable 'Ollama Plugin'" +echo " 3. Configure the plugin: Settings → Ollama Settings" +echo "" +echo " Make sure Ollama is running:" +echo " ollama serve" +echo " ollama pull llama3 (or your preferred model)" +echo "" diff --git a/manifest.json b/manifest.json index 183fd88..73d92b5 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "description": "Ollama integration plugin for Obsidian", "author": "Anonymous", "authorUrl": "", - "isDesktopOnly": false, + "isDesktopOnly": true, "main": "dist/main.js", "authorization": [], "permissions": [], diff --git a/package.json b/package.json index 9eb42c8..a589b23 100755 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ }, "dependencies": { "chromadb": "^1.5.3", - "node-fetch": "^3.3.2", "obsidian": "^1.4.11" } } diff --git a/src/semantic-cache.ts b/src/semantic-cache.ts index f80f162..108f09c 100644 --- a/src/semantic-cache.ts +++ b/src/semantic-cache.ts @@ -1,13 +1,11 @@ -// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return -/* eslint-disable */ // src/semantic-cache.ts -import { ChromaClient } from 'chromadb'; import { Logger } from './utils'; import { CacheConfig } from './types'; export class SemanticCacheService { - private client: ChromaClient; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private client: any | null = null; // eslint-disable-next-line @typescript-eslint/no-explicit-any private collection: any | null = null; private config: CacheConfig; @@ -16,15 +14,17 @@ export class SemanticCacheService { constructor(ollamaURL: string, config: CacheConfig) { this.ollamaURL = ollamaURL.replace(/\/+$/, ''); this.config = config; - // Use configurable ChromaDB URL or default to localhost - const chromaURL = config.chromaURL || 'http://localhost:8000'; - this.client = new ChromaClient({ path: chromaURL }); } async initialize(): Promise { if (!this.config.enabled) return; try { + // Dynamic import — chromadb is optional and may not be installed. + // This prevents the plugin from crashing at load time if chromadb is absent. + const { ChromaClient } = await import('chromadb'); + const chromaURL = this.config.chromaURL || 'http://localhost:8000'; + this.client = new ChromaClient({ path: chromaURL }); this.collection = await this.client.getOrCreateCollection({ name: this.config.collectionName, metadata: { 'hnsw:space': 'cosine' }, @@ -49,11 +49,8 @@ export class SemanticCacheService { }); if (results.ids[0] && results.ids[0].length > 0) { - const [id] = results.ids[0]; - const [content] = results.documents[0]; - if (results.distances[0] && results.distances[0][0] > this.config.similarityThreshold) { - return content; + return results.documents[0][0]; } }