{"_id":"@andershoffmann/obsidian-axi","_rev":"4-46de43d24f4ddc6f401afed9d6091b85","name":"@andershoffmann/obsidian-axi","dist-tags":{"latest":"0.2.2"},"versions":{"0.2.0":{"name":"@andershoffmann/obsidian-axi","version":"0.2.0","keywords":["axi","agent","cli","notes","markdown","toon"],"author":{"name":"Anders Hoffmann"},"license":"MIT","_id":"@andershoffmann/obsidian-axi@0.2.0","maintainers":[{"name":"au568584","email":"au568584@gmail.com"}],"homepage":"https://github.com/AndersHoffmann/obsidian-axi#readme","bugs":{"url":"https://github.com/AndersHoffmann/obsidian-axi/issues"},"bin":{"obsidian-axi":"dist/bin/obsidian-axi.js"},"dist":{"shasum":"a4d7f91508e2a5b5006b306c21aa8d3e105e12fa","tarball":"https://registry.npmjs.org/@andershoffmann/obsidian-axi/-/obsidian-axi-0.2.0.tgz","fileCount":84,"integrity":"sha512-TH+4R+ItJ+bVdh2SSaLWqJhRbMiRJ0cKT46aMuchGO5W3RCxLF8r7mzhpwAPDiJ78+aZAv5Px1qL5eJ6ZKzPkA==","signatures":[{"sig":"MEUCIHzl4hCUbuuuoIrb5p2Cp5ETxIo90Ixv7KWuqMDge2a3AiEA3h6rux/uPl0MkaAiW3aXS5qnm+V87KUQMIAg3IAa424=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":314954},"type":"module","engines":{"node":">=20"},"gitHead":"5ab60953f749026eab12bca1b1b3002e3dfb8550","scripts":{"dev":"tsx bin/obsidian-axi.ts","lint":"eslint .","test":"vitest run","bench":"tsx bench/measure.ts","build":"npm run clean && tsc","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","typecheck":"tsc --noEmit","test:watch":"vitest","build:skill":"tsx scripts/build-skill.ts","prepublishOnly":"npm run build"},"_npmUser":{"name":"au568584","email":"au568584@gmail.com"},"deprecated":"Vault escape via symlink, fixed in 0.2.1. Please\n  upgrade.","repository":{"url":"git+https://github.com/AndersHoffmann/obsidian-axi.git","type":"git"},"_npmVersion":"11.9.0","description":"Agent ergonomic CLI for Obsidian vaults - read, search, write, and link notes straight from the filesystem.","directories":{},"_nodeVersion":"24.11.1","dependencies":{"yaml":"^2.5.0","axi-sdk-js":"^0.1.10","@toon-format/toon":"^2.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.0","eslint":"^9.13.0","vitest":"^4.1.10","@eslint/js":"^9.13.0","typescript":"^5.6.0","@types/node":"^22.9.0","typescript-eslint":"^8.13.0"},"_npmOperationalInternal":{"tmp":"tmp/obsidian-axi_0.2.0_1786454769224_0.9224120680585903","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@andershoffmann/obsidian-axi","version":"0.2.1","keywords":["axi","agent","cli","notes","markdown","toon"],"author":{"name":"Anders Hoffmann"},"license":"MIT","_id":"@andershoffmann/obsidian-axi@0.2.1","maintainers":[{"name":"au568584","email":"au568584@gmail.com"}],"homepage":"https://github.com/AndersHoffmann/obsidian-axi#readme","bugs":{"url":"https://github.com/AndersHoffmann/obsidian-axi/issues"},"bin":{"obsidian-axi":"dist/bin/obsidian-axi.js"},"dist":{"shasum":"a4cc2d74175fb959ff8615dbfe68958aef101463","tarball":"https://registry.npmjs.org/@andershoffmann/obsidian-axi/-/obsidian-axi-0.2.1.tgz","fileCount":84,"integrity":"sha512-X5POmacDlVCqXSKzbrfFXvm7norfWytWYLBp9cFaAA4vQrqDhykLJseVOE1MyPNp8bibE8RA6BDN4QbVayM4xw==","signatures":[{"sig":"MEYCIQCNaSaFJz6b/ffxwfKXXiweUK0SobolJsvlaNFfYWn1FQIhAOcE7Bgkx6qZPj4FowJ0nyx3tIbcbS4VZgjuuoDmoQpL","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":319873},"type":"module","engines":{"node":">=20"},"gitHead":"df59ed0f74469067d2692fb537d8182373c6105f","scripts":{"dev":"tsx bin/obsidian-axi.ts","lint":"eslint .","test":"vitest run","bench":"tsx bench/measure.ts","build":"npm run clean && tsc","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","typecheck":"tsc --noEmit","test:watch":"vitest","build:skill":"tsx scripts/build-skill.ts","prepublishOnly":"npm run build"},"_npmUser":{"name":"au568584","email":"au568584@gmail.com"},"repository":{"url":"git+https://github.com/AndersHoffmann/obsidian-axi.git","type":"git"},"_npmVersion":"11.9.0","description":"Agent ergonomic CLI for Obsidian vaults - read, search, write, and link notes straight from the filesystem.","directories":{},"_nodeVersion":"24.11.1","dependencies":{"yaml":"^2.5.0","axi-sdk-js":"^0.1.10","@toon-format/toon":"^2.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.0","eslint":"^9.13.0","vitest":"^4.1.10","@eslint/js":"^9.13.0","typescript":"^5.6.0","@types/node":"^22.9.0","typescript-eslint":"^8.13.0"},"_npmOperationalInternal":{"tmp":"tmp/obsidian-axi_0.2.1_1786477603915_0.12721990769983837","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@andershoffmann/obsidian-axi","version":"0.2.2","description":"Agent ergonomic CLI for Obsidian vaults - read, search, write, and link notes straight from the filesystem.","keywords":["axi","agent","cli","notes","markdown","toon"],"license":"MIT","author":{"name":"Anders Hoffmann"},"repository":{"type":"git","url":"git+https://github.com/AndersHoffmann/obsidian-axi.git"},"homepage":"https://github.com/AndersHoffmann/obsidian-axi#readme","bugs":{"url":"https://github.com/AndersHoffmann/obsidian-axi/issues"},"type":"module","bin":{"obsidian-axi":"dist/bin/obsidian-axi.js"},"engines":{"node":">=20"},"scripts":{"clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","build":"npm run clean && tsc","build:skill":"tsx scripts/build-skill.ts","bench":"tsx bench/measure.ts","dev":"tsx bin/obsidian-axi.ts","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","lint":"eslint .","prepublishOnly":"npm run build"},"dependencies":{"@toon-format/toon":"^2.1.0","axi-sdk-js":"^0.1.10","yaml":"^2.5.0"},"devDependencies":{"@eslint/js":"^9.13.0","@types/node":"^22.9.0","eslint":"^9.13.0","tsx":"^4.19.0","typescript":"^5.6.0","typescript-eslint":"^8.13.0","vitest":"^4.1.10"},"publishConfig":{"access":"public"},"gitHead":"7a19eb8e46f7b285fdfcdf584fb493f8f7a90597","_id":"@andershoffmann/obsidian-axi@0.2.2","_nodeVersion":"24.11.1","_npmVersion":"11.9.0","dist":{"integrity":"sha512-NK9zVmi5xgDNAc+XtIHO42VPqZUgZ04HUvoyo/JMiSZEo8Yz7WWBmVcws0ir05ffoFJ6MkRyXko4HHctEz974g==","shasum":"911bce4e81b0383c93c1f5cae75a8ee42fa1ffb4","tarball":"https://registry.npmjs.org/@andershoffmann/obsidian-axi/-/obsidian-axi-0.2.2.tgz","fileCount":84,"unpackedSize":322208,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIG+/2x9M4LBpZG/XS0NhmKIWLBu6adaNfJY/4HI/vc+JAiEAxsNBOS8MFyr15V9Ct63GH/SxUgwWWDYocVF6pH1T8bs="}]},"_npmUser":{"name":"au568584","email":"au568584@gmail.com"},"directories":{},"maintainers":[{"name":"au568584","email":"au568584@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/obsidian-axi_0.2.2_1786518079284_0.9492550448119621"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-11T13:26:09.050Z","modified":"2026-08-12T07:01:19.639Z","0.2.0":"2026-08-11T13:26:09.400Z","0.2.1":"2026-08-11T19:46:44.027Z","0.2.2":"2026-08-12T07:01:19.492Z"},"bugs":{"url":"https://github.com/AndersHoffmann/obsidian-axi/issues"},"author":{"name":"Anders Hoffmann"},"license":"MIT","homepage":"https://github.com/AndersHoffmann/obsidian-axi#readme","keywords":["axi","agent","cli","notes","markdown","toon"],"repository":{"type":"git","url":"git+https://github.com/AndersHoffmann/obsidian-axi.git"},"description":"Agent ergonomic CLI for Obsidian vaults - read, search, write, and link notes straight from the filesystem.","maintainers":[{"name":"au568584","email":"au568584@gmail.com"}],"readme":"# obsidian-axi\n\nA command line tool that lets coding agents work with your Obsidian notes.\n\nIt reads and writes the vault folder directly. No plugin to install, no server to run, no\nAPI key, and Obsidian does not even have to be open.\n\n```console\n$ npx -y @andershoffmann/obsidian-axi\nbin: ~/.local/bin/obsidian-axi\ndescription: Agent ergonomic CLI for Obsidian vaults - read, search, write, and link notes.\nvault:\n  name: My Vault\n  path: ~/Documents/My Vault\n  notes: 214\n  source: obsidian.json (open)\nrecent[5]{path,modified,ago}:\n  Projects/Roadmap.md,2026-08-10,1d\n  Inbox/Idea.md,2026-08-09,2d\n  ...\nhelp[3]:\n  obsidian-axi search <query>\n  obsidian-axi ls --recursive\n  obsidian-axi tags list\n```\n\nBuilt to the [AXI](https://axi.md) standard, which is a set of design rules for CLIs that\nagents drive.\n\n## Why not an MCP server?\n\nAn MCP server loads its tool definitions into the model's context on every single turn, and\nthat cost adds up. A CLI does not, and it pipes into `grep` and `head` like anything else.\n\nThe Obsidian MCP servers also need real setup: a community plugin, a bearer token, and a\nrunning Obsidian. The most popular one does not currently install on a fresh machine, and\nfour of its tools no longer work with the current plugin.\n\nThe trade is that anything needing a live Obsidian is out of scope here. No Dataview, no\nTemplater, no semantic search, no command palette. In exchange it works everywhere, right\naway.\n\n## Install\n\nNothing to install. Just run it:\n\n```console\nnpx -y @andershoffmann/obsidian-axi <command>\n```\n\nIf you want the `setup hooks` and `update` commands too, install it properly:\n\n```console\nnpm i -g @andershoffmann/obsidian-axi\nobsidian-axi setup hooks\n```\n\n`setup hooks` wires a SessionStart hook into Claude Code, Codex and OpenCode, so an agent\nsession opens with your vault summary already loaded. Running it twice is safe, and it does\nnot touch your other settings.\n\nThe package also ships an agent skill at `skills/obsidian-axi/SKILL.md`. It is generated\nfrom the CLI's own help text, so it cannot drift out of date.\n\nNeeds Node 20 or newer.\n\n## Getting started\n\nRun it with no arguments to see where you are:\n\n```console\nobsidian-axi                            # your vault and its recent notes\nobsidian-axi ls -r --sort modified      # every note, newest first\nobsidian-axi read Notes/Roadmap.md      # one note, trimmed to 1000 characters\nobsidian-axi read a.md b.md --metadata  # just frontmatter and counts\nobsidian-axi search cosmosdb --context 2\nobsidian-axi recent --days 7            # changed this week\nobsidian-axi vault list                 # every vault Obsidian knows about\n```\n\nEvery command takes `--help`.\n\nOne rule to remember: flags go **after** the command.\n\n```console\nobsidian-axi vault info --vault \"My Vault\"     # yes\nobsidian-axi --vault \"My Vault\" vault info     # no\n```\n\n## Search\n\nSearch takes a query, some filters, or both.\n\n```console\nobsidian-axi search TODO --tag project --context 2\nobsidian-axi search --tag work --modified-since 7d      # filters only, no query\nobsidian-axi search --frontmatter status=active\nobsidian-axi search \"^## \" --regex --path \"Notes/**\"\n```\n\n`--tag project` also matches `#project/axi`. You can repeat `--tag` and `--frontmatter`, and\neverything you pass has to match.\n\n## Writing\n\n```console\nobsidian-axi write Inbox/idea.md --content \"# Idea\"\nobsidian-axi append Notes/log.md --content \"- [ ] ship it\"\necho \"- piped note\" | obsidian-axi append Inbox/log.md\nobsidian-axi rm Inbox/draft.md                  # goes to .trash, so you can get it back\nobsidian-axi mv Inbox/draft.md Notes/final.md\n```\n\n`patch` changes one part of a note without rewriting the whole thing. It can target a\nheading's section, a block reference, or a frontmatter field.\n\n```console\nobsidian-axi patch a.md --target-type heading --target Tasks --content \"- [ ] new\"\nobsidian-axi patch a.md --target-type heading --target \"Tasks::Today\" --op prepend --content \"- [ ] first\"\nobsidian-axi patch a.md --target-type frontmatter --target status=done --op replace\nobsidian-axi patch a.md --target-type block --target abc123 --op delete\n```\n\nTwo things worth knowing about `patch`:\n\n- When you append to a heading, the text lands in that section only. It will not slip into a\n  nested subsection below it. To write inside `### Today`, name it: `--target \"Tasks::Today\"`.\n  Using `--op delete` on a heading removes the heading and everything under it.\n- Your line endings and trailing newline are left alone, so editing the middle of a note\n  gives you a one line diff and nothing else.\n\nRe-running a write is safe. Appending text a note already ends with, deleting a note that is\nalready gone, and moving a note onto itself all do nothing and exit 0.\n\n## Links and tags\n\n```console\nobsidian-axi links \"Roadmap.md\"         # what it links to, and what links back\nobsidian-axi links --broken             # links pointing at notes that do not exist\nobsidian-axi links --orphans            # notes nothing links to\nobsidian-axi tags                       # every tag, with a note count\nobsidian-axi tags files project/axi\n```\n\nLinks are resolved the way Obsidian resolves them: exact path first, then relative to the\nnote doing the linking, then a matching filename anywhere in the vault, then frontmatter\naliases. Attachments count too, so `![[Pasted image.png]]` is not flagged as broken.\n\nTag counts roll up. `#project` includes notes tagged only `#project/axi`.\n\n## What Obsidian had open\n\n```console\nobsidian-axi active                     # the note Obsidian last had focused\nobsidian-axi open \"Roadmap.md\"          # ask Obsidian to jump to a note\n```\n\n`active` reads `.obsidian/workspace.json`. Obsidian only writes that file when the layout\nchanges, not on every tab switch, so treat it as the last saved state rather than live. The\noutput tells you how old it is.\n\n## Picking a vault\n\nFirst match wins:\n\n1. `--vault <name|path>`\n2. `OBSIDIAN_VAULT=<name|path>`\n3. a `.obsidian/` folder in the current directory or above it\n4. `defaultVault` in `~/.config/obsidian-axi/config.json`\n5. the vault Obsidian has open\n6. the vault opened most recently\n\n`vault info` tells you which rule applied, so you can check it picked the one you meant.\n\n## Output\n\nOutput is [TOON](https://toonformat.dev/), a compact format that writes lists as a header\nplus rows, using roughly 40% fewer tokens than JSON. Lists come with a `count:` line, long\nnote bodies are trimmed to 1000 characters (use `--full` for all of it), and an empty result\nsays so in words instead of printing nothing.\n\nErrors go to stdout too, with a code you can match on and a hint for what to try next:\n\n```\nerror: Note not found `Notes/Roadmap.md`\ncode: NOTE_NOT_FOUND\nhelp[2]:\n  obsidian-axi ls Notes\n  obsidian-axi search Roadmap\n```\n\nExit codes: `0` worked (including \"nothing to do\"), `1` something went wrong, `2` you typed\nit wrong.\n\n## If you use Obsidian Sync\n\nObsidian picks up outside edits and reloads the note. But if you have that note open with\nunsaved changes, Obsidian may overwrite what this tool just wrote. There is no way to detect\nthat from the filesystem, so save or close the note first if it matters.\n\nWrites go to a temp file and get renamed into place, so a note can never end up half\nwritten. And `rm` moves notes to `.trash` unless you pass `--permanent`.\n\n## Status\n\nUnder active development, but all 16 commands work: the dashboard, `ls`, `read`, `search`,\n`recent`, `write`, `append`, `patch`, `rm`, `mv`, `links`, `tags`, `active`, `open`, `vault`\nand `setup`, plus `update` from the AXI SDK.\n\nIt is fast because it does the simple thing. No cache, no index, everything synchronous. On\na 103 note vault a full recursive listing takes about 88ms and a full text search about\n120ms, both including Node startup.\n\n### Does it actually save tokens?\n\n`npm run bench` measures each command against the shell command an agent would otherwise\nreach for. On a 103 note vault it returns 18% fewer characters overall, but that average\nhides most of the story:\n\n| task | obsidian-axi | plain shell | |\n|---|---:|---:|---|\n| search for a term | 5764 | 13406 | **43%** |\n| read a note's metadata | 111 | 512 | **22%** |\n| read a note | 651 | 512 | 127% |\n| list every note | 8369 | 6218 | 135% |\n| list tags | 637 | 502 | 127% |\n\nSearching is the real win, since grep returns every matching line and this does not. Reading\na *typical* note actually costs more, because the median note here is shorter than the 1000\ncharacter trim limit, so nothing gets trimmed and the metadata is overhead. On a long note\nthe same command lands near 5%. Listing costs more too, because each row carries more than a\npath.\n\nAnd when it does cost more, it is often answering a better question. `links --broken`\nresolves real wikilinks, which no grep one liner can do.\n\n[bench/README.md](bench/README.md) has the full table, the caveats, and why a fair\ncomparison against the Obsidian MCP servers is not possible right now.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}