conorluddy/obsidianskills · Archived

obsidian-link

Link, inspect, or unlink a project's Claude Code agents and skills in an Obsidian vault.

First seen May 5, 2026

Installation

$ npx skills add conorluddy/obsidianskills --skill obsidian-link

Summary

  • Link, inspect, or unlink a project's Claude Code agents and skills in an Obsidian vault.
  • Four modes: `/obsidian-link` (link, default), `/obsidian-link status` (health check), `/obsidian-link unlink <project>` (remove), `/obsidian-link init` (configure plan frontmatter in CLAUDE.md).
  • Handles idempotency, broken symlink detection, Plans symlink, and auto-generates an Obsidian index note with wikilinks.

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from conorluddy/obsidianskills.

npx skills add conorluddy/obsidianskills

Browse all from conorluddy/obsidianskills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 4
License MIT
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Declared agents claude-code

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 13,099 B
  • docs SUMMARY.md 424 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 3 installs

SKILL.md

obsidian-link

Connect a project's Claude Code configuration (agents, skills) to an Obsidian vault for browsing, searching, and cross-referencing.

Directionality:

  • Global agents/skills: Obsidian is source of truth, symlinked into ~/.claude/
  • Per-project agents/skills: Project repo is source of truth, symlinked into Obsidian

Mode Dispatch

Parse the user's input to determine mode:

  • /obsidian-link or /obsidian-link link → Link mode (default)
  • /obsidian-link status → Status mode
  • /obsidian-link unlink <project> → Unlink mode
  • /obsidian-link init → Init mode (configure plan frontmatter)

Configuration

Resolving the vault path

Check in order:

  1. OBSIDIAN_VAULT environment variable
  2. ~/.obsidian-vault file (single line, absolute path)

If found, confirm with the user. If not found, ask. Once confirmed, offer to save to ~/.obsidian-vault.

Directory structure

<vault>/ClaudeCode/
  ├── README.md           # Auto-generated index (wikilinks)
  ├── Agents/
  │   ├── global/
  │   └── <project>/
  ├── Skills/
  │   ├── global/
  │   └── <project>/
  └── Plans/              # ~/.claude/plans → here

Preflight (runs before every mode)

Before executing any mode, silently check the current setup state. This takes a few seconds and informs how you interact with the user.

Checks

Check How States
Vault path ~/.obsidian-vault file or $OBSIDIAN_VAULT configured / missing
Vault directory <vault>/ClaudeCode/ exists exists / missing
Plans symlink readlink ~/.claude/plans linked-to-vault / linked-elsewhere / missing
Plan frontmatter Search ~/.claude/CLAUDE.md for ## Plan Files section configured / missing
Project linked <vault>/ClaudeCode/Agents/<project>/ has symlinks linked / not-linked

Behaviour

Summarise the setup state in a compact block before proceeding with the requested mode:

obsidian-link preflight:
  Vault:       /path/to/vault (OK)
  Plans:       ~/.claude/plans → vault (OK)
  Frontmatter: configured in CLAUDE.md (OK) | not configured
  Project:     <project> linked (6 agents, 2 skills) | not linked

Then, based on state and requested mode:

  • If vault path is missing → Ask the user before continuing with any mode. Cannot proceed without it.
  • If frontmatter is not configured and mode is link or status → Append a suggestion after the mode completes:

> Tip: Run /obsidian-link init to configure plan frontmatter in your CLAUDE.md — plans will then be browsable in Obsidian with Dataview, tags, and graph view.

  • If frontmatter is not configured and mode is init → Expected, proceed normally.
  • If frontmatter is already configured and mode is init → Show current config in preflight, then Step 2 of Init mode handles the replace-or-keep flow.
  • If project is not linked and mode is status → Note it in the status report, suggest running /obsidian-link to link.

The preflight should be lightweight and informational — never block a mode from running (except when vault path is missing). Its purpose is context, not gatekeeping.


Link Mode (default)

Step 1: Resolve vault + ensure directories

Confirm vault path, then: mkdir -p "<vault>/ClaudeCode/{Agents/global,Skills/global,Plans}"

Step 2: Plans symlink

Check ~/.claude/plans:

  • Missing → ln -sf "<vault>/ClaudeCode/Plans" "$HOME/.claude/plans"
  • Exists, target matches vault → skip (OK)
  • Exists, points elsewhere → warn and skip (do not overwrite)

Step 3: Detect project

git rev-parse --show-toplevel → basename, lowercased. If not in a git repo, ask for project name and root path.

Step 4: Link project agents (idempotent)

If <repo>/.claude/agents/ exists, mkdir -p "<vault>/ClaudeCode/Agents/<project>".

For each .md file, before creating a symlink, check existing state:

target="<vault>/ClaudeCode/Agents/<project>/<file>"
expected="<repo>/.claude/agents/<file>"
current=$(readlink "$target" 2>/dev/null)

if [ "$current" = "$expected" ]; then
  # already_linked — skip
elif [ -L "$target" ]; then
  # wrong target — overwrite (count as updated)
  ln -sf "$expected" "$target"
else
  # new — create
  ln -sf "$expected" "$target"
fi

Track counts: new, already_linked, updated.

Step 5: Link project skills (idempotent)

Same pattern as Step 4, but for each skill directory in <repo>/.claude/skills/.

Step 6: Sync global skills into ~/.claude

For each skill directory in <vault>/ClaudeCode/Skills/global/ (must contain SKILL.md):

  • If ~/.claude/skills/<name> doesn't exist → create symlink
  • If it exists and points to vault → skip
  • If it exists and points elsewhere → skip (never overwrite non-Obsidian skills)

Step 7: Sync global agents into ~/.claude

  • ~/.claude/agents doesn't exist → ln -sf "<vault>/ClaudeCode/Agents/global" "$HOME/.claude/agents"
  • Exists as symlink to vault → skip
  • Exists as real directory or wrong symlink → warn, skip

Step 8: Broken symlink detection

After all linking:

find "<vault>/ClaudeCode/Agents" "<vault>/ClaudeCode/Skills" -type l ! -exec test -e {} \; -print

Report broken links with their targets. Suggest cleanup but never auto-delete.

Step 9: Generate index note

Write <vault>/ClaudeCode/README.md (fully regenerated each run):

---
type: index
title: Claude Code Hub
updated: <YYYY-MM-DD>
tags:
  - claude-code
  - index
---

# Claude Code Hub

## Projects

| Project | Agents | Skills | Status |
|---------|--------|--------|--------|
| <name> | <count> | <count> | OK / N broken |

## Global

| Type | Name | Link |
|------|------|------|
| Agent | <name> | [[<name>]] |
| Skill | <name> | [[<name>]] |

## Plans

<count> plan files in ClaudeCode/Plans/

Use [[wikilinks]] for all agent and skill names so Obsidian's graph view connects them. Scan Agents/ and Skills/ subdirs (excluding global/) for project names.

Step 10: Report

obsidian-link: <project>

  Vault:   <vault-path>
  Project: <project> (<repo-root>)

  Agents: <N> new, <N> already linked
  Skills: <N> new, <N> already linked
  Broken: none | <N> broken (listed above)
  Plans:  ~/.claude/plans → vault (OK) | WARNING: points elsewhere | created

  Global: <N> skills synced, agents symlink OK
  Index:  ClaudeCode/README.md updated

Status Mode

Scans the vault's ClaudeCode/ directories (not the filesystem) to report health of all linked projects.

Steps

  1. Resolve vault path (same as Link mode Step 1)
  2. Scan <vault>/ClaudeCode/Agents/ and Skills/ for project subdirs (excluding global/)
  3. For each project: count symlinks, count broken symlinks, report health
  4. Check global sync: agents symlink target, skills presence
  5. Check Plans symlink
  6. Regenerate index note (Step 9 from Link mode)

Report format

obsidian-link status

  Vault: <vault-path>

  Projects:
    project-a  — 16 agents, 1 skill, 0 broken
    project-b  — 4 agents, 2 skills, 1 broken
      broken: project-b/old-agent.md → /path/that/moved

  Global: agents OK, 3 skills synced
  Plans:  ~/.claude/plans → vault (OK)
  Index:  ClaudeCode/README.md updated

Unlink Mode

Removes a project's symlinks from the vault. Never deletes repo files.

Steps

  1. Resolve vault path
  2. Validate <project> exists in <vault>/ClaudeCode/Agents/<project> or Skills/<project>
  3. Show what will be removed (counts per directory)
  4. Ask for explicit user confirmation before proceeding
  5. Remove the project's directories:

``bash rm -rf "<vault>/ClaudeCode/Agents/<project>" rm -rf "<vault>/ClaudeCode/Skills/<project>" `` These dirs contain only symlinks — repo source files are untouched.

  1. Regenerate index note

Report format

obsidian-link unlink: <project>

  Removed: 16 agent links, 1 skill link
  Source files in <repo-root> are untouched.
  Index: ClaudeCode/README.md updated

Init Mode

Interactively configures ~/.claude/CLAUDE.md so that Claude always adds Obsidian-friendly frontmatter when creating plan files. This is a one-time setup — safe to re-run (idempotent).

Step 1: Resolve vault path

Same as Link mode. Needed to generate the correct ~/.claude/plans symlink path in instructions.

Step 2: Check for existing frontmatter instructions

Search ~/.claude/CLAUDE.md for a ## Plan Files section (or similar frontmatter block referencing plans/).

  • Found → Show the user the current config, ask if they want to replace or keep it.
  • Not found → Proceed to Step 3.

Step 3: Ask the user about their frontmatter fields

Present a conversational prompt like:

I'll add instructions to your global CLAUDE.md so plan files always get Obsidian-friendly frontmatter.

Here are some common fields — which would you like?

Default fields (always included unless explicitly removed):

Field Example Purpose
type plan Obsidian note type for Dataview/queries
title User Auth OAuth Flow Human-readable title
status `draft \ approved \ done` Plan lifecycle tracking
created 2026-03-05 Creation date
tags [plan, <project>] Obsidian tag navigation

Optional fields (suggest these, let user pick):

Field Example Purpose
id <project>-oauth-flow Unique slug for cross-referencing
projects [proj-<project>] Multi-project attribution
priority `high \ medium \ low` Prioritisation
complexity 1-5 Estimation (per user's preference)
related [[other-plan]] Wikilink to related plans
linear PROJ-123 Linear/issue tracker reference
updated 2026-03-05 Last-modified date

Let the user add, remove, or rename fields freely. They may also suggest entirely custom fields — accept any valid YAML key.

Step 4: Ask about filename convention

Present the current convention (or a sensible default):

Filename format: <project>-<kebab-slug>.md (3–6 words)
e.g. myapp-user-auth-oauth-flow.md, backend-stripe-billing-integration.md

Want to adjust this? (e.g. date prefix, different separator, no project prefix)

Accept the user's preference or confirm the default.

Step 5: Generate the CLAUDE.md section

Build a ## Plan Files section containing:

  1. The filename convention
  2. A YAML frontmatter template with the chosen fields
  3. Brief inline comments showing example values

Example output (will vary based on user choices):

## Plan Files

When writing plan files (in `~/.claude/plans/`, which symlinks to `ObsidianVault/Plans/`), always include this frontmatter so they're browsable in Obsidian:

Filename should be kebab-case, prefixed with the project name, 3-6 words total, reflecting the plan content. E.g. `myapp-user-auth-oauth-flow.md`, `backend-stripe-billing-integration.md`.

\```yaml
---
type: plan
id: <project>-<kebab-slug>
title: <human-readable title>
status: draft | approved | done
projects:
  - <project ID>
tags:
  - plan
  - <project tag>
created: "<YYYY-MM-DD>"
---
\```

Step 6: Preview and confirm

Show the user the exact block that will be inserted (or will replace the existing block). Ask for confirmation before writing.

Step 7: Write to CLAUDE.md

  • If replacing an existing ## Plan Files section: replace from ## Plan Files to the next ## heading (or end of file).
  • If inserting new: add before the first --- horizontal rule after the initial sections, or append before # Code Style if that heading exists. Use best judgement to place it logically.
  • Never overwrite unrelated sections.

Step 8: Report

obsidian-link init: complete

  CLAUDE.md: ~/.claude/CLAUDE.md updated
  Section:   ## Plan Files (inserted | replaced)
  Fields:    type, title, status, created, tags, id, projects
  Filename:  <project>-<kebab-slug>.md

  Plans will now include Obsidian frontmatter automatically.

Notes

  • Never auto-delete broken symlinks — report them and let the user decide
  • Never overwrite non-Obsidian configs — if ~/.claude/agents is a real directory, warn and skip
  • Idempotent by design — running Link mode repeatedly produces the same result with accurate counts
  • Index note is disposable — fully regenerated each run, safe to delete manually