Tips & Tricks (Mis à jour: 03/06/2026)

Claude Code x Obsidian: structure du Vault, permissions, templates et audit des liens

Guide pratique Claude Code et Obsidian pour daily logs, handoff, snippets, content ops et audit des liens internes.

Claude Code x Obsidian: structure du Vault, permissions, templates et audit des liens

Un Vault Obsidian devient plus utile avec le temps, mais il devient aussi plus difficile à maintenir. Les notes quotidiennes s’empilent, les pages projet ne reflètent plus l’état réel, les snippets de code perdent leurs versions, et les idées d’articles oublient les liens internes ou les CTA qui devaient les accompagner. Claude Code peut aider, car un Vault est avant tout un dossier de fichiers Markdown.

Le bon workflow n’est pas de demander à l’IA de tout réorganiser. Il faut cadrer le travail: une petite structure de dossiers, des permissions étroites, des templates réutilisables et un audit de liens après modification. Pour débuter, on peut voir le Vault comme le dossier de notes, et le harness comme l’échafaudage qui indique à l’agent où lire, où écrire et quelle vérification exécuter.

Ce guide couvre quatre use case: daily logs, project handoff, snippets de code et content operations. Il détaille aussi les pitfall et risk principaux, car le vrai danger n’est pas seulement une phrase maladroite. Le vrai danger est un lien cassé, une propriété YAML invalide ou un dossier privé lu sans raison.

Le modèle d’intégration

L’aide officielle d’Obsidian explique que les liens internes peuvent utiliser des Wikilinks comme [[Nom de note]] ou des liens Markdown. Daily notes est un plugin de base pour les notes datées. Templates peut insérer {{date}}, et Properties stocke des métadonnées YAML en haut du fichier. Consultez les pages officielles sur les internal links, Daily notes, Templates, Properties et Web Clipper templates.

Côté Claude Code, les limites se définissent avec settings et permissions. CLAUDE.md décrit les règles du Vault, puis .claude/settings.json encadre les lectures, écritures et commandes.

flowchart LR
  A["Inbox"] --> B["Claude Code review"]
  B --> C["Daily logs"]
  B --> D["Projects"]
  B --> E["Content ops"]
  C --> F["Obsidian links"]
  D --> F
  E --> F
  F --> G["Link audit"]

Markdown reste la source de vérité. Claude Code trie, résume, prépare et vérifie; il ne doit pas devenir propriétaire du Vault.

Garder une structure simple

Commencez par des dossiers liés à des tâches concrètes.

mkdir -p inbox daily projects content-ops snippets templates scripts archive private
DossierRôleTravail sûr pour Claude Code
inbox/captures brutes et Web Clippercréer et trier
daily/journal quotidien et mémoire de travailcréer, compléter, résumer la veille
projects/handoff et décisionsmettre à jour l’état projet
content-ops/idées d’articles, CTA, publicationorganiser brouillons et liens
snippets/commandes et exemplesajouter contexte, version et tags
templates/templates Obsidianlire, éditer après accord
archive/notes geléesne pas modifier
private/données personnelles ou sensiblesne pas lire

Cette structure couvre les cas courants. Les daily logs reprennent les tâches non terminées. Les notes de project handoff indiquent objectif, état, prochaine action et risk. Les snippets gardent le code exécutable avec son contexte. Les notes content operations vérifient liens officiels, liens internes, /products/ et /training/.

Ajouter CLAUDE.md

Placez ce fichier à la racine du Vault. Il doit être direct.

# Obsidian Vault Rules

## Purpose
- This vault stores daily logs, project handoffs, code snippets, and content operations notes.
- Keep notes useful in Obsidian without requiring Claude Code to read private files.

## Directory policy
- `daily/`: create or update daily notes in `YYYY-MM-DD.md`.
- `projects/`: maintain one handoff note per active project.
- `content-ops/`: maintain article plans, CTA checks, and publishing notes.
- `snippets/`: store runnable commands and code examples with context.
- `templates/`: read freely, but ask before editing.
- `archive/` and `private/`: do not edit. Do not summarize private files.

## Note rules
- Use Wikilinks like `[[Project name]]` for internal links.
- Use YAML properties at the top of notes.
- Keep one paragraph under five lines.
- Add a `source:` property when a note comes from a URL.
- Add `status: draft`, `status: active`, or `status: done`.

## Safety rules
- Never rename existing notes without asking first.
- Never rewrite `.obsidian/` settings.
- Before bulk edits, list the target files and wait for approval.
- After changes, run `node scripts/audit-wikilinks.cjs .`.

Le pitfall classique est une consigne vague comme “range ce Vault”. Claude Code devine alors dossiers, titres et tags. Ces choix peuvent sembler propres mais dégrader la recherche, la vue graph et les handoffs.

Limiter les permissions

Créez .claude/settings.json.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Read(./CLAUDE.md)",
      "Read(./daily/**)",
      "Read(./projects/**)",
      "Read(./content-ops/**)",
      "Read(./snippets/**)",
      "Read(./templates/**)",
      "Read(./scripts/**)",
      "Edit(./daily/**)",
      "Edit(./projects/**)",
      "Edit(./content-ops/**)",
      "Edit(./snippets/**)",
      "Write(./inbox/**)",
      "Write(./daily/**)",
      "Write(./projects/**)",
      "Write(./content-ops/**)",
      "Write(./snippets/**)",
      "Bash(node scripts/audit-wikilinks.cjs .)"
    ],
    "ask": [
      "Edit(./templates/**)",
      "Bash(git *)",
      "WebFetch"
    ],
    "deny": [
      "Read(./private/**)",
      "Read(./**/.env)",
      "Read(./**/.env.*)",
      "Edit(./.obsidian/**)",
      "Edit(./archive/**)",
      "Write(./archive/**)",
      "Bash(rm *)",
      "Bash(del *)"
    ]
  }
}

Le but est simple: autoriser le travail répétitif, demander confirmation pour les zones sensibles, bloquer le privé. Un mode bypass large ne convient qu’à un Vault jetable ou isolé.

Trois templates utiles

Le daily log doit rester léger.

---
date: "{{date:YYYY-MM-DD}}"
status: active
tags:
  - daily
---

# {{date:YYYY-MM-DD}}

## Today
- [ ]

## Learned
-

## Questions
-

## Links
- [[Weekly review]]

Le project handoff met la prochaine action au centre.

---
status: active
owner: Masa
tags:
  - project
  - handoff
updated: "{{date:YYYY-MM-DD}}"
---

# Project handoff: {{title}}

## Goal

## Current state

## Next action
- [ ]

## Decisions
-

## Risks and pitfall
-

## Links
- [[Daily note]]
- [[Related snippet]]

Le template content operations relie le contenu aux objectifs de publication.

---
status: draft
channel: blog
source:
target_cta:
  - /products/
  - /training/
tags:
  - content-ops
---

# Content ops note: {{title}}

## Search intent

## Reader problem

## Outline

## Internal links
- [[Claude Code approval sandbox guide]]
- [[Claude Code documentation generation]]

## Monetization CTA
- Product CTA:
- Training CTA:

## Publish checklist
- [ ] Official links checked
- [ ] Code examples tested
- [ ] Broken internal links audited

Pour continuer, utilisez approval et sandbox, génération de documentation et audit de funnel contenu. Les ressources réutilisables vont vers products, et les équipes vers training.

Auditer les liens avec Node

Enregistrez ce script sous scripts/audit-wikilinks.cjs.

#!/usr/bin/env node
const fs = require("node:fs");
const path = require("node:path");

const vaultRoot = path.resolve(process.argv[2] || ".");
const ignoredDirs = new Set([".git", ".obsidian", ".trash", "node_modules"]);
const allFiles = [];
const markdownFiles = [];

function walk(dir) {
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    if (ignoredDirs.has(entry.name)) continue;
    const full = path.join(dir, entry.name);
    if (entry.isDirectory()) {
      walk(full);
    } else if (entry.isFile()) {
      allFiles.push(full);
      if (entry.name.toLowerCase().endsWith(".md")) markdownFiles.push(full);
    }
  }
}

function toPosix(filePath) {
  return filePath.split(path.sep).join("/");
}

function withoutMd(value) {
  return value.replace(/\.md$/i, "");
}

function stripTarget(raw) {
  return raw.split("|")[0].split("#")[0].split("^")[0].trim();
}

function safeDecode(value) {
  try {
    return decodeURIComponent(value);
  } catch {
    return value;
  }
}

function isExternal(target) {
  return /^(https?:|mailto:|obsidian:|#|\/)/i.test(target);
}

function candidateKeys(target, fromFile) {
  const clean = safeDecode(stripTarget(target));
  if (!clean) return [];
  const keys = new Set();
  const normalized = toPosix(path.normalize(clean));
  keys.add(normalized);
  keys.add(withoutMd(normalized));

  if (clean.includes("/") || clean.includes("\\")) {
    const fromDir = path.dirname(toPosix(path.relative(vaultRoot, fromFile)));
    const relative = toPosix(path.normalize(path.join(fromDir, clean)));
    keys.add(relative);
    keys.add(withoutMd(relative));
  } else {
    keys.add(withoutMd(path.posix.basename(normalized)));
    keys.add(path.posix.basename(normalized));
  }

  return [...keys].filter(Boolean);
}

walk(vaultRoot);

const byPath = new Map();
const byBase = new Map();

for (const file of allFiles) {
  const rel = toPosix(path.relative(vaultRoot, file));
  const lowerRel = rel.toLowerCase();
  byPath.set(lowerRel, file);
  if (rel.toLowerCase().endsWith(".md")) byPath.set(withoutMd(lowerRel), file);

  const base = rel.toLowerCase().endsWith(".md")
    ? withoutMd(path.posix.basename(rel)).toLowerCase()
    : path.posix.basename(rel).toLowerCase();
  const list = byBase.get(base) || [];
  list.push(file);
  byBase.set(base, list);
}

const problems = [];
const wikilink = /!?\[\[([^\]]+)\]\]/g;
const markdownLink = /!?\[[^\]]*\]\(([^)]+)\)/g;

for (const file of markdownFiles) {
  const text = fs.readFileSync(file, "utf8");
  const rel = toPosix(path.relative(vaultRoot, file));
  const targets = [];
  let match;

  while ((match = wikilink.exec(text))) targets.push(match[1]);
  while ((match = markdownLink.exec(text))) {
    const target = match[1].replace(/^<|>$/g, "").trim();
    if (!isExternal(target)) targets.push(target);
  }

  for (const target of targets) {
    const clean = stripTarget(target);
    if (!clean || isExternal(clean)) continue;
    const keys = candidateKeys(clean, file);
    const pathHit = keys.some((key) => byPath.has(key.toLowerCase()));
    const baseHits = keys.flatMap((key) => byBase.get(path.posix.basename(key).toLowerCase()) || []);

    if (!pathHit && baseHits.length === 0) {
      problems.push(`${rel} -> missing [[${clean}]]`);
    } else if (!pathHit && baseHits.length > 1) {
      problems.push(`${rel} -> ambiguous [[${clean}]] (${baseHits.length} matches)`);
    }
  }
}

if (problems.length) {
  console.error("Broken or ambiguous internal links:");
  for (const problem of problems) console.error(`- ${problem}`);
  process.exit(1);
}

console.log(`OK: checked ${markdownFiles.length} Markdown files in ${vaultRoot}`);

Commande:

node scripts/audit-wikilinks.cjs .

Prompt borné:

Read `daily/2026-06-02.md` and `projects/site-refresh.md`.
Create `daily/2026-06-03.md` from `templates/daily.md`.
Carry over unfinished tasks only when they still have an owner.
Do not edit `.obsidian/`, `archive/`, or `private/`.
After editing, run `node scripts/audit-wikilinks.cjs .` and report the result.

Pièges courants

Premier pitfall: laisser modifier .obsidian/. Plugins, thèmes et raccourcis ne sont pas des notes ordinaires.

Deuxième: renommer des fichiers hors d’Obsidian. Les backlinks peuvent casser.

Troisième: oublier les guillemets dans les Properties YAML. Utilisez related: "[[Project name]]".

Quatrième: surcharger les daily logs. Une note quotidienne doit être facile à remplir.

Cinquième: traiter content operations comme de la rédaction seulement. Une page publique a aussi des liens, CTA et vérifications.

Ce que Masa a testé

Dans le Vault de test de Masa, les meilleurs résultats venaient du report des tâches non terminées et de l’audit des liens avant publication. La moins bonne expérience était “nettoie tout le Vault”: Claude Code a ajouté trop de tags et de titres. Des permissions étroites, des templates légers et l’audit Node ont donné un workflow plus fiable.

#claude-code #obsidian #pkm #markdown #automation #second-brain
Gratuit

PDF gratuit: cheatsheet Claude Code

Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.

Nous protégeons vos données et n'envoyons pas de spam.

Masa

À propos de l'auteur

Masa

Ingénieur spécialisé dans les workflows pratiques avec Claude Code.