mirror of
https://github.com/logseq/logseq.git
synced 2026-05-15 16:32:21 +00:00
* enhance(libs): add Commands proxy and unified command APIs * enhance(plugin): improve unregistering of simple and palette commands * enhance(plugin): add unregister functionality for plugin commands * chore(libs): add logseq.Commands API guide and implementation * enhance(libs): introduce LSPluginNet for HTTP client functionality * fix(ipc): ensure proper handling of IPC messages and improve plugin call structure * enhance(libs): add HTTP methods (GET, HEAD, POST, PUT, PATCH, DELETE) and error handling * enhance(api): support additional identifier types for opening blocks in sidebar * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Tienson Qin <tiensonqin@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
9.0 KiB
9.0 KiB
name, description
| name | description |
|---|---|
| logseq-plugin-sdk | Build, debug, or review Logseq plugins with the `@logseq/libs` SDK (TypeScript/JavaScript, iframe/shadow sandboxed). Use when the task involves writing plugin entry code, registering slash/command/UI items, provideUI/provideStyle/provideModel, settings schema, macro renderers, DB-graph properties & tags, Datascript/DSL queries, experimental APIs, theme plugins, or the `logseq/*` CLJS facade generated under this package. |
Logseq Plugin SDK Skill
This skill governs work inside libs/ — the source of the npm package @logseq/libs and its CLJS facade under cljs-sdk/. Use it whenever the user is authoring, upgrading, or debugging a Logseq plugin, or extending the SDK itself.
When to use
Trigger this skill when the task mentions any of:
@logseq/libs,logseq.App,logseq.Editor,logseq.DB,logseq.UI,logseq.Assets,logseq.Git,logseq.ExperimentsprovideUI/provideStyle/provideModel/useSettingsSchema/onMacroRendererSlottedregisterSlashCommand,registerBlockContextMenuItem,registerCommandPalette,registerUIItem- Plugin
package.jsonlogseqblock, themes,effectplugins, iframe/shadow sandbox - DB-graph properties, tags/classes, property idents (
:logseq.property/*,:plugin.property.<id>/*) - Datascript / DSL queries through
logseq.DB.q/logseq.DB.datascriptQuery - Regenerating the CLJS SDK (
yarn run generate:schema,bb libs:generate-cljs-sdk)
If the user is editing core Logseq app code (not a plugin), prefer the repo-root AGENTS.md instead.
Golden rules
- Always
await logseq.ready(main)before touching any API. Most SDK calls are async RPC over postMessage. - Detect graph mode before using DB-only APIs:
await logseq.App.checkCurrentIsDbGraph().IBatchBlock.propertiesis not supported for DB graphs — useEditor.upsertBlockProperty/upsertPropertyinstead. - Clean up listeners in
logseq.beforeunload(collect theofffunctions returned by everyonXxxhook). - Batch mutations (
Editor.insertBatchBlock) and debounceDB.onChanged/onBlockChangedhandlers — they fire on every keystroke. - Prefer CSS variables (
--ls-primary-text-color,--ls-primary-background-color,--ls-border-color, …) over hard-coded colors so plugins follow the active theme. - Unique plugin id in
package.json > logseq.id; keep it lowercase-kebab.main/entrymust point at a built HTML file. - Experimental APIs (
logseq.Experiments.*) are unstable — only use when no stable API exists and document the reason. - Idents are identity. For built-in or cross-graph stable references, use idents (
:logseq.property/created-at,:plugin.property.<plugin-id>/<key>) instead of display names.
Canonical plugin skeleton
import '@logseq/libs'
const offHooks: Array<() => void> = []
async function main() {
logseq.useSettingsSchema([
{ key: 'enabled', type: 'boolean', default: true, title: 'Enabled', description: '' },
])
logseq.Editor.registerSlashCommand('My Command', async () => {
await logseq.Editor.insertAtEditingCursor('Hello from my plugin!')
})
offHooks.push(
logseq.DB.onChanged(({ blocks }) => {
// debounce in real code
}),
)
logseq.beforeunload(async () => {
offHooks.forEach((off) => off())
})
}
logseq.ready(main).catch(console.error)
Workflow
- Scope the request. Is it a new plugin, a change to an existing plugin, SDK-internal work, or the CLJS facade?
- Load the right reference file(s) from
./guides/(see table below) before proposing code. - For SDK-internal changes, open the matching TypeScript under
./src/(LSPlugin.tsfor types,LSPlugin.user.tsfor the proxy implementation,modules/for Experiments/Storage/Request). - For CLJS facade changes, regenerate with:
Non-proxy methods land in
yarn run generate:schema # dist/logseq-sdk-schema.json bb libs:generate-cljs-sdk # target/generated-cljs/logseq/*.cljslogseq.core; eachIXxxProxygets its own namespace (logseq.app,logseq.editor, …). - Validate. Build the plugin (
npm run build/parcel build) and load it via Settings → Developer mode →t p→ Load unpacked plugin. Use DevTools (Cmd+Shift+I) andlogseq.UI.showMsgfor quick feedback. - Respect the package.json rules (see
guides/AGENTS.md§Configuration Fields).
Reference map (./guides/)
Load these on demand — do not dump their full contents unless needed:
| File | Load when… |
|---|---|
guides/AGENTS.md |
Authoritative overview of SDK namespaces, package.json > logseq schema, theme plugins, UI injection, macro renderers, lifecycle. Start here for most plugin tasks. |
guides/custom_theme_guide.md |
Building or reviewing Logseq theme plugins, custom theme CSS, logseq.themes, provideTheme, theme variables, light/dark mode styling, or UI selector/theme-token guidance. |
guides/starter_guide.md |
Bootstrapping a new plugin project (Node/TS toolchain, desktop dev-mode loading, hello-world). |
guides/commands_api_guide.md |
logseq.Commands unified command bus, placements, command execution, unregister handlers, and migration from legacy command APIs. |
guides/db_properties_guide.md |
Conceptual model: file-graph vs DB-graph properties, schema vs values, tag/class modeling. |
guides/db_properties_references.md |
API reference for upsertProperty, upsertBlockProperty, property schemas/types/cardinality. |
guides/db_tag_property_idents_guide.md |
Ident naming rules (:logseq.property/*, :logseq.class/*, :plugin.property.<id>/*, :plugin.class.<id>/*) and when to use them. |
guides/db_query_guide.md |
DSL (logseq.DB.q) vs Datascript (logseq.DB.datascriptQuery) queries, parameters, change watchers. |
guides/experiments_api_guide.md |
logseq.Experiments.* — React/ReactDOM reuse, internal components, CLJS interop, custom fenced-code / route / sidebar / property / block-body renderers. |
Core API quick index
Full code examples live in guides/AGENTS.md — use this table to jump to the right namespace:
logseq.App— info, graph, navigation,registerUIItem,registerCommandPalette, lifecycle hooks (onCurrentGraphChanged,onThemeModeChanged,onRouteChanged,onMacroRendererSlotted),checkCurrentIsDbGraph.logseq.Editor— slash & context-menu commands, block CRUD,insertBatchBlock, pages, cursor/selection,upsertBlockProperty/getBlockProperties(DB).logseq.DB—q,datascriptQuery,onChanged,onBlockChanged,getFileContent/setFileContent.logseq.UI—showMsg,closeMsg,queryElementRect,queryElementById.logseq.Assets—listFilesOfCurrentGraph,makeSandboxStorage,makeUrl,builtInOpen.logseq.Git—execCommand,loadIgnoreFile,saveIgnoreFile(file graphs / desktop only).logseq.Experiments— unstable; see the Experiments guide before using.- Top-level —
provideUI,provideStyle,provideModel,useSettingsSchema,onSettingsChanged,updateSettings,showMainUI/hideMainUI/toggleMainUI/setMainUIInlineStyle,beforeunload,ready.
Common pitfalls
- Forgetting
await— nearly every API is async. - Using
IBatchBlock.propertiesin a DB graph (silently ignored). - Treating
block.contentas current — it is deprecated; useblock.title. - Registering the same
keytwice inprovideUI/provideStylewithout intending to replace. - Hard-coding colors instead of
--ls-*CSS variables. - Leaking listeners (no cleanup in
beforeunload). - Shipping plugins without
logseq.idor with a non-unique id. - Assuming Git APIs exist on mobile / DB graphs.
When editing SDK source
- Type definitions:
src/LSPlugin.ts. KeepIAppProxy,IEditorProxy,IDBProxy,IUIProxy,IAssetsProxy,IGitProxy,IExperimentsProxyand theILSPluginUsersurface in sync. - User proxy implementation:
src/LSPlugin.user.ts. - Modules:
src/modules/(Experiments, Storage, Request). - After changing the public surface, regenerate the CLJS facade (see Workflow step 4) and update
CHANGELOG.md. - Follow the repo commit style: short imperative subjects, optional scope (e.g.
enhance(libs): …,fix(libs): …).
Resources
- API docs: https://plugins-doc.logseq.com
- Samples: https://github.com/logseq/logseq-plugin-samples
- CLJS template: https://github.com/logseq/cljs-plugin-example
- TS template: https://github.com/YU000jp/logseq-plugin-sample-kit-typescript
- Discord: https://discord.gg/KpN4eHY