Skip to content
wiki-dashboard logo

Wiki Dashboard — Dynamic Vault Views

wiki-dashboard

Create dynamic, queryable dashboard views of the Obsidian vault using Obsidian Bases or Dataview. Use this skill when the user says "create a dashboard", "vault dashboard", "show all X as a table", "dynamic view", "query my vault", "build a content index", "show me all concepts/entities/projects"...

SKILL.md

Full skill instructions

Wiki Dashboard — Dynamic Vault Views

Two tools available: Obsidian Bases (native, GUI-driven, no plugin) and Dataview (community plugin, SQL-like, more powerful). Check which the user has and prefer Bases unless they ask for Dataview or need GROUP BY / computed columns.

Before You Start

  1. Resolve config — follow the Config Resolution Protocol in llm-wiki/​SKILL.md (walk up CWD for .env → ~/​.obsidian-wiki/​config → prompt setup). This gives OBSIDIAN_VAULT_PATH.
  2. Read $OBSIDIAN_VAULT_PATH/​index.md to understand what categories and pages exist.
  3. Ask the user what they want to view if not specified — folder, tag, category, date range?
  4. Ask if they have Dataview installed if you're unsure which tool to use.

Option A — Obsidian Bases (.base files)

Bases are YAML files that define live views over vault notes. Native to Obsidian 1.8+, no plugin needed.

Official canonical schema

Top-level keys:

filters:      # Global filter applied to all views (expression strings under and/​or/​not)
formulas:     # Named computed properties — referenced as formula.<name>
properties:   # Display config per property — sets displayName for column headers
summaries:    # Aggregation formulas (e.g. mean, sum)
views:        # Array of view definitions (required)

Each item in views::

views:
  - type: table          # table | list | cards | map
    name: "View Name"    # display label
    limit: 50            # optional max rows
    order:               # column display order (list of property/​formula names)
      - file.name
      - note.updated
    groupBy:             # grouping — goes INSIDE the view, NOT at top level
      property: note.tags
      direction: ASC     # ASC | DESC
    filters:             # view-specific filter (merges with global filters)
      and:
        - 'note.status != "done"'
    summaries:
      formula.myFormula: Average

Filter syntax — CRITICAL

Filters use expression strings, not typed objects. Always wrap in and:, or:, or not: — a bare list causes a "may only have one of and/​or/​not keys" parse error.

# CORRECT
filters:
  and:
    - file.inFolder("concepts")

# WRONG — typed objects (parse error)
filters:
  - type: folder
    folder: concepts

Filters support nesting:

filters:
  or:
    - file.hasTag("book")
    - and:
        - file.inFolder("concepts")
        - file.hasTag("research")
    - not:
        - file.hasTag("archived")

Property name conventions

Different contexts use different naming — confirmed from Obsidian's auto-reformat behaviour:

ContextFrontmatter field tagsFile nameFormula
properties: keysnote.tagsfile.nameformula.<name>
order: valuestags (bare)file.nameformula.<name>
groupBy.property:tags (bare)file.name—
filters: expressionsfile.hasTag(...) / note.tagsfile.nameformula.<name>
formulas: expressionsnote.tags, note.updatedfile.name—

Basic table — folder filter

filters:
  and:
    - file.inFolder("concepts")
properties:
  file.name:
    displayName: Page
  note.tags:
    displayName: Tags
  note.summary:
    displayName: Summary
  note.updated:
    displayName: Updated
views:
  - type: table
    name: Table
    order:
      - file.name
      - tags
      - summary
      - updated

Cards view — folder filter

filters:
  and:
    - file.inFolder("entities")
properties:
  file.name:
    displayName: Entity
  note.title:
    displayName: Full Name
  note.tags:
    displayName: Tags
  note.summary:
    displayName: Summary
views:
  - type: cards
    name: Cards
    order:
      - file.name
      - title
      - tags
      - summary

Group by property — groupBy goes INSIDE the view

When groupBy is set, omit that property from order: — it becomes the group header row and adding it as a column too causes duplication.

filters:
  and:
    - file.inFolder("concepts")
properties:
  file.name:
    displayName: Concept
  note.summary:
    displayName: Summary
  note.updated:
    displayName: Updated
views:
  - type: table
    name: By Domain
    groupBy:
      property: tags        # bare property name, no note. prefix
      direction: ASC
    order:
      - file.name           # do NOT include tags here — already the group header
      - summary
      - updated

Tag filter

filters:
  and:
    - file.hasTag("machine-learning")
properties:
  file.name:
    displayName: Page
  note.category:
    displayName: Category
  note.summary:
    displayName: Summary
views:
  - type: table
    name: Table
    order:
      - file.name
      - category
      - summary

Multi-filter (folder AND tag)

filters:
  and:
    - file.inFolder("projects")
    - file.hasTag("active")
properties:
  file.name:
    displayName: Project
  note.summary:
    displayName: Summary
  note.updated:
    displayName: Last Updated
views:
  - type: cards
    name: Cards
    order:
      - file.name
      - summary
      - updated

OR filter (two folders)

filters:
  or:
    - file.inFolder("concepts")
    - file.inFolder("entities")
properties:
  file.name:
    displayName: Page
  note.category:
    displayName: Category
  note.updated:
    displayName: Updated
views:
  - type: table
    name: Table
    order:
      - file.name
      - category
      - updated

Computed column via formulas

filters:
  and:
    - file.inFolder("concepts")
formulas:
  days_stale: "floor((now() - note.updated) / 86400000)"
properties:
  file.name:
    displayName: Page
  note.updated:
    displayName: Updated
  formula.days_stale:
    displayName: Days Stale
views:
  - type: table
    name: Stale
    order:
      - file.name
      - updated
      - formula.days_stale

Filter expression reference

ExpressionWhat it does
file.inFolder("path")Pages in that folder
file.hasTag("tag")Pages with that tag (no # prefix)
file.hasLink("Note Name")Pages linking to a note
file.name == "note-name"Exact filename match
file.ext == "md"Filter by extension
note.propertyNameAny frontmatter property
formula.formulaNameA named formula result
now()Current timestamp in ms

On Obsidian UI-generated format: When Obsidian's GUI writes or reformats a .base file it may output a simplified shorthand with top-level columns:, sort:, and view: keys instead of the canonical schema. That format also works — Obsidian accepts both. Manually authored files should use the canonical schema above.


Option B — Dataview (community plugin)

Dataview uses a SQL-like query language inside ```dataview ``` code blocks in any note. More powerful than Bases for computed columns, GROUP BY, and cross-folder queries.

Basic table — folder

```dataview
TABLE
  tags AS "Tags",
  summary AS "Summary",
  file.mtime AS "Last Modified"
FROM "concepts"
SORT file.mtime DESC
```

Table with clickable links (TABLE WITHOUT ID)

```dataview
TABLE WITHOUT ID
  file.link AS "Entity",
  tags AS "Tags",
  summary AS "Summary"
FROM "entities"
SORT file.name ASC
```

GROUP BY — use rows. prefix after grouping

After GROUP BY, individual file properties must be prefixed with rows. — otherwise the column is empty or errors.

```dataview
TABLE WITHOUT ID
  rows.file.link AS "Concept",
  rows.summary AS "Summary"
FROM "concepts"
GROUP BY tags[0] AS "Domain"
```

Stale pages — use file.mtime for date math

Avoid choice(updated, date(updated), file.mtime) — mixed date formats in updated frontmatter cause arithmetic errors. file.mtime is always a valid DateTime.

```dataview
TABLE WITHOUT ID
  file.link AS "Page",
  category AS "Type",
  file.mtime AS "Last Modified",
  (date(today) - file.mtime).days + " days" AS "Age"
FROM "concepts" OR "entities" OR "projects"
WHERE file.name != file.folder
WHERE (date(today) - file.mtime).days > 30
SORT (date(today) - file.mtime).days DESC
```

Multi-folder query

```dataview
TABLE
  summary AS "Summary",
  file.mtime AS "Last Modified"
FROM "projects"
WHERE file.name != file.folder
SORT file.mtime DESC
```

Dataview reference

ClauseUsage
FROM "folder"All notes in folder
FROM #tagAll notes with tag
FROM "a" OR "b"Union of two folders
WHERE file.name != file.folderExclude folder index pages
GROUP BY field AS "Label"Group rows — use rows. for properties after this
SORT field DESCSort direction
file.linkClickable wikilink
file.mtimeLast modified time (always valid DateTime)
(date(today) - file.mtime).daysDays since last modification

Step 3: Write the File

Bases: Target path $OBSIDIAN_VAULT_PATH/​_meta/<dashboard-name>.base

Dataview: Write queries directly into any .md note. A dedicated dashboard note at $OBSIDIAN_VAULT_PATH/​_meta/​dashboard.md works well for multi-section views.

Slug examples:

  • "All concepts" → _meta/​concepts-index.base
  • "Recent ingests" → _meta/​recent-ingests.base
  • "Project overview" → _meta/​projects-overview.base
  • "Stale pages" → _meta/​stale-pages.base
  • "Full dashboard" → _meta/​dashboard.md

Create _meta/ if it doesn't exist yet.

Step 4: Embed Bases (optional)

To embed a .base inside a note:

## Entities
![[_meta/​entities-tracker.base]]

Ask before modifying an existing note.

Step 5: Update Tracking

Append to $OBSIDIAN_VAULT_PATH/​log.md:

- [TIMESTAMP] WIKI_DASHBOARD name="<slug>" tool=bases|dataview view=<type> filter="<description>"

No manifest or index update needed — dashboards are live queries, not static pages.

Common Dashboard Recipes

DashboardBest toolWhat it shows
Content indexBases or DataviewAll pages grouped by category, sorted by updated
Entity trackerBases (cards)Entity pages as a visual card gallery
Concepts by domainDataviewConcepts grouped by first tag using GROUP BY
Ingestion logEitherPages sorted by created date
Stale contentDataviewPages not touched in 30+ days with day count
Project overviewEitherProject pages with last-sync date
Research trackerDataviewSynthesis pages tagged research

Quality Checklist

  • Bases: filters use expression strings under and:/or:/not:, never typed objects
  • Bases: groupBy goes inside the view definition — not as a top-level key
  • Bases: column headers set via properties: <name>: displayName: "...", not columns: [{title}]
  • Bases: formulas: used for computed columns, referenced as formula.<name> in order/​properties
  • Dataview: GROUP BY queries use rows.property not bare property
  • Dataview: date arithmetic uses file.mtime, not choice(updated, ...)
  • File written to _meta/ with a descriptive slug
  • log.md updated
  • User told how to embed Bases (![[_meta/<name>.base]]) or open the dashboard note

QMD Refresh After Vault Writes

QMD is a search index, not the source of truth. If $QMD_WIKI_COLLECTION is empty or unset, skip this step. Run it only after this skill has written or rewritten vault markdown. If QMD refresh fails, do not roll back the vault changes; report the QMD status separately.

Use $QMD_CLI if set; otherwise use qmd.

${QMD_CLI:-qmd} update

If the output says vectors are needed or embeddings may be stale, run:

${QMD_CLI:-qmd} embed

Verify the collection with either:

${QMD_CLI:-qmd} ls "$QMD_WIKI_COLLECTION"

or, when a specific page path is known:

${QMD_CLI:-qmd} get "qmd://$QMD_WIKI_COLLECTION/<page>.md" -l 5

Record one of:

  • QMD refreshed: update + embed + verified
  • QMD refreshed: update only + verified
  • QMD skipped: QMD_WIKI_COLLECTION unset
  • QMD skipped: qmd CLI unavailable
  • QMD failed: <short error summary>

More skills from gabrielmoreira

workflow-router logo
gabrielmoreira/agent-skills-mirror

workflow-router

研发工作流入口 - 帮助用户快速进入正确的工作流阶段。 触发关键词: 工作流, 流程, 从哪开始, 帮我, 我该怎么做, 下一步, workflow, 不知道用什么, 新手引导, 怎么用

19 0
View
平台架构知识 logo
gabrielmoreira/agent-skills-mirror

平台架构知识

Periodically refreshed mirror of agents, skills, prompts and instruction files from public repositories.

19 0
View
unity-profiler logo
gabrielmoreira/agent-skills-mirror

unity-profiler

Read-only Unity runtime performance snapshots — FPS, frame time, batches/draw calls, triangles/vertices, memory (total/mono/per-asset), object counts, AssetBundle stats. Exact signatures via GET /skills/schema.

19 0
View
ads-audit logo
gabrielmoreira/agent-skills-mirror

ads-audit

Full multi-platform paid advertising audit with parallel subagent delegation. Analyzes Google Ads, Meta Ads, LinkedIn Ads, TikTok Ads, Microsoft Ads, and Apple Ads accounts via 6 parallel audit agents. Amazon Ads, cross-platform attribution, and server-side tracking are covered by their standalon...

19 0
View
unity-skills logo
gabrielmoreira/agent-skills-mirror

unity-skills

Unity Editor automation via REST API — create scripts, analyze scenes, manage assets, control editor, orchestrate workflows, run batch jobs, and route by Unity version. Triggers: Unity, Unity Skills, in Unity, automate Unity, Unity editor automation, create Unity script, scene summary, analyze Un...

19 0
View
purple-cow-audit logo
gabrielmoreira/agent-skills-mirror

purple-cow-audit

Score product remarkability 1-10 to decide if it's worth promoting. Seth Godin's Purple Cow test. Triggers on: "is this product worth promoting", "should I promote", "product audit", "purple cow", "remarkable product", "is it remarkable", "rate this product", "product quality check", "worth my re...

19 0
View
unity-cleaner logo
gabrielmoreira/agent-skills-mirror

unity-cleaner

Project cleanup and audit — find unused assets, content-hash duplicates, missing references, empty folders, large assets, dependency trees; two-step confirm-token delete. Exact signatures via GET /skills/schema.

19 0
View
skill-manager-guide logo
gabrielmoreira/agent-skills-mirror

skill-manager-guide

**GUIDE SKILL** — Guide to the Skill Manager for Copilot extension. USE FOR: adding/removing skill repos, syncing skills, pushing feedback, configuring sync intervals, troubleshooting sync issues, understanding skill format. DO NOT USE FOR: creating new skills (use skill-creator), creating agents...

19 0
View
configure-nightwatch logo
gabrielmoreira/agent-skills-mirror

configure-nightwatch

Configures Laravel Nightwatch data collection, sampling rates, filtering rules, and redaction policies. Use when setting up Nightwatch, managing data volume, protecting sensitive data (PII), or optimizing event collection for production workloads.

19 0
View
research-and-write logo
gabrielmoreira/agent-skills-mirror

research-and-write

End-to-end workflow: research a topic and then write a LinkedIn post about it. Use this skill whenever the user wants the full pipeline — from a topic idea to a finished LinkedIn post. Triggers on: 'research and write a post about', 'create a LinkedIn post about [topic]', 'I want to post about', ...

19 0
View
AI Tutor Persona logo
gabrielmoreira/agent-skills-mirror

AI Tutor Persona

Periodically refreshed mirror of agents, skills, prompts and instruction files from public repositories.

19 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View