solid-notion

TotalClaw 作者 DZ Chen v0.1.1

使用solid-notion CLI 以 Markdown 形式读取、编辑和编写 Notion 页面。在拉取 Notion 内容、编辑页面、管理变更集、提交编辑、恢复更改或设置 Notion API 身份验证时使用。关键词:solid-notion、Notion、Notion API、markdown、pull、edit、write、submit、restore、changeset、notion page、notion block。

源码 ↗

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:vincentdchan~solid-notion
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Avincentdchan~solid-notion/file -o solid-notion.md
Git 仓库获取源码
git clone https://github.com/openclaw/skills/commit/0b8a785b8e7ab18543fe7fed5c0fbdeecff85292
## 概述(中文)

使用solid-notion CLI 以 Markdown 形式读取、编辑和编写 Notion 页面。在拉取 Notion 内容、编辑页面、管理变更集、提交编辑、恢复更改或设置 Notion API 身份验证时使用。关键词:solid-notion、Notion、Notion API、markdown、pull、edit、write、submit、restore、changeset、notion page、notion block。

## 原文

# solid-notion CLI Guide

`solid-notion` is a CLI for reading, editing, and writing Notion pages as Markdown with local reversible changesets.

---

## 0. Installation

For normal usage (published package):

```bash
npm install -g solid-notion
solid-notion --version
```

For local development from source:

```bash
pnpm install
pnpm build
```

---

## 1. Authentication Setup

Before using any command that talks to Notion, a token must be configured.

### Getting a Notion Token

Create a Notion integration to get an API token:

1. Visit [https://www.notion.so/profile/integrations/internal](https://www.notion.so/profile/integrations/internal)
2. Click "New integration" and give it a name
3. Copy the "Internal Integration Token"
4. Share your pages with this integration (via page "Share" settings)

### Check current auth status

```bash
solid-notion auth status --json
```

Returns:

```json
{
  "ok": true,
  "profile": "default",
  "config_path": "...",
  "token_present": true,
  "token_fingerprint": "a1b2c3d4",
  "token_valid": null
}
```

If `token_present` is `false`, run init first.

### Save a token (agent-recommended method)

```bash
printf "%s" "$NOTION_TOKEN" | solid-notion init --token-stdin --json
```

Returns on success:

```json
{
  "ok": true,
  "action": "init",
  "profile": "default",
  "config_path": "...",
  "token_saved": true,
  "overwritten": false,
  "ignored_inputs": [],
  "dry_run": false
}
```

Other token input methods (in precedence order):

| Method | Flag | Notes |
|--------|------|-------|
| Direct | `--token <value>` | Visible in `ps` / shell history |
| Stdin | `--token-stdin` | **Recommended** for agents |
| JSON | `--input-json '{"token":"..."}'` | Useful for structured protocols |

Additional flags:

| Flag | Effect |
|------|--------|
| `--json` | Machine-readable JSON output only |
| `--dry-run` | Preview without writing |
| `--force` | Overwrite existing token |
| `--profile <name>` | Use a named profile (default: `"default"`) |

### Remove a token

```bash
solid-notion auth logout --json
```

---

## 2. Command Reference

### 2.1 Browse

#### List locally pulled pages

```bash
solid-notion ls
solid-notion ls --json
```

Lists all pages that have been pulled to `$SOLID_NOTION_HOME/`. Does **not** call the Notion API.

Default output: tab-separated `<pulled_at>\t<page_id>\t<title>`, sorted newest first.

JSON output (`--json`): array of objects with `page_id`, `title`, `pulled_at`, `path`.

#### List all pages (remote)

```bash
solid-notion pages
```

Output: tab-separated lines of `<last_edited>\t<page_id>\t<title>`.

#### Search pages

```bash
solid-notion search <query>
```

Output: same tab-separated format as `pages`.

### 2.2 Read

#### Show a page (non-recursive, stdout)

```bash
solid-notion show page <page_id_or_name> --format markdown
solid-notion show page <page_id_or_name> --format json
```

`<page_id_or_name>` can be a UUID or a page title. Default format: `markdown`.

#### Show a block (JSON only)

```bash
solid-notion show block <block_id> --format json
```

#### Pull a page to local files

```bash
solid-notion pull page <page_id_or_name> --format markdown --outdir ./output
```

Options:

| Flag | Default | Description |
|------|---------|-------------|
| `--format <format>` | `json` | `json` or `markdown` |
| `--outdir <dir>` | `$SOLID_NOTION_HOME/<page_id>` | Output directory |
| `--no-local-images` | (images downloaded) | Skip downloading images |
| `--no-local-videos` | (videos downloaded) | Skip downloading videos |
| `--no-recursive` | (recursive) | Only first-level blocks |

Outputs the path of the written file.

If the page was already pulled locally, running `pull page` again fetches the latest content from Notion and overwrites local output files in that directory.

#### Pull a block to local file

```bash
solid-notion pull block <block_id> --outdir ./output
```

Options: `--outdir <dir>`, `--no-recursive`

### 2.3 Edit and Write

All edit/write/submit commands require a **strict Notion page ID** (UUID format like `aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee`). Page names are NOT accepted.

#### Apply a JSON patch

Pipe a JSON patch object to stdin:

```bash
echo '{"ops": [...]}' | solid-notion edit <page_id>
```

Also accepts a markdown file path (`notion-page-<uuid>.md`) to resolve the page ID.

**CRITICAL: Valid Patch Schema**

The patch object must have exactly these keys: `ops` (array) and `notes` (string). No other keys allowed.

```json
{
  "ops": [
    { "op": "replace_block_text", "block_id": "...", "new_markdown": "...", "reason": "..." },
    { "op": "append_blocks", "parent_block_id": "...", "blocks": [...], "reason": "..." },
    { "op": "set_props", "page_id": "...", "set": {...}, "reason": "..." }
  ],
  "notes": "optional notes"
}
```

**Three allowed operation types:**

##### `replace_block_text`

Replaces rich_text content of a block. Supported block types:

`paragraph`, `heading_1`, `heading_2`, `heading_3`, `bulleted_list_item`, `numbered_list_item`, `to_do`, `quote`, `callout`

```json
{
  "op": "replace_block_text",
  "block_id": "block-uuid",
  "new_markdown": "## New heading",
  "reason": "Clarified section title"
}
```

##### `append_blocks`

Appends new blocks under a parent block.

- Most block types need `type` + `rich_text_md`
- `divider` needs only `type`
- `code` supports optional `language` (defaults to `plain text`)

```json
{
  "op": "append_blocks",
  "parent_block_id": "parent-uuid",
  "blocks": [
    { "type": "paragraph", "rich_text_md": "New paragraph content" },
    { "type": "heading_2", "rich_text_md": "New section" }
  ],
  "reason": "Added conclusion section"
}
```

Allowed block types:

- `paragraph`, `heading_1`, `heading_2`, `heading_3`
- `bulleted_list_item`, `numbered_list_item`, `to_do`, `quote`, `callout`
- `code`, `divider`

##### `set_props`

Updates page properties (title, rich_text, number, checkbox, select, multi_select, date).

```json
{
  "op": "set_props",
  "page_id": "page-uuid",
  "set": {
    "Status": { "type": "select", "name": "Done" },
    "Priority": { "type": "number", "value": 3 },
    "Done": { "type": "checkbox", "value": true },
    "Tags": { "type": "multi_select", "names": ["urgent", "important"] },
    "Due Date": { "type": "date", "start": "2026-03-02", "end": null },
    "Title": { "type": "title", "md": "New page title" },
    "Notes": { "type": "rich_text", "md": "Some notes" }
  },
  "reason": "Updated status to Done"
}
```

**Property value types:**

| Type | Shape | Example |
|------|-------|---------|
| `number` | `{ "type": "number", "value": 42 }` | - |
| `checkbox` | `{ "type": "checkbox", "value": true }` | - |
| `select` | `{ "type": "select", "name": "Option" }` | - |
| `multi_select` | `{ "type": "multi_select", "names": ["A", "B"] }` | - |
| `date` | `{ "type": "date", "start": "2026-03-02", "end": null }` | end optional |
| `title` | `{ "type": "title", "md": "markdown" }` | - |
| `rich_text` | `{ "type": "rich_text", "md": "markdown" }` | - |

#### Write workspace changes back to Notion

```bash
solid-notion write <page_id>
```

Reads the workspace files (`page.md`, `.original.md`), replaces the page content in Notion, creates a changeset, and cleans up the workspace.

#### Submit pending edits with rollback

```bash
solid-notion submit <page_id> -m "description of changes"
```

**CRITICAL: How submit works**

`submit` consumes **pending edit logs** (created by previous `edit` commands) and applies them to Notion with transaction-like semantics:

1. **Phase 0: Load** — Reads all edit log files from `edit-logs/<page_id>/` that don't have `.submitted` markers
2. **Phase 1: Prepare** — Fetches before-snapshots (current block content, property values) so rollback is possible
3.