Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions modules/obsidian/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# obsidian

A starter pack for a new Obsidian vault: settings (Catppuccin appearance,
hotkeys, vimrc, CSS snippet, per-plugin settings), a folder layout, a root
`AGENTS.md`, `Home.md`, and a `.gitignore`. After seeding, each vault owns
its copy and is free to drift from this one.
A starter pack for an Obsidian vault, new or existing: settings
(Catppuccin appearance, hotkeys, vimrc, CSS snippet, per-plugin settings),
a folder layout, a root `AGENTS.md`, `Home.md`, and a `.gitignore`. After
seeding, each vault owns its copy and is free to drift from this one.

The module is in no role. `./install` and `./provision.sh` skip it; run the
script by hand.
Expand All @@ -14,18 +14,34 @@ script by hand.
~/.dotfiles/modules/obsidian/seed-vault ~/my-vault
```

The script copies files without overwriting existing ones, creates the
folders, and runs `git init` with no remote. Re-running it only fills in
what is missing.
Close Obsidian first; the script refuses to run while it is open, because
Obsidian writes its in-memory settings back over the new files.

The script:

- resets the pack's settings files (`.obsidian/*.json`, the snippet,
per-plugin `data.json`, `.obsidian.vimrc`). A file that differs is
backed up to `~/.local/state/seed-vault/<vault>-<timestamp>/` first.
Settings the pack does not ship, such as `workspace.json` or other
plugins' folders, are left alone. `community-plugins.json` is replaced,
so plugins the vault had enabled that are not in the pack end up
disabled; re-enable them in Settings.
- adds `AGENTS.md`, `Home.md` and `.gitignore` only when missing.
- creates the folders and runs `git init` with no remote if there is no
repo yet.

Re-running it on the same vault resets any settings changed since, again
with a backup.

## Finish in Obsidian

These steps are manual, or for an agent to walk through with the owner.

1. Open the folder as a vault ("Open folder as vault").
2. Settings → Community plugins: turn off Restricted mode, then Browse
and install each of these by name. The seeded settings are picked up
on install.
and install each of these by name. Plugin code is not part of the pack,
so until this step no plugin appears and vim bindings from the vimrc do
nothing. The seeded settings are picked up on install.

| Search for | Plugin id |
|----------------|---------------------------|
Expand Down
4 changes: 2 additions & 2 deletions modules/obsidian/config/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"spellcheck": false,
"defaultViewMode": "source",
"showUnsupportedFiles": true,
"attachmentFolderPath": "attachments",
"attachmentFolderPath": "./",
"mobileToolbarCommands": [
"command-palette:open",
"editor:toggle-checklist-status",
Expand Down Expand Up @@ -52,7 +52,7 @@
],
"propertiesInDocument": "hidden",
"newFileLocation": "folder",
"newFileFolderPath": "_inbox",
"newFileFolderPath": "_Inbox",
"openBehavior": "file:Home.md",
"useTab": false
}
4 changes: 2 additions & 2 deletions modules/obsidian/config/plugins/templater-obsidian/data.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"command_timeout": 5,
"templates_folder": "templates",
"templates_folder": "Templates",
"templates_pairs": [
[
"",
Expand Down Expand Up @@ -31,4 +31,4 @@
],
"intellisense_render": 1,
"enable_ribbon_icon": true
}
}
22 changes: 10 additions & 12 deletions modules/obsidian/config/vault/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,18 @@ Obsidian knowledge vault. Start navigation at [[Home]].
## Structure

```
concepts/ # Ideas you synthesized: flat, evergreen, reusable
projects/ # Things you work on, including their meetings and logs
references/ # External information: people, teams, systems, processes
people/
archive/ # Finished or historical material
templates/ # Templater templates
attachments/ # Pasted images and files
_inbox/ # Default location for new notes; sort regularly
Projects/ # Things you work on, finite or ongoing, with their meetings and logs
Knowledge/ # What you worked out: ideas, mental models, lessons; flat and evergreen
References/ # External information: people, teams, systems, processes
Archive/ # Finished or historical material
Templates/ # Templater templates
_Inbox/ # Default location for new notes; sort regularly
.claude/ # Claude Code skills, hooks, and settings for this vault
```

- Boundary test: "Did I author this insight?" → `concepts/`. "Am I recording external info?" → `references/`. "Am I working on it?" → `projects/`.
- Folders describe domain, not status. Completed projects stay in `projects/` with `status: complete`.
- New notes land in `_inbox/`. Move a note to its folder once its home is clear; `Home.md` lists what is waiting.
- Filing test: "Am I working on it?" → `Projects/`. "Did I work this out myself?" → `Knowledge/`. "Am I recording information from outside?" → `References/`. Group related references in subfolders (`References/People/`) as they accumulate.
- Folders describe domain, not status. Completed projects stay in `Projects/` with `status: complete`.
- New notes land in `_Inbox/`. Move a note to its folder once its home is clear; `Home.md` lists what is waiting.
- Add an `AGENTS.md` to a folder when it gains conventions of its own. This file is authoritative at the root; folder files add local rules.

## Properties (frontmatter)
Expand All @@ -44,7 +42,7 @@ _inbox/ # Default location for new notes; sort regularly

## Templates

Templater reads `templates/`. Templates have frontmatter and no H1; use `<% tp.date.now("YYYY-MM-DD") %>` for dates. When an agent creates a note from a template, it writes the expanded values (such as today's date) instead of the `<% %>` tags.
Templater reads `Templates/`. Templates have frontmatter and no H1; use `<% tp.date.now("YYYY-MM-DD") %>` for dates. When an agent creates a note from a template, it writes the expanded values (such as today's date) instead of the `<% %>` tags.

## Keys

Expand Down
4 changes: 2 additions & 2 deletions modules/obsidian/config/vault/Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ SORT status ASC, file.mtime DESC

## Inbox

New notes land in `_inbox/`. Move each one to its folder once it has a home.
New notes land in `_Inbox/`. Move each one to its folder once it has a home.

```dataview
LIST
FROM "_inbox"
FROM "_Inbox"
SORT file.ctime DESC
```

Expand Down
45 changes: 37 additions & 8 deletions modules/obsidian/seed-vault
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@
#
# usage: seed-vault <vault-path>
#
# Run by hand, once per vault; no role lists this module, so ./install and
# ./provision.sh never touch it. Files are copied rather than linked because
# Obsidian rewrites its JSON whenever a setting changes, and a vault's tweaks
# should stay in that vault. An existing file is never overwritten, so a
# re-run only fills in what is missing.
# Run by hand; no role lists this module, so ./install and ./provision.sh
# never touch it. Files are copied rather than linked because Obsidian
# rewrites its JSON whenever a setting changes, and a vault's tweaks should
# stay in that vault.
#
# Settings (.obsidian/ files from the pack and .obsidian.vimrc) are reset to
# the pack's: an existing file that differs is backed up under
# $XDG_STATE_HOME/seed-vault/ and replaced. Settings the pack does not ship
# (workspace, other plugins) are left alone. Starter content (AGENTS.md,
# Home.md, .gitignore) is never overwritten. Obsidian must be closed, or it
# writes its in-memory settings back over the new files.
#
# Plugin code, the Catppuccin theme, and fonts are not shipped here; see
# README.md for the steps that finish the vault inside Obsidian.
Expand All @@ -37,21 +43,44 @@ place() {
fi
}

# usage: place_setting <src> <dest> - copy, backing up a differing dest.
place_setting() {
local rel="${2#"$VAULT"/}"
if [ -e "$2" ] && cmp -s "$1" "$2"; then
skip "$rel up to date"
return
fi
if [ -e "$2" ]; then
mkdir -p "$(dirname "$BACKUP/$rel")"
cp -p "$2" "$BACKUP/$rel"
note "replaced $rel (old copy in $BACKUP)"
else
mkdir -p "$(dirname "$2")"
note "added $rel"
fi
cp "$1" "$2"
}

if pgrep -x obsidian >/dev/null 2>&1; then
die "Obsidian is running; close it first, or it overwrites the new settings"
fi

log "seeding $VAULT"
mkdir -p "$VAULT"
VAULT="$(cd "$VAULT" && pwd)"
BACKUP="${XDG_STATE_HOME:-$HOME/.local/state}/seed-vault/$(basename "$VAULT")-$(date +%Y%m%dT%H%M%S)"

for d in concepts projects references/people archive templates attachments _inbox .claude/skills; do
for d in Projects Knowledge References Archive Templates _Inbox .claude/skills; do
mkdir -p "$VAULT/$d"
done

# Obsidian settings: everything under config/ except the vimrc (which lives
# at the vault root) and vault/ (starter content).
while IFS= read -r -d '' f; do
rel="${f#"$CONFIG"/}"
place "$f" "$VAULT/.obsidian/$rel"
place_setting "$f" "$VAULT/.obsidian/$rel"
done < <(find "$CONFIG" -path "$CONFIG/vault" -prune -o -type f ! -name vimrc -print0)
place "$CONFIG/vimrc" "$VAULT/.obsidian.vimrc"
place_setting "$CONFIG/vimrc" "$VAULT/.obsidian.vimrc"

# Starter content. gitignore is stored without its dot so it does not apply
# to this repo.
Expand Down
Loading