zhuyuanbin.gdut 6ac31eae87 feat(slides): lint slide writes server-side, add --no-lint to opt out
+create, +add-slide, +update-slide and +replace-slide are the four
shortcuts that change slide content, so they are the four that can ask
the backend to check the page before accepting the write. All four now
send lint_xml=true by default and lint_xml=false when --no-lint is
passed. The subject of the check is the page the write produces, not the
payload it was handed: +replace-slide submits fragments, and a fragment
that is correct on its own can still push a neighbour off the canvas.

The switch travels in the request body rather than the query string. A
query parameter has to be declared in the gateway's own api meta before
it is bound to a field, and the published definition of these endpoints
does not list one — so an undeclared parameter is dropped, the field
arrives unset, and the server reads it as "not requested". Verified
against a live backend: pages that asked to be linted were written
unlinted, with nothing anywhere to say so. Body fields ride along with
the JSON already being sent and need no registration.

The value is sent explicitly in both directions rather than omitted when
on. The parameter is newer than the registry, so the server-side default
is not something this CLI can read anywhere, and a request that states
the value keeps meaning the same thing if that default ever moves.

A refusal is passed through verbatim. The message field carries the lint
report itself — the same document the lint tool writes when it is run by
hand — and the same refusal reaches callers through `lark-cli api` as
well, where nothing rewrites it. Rendering it to prose here would give
one refusal two formats depending on which command produced it. Each
finding carries the numbers behind its own rule, and which numbers those
are differs per rule, so nothing is decoded that is not used: the report
is what the caller reads.

The refusal is recognised by its error code, 4000153, which the engine
raises for nothing else and which reaches the CLI unchanged. Matching on
the shape of the message instead would mean claiming any JSON that
resembles a report, and a false positive there rewrites the hint of an
error this code does not understand.

What the backend cannot say goes in the hint instead: how many findings
refused the write, that the page did not land, and --no-lint, which is a
CLI flag the server has never heard of. The count is summary.error_count
rather than the number of findings, because errors are what refuse a
page — the same line the lint tool draws when it is run by hand, exiting
non-zero on error_count alone. A report can arrive with warnings beside
its errors, and counting those too would send the caller hunting for
blockers that are not there. A message that does not parse still gets
the hint: the escape hatch is the half of it they cannot get anywhere
else, and withholding it over a missing number helps nobody.

The hint names no page. Every write path submits exactly one page, so a
finding's slide_number is its position inside that submission and is
always 1 — which is not the page the caller is looking for. On +create
it is actively wrong: it would read "on slide 1" next to a progress line
saying "adding slide 2/3 failed". The page number has one source, and it
is that line.

Findings that did not refuse the write come back the other way. The
backend returns them in an issues field on a response that succeeded, and
all four shortcuts now pass that field through untouched rather than
dropping it. It only ever arrives on a page that was written: anything
serious enough to refuse the write left as the error above, carrying the
same report. Dropping it would leave the caller believing the deck says
exactly what they wrote, with no way to learn otherwise short of looking
at the rendered page. It is passed through rather than reformatted so
that one field reads the same however the page was written.

The reference docs say which of the two a caller is holding. A refusal is
4000153 and the page is not there; an issues field means the page is
there and the backend still had something to say about it. Both carry the
same report, so the docs describe the shape once and link to it from each
command.

+create keeps adding its pages one at a time, so a refusal there can
arrive with the presentation and some of its pages already written. It
is reported as such: the error carries the lint report and, next to it,
which page was refused and how many landed before it, so the retry adds
the rest instead of building a second deck. +replace-pages does the same
for the items in its plan.

A batch that was told to keep going reports its failures only through the
per-item records, so those carry the report, the code and the flag hint
as well; a record built from the error's message alone would have named
neither the refusal nor the way past it. The position stays on the
returning path, where it is the only thing that says how far the batch
got — beside a per-item record it would describe a batch that did not
stop.

Tests assert on the wire — the body the stub actually received — rather
than on the builder's return value, so a command that stops calling its
own builder still fails.
2026-09-02 19:19:18 +08:00
2026-08-28 18:47:32 +08:00
2026-08-28 18:47:32 +08:00

lark-cli

License: MIT Go Version npm version

中文版 | English

The official Lark/Feishu CLI tool, maintained by the larksuite team — built for humans and AI Agents. Covers core business domains including Messenger, Docs, Base, Sheets, Slides, Calendar, Mail, Tasks, Meetings, Markdown, and more, with 200+ commands and 26 AI Agent Skills.

Install · AI Agent Skills · Auth · Commands · Advanced · Enterprise · Security · Contributing

Why lark-cli?

  • Agent-Native Design — 24 structured Skills out of the box, compatible with popular AI tools — Agents can operate Lark with zero extra setup
  • Wide Coverage — 18 business domains, 200+ curated commands, 26 AI Agent Skills
  • AI-Friendly & Optimized — Every command is tested with real Agents, featuring concise parameters, smart defaults, and structured output to maximize Agent call success rates
  • Open Source, Zero Barriers — MIT license, ready to use, just npm install
  • Up and Running in 3 Minutes — One-click app creation, interactive login, from install to first API call in just 3 steps
  • Secure & Controllable — Input injection protection, terminal output sanitization, OS-native keychain credential storage
  • Three-Layer Architecture — Shortcuts (human & AI friendly) → API Commands (platform-synced) → Raw API (full coverage), choose the right granularity

Personal or Enterprise?

You are... Recommended path
An individual developer — using lark-cli in your terminal or with your own AI Agent Follow the Quick Start below
Enterprise IT / ISV — embedding lark-cli into your own Agent or platform, with centralized credentials (database / Vault / config center), unified audit logging, and a restricted command surface Read Embed lark-cli in your Agent and the extension/ packages — extend via a wrapper main, no need to modify CLI source

💡 For AI Agents: append .md to any Open Platform doc URL to fetch it as raw Markdown, e.g. embed-feishu-cli-in-agent.md.

Features

Category Capabilities
📅 Calendar View, create and update events, invite attendees, find meeting rooms, RSVP to invitations, check free/busy & time suggestions
💬 Messenger Send/reply messages, create and manage group chats, view chat history & threads, search messages, download media
📄 Docs Create, read, update, and search documents, read/write media & whiteboards
📁 Drive Upload and download files, search docs & wiki, manage comments
📝 Markdown Create, fetch, patch, and overwrite Drive-native .md files
📊 Base Create and manage tables, fields, records, views, dashboards, workflows, forms, roles & permissions, data aggregation & analytics
📈 Sheets Create, read, write, append, find, and export spreadsheet data
🖼️ Slides Create and manage presentations, read presentation content, and add or remove slides
✅ Tasks Create, query, update, and complete tasks; manage task lists, subtasks, comments & reminders
📚 Wiki Create and manage knowledge spaces, nodes, and documents
👤 Contact Search users by name/email/phone, get user profiles
📧 Mail Browse, search, read emails, send, reply, forward, manage drafts, watch new mail
🎥 Meetings Search live and historical meetings, inspect participants and artifacts, analyze transcripts, manage Minutes, and assist in meetings
🕐 Attendance Query personal attendance check-in records
✍️ Approval Query approval tasks, approve/reject/transfer tasks, cancel and CC instances
🎯 OKR Query, create, update OKRs; manage objective & key results, alignments, indicators and progress.
📋 Project Meegle — manage work items, schedules, and data via the standalone meegle-cli (install separately)
🔗 Apps Create Spark/Miaoda apps, publish HTML/static sites, run cloud generation, and manage access scope

Installation & Quick Start

Requirements

Before you start, make sure you have:

  • Node.js (npm/npx)
  • Go v1.23+ and Python 3 (only required for building from source)

Quick Start (Human Users)

Note for AI assistants: If you are an AI Agent helping the user with installation, jump directly to Quick Start (AI Agent), which contains all the steps you need to complete.

Install

Choose one of the following methods:

Option 1 — From npm (recommended):

npx @larksuite/cli@latest install

Option 2 — From source:

Requires Go v1.23+ and Python 3.

git clone https://github.com/larksuite/cli.git
cd cli
make install

# Install CLI SKILL (required)
npx skills add larksuite/cli -y -g

Configure & Use

# 1. Configure app credentials (one-time, interactive guided setup)
lark-cli config init

# 2. Log in (--recommend auto-selects commonly used scopes)
lark-cli auth login --recommend

# 3. Start using
lark-cli calendar +agenda

Quick Start (AI Agent)

The following steps are for AI Agents. Some steps require the user to complete actions in a browser.

Step 1 — Install

npx @larksuite/cli@latest install

Step 2 — Configure app credentials

Run this command in the background. It will output an authorization URL — extract it and send it to the user. The command exits automatically after the user completes the setup in the browser.

lark-cli config init --new

Step 3 — Login

Same as above: run in the background, extract the authorization URL and send it to the user.

lark-cli auth login --recommend

Step 4 — Verify

lark-cli auth status

Agent Skills

Skill Description
lark-shared App config, auth login, identity switching, scope management, security rules (auto-loaded by all other skills)
lark-calendar Calendar events (create/update), agenda view, free/busy queries, time suggestions, room finding, RSVP replies
lark-im Send/reply messages, group chat management, message search, upload/download images & files, reactions
lark-doc Create, read, update, search documents (Markdown-based)
lark-drive Upload, download files, manage permissions & comments
lark-markdown Create, fetch, patch, and overwrite Drive-native Markdown files
lark-sheets Create, read, write, append, find, export spreadsheets
lark-slides Create and manage presentations, read presentation content, and add or remove slides
lark-base Tables, fields, records, views, dashboards, data aggregation & analytics
lark-task Tasks, task lists, subtasks, reminders, member assignment
lark-mail Browse, search, read emails, send, reply, forward, draft management, watch new mail
lark-contact Search users by name/email/phone, get user profiles
lark-wiki Knowledge spaces, nodes, documents
lark-event Real-time event subscriptions (WebSocket), regex routing & agent-friendly format
lark-meeting Search live or historical meetings, inspect participants and artifacts, analyze transcripts, manage Minutes, and assist in meetings
lark-whiteboard Whiteboard/chart DSL rendering
lark-openapi-explorer Explore underlying APIs from official docs
lark-skill-maker Custom skill creation framework
lark-attendance Query personal attendance check-in records
lark-approval Query approval tasks, approve/reject/transfer tasks, cancel and CC instances
lark-workflow-meeting-summary Workflow: meeting minutes aggregation & structured report
lark-workflow-standup-report Workflow: agenda & todo summary
lark-okr Query, create, update OKRs; manage objective & key results, alignments and indicators.

Authentication

Command Description
auth login OAuth login with interactive selection or CLI flags for scopes
auth logout Sign out and remove stored credentials
auth status Show current login status and granted scopes
auth check Verify a specific scope (exit 0 = ok, 1 = missing)
auth scopes List all available scopes for the app
auth list List all authenticated users
# Interactive login (TUI guides domain and permission level selection)
lark-cli auth login

# Filter by domain
lark-cli auth login --domain calendar,task

# Recommended auto-approval scopes
lark-cli auth login --recommend

# Exact scope
lark-cli auth login --scope "calendar:calendar:read"

# Agent mode: return verification URL immediately, non-blocking
lark-cli auth login --domain calendar --no-wait
# Resume polling later
lark-cli auth login --device-code <DEVICE_CODE>

# Identity switching: execute commands as user or bot
lark-cli calendar +agenda --as user
lark-cli im +messages-send --as bot --chat-id "oc_xxx" --text "Hello"

Three-Layer Command System

The CLI provides three levels of granularity, covering everything from quick operations to fully custom API calls:

1. Shortcuts

Prefixed with +, designed to be friendly for both humans and AI, with smart defaults, table output, and dry-run previews.

lark-cli calendar +agenda
lark-cli im +messages-send --chat-id "oc_xxx" --text "Hello"
lark-cli docs +create --doc-format markdown --content $'<title>Weekly Report</title>\n# Progress\n- Completed feature X'

Run lark-cli <service> --help to see all shortcut commands.

2. API Commands

Auto-generated from Lark OAPI metadata, curated through evaluation and quality gates — 100+ commands mapped 1:1 to platform endpoints.

lark-cli calendar calendars list
lark-cli calendar events instance_view --params '{"calendar_id":"primary","start_time":"1700000000","end_time":"1700086400"}'

3. Raw API Calls

Call any Lark Open Platform endpoint directly, covering 2500+ APIs.

lark-cli api GET /open-apis/calendar/v4/calendars
lark-cli api POST /open-apis/im/v1/messages --params '{"receive_id_type":"chat_id"}' --data '{"receive_id":"oc_xxx","msg_type":"text","content":"{\"text\":\"Hello\"}"}'

Advanced Usage

Output Formats

--format json      # Full JSON response (default)
--format pretty    # Human-friendly formatted output
--format table     # Readable table
--format ndjson    # Newline-delimited JSON (for piping)
--format csv       # Comma-separated values

JSON Output Contract

With --format json (the default), success and error envelopes are distinct.

Success goes to stdout, exit code 0:

{ "ok": true, "identity": "user", "data": { "guid": "..." }, "meta": { "count": 1 } }

Errors go to stderr, non-zero exit code:

{ "ok": false, "identity": "user", "error": { "type": "api", "subtype": "...", "code": 99991679, "message": "...", "hint": "..." } }

To check whether a command succeeded, test ok == true (or the exit code) — not code == 0. Unlike raw OpenAPI responses ({"code": 0, "msg": "ok", ...}), the success envelope carries no code or msg field; code appears only inside error as the upstream OpenAPI code. See errs/ERROR_CONTRACT.md for the full error taxonomy.

Pagination

--page-all                  # Auto-paginate through all pages
--page-limit 5              # Max 5 pages
--page-delay 500            # 500ms between page requests

Dry Run

For commands that may have side effects, preview the request with --dry-run first:

lark-cli im +messages-send --chat-id oc_xxx --text "hello" --dry-run

Schema Introspection

Use schema to inspect any API method's parameters, request body, response structure, supported identities, and scopes:

lark-cli schema
lark-cli schema calendar.events.instance_view
lark-cli schema im.messages.delete

Security & Risk Warnings (Read Before Use)

This tool can be invoked by AI Agents to automate operations on the Lark/Feishu Open Platform, and carries inherent risks such as model hallucinations, unpredictable execution, and prompt injection. After you authorize Lark/Feishu permissions, the AI Agent will act under your user identity within the authorized scope, which may lead to high-risk consequences such as leakage of sensitive data or unauthorized operations. Please use with caution.

To reduce these risks, the tool enables default security protections at multiple layers. However, these risks still exist. We strongly recommend that you do not proactively modify any default security settings; once relevant restrictions are relaxed, the risks will increase significantly, and you will bear the consequences.

We recommend using the Lark/Feishu bot integrated with this tool as a private conversational assistant. Do not add it to group chats or allow other users to interact with it, to avoid abuse of permissions or data leakage.

To reduce the security risks associated with access token theft, the CLI sends a minimal set of risk-control signals with OpenAPI requests made to exact official Feishu/Lark HTTPS domains. These signals are used to help identify anomalous API activity. This protection is enabled by default. The information sent is limited to:

  • Operating system type: macOS, Windows, or Linux
  • Device hardware model: for example, Mac17,9

To disable this protection for the current workspace, run:

lark-cli config risk-control off

To enable this protection for the current workspace, run:

lark-cli config risk-control on

To restore the default policy for the current workspace, run:

lark-cli config risk-control default

Please fully understand all usage risks. By using this tool, you are deemed to voluntarily assume all related responsibilities.

Contributing

Community contributions are welcome! If you find a bug or have feature suggestions, please submit an Issue or Pull Request.

For major changes, we recommend discussing with us first via an Issue.

Before opening a PR, see AGENTS.md for the local build, test, and PR checklist used by contributors and AI agents.

License

This project is licensed under the MIT License. When running, it calls Lark/Feishu Open Platform APIs. To use these APIs, you must comply with the following agreements and privacy policies:

S
Description
lark-doc: 飞书云文档(Docx / Wiki)内容操作:读取、创建、编辑文档,插入或下载图片附件,以及操作思维笔记。用户提供文档 URL/token(包括 doubao.com 的 /docx/、/wiki/)时使用;按 URL 路径/token 而非域名路由。文档内嵌资源按读取参考中的统一规则分流。独立评论操作走…; lark-base: 飞书多维表格(Base)操作:建表、字段、记录、视图、统计、公式/lookup、表单、仪表盘、应用模式(BaseApp/AppMode 页面与组件)、Workspace 目录、workflow、角色权限、模板中心(多维表格模板分类/列表/搜索);遇到…; lark-shared: Use for lark-cli setup/auth tasks: auth login/status/logout, user vs bot identity, business-domain permissions (--domain, including all/docs/drive), missing…; lark-im: 飞书即时通讯:收发消息和管…
Readme MIT 239 MiB
Languages
Go 94.6%
JavaScript 2.5%
Python 2.2%
HTML 0.4%
Shell 0.3%