@qvac/skills 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled.js +1 -1
- package/hash.js +1 -1
- package/package.json +1 -1
- package/skills/obsidian/SKILL.md +18 -0
package/bundled.js
CHANGED
|
@@ -46,7 +46,7 @@ export const SKILLS = {
|
|
|
46
46
|
"notion/references/databases.md": "# Notion Databases, Data Sources and Views\n\nA database holds one or more **data sources** (the typed schema behind it) and **views** over them. Every call is one `mcp_call` with `url: \"https://mcp.notion.com/mcp\"`, the tool name as `method`, and its args as `params` (a JSON object, never a string). Call these tools directly — no `tools/list`.\n\n| tool | required args | use for |\n| --------------------------- | ---------------------------------------- | ------------------------------------------------------------------------ |\n| `notion-fetch` | `id` (database / data-source / view URL) | read the schema, the `collection://` data-source URLs, and the view URLs |\n| `notion-query-data-sources` | `data` (`mode` + its fields) | run a database view, or query rows by SQL |\n| `notion_create_page` | `title`, `parentDatabaseId` | add one row to a database (typed tool — no `params`) |\n| `notion-create-database` | properties for the new database | create a database + its initial data source + view |\n| `notion-update-data-source` | `data_source_id` + fields | rename a data source or edit its properties |\n| `notion-create-view` | `data_source_id`, `name`, `type` | add a table / board / list / calendar / timeline / gallery view |\n| `notion-update-view` | `view_id` + fields | edit a view's name, filters, sorts, or display |\n\n## Reading a database\n\nFetch the database first: the result carries the schema, each data source's `collection://<id>` URL (used as the SQL table name), and each view's URL (the one carrying `?v=<view-id>`).\n\n```json\n{\n \"url\": \"https://mcp.notion.com/mcp\",\n \"method\": \"notion-fetch\",\n \"params\": { \"id\": \"<database id or URL>\" }\n}\n```\n\n## Querying rows\n\n`notion-query-data-sources` nests every argument under `data`, and the two modes take different fields — send the wrong one and the server rejects the call:\n\n| `mode` | carries | for |\n| --------------- | ---------------------------- | ------------------------------------------- |\n| `view` | `view_url` | run a database view's own filters and sorts |\n| `sql` (default) | `data_source_urls` + `query` | filter, group or aggregate rows yourself |\n\nView mode works on every plan, so start there:\n\n```json\n{\n \"url\": \"https://mcp.notion.com/mcp\",\n \"method\": \"notion-query-data-sources\",\n \"params\": { \"data\": { \"mode\": \"view\", \"view_url\": \"<database url including ?v=>\" } }\n}\n```\n\nSQL mode is plan-gated: `data_source_urls` lists the `collection://` URLs and `query` is SQLite using them as table names. If the response is an upgrade prompt, tell the user their plan doesn't support it (single-source needs Business+Notion AI, multi-source needs Enterprise+Notion AI) — don't retry.\n\n## Adding a row\n\nA row is a page whose parent is the database. Use `notion_create_page` with `parentDatabaseId`; the `title` fills the title property and `content` becomes the row's page body:\n\n```json\n{ \"title\": \"Row title\", \"content\": \"Optional body\", \"parentDatabaseId\": \"<database id or URL>\" }\n```\n\nSet other properties afterwards with `notion-update-page` → `update_properties` (see `references/pages.md`).\n\n## Creating and changing structure\n\n`notion-create-database` creates the database with its first data source and view; `notion-update-data-source` renames a data source or changes its properties; `notion-create-view` / `notion-update-view` manage views. Take the `data_source_id` and `view_id` from a `notion-fetch` of the database — never guess them. If the server rejects the call, quote its message and ask the user how to proceed instead of retrying with invented fields.\n\n## Output\n\nLead with counts and rollups when present, then rows; surface user-visible property names, not IDs. Show the database as a `[title](url)` link.\n\n## Now act\n\nYour next output is the tool call (or, after the result, the reply) — no further skill loads.\n",
|
|
47
47
|
"notion/references/pages.md": "# Notion Pages\n\nCreate with `notion_create_page`, add text with `notion_insert_content`; every other call is one `mcp_call` with `url: \"https://mcp.notion.com/mcp\"`, the tool name as `method`, and its args as `params` (a JSON object, never a string). Call these tools directly — no `tools/list`.\n\n| tool | required args | use for |\n| ----------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------- |\n| `notion-fetch` | `id` (page URL or ID, or `\"self\"`) | read a page's properties + content, or the connection identity |\n| `notion_create_page` | `title`; optional `content`, `parentPageId` | create one page (typed tool — no `params`) |\n| `notion-create-pages` | `pages` | create several pages in one request; `allow_async: true` for very large content |\n| `notion_insert_content` | `pageId`, `content`; optional `position` | add text to a page (typed tool — no `params`) |\n| `notion-update-page` | `page_id`, `command`, + its one companion field | change text, rename, set a property, icon, cover |\n| `notion-move-pages` | `page_or_database_ids`, `new_parent` | reparent pages or databases |\n| `notion-duplicate-page` | `page_id` | duplicate a page — always async, poll the returned task (`references/tasks.md`) |\n\nComments are not a page command: to read or add a comment, load `references/comments.md` and use `notion-create-comment` / `notion-get-comments`.\n\n## Reading a page\n\n`notion-fetch` returns the page's properties and its content as Markdown. Always name the page you read (title + link) when reporting its content. A read-only question ends after the read — never follow it with a write.\n\n```json\n{\n \"url\": \"https://mcp.notion.com/mcp\",\n \"method\": \"notion-fetch\",\n \"params\": { \"id\": \"<page id or URL>\" }\n}\n```\n\nFor \"who am I\" / \"which workspace\", the same call with `\"id\": \"self\"` is the fixed one-call answer — never loop on search for it.\n\n## Creating a page\n\nOne user request → one create. `notion_create_page` is a tool of its own, listed beside `mcp_call` — call it directly with these arguments (it is not a `method` for `mcp_call`, and it takes no `url` or `params`):\n\n```json\n{ \"title\": \"Exact title from the user\", \"content\": \"The page body\" }\n```\n\n`title` is the exact title from the user; `content` is optional Markdown (do not repeat the title in the body). For a private standalone page send only those two fields — no parent field at all. Add `\"parentPageId\": \"<page id or URL>\"` only when the user named a parent page, or `\"parentDatabaseId\"` for a database row.\n\nUse `notion-create-pages` through `mcp_call` only when one request asks for several pages. Each entry uses `properties.title` — a plain string — plus optional `content`; leave `parent` out for standalone pages and add `\"parent\": { \"page_id\": \"<id>\" }` beside `pages` only when the user named one:\n\n```json\n{\n \"url\": \"https://mcp.notion.com/mcp\",\n \"method\": \"notion-create-pages\",\n \"params\": {\n \"pages\": [\n { \"properties\": { \"title\": \"First title\" }, \"content\": \"First body\" },\n { \"properties\": { \"title\": \"Second title\" }, \"content\": \"Second body\" }\n ]\n }\n}\n```\n\nOne user request → one `notion-create-pages` write unless they asked for several pages in that request. Never recreate a page to \"make sure\", to fill an empty wrap-up, or because a previous call timed out. After a confirmed create, show the title as a Markdown link from the result `url` and keep the result `id` for follow-up edits. To verify, `notion-search` / `notion-fetch` — do not write again. If create times out or returns an uncertain result: search for the **exact title**, then fetch any title match. Only create again if no exact-title page exists.\n\n## Adding text\n\n`notion_insert_content` is also a tool of its own — call it directly. It appends by default; `\"position\": \"start\"` prepends. It sends `\"command\": \"insert_content\"` to `notion-update-page` for you, so never call that command through `mcp_call`.\n\n```json\n{ \"pageId\": \"<page id or URL>\", \"content\": \"The line to add\" }\n```\n\n## Changing a page\n\n`notion-update-page` always takes `page_id` and `command`. Each command carries **its own one extra field** — send a different one and the server rejects the call, so pick the row before writing:\n\n| `command` | carries | for |\n| --------------------- | --------------------- | ------------------------------------ |\n| `update_content` | `content_updates` | change part of the body |\n| `replace_content` | `new_str` | overwrite the whole body |\n| `update_properties` | `properties` | title, status, any database property |\n| `apply_template` | `template_id` | apply a database template |\n| `update_verification` | `verification_status` | mark a page verified |\n\nRename = `update_properties` with the new title as a plain string:\n\n```json\n{\n \"url\": \"https://mcp.notion.com/mcp\",\n \"method\": \"notion-update-page\",\n \"params\": {\n \"page_id\": \"<page id or URL>\",\n \"command\": \"update_properties\",\n \"properties\": { \"title\": \"New title\" }\n }\n}\n```\n\nReserve `update_content` for changing text that is already there: its `content_updates` is an array of `{ \"old_str\", \"new_str\" }` pairs, `old_str` must match the page exactly, so `notion-fetch` first. `update_content` has no top-level `new_str`. `new_str` is a Markdown string, never an array. Icon and cover can be set alongside any command.\n\n## Archiving (deleting) a page\n\nThis connection cannot move a page to Trash: `notion-update-page` rejects `in_trash`, and there is no delete tool. When the user asks to delete, remove or archive a page, make no tool call — reply that the page has to be deleted in Notion itself (open the page, `•••` menu, **Move to Trash**) and link it. Never empty the page, overwrite its body, rename it or move it as a substitute for deleting it.\n\n## Moving and duplicating\n\n```json\n{\n \"url\": \"https://mcp.notion.com/mcp\",\n \"method\": \"notion-move-pages\",\n \"params\": {\n \"page_or_database_ids\": [\"<page id>\"],\n \"new_parent\": { \"page_id\": \"<new parent id>\" }\n }\n}\n```\n\n`new_parent` is `{ \"page_id\": … }`, `{ \"database_id\": … }`, or `{ \"data_source_id\": … }`. `notion-duplicate-page` takes `page_id` and returns a `task_id`, not the copy — load `references/tasks.md` to poll it before telling the user it is done.\n\n## Output\n\nAfter a write, show the page as a `[title](url)` link and say what changed. After a read, report the content under the page's title and link.\n\n## Now act\n\nYour next output is the tool call (or, after the result, the reply) — no further skill loads.\n",
|
|
48
48
|
"notion/references/tasks.md": "# Notion Async Tasks\n\nSome writes do not finish inside the call. The response then carries a `task_id`, not the final result — poll it, and don't tell the user it's done until the status is `succeeded`. Every call is one `mcp_call` with `url: \"https://mcp.notion.com/mcp\"`, the tool name as `method`, and its args as `params` (a JSON object, never a string).\n\n| tool | required args | use for |\n| ----------------------- | ------------- | ------------------------------- |\n| `notion-get-async-task` | `task_id` | poll an async operation's state |\n\nWhich calls go async:\n\n- `notion-duplicate-page` — always.\n- `notion-create-pages` and `notion-update-page` — when sent with `\"allow_async\": true` (use it only for very large content).\n\n## Polling\n\n```json\n{\n \"url\": \"https://mcp.notion.com/mcp\",\n \"method\": \"notion-get-async-task\",\n \"params\": { \"task_id\": \"<task_id from the prior response>\" }\n}\n```\n\nStatus is `queued`, `running`, `retrying`, `succeeded`, or `failed`. Respect the suggested backoff in the response before polling again; poll at most a few times, then tell the user it is still running and how to check later. On `succeeded`, report the result it carries (for a duplicate, the new page's title as a `[title](url)` link). On `failed`, quote the error and stop — do not retry the original write.\n\n## Now act\n\nYour next output is the tool call (or, after the result, the reply) — no further skill loads.\n",
|
|
49
|
-
"obsidian/SKILL.md": "---\nname: obsidian\ndescription: Manage local Obsidian vault notes through the registered Obsidian CLI. Search, read, create, append, rename, move, inspect backlinks, list tasks, and work with daily notes.\ntools: [exec(obsidian)]\nplatform: [darwin, linux, win32]\nmetadata:\n {\n \"openclaw\":\n {\n \"requires\":\n {\n \"bins\": [\"obsidian\"],\n \"binMinVersions\": { \"obsidian\": { \"min\": \"1.12.7\", \"command\": \"obsidian version\" } }\n },\n \"setup\":\n {\n \"summary\": \"Obsidian works through the official Obsidian CLI connected to the running desktop app. You can instead select a vault folder for direct Markdown file access; app-only actions need the CLI. Workbench opens Obsidian on demand when using the CLI.\",\n \"routes\":\n [\n {\n \"kind\": \"instructions\",\n \"label\": \"Register the Obsidian CLI\",\n \"description\": \"Requires Obsidian 1.12.7 or newer with the command line interface registered. Keep the app installed; Workbench opens it on demand.\",\n \"helpUrl\": \"https://help.obsidian.md/cli\",\n \"steps\":\n [\n \"Open the Obsidian desktop app and update it to 1.12.7 or newer.\",\n \"Go to Settings → General → Advanced and enable Command line interface.\",\n \"Click Register CLI to add it to your PATH.\",\n \"Reopen this Skills page.\"\n ]\n },\n {\n \"kind\": \"picker\",\n \"label\": \"Select vault folder\",\n \"provider\": \"obsidian\",\n \"description\": \"Choose a folder that contains a .obsidian config directory. Switches to vault file mode (no running app required).\",\n \"credentialKey\": \"obsidian_vault_path\"\n }\n ]\n }\n }\n }\n---\n\n# Obsidian\n\nWork with a local Obsidian vault through the `obsidian` CLI. The CLI is a local\ncontroller for the running Obsidian desktop app and can search, read, create,\nappend, rename, move, open, and manage notes inside known vaults.\n\n## Load the Recipe File First\n\nThis file carries no commands. The working commands live in two reference files\n— load the one for the job with the `skill` tool BEFORE calling `exec`, then\ncopy its command and change only the arguments:\n\nEach load is a real `skill` tool call — printing the call as JSON or text in\nyour reply loads nothing.\n\n- **Finding and reading notes** — \"what are my notes\", \"list notes in X\",\n \"find / search notes about X\", \"read / open / summarize note X\", \"what's in\n my daily note\", \"list my tags\", backlinks, tasks: call the `skill` tool with\n `name: \"obsidian\"` and `file: \"references/read.md\"`.\n- **Changing notes** — \"create a note\", \"add to note X\", \"prepend\", \"add to\n my daily note\", rename, move, delete: call the `skill` tool with\n `name: \"obsidian\"` and `file: \"references/write.md\"`.\n\nMost requests are ONE command. Run that single command, then answer from its\noutput. Do NOT run `obsidian vault info` first unless the vault is ambiguous.\n\n## Always Use the obsidian CLI — Never Shell Out\n\nThe vault is managed by Obsidian. ALWAYS read, list, search, and edit notes with\n`obsidian` commands via the `exec` tool. NEVER use `cat`, `ls`, `find`, `grep`,\n`head`, `tail`, `echo`, output redirection, or filesystem paths under the vault\ndirectory — those bypass Obsidian and are wrong even when they appear to work.\nIf an `obsidian` command fails, correct its arguments and retry the `obsidian`\ncommand; do not switch to shell or file tools. Use `exec` only, one `obsidian`\ncommand per call. Do not chain with `&&`, `;`, or pipes.\n\n## When to Use\n\n- The user asks to search, read, summarize, create, append, rename, move, or\n delete notes in Obsidian.\n- The user asks about daily notes, tags, backlinks, aliases, properties, tasks,\n templates, bookmarks, or vault structure.\n- The user refers to \"my vault\", \"my notes\", \"daily note\", \"Obsidian\",\n wikilinks, or Markdown notes managed by Obsidian.\n\n## When NOT to Use\n\n- General filesystem work outside Obsidian.\n- Remote note providers such as Notion, Google Drive, Apple Notes, or cloud\n storage.\n- Browser automation, OAuth, MCP, web search, or direct filesystem tools.\n- Plugin installation, theme changes, sync changes, command execution by ID, or\n deletion unless the user explicitly asks for that exact side effect.\n\n## Setup and Availability\n\n- CLI mode: Obsidian 1.12.7+ with Command line interface registered. Workbench\n launches the app on demand when needed.\n- Vault file mode: Skills page → Obsidian → Select vault folder. Commands run\n against that folder's Markdown files without the running app.\n- Confirm the active vault with `obsidian vault info=name` ONLY when the request\n is ambiguous or multiple vaults exist — not before every request. If the\n request names a specific vault, add `vault=\"<Vault Name>\"`.\n- If no vault is active or the CLI cannot reach Obsidian, ask the user to open\n Obsidian or select a vault folder. A missing vault path is a runtime setup\n question, not a reason to use another tool or python.\n\n## Output Policy\n\n- Keep results small: note path, matching line, and the minimal relevant\n excerpt. Cite note paths and headings when answering from vault content.\n- After a successful command, finish with a concise visible answer.\n- If a command fails because Obsidian is not running, a vault is missing, or a\n note path is ambiguous, report that clearly and ask for the next specific\n setup step. Never claim a note changed unless the command succeeded.\n- Do not expose full vault dumps, plugin listings, or large note bodies unless\n the user explicitly requests them.\n",
|
|
49
|
+
"obsidian/SKILL.md": "---\nname: obsidian\ndescription: Manage local Obsidian vault notes through the registered Obsidian CLI. Search, read, create, append, rename, move, inspect backlinks, list tasks, and work with daily notes.\ntools: [exec(obsidian)]\nplatform: [darwin, linux, win32]\nmetadata:\n {\n \"openclaw\":\n {\n \"requires\":\n {\n \"bins\": [\"obsidian\"],\n \"binMinVersions\": { \"obsidian\": { \"min\": \"1.12.7\", \"command\": \"obsidian version\" } }\n },\n \"setup\":\n {\n \"summary\": \"Obsidian works through the official Obsidian CLI connected to the running desktop app. You can instead select a vault folder for direct Markdown file access; app-only actions need the CLI. Workbench opens Obsidian on demand when using the CLI.\",\n \"routes\":\n [\n {\n \"kind\": \"instructions\",\n \"label\": \"Register the Obsidian CLI\",\n \"description\": \"Requires Obsidian 1.12.7 or newer with the command line interface registered. Keep the app installed; Workbench opens it on demand.\",\n \"helpUrl\": \"https://help.obsidian.md/cli\",\n \"steps\":\n [\n \"Open the Obsidian desktop app and update it to 1.12.7 or newer.\",\n \"Go to Settings → General → Advanced and enable Command line interface.\",\n \"Click Register CLI to add it to your PATH.\",\n \"Reopen this Skills page.\"\n ]\n },\n {\n \"kind\": \"picker\",\n \"label\": \"Select vault folder\",\n \"provider\": \"obsidian\",\n \"description\": \"Choose a folder that contains a .obsidian config directory. Switches to vault file mode (no running app required).\",\n \"credentialKey\": \"obsidian_vault_path\"\n }\n ]\n }\n }\n }\n---\n\n# Obsidian\n\nWork with a local Obsidian vault through the `obsidian` CLI. The CLI is a local\ncontroller for the running Obsidian desktop app and can search, read, create,\nappend, rename, move, open, and manage notes inside known vaults.\n\n## Load the Recipe File First\n\nThis file carries no commands. The working commands live in two reference files\n— load the one for the job with the `skill` tool BEFORE calling `exec`, then\ncopy its command and change only the arguments:\n\nEach load is a real `skill` tool call — printing the call as JSON or text in\nyour reply loads nothing.\n\n- **Finding and reading notes** — \"what are my notes\", \"list notes in X\",\n \"find / search notes about X\", \"read / open / summarize note X\", \"what's in\n my daily note\", \"list my tags\", backlinks, tasks: call the `skill` tool with\n `name: \"obsidian\"` and `file: \"references/read.md\"`.\n- **Changing notes** — \"create a note\", \"add to note X\", \"prepend\", \"add to\n my daily note\", rename, move, delete: call the `skill` tool with\n `name: \"obsidian\"` and `file: \"references/write.md\"`.\n\nMost requests are ONE command. Run that single command, then answer from its\noutput. Do NOT run `obsidian vault info` first unless the vault is ambiguous.\n\n## Command Names Are Fixed — Never Guess\n\nThe CLI accepts only its own commands and parameters. These are the common\nones; the reference files carry the rest:\n\n```bash\nobsidian create name=\"Title\" content=\"...\"\nobsidian append file=\"Title\" content=\"...\"\nobsidian search query=\"X\"\nobsidian read file=\"Title\"\nobsidian daily:append content=\"...\"\n```\n\nThere is no `new`, `add`, `note`, or `write` command, and no `title=`\nparameter: a note's title goes in `name=`. If a command is rejected, the error\nlists what that command accepts — fix the call from that list or load the\nreference file, never try another invented name.\n\n## Always Use the obsidian CLI — Never Shell Out\n\nThe vault is managed by Obsidian. ALWAYS read, list, search, and edit notes with\n`obsidian` commands via the `exec` tool. NEVER use `cat`, `ls`, `find`, `grep`,\n`head`, `tail`, `echo`, output redirection, or filesystem paths under the vault\ndirectory — those bypass Obsidian and are wrong even when they appear to work.\nIf an `obsidian` command fails, correct its arguments and retry the `obsidian`\ncommand; do not switch to shell or file tools. Use `exec` only, one `obsidian`\ncommand per call. Do not chain with `&&`, `;`, or pipes.\n\n## When to Use\n\n- The user asks to search, read, summarize, create, append, rename, move, or\n delete notes in Obsidian.\n- The user asks about daily notes, tags, backlinks, aliases, properties, tasks,\n templates, bookmarks, or vault structure.\n- The user refers to \"my vault\", \"my notes\", \"daily note\", \"Obsidian\",\n wikilinks, or Markdown notes managed by Obsidian.\n\n## When NOT to Use\n\n- General filesystem work outside Obsidian.\n- Remote note providers such as Notion, Google Drive, Apple Notes, or cloud\n storage.\n- Browser automation, OAuth, MCP, web search, or direct filesystem tools.\n- Plugin installation, theme changes, sync changes, command execution by ID, or\n deletion unless the user explicitly asks for that exact side effect.\n\n## Setup and Availability\n\n- CLI mode: Obsidian 1.12.7+ with Command line interface registered. Workbench\n launches the app on demand when needed.\n- Vault file mode: Skills page → Obsidian → Select vault folder. Commands run\n against that folder's Markdown files without the running app.\n- Confirm the active vault with `obsidian vault info=name` ONLY when the request\n is ambiguous or multiple vaults exist — not before every request. If the\n request names a specific vault, add `vault=\"<Vault Name>\"`.\n- If no vault is active or the CLI cannot reach Obsidian, ask the user to open\n Obsidian or select a vault folder. A missing vault path is a runtime setup\n question, not a reason to use another tool or python.\n\n## Output Policy\n\n- Keep results small: note path, matching line, and the minimal relevant\n excerpt. Cite note paths and headings when answering from vault content.\n- After a successful command, finish with a concise visible answer.\n- If a command fails because Obsidian is not running, a vault is missing, or a\n note path is ambiguous, report that clearly and ask for the next specific\n setup step. Never claim a note changed unless the command succeeded.\n- Do not expose full vault dumps, plugin listings, or large note bodies unless\n the user explicitly requests them.\n",
|
|
50
50
|
"obsidian/cli.schema.json": "{\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"version\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {},\n \"x-effect\": \"read\"\n },\n \"vaults\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {},\n \"x-effect\": \"read\"\n },\n \"vault\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"list\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {},\n \"x-effect\": \"read\"\n },\n \"info\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n }\n },\n \"x-effect\": \"read\"\n },\n \"files\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"folder\": {\n \"type\": \"string\"\n },\n \"ext\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"limit\": {\n \"type\": \"string\"\n },\n \"total\": {\n \"type\": \"boolean\"\n },\n \"counts\": {\n \"type\": \"boolean\"\n },\n \"verbose\": {\n \"type\": \"boolean\"\n }\n },\n \"x-effect\": \"read\"\n },\n \"search\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\"\n },\n \"limit\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"folder\": {\n \"type\": \"string\"\n },\n \"verbose\": {\n \"type\": \"boolean\"\n },\n \"total\": {\n \"type\": \"boolean\"\n }\n },\n \"x-effect\": \"read\"\n },\n \"read\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"file\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"verbose\": {\n \"type\": \"boolean\"\n }\n },\n \"x-effect\": \"read\"\n },\n \"create\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"file\": {\n \"type\": \"string\"\n },\n \"content\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"template\": {\n \"type\": \"string\"\n },\n \"silent\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"append\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"file\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"content\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"silent\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"prepend\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"file\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"content\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"silent\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"backlinks\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"file\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"verbose\": {\n \"type\": \"boolean\"\n }\n },\n \"x-effect\": \"read\"\n },\n \"tags\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"vault\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"counts\": {\n \"type\": \"boolean\"\n },\n \"verbose\": {\n \"type\": \"boolean\"\n }\n },\n \"x-effect\": \"read\"\n },\n \"tasks\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"vault\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"folder\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"todo\": {\n \"type\": \"boolean\"\n },\n \"done\": {\n \"type\": \"boolean\"\n },\n \"verbose\": {\n \"type\": \"boolean\"\n }\n },\n \"x-effect\": \"read\"\n },\n \"daily:read\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"vault\": {\n \"type\": \"string\"\n },\n \"verbose\": {\n \"type\": \"boolean\"\n }\n },\n \"x-effect\": \"read\"\n },\n \"daily:append\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"content\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"silent\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"daily:prepend\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"content\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"silent\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"rename\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"file\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"name\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n }\n }\n },\n \"move\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"file\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"to\": {\n \"type\": \"string\"\n },\n \"vault\": {\n \"type\": \"string\"\n }\n }\n },\n \"delete\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"file\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"vault\": {\n \"type\": \"string\"\n },\n \"force\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"open\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"file\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\",\n \"pattern\": \"^(?![/\\\\\\\\~]|[A-Za-z]:).+$\",\n \"description\": \"vault-relative path (not absolute)\"\n },\n \"vault\": {\n \"type\": \"string\"\n }\n }\n }\n }\n}\n",
|
|
51
51
|
"obsidian/references/read.md": "# Finding and Reading Notes\n\nOne `obsidian` command per `exec` call, no chaining. Skip `vault info` unless\nthe vault is ambiguous.\n\n| Request | Command |\n| ----------------------------------------- | ------------------------------------------ |\n| \"what are my notes\" / \"list my notes\" | `obsidian files` |\n| \"list notes in <folder>\" | `obsidian files folder=\"<Folder>\"` |\n| \"find / search notes about X\" | `obsidian search query=\"X\"` |\n| \"read / open / summarize note X\" | `obsidian read file=\"X\"` (name, no `.md`) |\n| \"what's in my daily note\" | `obsidian daily:read` |\n| \"list my tags\" | `obsidian tags` |\n\n## List or search\n\n```bash\nobsidian files\nobsidian files folder=\"Projects\" ext=md\nobsidian search query=\"release handoff\" limit=10\n```\n\n`search` REQUIRES `query=\"...\"`. Add `limit=` to keep results small; if they are\nstill broad, ask a narrowing question or rerun with a tighter query.\n\n## Read\n\nRead by NAME (no `.md`) or by a VAULT-RELATIVE path — never an absolute\nfilesystem path (`/Users/.../Vault/Note.md` fails with \"File not found\").\nPrefer `path=` when two notes may share a name.\n\n```bash\nobsidian read file=\"QVAC\"\nobsidian read path=\"Projects/QVAC.md\"\nobsidian daily:read\n```\n\n## Structured output\n\nFor counts or machine-readable output add `total`, `counts`, or `format=json`:\n\n```bash\nobsidian files folder=\"Projects\" ext=md total\nobsidian tags counts format=json\n```\n\n## Backlinks and tasks (CLI mode only)\n\n`backlinks` and `tasks` need the running Obsidian app; in vault-folder mode\nthey fail with `not supported in vault file mode` — then say so instead of\nretrying or falling back to shell tools.\n\n```bash\nobsidian backlinks path=\"Projects/QVAC.md\" format=json\nobsidian tasks todo verbose\n```\n\n## Vault checks (only when needed)\n\n```bash\nobsidian vaults\nobsidian vault info=name\nobsidian version\n```\n\n## Answering\n\nGive the note path and the exact line or excerpt that supports the answer. Do\nnot dump whole notes or the whole vault unless asked. A read-only request ends\nafter the read — never follow it with a write.\n\n## Common Mistakes\n\n- Shelling out with `cat`, `ls`, `find`, `grep`, or filesystem tools instead of\n `obsidian` commands. Always use `obsidian`, even for a single note.\n- Passing an absolute filesystem path to `read`. Use `file=\"Name\"` or a\n vault-relative `path=\"Folder/Note.md\"`.\n- Calling `search` without `query=`.\n- Running `obsidian vault info` before every request.\n",
|
|
52
52
|
"obsidian/references/write.md": "# Creating and Changing Notes\n\nOne `obsidian` command per `exec` call, no chaining. Writes must go through\n`obsidian` CLI commands — never direct filesystem writes.\n\n| Request | Command |\n| -------------------------------- | --------------------------------------------------------- |\n| \"create a note\" | `obsidian create name=\"Title\" content=\"...\"` |\n| \"create a note in <folder>\" | `obsidian create path=\"Folder/Title.md\" content=\"...\"` |\n| \"add to note X\" | `obsidian append file=\"X\" content=\"...\"` |\n| \"add to the top of note X\" | `obsidian prepend file=\"X\" content=\"...\"` |\n| \"add to my daily note\" | `obsidian daily:append content=\"...\"` |\n| \"rename / move / delete note X\" | only when explicitly asked — see below |\n\n## Create\n\nName new notes with `name=\"Title\"` or an exact `path=\"Folder/Title.md\"`. Never\nuse `file=` with `create`: the official CLI ignores it and silently creates an\n\"Untitled\" note. `content=` is Markdown; write line breaks as `\\n`.\n\n```bash\nobsidian create name=\"QVAC\" content=\"# QVAC\\n\\nInitial note\"\nobsidian create path=\"Projects/QVAC.md\" content=\"# QVAC\\n\\nInitial note\"\n```\n\n## Append and prepend\n\nTarget by NAME (no `.md`) or by a VAULT-RELATIVE path — never an absolute\nfilesystem path. Prefer `path=` when two notes may share a name.\n\n```bash\nobsidian append file=\"QVAC\" content=\"- [ ] Follow up on QVAC notes\"\nobsidian append path=\"Daily/2026-05-29.md\" content=\"- [ ] Follow up on QVAC notes\"\nobsidian prepend path=\"Projects/QVAC.md\" content=\"> Updated 2026-05-29\"\nobsidian daily:append content=\"- [ ] Review local Obsidian skill wiring\"\n```\n\nTo change existing text inside a note, read it first (`references/read.md`),\nthen `append`/`prepend` the corrected content — there is no in-place replace.\n\n## Rename, move, delete\n\nRun these ONLY when the user explicitly asks for that exact side effect, and\nconfirm the target path when the request is ambiguous.\n\n```bash\nobsidian rename path=\"Projects/QVAC.md\" name=\"QVAC v2\"\nobsidian move path=\"Projects/QVAC.md\" to=\"Archive/QVAC.md\"\nobsidian delete path=\"Archive/QVAC.md\" force\n```\n\nAvoid `overwrite`, plugin commands, sync commands, and theme commands unless the\nuser explicitly asks.\n\n## Answering\n\nDo not claim a note changed unless the `obsidian` command completed\nsuccessfully. Confirm with the note path and what was written.\n\n## Common Mistakes\n\n- Using `create file=\"Title\"` — the CLI ignores `file=` on create and makes an\n \"Untitled\" note. Use `name=\"Title\"` or `path=`.\n- Passing an absolute filesystem path to `create` or `append`.\n- Using `file=` when two notes may share the same name. Prefer exact `path=`.\n- Writing through `echo`, redirection, or file tools instead of `obsidian`.\n- Treating a failed command as success.\n",
|
package/hash.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Autogenerated by scripts/build.mjs from skills/. Do not edit.
|
|
2
|
-
export const SKILLS_HASH = '
|
|
2
|
+
export const SKILLS_HASH = '636bd5f7be09d4ed'
|
package/package.json
CHANGED
package/skills/obsidian/SKILL.md
CHANGED
|
@@ -69,6 +69,24 @@ your reply loads nothing.
|
|
|
69
69
|
Most requests are ONE command. Run that single command, then answer from its
|
|
70
70
|
output. Do NOT run `obsidian vault info` first unless the vault is ambiguous.
|
|
71
71
|
|
|
72
|
+
## Command Names Are Fixed — Never Guess
|
|
73
|
+
|
|
74
|
+
The CLI accepts only its own commands and parameters. These are the common
|
|
75
|
+
ones; the reference files carry the rest:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
obsidian create name="Title" content="..."
|
|
79
|
+
obsidian append file="Title" content="..."
|
|
80
|
+
obsidian search query="X"
|
|
81
|
+
obsidian read file="Title"
|
|
82
|
+
obsidian daily:append content="..."
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
There is no `new`, `add`, `note`, or `write` command, and no `title=`
|
|
86
|
+
parameter: a note's title goes in `name=`. If a command is rejected, the error
|
|
87
|
+
lists what that command accepts — fix the call from that list or load the
|
|
88
|
+
reference file, never try another invented name.
|
|
89
|
+
|
|
72
90
|
## Always Use the obsidian CLI — Never Shell Out
|
|
73
91
|
|
|
74
92
|
The vault is managed by Obsidian. ALWAYS read, list, search, and edit notes with
|