skills/export-vault-note/SKILL.md
Exports a single Obsidian vault note and all its linked images into a portable zip or tar.gz archive, preserving vault-root-relative paths so the archive unpacks correctly anywhere. Use only when the user explicitly invokes /export-vault-note.
npx skillsauth add psenger/ai-agent-skills export-vault-noteInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill runs inside an Obsidian vault. It bundles a single Markdown note and every image it links into a portable archive placed at a location of the user's choosing (defaulting to one directory above the vault root).
Handles two image link styles:
![[image.png]] or ![[subfolder/image.png]]Example:
/export-vault-note projects/blog/my-post.md zip ~/Desktop
Read $ARGUMENTS. Extract:
note_path — vault-relative path to the Markdown file (e.g. ai/notes/my-note.md)format — zip or taroutput_dir — absolute or relative path where the archive should be savedIf note_path is missing, ask: "Which note do you want to export? Provide the vault-relative path, e.g. ai/notes/my-note.md."
If format is not provided, ask: "Do you want a zip or tar archive?"
If output_dir is not provided, tell the user: "The archive will be saved to one directory above the vault root by default. Is that OK, or do you want a different location?" Wait for confirmation or a new path before continuing.
Walk up the directory tree from the current working directory looking for a .obsidian folder. If the note path given is absolute, also try walking up from its parent directory.
python3 -c "
import sys
from pathlib import Path
for start in sys.argv[1:]:
p = Path(start).resolve()
for candidate in [p] + list(p.parents):
if (candidate / '.obsidian').is_dir():
print(candidate)
raise SystemExit(0)
print('')
" "." "<absolute-note-parent-if-known>"
If the output is empty (no .obsidian found), ask: "I couldn't detect the vault root automatically. What is the absolute path to your vault root?"
Write the script below to /tmp/export_vault_note.py and run it. The script is embedded directly so the skill works regardless of install location.
cat > /tmp/export_vault_note.py << 'PYEOF'
import sys
import re
import zipfile
import tarfile
from pathlib import Path
def find_vault_wide(vault_root, name):
for p in vault_root.rglob(name):
return p
return None
def collect_images(vault_root, note_path):
content = note_path.read_text(encoding="utf-8")
note_dir = note_path.parent
images = []
warnings = []
seen = set()
wiki = re.findall(r"!\[\[([^\]|#]+)", content)
inline = re.findall(r"!\[[^\]]*\]\(([^)#\s]+)", content)
for ref in wiki + inline:
ref = ref.strip()
if not ref or ref in seen:
continue
seen.add(ref)
if re.match(r"https?://", ref):
warnings.append(f"Skipping external image: {ref}")
continue
abs_path = None
if "/" in ref or "\\" in ref:
for candidate in [vault_root / ref, note_dir / ref]:
if candidate.exists():
abs_path = candidate
break
else:
found = find_vault_wide(vault_root, ref)
if found:
abs_path = found
print(f"Resolved bare link '{ref}' -> {abs_path.relative_to(vault_root)}")
if abs_path is None:
warnings.append(f"Warning: image not found, skipping: {ref}")
continue
try:
vault_rel = str(abs_path.relative_to(vault_root))
images.append((abs_path, vault_rel))
except ValueError:
warnings.append(f"Warning: image outside vault, skipping: {abs_path}")
return images, warnings
def main():
if len(sys.argv) < 3:
print(f"Usage: {sys.argv[0]} <vault_root> <note_rel_path> [zip|tar] [output_dir]", file=sys.stderr)
sys.exit(1)
vault_root = Path(sys.argv[1]).resolve()
note_rel = sys.argv[2]
fmt = sys.argv[3] if len(sys.argv) > 3 else "zip"
output_dir = Path(sys.argv[4]).resolve() if len(sys.argv) > 4 else vault_root.parent
if fmt not in ("zip", "tar"):
print(f"Error: format must be 'zip' or 'tar', got '{fmt}'", file=sys.stderr)
sys.exit(1)
if not vault_root.is_dir():
print(f"Error: vault root not found: {vault_root}", file=sys.stderr)
sys.exit(1)
note_path = vault_root / note_rel
if not note_path.exists():
print(f"Error: note not found: {note_path}", file=sys.stderr)
sys.exit(1)
if not output_dir.exists():
output_dir.mkdir(parents=True)
images, warnings = collect_images(vault_root, note_path)
stem = note_path.stem
if fmt == "tar":
archive_path = output_dir / f"{stem}.tar.gz"
with tarfile.open(archive_path, "w:gz") as tar:
tar.add(note_path, arcname=note_rel)
for abs_path, vault_rel in images:
tar.add(abs_path, arcname=vault_rel)
else:
archive_path = output_dir / f"{stem}.zip"
with zipfile.ZipFile(archive_path, "w", zipfile.ZIP_DEFLATED) as zf:
zf.write(note_path, note_rel)
for abs_path, vault_rel in images:
zf.write(abs_path, vault_rel)
print(f"Archive: {archive_path}")
print(f"Note: {note_rel}")
for _, vault_rel in images:
print(f"Image: {vault_rel}")
for w in warnings:
print(w)
if __name__ == "__main__":
main()
PYEOF
python3 /tmp/export_vault_note.py "<vault_root>" "<note_rel_path>" "<format>" "<output_dir>"
Substitute all four values. If the user accepted the default output location, resolve and pass vault_root.parent explicitly.
Parse the script output and report:
development
Provides the audit checklists, severity criteria (blocking/warning/suggestion), and artifact patterns needed to properly review Agent OS profiles and standards. Always invoke this skill before auditing - without it you can only give generic feedback, not structured severity-tagged findings. Invoke when the user pastes a standard and asks if it is good or what is wrong with it; when the user asks to review, audit, validate, or critique an agent-os profile or standard; or when the user mentions "agent-os profile", "agent-os standard", or "my agent-os setup" in a review or validation context.
development
Converts transcripts, video summaries, meeting notes, brainstorming sessions, strategy documents, and rough notes into polished Obsidian-flavored Markdown. Activates when creating or editing notes in an Obsidian vault, generating front matter, applying callout blocks, structuring knowledge base articles, or producing developer-facing guides. Also triggers on mentions of Obsidian, front matter, callout blocks, vault organisation, or requests for GitHub-compatible Markdown documents.
documentation
Generate git commit messages, PR titles/descriptions, and changelog entries. Analyzes staged changes, enforces Conventional Commits, scans for sensitive content, links tickets (GitHub Issues / Jira), and updates CHANGELOG.md. Triggers on: "commit", "create a PR", "push", "changelog", "release", or when the user is ready to commit or open a pull request.
development
Create new agent skills from scratch, modify and improve existing skills, and measure skill performance through evaluation and benchmarking. Use when users want to create a skill, write a skill, build a new skill, edit or optimize an existing skill, run evals to test a skill, benchmark skill performance, or optimize a skill's description for better triggering accuracy. Also triggers when users say "turn this into a skill", "make a skill for X", "skill for doing Y", or ask about skill structure, skill format, or SKILL.md files.