ClawSkills logoClawSkills

Logseq

提供通过其插件 API 与本地 Logseq 实例交互的命令。用于创建页面、插入块、查询图数据库、管理

介绍

# Logseq Plugin API

通过 Logseq 的 JavaScript 插件 API 与本地 Logseq 实例进行交互。此技能支持在 Logseq 图谱中进行读取、写入、查询以及自动化工作流。

## 前置条件

**Logseq 必须在本地运行**,并安装有暴露该 API 的插件。标准方式如下:

1. **安装桥接插件**,通过 HTTP 暴露 `logseq` API(例如,通过自定义插件或 localhost 端点) 2. **替代方案**:使用带有 `@logseq/libs` 包的 Node.js 来针对运行的 Logseq 实例编写脚本

该 API 主要设计用于浏览器内插件,因此从外部脚本访问它需要一个桥接/代理。

## 核心 API 命名空间

Logseq 插件 API 组织为以下主要代理:

### `logseq.App` 应用程序级操作:获取应用信息、用户配置、当前图谱、命令、UI 状态、外部链接。

**关键方法:** - `getInfo()` - 获取应用版本和信息 - `getUserConfigs()` - 获取用户偏好(主题、格式、语言等) - `getCurrentGraph()` - 获取当前图谱信息(名称、路径、URL) - `registerCommand(type, opts, action)` - 注册自定义命令 - `pushState(route, params, query)` - 导航到路由

### `logseq.Editor` 块和页面编辑操作:创建、更新、移动、查询内容。

**关键方法:** - `getBlock(uuid)` - 通过 UUID 获取块 - `getCurrentPage()` - 获取当前页面实体 - `getCurrentPageBlocksTree()` - 获取当前页面上的所有块 - `getPageBlocksTree(page)` - 获取特定页面的所有块 - `insertBlock(target, content, opts)` - 插入一个新块 - `updateBlock(uuid, content)` - 更新块内容 - `createPage(pageName, properties, opts)` - 创建一个新页面 - `deletePage(pageName)` - 删除一个页面 - `getPageLinkedReferences(page)` - 获取指向页面的反向链接 - `registerSlashCommand(tag, action)` - 添加自定义斜杠命令

### `logseq.DB` 使用 Datalog 进行数据库查询。

**关键方法:** - `q(query, ...inputs)` - 运行 Datalog 查询 - `datascriptQuery(query, ...inputs)` - 直接 Datascript 查询

### `logseq.UI` UI 操作:消息、对话框、主 UI 可见性。

**关键方法:** - `showMsg(content, status)` - 显示 Toast 通知 - `queryElementById(id)` - 查询 DOM 元素

### `logseq.Git` 当前图谱的 Git 操作。

**关键方法:** - `execCommand(args)` - 执行 git 命令

### `logseq.Assets` 资源管理。

**关键方法:** - `listFilesOfCurrentGraph(path)` - 列出图谱中的文件

## 常见工作流

### 读取内容

```javascript // Get current page const page = await logseq.Editor.getCurrentPage();

// Get all blocks on a page const blocks = await logseq.Editor.getPageBlocksTree('Daily Notes');

// Get a specific block const block = await logseq.Editor.getBlock('block-uuid-here');

// Query with Datalog const results = await logseq.DB.q(` [:find (pull ?b [*]) :where [?b :block/marker "TODO"]] `); ```

### 写入内容

```javascript // Create a new page await logseq.Editor.createPage('Project Notes', { tags: 'project', status: 'active' }, { redirect: false });

// Insert a block const block = await logseq.Editor.insertBlock( 'target-block-uuid', '- New task item', { before: false, sibling: true } );

// Update a block await logseq.Editor.updateBlock('block-uuid', 'Updated content');

// Batch insert multiple blocks const blocks = [ { content: 'First item' }, { content: 'Second item', children: [ { content: 'Nested item' } ]} ]; await logseq.Editor.insertBatchBlock('parent-uuid', blocks, { sibling: false }); ```

### 任务管理

```javascript // Find all TODO items const todos = await logseq.DB.q(` [:find (pull ?b [*]) :where [?b :block/marker ?marker] [(contains? #{"TODO" "DOING"} ?marker)]] `);

// Mark task as DONE await logseq.Editor.updateBlock('task-uuid', 'DONE Task content');

// Get tasks on current page const page = await logseq.Editor.getCurrentPage(); const blocks = await logseq.Editor.getPageBlocksTree(page.name); const tasks = blocks.filter(b => b.marker === 'TODO' || b.marker === 'DOING'); ```

### 导航与 UI

```javascript // Navigate to a page logseq.App.pushState('page', { name: 'Project Notes' });

// Show notification logseq.UI.showMsg('✅ Task completed!', 'success');

// Get app config const configs = await logseq.App.getUserConfigs(); console.log('Theme:', configs.preferredThemeMode); console.log('Format:', configs.preferredFormat); ```

## 实现方案

由于 Logseq 的插件 API 基于浏览器,您有几种选择:

### 方案 1:桥接插件

创建一个最小的 Logseq 插件,通过 HTTP 暴露 API 调用:

```javascript // In Logseq plugin (index.js) logseq.ready(() => { // Expose API endpoints logseq.provideModel({ async handleAPICall({ method, args }) { return await logseq.Editor[method](...args); } }); });

// Then call from external script via HTTP POST ```

### 方案 2:使用 @logseq/libs 的 Node.js 脚本

对于自动化脚本,请使用 `@logseq/libs` 包:

```bash npm install @logseq/libs ```

**注意:** 这需要一个正在运行的 Logseq 实例以及正确的连接设置。

### 方案 3:直接插件开发

开发一个完整的 Logseq 插件,参考以下插件示例: https://github.com/logseq/logseq-plugin-samples

## API 参考

有关完整的 API 文档,请参阅: - **API 文档**: https://logseq.github.io/plugins/ - **插件示例**: https://github.com/logseq/logseq-plugin-samples - **类型定义**: `references/api-types.md`(从 `@logseq/libs` 中提取)

## 关键数据结构

### BlockEntity ```typescript { id: number, // Entity ID uuid: string, // Block UUID content: string, // Block content format: 'markdown' | 'org', page: { id: number }, // Parent page parent: { id: number }, // Parent block left: { id: number }, // Previous sibling properties: {}, // Block properties marker?: string, // TODO/DOING/DONE children?: [] // Child blocks } ```

### PageEntity ```typescript { id: number, uuid: string, name: string, // Page name (lowercase) originalName: string, // Original case 'journal?': boolean, properties: {}, journalDay?: number, // YYYYMMDD for journals } ```

## 提示与最佳实践

1. **始终检查 null**:如果实体不存在,API 方法可能会返回 `null` 2. **优先使用 UUID 而非 ID**:块的 UUID 是稳定的,实体 ID 可能会发生变化 3. **批量操作**:使用 `insertBatchBlock` 进行多次插入 4. **高效查询**:Datalog 查询很强大,但在大型图谱上可能会很慢 5. **属性是对象**:使用 `block.properties.propertyName` 访问 6. **格式很重要**:请尊重用户的首选格式(markdown 与 org-mode) 7. **全程异步**:所有 API 调用都返回 Promises

## 常见陷阱

- **页面名称为小写**:查询时,请使用小写的页面名称 - **日记页面**:使用 `journalDay` 格式(YYYYMMDD)而不是日期字符串 - **块层级**:插入时请遵守父子关系 - **格式差异**:Markdown 使用 `-` 作为项目符号,Org 使用 `*` - **属性语法**:在 markdown(`prop::`)和 org(`:PROPERTIES:`)之间有所不同

更多产品