obsidian-bases
Create and edit Obsidian Bases (.base files) with views, filters, formulas, and summaries. Use when working with .base files, creating database-like views of notes, or when the user mentions Bases, table views, card views, filters, or formulas in Obsidian.
git clone --depth 1 https://github.com/breferrari/obsidian-mind /tmp/obsidian-bases && cp -r /tmp/obsidian-bases/.claude/skills/obsidian-bases ~/.claude/skills/obsidian-basesSKILL.md
# Obsidian Bases Skill
## Workflow
1. **Create the file**: Create a `.base` file in the vault with valid YAML content
2. **Define scope**: Add `filters` to select which notes appear (by tag, folder, property, or date)
3. **Add formulas** (optional): Define computed properties in the `formulas` section
4. **Configure views**: Add one or more views (`table`, `cards`, `list`, or `map`) with `order` specifying which properties to display
5. **Validate**: Verify the file is valid YAML with no syntax errors. Check that all referenced properties and formulas exist. Common issues: unquoted strings containing special YAML characters, mismatched quotes in formula expressions, referencing `formula.X` without defining `X` in `formulas`
6. **Test in Obsidian**: Open the `.base` file in Obsidian to confirm the view renders correctly. If it shows a YAML error, check quoting rules below
## Schema
Base files use the `.base` extension and contain valid YAML.
```yaml
# Global filters apply to ALL views in the base
filters:
# Can be a single filter string
# OR a recursive filter object with exactly ONE key: and, or, or not
and:
- 'status == "active"'
- not:
- 'file.hasTag("archived")'
# Define formula properties that can be used across all views
formulas:
formula_name: 'expression'
# Configure display names and settings for properties
properties:
property_name:
displayName: "Display Name"
formula.formula_name:
displayName: "Formula Display Name"
file.ext:
displayName: "Extension"
# Define custom summary formulas
summaries:
custom_summary_name: 'values.mean().round(3)'
# Define one or more views
views:
- type: table | cards | list | map
name: "View Name"
limit: 10 # Optional: limit results
groupBy: # Optional: group results
property: property_name
direction: ASC | DESC
filters: # View-specific filters follow the same rules
and:
- 'status == "active"'
order: # Properties to display in order
- file.name
- property_name
- formula.formula_name
summaries: # Map properties to summary formulas
property_name: Average
```
## Filter Syntax
Filters narrow down results. They can be applied globally or per-view.
### Filter Structure
```yaml
# Single filter
filters: 'status == "done"'
# AND - all conditions must be true
filters:
and:
- 'status == "done"'
- 'priority > 3'
# OR - any condition can be true
filters:
or:
- 'file.hasTag("book")'
- 'file.hasTag("article")'
# NOT - exclude matching items
filters:
not:
- 'file.hasTag("archived")'
# Nested filters
filters:
or:
- file.hasTag("tag")
- and:
- file.hasTag("book")
- file.hasLink("Textbook")
- not:
- file.hasTag("book")
- file.inFolder("Required Reading")
```
### Filter Operators
| Operator | Description |
|----------|-------------|
| `==` | equals |
| `!=` | not equal |
| `>` | greater than |
| `<` | less than |
| `>=` | greater than or equal |
| `<=` | less than or equal |
| `&&` | logical and |
| `\|\|` | logical or |
| <code>!</code> | logical not |
## Properties
### Three Types of Properties
1. **Note properties** - From frontmatter: `note.author` or just `author`
2. **File properties** - File metadata: `file.name`, `file.mtime`, etc.
3. **Formula properties** - Computed values: `formula.my_formula`
### File Properties Reference
| Property | Type | Description |
|----------|------|-------------|
| `file.name` | String | File name |
| `file.basename` | String | File name without extension |
| `file.path` | String | Full path to file |
| `file.folder` | String | Parent folder path |
| `file.ext` | String | File extension |
| `file.size` | Number | File size in bytes |
| `file.ctime` | Date | Created time |
| `file.mtime` | Date | Modified time |
| `file.tags` | List | All tags in file |
| `file.links` | List | Internal links in file |
| `file.backlinks` | List | Files linking to this file |
| `file.embeds` | List | Embeds in the note |
| `file.properties` | Object | All frontmatter properties |
### The `this` Keyword
- In main content area: refers to the base file itself
- When embedded: refers to the embedding file
- In sidebar: refers to the active file in main content
## Formula Syntax
Formulas compute values from properties. Defined in the `formulas` section.
```yaml
formulas:
# Simple arithmetic
total: "price * quantity"
# Conditional logic
status_icon: 'if(done, "✅", "⏳")'
# String formatting
formatted_price: 'if(price, price.toFixed(2) + " dollars")'
# Date formatting
created: 'file.ctime.format("YYYY-MM-DD")'
# Calculate days since created (use .days for Duration)
days_old: '(now() - file.ctime).days'
# Calculate days until due date
days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'
```
## Key Functions
Most commonly used functions. For the complete reference of all types (Date, String, Number, List, File, Link, Object, RegExp), see [FUNCTIONS_REFERENCE.md](references/FUNCTIONS_REFERENCE.md).
| Function | Signature | Description |
|----------|-----------|-------------|
| `date()` | `date(string): date` | Parse string to date (`YYYY-MM-DD HH:mm:ss`) |
| `now()` | `now(): date` | Current date and time |
| `today()` | `today(): date` | Current date (time = 00:00:00) |
| `if()` | `if(condition, trueResult, falseResult?)` | Conditional |
| `duration()` | `duration(string): duration` | Parse duration string |
| `file()` | `file(path): file` | Get file object |
| `link()` | `link(path, display?): Link` | Create a link |
### Duration Type
When subtracting two dates, the result is a **Duration** type (not a number).
**Duration Fields:** `duration.days`, `duration.hours`, `duration.minutes`, `duration.seconds`, `duration.milliseconds`
**IMPORTANT:** Duration does NOT support `.round()`, `.floor()`, `.ceProactively scans for achievements and wins that aren't in the brag doc yet. Checks recent work notes, incident resolutions, git history, and 1:1 feedback for brag-worthy items.
Load all vault context about a specific topic — person, project, incident, team, or concept. Gathers notes, backlinks, mentions, timeline, and produces a synthesized briefing.
Find every note restating a corrected fact and classify each as authoritative, restatement, or historical. Discovery and judgement only — never edits. Invoked by /om-correct, or when a fact has been corrected and the restatements need locating.
Scan recent or specified notes for missing wikilinks. Finds mentions of people, projects, teams, competencies, and incidents that should be linked but aren't. Suggests missing bidirectional links for user approval.
Bulk create or update person notes from Slack profiles. Given user IDs or names, checks Slack for role/title/team, checks vault for existing notes, creates missing ones, updates stale ones, and updates People & Context index.
Verify every factual claim in a review draft against vault sources. Returns verified/unverified/flagged claims.
Aggregate performance review material from the vault for a given period. Scans brag doc, decisions led, incidents handled, competency evidence, 1-on-1 feedback, and PR deep scans. Invoke via /om-review-brief or when the user asks for review prep.
Deep reconstruction of Slack conversations. Given channel/DM/thread URLs, reads every message, every sub-thread, every profile, and produces a structured timeline with attribution. Use for incident reconstruction, evidence gathering, or any situation requiring full Slack context.