Tips & Tricks (Atualizado: 03/06/2026)

Claude Code x Obsidian: estrutura do Vault, permissions, templates e auditoria de links

Workflow prático para Claude Code e Obsidian: daily logs, handoff, snippets, content ops e auditoria de links.

Claude Code x Obsidian: estrutura do Vault, permissions, templates e auditoria de links

Um Vault do Obsidian fica mais valioso com o tempo, mas também exige mais manutenção. Daily notes se acumulam, notas de projeto ficam desatualizadas, snippets de código perdem contexto de versão e ideias de conteúdo param de apontar para os links internos ou CTAs corretos. Claude Code pode ajudar porque, no fundo, um Vault é uma pasta com arquivos Markdown.

O caminho seguro não é pedir para a IA reorganizar tudo. O workflow útil é limitado: estrutura pequena, permissions estreitas, templates reutilizáveis e uma auditoria de links depois das alterações. Para iniciantes, o Vault é a pasta de notas; o harness é a base de trabalho que diz ao agente onde ele pode ler, escrever e verificar.

Este guia cobre quatro use case: daily logs, project handoff, code snippets e content operations. Também mostra cada pitfall e risk importante, porque o maior problema costuma ser um link quebrado, uma Property YAML inválida ou uma nota privada lida sem necessidade.

Modelo de integração

A ajuda oficial do Obsidian explica que internal links podem usar Wikilinks como [[Nome da nota]] ou links Markdown. Daily notes é um core plugin para notas por data. Templates pode inserir valores como {{date}}, e Properties usa YAML no topo da nota. Veja as páginas oficiais de internal links, Daily notes, Templates, Properties e Web Clipper templates.

No Claude Code, a fronteira de segurança vem de settings e permissions. CLAUDE.md ensina as regras do Vault. .claude/settings.json limita leitura, escrita e comandos.

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 no Obsidian continua sendo a fonte da verdade. Claude Code ajuda a organizar, resumir, preparar rascunhos e verificar links.

Comece com uma estrutura pequena

Use pastas que correspondam a trabalho real.

mkdir -p inbox daily projects content-ops snippets templates scripts archive private
PastaUsoTrabalho seguro para Claude Code
inbox/capturas brutas e Web Clippercriar e classificar
daily/daily logs e memória de trabalhocriar, acrescentar, resumir ontem
projects/project handoff e decisõesatualizar handoff
content-ops/ideias de artigos, CTA, publicaçãoorganizar drafts e links
snippets/comandos e exemplos de códigoadicionar contexto e tags
templates/templates do Obsidianler; editar só com aprovação
archive/notas encerradasnão editar
private/dados pessoais ou secretosnão ler

Essa estrutura cobre casos concretos. Daily logs carregam tarefas não concluídas. Project handoff explica objetivo, estado, próxima ação e risk. Snippets guardam comando executável, versão e failure case. Content operations verifica links oficiais, links internos, /products/ e /training/.

Adicione CLAUDE.md

Coloque este arquivo na raiz do Vault.

# 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 .`.

O pitfall comum é pedir “organize meu Vault”. Claude Code passa a adivinhar pastas, títulos e tags. A saída pode parecer limpa, mas quebrar pesquisa, Graph view e backlinks.

Configure permissions estreitas

Crie .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 *)"
    ]
  }
}

Essa configuração permite o trabalho diário, mas pede confirmação para templates, Git e WebFetch. Evite bypass amplo em Vaults reais.

Três templates do Obsidian

O daily template deve ser leve.

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

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

## Today
- [ ]

## Learned
-

## Questions
-

## Links
- [[Weekly review]]

O project handoff deixa a próxima ação visível.

---
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]]

O template de content operations inclui monetização desde o planejamento.

---
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

Leia também approval e sandbox, documentation generation e content funnel audit. Materiais reutilizáveis vão para products e adoção em equipe para training.

Salve como 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}`);

Execute:

node scripts/audit-wikilinks.cjs .

Prompt delimitado:

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.

Pitfalls comuns

Primeiro: permitir edição de .obsidian/. Plugins, temas e atalhos não são notas comuns.

Segundo: renomear notas fora do Obsidian. Bulk rename pode quebrar backlinks.

Terceiro: YAML Properties sem aspas. Use related: "[[Project name]]".

Quarto: daily notes pesadas demais. Template que ninguém preenche vira ruído.

Quinto: content operations não é só escrita. Um artigo público precisa de links oficiais, links internos, CTA e verificação.

O que Masa testou

No Vault de teste de Masa, os melhores resultados vieram de dois workflows: levar tarefas inacabadas para a próxima daily note e auditar links antes de publicar notas de conteúdo. A pior experiência foi pedir “limpe todo o Vault”; Claude Code criou tags e headings demais. Permissions estreitas, templates leves e auditoria Node deram um processo mais estável.

#claude-code #obsidian #pkm #markdown #automation #second-brain
Grátis

PDF grátis: cheatsheet do Claude Code

Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.

Cuidamos dos seus dados e não enviamos spam.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.