diff --git a/src/cache/searchData.js b/src/cache/searchData.js index 32fe8663..afed3c63 100644 --- a/src/cache/searchData.js +++ b/src/cache/searchData.js @@ -1 +1 @@ -export const posts = [{"id":"2018-01-05-vscode-debugging","date":"2018-01-05","title":"vscode debugging"},{"id":"2018-11-11-react-instead-of-jsp","date":"2018-11-11","title":"react instead of jsp"},{"id":"2018-11-11-ssr-with-react","date":"2018-11-11","title":"ssr with react"},{"id":"2018-11-22-react-served-by-express-running-in-docker","date":"2018-11-22","title":"react served by express running in docker"},{"id":"2018-12-29-free-static-site","date":"2018-12-29","title":"free static site"},{"id":"2019-12-13-browser-tools","date":"2019-12-13","title":"browser tools"},{"id":"2019-12-15-svelte","date":"2019-12-15","title":"svelte"},{"id":"2020-02-04-jest-coverage","date":"2020-02-04","title":"jest coverage"},{"id":"2020-05-19-ssr-with-react-redux","date":"2020-05-19","title":"ssr with react redux"},{"id":"2020-09-24-javascript-uncanny-valley","date":"2020-09-24","title":"javascript uncanny valley"},{"id":"2020-09-29-uuid-as-apassword","date":"2020-09-29","title":"uuid as apassword"},{"id":"2020-1-16-css-grid","title":"2020-1-16-css-grid"},{"id":"2020-10-05-serverless-functions-on-netlify","date":"2020-10-05","title":"serverless functions on netlify"},{"id":"2020-10-06-deploy-serverless-function-on-netlify","date":"2020-10-06","title":"deploy serverless function on netlify"},{"id":"2020-10-15-browser-debugging-with-breakpoints","date":"2020-10-15","title":"browser debugging with breakpoints"},{"id":"2020-10-18-loop-vs-function","date":"2020-10-18","title":"loop vs function"},{"id":"2020-12-03-jsonresume","date":"2020-12-03","title":"jsonresume"},{"id":"2020-12-23-animation","date":"2020-12-23","title":"animation"},{"id":"2021-01-12-whatsapp-by-facebook","date":"2021-01-12","title":"whatsapp by facebook"},{"id":"2021-01-23-next-js-blog","date":"2021-01-23","title":"next js blog"},{"id":"2021-03-06-vue-js-solar","date":"2021-03-06","title":"vue js solar"},{"id":"2021-04-11-electron-basics","date":"2021-04-11","title":"electron basics"},{"id":"2021-04-11-electron-save-file","date":"2021-04-11","title":"electron save file"},{"id":"2021-08-07-pagination","date":"2021-08-07","title":"pagination"},{"id":"2021-10-09-publish-pagination","date":"2021-10-09","title":"publish pagination"},{"id":"2022-01-10-recursive-function","date":"2022-01-10","title":"recursive function"},{"id":"2022-05-02-tools","date":"2022-05-02","title":"tools"},{"id":"2022-09-19-applicant-list","date":"2022-09-19","title":"applicant list"},{"id":"2024-01-21-deploy-astro-static-on-deno-deploy","date":"2024-01-21","title":"deploy astro static on deno deploy"},{"id":"2025-05-31-prompt-engineering-do-dont","date":"2025-05-31","title":"prompt engineering do dont"},{"id":"2025-06-14-claude-code-feature-output","date":"2025-06-14","title":"claude code feature output"},{"id":"2025-08-20-intl-segmenter","date":"2025-08-20","title":"intl segmenter"},{"id":"2025-08-27-best-note-taking-tools","date":"2025-08-27","title":"best note taking tools"},{"id":"2025-10-29-top-10-sites-blocking-openai-bot","date":"2025-10-29","title":"top 10 sites blocking openai bot"},{"id":"2025-11-24-building-basic-pomo-with-antigravity","date":"2025-11-24","title":"building basic pomo with antigravity"},{"id":"2025-12-15-remix-run-how-it-works","date":"2025-12-15","title":"remix run how it works"},{"id":"2025-12-16-the-windows-11-crisis","date":"2025-12-16","title":"the windows 11 crisis"},{"id":"2025-12-19-project-vend-ai-vending-machine","date":"2025-12-19","title":"project vend ai vending machine"},{"id":"2026-01-05-free-ai-learning-resources-nvidia-google-microsoft","date":"2026-01-05","title":"free ai learning resources nvidia google microsoft"},{"id":"2026-01-13-ucp-protocol","date":"2026-01-13","title":"ucp protocol"},{"id":"2026-01-14-google-tools-for-developers","date":"2026-01-14","title":"google tools for developers"},{"id":"2026-02-05-opencode-ai-coding-agent","date":"2026-02-05","title":"opencode ai coding agent"},{"id":"2026-02-18-leveraging-agent-skills-in-web-development","date":"2026-02-18","title":"leveraging agent skills in web development"},{"id":"2026-03-05-llm-developer-platforms-comparison","date":"2026-03-05","title":"llm developer platforms comparison"}]; \ No newline at end of file +export const posts = [{"id":"2018-01-05-vscode-debugging","date":"2018-01-05","title":"vscode debugging"},{"id":"2018-11-11-react-instead-of-jsp","date":"2018-11-11","title":"react instead of jsp"},{"id":"2018-11-11-ssr-with-react","date":"2018-11-11","title":"ssr with react"},{"id":"2018-11-22-react-served-by-express-running-in-docker","date":"2018-11-22","title":"react served by express running in docker"},{"id":"2018-12-29-free-static-site","date":"2018-12-29","title":"free static site"},{"id":"2019-12-13-browser-tools","date":"2019-12-13","title":"browser tools"},{"id":"2019-12-15-svelte","date":"2019-12-15","title":"svelte"},{"id":"2020-02-04-jest-coverage","date":"2020-02-04","title":"jest coverage"},{"id":"2020-05-19-ssr-with-react-redux","date":"2020-05-19","title":"ssr with react redux"},{"id":"2020-09-24-javascript-uncanny-valley","date":"2020-09-24","title":"javascript uncanny valley"},{"id":"2020-09-29-uuid-as-apassword","date":"2020-09-29","title":"uuid as apassword"},{"id":"2020-1-16-css-grid","title":"2020-1-16-css-grid"},{"id":"2020-10-05-serverless-functions-on-netlify","date":"2020-10-05","title":"serverless functions on netlify"},{"id":"2020-10-06-deploy-serverless-function-on-netlify","date":"2020-10-06","title":"deploy serverless function on netlify"},{"id":"2020-10-15-browser-debugging-with-breakpoints","date":"2020-10-15","title":"browser debugging with breakpoints"},{"id":"2020-10-18-loop-vs-function","date":"2020-10-18","title":"loop vs function"},{"id":"2020-12-03-jsonresume","date":"2020-12-03","title":"jsonresume"},{"id":"2020-12-23-animation","date":"2020-12-23","title":"animation"},{"id":"2021-01-12-whatsapp-by-facebook","date":"2021-01-12","title":"whatsapp by facebook"},{"id":"2021-01-23-next-js-blog","date":"2021-01-23","title":"next js blog"},{"id":"2021-03-06-vue-js-solar","date":"2021-03-06","title":"vue js solar"},{"id":"2021-04-11-electron-basics","date":"2021-04-11","title":"electron basics"},{"id":"2021-04-11-electron-save-file","date":"2021-04-11","title":"electron save file"},{"id":"2021-08-07-pagination","date":"2021-08-07","title":"pagination"},{"id":"2021-10-09-publish-pagination","date":"2021-10-09","title":"publish pagination"},{"id":"2022-01-10-recursive-function","date":"2022-01-10","title":"recursive function"},{"id":"2022-05-02-tools","date":"2022-05-02","title":"tools"},{"id":"2022-09-19-applicant-list","date":"2022-09-19","title":"applicant list"},{"id":"2024-01-21-deploy-astro-static-on-deno-deploy","date":"2024-01-21","title":"deploy astro static on deno deploy"},{"id":"2025-05-31-prompt-engineering-do-dont","date":"2025-05-31","title":"prompt engineering do dont"},{"id":"2025-06-14-claude-code-feature-output","date":"2025-06-14","title":"claude code feature output"},{"id":"2025-08-20-intl-segmenter","date":"2025-08-20","title":"intl segmenter"},{"id":"2025-08-27-best-note-taking-tools","date":"2025-08-27","title":"best note taking tools"},{"id":"2025-10-29-top-10-sites-blocking-openai-bot","date":"2025-10-29","title":"top 10 sites blocking openai bot"},{"id":"2025-11-24-building-basic-pomo-with-antigravity","date":"2025-11-24","title":"building basic pomo with antigravity"},{"id":"2025-12-15-remix-run-how-it-works","date":"2025-12-15","title":"remix run how it works"},{"id":"2025-12-16-the-windows-11-crisis","date":"2025-12-16","title":"the windows 11 crisis"},{"id":"2025-12-19-project-vend-ai-vending-machine","date":"2025-12-19","title":"project vend ai vending machine"},{"id":"2026-01-05-free-ai-learning-resources-nvidia-google-microsoft","date":"2026-01-05","title":"free ai learning resources nvidia google microsoft"},{"id":"2026-01-13-ucp-protocol","date":"2026-01-13","title":"ucp protocol"},{"id":"2026-01-14-google-tools-for-developers","date":"2026-01-14","title":"google tools for developers"},{"id":"2026-02-05-opencode-ai-coding-agent","date":"2026-02-05","title":"opencode ai coding agent"},{"id":"2026-02-18-leveraging-agent-skills-in-web-development","date":"2026-02-18","title":"leveraging agent skills in web development"},{"id":"2026-02-20-obsidian-cli-productivity","date":"2026-02-20","title":"obsidian cli productivity"},{"id":"2026-03-05-llm-developer-platforms-comparison","date":"2026-03-05","title":"llm developer platforms comparison"}]; \ No newline at end of file diff --git a/src/pages/blog/2026-02-20-obsidian-cli-productivity/index.md b/src/pages/blog/2026-02-20-obsidian-cli-productivity/index.md new file mode 100644 index 00000000..964ab0c1 --- /dev/null +++ b/src/pages/blog/2026-02-20-obsidian-cli-productivity/index.md @@ -0,0 +1,165 @@ +--- +title: "Developer's Introduction to the Obsidian CLI" +description: "Obsidian 1.12 introduces an official binary. Bridge your vault with your shell and manage the security risks of a CLI-enabled knowledge base." +createdDate: "2026-02-20" +published: true +status: "published" +pubDate: "2026-02-20" +readTime: "8 min read" +layout: "../../../layouts/BlogArticle.astro" +--- + +With [Obsidian 1.12](https://obsidian.md/changelog), your vault is no longer trapped behind a GUI. It’s a binary. An official Command Line Interface (CLI) allows you to treat your notes as part of your shell ecosystem—enabling zero-friction capture, AI-agentic workflows, and automated maintenance. + +--- + +## Quick Setup + +The CLI is bundled with the Obsidian 1.12 installer. + +1. **Activate**: **Settings → General → Command line interface** → "On." +2. **Path Registration**: + * **macOS**: `export PATH="$PATH:/Applications/Obsidian.app/Contents/MacOS"` + * **Linux**: Symlinked to `/usr/local/bin/obsidian`. + * **Windows**: Use `Obsidian.com`. + +Verify with `obsidian help`. + +> [!CAUTION] +> **Power with Responsibility**: The CLI grants deep access to your vault and the Obsidian runtime. Review the [Security & Risks](#security-considerations--risks) section before building complex pipelines. + + +--- + +## The Force Multiplier: High-Impact Workflows + +The real power of a CLI isn't in typing commands; it’s in *combining* them. Here are four "Force Multiplier" patterns that will fundamentally change how you interact with your knowledge. + +### 1. The "Ghost Capture" Pipeline +Stop app-switching for small tasks. Instead, create a shell function that appends data to your daily note silently in the background. + +```bash +# Add this to your .zshrc +q() { + if [[ -z "$1" ]]; then + echo "Usage: q 'task description'" + return 1 + fi + # Basic sanitization to prevent accidental flag injection + local content="- [ ] ${1//\"/\\\"} #inbox" + obsidian daily:append content="$content" + echo "Captured to Inbox: $1" +} +``` +**The result:** Typing `q "Email the architect about the API spec"` while mid-refactor in your IDE ensures the task is logged without you ever seeing the Obsidian UI. + +### 2. Search & Jump (fzf + ripgrep) +Obsidian’s built-in search is great, but it can’t compete with the speed of `ripgrep` and the interactivity of `fzf`. Combine them to create a "Universal Note Picker." + +```bash +# Search for a term and open the file in Obsidian +note-search() { + local term="$1" + # Use ripgrep to find matches, fzf for selection, bat for preview + local file=$(rg --files-with-matches "$term" | fzf --preview 'bat --color=always {}') + + if [[ -n "$file" ]]; then + obsidian open "$file" + fi +} +``` +This script searches your entire vault for a string, shows you a syntax-highlighted preview of the matching files, and opens the winner in Obsidian instantly. + +### 3. The "Agentic" Knowledge Injection +AI agents like [OpenCode](/blog/2026-02-05-opencode-ai-coding-agent) or [Claude Code](https://anthropic.com) are becoming standard in the developer toolkit. By using the CLI, you can now give these agents a "Read-Only" (or Read-Write) view of your knowledge base. + +* **The Workflow**: "Hey OpenCode, search my Obsidian vault for 'Redis Caching' and summarize my previous findings." +* **The Bridge**: The agent executes `obsidian search query="Redis Caching"` and `obsidian read` to gather context. + +**Critique**: While powerful, this "Agentic Bridge" is a double-edged sword. You are giving an LLM the ability to read your private notes. If the agent is compromised or suffers from prompt injection, it could leak your personal data or, worse, overwrite critical notes if granted write access. + +### 4. Git-Hook Dashboards +If you keep your vault in a Git repo, you can use `post-commit` hooks to update a "Project Dashboard" automatically. + +```bash +#!/bin/bash +# .git/hooks/post-commit +# Ensure we're not in a headless environment without a bridge +if ! pgrep -x "Obsidian" > /dev/null; then + exit 0 +fi + +TIMESTAMP=$(date "+%Y-%m-%d %H:%M") +COMMIT_MSG=$(git log -1 --pretty=%B) +# Escape newlines for the CLI command +ESCAPED_MSG=$(echo "$COMMIT_MSG" | sed ':a;N;$!ba;s/\n/\\n/g') + +obsidian daily:append content="### Git Commit @ $TIMESTAMP \n- $ESCAPED_MSG" +``` +Every time you commit code, your daily note is updated with a log of what you did. This is a game-changer for weekly reviews and stand-up preparation. + +--- + +## Security Considerations & Risks + +The Obsidian CLI is a powerful tool, and with great power comes significant security responsibility. As a developer, you should be aware of the following risks: + +### 1. The `obsidian eval` Nuclear Option +The `obsidian eval` command allows for arbitrary JavaScript execution within the Obsidian context. This context has access to the [Obsidian API](https://marcus.se.net/obsidian-plugin-docs/), the file system, and potentially sensitive environment variables. +* **Risk**: If a malicious script or a compromised AI agent executes `obsidian eval`, it can effectively take over your vault, steal data, or even execute system-level commands via Node.js integrations. +* **Mitigation**: Never run `eval` commands from untrusted sources. If using an AI agent, restrict its permissions to specific, non-destructive CLI commands. + +### 2. Shell Injection in Automation +When building shell functions like the "Ghost Capture" example, you must be careful with how user input is handled. +* **Risk**: A maliciously crafted input could potentially "break out" of the intended command. For example, `q "Note title\"; rm -rf /; #"` might cause unexpected behavior depending on how the CLI wrapper handles arguments. +* **Mitigation**: Always use quotes around variables in your shell scripts and perform basic sanitization (as shown in the refined `q()` function above). + +### 3. Privacy & AI Data Leakage +Connecting tools like OpenCode to your vault means your private thoughts are being processed by an LLM. +* **Risk**: Sensitive information (passwords, private keys, personal reflections) stored in your vault could be included in the LLM's context window and potentially logged by the provider. +* **Mitigation**: Use a `.obsidianignore` file (or similar) to prevent agents from indexing sensitive folders. Be mindful of what you ask agents to search for. + +### 4. Headless Bridge Vulnerabilities +The "Bridge" architecture requires a running app to listen for commands. +* **Risk**: If the communication channel (e.g., a local WebSocket or Unix socket) is not properly secured, other local users or processes on the same machine could send commands to your Obsidian instance. + +--- + +## Practical Limitations & Edge Cases + +Before moving your entire workflow to the CLI, consider these practical hurdles: + +* **The "Running App" Requirement**: Unless you use [Headless Sync](https://obsidian.md/help/sync/headless), the CLI commands will fail (or launch the GUI) if Obsidian isn't already open. This makes it unsuitable for truly headless cron jobs on a server. +* **Race Conditions**: Appending to the same file from multiple concurrent shell scripts can occasionally lead to data loss or "Conflicted Copy" sync errors if the internal indexer hasn't caught up. +* **Performance with Large Vaults**: Heavy `obsidian search` queries can momentarily freeze the UI of the running app as the bridge processes the request. +* **Error Handling**: The CLI is often "fire and forget." If a command fails (e.g., due to a locked file), you might not get a clear non-zero exit code back to your shell. + +--- + +## For the Builders: Developer Loops + +If you build Obsidian plugins or themes, the CLI is your new best friend. It exposes internal DevTools capabilities directly to the terminal. + +* **Hot-Reloading**: Link your build script to the CLI: `"build": "esbuild ... && obsidian plugin:reload my-plugin"`. No more manual "Disable/Enable" toggling. +* **Mobile Auditing**: Use `obsidian dev:mobile on` to toggle the mobile emulator for UI testing. +* **State Inspection**: Run `obsidian eval code="app.vault.getFiles().length"` to verify vault statistics or plugin state without opening the console. **Warning**: Use `eval` only in controlled, local development environments. + +--- + +## Strategy: The "Running App" Constraint + +It is a common point of confusion: **Does the Obsidian CLI work headless?** + +By default, the `obsidian` command acts as a bridge to a *running* instance of the app. If the app isn't open, the command will typically launch it. + +**For truly headless server usage**, you should look into **[Headless Sync](https://obsidian.md/help/sync/headless)**. This is a specialized mode designed for CI/CD environments and remote servers that allows for background synchronization and CLI interaction without a GUI or Window Server. + +--- + +## Conclusion: Balanced Interoperability + +The Obsidian CLI removes the wall around your knowledge base, allowing your notes to participate in your broader digital ecosystem. This interoperability expands your attack surface, so the goal is finding the balance between **frictionless productivity** and **robust security**. + +Start small: replace one manual capture step with a shell function this week, audit how it handles data, and scale your automation as you gain confidence in the security of your pipelines. + +Happy scripting!