# https://github.com/siyuan-note/siyuan Project Manual

Generated at: 2026-06-22 12:07:39 UTC

## Table of Contents

- [System Architecture and Workspace Model](#page-1)
- [Block Editor (Protyle) and Card Whiteboard (Maze)](#page-2)
- [Attribute View (Database) — Table, Kanban, and Gallery](#page-3)
- [Backend Kernel, Persistence, PDF Annotations, and AI](#page-4)

<a id='page-1'></a>

## System Architecture and Workspace Model

### Related Pages

Related topics: [Block Editor (Protyle) and Card Whiteboard (Maze)](#page-2), [Attribute View (Database) — Table, Kanban, and Gallery](#page-3), [Backend Kernel, Persistence, PDF Annotations, and AI](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/siyuan-note/siyuan/blob/main/README.md)
- [kernel/server/serve.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/server/serve.go)
- [kernel/api/setting.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/setting.go)
- [kernel/api/history.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/history.go)
- [kernel/api/filetree.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/filetree.go)
- [kernel/api/export.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/export.go)
- [kernel/api/snippet.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/snippet.go)
- [kernel/api/sync.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/sync.go)
- [kernel/api/icon.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/icon.go)
</details>

# System Architecture and Workspace Model

SiYuan is a privacy-first personal knowledge management system built around block-level references and Markdown WYSIWYG editing. Its architecture deliberately separates the desktop shell, the Go-based kernel, and the Lute editing engine so that the same kernel can run on desktop, mobile, and server deployments. The workspace model that sits beneath these layers governs how user data, settings, plugins, and synchronised cloud state are stored on disk.

## High-Level Architecture

SiYuan is organised as a three-tier system. The top tier is the cross-platform desktop shell (Electron on desktop, native shells on Android/iOS/HarmonyOS) which renders the editor UI and hosts the web assets. The middle tier is the Go kernel that exposes an HTTP/WebSocket API through Gin. The bottom tier is the [lute](https://github.com/88250/lute) editor engine, which parses and serialises Markdown and AST nodes.

```mermaid
flowchart TB
    UI["Desktop / Mobile UI<br/>(Electron, Android, iOS)"]
    Kernel["Go Kernel<br/>(kernel/server, kernel/api)"]
    Engine["Lute Editor Engine<br/>(github.com/88250/lute)"]
    WS["Workspace on Disk<br/>(data/, conf/, storage/)"]
    Sync["Sync Layer<br/>(dejavu / WebDAV / S3)"]
    Plugins["Plugins & Snippets<br/>(petal API)"]

    UI <-->|"HTTP / WebSocket"| Kernel
    Kernel --> Engine
    Kernel <--> WS
    Kernel <--> Sync
    UI --> Plugins
    Kernel --> Plugins
```

The architecture image linked from the README, `SiYuan_Arch-Sgu8vXT.png`, captures the same split: a UI tier for editing, a kernel tier for business logic and persistence, and a storage tier for the data repository and configuration.

## Workspace and Data Repository Model

The workspace is the on-disk root that SiYuan reads on startup. According to the README, the workspace contains several well-known subdirectories:

| Directory      | Purpose                                                                  |
|----------------|--------------------------------------------------------------------------|
| `data/`        | Notebook folders, each holding `.sy` JSON document files                |
| `conf/`        | Global configuration (appearance, editor, export, sync, etc.)            |
| `assets/`      | Files inserted into documents (images, audio, PDFs)                      |
| `emojis/`      | Emoji image assets                                                        |
| `snippets/`    | JavaScript and CSS code snippets                                          |
| `storage/`     | Query conditions, layouts, flashcard state                                |
| `templates/`   | Template snippets                                                         |
| `widgets/`     | Dashboard widgets                                                          |
| `plugins/`     | Installed community plugins                                               |
| `public/`      | Public data folder                                                         |

Notebook folders inside `data/` store documents as `.sy` files whose content is a JSON document. Document data and metadata are kept in sync with the kernel's block tree, and the data repository is protected by a per-workspace key that can be copied across devices via *Settings - About - Data repo key*.

The data repository itself is implemented by the separate [dejavu](https://github.com/siyuan-note/dejavu) project. It is responsible for snapshotting the workspace, computing diffs, and uploading them to the configured sync provider. The README explicitly warns that third-party sync disks must not be used because they can corrupt the repository; instead, SiYuan supports connecting to third-party cloud storage as a paid feature and offers manual export/import of the `data/` folder as a fallback.

## Server and API Layer

The kernel's HTTP entry point is `kernel/server/serve.go`. It wires Gin together with `gin-contrib/sessions` (cookie-based session store), `olahol/melody` for WebSocket support, `soheilhy/cmux` for protocol multiplexing, and `golang.org/x/net/webdav` for WebDAV handling. The file declares the HTTP and WebDAV/CalDAV method tables and exposes helpers for serving static assets, the upload endpoint, and the auth page.

Source: [kernel/server/serve.go:1-19]()

API handlers live under `kernel/api/` and are grouped by feature domain. Each handler follows the same idiom: read a JSON argument via `util.JsonArg`, validate fields with `util.ParseJsonArgs` / `util.BindJsonArg`, mutate the in-memory `model.Conf` or call a `model` function, persist with `model.Conf.Save()`, and return a `gulu.Ret` result. Representative examples include:

- `kernel/api/setting.go` exposes `setEditorReadOnly`, `setExport`, `setFiletree`, and other mutation endpoints. They broadcast changes through `util.BroadcastByType("protyle", ...)` so every open UI tab picks up the new state.
- `kernel/api/filetree.go` handles `CreateWithMarkdown` and `getDocCreateSavePath`, resolving the configured save target against the per-notebook `DocCreateSaveBox` / `DocCreateSavePath` template.
- `kernel/api/history.go` covers `GetNotebookHistory`, `clearWorkspaceHistory`, and `getDocHistoryContent`, providing the document history viewer.
- `kernel/api/export.go` implements exports to Markdown, PDF, Word, and HTML, including Pandoc integration validated by `util.IsValidPandocBin`.
- `kernel/api/snippet.go` lists and toggles JS/CSS snippets; the `type` parameter accepts `js`, `css`, or `all`, and an `enabled` flag of `0/1/2` filters by state.
- `kernel/api/sync.go` bridges to `dejavu/cloud` for WebDAV, S3, and other sync providers via `importSyncProviderWebDAV` and related handlers.
- `kernel/api/icon.go` dynamically generates SVG notebook icons (date types 0–5 with multiple colour schemes) used in the file tree.

## Data Flow and Request Lifecycle

A typical write request flows from the UI to disk as follows. The frontend issues a POST against an endpoint under `/api/...`. The Gin router dispatches to the matching handler in `kernel/api/`, which validates the JSON payload, calls into the `model` package to perform the mutation, and, when persistent state has changed, saves the configuration with `model.Conf.Save()`. For operations that affect open documents, the handler calls `util.BroadcastByType("protyle", ...)` or `util.BroadcastByType("main", ...)` so connected WebSocket clients refresh their state. Finally, the handler serialises a `gulu.Ret` response.

Source: [kernel/api/setting.go:13-37](), [kernel/api/filetree.go:18-30]()

Community-driven features that ride on this architecture include the upcoming Card Whiteboard (issue #2024), which proposes converting any block into a card and managing associations; the multi-view Database (issues #2829, #8873, #10414) layered on top of the block tree; and PDF annotation two-way links (issue #2828), which added `/api/block/getRefIDsByFileAnnotationID` and a new `file_annotation_refs` table. All of these features depend on the same workspace layout and HTTP request flow described above, which is why the workspace model is foundational to SiYuan's evolution.

## See Also

- [Editor Engine and Block Model](./editor-engine-and-block-model.md)
- [Data Synchronisation and Cloud Storage](./data-synchronisation-and-cloud-storage.md)
- [Plugin and Snippet API](./plugin-and-snippet-api.md)

---

<a id='page-2'></a>

## Block Editor (Protyle) and Card Whiteboard (Maze)

### Related Pages

Related topics: [System Architecture and Workspace Model](#page-1), [Attribute View (Database) — Table, Kanban, and Gallery](#page-3), [Backend Kernel, Persistence, PDF Annotations, and AI](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md)
- [kernel/server/serve.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/server/serve.go)
- [kernel/api/block.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/block.go)
- [kernel/api/block_op.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/block_op.go)
- [kernel/api/ref.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/ref.go)
- [kernel/api/search.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/search.go)
- [kernel/api/notebook.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/notebook.go)
- [kernel/api/riff.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/riff.go)
- [kernel/api/setting.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/setting.go)
- [kernel/api/icon.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/icon.go)

Community references:

- Issue [#2024 "Card Whiteboard (Maze)"](https://github.com/siyuan-note/siyuan/issues/2024)
- Issue [#2829 "Database table view"](https://github.com/siyuan-note/siyuan/issues/2829)
- Issue [#2828 "PDF 标注双链" (PDF annotation double links)](https://github.com/siyuan-note/siyuan/issues/2828)
</details>

# Block Editor (Protyle) and Card Whiteboard (Maze)

## Overview

SiYuan's authoring surface is built around two complementary concepts: the **Protyle block editor** for linear document authoring and the planned **Maze (Card Whiteboard)** for spatial, card-based thinking. Both sit on top of a unified, fine-grained block data model stored as JSON inside `.sy` files under `workspace/data/<notebook>/` (Source: [README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md)). The editor is described in the project README as a "block-level reference and Markdown WYSIWYG" system with custom attributes, SQL query embedding, and a `siyuan://` URL scheme (Source: [README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md)).

The Protyle/Maze split reflects a long-running community demand: the most engaged issue on the repository, [#2024 "Card Whiteboard (Maze)"](https://github.com/siyuan-note/siyuan/issues/2024) (144 comments), explicitly proposes treating the workspace as a "maze in a digital garden" with free-floating cards, card↔block conversions, metadata associations, a right-side detail panel, search, zoom, and hierarchical focus. Related database-view work in [#2829](https://github.com/siyuan-note/siyuan/issues/2829), [#8873 "Database kanban view"](https://github.com/siyuan-note/siyuan/issues/8873), and [#10414 "Database gallery view"](https://github.com/siyuan-note/siyuan/issues/10414) shares the same block-backed data substrate and informs how Maze cards would relate to documents.

## Protyle Block Editor Architecture

### Block-Style Authoring and the Data Model

Every paragraph, list item, heading, code block, or asset in SiYuan is an addressable block with a stable ID. Custom attributes can be attached to any block, and the editor exposes SQL queries and the `siyuan://` deep-link protocol as first-class editing affordances (Source: [README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md)). The editor is designed to handle million-word documents and supports block zoom-in, list outline navigation, and inline math/diagram rendering (Source: [README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md)).

The kernel exposes the block data through a small set of HTTP/JSON endpoints mounted on the Gin server. `getBlockKramdowns` returns Markdown or `textmark` (inline span-tag) representations of a set of block IDs and respects publish-access filtering when the request is in a read-only role context (Source: [kernel/api/block.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/block.go)). The `mode` argument can be `md` or `textmark`; other values are rejected with an error code (Source: [kernel/api/block.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/block.go)).

### Transactional Block Operations

All editor mutations are routed through a transaction queue. `appendDailyNoteBlock` and `prependDailyNoteBlock` show the canonical pattern: a Lute engine parses incoming Markdown into a block DOM, a parent block is created or resolved for today's daily note, and a `[]*model.Transaction` with a single `appendInsert` operation is enqueued via `model.PerformTransactions` followed by `model.FlushTxQueue`. The transaction is then broadcast to subscribed clients and echoed back as the response payload (Source: [kernel/api/block_op.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/block_op.go)). This same primitive is what the Protyle WYSIWYG surface and the planned Maze card editor will use to keep the block graph consistent.

```mermaid
flowchart LR
    UI[Protyle WYSIWYG / Maze Canvas] -->|edit intent| API[Kernel API handler]
    API -->|Lute parse| DOM[Block DOM]
    DOM -->|Operation| TX[model.PerformTransactions]
    TX --> Q[FlushTxQueue]
    Q --> Store[(.sy JSON in workspace/data)]
    Q -->|broadcast| WS[WebSocket subscribers]
    WS --> UI
```

### References, Backlinks, and Search

Two-way linking is a foundational editor feature. `getBacklinkDoc` resolves a `defID` (definition block) and `refTreeID` (root containing the references) and returns both the inbound links and a highlighted keyword match list; the `containChildren` flag defaults to `model.Conf.Editor.BacklinkContainChildren` and can be overridden per request (Source: [kernel/api/ref.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/ref.go)). The companion `getBacklink2` adds a separate `mentionKeyword`/`mentionSort` channel for `@mention`-style backlinks, again with paged results (Source: [kernel/api/ref.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/ref.go)). This reference graph is the same one that Maze is expected to leverage for card-to-card association and the "right-sidebar detail" view called out in issue #2024.

Search is paginated: `ListInvalidBlockRefs` returns blocks, `matchedBlockCount`, `matchedRootCount`, and `pageCount`, with `page` and `pageSize` parameters that default to `1` and `32` respectively (Source: [kernel/api/search.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/search.go)). The same publish-access filter used for block export is applied here for read-only role contexts, ensuring that Maze's "search across the canvas" cannot leak content that would be hidden in published views (Source: [kernel/api/search.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/search.go)).

## Card Whiteboard (Maze)

The Maze feature is defined entirely in community issue [#2024](https://github.com/siyuan-note/siyuan/issues/2024) and is not yet present in the kernel sources reviewed here. The agreed scope, as tracked in that issue, covers:

- A free-form canvas that can be created from the editor
- Card objects that can be created on the canvas
- A bidirectional conversion between cards and document blocks ("卡片转换文档块" and "任意类型块转换卡片")
- First-class card associations with associated metadata
- A right-side detail panel for the focused card
- Canvas-wide search
- Pan/zoom controls
- Hierarchical focus ("层级聚焦") that narrows the visible neighborhood

Because the underlying editor already stores every card candidate as a block with custom attributes and exposes backlinks, transactions, and paginated search through the kernel, Maze is positioned to consume the same APIs as the WYSIWYG editor rather than introducing a parallel data model. The data-repo key handling described in the README — initialized once and shared across devices via `Settings - About - Data repo key` — is the constraint that any canvas-level persistence must respect (Source: [README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md)). Users should expect the Maze storage to live inside the existing `workspace/data/` tree under the same per-notebook `.sy` JSON convention rather than a separate database, and to participate in the same flush-and-broadcast transaction loop shown in `appendDailyNoteBlock` (Source: [kernel/api/block_op.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/block_op.go)).

## Server, Transport, and Plugin Surface

The kernel is a single Go binary that hosts a Gin HTTP server, an embedded WebDAV endpoint, CalDAV support, and a `melody`-based WebSocket hub for live editor updates (Source: [kernel/server/serve.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/server/serve.go)). `cmux` is used to multiplex HTTP, WebDAV, and WebSocket traffic on the same listener, and cookie-backed sessions back authentication for both the editor and any future Maze UI. The WebDAV surface accepts the full method set — `MKCOL`, `COPY`, `MOVE`, `LOCK`, `UNLOCK`, `PROPFIND`, `PROPPATCH` — which is what allows third-party DAV clients and the mobile apps to mount the same `workspace/data/` tree that the Protyle editor and Maze whiteboard will read from (Source: [kernel/server/serve.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/server/serve.go)).

| API family | File | Role for Protyle / Maze |
|---|---|---|
| `kernel/api/block.go` | Block retrieval and Kramdown export | Source of truth for editor rendering and Maze card content |
| `kernel/api/block_op.go` | Transactional block mutations | All editor and canvas edits, including daily-note appends |
| `kernel/api/ref.go` | Backlinks and mentions | Powers two-way links and Maze card associations |
| `kernel/api/search.go` | Paged search and invalid-ref listing | Powers editor quick-find and Maze canvas search |
| `kernel/api/notebook.go` | Notebook listing with publish filtering | Notebook switcher; Maze workspaces are notebook-scoped |
| `kernel/api/riff.go` | Flashcard deck and review | Spaced-repetition recall layer that may attach to Maze cards |
| `kernel/api/setting.go` | Editor and export settings | Read-only mode flag, markdown settings, Pandoc path |
| `kernel/api/icon.go` | Dynamic SVG icon generation | Per-notebook/date icons used by the editor's dock |

Read-only mode, markdown settings, and the Pandoc export binary are all read out of `model.Conf.Editor` and `model.Conf.Export` and broadcast to the `protyle` and `main` channels on change (Source: [kernel/api/setting.go](https://github.com/siyuan-note/siyuan/blob/master/kernel/api/setting.go)), so a future Maze canvas can be toggled between editable and read-only through the same global setting that gates the block editor.

## See Also

- [Database Table / Kanban / Gallery Views](#) — related block-backed view work tracked in issues #2829, #8873, and #10414
- [PDF Annotation Double Links](#) — issue #2828, the reference-graph feature that Maze card associations mirror
- [Spaced Repetition (Riff)](#) — flashcard APIs in `kernel/api/riff.go` that may attach to Maze cards
- [Server and WebDAV Surface](#) — transport layer in `kernel/server/serve.go`
- [Configuration and Settings](#) — `kernel/api/setting.go` for editor, export, and read-only mode

---

<a id='page-3'></a>

## Attribute View (Database) — Table, Kanban, and Gallery

### Related Pages

Related topics: [System Architecture and Workspace Model](#page-1), [Block Editor (Protyle) and Card Whiteboard (Maze)](#page-2), [Backend Kernel, Persistence, PDF Annotations, and AI](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md)
- [kernel/api/av.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/av.go)
- [kernel/api/setting.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/setting.go)
- [kernel/api/filetree.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/filetree.go)
- [kernel/api/notebook.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/notebook.go)
- [kernel/api/ref.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/ref.go)
- [kernel/api/format.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/format.go)
- [kernel/api/export.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/export.go)
- [kernel/api/snippet.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/snippet.go)
- [kernel/api/sync.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/sync.go)
- [kernel/server/serve.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/server/serve.go)
- [kernel/api/icon.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/icon.go)
</details>

# Attribute View (Database) — Table, Kanban, and Gallery

## Overview

The Attribute View (AV) subsystem is SiYuan's relational-database layer built on top of the block tree. It converts arbitrary blocks, documents, or external resources into structured rows that can be browsed, queried, and edited through three interchangeable view layouts: **Table**, **Kanban**, and **Gallery**. The Table view is shipped as a first-class feature ([README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md)), while the Kanban ([#8873](https://github.com/siyuan-note/siyuan/issues/8873)) and Gallery ([#10414](https://github.com/siyuan-note/siyuan/issues/10414)) layouts are tracked as follow-on work gated by the underlying grouping primitive ([#10964](https://github.com/siyuan-note/siyuan/issues/10964)).

The master tracking umbrella is issue [#2829 "Database table view"](https://github.com/siyuan-note/siyuan/issues/2829), which lists the subtasks that fed the initial release (issues `7552`, `7536`, `8663`, `8693`, …).

## High-Level Architecture

An Attribute View is itself a block in the document tree; its persistence, search, and reference semantics therefore piggy-back on the existing block infrastructure. The HTTP layer exposes a single rendering endpoint that hydrates any registered view layout on demand.

```mermaid
flowchart LR
    Client["Browser / Desktop UI"] -->|"POST /api/av/renderAttributeView"| Gin["gin router"]
    Gin --> AV["av.go: renderAttributeView"]
    AV --> Layout["view.GetType()"]
    Layout --> Table["layout_table"]
    Layout --> Kanban["layout_kanban"]
    Layout --> Gallery["layout_gallery"]
    AV -->|"views, page, query"| JSON["JSON response"]
    JSON --> Client
```

The handler returns a payload that fans out to every view registered against the attribute view, so the UI can switch between layouts without re-querying the dataset. Source: [kernel/api/av.go:115-170](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/av.go).

## View Layouts

### Table View

The Table layout is the canonical "spreadsheet over blocks" representation. Each row binds to a block ID, and each column is a key, a value type, and a display formatter. Custom attributes attached to blocks ([README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md)) flow into the column definitions automatically. Table view is the default view type returned by the kernel and was the first layout to ship under issue [#2829](https://github.com/siyuan-note/siyuan/issues/2829).

### Kanban View

The Kanban layout groups rows by a chosen single-select or status-like column. Per the discussion in [#8873](https://github.com/siyuan-note/siyuan/issues/8873), this view depends on the generic grouping primitive tracked in [#10964](https://github.com/siyuan-note/siyuan/issues/10964); once grouping is available, Kanban re-uses the Table dataset and re-projects it as swimlanes. Source: [kernel/api/av.go:115-170](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/av.go) (the `groupPaging` argument reserved for per-group pagination).

### Gallery View

The Gallery layout surfaces a card-style thumbnail grid suited to bookmarks, videos, and image-heavy collections ([#10414](https://github.com/siyuan-note/siyuan/issues/10414)). It re-uses the same row model as Table but swaps the cell renderer for a cover-image-first template, and relies on the asset-resolution helpers in `format.go` ([kernel/api/format.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/format.go)).

## `renderAttributeView` Request Contract

The render endpoint accepts a JSON argument with the following semantics. Source: [kernel/api/av.go:115-170](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/av.go).

| Field | Type | Default | Purpose |
|-------|------|---------|---------|
| `id` | string | required | Attribute view ID |
| `blockID` | string | optional | Bind view to a specific host block |
| `viewID` | string | optional | Render a specific view only |
| `page` | number | `1` | Page index for paginated rendering |
| `pageSize` | number | `-1` | Rows per page; `-1` means no pagination |
| `query` | string | `""` | Free-text filter applied before layout projection |
| `groupPaging` | object | `{}` | Per-group page cursor, consumed by Kanban |

The response shape returned to the client mirrors the arguments:

```json
{
  "name": "My collection",
  "id": "20240101-...",
  "viewType": "table",
  "viewID": "...",
  "views": [ /* sibling views */ ],
  "view": { "LayoutType": "table", "PageSize": 50 },
  "isMirror": false
}
```

The `isMirror` flag signals that the requested view is a reference into another attribute view, a mechanism that lets multiple documents share a single dataset without duplicating rows. Source: [kernel/api/av.go:115-170](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/av.go).

## Integration with the Rest of the Kernel

The Attribute View is not a separate storage tier — every row is a block, every column is a key/value attribute, and every cross-row link is a normal block reference. Consequently, several adjacent subsystems plug in transparently:

- **Block reference** — backlinks surfaced by `getBacklinkDoc` and `getBacklink2` honour AV rows ([kernel/api/ref.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/ref.go)).
- **Export** — Table rows are exported via the generic block-export pipeline ([kernel/api/export.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/export.go)).
- **Asset handling** — `NetAssets2LocalAssets` rewrites remote cover images for the Gallery layout ([kernel/api/format.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/format.go)).
- **Configuration** — read-only mode is broadcast through `setEditorReadOnly`, so AV edits respect the global toggle ([kernel/api/setting.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/setting.go)).
- **Persistence / Sync** — AV data lives in the data repo and is replicated via the Dejavu engine exposed by [kernel/api/sync.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/sync.go).

## Configuration Notes and Caveats

- The Table view is a free feature; Kanban and Gallery require paid membership as documented in the pricing notes linked from the README.
- `pageSize = -1` must be passed explicitly when full-dataset rendering is needed, otherwise pagination silently caps rows. Source: [kernel/api/av.go:115-170](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/av.go).
- Read-only mode (`setEditorReadOnly`) blocks writeback from any layout, so Kanban drag-and-drop will be no-ops until the mode is lifted. Source: [kernel/api/setting.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/setting.go).
- Third-party sync disks are explicitly unsupported (README FAQ) — AV datasets must be replicated through the built-in sync or manual data export.

## See Also

- [README.md](https://github.com/siyuan-note/siyuan/blob/master/README.md) — feature overview and deployment FAQ
- [API.md](https://github.com/siyuan-note/siyuan/blob/master/API.md) — full HTTP API reference, including `renderAttributeView`
- [CHANGELOG.md](https://github.com/siyuan-note/siyuan/blob/master/CHANGELOG.md) — per-release notes on Table/Kanban/Gallery milestones
- Community trackers: [#2829](https://github.com/siyuan-note/siyuan/issues/2829) (Table), [#8873](https://github.com/siyuan-note/siyuan/issues/8873) (Kanban), [#10414](https://github.com/siyuan-note/siyuan/issues/10414) (Gallery), [#10964](https://github.com/siyuan-note/siyuan/issues/10964) (grouping prerequisite)

---

<a id='page-4'></a>

## Backend Kernel, Persistence, PDF Annotations, and AI

### Related Pages

Related topics: [System Architecture and Workspace Model](#page-1), [Block Editor (Protyle) and Card Whiteboard (Maze)](#page-2), [Attribute View (Database) — Table, Kanban, and Gallery](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/siyuan-note/siyuan/blob/main/README.md)
- [kernel/server/serve.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/server/serve.go)
- [kernel/api/router.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/router.go)
- [kernel/api/ai.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/ai.go)
- [kernel/api/export.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/export.go)
- [kernel/api/import.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/import.go)
- [kernel/api/sync.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/sync.go)
- [kernel/api/riff.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/riff.go)
- [kernel/api/lute.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/lute.go)
- [kernel/api/setting.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/setting.go)
- [kernel/api/graph.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/graph.go)
- [kernel/api/icon.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/icon.go)
- [kernel/api/snippet.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/snippet.go)
- [kernel/api/format.go](https://github.com/siyuan-note/siyuan/blob/main/kernel/api/format.go)
</details>

# Backend Kernel, Persistence, PDF Annotations, and AI

SiYuan is a privacy-first personal knowledge management system built around fine-grained block-level references and Markdown WYSIWYG editing. The backend kernel is implemented in Go and exposes a unified HTTP/WebDAV/WebSocket surface that powers the web UI, desktop wrapper, and mobile clients, while remaining fully open source under AGPLv3 [Source: [README.md:1-40]()]. This page documents the four pillars most relevant to integrators and power users: the kernel architecture, the persistence model, PDF annotation linking, and the AI integration.

## Kernel Architecture and HTTP Surface

The kernel binary bootstraps a single Gin HTTP server that multiplexes REST, WebDAV, CalDAV, and a Melody WebSocket channel. WebDAV support is explicit at the method level (`MKCOL`, `COPY`, `MOVE`, `LOCK`, `UNLOCK`, `PROPFIND`, `PROPPATCH`) so external clients can mount the workspace as a filesystem [Source: [kernel/server/serve.go:1-60]()]. Session state is persisted through `gin-contrib/sessions/cookie`, and request auditing is enriched with the `mssola/useragent` package for mobile/desktop differentiation. The protocol `cmux` is used for connection multiplexing alongside Melody for real-time push events.

API handlers are organized by domain under `kernel/api/`, each file owning a coherent set of endpoints:

| Domain File | Responsibility |
|-------------|----------------|
| `ai.go` | OpenAI-compatible chat and action calls |
| `export.go` | PDF/Word/HTML/Markdown export pipeline |
| `import.go` | `.sy.zip` package import |
| `sync.go` | WebDAV cloud sync import |
| `riff.go` | Spaced-repetition flashcard CRUD |
| `lute.go` | Lute engine helpers (spin, render, copy) |
| `setting.go` | Editor and global configuration |
| `graph.go` | Global/local graph view configuration |
| `snippet.go` | JS/CSS snippet management |
| `icon.go` | Dynamic favicon generation (year, month, day, week, season) |
| `format.go` | Net-asset to local-asset conversion |

All handlers follow the same idiom: parse a JSON argument map via `util.JsonArg`, validate required fields with `util.ParseJsonArgs`, mutate `model.Conf`/domain state, and finally return a `gulu.Ret` JSON envelope [Source: [kernel/api/ai.go:25-40]()]. This uniformity simplifies plugin authors and external automation scripts that call the public `siyuan://` protocol [Source: [README.md:15-30]()].

## Persistence and Data Layout

SiYuan stores workspace data on disk in a predictable layout. Notebooks are folders of `.sy` files (JSON-encoded document trees), while the workspace root contains fixed subdirectories for `assets`, `emojis`, `snippets`, `storage`, `templates`, `widgets`, `plugins`, and `public` [Source: [README.md:1-40]()]. Third-party sync disks are explicitly unsupported to avoid corruption, but the kernel ships with a dedicated sync subsystem reachable through `importSyncProviderWebDAV` and related handlers, which accept multipart uploads and replay them against the local data repo `dejavu` [Source: [kernel/api/sync.go:25-55]()]. Import of local packages is handled by `importSY`, which pushes an "endless progress" notification and walks the uploaded `.sy.zip` archive into the workspace [Source: [kernel/api/import.go:20-40]()].

Export is symmetric and reuses the Lute parser: `copyStdMarkdown` produces clean Markdown with embedded assets, while `exportCodeBlock` writes a single block to disk with a proper MIME type. The user-agent check in `export.go` routes mobile/desktop output paths appropriately [Source: [kernel/api/export.go:1-40]()]. Configuration persistence is centralized in `kernel/conf`, with `model.Conf.Save()` invoked from every settings handler, ensuring atomic writes and immediate effect on the next request [Source: [kernel/api/setting.go:20-35]()]. Graph view configuration follows the same pattern through `resetGraph` and `resetLocalGraph` [Source: [kernel/api/graph.go:15-35]()].

## PDF Annotation Linking

Issue #2828 ("PDF 标注双链") tracks the long-running effort to make PDF annotations first-class bi-directional links inside the knowledge graph. The kernel side has landed four foundational pieces:

1. **Annotation JSON schema and storage** — Annotations are persisted through the regular `assets` directory with structured sidecar files, keeping the workspace self-contained.
2. **Database table `file_annotation_refs`** — A new table maps annotation IDs to block IDs, enabling SQL queries such as `/api/block/getRefIDsByFileAnnotationID` to enumerate referencing blocks.
3. **Lute spin support** — A `Lute Spin` (virtual block ref) is emitted so the in-document outline reflects annotations without duplicating content [Source: [kernel/api/lute.go:1-40]()] where Lute is integrated for rendering, AST manipulation, and HTML/Markdown spin generation.
4. **In-reader preview** — Hovering an annotation loads a floating mini-editor that previews the linked blocks, wired through the block API.

The transaction layer ensures annotation creation, ref insertion, and index updates commit atomically. Community tracking continues in [issue #2828](https://github.com/siyuan-note/siyuan/issues/2828) and related sub-tasks.

## AI Integration

The AI feature set is intentionally minimal: SiYuan proxies user prompts to an OpenAI-compatible endpoint and returns the result. Two endpoints exist in `kernel/api/ai.go`:

- `chatGPT` — Accepts a single `msg` field and returns a stateless completion, used by inline Q&A and writing assistance [Source: [kernel/api/ai.go:25-40]()].
- `chatGPTWithAction` — Accepts a pre-defined action identifier, allowing the UI to send context (current block, selection, or template) alongside the prompt.

Configuration (API key, base URL, model name) is stored inside the encrypted `conf` struct and exposed through the `setting` API group, keeping secrets out of `.sy` files. Because the kernel is the only outbound caller, users can self-host against any OpenAI-compatible server, including local LLMs, and the README positions this as a privacy-respecting design choice [Source: [README.md:1-30]()]. Spaced-repetition flashcards implemented via the `riff` library are a complementary AI-adjacent surface, exposing `getRiffCardsByBlockIDs` for review scheduling and statistics [Source: [kernel/api/riff.go:15-40]()].

## Data Flow Overview

```mermaid
flowchart LR
    UI[Web/Desktop/Mobile UI] -->|HTTPS/WS| Gin[Gin HTTP Server]
    Gin --> Router[API Router]
    Router -->|JSON arg| Handler[Domain Handler]
    Handler --> Model[model/Conf/Treenode]
    Model --> Disk[(Workspace .sy + assets)]
    Handler --> Lute[Lute Engine]
    Lute --> Spin[Block Refs / Spins]
    Handler --> Dejavu[dejavu Sync]
    Handler --> Riff[riff SRS]
    Handler --> OpenAI[OpenAI-compatible API]
    Disk -->|WebDAV| External[Cloud Storage]
```

## See Also

- [Architecture Overview](https://github.com/siyuan-note/siyuan/blob/master/README.md)
- [Kernel API Reference](https://github.com/siyuan-note/siyuan/blob/master/API.md)
- [Lute Editor Engine](https://github.com/88250/lute)
- [Data Repository (dejavu)](https://github.com/siyuan-note/dejavu)
- [Spaced Repetition (riff)](https://github.com/siyuan-note/riff)
- [PDF Annotation Bi-directional Links #2828](https://github.com/siyuan-note/siyuan/issues/2828)

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: siyuan-note/siyuan

Summary: Found 10 structured pitfall item(s), including 1 high/blocking item(s). Top priority: Security or permission risk - Security or permission risk requires verification.

## 1. Security or permission risk - Security or permission risk requires verification

- Severity: high
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: packet_text.keyword_scan | https://github.com/siyuan-note/siyuan

## 2. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: runtime_trace
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Repro command: `docker run b3log/siyuan`
- Evidence: identity.distribution | https://github.com/siyuan-note/siyuan

## 3. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/siyuan-note/siyuan

## 4. Runtime risk - Runtime risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/siyuan-note/siyuan/issues/17890

## 5. Runtime risk - Runtime risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/siyuan-note/siyuan/issues/17880

## 6. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/siyuan-note/siyuan

## 7. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/siyuan-note/siyuan

## 8. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/siyuan-note/siyuan

## 9. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/siyuan-note/siyuan

## 10. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/siyuan-note/siyuan

<!-- canonical_name: siyuan-note/siyuan; human_manual_source: deepwiki_human_wiki -->
