--- name: obsidian-bases description: "Obsidian Bases Skill workflow skill. Use this skill when the user needs 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 and the operator should preserve the upstream workflow, copied support files, and provenance before merging or handing off." version: "0.0.1" category: backend tags: ["obsidian-bases", "create", "and", "edit", "obsidian", "bases", "base", "files"] complexity: advanced risk: safe tools: ["codex-cli", "claude-code", "cursor", "gemini-cli", "opencode"] source: community author: "sickn33" date_added: "2026-04-15" date_updated: "2026-04-25" --- # Obsidian Bases Skill ## Overview This public intake copy packages `plugins/antigravity-awesome-skills-claude/skills/obsidian-bases` from `https://github.com/sickn33/antigravity-awesome-skills` into the native Omni Skills editorial shape without hiding its origin. Use it when the operator needs the upstream workflow, support files, and repository context to stay intact while the public validator and private enhancer continue their normal downstream flow. This intake keeps the copied upstream files intact and uses the `external_source` block in `metadata.json` plus `ORIGIN.md` as the provenance anchor for review. # Obsidian Bases Skill Imported source sections that did not map cleanly to the public headings are still preserved below or in the support files. Notable imported sections: Schema, Filter Syntax, Properties, Formula Syntax, Key Functions, View Types. ## When to Use This Skill Use this section as the trigger filter. It should make the activation boundary explicit before the operator loads files, runs commands, or opens a pull request. - Use when creating or editing .base files in Obsidian. - Use for database-like note views with filters, formulas, summaries, or cards/tables. - Use when the user asks about Obsidian Bases specifically. - Use when the request clearly matches the imported source intent: 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.... - Use when the operator should preserve upstream workflow detail instead of rewriting the process from scratch. - Use when provenance needs to stay visible in the answer, PR, or review packet. ## Operating Table | Situation | Start here | Why it matters | | --- | --- | --- | | First-time use | `metadata.json` | Confirms repository, branch, commit, and imported path through the `external_source` block before touching the copied workflow | | Provenance review | `ORIGIN.md` | Gives reviewers a plain-language audit trail for the imported source | | Workflow execution | `references/FUNCTIONS_REFERENCE.md` | Starts with the smallest copied file that materially changes execution | | Supporting context | `references/FUNCTIONS_REFERENCE.md` | Adds the next most relevant copied source file without loading the entire package | | Handoff decision | `## Related Skills` | Helps the operator switch to a stronger native skill when the task drifts | ## Workflow This workflow is intentionally editorial and operational at the same time. It keeps the imported source useful to the operator while still satisfying the public intake standards that feed the downstream enhancer flow. 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 7. Confirm the user goal, the scope of the imported workflow, and whether this skill is still the right router for the task. ### Imported Workflow Notes #### Imported: 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 #### Imported: 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 and/or/not and: [] or: [] not: [] # 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 and: [] order: # Properties to display in order - file.name - property_name - formula.formula_name summaries: # Map properties to summary formulas property_name: Average ``` ## Examples ### Example 1: Ask for the upstream workflow directly ```text Use @obsidian-bases to handle . Start from the copied upstream workflow, load only the files that change the outcome, and keep provenance visible in the answer. ``` **Explanation:** This is the safest starting point when the operator needs the imported workflow, but not the entire repository. ### Example 2: Ask for a provenance-grounded review ```text Review @obsidian-bases against metadata.json and ORIGIN.md, then explain which copied upstream files you would load first and why. ``` **Explanation:** Use this before review or troubleshooting when you need a precise, auditable explanation of origin and file selection. ### Example 3: Narrow the copied support files before execution ```text Use @obsidian-bases for . Load only the copied references, examples, or scripts that change the outcome, and name the files explicitly before proceeding. ``` **Explanation:** This keeps the skill aligned with progressive disclosure instead of loading the whole copied package by default. ### Example 4: Build a reviewer packet ```text Review @obsidian-bases using the copied upstream files plus provenance, then summarize any gaps before merge. ``` **Explanation:** This is useful when the PR is waiting for human review and you want a repeatable audit packet. ### Imported Usage Notes #### Imported: Complete Examples ### Task Tracker Base ```yaml filters: and: - file.hasTag("task") - 'file.ext == "md"' formulas: days_until_due: 'if(due, (date(due) - today()).days, "")' is_overdue: 'if(due, date(due) < today() && status != "done", false)' priority_label: 'if(priority == 1, "🔴 High", if(priority == 2, "🟡 Medium", "🟢 Low"))' properties: status: displayName: Status formula.days_until_due: displayName: "Days Until Due" formula.priority_label: displayName: Priority views: - type: table name: "Active Tasks" filters: and: - 'status != "done"' order: - file.name - status - formula.priority_label - due - formula.days_until_due groupBy: property: status direction: ASC summaries: formula.days_until_due: Average - type: table name: "Completed" filters: and: - 'status == "done"' order: - file.name - completed_date ``` ### Reading List Base ```yaml filters: or: - file.hasTag("book") - file.hasTag("article") formulas: reading_time: 'if(pages, (pages * 2).toString() + " min", "")' status_icon: 'if(status == "reading", "📖", if(status == "done", "✅", "📚"))' year_read: 'if(finished_date, date(finished_date).year, "")' properties: author: displayName: Author formula.status_icon: displayName: "" formula.reading_time: displayName: "Est. Time" views: - type: cards name: "Library" order: - cover - file.name - author - formula.status_icon filters: not: - 'status == "dropped"' - type: table name: "Reading List" filters: and: - 'status == "to-read"' order: - file.name - author - pages - formula.reading_time ``` ### Daily Notes Index ```yaml filters: and: - file.inFolder("Daily Notes") - '/^\d{4}-\d{2}-\d{2}$/.matches(file.basename)' formulas: word_estimate: '(file.size / 5).round(0)' day_of_week: 'date(file.basename).format("dddd")' properties: formula.day_of_week: displayName: "Day" formula.word_estimate: displayName: "~Words" views: - type: table name: "Recent Notes" limit: 30 order: - file.name - formula.day_of_week - formula.word_estimate - file.mtime ``` ## Best Practices Treat the generated public skill as a reviewable packaging layer around the upstream repository. The goal is to keep provenance explicit and load only the copied source material that materially improves execution. - Use single quotes for formulas containing double quotes: 'if(done, "Yes", "No")' - Use double quotes for simple strings: "My View Name" - Escape nested quotes properly in complex expressions - Keep the imported skill grounded in the upstream repository; do not invent steps that the source material cannot support. - Prefer the smallest useful set of support files so the workflow stays auditable and fast to review. - Keep provenance, source commit, and imported file paths visible in notes and PR descriptions. - Point directly at the copied upstream files that justify the workflow instead of relying on generic review boilerplate. ### Imported Operating Notes #### Imported: YAML Quoting Rules - Use single quotes for formulas containing double quotes: `'if(done, "Yes", "No")'` - Use double quotes for simple strings: `"My View Name"` - Escape nested quotes properly in complex expressions ## Troubleshooting ### Problem: The operator skipped the imported context and answered too generically **Symptoms:** The result ignores the upstream workflow in `plugins/antigravity-awesome-skills-claude/skills/obsidian-bases`, fails to mention provenance, or does not use any copied source files at all. **Solution:** Re-open `metadata.json`, `ORIGIN.md`, and the most relevant copied upstream files. Check the `external_source` block first, then restate the provenance before continuing. ### Problem: The imported workflow feels incomplete during review **Symptoms:** Reviewers can see the generated `SKILL.md`, but they cannot quickly tell which references, examples, or scripts matter for the current task. **Solution:** Point at the exact copied references, examples, scripts, or assets that justify the path you took. If the gap is still real, record it in the PR instead of hiding it. ### Problem: The task drifted into a different specialization **Symptoms:** The imported skill starts in the right place, but the work turns into debugging, architecture, design, security, or release orchestration that a native skill handles better. **Solution:** Use the related skills section to hand off deliberately. Keep the imported provenance visible so the next skill inherits the right context instead of starting blind. ### Imported Troubleshooting Notes #### Imported: Troubleshooting ### YAML Syntax Errors **Unquoted special characters**: Strings containing `:`, `{`, `}`, `[`, `]`, `,`, `&`, `*`, `#`, `?`, `|`, `-`, `<`, `>`, `=`, `!`, `%`, `@`, `` ` `` must be quoted. ```yaml # WRONG - colon in unquoted string displayName: Status: Active # CORRECT displayName: "Status: Active" ``` **Mismatched quotes in formulas**: When a formula contains double quotes, wrap the entire formula in single quotes. ```yaml # WRONG - double quotes inside double quotes formulas: label: "if(done, "Yes", "No")" # CORRECT - single quotes wrapping double quotes formulas: label: 'if(done, "Yes", "No")' ``` ### Common Formula Errors **Duration math without field access**: Subtracting dates returns a Duration, not a number. Always access `.days`, `.hours`, etc. ```yaml # WRONG - Duration is not a number "(now() - file.ctime).round(0)" # CORRECT - access .days first, then round "(now() - file.ctime).days.round(0)" ``` **Missing null checks**: Properties may not exist on all notes. Use `if()` to guard. ```yaml # WRONG - crashes if due_date is empty "(date(due_date) - today()).days" # CORRECT - guard with if() 'if(due_date, (date(due_date) - today()).days, "")' ``` **Referencing undefined formulas**: Ensure every `formula.X` in `order` or `properties` has a matching entry in `formulas`. ```yaml # This will fail silently if 'total' is not defined in formulas order: - formula.total # Fix: define it formulas: total: "price * quantity" ``` ## Related Skills - `@00-andruia-consultant` - Use when the work is better handled by that native specialization after this imported skill establishes context. - `@00-andruia-consultant-v2` - Use when the work is better handled by that native specialization after this imported skill establishes context. - `@10-andruia-skill-smith` - Use when the work is better handled by that native specialization after this imported skill establishes context. - `@10-andruia-skill-smith-v2` - Use when the work is better handled by that native specialization after this imported skill establishes context. ## Additional Resources Use this support matrix and the linked files below as the operator packet for this imported skill. They should reflect real copied source material, not generic scaffolding. | Resource family | What it gives the reviewer | Example path | | --- | --- | --- | | `references` | copied reference notes, guides, or background material from upstream | `references/FUNCTIONS_REFERENCE.md` | | `examples` | worked examples or reusable prompts copied from upstream | `examples/n/a` | | `scripts` | upstream helper scripts that change execution or validation | `scripts/n/a` | | `agents` | routing or delegation notes that are genuinely part of the imported package | `agents/n/a` | | `assets` | supporting assets or schemas copied from the source package | `assets/n/a` | - [FUNCTIONS_REFERENCE.md](references/FUNCTIONS_REFERENCE.md) - [FUNCTIONS_REFERENCE.md](references/FUNCTIONS_REFERENCE.md) ### Imported Reference Notes #### Imported: References - [Bases Syntax](https://help.obsidian.md/bases/syntax) - [Functions](https://help.obsidian.md/bases/functions) - [Views](https://help.obsidian.md/bases/views) - [Formulas](https://help.obsidian.md/formulas) - [Complete Functions Reference](references/FUNCTIONS_REFERENCE.md) #### Imported: 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 | | ! | logical not | #### Imported: 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 #### Imported: 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, "")' ``` #### Imported: 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()`, `.ceil()` directly. Access a numeric field first (like `.days`), then apply number functions. ```yaml # CORRECT: Calculate days between dates "(date(due_date) - today()).days" # Returns number of days "(now() - file.ctime).days" # Days since created "(date(due_date) - today()).days.round(0)" # Rounded days # WRONG - will cause error: # "((date(due) - today()) / 86400000).round(0)" # Duration doesn't support division then round ``` ### Date Arithmetic ```yaml # Duration units: y/year/years, M/month/months, d/day/days, # w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds "now() + \"1 day\"" # Tomorrow "today() + \"7d\"" # A week from today "now() - file.ctime" # Returns Duration "(now() - file.ctime).days" # Get days as number ``` #### Imported: View Types ### Table View ```yaml views: - type: table name: "My Table" order: - file.name - status - due_date summaries: price: Sum count: Average ``` ### Cards View ```yaml views: - type: cards name: "Gallery" order: - file.name - cover_image - description ``` ### List View ```yaml views: - type: list name: "Simple List" order: - file.name - status ``` ### Map View Requires latitude/longitude properties and the Maps community plugin. ```yaml views: - type: map name: "Locations" # Map-specific settings for lat/lng properties ``` #### Imported: Default Summary Formulas | Name | Input Type | Description | |------|------------|-------------| | `Average` | Number | Mathematical mean | | `Min` | Number | Smallest number | | `Max` | Number | Largest number | | `Sum` | Number | Sum of all numbers | | `Range` | Number | Max - Min | | `Median` | Number | Mathematical median | | `Stddev` | Number | Standard deviation | | `Earliest` | Date | Earliest date | | `Latest` | Date | Latest date | | `Range` | Date | Latest - Earliest | | `Checked` | Boolean | Count of true values | | `Unchecked` | Boolean | Count of false values | | `Empty` | Any | Count of empty values | | `Filled` | Any | Count of non-empty values | | `Unique` | Any | Count of unique values | #### Imported: Embedding Bases Embed in Markdown files: ```markdown ![[MyBase.base]] ![[MyBase.base#View Name]] ``` #### Imported: Limitations - Use this skill only when the task clearly matches the scope described above. - Do not treat the output as a substitute for environment-specific validation, testing, or expert review. - Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.