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
7 changes: 7 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@ in the plugin repo, checked out alongside this one at `../smart-second-brain`:
| Providers | `src/providers/index.ts` → `PROVIDER_TEMPLATES` |
| Built-in tools | `src/types/plugin.ts` → `BUILT_IN_TOOL_IDS` |
| Bundled core skills | `src/skills/defaults/*/SKILL.md` |
| Widgets (fence, `.widget` files, header keys, libraries, sandbox) | `src/widget/` (`widgetSpec.ts`, `widgetFrame.ts`, `widgetLibs.ts`, `registerWidgetBlocks.ts`), `src/views/widget/` |
| Integration skills | `src/skills/integrations/*/SKILL.md`, and `CURATED_PLUGIN_INTEGRATIONS` in `src/agent/integrations/pluginIntegrations.ts` |
| Skill/memory folder paths | `src/utils/agentPaths.ts` |
| Command names | `src/main.ts` → `addCommand` calls |
Expand Down Expand Up @@ -804,6 +805,12 @@ hand before each release. Work through this list against the sources above:

- [ ] `start/providers` — provider table matches `PROVIDER_TEMPLATES`
- [ ] `agents/skills` — bundled core skills match `src/skills/defaults/`
- [ ] `agents/widgets` — header keys match `WidgetSpec` in
`src/widget/widgetSpec.ts`, `libs` matches `WIDGET_LIBS` in
`src/widget/widgetLibs.ts` (and the trace types the Plotly build carries),
the chat toolbar labels match `registerWidgetBlocks.ts`, the tab actions
match `views/widget/WidgetView.ts`, and the default icon matches
`DEFAULT_WIDGET_ICON`
- [ ] `agents/integrations` — curated list matches
`CURATED_PLUGIN_INTEGRATIONS`; the seeded-at-startup core-plugin
integrations are the entries in `src/skills/integrations/` whose
Expand Down
1 change: 1 addition & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export default defineConfig({
items: [
{ label: 'Overview', slug: 'agents' },
{ label: 'Skills', slug: 'agents/skills' },
{ label: 'Widgets', slug: 'agents/widgets' },
{ label: 'Integrations', slug: 'agents/integrations' },
{ label: 'Memory', slug: 'agents/memory' },
{ label: 'MCP servers', slug: 'agents/mcp' },
Expand Down
6 changes: 4 additions & 2 deletions src/content/docs/agents/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ What an agent *has* is covered on its own page: the
[skills](/agents/skills/) that give it tools, the
[integrations](/agents/integrations/) that let it script other plugins, its
[memory](/agents/memory/), and any [MCP servers](/agents/mcp/) it connects to.
What it can *build* for you — dashboards, charts and plots from your notes —
is on the [Widgets](/agents/widgets/) page.

## Conversations are notes

Expand Down Expand Up @@ -68,12 +70,12 @@ on its enabled skills. See [Skills](/agents/skills/).
| --- | --- |
| `search_notes` | Search the vault (lexical, semantic, or hybrid) |
| `list_directory` | List folders and files |
| `read_content` | Read a note's content |
| `read_content` | Read a note (or a `.widget` file) |
| `grep_notes` | Find an exact substring or regex across notes |
| `get_all_tags` | List every tag in the vault |
| `get_properties` | Read frontmatter properties, or list all property keys |
| `execute_javascript` | Run JavaScript against the vault |
| `manage_notes` | Create, update, delete, and move notes (**staged for review**) |
| `manage_notes` | Create, update, delete, and move notes and `.widget` files (**staged for review**) |
| `fetch_url` | Fetch a public web page as markdown |
| `web_search` | Search the web |
| `manage_skills` | Create, revise, or delete skills |
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/agents/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Integrations
description: Let an agent script other Obsidian plugins through their public APIs.
sidebar:
order: 3
order: 4
---

An integration lets an agent call another Obsidian plugin's public API. Ask for
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/agents/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: MCP servers
description: Connect external tools and data sources via MCP.
sidebar:
order: 5
order: 6
---

[MCP](https://modelcontextprotocol.io/), the Model Context Protocol, is an
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/agents/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Memory
description: Working memory stored as real notes in your vault.
sidebar:
order: 4
order: 5
---

Memory lets an agent remember things between conversations: that you prefer
Expand Down
3 changes: 2 additions & 1 deletion src/content/docs/agents/skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ allowed-tools: manage_notes

## Bundled core skills

Four ship with the plugin and are seeded into your vault on first run:
Five ship with the plugin and are seeded into your vault on first run:

| Skill | Attaches | Covers |
| --- | --- | --- |
| `explore-vault` | `search_notes`, `list_directory`, `read_content`, `grep_notes`, `get_all_tags`, `get_properties`, `execute_javascript` | Finding and reading notes: verify tags and properties before querying, and what to do when a search comes back weak |
| `manage-notes` | `manage_notes` | Creating, editing, deleting and moving notes: the staging policy, and how to replace or withdraw an edit it has already staged |
| `web` | `fetch_url`, `web_search` | Reaching the public internet, vault-first |
| `manage-skills` | `manage_skills` | Authoring and revising skills |
| `widgets` | *(no tools)* | Building [widgets](/agents/widgets/): the block format, the data bridge, and the sandbox rules. Pure guidance, so it is never hidden by a tool override |

Older vaults had `manage-notes` under the name `edit-notes` and `manage-skills`
under `update-skills`. The plugin renames the folders on update and keeps your
Expand Down
128 changes: 128 additions & 0 deletions src/content/docs/agents/widgets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
title: Widgets
description: "Interactive dashboards, charts and plots the agent builds from your vault, kept as files you can embed anywhere."
sidebar:
order: 3
---

Ask the agent for a dashboard of your open tasks, a heatmap of when you edit
notes, or a 3D plot of a function you are studying, and it answers with a
**widget**: a small interactive page, rendered right there in the chat, built
from live data in your vault. Keep the ones you like as `.widget` files. They
open in their own tab, embed in any note, and stay up to date as the vault
changes.

Widgets need the [`widgets` skill](/agents/skills/), which ships with the plugin
and is on by default. Live data needs the
[Dataview](https://github.com/blacksmithgu/obsidian-dataview) plugin; without it
a widget can still show data the agent gathered, it just won't refresh itself.

## In the chat

A widget renders as a card in the reply, with a small toolbar above it:

- **Expand** opens it almost full-window for a closer look.
- **Copy as block** puts the widget on the clipboard as a code block you can
paste into any note, where it renders the same way.
- **Save as a widget file** writes it to your **Widgets folder** (Settings →
Agents → Widgets, default `Widgets/`) and opens it.

A widget starts rendering the moment its block is complete, while the rest of
the reply is still streaming.

## Widget files

A saved widget is a `.widget` file. It behaves like any file in the vault:

- **Its own tab.** Open it from the file explorer or the quick switcher and it
fills the pane. The tab's context menu adds **Edit source** (a plain-text
editor for the file, since Obsidian has none for the extension) and
**Rename…** next to the usual file actions.
- **Embeddable.** `![[Vault overview.widget]]` renders it inside a note at its
own height. Hovering a link to it shows the same preview as any page preview.
- **Live.** Edit the file, or accept an agent's edit to it, and every open tab
and embed re-renders.

The agent can revise a saved widget the same way it edits notes: it reads the
file and stages the change, and you review it as the **rendered widget** before
anything is written. The chat's pending-changes bar previews the proposal in
place (with the source diff a click away), and the widget's own pane shows the
proposed version under an accept/reject bar, with a toggle back to the current
one.

:::note
Obsidian Sync carries `.widget` files only if **Sync all other types** is on
in its settings. Links written *inside* a widget open and preview normally but
don't count as backlinks, since Obsidian's link index reads markdown only.
:::

## What is in a widget

A widget is an HTML page with a short header:

````markdown
```s2b-widget
---
title: Notes per tag
description: The fifteen most-used tags, as a bar chart
icon: tags
queries:
tags: TABLE length(rows) AS n FROM "" FLATTEN file.tags AS tag GROUP BY tag
---
<div id="chart"></div>
<script>
s2b.onData(({ tags }) => { /* draw from tags.rows */ });
</script>
```
````

The header keys, all optional:

| Key | What it does |
| --- | --- |
| `title` | Shown on the card and the tab; the file name when saved |
| `description` | One line on what the widget shows. With the title, the only part of a saved widget that search indexes |
| `icon` | Any [Lucide](https://lucide.dev/icons/) icon name for the tab and card; the default is `component` |
| `height` | A fixed height in pixels. Without it the widget sizes to its content; with it, it still shrinks when the content is shorter |
| `queries` | Named [Dataview](https://blacksmithgu.github.io/obsidian-dataview/queries/structure/) queries. The plugin runs them, hands the results to the widget, and runs them again whenever the vault changes |
| `libs` | Bundled libraries to load. Currently `plotly`, for 2D and 3D plots |

The `.widget` file is exactly this, without the fence lines. You never need to
write one by hand, but you can, and the source editor shows the header keys as
a reminder.

### Links to notes

Anything in a widget marked with `data-note="Path/To/Note.md"` (or a plain link
whose target is a vault path) is a note link: click opens the note, Cmd/Ctrl-click
opens it in a new tab, and hovering shows a page preview. Page preview lists
widgets as their own source, **S2B Widgets**, so you can decide there whether the
preview needs a modifier key, as for any other source.

### Plots

With `libs: plotly` a widget gets [Plotly](https://plotly.com/javascript/) for
line, scatter, bar and pie charts, and for 3D surfaces, scatter and meshes with
orbit and zoom. The build is bundled with the plugin, so plots work offline like
everything else. Without a library, a widget can still draw with SVG or a
canvas.

## Widgets are sandboxed

A widget is code the agent wrote, so it runs in a box:

- It renders in an isolated frame with **no access to Obsidian, your vault, or
the network**. It cannot fetch, load remote scripts, or navigate anywhere.
- The **plugin** runs the widget's queries and passes the results in. The
widget sees only what its own queries return.
- Libraries are bundled with the plugin, never downloaded.

Treat a widget like anything else the agent produces: it can only act on data
you let the agent read.

## Widgets and search

A saved widget is indexed by its **title and description only**, so you and
the agent can find "the tags overview" without its code ever showing up as a
search result. A widget pasted into a note as a block is likewise reduced to a
marker with its title before that note is indexed.
Loading