Token导航 LogoToken导航TokenDH.com
研究检索操作浏览器github未标认证来源可访问许可证需确认审计提醒

lark-suite云雀套房

Agent Skill

lark-suite 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

675

周安装

29

GitHub Stars

1

下载量

237
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:lark-suite(云雀套房)
来源仓库:https://github.com/verneagent/lark-suite
仓库路径:skills/lark-suite
安装命令:
npx skills add https://github.com/verneagent/lark-suite --skill lark-suite
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/verneagent/lark-suite --skill lark-suite

简介

lark-suite 用于查找、检索和筛选相关信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中根据关键词或任务场景快速定位候选结果。
  • 通过 npx skills add 命令从 verneagent/lark-suite 仓库安装,需确认权限和维护状态。
  • 使用前应核实是否会触发联网、命令执行或文件读写操作。
  • 建议结合原始 README 核验具体用法和功能边界。

SKILL.md

Read, create, and edit Lark wiki pages and documents using the Lark Open API.

Reading Wiki Documents

When reading a wiki document, prefer the block-based method (blocks) over the plain text method (read) unless the user explicitly asks for raw text. The block method preserves structure (headings, lists, tables, formatting) and is more useful for understanding and processing document content.

  • blocks (default): Returns structured JSON with block types, hierarchy, and formatting. Use this when you need to understand the document layout, extract specific sections, or work with structured content.
  • read: Returns flat plain text with no formatting. Use this only when the user explicitly asks for raw/plain text, or when you just need a quick text dump.

Workflow: Use read <node_token> first to resolve the obj_token (printed to stderr), then use blocks <obj_token> to get the structured content.

Note: The read command also works with obj_token directly (not just node_token). If you already have the obj_token, you can skip the read step and go straight to blocks <obj_token>.

Prerequisites

  • Config file: ~/.lark-suite/config.json with app_id and app_secret

- The skill still falls back to ~/.lark-wiki/config.json if the old path exists and the new one does not - If the file doesn't exist, run the init command to create it interactively (see below)

  • Required Lark app scopes: wiki:wiki, docx:document (for write operations)
  • The bot must have edit permission on the target wiki space
  • For browser-based commands (comment): set LARK_BASE env var to your organization's domain (e.g. https://yourcompany.larksuite.com)

CLI Helper

All operations are available via the helper script:

python3 .claude/skills/lark-suite/scripts/lark_suite.py <command> [args]

Important: All commands require network access, so use dangerouslyDisableSandbox: true for Bash calls.

Commands

Initialize credentials (first-time setup)

python3 .claude/skills/lark-suite/scripts/lark_suite.py init

Interactive prompt to create or update ~/.lark-suite/config.json. Run this when credentials are missing or need updating. Shows existing values (masked for secrets) and lets you keep or replace them.

Read a wiki page

python3 .claude/skills/lark-suite/scripts/lark_suite.py read <node_token>

Extract node_token from wiki URLs: https://...larksuite.com/wiki/<node_token>

Returns the plain text content of the page.

List child nodes

python3 .claude/skills/lark-suite/scripts/lark_suite.py list <node_token>

Returns JSON array of child nodes with node_token, title, obj_type, has_child.

Tree view (recursive)

python3 .claude/skills/lark-suite/scripts/lark_suite.py tree <node_token> [--depth N]

Prints an indented tree of all descendant nodes. Default depth: 3.

Create a wiki page

python3 .claude/skills/lark-suite/scripts/lark_suite.py create <parent_node_token> "<title>"

Creates a new empty docx page under the given parent. Returns the new node's tokens.

Read document blocks (structured)

python3 .claude/skills/lark-suite/scripts/lark_suite.py blocks <document_id>

Returns the full block tree as JSON. Use obj_token (not node_token) as the document ID.

Write blocks to a document

python3 .claude/skills/lark-suite/scripts/lark_suite.py write <document_id> '<blocks_json>' [--index N]

Write blocks to a document. Accepts a JSON string or file path. Index -1 = append (default).

Add a comment

python3 .claude/skills/lark-suite/scripts/lark_suite.py comment <document_id> "<text>"

Adds a global (whole-document) comment. The Lark Open API only supports global comments for docx files — inline comments anchored to specific text selections require browser automation (see below).

Browser-Based Commands (Playwright)

For operations the Lark API doesn't support (like inline comments), a separate Playwright-based script is available. Requires a one-time manual login.

Prerequisites:

  • pip3 install playwright && python3 -m playwright install chromium
  • Run login once to authenticate: browser opens, you log in manually, session is saved to ~/.playwright-lark-session

Login (one-time setup)

python3 .claude/skills/lark-suite/scripts/lark_suite_browser.py login

Opens a headed browser to the Lark login page. Log in manually, then Ctrl+C. Session persists across runs.

Add inline comment

python3 .claude/skills/lark-suite/scripts/lark_suite_browser.py inline-comment <node_token_or_url> --search '<text_to_select>' --comment '<comment_text>'

Selects the specified text in the document and adds an inline comment anchored to it. Runs in headed mode by default (Lark's toolbar doesn't render in headless). Add --headless to attempt headless mode (less reliable).

Extract highlighted text

python3 .claude/skills/lark-suite/scripts/lark_suite_browser.py highlights <node_token_or_obj_token>

Uses the API (no browser needed) to find all text with background_color set. Returns JSON with text, color code, and color name.

Screenshot a document

python3 .claude/skills/lark-suite/scripts/lark_suite_browser.py screenshot <node_token_or_url> [-o output.png] [--full-page]

Takes a screenshot of a Lark document (headless). Useful for visual inspection.

Contact Commands

Look up user IDs by email

python3 .claude/skills/lark-suite/scripts/lark_suite.py contact-lookup user@example.com [user2@example.com ...]

Returns open_id for each email. Useful for permission management (perm-add needs open_id).

Permission Commands

Add a collaborator

python3 .claude/skills/lark-suite/scripts/lark_suite.py perm-add <token> <member_open_id> [--file-type docx] [--perm edit]
  • token: Document/file obj_token
  • member_open_id: User's open_id (from contact-lookup)
  • --file-type: docx, sheet, bitable, doc, slide (default: docx)
  • --perm: view, edit, full_access (default: edit)

List collaborators

python3 .claude/skills/lark-suite/scripts/lark_suite.py perm-list <token> [--file-type docx]

Document Search

Search documents globally

python3 .claude/skills/lark-suite/scripts/lark_suite.py doc-search "<query>" [--count 20] [--doc-types docx,sheet,bitable]
  • --doc-types: Comma-separated filter — doc, docx, sheet, bitable, slide, wiki
  • Returns: title, token, type, URL, owner

Block Type Reference

Creatable via API

TypeKeyExample
2text{"block_type": 2, "text": {"elements": [{"text_run": {"content": "Hello", "text_element_style": {}}}], "style": {}}}
3-11heading1-heading9Same structure as text, with headingN key
12bulletUnordered list item. Requires "style": {"align": 1, "folded": false}
13orderedOrdered list item. Same style requirement as bullet
14codeCode block. "style": {"language": 12} (12=JS, 1=Python, etc.)
15quoteQuote block
17todoCheckbox. "style": {"done": false, "align": 1, "folded": false}
19callout{"block_type": 19, "callout": {"emoji_id": "thumbsup", "background_color": 2}}
22divider{"block_type": 22, "divider": {}}
24gridColumn layout. {"block_type": 24, "grid": {"column_size": 2}}
26iframeEmbed. {"block_type": 26, "iframe": {"component": {"iframe_type": 1, "url": "..."}}}
31table{"block_type": 31, "table": {"property": {"column_size": 2, "row_size": 2}}}cells are always empty on creation; populate each cell separately (see "Tables in Documents")
34quote_containerQuote wrapper container

NOT Creatable via API

TypeBlockNotes
16EquationExplicitly excluded from create API
21Diagram / Flowchart / Mind Map / UML"block not support to create"
27ImageRequires separate upload flow, then reference token
23FileRequires separate upload flow
41Synced Block"block not support to create"
999Sub-doc"block not support to create"

Board blocks (type 43)

Board blocks (whiteboard/画板) CAN be created via the docx API:

{"block_type": 43, "board": {}}

The response includes a board.token for use with the Board API (board/v1). This is distinct from type 21 (diagram blocks) which cannot be created.

Rich Text Elements

Text elements within blocks support these styles in text_element_style:

  • bold: boolean
  • italic: boolean
  • underline: boolean
  • strikethrough: boolean
  • inline_code: boolean
  • background_color: int (only present when set) — text highlight color. Values: 1=light grey, 2=light purple, 3=yellow, 4=light green, 5=pink, etc.
  • comment_ids: string[] (only present when set) — IDs of inline comments anchored to this text. Read-only.

Example with mixed formatting:

{
  "elements": [
    {"text_run": {"content": "Normal ", "text_element_style": {}}},
    {"text_run": {"content": "bold", "text_element_style": {"bold": true}}},
    {"text_run": {"content": " and ", "text_element_style": {}}},
    {"text_run": {"content": "italic", "text_element_style": {"italic": true}}}
  ]
}

URL → Token Extraction

Wiki URL format: https://{domain}.larksuite.com/wiki/{node_token}

The node_token is the path segment after /wiki/. To get the document_id (obj_token) needed for block operations, use the read or list command which resolves it automatically, or call:

# Manual resolution
python3 -c "
import sys; sys.path.insert(0, '.claude/skills/lark-suite/scripts')
from lark_auth import LarkAuth
import json, urllib.request
t = LarkAuth('~/.lark-suite/config.json').get_token()
r = urllib.request.urlopen(urllib.request.Request(
    'https://open.larksuite.com/open-apis/wiki/v2/spaces/get_node?token=NODE_TOKEN',
    headers={'Authorization': f'Bearer {t}'}))
print(json.loads(r.read())['data']['node']['obj_token'])
"

Bitable (Base) Commands

List tables

python3 .claude/skills/lark-suite/scripts/lark_suite.py base-tables <app_token>

List fields in a table

python3 .claude/skills/lark-suite/scripts/lark_suite.py base-fields <app_token> <table_id>

List/search records

python3 .claude/skills/lark-suite/scripts/lark_suite.py base-records <app_token> <table_id> [--filter '<json>']

Filter format (Lark filter syntax):

{"conjunction": "and", "conditions": [{"field_name": "Status", "operator": "is", "value": ["Done"]}]}

Add a record

python3 .claude/skills/lark-suite/scripts/lark_suite.py base-add <app_token> <table_id> '{"Feature": "New item", "Status": "Backlog"}'

Update a record

python3 .claude/skills/lark-suite/scripts/lark_suite.py base-update <app_token> <table_id> <record_id> '{"Status": "Done"}'

Create a table

python3 .claude/skills/lark-suite/scripts/lark_suite.py base-create-table <app_token> '<table_json>'

Table JSON example:

{"name": "Tasks", "default_view_name": "All", "fields": [
  {"field_name": "Title", "type": 1},
  {"field_name": "Status", "type": 3, "property": {"options": [{"name": "Todo"}, {"name": "Done"}]}},
  {"field_name": "Priority", "type": 2}
]}

Bitable Field Types

TypeNameNotes
1TextMulti-line text
2Number
3SingleSelectWith property.options
4MultiSelectWith property.options
5DateTimeWith property.date_formatter
7Checkboxtrue/false
11User/PersonUses open_id
13Phone
15URL/Hyperlink
17AttachmentNeeds file upload
1001CreatedTimeAuto-filled
1002ModifiedTimeAuto-filled

Bitable Patterns & Gotchas

Accessing embedded bitables (bitable tabs within spreadsheets)

Spreadsheets can contain bitable-type tabs. These are NOT accessible via the regular Sheet Values API or directly via the Bitable API using the spreadsheet token. To access them:

  1. Call the v2 metainfo endpoint: GET /sheets/v2/spreadsheets/{spreadsheetToken}/metainfo
  2. Find the bitable tab — it has blockInfo.blockToken in format {app_token}_{table_id}
  3. Use the extracted app_token and table_id with standard Bitable API endpoints
# Example: extract app_token and table_id from blockToken
block_token = sheet["blockInfo"]["blockToken"]  # e.g. "Qnxmbq2euaQuI1sDOXVl5MGJg1d_tblcRkOGPnFoIr1Z"
app_token, table_id = block_token.rsplit("_", 1)

Text field conversion for batch_create

When reading records via records/search, text fields (type 1) return as rich text arrays:

[{"text": "Hello", "type": "text"}]

When writing via batch_create, text fields must be plain strings — passing the rich text array causes TextFieldConvFail. Convert first:

value = "".join(e.get("text", "") for e in field_value if isinstance(e, dict))

User field passthrough

User fields (type 11) can be written with the exact format returned by search:

[{"id": "ou_xxx", "name": "Wind2star", "email": "user@example.com"}]

Minimal format also works: [{"id": "ou_xxx"}]. Plain strings do NOT work (UserFieldConvFail).

View API limitations

The Bitable View API (PATCH /bitable/v1/apps/{app_token}/tables/{table_id}/views/{view_id}) only supports:

  • filter_info — filter conditions
  • hidden_fields — column visibility
  • hierarchy_config — parent-child nesting

NOT supported via API (UI only): Group By, Sort, Frozen columns.

SingleSelect filter values in views

View filter conditions for SingleSelect/MultiSelect fields require option IDs (not names):

# Get option IDs from the fields endpoint first
# Then use them in the filter, wrapped as a JSON string:
"value": json.dumps(["optZDvNgr8"])  # NOT ["P0"]

Option colors must be explicitly set

When creating bitable fields with select options (SingleSelect/MultiSelect), you must include the color property from the source. If omitted, the API assigns sequential defaults (0, 1, 2,...) which causes visual mismatch with the original.

# Include color when creating options
options = [{"name": opt["name"], "color": opt.get("color", 0)} for opt in source_options]

Use batch_create response for record ID mapping

When copying records between tables, use the batch_create response to build old→new record ID mappings directly. Do NOT re-read records by index — leftover or deleted records can shift the order and break parent-child relationships.

resp = batch_create(app_token, table_id, records_batch)
# resp["data"]["records"] contains new records in the same order as input
for old_rec, new_rec in zip(source_batch, resp["data"]["records"]):
    id_map[old_rec["record_id"]] = new_rec["record_id"]

New bitables have 10 pre-created sample records

When creating a bitable via the wiki API (obj_type: "bitable"), it comes with 10 empty sample records. Delete them before or after copying data to avoid count mismatches:

# Find and delete empty records
empty = [r['record_id'] for r in records if not any(
    v for v in r.get('fields', {}).values() if v is not None and v != '' and v != []
)]
if empty:
    api('POST', f'/bitable/v1/apps/{app}/tables/{table}/records/batch_delete', {'records': empty})

Link field write format differs from read format

  • Read format: {"link_record_ids": ["recXXX"]} (returned by search/get)
  • Write format: ["recXXX"] (plain list of record IDs)

Writing {"link_record_ids": [...]} causes LinkFieldConvFail.

Field rename (PUT) requires type in body

When renaming a field via PUT, you must include the type parameter — not just field_name:

# Wrong: {"field_name": "New Name"}  → 400 "type is required"
# Correct:
api('PUT', f'/bitable/.../fields/{field_id}', {"field_name": "New Name", "type": 1})

Pagination is REQUIRED for querying records

When querying Bitable records via base-records or raw API calls, always implement pagination. The API returns results in pages — if you don't handle page_token, you'll only get the first page and miss remaining records.

The problem:

# ❌ WRONG — only gets first 100 records, misses the rest
records_req = urllib.request.Request(
    f'https://open.larksuite.com/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records?page_size=100',
    headers={'Authorization': f'Bearer {tenant_token}'}
)
with urllib.request.urlopen(records_req) as resp:
    records = json.loads(resp.read())['data']['items']  # Only page 1!

Even if the response shows "total": 302, you only got the first page.

The solution:

# ✅ CORRECT — fetches all pages
all_records = []
page_token = None

while True:
    url = f'https://open.larksuite.com/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records?page_size=100'
    if page_token:
        url += f'&page_token={page_token}'

    with urllib.request.urlopen(...) as resp:
        data = json.loads(resp.read())['data']
        all_records.extend(data['items'])

        if not data.get('has_more', False):
            break
        page_token = data.get('page_token')

Key checklist:

  • Always check has_more in the response
  • Use page_token from the response (not request parameters) to fetch the next page
  • Stop when has_more is false or missing
  • Same rule applies to: records, tables, views, fields — any list-type endpoint

Board API (画板/Whiteboard)

The Board API (board/v1) manages content on whiteboard canvases. Boards are created as document blocks (type 43), then their content is managed via the Board API.

Creating a board

No standalone "create board" endpoint exists. Instead, create a board block inside a document:

# Creates board block — extract board.token from the response
resp = api('POST', f'/docx/v1/documents/{doc_id}/blocks/{parent_block_id}/children',
    {"children": [{"block_type": 43, "board": {}}], "index": -1})
# Response data.children contains FULL block objects, not just IDs
board_token = resp["data"]["children"][0]["board"]["token"]

Node creation format

api('POST', f'/board/v1/whiteboards/{board_token}/nodes', {"nodes": [
    {
        "type": "composite_shape",  # Node type
        "x": 100.0, "y": 100.0,    # Position (floats)
        "width": 200.0, "height": 80.0,  # Dimensions
        "composite_shape": {"type": "round_rect"},  # Shape subtype
        "text": {  # Text content (top-level, NOT inside shape)
            "text": "Hello",
            "font_size": 14,
            "horizontal_align": "center",
            "vertical_align": "mid"
        },
        "style": {  # Visual styling
            "fill_color": "#4A90D9",
            "fill_opacity": 100,  # 0-100 integer
            "border_style": "solid",  # "solid" | "none"
            "border_width": "medium",  # "medium" | "bold"
            "border_color": "#2D6CB4"
        }
    }
]})

Connector format

Connectors use start/end with attached_object and relative position (0.0-1.0 within the target shape):

{
    "type": "connector",
    "connector": {
        "start": {"attached_object": {"id": "o2:1", "position": {"x": 0.5, "y": 1.0}}},
        "end": {"attached_object": {"id": "o2:2", "position": {"x": 0.5, "y": 0.0}}}
    }
}

Free-floating connectors (no attachment) use position only:

{"start": {"position": {"x": 100.0, "y": 200.0}}, "end": {"position": {"x": 300.0, "y": 200.0}}}

Do NOT use start_object/end_object at the connector level (error: "connector info empty"). arrow_style and shape fields cause field validation errors.

Composite shape subtypes (confirmed working)

rect, round_rect, diamond, ellipse

PlantUML / Mermaid diagrams

Generate diagrams from code using the create_plantuml endpoint:

api('POST', f'/board/v1/whiteboards/{board_token}/nodes/plantuml', {
    "plant_uml_code": code_string,
    "syntax_type": 2,    # 1=PlantUML, 2=Mermaid
    "diagram_type": 1    # 1=flowchart, 4=sequence (and others)
})
  • Returns ids: [] (empty) on success — this is normal behavior
  • Handles all layout, shapes, connectors, and styling automatically
  • Mermaid is recommended — works reliably on new boards
  • PlantUML rendering bug: New boards with ONLY PlantUML content show "Nothing on the board yet" in the doc preview, despite data being present (list/download APIs work). Workaround: add a dummy composite_shape node first to initialize the board renderer, or use Mermaid instead
  • Cannot delete document blocks via API — no delete endpoint for docx blocks

Known limitations

  • Append-only: Can create and list nodes, but no update or delete endpoints
  • Doc block deletion: Use DELETE.../blocks/{parent_id}/children/batch_delete with {"start_index": N, "end_index": M} (see below)
  • sticky_note type: Returns error 4003101 despite being in the SDK types
  • Connector styling: arrow_style and shape fields cause validation errors
  • Images: Require pre-upload via Drive API (image token reference)
  • List nodes: GET.../nodes may return empty for boards with content (inconsistent)

Deleting boards from documents

While board nodes cannot be deleted, entire board blocks can be removed from a document using the docx batch delete API:

# Delete blocks at indices start_index..end_index-1 (0-based) under the parent block
api('DELETE', f'/docx/v1/documents/{doc_id}/blocks/{parent_block_id}/children/batch_delete',
    {"start_index": 4, "end_index": 6})  # Deletes children at indices 4 and 5

First list blocks to find indices, then delete. Careful: indices shift after each delete.

Other endpoints

  • GET /board/v1/whiteboards/{token}/download_as_image — export as JPEG
  • GET/POST /board/v1/whiteboards/{token}/theme — get/set board theme
  • POST /board/v1/whiteboards/{token}/nodes/plantuml — create from PlantUML/Mermaid code
  • GET /board/v1/whiteboards/{token}/nodes — list all nodes

Tables in Documents

Create tables using block type 31. CRITICAL: The cells parameter in the creation request is ignored — the API always creates empty cells. You must populate each cell individually as a separate step.

# 1. Create the table block — API auto-creates EMPTY cells
# Do NOT pass "cells" with content strings — they are ignored
resp = api('POST', f'/docx/v1/documents/{doc_id}/blocks/{parent_block_id}/children', {
    "children": [{"block_type": 31, "table": {"property": {"row_size": 4, "column_size": 3}}}],
    "index": -1
})
# Response contains cell block IDs in table.cells[] (flat list, row-major order)
cells = resp['data']['children'][0]['table']['cells']
# cells = [row0col0_id, row0col1_id, row0col2_id, row1col0_id, ...]

# 2. Populate EACH cell by inserting a text block as its child
for cell_id, content in zip(cells, ["H1", "H2", "H3", "R1C1", "R1C2", "R1C3", ...]):
    api('POST', f'/docx/v1/documents/{doc_id}/blocks/{cell_id}/children', {
        "children": [{"block_type": 2, "text": {
            "elements": [{"text_run": {"content": content, "text_element_style": {}}}],
            "style": {"align": 1, "folded": False}
        }}],
        "index": 0
    })

Gotchas:

  • Each cell requires a separate API call — for large tables, add time.sleep(0.5) every ~10 calls to avoid 429 rate limits
  • Cell IDs are in flat row-major order: [r0c0, r0c1,..., r1c0, r1c1,...]
  • To make header cells bold, set "bold": True in text_element_style for the first column_size cells
  • Reading existing tables: use blocks command to get the document block tree, find type-31 blocks, extract table.cells[] for cell IDs

Column widths

Set column_width during table creation (in property). It cannot be updated after creation via PATCH — update_table_property.column_width returns "field is invalid".

# Set widths during creation (list of pixel values, one per column)
api('POST', f'/docx/v1/documents/{doc_id}/blocks/{parent_id}/children', {
    "children": [{"block_type": 31, "table": {"property": {
        "row_size": 3, "column_size": 2,
        "column_width": [200, 500]  # pixels, must match column_size
    }}}],
    "index": -1
})

If you need to change widths on an existing table, you must delete it and recreate it at the same index.

Tables also support merge_info (for merged cells).

Comments

Read comments

GET /drive/v1/files/{document_id}/comments?file_type=docx&page_size=50

Returns all comments (both whole-document and inline). Each has comment_id, is_whole, quote, is_solved, reply_list.

Create whole-document comment

POST /drive/v1/files/{document_id}/comments?file_type=docx
Body: {"reply_list": {"replies": [{"content": {"elements": [{"type": "text_run", "text_run": {"text": "..."}}]}}]}}

Reply to a comment

POST /drive/v1/files/{document_id}/comments/{comment_id}/replies?file_type=docx
Body: {"content": {"elements": [{"type": "text_run", "text_run": {"text": "..."}}]}}

Resolve/unresolve a comment

PATCH /drive/v1/files/{document_id}/comments/{comment_id}?file_type=docx
Body: {"is_solved": true}

Inline comment limitations

  • Creating inline (anchored) comments is NOT possible via API — the endpoint only creates whole-document comments
  • is_whole and quote are response-only fields, not settable inputs
  • comment_ids in text_element_style is read-only (cannot be set via block PATCH)
  • Reading inline comments (created via UI) works fine — they have is_whole: false and quote

Slides API

The Slides API is very limited:

# Create empty presentation
api('POST', '/slides/v1/presentations', {"title": "My Slides"})

# Read presentation metadata (slide IDs, layouts, masters, page size)
api('GET', f'/slides/v1/presentations/{token}')

# Update title only (requires client_token as query param)
api('PATCH', f'/slides/v1/presentations/{token}?client_token={uuid}', {"title": "New Title"})

Limitations:

  • Cannot read slide page content (elements, shapes, text) — only metadata
  • Cannot create/add new slide pages — all formats return "param is invalid" (3130001)
  • Cannot modify slide content — no known endpoint
  • Not in any official SDK (Go, Node, Python)
  • Scopes exist: slides:presentation:read, slides:presentation:create, slides:presentation:update, slides:presentation:write_only

Required Lark App Scopes

ScopeOperations
(default)Read wiki nodes, read document content, read blocks
wiki:wikiCreate wiki nodes
docx:documentWrite document blocks (including board blocks)
bitable:appAll bitable operations (tables, fields, records)
board:whiteboard:node:readList board nodes, download board as image
board:whiteboard:node:createCreate nodes on boards
drive:driveDelete documents (not fully working yet)
drive:drive:permission:memberAdd/list document collaborators
contact:user.id:readonlyLook up user IDs by email
search:docsSearch documents globally
slides:presentation:readRead slides metadata
slides:presentation:createCreate empty presentations
slides:presentation:updateUpdate presentation title

The bot also needs edit permission on the wiki space (added via wiki space settings → Members).

Troubleshooting

Wiki Document Write Returns 1770032 forBidden

Symptom: App has docx:document scope and can read wiki documents, but POST /docx/v1/documents/{doc_id}/blocks/{doc_id}/children returns {"code": 1770032, "msg": "forBidden"}. Creating wiki nodes returns 131006 "tenant needs edit permission".

Root cause: Having the docx:document scope gives the app the *capability* to edit docs, but the app's tenant_access_token also needs document-level or wiki-space-level edit permission. Two conditions must be met:

  1. The app must be added to the document/wiki-space's "Application" section with editable access
  2. Only the app's Creator/Owner can effectively grant this — if a non-owner adds the app, the association is created but the tenant_access_token does not actually receive edit permission

Fix: Have the app's Creator (visible in Lark developer console → app card) add the app to the wiki space or document's "Application" section with edit access. Non-creators adding the app will not work.

Alternative: Use user_access_token instead of tenant_access_token — this inherits the user's own document permissions, bypassing the app-level authorization requirement.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

35.17%
按下载量换算83

Claude

30.5%
按下载量换算72

Cursor

21.16%
按下载量换算50

Gemini CLI

9.33%
按下载量换算22

安全审计

Gen Agent Trust Hub

可疑

Socket

通过

Snyk

可疑

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills