{"skill":{"slug":"solid-notion","displayName":"solid-notion","summary":"Manage Notion pages locally as Markdown: pull, edit with JSON patches, write changes, submit edits with rollback, and handle API authentication via solid-not...","description":"---\nname: solid-notion\ndescription: Read, edit, and write Notion pages as Markdown using the solid-notion CLI. Use when pulling Notion content, editing pages, managing changesets, submitting edits, restoring changes, or setting up Notion API authentication. Keywords: solid-notion, Notion, Notion API, markdown, pull, edit, write, submit, restore, changeset, notion page, notion block.\nmetadata:\n  author: DZ Chen\n  version: \"0.1\"\n---\n\n# solid-notion CLI Guide\n\n`solid-notion` is a CLI for reading, editing, and writing Notion pages as Markdown with local reversible changesets.\n\n---\n\n## 0. Installation\n\nFor normal usage (published package):\n\n```bash\nnpm install -g solid-notion\nsolid-notion --version\n```\n\nFor local development from source:\n\n```bash\npnpm install\npnpm build\n```\n\n---\n\n## 1. Authentication Setup\n\nBefore using any command that talks to Notion, a token must be configured.\n\n### Getting a Notion Token\n\nCreate a Notion integration to get an API token:\n\n1. Visit [https://www.notion.so/profile/integrations/internal](https://www.notion.so/profile/integrations/internal)\n2. Click \"New integration\" and give it a name\n3. Copy the \"Internal Integration Token\"\n4. Share your pages with this integration (via page \"Share\" settings)\n\n### Check current auth status\n\n```bash\nsolid-notion auth status --json\n```\n\nReturns:\n\n```json\n{\n  \"ok\": true,\n  \"profile\": \"default\",\n  \"config_path\": \"...\",\n  \"token_present\": true,\n  \"token_fingerprint\": \"a1b2c3d4\",\n  \"token_valid\": null\n}\n```\n\nIf `token_present` is `false`, run init first.\n\n### Save a token (agent-recommended method)\n\n```bash\nprintf \"%s\" \"$NOTION_TOKEN\" | solid-notion init --token-stdin --json\n```\n\nReturns on success:\n\n```json\n{\n  \"ok\": true,\n  \"action\": \"init\",\n  \"profile\": \"default\",\n  \"config_path\": \"...\",\n  \"token_saved\": true,\n  \"overwritten\": false,\n  \"ignored_inputs\": [],\n  \"dry_run\": false\n}\n```\n\nOther token input methods (in precedence order):\n\n| Method | Flag | Notes |\n|--------|------|-------|\n| Direct | `--token <value>` | Visible in `ps` / shell history |\n| Stdin | `--token-stdin` | **Recommended** for agents |\n| JSON | `--input-json '{\"token\":\"...\"}'` | Useful for structured protocols |\n\nAdditional flags:\n\n| Flag | Effect |\n|------|--------|\n| `--json` | Machine-readable JSON output only |\n| `--dry-run` | Preview without writing |\n| `--force` | Overwrite existing token |\n| `--profile <name>` | Use a named profile (default: `\"default\"`) |\n\n### Remove a token\n\n```bash\nsolid-notion auth logout --json\n```\n\n---\n\n## 2. Command Reference\n\n### 2.1 Browse\n\n#### List locally pulled pages\n\n```bash\nsolid-notion ls\nsolid-notion ls --json\n```\n\nLists all pages that have been pulled to `$SOLID_NOTION_HOME/`. Does **not** call the Notion API.\n\nDefault output: tab-separated `<pulled_at>\\t<page_id>\\t<title>`, sorted newest first.\n\nJSON output (`--json`): array of objects with `page_id`, `title`, `pulled_at`, `path`.\n\n#### List all pages (remote)\n\n```bash\nsolid-notion pages\n```\n\nOutput: tab-separated lines of `<last_edited>\\t<page_id>\\t<title>`.\n\n#### Search pages\n\n```bash\nsolid-notion search <query>\n```\n\nOutput: same tab-separated format as `pages`.\n\n### 2.2 Read\n\n#### Show a page (non-recursive, stdout)\n\n```bash\nsolid-notion show page <page_id_or_name> --format markdown\nsolid-notion show page <page_id_or_name> --format json\n```\n\n`<page_id_or_name>` can be a UUID or a page title. Default format: `markdown`.\n\n#### Show a block (JSON only)\n\n```bash\nsolid-notion show block <block_id> --format json\n```\n\n#### Pull a page to local files\n\n```bash\nsolid-notion pull page <page_id_or_name> --format markdown --outdir ./output\n```\n\nOptions:\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--format <format>` | `json` | `json` or `markdown` |\n| `--outdir <dir>` | `$SOLID_NOTION_HOME/<page_id>` | Output directory |\n| `--no-local-images` | (images downloaded) | Skip downloading images |\n| `--no-local-videos` | (videos downloaded) | Skip downloading videos |\n| `--no-recursive` | (recursive) | Only first-level blocks |\n\nOutputs the path of the written file.\n\nIf the page was already pulled locally, running `pull page` again fetches the latest content from Notion and overwrites local output files in that directory.\n\n#### Pull a block to local file\n\n```bash\nsolid-notion pull block <block_id> --outdir ./output\n```\n\nOptions: `--outdir <dir>`, `--no-recursive`\n\n### 2.3 Edit and Write\n\nAll edit/write/submit commands require a **strict Notion page ID** (UUID format like `aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee`). Page names are NOT accepted.\n\n#### Apply a JSON patch\n\nPipe a JSON patch object to stdin:\n\n```bash\necho '{\"ops\": [...]}' | solid-notion edit <page_id>\n```\n\nAlso accepts a markdown file path (`notion-page-<uuid>.md`) to resolve the page ID.\n\n**CRITICAL: Valid Patch Schema**\n\nThe patch object must have exactly these keys: `ops` (array) and `notes` (string). No other keys allowed.\n\n```json\n{\n  \"ops\": [\n    { \"op\": \"replace_block_text\", \"block_id\": \"...\", \"new_markdown\": \"...\", \"reason\": \"...\" },\n    { \"op\": \"append_blocks\", \"parent_block_id\": \"...\", \"blocks\": [...], \"reason\": \"...\" },\n    { \"op\": \"set_props\", \"page_id\": \"...\", \"set\": {...}, \"reason\": \"...\" }\n  ],\n  \"notes\": \"optional notes\"\n}\n```\n\n**Three allowed operation types:**\n\n##### `replace_block_text`\n\nReplaces rich_text content of a block. Supported block types:\n\n`paragraph`, `heading_1`, `heading_2`, `heading_3`, `bulleted_list_item`, `numbered_list_item`, `to_do`, `quote`, `callout`\n\n```json\n{\n  \"op\": \"replace_block_text\",\n  \"block_id\": \"block-uuid\",\n  \"new_markdown\": \"## New heading\",\n  \"reason\": \"Clarified section title\"\n}\n```\n\n##### `append_blocks`\n\nAppends new blocks under a parent block.\n\n- Most block types need `type` + `rich_text_md`\n- `divider` needs only `type`\n- `code` supports optional `language` (defaults to `plain text`)\n\n```json\n{\n  \"op\": \"append_blocks\",\n  \"parent_block_id\": \"parent-uuid\",\n  \"blocks\": [\n    { \"type\": \"paragraph\", \"rich_text_md\": \"New paragraph content\" },\n    { \"type\": \"heading_2\", \"rich_text_md\": \"New section\" }\n  ],\n  \"reason\": \"Added conclusion section\"\n}\n```\n\nAllowed block types:\n\n- `paragraph`, `heading_1`, `heading_2`, `heading_3`\n- `bulleted_list_item`, `numbered_list_item`, `to_do`, `quote`, `callout`\n- `code`, `divider`\n\n##### `set_props`\n\nUpdates page properties (title, rich_text, number, checkbox, select, multi_select, date).\n\n```json\n{\n  \"op\": \"set_props\",\n  \"page_id\": \"page-uuid\",\n  \"set\": {\n    \"Status\": { \"type\": \"select\", \"name\": \"Done\" },\n    \"Priority\": { \"type\": \"number\", \"value\": 3 },\n    \"Done\": { \"type\": \"checkbox\", \"value\": true },\n    \"Tags\": { \"type\": \"multi_select\", \"names\": [\"urgent\", \"important\"] },\n    \"Due Date\": { \"type\": \"date\", \"start\": \"2026-03-02\", \"end\": null },\n    \"Title\": { \"type\": \"title\", \"md\": \"New page title\" },\n    \"Notes\": { \"type\": \"rich_text\", \"md\": \"Some notes\" }\n  },\n  \"reason\": \"Updated status to Done\"\n}\n```\n\n**Property value types:**\n\n| Type | Shape | Example |\n|------|-------|---------|\n| `number` | `{ \"type\": \"number\", \"value\": 42 }` | - |\n| `checkbox` | `{ \"type\": \"checkbox\", \"value\": true }` | - |\n| `select` | `{ \"type\": \"select\", \"name\": \"Option\" }` | - |\n| `multi_select` | `{ \"type\": \"multi_select\", \"names\": [\"A\", \"B\"] }` | - |\n| `date` | `{ \"type\": \"date\", \"start\": \"2026-03-02\", \"end\": null }` | end optional |\n| `title` | `{ \"type\": \"title\", \"md\": \"markdown\" }` | - |\n| `rich_text` | `{ \"type\": \"rich_text\", \"md\": \"markdown\" }` | - |\n\n#### Write workspace changes back to Notion\n\n```bash\nsolid-notion write <page_id>\n```\n\nReads the workspace files (`page.md`, `.original.md`), replaces the page content in Notion, creates a changeset, and cleans up the workspace.\n\n#### Submit pending edits with rollback\n\n```bash\nsolid-notion submit <page_id> -m \"description of changes\"\n```\n\n**CRITICAL: How submit works**\n\n`submit` consumes **pending edit logs** (created by previous `edit` commands) and applies them to Notion with transaction-like semantics:\n\n1. **Phase 0: Load** — Reads all edit log files from `edit-logs/<page_id>/` that don't have `.submitted` markers\n2. **Phase 1: Prepare** — Fetches before-snapshots (current block content, property values) so rollback is possible\n3. **Phase 2: Apply** — Applies ops sequentially to Notion\n4. **Phase 3: Finalize** — On success, saves commit to `versions/`. On failure, rolls back already-applied ops using before-snapshots.\n\n**Exit statuses:**\n\n| `status` | Meaning | `ok` |\n|----------|---------|------|\n| `pushed` | All ops applied successfully | `true` |\n| `nothing_to_submit` | No pending edits found | `false` |\n| `rolled_back` | Apply failed but rollback succeeded | `false` |\n| `failed_needs_reconcile` | Apply failed AND rollback partially failed | `false` |\n\n**Submit result format:**\n\n```json\n{\n  \"ok\": true,\n  \"commit_id\": \"cmt_20260302_143022\",\n  \"notion_id\": \"3d1b-...\",\n  \"status\": \"pushed\",\n  \"applied_ops\": 3,\n  \"included_edits\": 2\n}\n```\n\n**Best practices:**\n- Always run `submit` after `edit` operations to publish changes\n- If submit returns `rolled_back`, the page is back to original state — no manual cleanup needed\n- If submit returns `failed_needs_reconcile`, manual intervention may be required\n- The `-m` (message) flag is **required**\n\n### 2.4 Create New Pages\n\n**CRITICAL: Use the `new` command to create Notion pages programmatically**\n\nThe `new` command creates a new page under a parent (page or database) with **metadata only** (title, icon, cover, props) via stdin as JSON. After creation, the page is **automatically pulled** locally as markdown. To add content (blocks), use the existing `edit` + `submit` workflow.\n\n#### Create a new page\n\n```bash\necho '{\"title\":\"My New Page\",\"notes\":\"\"}' | solid-notion new --parent <parent_id> -m \"Create page\" --json\n```\n\n**Required flags:**\n- `--parent <parent_id>` — Parent page or database ID\n- `-m, --message <message>` — Commit message\n\n**Optional flags:**\n- `--database` — Parent is a database (creates as database entry)\n- `--json` — Output JSON only\n- `--dry-run` — Validate without creating\n\n**CRITICAL: Valid Payload Schema**\n\nThe JSON payload via stdin must have exactly these keys:\n\n```json\n{\n  \"title\": \"Page Title\",\n  \"icon\": { \"type\": \"emoji\", \"emoji\": \"📝\" },\n  \"cover\": { \"type\": \"external\", \"url\": \"https://...\" },\n  \"props\": {\n    \"Status\": { \"type\": \"select\", \"name\": \"In Progress\" }\n  },\n  \"notes\": \"optional notes about this creation\"\n}\n```\n\n**Required fields:**\n- `title` (string, non-empty)\n- `notes` (string, can be empty)\n\n**Optional fields:**\n- `icon` — `{ \"type\": \"emoji\", \"emoji\": \"🎉\" }` or `{ \"type\": \"external\", \"url\": \"...\" }`\n- `cover` — `{ \"type\": \"external\", \"url\": \"...\" }`\n- `props` — Page properties (database entries), same types as `set_props` plus `url`, `email`, `phone_number`\n\n**No `blocks` field.** Content is added via `edit` + `submit` after creation.\n\n**Property types for `props` (database entries):**\n\nAll types from `set_props` plus:\n- `url`: `{ \"type\": \"url\", \"value\": \"https://...\" }`\n- `email`: `{ \"type\": \"email\", \"value\": \"user@example.com\" }`\n- `phone_number`: `{ \"type\": \"phone_number\", \"value\": \"+1234567890\" }`\n\n**CRITICAL rules:**\n- Payload must have exactly `title`, `notes`, and optional fields — no extra keys\n- For database pages, `props` must match the database schema\n- After creation, the page is auto-pulled locally as markdown\n\n**Transaction semantics:**\n\n`new` follows the same 4-phase pipeline as `submit`:\n\n1. **Phase 0: Parse** — Read and validate JSON from stdin\n2. **Phase 1: Prepare** — Verify parent exists, derive internal ops, create commit draft\n3. **Phase 2: Apply** — Create page on Notion (metadata only)\n4. **Phase 3: Finalize** — Persist version record, auto-pull page. On failure, rollback (archive page).\n\nRollback for `new`:\n- Archives the created page (soft-delete)\n\n**Success output (JSON mode):**\n\n```json\n{\n  \"ok\": true,\n  \"commit_id\": \"parent-id-20260304T120000Z\",\n  \"action\": \"new\",\n  \"status\": \"pushed\",\n  \"created_page_id\": \"abc123-def456\",\n  \"page_url\": \"https://notion.so/abc123def456\",\n  \"title\": \"My New Page\",\n  \"parent_id\": \"parent-id\",\n  \"parent_type\": \"page\",\n  \"pulled_to\": \"/path/to/notion-page-abc123-def456.md\"\n}\n```\n\n**Dry run output:**\n\n```json\n{\n  \"ok\": true,\n  \"action\": \"new\",\n  \"status\": \"dry_run\",\n  \"dry_run\": true,\n  \"validation\": \"passed\",\n  \"title\": \"My New Page\",\n  \"parent_id\": \"parent-id\"\n}\n```\n\n### 2.5 History and Restore\n\n#### View history\n\n```bash\nsolid-notion history <page_id>\n```\n\nOutput: tab-separated `<id>\\t<created_at>\\t<type>`.\n\nTypes:\n- `changeset` — Created by `write` or `restore`\n- `new` — Created by `new` command\n- `submit` — Created by `submit` command\n\n#### Restore to a previous changeset or version\n\n```bash\nsolid-notion restore <page_id> <changeset_or_commit_id>\nsolid-notion restore <changeset_or_commit_id>\n```\n\n**Behavior depends on type:**\n- **Changeset** (from `write`/`restore`): Restores page to that changeset's state\n- **Version (`submit` or `new`)**: Restore to the target hash by undoing only the later `submit` versions, then writes a new changeset\n\nHash-only lookup is supported. If the hash exists in multiple pages, CLI asks you to disambiguate with page ID.\n\nAfter restore-to-version, local version files after the target hash are deleted.\n\nOutputs the new changeset ID created by restore.\n\n---\n\n## 3. Agent Workflows\n\n### Workflow: Read a page as Markdown\n\n```bash\nsolid-notion pull page <page_id_or_name> --format markdown --outdir /tmp/notion-work\n```\n\nThen read the output file path printed to stdout.\n\n### Workflow: Full edit cycle (Markdown mode)\n\n1. **Pull** the page to a workspace:\n   ```bash\n   solid-notion pull page <page_id> --format markdown --outdir ~/.local/share/solid-notion-cli/<page_id>\n   ```\n\n2. **Edit** the local `page.md` file as needed.\n\n3. **Write** changes back:\n   ```bash\n   solid-notion write <page_id>\n   ```\n\n4. **Submit** with a message:\n   ```bash\n   solid-notion submit <page_id> -m \"Updated section headings\"\n   ```\n\n### Workflow: Edit via JSON patch (Programmatic mode)\n\nUse this workflow when making precise, targeted edits without pulling full markdown.\n\n1. **Get the target block IDs** (you may need to pull JSON first):\n   ```bash\n   solid-notion pull page <page_id> --format json --outdir /tmp\n   # or inspect specific block:\n   solid-notion show block <block_id> --format json\n   ```\n\n2. **Construct a valid patch** with `ops` array and `notes`:\n   ```json\n   {\n     \"ops\": [\n       {\n         \"op\": \"replace_block_text\",\n         \"block_id\": \"block-uuid-here\",\n         \"new_markdown\": \"Updated content here\",\n         \"reason\": \"Clarified the explanation\"\n       },\n       {\n         \"op\": \"set_props\",\n         \"page_id\": \"page-uuid-here\",\n         \"set\": {\n           \"Status\": { \"type\": \"select\", \"name\": \"In Progress\" }\n         },\n         \"reason\": \"Moving to next phase\"\n       }\n     ],\n     \"notes\": \"Batch update from review session\"\n   }\n   ```\n\n3. **Apply the patch** via stdin:\n   ```bash\n   cat patch.json | solid-notion edit <page_id>\n   ```\n\n4. **Submit** the pending edits:\n   ```bash\n   solid-notion submit <page_id> -m \"Applied review feedback\"\n   ```\n\n**CRITICAL rules for JSON patch editing:**\n- The patch must have exactly `ops` and `notes` — no extra keys\n- Each op must have `op`, `reason`, and type-specific fields\n- `block_id` in `replace_block_text` must be a valid Notion block ID\n- `page_id` in `set_props` must be the target page UUID\n- `append_blocks` creates new blocks — the `created_block_ids` are recorded in edit logs for rollback\n\n### Workflow: Batch multiple edits before submit\n\nYou can run multiple `edit` commands before a single `submit`. All pending edits are aggregated:\n\n```bash\n# First edit\necho '{\"ops\":[...],\"notes\":\"First change\"}' | solid-notion edit <page_id>\n\n# Second edit  \necho '{\"ops\":[...],\"notes\":\"Second change\"}' | solid-notion edit <page_id>\n\n# Third edit\necho '{\"ops\":[...],\"notes\":\"Third change\"}' | solid-notion edit <page_id>\n\n# Submit all at once\nsolid-notion submit <page_id> -m \"Batch: three related updates\"\n```\n\nSubmit reads all edit logs from `edit-logs/<page_id>/`, marks them `.submitted` on success, and creates a single commit record.\n\n### Workflow: Restore a change\n\n1. **List** changesets:\n   ```bash\n   solid-notion history <page_id>\n   ```\n\n2. **Restore** to a specific hash:\n   ```bash\n   solid-notion restore <page_id> <changeset_or_commit_id>\n   # or hash-only when unique:\n   solid-notion restore <changeset_or_commit_id>\n   ```\n\n---\n\n## 4. Storage Concepts & Layout\n\nAll data is stored under `$SOLID_NOTION_HOME` (default: `~/.local/share/solid-notion-cli`).\n\n### Storage Concepts Explained\n\n**Workspace files** (`<page_id>/`) — Created by `pull`, used by `write`:\n- `page.md` — The markdown you edit\n- `.original.md` — Snapshot before editing (for diff/comparison)\n- `page.meta.md` — Page metadata (properties, etc.)\n- **Lifecycle**: Created on `pull`, deleted on successful `write`\n\n**Edit logs** (`edit-logs/<page_id>/`) — Created by `edit`, consumed by `submit`:\n- JSONL files recording each patch operation with before/after snapshots\n- **Purpose**: Enable rollback if submit fails\n- **Format**: Each line is a JSON object with `op`, `block_id`/`page_id`, `reason`, and before/after values\n- **Lifecycle**: Created on `edit`, marked `.submitted` on successful `submit`\n\n**Versions** (`<page_id>/versions/`) — Created by `submit`:\n- Commit records with full operation history and snapshots\n- **Purpose**: Immutable history of what was published to Notion\n- **Format**: JSON with `commitId`, `status`, `ops`, `beforeSnapshots`, `applyState`\n- **Lifecycle**: Created on every `submit` attempt (even failures)\n\n**Changesets** (`changesets/<page_id>/`) — Created by `write` and `restore`:\n- Reversible markdown diffs for the \"write -> restore\" workflow\n- **Purpose**: Track full page content changes for `history` and `restore`\n- **Format**: Markdown files with YAML frontmatter containing before/after content\n- **Lifecycle**: Created on `write`, referenced by `history` and `restore`\n\n### Directory Layout\n\n```\n$SOLID_NOTION_HOME/\n  config.json                          # Auth tokens (mode 0600)\n  \n  # Workspace (markdown editing workflow)\n  <page_id>/\n    page.md                            # Edited markdown\n    page.meta.md                       # Page metadata\n    .original.md                       # Original for diff\n    versions/                          # Submit commits (JSON)\n  \n  # Edit logs (JSON patch workflow)\n  edit-logs/<page_id>/\n    <page_id>-<timestamp>.jsonl        # Pending edits (before submit)\n    <page_id>-<timestamp>.jsonl.submitted  # Marker file (after submit)\n  \n  # Changesets (restorable full-page versions)\n  changesets/<page_id>/\n    <page_id>-<timestamp>.md           # Changeset with YAML frontmatter\n```\n\nOverride the base directory with `SOLID_NOTION_HOME` environment variable.\n\n---\n\n## 5. Global Flags\n\n| Flag | Effect |\n|------|--------|\n| `-v, --verbose` | Print debug logs to stderr |\n| `-V, --version` | Print version |\n\n---\n\n## 6. Error Handling\n\n### init command error codes\n\n| Exit code | Error | Meaning |\n|-----------|-------|---------|\n| 2 | `missing_arguments` | No token provided |\n| 3 | `invalid_token` | Token is empty or invalid |\n| 4 | `token_already_exists` | Token exists, use `--force` |\n| 5 | `write_failed` | Could not write config file |\n\n### General errors\n\nAll other commands exit `1` on failure and print diagnostics to stderr including error name, message, metadata (status, code, errno, syscall, hostname), cause chain, and stack trace.\n\n---\n\n## 7. Anti-Patterns\n\n### Authentication\n- **Do NOT** use `--token <value>` in automated flows. Use `--token-stdin` to avoid leaking tokens in process lists.\n- **Do NOT** skip `solid-notion auth status --json` before running commands. If there is no token, all Notion API calls will fail.\n\n### Page IDs\n- **Do NOT** pass page names to `edit`, `write`, `submit`, `history`, or `restore`. These commands require strict page UUIDs.\n\n### Output parsing\n- **Do NOT** forget `--json` when you need to parse command output programmatically.\n\n### Submit command\n- **Do NOT** call `submit` without `-m`. The message flag is **required**.\n- **Do NOT** assume `submit` takes stdin — it reads from local `edit-logs/`, not from stdin.\n- **Do NOT** ignore `status: \"rolled_back\"` — this means Notion writes failed but were undone.\n- **Do NOT** ignore `status: \"failed_needs_reconcile\"` — this means both apply AND rollback failed.\n\n### Edit patch schema\n- **Do NOT** include extra keys in the patch object (only `ops` and `notes` allowed).\n- **Do NOT** forget the `reason` field in each op — it is required.\n- **Do NOT** use unsupported block types in `replace_block_text` or `append_blocks`.\n- **Do NOT** use `set_props` on properties with unsupported types (only: number, checkbox, select, multi_select, date, title, rich_text).\n- **Do NOT** pass Notion block objects as `new_markdown` — pass simple Markdown text (e.g., \"## Heading\" or \"Paragraph with **bold**\").\n","tags":{"latest":"0.1.1"},"stats":{"comments":0,"downloads":531,"installsAllTime":0,"installsCurrent":0,"stars":0,"versions":2},"createdAt":1772638020811,"updatedAt":1778491718264},"latestVersion":{"version":"0.1.1","createdAt":1772639647334,"changelog":"solid-notion 0.1.1 Changelog\n\n- Added clear instructions for obtaining a Notion API token by creating and configuring a Notion integration.\n- Expanded the authentication setup section to guide users through integration setup steps.\n- No other functional or command changes; documentation quality improved for onboarding.","license":null},"metadata":null,"owner":{"handle":"vincentdchan","userId":"s17bn7ghwrw4gcrm4sra4avqxd885gy8","displayName":"vincentdchan","image":"https://avatars.githubusercontent.com/u/2352832?v=4"},"moderation":null}