agentsclimarketplace

Obsidian

Skill furkangonel/cowrangler/bundled_skills/note-taking/obsidian

Autonomous terminal AI agent for workflows and feasible project procedures. Co-Worker Co-Wrangler πŸ™

Install
npx -y skills add furkangonel/cowrangler --skill obsidian

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Obsidian vault management β€” create notes, backlinks, tags, and Dataview queries via file operations

SKILL.md

6.0 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it

Obsidian Vault Management

Goal

Create, update, and organize notes in an Obsidian vault programmatically. Query notes with Dataview syntax. Maintain a consistent vault structure.

Vault Structure

vault/
β”œβ”€β”€ Daily Notes/          # YYYY-MM-DD.md
β”œβ”€β”€ Projects/             # One folder per project
β”œβ”€β”€ Areas/                # Ongoing responsibilities
β”œβ”€β”€ Resources/            # Reference material
β”œβ”€β”€ Archive/              # Inactive notes
└── _templates/           # Note templates

Use PARA method (Projects / Areas / Resources / Archive) as the default organization.

Frontmatter Conventions

Every note should have frontmatter:

---
title: Note Title
date: 2024-01-15
tags: [topic, subtopic]
aliases: [alternative-name]
status: draft | active | archived
related: [[Other Note]], [[Another Note]]
---
  • date: ISO 8601 (YYYY-MM-DD)
  • tags: lowercase, hyphenated
  • aliases: alternate names for search/linking
  • status: lifecycle state
  • related: explicit links (supplement to inline wikilinks)

Creating Notes Programmatically

Basic note creation

from pathlib import Path
from datetime import datetime

def create_note(vault_path: str, folder: str, title: str, content: str, tags: list[str] = []) -> Path:
    vault = Path(vault_path)
    target_dir = vault / folder
    target_dir.mkdir(parents=True, exist_ok=True)
    
    # Sanitize title for filename
    filename = title.replace("/", "-").replace(":", "-") + ".md"
    note_path = target_dir / filename
    
    frontmatter = f"""---
title: {title}
date: {datetime.now().strftime("%Y-%m-%d")}
tags: {tags}
---

"""
    note_path.write_text(frontmatter + content, encoding="utf-8")
    return note_path

Daily note

def create_daily_note(vault_path: str, template: str = "") -> Path:
    today = datetime.now().strftime("%Y-%m-%d")
    content = template or f"""# {today}

## Tasks
- [ ] 

## Notes

## Links
"""
    return create_note(vault_path, "Daily Notes", today, content)

Wikilink Syntax

[[Note Title]]                    # Basic link
[[Note Title|Display Text]]       # Link with alias
[[Note Title#Heading]]            # Link to section
![[Note Title]]                   # Embed note
![[image.png]]                    # Embed image

Adding backlinks programmatically

def add_backlink(note_path: str, linked_title: str):
    path = Path(note_path)
    content = path.read_text(encoding="utf-8")
    link = f"[[{linked_title}]]"
    if link not in content:
        content += f"\n\n## Related\n{link}\n"
        path.write_text(content, encoding="utf-8")

Tag Management

import re

def add_tags(note_path: str, new_tags: list[str]):
    path = Path(note_path)
    content = path.read_text(encoding="utf-8")
    
    # Find existing tags in frontmatter
    match = re.search(r'^tags:\s*\[([^\]]*)\]', content, re.MULTILINE)
    if match:
        existing = [t.strip() for t in match.group(1).split(",") if t.strip()]
        merged = list(set(existing + new_tags))
        content = content[:match.start()] + f"tags: {merged}" + content[match.end():]
        path.write_text(content, encoding="utf-8")

def find_notes_by_tag(vault_path: str, tag: str) -> list[Path]:
    vault = Path(vault_path)
    results = []
    for md in vault.rglob("*.md"):
        if f"#{tag}" in md.read_text() or f'"{tag}"' in md.read_text():
            results.append(md)
    return results

Dataview Queries

Dataview plugin queries (placed inside dataview code blocks in notes):

List notes by tag

```dataview
LIST
FROM #project
SORT date DESC
```

Table of tasks

```dataview
TABLE date, status, tags
FROM "Projects"
WHERE status != "archived"
SORT date DESC
```

Incomplete tasks across vault

```dataview
TASK
WHERE !completed
FROM "Projects"
GROUP BY file.link
```

Notes modified this week

```dataview
LIST
WHERE file.mtime >= date(today) - dur(7 days)
SORT file.mtime DESC
```

Search and Query (CLI)

# Find all notes containing a phrase
grep -rl "search term" /path/to/vault --include="*.md"

# Find broken wikilinks (links with no matching file)
python3 << 'EOF'
from pathlib import Path
import re

vault = Path("/path/to/vault")
all_titles = {p.stem for p in vault.rglob("*.md")}
wikilink_pattern = re.compile(r'\[\[([^\]|#]+)')

for note in vault.rglob("*.md"):
    content = note.read_text()
    for link in wikilink_pattern.findall(content):
        if link.strip() not in all_titles:
            print(f"Broken link in {note.name}: [[{link}]]")
EOF

Templates

Meeting note template

---
title: Meeting β€” {{title}}
date: {{date}}
tags: [meeting]
attendees: []
---

# {{title}}

**Date**: {{date}}  
**Attendees**: 

## Agenda
1. 

## Notes

## Action Items
- [ ] 

## Decisions

Project note template

---
title: {{project-name}}
date: {{date}}
tags: [project]
status: active
deadline: 
---

# {{project-name}}

## Goal

## Success Criteria
- [ ] 

## Tasks
- [ ] 

## Notes

## Related

Folder Organization Patterns

Content TypeLocationNaming
Daily notesDaily Notes/YYYY-MM-DD.md
Meeting notesAreas/Meetings/YYYY-MM-DD Topic.md
Project notesProjects/{name}/README.md + sub-notes
ReferenceResources/{topic}/Descriptive title
Permanent notesResources/Zettelkasten/ID + title

Common Pitfalls

  • Spaces in filenames: Obsidian handles them, but some plugins prefer hyphens
  • Nested tags: Use #category/subcategory syntax for hierarchy
  • Sync conflicts: Prefer iCloud or Obsidian Sync over Dropbox for vault sync
  • Large vaults: Limit graph view for vaults >5000 notes; use search instead

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.