Files
Daniel e7d50fa199 📝 Update AGENTS.md
Signed-off-by: Daniel <845765@qq.com>
2026-06-27 23:41:27 +08:00

8.9 KiB

AGENTS.md

SiYuan repository guide. Module path github.com/siyuan-note/siyuan, license AGPL-3.0.

Architecture: Go kernel (kernel/) + TypeScript frontend (app/), plus a separate export bundle (global Protyle, entry src/protyle/method.ts) for rendering rich content in exported HTML / PDF preview. Read versions from kernel/go.mod, app/package.json, kernel/util/working.go.

1. Required toolchain

Tool Version Source of truth
Go see go directive kernel/go.mod
Node (+ pnpm) see CI matrix .github/workflows/cd.yml, app/package.json (packageManager field)

SiYuan spans several repos. This repo (siyuan) holds the kernel + Electron/web frontend; the others are separate projects with their own tooling.

Repo Role / what to know
siyuan This repo — kernel + Electron/web/tablet UI
siyuan-android / siyuan-ios / siyuan-harmony Native apps wrapping the gomobile kernel; build steps differ per platform — see each project's README
siyuan-chrome Browser extension (web clipper); talks to the running kernel over HTTP only
petal SiYuan Plugin API declaration (the plugin system is named "petal"); consumed by plugins, not a kernel Go dependency
lute Markdown/Kramdown AST engine — the editor + .sy format; also the source of the bundled lute.min.js (a GopherJS build served to the frontend). Lives under $GOPATH/src/github.com/88250/lute, not as a sibling repo
dejavu Data repo / sync engine (encrypted snapshots)
riff Spaced-repetition (SRS) flashcard scheduler
gulu General Go utility library (gulu.Ret, gulu.JSON, …)
eventbus In-process event bus
filelock Cross-platform file locking (.sy read/write)
httpclient HTTP client wrapper (cloud / sync / bazaar calls)
logging Leveled logging used throughout the kernel
go-sqlite3 / pdfcpu Maintainer's forks, pulled in via permanent replace in kernel/go.mod (keep those)
epub / clipboard / go-humanize / vitess-sqlparser / dataparser / encryption Smaller Go libraries (export / clipboard / formatting / SQL parse / data parse / crypto)

All Go libraries above are dependencies in kernel/go.mod. GitHub org: siyuan-note/* for the siyuan- apps and most libs; 88250/* for lute, gulu, and the forks (go-sqlite3 / pdfcpu).

Cross-repo notes

  • Editing any Go dependency (Lute / dejavu / gulu / eventbus / riff / filelock / httpclient / logging / go-sqlite3 / pdfcpu / epub / …): these are imported by the kernel as Go modules (kernel/go.mod). To test a local change, add a temporary replace in kernel/go.mod pointing at your local checkout — but never commit that replace; it breaks builds for everyone else.
  • Rebuilding lute.min.js: it's the JS build of the Go lute project — generated upstream and checked into app/stage/protyle/js/lute/. Don't edit it here; change lute, rebuild, and copy the artifact in.
  • Mobile apps (siyuan-android / siyuan-ios / siyuan-harmony): each is a separate native app that wraps the kernel built from this repo. For how to build, vendor the kernel binding, and wire everything up, read each project's own README — the toolchains and steps differ per platform and aren't documented here.
  • siyuan-chrome: independent TypeScript project; it only interacts with a running SiYuan instance through the public HTTP API documented in API.md.

3. Repository layout

Top level (repo root):

Path Contents
kernel/ Go backend — server, data engine, API, all domain logic
app/ TypeScript frontend (Electron/web), built by webpack into app/stage/build/
app/appearance/ Themes, icons, i18n (appearance/langs/*.json)
app/stage/ Build output served by the kernel
app/changelogs/ Per-version changelog markdown
.github/ CONTRIBUTING.md (+zh-CN), SECURITY.md, CODE_OF_CONDUCT.md, PULL_REQUEST_TEMPLATE.md, issue templates, workflows/
scripts/ Release packaging: win-build.bat, darwin-build.sh, linux-build.sh, parse-changelog.py, check-lang-keys.py

Major kernel/ packages (under kernel/)

Package Responsibility
main.go (//go:build !mobile) Desktop entry point → cli/cmd
cli/cmd/ Cobra CLI subcommands (serve, notebook, block, search, sql, export, repo, sync, …)
model/ Core domain (~70 files): blocks/trees, transactions, indexing, search, attribute views, export, history, sync, flashcards, AI, CalDAV/CardDAV, auth
treenode/ In-memory tree over the Lute AST + blocktree.db (BlockTree{ID,RootID,ParentID,BoxID,Path,HPath,Type,...})
av/ Attribute View (database) engine: values, filters, sorts, layouts (table/kanban/gallery)
sql/ Embedded SQLite (siyuan.db, history.db, asset_content.db) + FTS5; async index queues
search/ FTS tokenizer helpers, CJK conversion (hanconv.go)
bazaar/ Marketplace: plugins/widgets/themes/icons/templates
filesys/ Read/write .sy files on disk (via filelock)
server/ Gin server bootstrap (serve.go): middleware, TLS/cmux, WebDAV/CalDAV/CardDAV, WebSocket, MCP
api/ HTTP route registration (router.go::ServeAPI, ~400 endpoints) + per-area handlers
conf/ Configuration structs
util/ Cross-cutting: working.go (workspace, Boot()), lute.go, i18n.go, websocket.go (melody push), result.go (API envelope)
plugin/ Plugin subsystem (kernel side)
mcp/ MCP (Model Context Protocol) server
agent/ AI agent runtime
mobile/, harmony/ //go:build mobile gomobile bindings for Android/iOS/HarmonyOS

Frontend (app/src/) highlights

Dir Purpose
index.ts Main App class — boots SPA, opens main WebSocket, handles WS push events
window/ Detached Electron window variant
protyle/ The block editorwysiwyg/, toolbar/, gutter/, breadcrumb/, hint/, scroll/, undo/, preview/, render/ (incl. render/av/)
editor/, layout/, menus/, dialog/, config/, mobile/, ai/, sync/, history/, search/, card/ Feature modules
util/fetch.ts fetchGet/fetchPost — all kernel calls
layout/Model.ts WebSocket client all UI binds to
constants.ts Global constants (version, IDs, storage keys)

Four webpack configs each emit a separate bundle to app/stage/build/{app,desktop,mobile,export}/. The kernel's serveAppearance picks which bundle to serve based on User-Agent. The export bundle is different from the other three: it is not an app UI — it is a client-side library (global Protyle, entry src/protyle/method.ts) exposing renderers for code highlighting, math (KaTeX), and diagrams (Mermaid/flowchart/graphviz/…). It is loaded by the HTML pages assembled during export (app/src/protyle/export/index.ts) — the desktop PDF preview window and standalone exported HTML files — so rich content renders outside the editor.


4. Do not hand-edit

  • app/stage/protyle/js/lute/lute.min.js (built from upstream 88250/lute)
  • app/stage/build/**, app/src/types/dist/**
  • app/changelogs/** (generated by separate tooling)
  • app/kernel/SiYuan-Kernel*, *.syso, kernel/kernel.aar
  • app/pandoc/*

5. Project-specific rules

  1. i18n:
    • New keys go at the top of each langs/*.json object; add to every language file (reference en.json)
    • Each language must be properly translated — do NOT copy the same text across all language files
    • Domains: ld246.com only in zh-CN.json; use liuyun.io in all other languages
    • After modifying i18n files, run python scripts/check-lang-keys.py to verify key completeness across all language files
  2. Windows scripting: Prefer Node.js / Python; avoid PowerShell unless necessary
  3. Frontend verification: Do not use npx webpack or pnpm dev to verify changes; after changes, run cd app && pnpm run lint to check code style
  4. Frontend build: Do NOT run pnpm build — the developer runs pnpm dev manually, and pnpm build will conflict with it, producing broken bundles
  5. Icons: Do not hand-write SVG; use existing icons from app/appearance/icons/litheness/icon.js when possible

6. Coding conventions

  1. Comments: Wrap code comments at 120 characters
  2. Comments: Describe what the code does, not what it replaced — don't reference the old implementation in comments
  3. Comments: Write comments in Chinese
  4. Markdown: Do not hand-wrap; keep each line (paragraphs, table rows, list items, etc.) on a single line
  5. TypeScript/JavaScript: Semicolons required, use double quotes, indent with spaces
  6. Go: Format with gofmt after editing

7. Response style

  1. Language: Match the user's language; do not mix languages mid-sentence (keep proper nouns / identifiers in their original form)