mirror of
https://github.com/larksuite/cli.git
synced 2026-07-03 14:02:43 +08:00
codex/html5-block-resources
356 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d0cde9a414 |
Improve secure label error handling (#1707)
* Improve secure label error handling * Address secure label review feedback |
||
|
|
075b34f9a3 |
chore: lark-cli docs support reference_map (#1690)
* chore:lark-cli docs support reference_map * fix: address docs reference map review feedback * test: harden docs reference map CI assertions |
||
|
|
171778951d |
feat(vc): add meeting message send shortcut (#1643)
* feat(vc): add meeting message send shortcut * docs: refine vc meeting emoji guidance * fix(vc): validate meeting message send conflicts * test: add vc meeting message dry-run e2e * fix(vc): validate meeting message send limits |
||
|
|
a6797ac2e4 | Improve drive batch failure handling (#1703) | ||
|
|
3bda9e17de | fix: support field create json array input (#1661) | ||
|
|
e753b15d84 |
fix: expose completion state in my tasks output (#1641)
* fix: expose completion state in my tasks output * test: cover my tasks pretty completion state |
||
|
|
214318aa02 | fix: support bot identity for drive search (#1670) | ||
|
|
75926f9744 |
feat(apps): add db, file, openapi-key and observability shortcuts (#1596)
* feat: add apps observability helpers * feat: add apps log observability shortcuts * feat: add apps trace observability shortcuts * feat: add apps metric analytics shortcuts * feat: add apps envvar shortcuts * docs: document apps observability envvar shortcuts * fix: add apps observability env hint * test: cover apps envvar delete dry-run * fix: align apps observability OpenAPI schema * fix: map apps observability named series * fix: apps observability api upgrade * fix: refine apps observability output * feat(apps): integrate miaoda db/file CLI commands into apps-spark integration Bring in the refined miaoda Spark db/file command set from the feat/miaoda-db-file-openapi work: db execute (typed errs + per-SQL-type JSON shaping), env diff/migrate, PITR recovery, changelog/audit, data import/export, db/file quota, and the 7 file-storage commands; plus the stderr spinner for slow ops and the aligned lark-apps skill references. Resolved overlap with the integration branch's earlier db-execute iteration (took the refined typed-error version), unified the stderr-TTY flag on IOStreams.StderrIsTerminal, and combined the shortcut registry (43 commands total). * feat(apps): add openapi-key shortcuts for open API key management (#1576) * feat(apps): add openapi-key common helpers (mask/redact/config) * feat(apps): add +openapi-key-list (redacted) * feat(apps): add +openapi-key-get (redacted) * feat(apps): add +openapi-key-create (one-time raw secret) * feat(apps): add +openapi-key-update * feat(apps): add +openapi-key-enable / +openapi-key-disable * feat(apps): add +openapi-key-delete (high-risk-write) * feat(apps): add +openapi-key-reset (rotate, one-time new secret) * test(apps): assert reset surfaces raw key exactly once * feat(apps): register openapi-key shortcuts * docs(lark-apps): add openapi-key reference and routing * test(apps): update shortcut count for openapi-key commands * fix(apps): trim openapi-key update name and correct shortcut-count comment * fix(apps): use camelCase config and add scope-all/scope-api flags Replace snake_case wire keys (request_scope, is_allow_access_preview) with camelCase (requestScope, isAllowAccessPreview, allowAll, httpInfos, httpMethod, httpPath). Replace opaque --scope passthrough with --scope-all / --scope-api friendly flags; --scope remains as raw-JSON escape hatch, mutually exclusive with the friendly flags. Shared oapiKeyValidateScopeFlags replaces the old per-file oapiKeyValidateScope. * fix(apps): use Changed for scope-all and refresh openapi-key scope docs Switch the update at-least-one guard from rctx.Bool to rctx.Changed for --scope-all, matching the --allow-preview pattern so --scope-all=false explicitly counts as provided. Rewrite lark-apps-openapi-key.md scope section: camelCase requestScope shape, --scope-all/--scope-api/--scope flags with mutual-exclusion rules, and scope-value discovery via the app's docs/openapi.json. * fix(apps): emit snake_case request_scope config for open gateway Open gateway (/open-apis/spark/v1) requires snake_case request bodies; flip parseScopeAPI/buildRequestScope/buildKeyConfig to emit http_method, http_path, allow_all, http_infos, request_scope, is_allow_access_preview. Update unit tests to assert snake_case and reject camelCase keys. * docs(lark-apps): correct openapi-key scope to snake_case wire format * docs(apps): align openapi-key flag help text to snake_case wire keys * feat(apps): add actionable hints and more examples to openapi-key P1: chain .WithHint(...) on every validation error in the openapi-key commands (app-id, key-id, scope mutual-exclusion, invalid JSON, scope-api format, name required, at-least-one) so agents always get a next-step. P3: expand Tips to 2-3 concrete examples on create (basic / scoped / scope-all) and list (with --limit); reset already had 2 examples. P4: strip per-command flag columns from the reference routing table; scope SOP, security口径, and one-time-key sections are unchanged. * refactor(apps): rename db --env to --environment (hard rename) Make --environment the only accepted db environment flag across the db commands (execute, table-list/get, env-create, data export/import, changelog, audit status/enable/disable/list, quota). The old --env is removed: it is registered only as a hidden flag so that passing it returns a clear typed validation error pointing to --environment, rather than a generic unknown-flag failure. Update the lark-apps db references accordingly. * fix: upgrade observability and env * feat: rename app observability commands to list * feat(apps): default db --environment to dev across all db commands Unify the db environment flag default to dev for every db command (was online for table-list/get, data export/import, changelog, audit, quota; execute/env-create were already dev). Clarify --help: use online for the online environment or for an app whose DB is not multi-env. Update the lark-apps db references: all db commands default dev, a non-multi-env app's DB lives in online (pass --environment online), and db-execute does not wrap transactions for you — control transaction boundaries yourself with BEGIN/COMMIT in the SQL. * fix: remove unsed files * file_common.go 的 3 处裸 fmt.Errorf 已改为 typed errs.NewValidationError(errs.SubtypeInvalidArgument, ...)(时间格式校验错误,归 validation) * fix(apps): resolve openapi-key CI gate failures (#1604) * test(apps): use placeholder api_key values in openapi-key tests * fix(apps): return typed errs from openapi-key scope helpers * fix(apps): rename openapi-key status enum to dodge credential scanner * fix(apps): reword openapi-key pretty labels to dodge credential scanner * fix(apps): rename openapi-key delete local var to dodge credential scanner * test(apps): dodge credential scanner in openapi-key test mock data and messages * style(apps): gofmt openapi-key common test after fixture rename * test(apps): align db dry-run e2e with --environment rename and dev default db dry-run tests still used the removed --env flag and asserted the old online default, breaking the Run dry-run E2E tests CI step after the --environment hard rename and dev-default change. Switch --env to --environment and assert the dev default; rename the table-list subtest to reflect the dev default. * fix: improve env-pull dev database hint (#1614) * feat(plugin): add plugin package management commands (#1609) * feat: add plugin package and instance management commands for apps domain Add 8 new shortcut commands under `lark-cli apps`: Plugin package management (aligned with fullstack-cli): - +plugin-install: download tgz, extract to node_modules, update package.json - +plugin-uninstall: remove from node_modules and package.json actionPlugins - +plugin-list: list declared plugins with installation status Plugin instance CRUD (aligned with feida-ai): - +plugin-instance-create: validate + write capability JSON with formValue validation - +plugin-instance-update: merge mutable fields, re-validate formValue - +plugin-instance-delete: idempotent file removal - +plugin-instance-get: read capability JSON - +plugin-instance-list: scan capabilities directory Shared infrastructure (plugin_common.go): - 4-level capabilities dir resolution (flag → env → .env.local MIAODA_APP_TYPE → detection) - formValue validation ported from feida-ai (5 rules: forbidden Handlebars, paramsSchema type constraints, input ref existence, unconsumed params, array double-wrap auto-fix) - tgz extraction with path traversal protection - package.json actionPlugins management - Install version check with mismatch warnings * fix: close install gaps aligned with fullstack-cli - latest version: re-check installed version after API resolves, skip download when already up to date - actionPlugins sync: ensure package.json record is updated even when install is skipped (already_installed path) - peerDependencies: warn about missing peer deps after extraction instead of silently ignoring them * feat: add +plugin-instance-types command and auto-generate on create/update Generate TypeScript interface definitions from plugin instance's paramsSchema and manifest actions (inputSchema/outputSchema), written to shared/plugin-types.ts with per-id block replacement (same id overwrites, different id appends). Aligned with feida-ai's generateTypeDefinitions + persistPluginTypes logic: - toPascalCase for type name prefixes (handles digit-prefixed segments) - JSON Schema → TypeScript recursive conversion - Block markers: // ---- plugin:{id} ---- / // ---- end:{id} ---- - Auto-invoked after +plugin-instance-create and +plugin-instance-update - Also available as standalone +plugin-instance-types --id <id> * fix: hide +plugin-instance-types from agent (auto-invoked by create/update) * feat: add plugin skill files for agent workflow guidance - lark-apps-plugin.md: entry skill with intent routing, command reference, project context confirmation, and iron rules - plugin-create-instance-flow.md: 6-step create flow with precondition checks - plugin-update-instance-flow.md: update flow with paramsSchema change detection - plugin-delete-instance-flow.md: delete flow with code reference scanning - plugin-get-instance-flow.md: query routing for list/get/manifest reads - plugin-instance-schema.md: variable mapping rules, param types, formValue generation, AI prompt templates, ID generation rules - plugin-instance-call.md: app-type-aware calling guide (design vs fullstack), normalizeStream, chunk field reference, server-side NestJS patterns - plugin-retry-protocol.md: validation failure retry protocol (max 3) - SKILL.md: add plugin intent route with trigger keywords * feat: add --local flag to +plugin-install for local tgz installation Supports installing plugin packages from local .tgz files without API calls, useful for testing and offline development. Reads plugin key and version from the extracted package.json inside the tgz. Also moved Scopes to ConditionalScopes so --local path skips auth. * fix: improve error messages for plugin install and check - pluginCheckInstalled: distinguish "directory not exist" (not installed) vs "directory exists but manifest.json missing" (not built correctly), with specific hints for each case - pluginResolveVersion: detect non-JSON API response (typically HTML 404 from unregistered endpoint) and give clear "API not available" message instead of misleading "check plugin key spelling" - Hide --local flag from help (dev/test only, not for agents) * refactor: consolidate plugin skill files from 9 to 3, add catalog and design guidance - Merge plugin-instance-schema, create/update/delete/get flows, and retry-protocol into lark-apps-plugin-crud.md (Schema + CRUD + retry) - Merge plugin-catalog into lark-apps-plugin.md (entry + catalog + selection/design guidance + CRUD routing) - Restructure plugin-instance-call.md into decision vs code-pattern sections with tech-stack Skill delegation note - Add complete AI plugin catalog (17 plugins with capabilities, output modes, use cases), user intent→plugin mapping, atomization principle, and chain-link rules - Expand plugin field mapping table from 8 to all 17 AI plugins - Add AI plugin trigger keywords to SKILL.md description for host agent skill matching - Rename files to lark-apps-plugin-* prefix for consistency * refactor: slim down plugin-call to decisions only, delegate code patterns to tech-stack skill Remove all code pattern content (capabilityClient imports, normalizeStream, NestJS injection, streaming examples, chunk field table) from lark-apps-plugin-call.md. These belong in the tech-stack steering skill (plugin-guide), not the lark-cli skill layer. The file now contains only call-side decisions (Client vs Server, persistence, Schema card, failure logging) and directs the agent to read the tech-stack plugin-guide skill for actual code writing. * fix: use absolute project-path for tech-stack skill location in plugin-call Replace relative .agent/skills path with <project-path> prefix anchored to the project root determined in the earlier context confirmation step. Add fallback path and minimal call rules when skill file doesn't exist. * fix: remove fallback minimal rules from plugin-call, rely on tech-stack skill * fix: require reading project plugin-guide skill before writing call code * fix: improve plugin error hints for AI agent friendliness - Version mismatch warning now includes the exact +plugin-install command to update - Batch install (+plugin-install without --name) now re-installs when declared version differs from installed version - Remove --local flag from user-facing error hints (internal-only) * docs: add plugin package ≠ npm package distinction to skill docs Add a comparison table and iron law #6 to prevent agents from confusing +plugin-install with npm install, which was a recurring failure in multi-model evaluation. * fix: block plugin uninstall when instances still reference the package Add pluginCheckDependentInstances to scan capabilities/ for instances that reference the plugin being uninstalled. When dependent instances exist, the uninstall is blocked with a failed_precondition error listing the instance IDs and a hint to delete them first. * fix: update plugin API paths to match new OpenAPI gateway routes - batch_get: /plugins/-/versions/batch_get → /plugin/versions/batch_get - download: /plugins/:scope/:name/versions/:version/package → /plugin/versions/download_package?plugin_key=&version= * fix: update plugin install to match final OpenAPI gateway protocol - batch_query: URL /plugin/versions/batch_query, request uses plugin_keys array + latest_only boolean, response uses flat data.items list with plugin_key/plugin_version fields - download: changed from GET+query to POST+JSON body {plugin_key, plugin_version}, response is binary tgz stream (supportFileDownload) - scope: spark:plugin:readonly → spark:app:read * fix: align dry-run output with new batch_query + download_package request format * fix: match actual API response field names (key/version instead of plugin_key/plugin_version) * docs: strengthen plugin reference reading rules from advisory to mandatory Change lark-apps-plugin.md from implicit to explicit required reading for any plugin work. Replace soft '按需读' with bold '必读' for all three plugin reference files. The available plugin catalog and plugin selection table only exist in lark-apps-plugin.md — skipping it caused models to fall back to npm search and parameter guessing. * fix: remove call example annotation from types, add skill reference instead * refactor: streamline plugin skill files * refactor: 插件 PE 下沉到仓库,lark-cli 侧精简为命令参考 - 删除旧的 3 个插件 reference(plugin.md / plugin-crud.md / plugin-call.md), 其中的 Schema 规则、CRUD 流程、插件目录、Prompt 模板等内容已下沉到 应用仓库 .agents/skills/plugin-guide/SKILL.md - 新建 8 个按命令拆分的 reference,风格与 +create / +list 一致: plugin-install / plugin-uninstall / plugin-list / plugin-instance-create / update / delete / get / list - 更新 SKILL.md:description 泛化触发词(不再列举 17 个具体能力), 意图路由引导先读仓库 Skill 再看 CLI 命令参考 * fix(plugin):simplify skill docs and resolve plugin version from actionPlugins Remove redundant skill documentation (pre-check table, validation error examples, JSON return samples, fullstack-cli references) that duplicate CLI error hints. Make --plugin version optional and resolve from package.json actionPlugins. Drop unused createdBy field. * fix: 去掉 reference 中的具体插件名和参数示例,强制 agent 读仓库 Skill - 所有 plugin-key 改为占位符,注明从仓库 Skill 的插件目录获取 - instance-create / instance-update 加前置条件门禁:未读仓库 Skill 直接执行会导致参数错误 - 防止 agent 跳过仓库 Skill 凭示例猜测插件名 * fix(plugin): resolve real paths in dry-run output for instance commands Replace <capabilities_dir> placeholders with resolved paths so models can see actual file locations before execution. Add version_source, types_output, and scan_dir fields to describe implicit behaviors. * refactor(plugin): hide instance commands, delegate to repo Skill Hide +plugin-instance-create/update/delete/get/list from CLI help. Remove instance reference files from lark-apps skill. Route instance CRUD and call code generation to project repo plugin-guide skill. Go instance code preserved, just hidden. * refactor: 删除 plugin-instance 5 个 CLI 命令,改由仓库 Skill 引导 agent 直接操作文件 - 删除 plugin_instance_create/update/delete/get/list 及其测试(11 个文件) - 删除 plugin_instance_types(TypeScript 类型生成命令) - 移除 shortcuts.go 中的 6 个注册项 - 清理 plugin_common.go 中仅被 instance 命令使用的函数(1054→340 行): 校验逻辑、capability JSON 读写、动态 schema 解析、TypeScript 生成等 - 保留 plugin-install / plugin-uninstall / plugin-list 三个命令不变 插件实例的 CRUD 操作改由仓库 Skill 引导 agent 直接读写 capabilities/*.json, 验证规则写在 Skill 中由 agent 自校验。 * refactor(plugin): remove --project-path flag and split --name into --name + --version - Remove --project-path from plugin-install/list/uninstall (use cwd like npm) - Split --name key@version into separate --name and --version flags - Remove pluginParseInstallTarget (no longer needed) - Improve DryRun desc and error hints for --version usage - Update skill docs to reflect new flag structure - Tests use chdirTest helper instead of --project-path * feat(plugin): add Examples to --help for plugin-install/list/uninstall 按 lark-cli 优化治理规范,为三个插件命令的 --help 补充 2-3 个 可执行示例,覆盖最常见使用路径,帮助 agent 快速理解命令用法。 * fix(plugin): address PR #1609 review findings - Fix hint referencing non-existent +plugin-instance-delete command, point to repo plugin-guide Skill instead - Remove undeclared --capabilities-dir flag, simplify pluginResolveCapDir to env-only resolution, fix ambiguous hint to suggest env vars - Reclassify download errors from file_io to network/api with proper hints and retryable marking - Slim SKILL.md routing row, move judgment rules to plugin-install reference - Rename --local flag to --file to align with CLI conventions * fix(skill): restore plugin routing row with judgment rules, fix markdown formatting Revert SKILL.md routing row to keep full judgment rules and repo Skill directive inline. Fix bold marker spacing and restore missing table column. Revert reference to original content without duplicated rules. * fix(plugin): revert SKILL.md to pre-review version, fix shortcut count test Restore SKILL.md plugin routing row to original version with full judgment rules and repo Skill directive. Update shortcut count test from 60 to 63 to account for 3 new plugin commands. * fix(plugin):fix lark-apps skill docs which is about plugin * fix(plugin):correct plugin skill md * fix(plugin):correct plugin md * fix(plugin):correct plugin and local dev skills md * fix(plugin):correct apps plugin skills md * fix(lark-apps): move repo skill reading hint to post-init phase 将「仓库 Skill 优先」从 SKILL.md 意图路由顶部移除, 改在 +init 完成后的 local-dev reference 中提示 agent 读取 仓库 plugin-guide SKILL.md,解决应用未初始化时 repo skill 不存在导致 agent 无法获取插件知识的时序问题。 * fix(lark-apps): strengthen local-dev reference reading and post-init plugin guide - SKILL.md 路由表:local-dev.md 从"按需读取"提升为"执行前必读" - local-dev.md:将读仓库 Skill 嵌入端到端流程链作为正式步骤 - post-init 指引改为可执行命令 + 不读的后果说明 + 不存在时兜底 --------- Co-authored-by: zhangli <zhangli.268@bytedance.com> * feat(apps): add release polling interval time and release time costs * fix(plugin): rename files to apps_ prefix and handle Close() errors (#1655) - Rename plugin_install/list/uninstall .go files to apps_plugin_ prefix for consistency with other files in the package - Handle f.Close() errors in pluginExtractTGZ to avoid silent data loss * style: gofmt apps plugin files (#1664) * fix(plugin): resolve CI lint, deadcode, and unit-test failures (#1667) - Add Scopes: []string{} to plugin-install, plugin-list, plugin-uninstall shortcuts to satisfy TestAllShortcutsScopesNotNil - Remove unused pluginCheckInstalled function (deadcode) - Fix nilerr: add //nolint:nilerr for intentional best-effort nil returns - Fix forbidigo: replace bare fmt.Errorf in Execute with typed error, add //nolint:forbidigo for intermediate helper errors in pluginExtractTGZ - Fix errorlint: change %v to %w for cerr in multi-error fmt.Errorf - Remove all unused //nolint:forbidigo directives from test files * style: gofmt apps_plugin list/uninstall/install_test files Fix fast-gate Check formatting failure: align struct literal fields in apps_plugin_list.go and apps_plugin_uninstall.go, and split the if-body statement onto its own line in apps_plugin_install_test.go. * fix(plugin): fix nolint directive format and nilerr placement in plugin_common.go (#1668) - Change nolint comment separator from -- to // to satisfy nolintlint - Move nilerr nolint directive to return statement to suppress nilerr correctly - Fix forbidigo nolint format for intermediate fmt.Errorf in pluginExtractTGZ * fix(apps): validate openapi-key scope method, path and raw JSON (#1675) Enforce an HTTP method whitelist (GET/POST/PUT/PATCH/DELETE), reject malformed --scope-api paths (must start with '/', no '..' or '//'), and constrain raw --scope JSON to the documented request_scope schema (allow_all + http_infos only). Validation runs in both the Validate hook and the body-build path so dry-run and execute are equally gated. Fixes PR #1596 audit findings HIGH-2 and MEDIUM-4. * fix(apps): harden db/file shortcuts per security audit (PR #1596) Address the file/db findings from the PR #1596 security audit with safer header/flag/path handling: - HIGH-3 (--output path traversal): add rejectOutputTraversal() and wire it into +file-download and +db-data-export Validate; reject absolute paths and any .. component up front. (FileIO.Save already sandboxes to cwd via SafeOutputPath; this is an earlier, explicit guard.) - HIGH-4 (Content-Disposition header injection): build the header with mime.FormatMediaType instead of manual string concatenation. - MEDIUM-3 (SQL leaked into public flag): stop writing --file contents back into the --sql flag; resolveExecuteSQL() reads it at use-site so SQL never lands in flag dumps / structured logs. - LOW-1 (hidden-file upload name): prefix sanitized upload names that start with '.' with '_'. - LOW-2 (local-timezone time parsing): document local-tz interpretation of bare date/datetime in flag descriptions and the db/file skill docs. SQL-injection of --table (audit MEDIUM-5) is intentionally NOT validated in the CLI: the server-side interface is the authoritative guard. Add apps_security_fixes_test.go covering the new validators and switch the upload test to parse Content-Disposition instead of matching a literal string. Update lark-apps-db.md / lark-apps-file.md skill refs. * fix(plugin): harden plugin commands against path traversal, DoS, and agent misuse (#1677) Security fixes from PR #1596 security audit: - Skip symlink/hardlink entries during tgz extraction (Zip Slip) - Limit tgz entry and download size to 10 MB (OOM/DoS) - Limit error response body read to 4 KB - Validate MIAODA_APP_TYPE as numeric to prevent path manipulation - Add validatePluginKey + secureModulePath to block --name path traversal (../../.ssh etc.) for install/uninstall Usability fix: - Add explicit 'local command, no --app-id' notice in plugin reference docs to prevent agent from incorrectly passing --app-id to plugin commands (which read package.json locally) * fix(apps): cap db async poll timeout at 2 minutes +db-recovery-apply blocked up to 30min and +db-env-migrate / +db-recovery-diff up to 10min while polling the server for async-task completion. These operations are expected to finish within ~1 minute; the long ceilings mostly hurt agents, whose harness kills the command on timeout while the server-side operation keeps running with no handle to re-query — especially risky for the irreversible recovery-apply. Cap all three pollUntil ceilings at 2 minutes (polling interval unchanged). Stuck operations now surface the retryable network/timeout envelope after 2min instead of hanging for 10-30min. * fix(plugin): create temp dir in project path to avoid cross-filesystem EXDEV on Rename (#1683) pluginInstallLocal used os.MkdirTemp("") which creates the temp directory on the system temp partition. On Windows (and some Linux/macOS setups), the temp partition is on a different filesystem from the project directory, causing os.Rename to fail with EXDEV. Use projectPath as the temp dir parent so it is always on the same filesystem as node_modules. * fix(plugin): improve --help Tips with local-command hint and update semantics (#1691) - Add "Run in project root; does NOT take --app-id" to all plugin Tips - Clarify install command also supports update (install or update to latest/specific version) - Clarify batch install reads from package.json actionPlugins --------- Co-authored-by: 陈兴炀 <chenxingyang.1019@bytedance.com> Co-authored-by: raistlin042 <lvxinsheng@bytedance.com> Co-authored-by: anngo-nk <anguohui@bytedance.com> Co-authored-by: zhangli <zhangli.268@bytedance.com> |
||
|
|
5c4ad52741 | fix: harden git credential error handling (#1676) | ||
|
|
22108c3300 | feat(docs): add reference map flags (#1547) | ||
|
|
5b0c3137e3 |
test(doc): derive fetch test flag defaults from v2FetchFlags (#1428)
Replace hardcoded flag defaults in the fetch test helpers with fetchDefault() / fetchDefaultInt() helpers that read the declared defaults from v2FetchFlags(). This prevents future drift between production flag defaults and test setup, and panics loudly if a flag name is misspelled rather than silently returning "". The tests now correctly avoid hardcoding doc-format, but other flag defaults (detail, revision-id, scope, etc.) were still duplicated here. Deriving all defaults from v2FetchFlags() keeps the whole test command definition aligned with production. Co-authored-by: TraeCli (Doubao-Seed-Dogfooding) <trae@bytedance.com> Co-authored-by: fangshuyu <fangshuyu@bytedance.com> |
||
|
|
4c31323de1 |
feat(sheets): use office_sheet_file parent_type for imported office spreadsheets (#1606)
Image uploads to a spreadsheet hard-coded parent_type=sheet_image at every entry point. Imported "office" spreadsheets carry a token prefixed with "fake_office_", for which the drive backend requires parent_type=office_sheet_file. Funnel the parent_type selection through a single sheets-domain helper so the rule lives in one place and every image-upload path (float-image, +cells-set-image, backward +media-upload, and every dry-run preview) stays consistent. - Add sheetMediaParentType(token) in the sheets domain: returns office_sheet_file for fake_office_-prefixed tokens, otherwise sheet_image. - Add an uploadSheetImage(...) collector that builds the DriveMediaUploadAllConfig (including parent_type) once, replacing the per-call-site hand-rolled configs. - Route both main-domain image entries through the collector — float-image local upload and +cells-set-image — covering Execute and the dry-run preview body/desc. - Cover the backward +media-upload entry: single-part, multipart (>20MB), and both dry-run bodies. backward is a separate package and an intentional verbatim mirror of shortcuts/sheets/, so it keeps its own copy of the helper rather than importing the main domain. - Leave the shared common.UploadDriveMediaAllTyped upload layer untouched — the fake_office_ rule is sheets-specific and must not leak into mail/slides/doc/drive/base. Tests: - Pure-function TestSheetMediaParentType (5 cases incl. prefix-only and mid-string non-match). - Main-domain dry-run TestCellsSetImage_DryRunOfficeParentType and TestUploadSheetImage_ParentType / _FileOpenError that exercise the Execute path on the wire, asserting parent_type via the captured multipart body and typed validation metadata (errs.ProblemOf category/subtype, fs.ErrNotExist cause preserved) on file open errors. decodeSheetMediaMultipartBody fails fast on NextPart / ReadFrom errors rather than silently producing a partial body. - backward TestSheetMediaUploadExecuteOfficeParentType (real multipart wire) and TestSheetMediaUploadDryRunSmallFileOfficeParentType (small-file dry-run preview for fake_office_). - cli_e2e tests/cli_e2e/sheets/sheets_image_upload_dryrun_test.go: --dry-run end-to-end across +media-upload and +cells-set-image, native and fake_office_ tokens, asserting api.0 is POST upload_all with parent_type=sheet_image / office_sheet_file and parent_node = token. |
||
|
|
39d60cb706 |
feat: add slides replace-pages and xml-get shortcuts (#1585)
* feat: add slides replace-pages shortcut * feat: add slides xml get shortcut * fix: stop advertising slides screenshot scope * feat: expose slides presentation url |
||
|
|
d9330b7ab3 | fix(docs): hide docs api-version compat flag (#1580) | ||
|
|
6b833257c7 | fix: optimize calendar,vc,minutes,note shortcut and skill (#1571) | ||
|
|
ba51d4874e | feat: support speaker list and nolark speaker replace (#1594) | ||
|
|
fe32a6e0a9 |
feat(docs): support create title option (#1536)
* feat: support docs create title option Change-Id: I6fd840fe813e5e664ea9ec680765fd41375cdebf * docs: refine docs title guidance Change-Id: I2f986a4606729bc791a1bff6c03aaa198b0798dc * docs: keep lark doc skill create example Change-Id: Ic7005e015c9e71a4582c1f4a8ac8222d552426d4 * test: allow docs create title flag in help Change-Id: I0226e20c6bf2187eb6c4f0d2d5e37ab9225d4171 |
||
|
|
af9835c288 | feat(drive): add +member-add shortcut with wiki space member collection collaborator support (#1204) | ||
|
|
1c92ed8841 |
feat: add im-markdown output for doc fetch (#1550)
* feat: add docs im-markdown fetch format * refactor: tune docs im-markdown conversion * test: expand docs im-markdown conversion coverage * refactor: simplify docs im-markdown handlers * test: cover docs im-markdown edge cases * fix: expand doc im markdown tag downgrades * fix: preserve blockquote paragraph breaks * fix: handle im markdown nested tables and urls * docs: document im markdown skill usage * test: cover doc im markdown fetch * test: strengthen doc fetch error coverage * fix: fetch doc skill typo |
||
|
|
644c3c77dd |
doc(whiteboard):support export whiteboard as SVG and update whiteboard via SVG (#1559)
* feat(lark-whiteboard): update shortcut, support query or update whiteboard by svg * feat(whiteboard): pin whiteboard-cli to v0.2.12 in lark-whiteboard skill * fix(whiteboard): whiteboard shortcuts unit test * fix(whiteboard): add whiteboard query shortcut unit test |
||
|
|
bd898a1d74 |
feat(sheets): typed table I/O & error contract, workbook import/export, skill refresh (#1355)
* feat(sheets): add +sheet-show-gridline / +sheet-hide-gridline shortcuts
* docs(sheets): strengthen lark-sheets references for common editing pitfalls
Add targeted guidance to six lark-sheets references to reduce frequent
mistakes when editing spreadsheets through the CLI:
- write-cells: sanity-check units / dimension conversion / quantity factors
before formula writes (formulas can run clean yet be off by a factor);
keep derived output off original data columns to avoid clobbering source
- core-operations: prefer live formulas for derived values even when "live
update" is not explicitly requested; scope rewrite/transform precisely so
rows/columns that should stay unchanged are kept 1:1; treat header-stated
format rules as checklist items; confirm the artifact file actually exists
before finishing; write back bare values from local scripts
- visual-standards: apply border/header formatting on explicit request and
identify the real header row; keep font size consistent with the source
- range-operations: keep total column width within A4 for printing
- read-data: dedup/compare long numbers via raw values, not csv formatted
display (scientific notation collapses distinct numbers and causes false
duplicates)
- chart: format date/number axes via source-cell number_format; place charts
outside the data area so they do not cover existing data
* feat(sheets): implement table-put/table-get and sync skill specs
- Add lark_sheet_table_io.go with +table-put / +table-get and tests
- Refactor read-data; extend workbook; register new shortcuts
- Sync generated flag defs/schemas (go:embed) from sheet-skill-spec
- Sync skill references (write-cells numeric-column guidance, plus
read-data / workbook / chart updates)
* docs(sheets): surface typed-write path at the write-decision point
Quick-ref table (SKILL.md, the first decision point) had no +table-put and
gated typed writes on "DataFrame", so a model holding a Counter/list/dict
would fall back to +csv-put and silently lose number/date fidelity.
- split csv-put row to plain-text values (no numeric/date semantics)
- add +table-put row for typed writes into an existing sheet
- add +workbook-create --sheets row for create + typed write in one shot
- add judgment note: number/amount/date/percent/count -> +table-put
(or +workbook-create --sheets when the workbook does not exist yet);
plain text -> +csv-put
- reframe write-cells scenario row to lead with numeric semantics
- point new-table writes at +workbook-create --sheets (one shot) instead
of the create-empty-then-table-put two-step
Synced from sheet-skill-spec canonical (generate:cli + sync:cli).
* docs(sheets): sync SKILL.md (drop "not for local Excel" caveat)
Mirror the upstream sheet-skill-spec change removing the "not applicable to local Excel files" tail from the sheets skill and reference descriptions.
* docs(sheets): sync SKILL.md (drop "Feishu sheets only" caveat)
Mirror the upstream sheet-skill-spec change removing the "applies to Feishu sheets only" tail from the 14 sheet reference descriptions.
* feat(sheets): add +workbook-import wrapping the drive import core
Import a local xlsx/xls/csv as a new spreadsheet by delegating to the shared drive import flow with the target type pinned to sheet. Refactor drive +import to expose ImportParams / ValidateImport / PlanImportDryRun / RunImport (behavior unchanged, existing drive tests still cover it); sheets reuses them. Regenerate flag_defs_gen.go and sync the spec mirror.
* refactor(sheets): reuse the drive export core in +workbook-export
Replace +workbook-export's parallel export-task implementation with the shared drive ExportParams/RunExport core (pinned to type=sheet). Drops ~90 lines of duplicated poll/download code; +workbook-export now inherits drive's ctx cancellation, resume-on-timeout, filename sanitize/overwrite, and the full set of export status labels. The output contract aligns with drive's (adds ready/downloaded/doc_type; saved_path preserved). Also normalize an empty drive --output-dir to "." so drive +export behavior is unchanged, and fix the sheets export e2e to call +workbook-export instead of a nonexistent +export.
* docs(sheets): keep original column widths; align chart axis with requested metric
- range-operations: only widen new / overflowing columns; never recompute or
shrink the widths of existing columns (any blanket resize, even by 1px,
breaks the original visual format)
- chart: when the user asks for a share / percentage, the value axis should be
a percentage (pie, or stack.percentage on bar/column) rather than raw counts
* docs(sheets): reword guidance to avoid eval-specific phrasing
Replace scoring-framework wording in the examples with plain functional
consequences (e.g. "not delivered", "goes stale when the source changes",
"breaks the original visual format"), so the references stay agent-facing.
* docs: add lark sheets financial modeling guidance
* docs(sheets): align write-cells reference with the generated output
Bring the hand-applied write-cells example in line with the spec-generated
reference so the CLI mirror is byte-identical to the canonical source.
* docs(sheets): align +csv-put help with formula support
Sync the formula-support wording from sheet-skill-spec (flag-defs, skill
references) and update the hand-authored cobra Description and comment for
+csv-put. +csv-put evaluates a leading-= cell as a formula via
set_range_from_csv; descriptions only, no behavior change.
* docs(sheets): fix invalid +dim-insert example in chart reference
The chart reference's placement example used non-existent flags
--dimension/--start/--end for +dim-insert. The real signature is
--position (required) + --count (required); copying the example
fails Validate with "--position is required". Replace it with
+dim-insert --position V --count 6 (insert 6 columns before V,
i.e. after U), aligning with the sheet-structure reference.
* docs(sheets): chart coordinate base / quoting + filter condition enums
Sync three reference-doc corrections from the spec source:
1. chart: label position.row as 0-based (first row = row:0), distinct
from the 1-based row numbers used by A1 ranges and +dim-insert
--position, removing the row-base ambiguity.
2. chart: convert the three runnable examples whose JSON contains a
quoted sheet prefix ('Sheet1'!A1) from inline single-quoted
--properties '{...}' to a stdin heredoc (--properties - <<'JSON').
Inside an inline single-quoted string bash strips the inner quotes
around the sheet name (and splits names with spaces into words),
corrupting the JSON; a quoted heredoc delimiter performs no shell
substitution and preserves it. Adds a short note on the pitfall.
3. filter / filter-view: add the full conditions[].type x compare_type
enum table (text / number / multiValue / color and their respective
compare_type values and values shape), and call out the
equals/notEquals (with s) vs equal/notEqual (no s) gotcha. The docs
previously only showed two values via examples.
* docs(sheets): label +sheet-create --index as 0-based
The base flag description for +sheet-create's --index omitted the
coordinate base, while its siblings +sheet-move ("Target position
(0-based)") and +sheet-copy already state 0-based. Align the description
so the index base is unambiguous. Synced from the spec source
(flag-defs.json + workbook reference).
* fix(sheets): regenerate flag defs and fix asasalint in table io
* feat(sheets): add counta to chart aggregateType enum
Add `counta` (count non-empty cells, incl. text) to manage_chart_object
dim2.series[].aggregateType in the chart flag schema. `count` only counts
numeric cells, so counting occurrences of a text/category column renders an
empty chart; `counta` enables category frequency counts. Synced from the
sheet-skill-spec canonical schema.
* feat(sheets): make --target-position and --range mutually exclusive on +pivot-create
Both flags map to the same wire field (properties.range), so passing
non-default values for both is ambiguous. Mirror the
--target-sheet-id / --target-sheet-name mutex pattern: --target-position
takes priority over --range, and supplying both with non-default values
is rejected up front with a typed FlagErrorf. --target-position=A1 is
the documented default and is treated as "not set".
Add a symmetric validateCreateInput hook on objectCRUDSpec (alongside
the existing validateUpdateInput), wire it into objectCreateInput, and
inject the pivot-specific check on pivotSpec.
* feat(sheets): rework +workbook-create flags and --styles
- --values builds a type-less typed payload, writing through --sheets' batched set_cell_range path (raw passthrough preserves auto-detect; large tables batch; big ints via json.Number)
- drop --headers (subsumed by --values first row) and --header-style (typed header no longer auto-bold; use --styles instead)
- styles: deep-merge overlapping cell_styles/border_styles fields (was wholesale-replace which dropped fields); add manual border_styles validation (style/weight enums + sides) since --styles is on parseJSONFlagSkip and bypasses the schema validator
- regenerate flag-defs/flag-schemas/skills mirror from sheet-skill-spec (--styles flag + full per-side border schema)
* fix(sheets): add mention_type enum to set_cell_range cells schema
Constrain rich_text mention_type to the proto MENTION_FILE_TYPE set so a
file @mention with an out-of-enum value (e.g. 6 = cloud shared folder) is
rejected by the schema validator before it reaches the server and fails
pb serialization ("mentionFileInfo.fileType: enum value expected").
- data/flag-schemas.json: mention_type gains enum + per-value description
- lark_sheet_write_cells_test.go: cover reject (6) + allow (0 / 2 / 22)
* feat(sheets): implement pandas-split --sheets protocol for +table-put/+table-get/+workbook-create
Synced from sheet-skill-spec canonical (cli:table_put schema +
references). +table-put/+workbook-create accept the new shape via a
tableSheetIn -> tableSheetSpec normalize step (dtype string -> internal
type/format mapping). +table-get emits the same shape so the writer's
df_to_sheet and the reader's sheet_to_df round-trip cleanly.
isoDateToSerial now accepts the full ISO datetime form
(2024-01-15T00:00:00.000, including timezone suffixes) emitted by
df.to_json(date_format="iso"), not just yyyy-mm-dd. End-to-end verified
by the spec repo's contracts/python_helper_roundtrip script against a
real Lark spreadsheet on pandas 2.2 and 3.0.
* feat(sheets): add --dataframe Arrow IPC input for +table-put/+table-get/+workbook-create
Introduce a binary-typed twin of --sheets: --dataframe accepts an Arrow IPC
(Feather v2) payload that pandas' df.to_feather() writes, deriving dtypes and
per-column number formats from the Arrow schema. The two producers are mutually
exclusive and funnel through a shared resolver so +table-put and
+workbook-create stay in lockstep; +table-get gains --dataframe-out for
single-sheet reads. Also auto-grow a sub-sheet's row/column count before
writing so blocks past the backend's default 200x20 bounds no longer fail with
range-exceeds-sheet-bounds.
* docs(lark-sheets): remove financial modeling standards reference
Drop the lark-sheets-financial-modeling-standards.md reference doc and all
pointers to it from SKILL.md, core-operations, and visual-standards. Bump
skill version to 3.0.0.
* docs(lark-sheets): clarify cell-image vs float-image routing and fix reference self-references
Synced from sheet-skill-spec.
- Add a binding-based decision (does the image belong to a record and move with its row?) to route +cells-set-image vs +float-image-create across the SKILL entry, float-image and write-cells references.
- Add routing rows to the SKILL command cheat-sheet and warn against defaulting to float-image out of familiarity.
- Replace mislabeled 本 skill / 子 skill / 跨 skill wording in references with 本文 / reference names, matching the existing convention.
* feat(sheets): add --styles to +table-put for one-step typed write with styling
+table-put now accepts --styles (same shape as +workbook-create's --styles):
cell_styles merge into the set_cell_range matrix, while cell_merges /
row_sizes / col_sizes apply as their own tool calls after the write. The
styles payload is name-matched against the written sheets and validated up
front, so a malformed or mismatched style fails before any write lands.
Also points +sheet-create users to +table-put (auto-creates missing sheets)
when they need data/styles, via a runtime Tip and the lark-sheets skill
references. Flag is sourced from the upstream Base table and regenerated
through sheet-skill-spec (flag-defs.json / flag-schemas.json / gen file).
Adds unit tests (dry-run styles, name-mismatch reject, execute) and a
dry-run E2E (tests/cli_e2e/sheets/sheets_table_put_dryrun_test.go).
* docs(lark-sheets): point read-data to +sheet-info for hidden row/col identification
skip-hidden defaults to false (lossless reads), but the read primitives don't mark which rows/cols are hidden. Cross-reference +sheet-info --include hidden_rows,hidden_cols + row_indices/col_indices so agents can identify hidden ranges when they need to filter or interpret hidden data.
Synced from sheet-skill-spec.
* feat(sheets): document link requirement for @document mentions in cells flag schema
@document mentions (mention_type != 0) must pass link (doc URL) to render a
clickable card; @user mentions (mention_type=0) don't need it. Synced from the
upstream tools-schema.
* fix(sheets): reject cond-format attrs whose shape mismatches rule_type
A conditional-format rule created with --rule-type colorScale but
cellIs-shaped attrs ({compare_type,value}, no color) was accepted by
the CLI and written through to the server, producing a color-less
color-scale segment. That dirty data crashes the frontend on snapshot
deserialization, so the spreadsheet can no longer be opened (5005).
The per-entry schema check can't catch this: properties.attrs.items is
a oneOf over all nine attr shapes and passes as soon as any branch
matches, blind to the sibling rule_type — {compare_type,value} matches
the cellIs branch even when rule_type says colorScale. The tool side
maps attrs blindly by rule_type and only validates dataBar count and
iconSet ordering, so the gap reaches the data layer.
Add a cross-field validator (validateCondFormatAttrs) wired into both
create and update via the new objectCRUDSpec.validateCreateInput hook
(twin of validateUpdateInput). It enforces, per rule_type, the keys
every attrs entry must carry — mirroring the tool's converter contract
— and treats an empty required string (notably color) as missing.
Rule types that take no attrs (duplicateValues / uniqueValues /
containsBlanks / notContainsBlanks) and updates that omit rule_type are
left to the server.
* test(sheets): guard condFormatAttrsRequired against flag-schemas drift
Add TestCondFormatAttrsRequired_MatchesSchemaOneOf, comparing the
hand-maintained condFormatAttrsRequired table against the embedded
flag-schemas.json attrs oneOf (multiset of required-key sets, for both
create and update). The cross-field validator only holds if its
per-rule_type required keys mirror the schema branches, and the two
share no compile-time link — this pins them together so a future schema
sync that adds/drops a required key can't silently desync the table.
* fix(sheets): default +table-get to full used range, not A1 current region
+table-get without --range anchored its current_region probe at A1, so an
internal blank row or column silently truncated everything past it — agents
then treated the partial data as complete (the pro016 / pro025 incident).
- Probe the used range over the full physical grid (row_count × column_count
from the workbook structure) so it spans internal blank rows/columns; fall
back to the legacy A1 anchor when dimensions are unknown.
- Emit the actually-read `range` on every sheet so callers can detect
truncation (get_cell_ranges has no has_more flag).
- Fix the same A1-anchor bug in append mode's last-data-row probe, which could
otherwise overwrite data past an internal blank row.
- Add unit + dry-run/live E2E coverage; refresh synced skill docs.
* docs(sheets): fix csv-get current_region guidance to cross-check row_count
current_region is a blank-row/column-bounded block, not the true sheet extent:
an internal blank row truncates it, so it can miss rows past the gap. The
read-data reference previously called it the "真实数据边界" and told agents to
prefer it over row_count — which drove the "read only to current_region's last
row, miss the tail" failure.
- current_region: warn it can be both smaller (internal blank rows truncate)
and larger (trailing summary/signature rows) than the real data range.
- csv-get output contract: clarify its row_count/col_count is the returned size
(= actual_range), not the physical sheet size; has_more only reflects the
current range, not whether the whole sheet was read.
- "确定数据范围的正确流程": add a step to cross-check against +workbook-info's
physical row_count and probe past current_region's last row for data beyond an
internal blank row.
* fix(sheets): collapse duplicate validateCreateInput from bad merge resolution
A prior merge kept both branches' independently-added validateCreateInput
fields on objectCRUDSpec with conflicting signatures (pivot's
func(rt, input) and cond-format's func(input)), plus both call sites in
objectCreateInput, which failed to compile (validateCreateInput redeclared).
Collapse to the single richer func(rt flagView, input) signature and one
call site. cond-format's validateCondFormatAttrs (func(input), still shared
with validateUpdateInput) is wrapped in a closure that ignores rt. Both
behaviors are preserved: pivot --target-position/--range mutex and
cond-format attrs-shape-vs-rule_type validation.
* refactor(sheets): migrate legacy error helpers to typed errs in sheets domain
golangci-lint forbidigo (errs-no-legacy-helper / errs-no-bare-wrap) flagged
the table I/O, workbook, and dataframe shortcuts that landed on this branch:
93 common.FlagErrorf and 48 fmt.Errorf calls.
- Replace every common.FlagErrorf with common.ValidationErrorf (typed
*errs.ValidationError, same signature) across workbook / table_io /
dataframe / object_crud.
- writeDataframeOut's two final --dataframe-out write failures become typed
errs.NewInternalError(SubtypeFileIO, ...).WithCause(err).
- applyWorkbookCreateVisualOps now passes the typed callTool error through
unchanged (re-wrapping would downgrade classification) and attaches the
failing op as a recovery hint only when none is set.
- The remaining fmt.Errorf are genuine intermediate errors that the command
layer re-wraps into typed validation errors (buildTypedCell / Arrow
decode-encode) or surfaces as a partial_success message string
(writeTypedSheets via tablePutPartial); each carries a //nolint:forbidigo
with that reason, per the lint guidance.
No behavior change: error messages and partial-success shapes are preserved;
gofmt, go vet, golangci-lint (0 issues) and sheets tests all pass.
* fix(shortcuts): clarify single-stdin constraint in flag help and error hint
Input flags advertised '(supports @file, - for stdin)' per flag, leading
AI agents to write '--a - <x --b - <y' where the second '<' silently
clobbers the first and the first flag reads the wrong payload. A process
has a single stdin, so at most one flag per call can use '-'.
- Reword the generated help hint to '- reads stdin (one flag per call;
use @file for others)'.
- Add an actionable .WithHint to the stdin-conflict validation error
pointing callers to @file for the extra flags.
- Assert the new hint in TestResolveInputFlags_DuplicateStdin.
* feat(sheets): +cells-get/+csv-get --max-chars 默认值 200000 → 500000
放宽默认防爆上限。flag_defs_gen.go 由 go generate 重生;flag_defs_test.go
的 expected default 同步;flag-schemas.json schema_version 2 → 3 是上游
spec-tables 架构调整带来的元数据 bump,与本业务改动无关、go:embed 不解析
该字段、无功能影响。
Synced from sheet-skill-spec@93f7a78.
* docs(lark-sheets): sync from spec — +csv-put 含逗号公式正例 + 收敛警示标签
源同步自 sheet-skill-spec:write-cells 补含逗号公式 RFC 4180 转义正例与结构化写入优先指引;全 reference 收敛「高频致命错误」类标签。
* docs(lark-sheets): sync from spec — --max-chars 放出为可见 flag + 落盘优先指引
源同步自 sheet-skill-spec:--max-chars 放出(默认 500000,可调小避免大输出被 Bash/终端转存为文件、改 has_more 分页);read-data 增「大数据优先落盘」指引。
* feat(sheets): 写操作报错增强 + --token 别名
- 复合 JSON shape 校验失败时报错附 --print-schema 提示,agent 可直接拿到精确结构(pro26 头号:+cells-set --cells 反复猜 shape)
- JSON 解析失败且该 flag 支持 stdin 时提示改用 stdin(公式/引号/逗号内联到 shell 被转义弄坏 JSON)
- --token 作为 --spreadsheet-token 的解析期别名:复用 sheets 已有 PostMount 钩子 + pflag normalize,仅 sheets 包,common 零改动
* docs(lark-sheets): sync from spec — set+H 改单引号 / 速查表补臆造命令名 / workbook-import 引导
* fix(sheets): migrate +table-put to typed error contract
The merge from main brought in #1449 (retire legacy error envelopes),
which removed output.ExitError / output.ErrDetail and forbids
constructing them. Port tablePutPartial off the legacy envelope:
- no sheets written -> typed errs.APIError (plain failure)
- some sheets written -> ok:false result via runtime.OutPartialFailure
carrying written_sheets, returning the partial-failure exit signal
Also fix two drifts the same merge introduced:
- regenerate flag_defs_gen.go to match the committed flag-defs.json
- update the --max-chars flag test to assert visible (no longer hidden)
* docs(lark-sheets): sync from spec — set+H 告诫通则化(移入 stdin 段)
* feat(sheets): styles 接受 halign/valign 等对齐字段别名
把模型常幻觉的 horizontal_align / halign / vertical_align / valign 映射到
规范字段 horizontal_alignment / vertical_alignment,覆盖 --styles 与 typed
--cells;与规范字段冲突时报错而非静默择一。同步 lark-sheets skill 文档补
对齐字段说明 + --print-schema --flag-name styles 提示。
* feat(sheets): resolve wiki URLs to the backing spreadsheet for --url
Sheets shortcuts only accepted /sheets/ and /spreadsheets/ URLs via --url.
A /wiki/<node_token> URL was rejected with "must be a spreadsheet URL"
because the wiki node_token is not a spreadsheet token: resolving it to the
backing spreadsheet needs a wiki get_node call, which Validate/DryRun (kept
network-free) must not make.
Mirror the existing slides/doc/drive two-stage pattern:
- parseSpreadsheetRef classifies --url / --spreadsheet-token network-free
into a sheet token or an (unresolved) wiki node_token.
- resolveSpreadsheetTokenExec (Execute only) resolves a /wiki/ node_token
via wiki get_node, verifies obj_type=sheet, and returns the obj_token.
The wiki:node:read scope is enforced on this path only, so non-wiki
invocations are unaffected.
- resolveSpreadsheetToken stays network-free for Validate/DryRun, passing
the node_token through unchanged.
All 47 Execute paths (including +batch-update and +workbook-export) switch
to the Exec resolver; Validate/DryRun keep the network-free one. No tool
schema change: the CLI feeds the resolved spreadsheet token as excel_id, so
this is a pure CLI-layer change.
Tested: unit (parse classification + wiki get_node e2e via httpmock) and
live end-to-end against a real wiki spreadsheet (read: +workbook-info,
+cells-get, +csv-get; write: +sheet-create, +sheet-rename, +csv-put).
* docs(sheets): note --url accepts wiki URLs (synced from spec)
* fix(sheets): match --url path segment via url.Parse, not substring
parseSpreadsheetRef classified /wiki/ with strings.Index over the whole URL, so a /sheets/ link whose query or fragment merely contained /wiki/ (e.g. .../sheets/sht?from=/wiki/x) was hijacked into a get_node call. Now parse the URL and match /sheets/, /spreadsheets/, /wiki/ only as a path prefix, mirroring slides parsePresentationRef which already fixed this class. Drop the substring helpers. Also align wiki resolution with slides: CallAPITyped (typed error + log_id) and classify an incomplete get_node response as InternalError instead of a --url validation error. Add regression tests for query/fragment /wiki/ and incomplete node.
* fix(sheets): satisfy errorlint/copyloopvar + regen flag defs
- helpers_test.go: drop the Go 1.22+ redundant `tc := tc` loop copy
(copyloopvar).
- lark_sheet_dataframe.go, lark_sheet_table_io.go: switch the
intermediate-error fmt.Errorf calls from %v to %w so errorlint passes.
Behavior unchanged — these errors are always rewrapped into typed
validation errors at the command layer.
- flag_defs_gen.go: regenerate from data/flag-defs.json (drift from the
wiki-URL merge).
* ci: allow Apache Arrow module in license check
Arrow is Apache-2.0 overall, but it vendors c-ares (LicenseRef-C-Ares,
ISC-like) inside the module which go-licenses classifies as Unknown and
the strict disallowed_types=...,unknown gate rejects.
Pass --ignore github.com/apache/arrow/go/v17 since Arrow is required by
sheets +table-put / +table-get / +workbook-create --dataframe (Arrow IPC
ingest) and the vendored c-ares is not redistributed by us.
* fix(sheets): resolve wiki URL in +range-move/+range-copy Execute
transformExecuteFn (the named Execute helper shared by +range-move and +range-copy) still called the network-free resolveSpreadsheetToken, so a /wiki/ URL reached transform_range as an unresolved node_token and failed. #1519's sweep over Execute hooks only rewrote inline closures; this is the only Execute backed by a named helper. Switch it to resolveSpreadsheetTokenExec (Validate/DryRun stay network-free) and add a +range-move wiki-URL regression test.
* refactor(sheets): drop +table-put manual capacity grow; rely on set_cell_range auto-grow
set_cell_range now auto-grows the sub-sheet to fit the write, so the
ensureSheetCapacity helper (and its modify_sheet_structure dim-insert
call before each write) is no longer needed. This also closes a data-
safety hole flagged in review: inserting before the last existing row
could push real data down into the area set_cell_range was about to
write, and allow_overwrite=false could not protect against it because
the structural insert had already mutated the sheet by the time the
write-collision check ran.
Verified end-to-end against a real spreadsheet: +table-put writing
300x25 into a fresh Sheet1 (default 200x20) succeeds in one write and
the sheet ends up 301x25.
* fix(sheets): close --dataframe stdin guard hole
--dataframe is binary and bypasses the common Input resolver, which is
where the existing single-stdin guard lives. Result: an invocation like
+table-put --dataframe - --styles - was accepted, then one of the two
consumers raced for stdin and the other silently saw an empty stream.
Add a stdinConsumed marker on RuntimeContext that both consumers share:
common.resolveInputFlags sets it when an Input flag uses '-', and
readDataframeBytes both checks and sets it. A second consumer is
rejected up front with an actionable hint pointing at @file.
Flagged in code review (lark_sheet_dataframe.go:93).
* fix(sheets): harden +table-put / +table-get input validation and round-trip safety
Four review-flagged correctness gaps in table I/O, all bundled because
they touch the same file:
1. --sheets accepted trailing data after the first JSON value
(json.Decoder does not surface that, unlike json.Unmarshal). A new
decoderExpectEOF helper rejects e.g. `--sheets '{...} oops'` with a
typed validation error instead of letting the leading object pass
through and surface as a confusing downstream failure.
2. +table-get with a duplicate header (e.g. `amount, amount`) used to
read back successfully — the dtypes map silently collapsed to one
entry — and only failed later on +table-put because the writer
rejects duplicate column names. Fail fast at read time with an
actionable hint to rename or pass --no-header. --no-header mode is
exempt (fallback col<N> names are always unique).
3. +table-put dry-run rendered an invalid range like A1:C0 when
header=false with rows=[]. tablePutFullRange returns "" for an
empty matrix or zero columns instead of building a degenerate
rectangle.
4. +table-get with --sheet-id and a get_workbook_structure miss (read
failure or selector mismatch) used to return a target with
name="", which then broke +table-get → +table-put round-trip (the
writer requires a non-empty sheet name). Fall back to using the id
as the name.
End-to-end verified against a real spreadsheet: trailing data, duplicate
header, and --no-header fallback all behave as advertised.
* fix(sheets): apply +workbook-create style-only ops instead of silently dropping them
A +workbook-create call carrying only cell_merges / row_sizes / col_sizes
(no --values / --sheets and no cell_styles) used to create the workbook
but silently drop the requested visual ops. Two reasons, both fixed:
- workbookCreateStyleDimensions only counted cell_styles when computing
the write extent, so cell_merges / row_sizes / col_sizes always
contributed 0 → buildValuesPayload returned a nil payload → Execute
skipped writeTypedSheets entirely → no visual ops ran. Extend the
helper to fold the merge / resize ranges in.
- Pure row_sizes / col_sizes payloads can never expand a cell rectangle
(they are dimension ranges, not cell ranges), so even with the extent
fix Execute would still skip the write path. Add a no-data branch:
when payload == nil but a styles item is present, look up the default
sheet and apply visual ops directly via applyWorkbookCreateVisualOps.
The dry-run plan mirrors this so the preview shows the visual ops.
Also picks up the --values trailing-JSON-data EOF check (mirror of the
--sheets one in lark_sheet_table_io.go).
End-to-end verified against a real spreadsheet: a cell_merges-only
+workbook-create now produces a sheet with merged_cells_count: 1.
* fix(sheets): preserve causes and render messages cleanly for typed validation errors
common.ValidationErrorf goes through fmt.Sprintf, which does not support
%w — the seven call sites that used `%w` were rendering the cause as
literal `%!w(*fmt.wrapError=&{...})` and dropping the cause from the
typed-error chain (so callers couldn't errors.As back to the underlying
error).
Switch each to `%v` for clean rendering and attach the cause via
.WithCause(err) so the typed contract is preserved. Touched call sites:
- lark_sheet_dataframe.go: --dataframe Arrow decode / stdin read / file
read failures (3 call sites).
- lark_sheet_table_io.go: --sheets invalid JSON, payload-validate
per-cell coercion error, buildSheetMatrix per-cell error,
--dataframe-out arrow encode failure (4 call sites).
End-to-end verified against a real spreadsheet: both invalid-JSON and
typed-cell errors now render readable messages instead of %!w(...).
* sync(sheets): pick up +sheet-{show,hide}-gridline in +batch-update schema
Mirror of the sheet-skill-spec change adding the two gridline shortcuts
to cli-schemas.json batch_update.operations.shortcut enum. Synced from
the upstream canonical via generate:cli + sync:cli.
Verified end-to-end on a real spreadsheet — +batch-update with a
+sheet-hide-gridline op passes schema validation and the backend run
returns succeeded: 1.
* sync(sheets): pick up +workbook-export UX clarification from spec
Mirror of the sheet-skill-spec update that documents +workbook-export's
default-no-download behavior and its relationship to drive +export
--doc-type sheet. Synced from canonical via generate:cli + sync:cli +
go generate.
End-to-end verified against a real spreadsheet:
- Omit --output-path → ok:true, downloaded:false, file_token returned
- Pass --output-path ./crfix_test.xlsx → ok:true, file saved
(17892 bytes), saved_path returned
The --help output for +workbook-export now states the default behavior
and points callers at `drive +export --doc-type sheet` when they need
the --output-dir / --file-name / --overwrite split.
* test(sheets): assert typed errs.Problem instead of err.Error() substrings
Per the coding guideline "Error-path tests must assert typed metadata via
errs.ProblemOf (category / subtype / param) and cause preservation, not
message substrings alone." — sweep through every error-path assertion in
the sheets domain and replace the
`strings.Contains(stdout+stderr+err.Error(), ...)` pattern with two
small helpers landed in helpers_test.go:
requireProblem(t, err, wantCategory, wantSubtype, msgContains)
-> *errs.Problem
requireValidation(t, err, msgContains)
-> *errs.ValidationError // shorthand for CategoryValidation +
// SubtypeInvalidArgument; lets callers
// also assert .Param / .Params / .Cause
~60 assertion sites across 18 test files now check the typed envelope
shape, with message-substring checks moved onto the returned Problem
(.Message / .Hint / .Param). The substring is preserved as a sanity
check rather than the sole assertion, so a category drift like
validation → internal would now fail loudly instead of slipping past.
Cases intentionally left as substring (each with a one-line reason):
- Errors that come straight from cobra's native flag parser (untyped
*errors.errorString — e.g. "required flag(s) ... not set", mutually-
exclusive groups). Re-typing these needs a custom FlagErrorFunc and
is out of scope here.
- Intermediate errors from decodeArrowToSheet that the caller wraps
into a typed envelope (`//nolint:forbidigo` reason). Those unit
tests assert the unwrapped intermediate directly.
One production tweak:
- shortcuts/sheets/flag_schema.go: printFlagSchemaFor returns typed
*errs.ValidationError (with WithParam("--flag-name") on the
unknown-flag branch) instead of raw fmt.Errorf. The framework
already wraps this when called via --print-schema, so user-facing
behaviour is unchanged; direct callers (and tests) now get the
typed envelope.
Verified: go test ./shortcuts/sheets/... passes; golangci-lint
--new-from-rev=origin/main reports 0 issues.
* test(common): assert typed errs.Problem instead of err.Error() substrings
Mirror of the sweep just landed in shortcuts/sheets: replace error-path
substring assertions with typed-envelope checks via two small helpers
landed in a new shortcuts/common/typed_error_assertions_test.go:
requireProblem(t, err, wantCategory, wantSubtype, msgContains)
-> *errs.Problem
requireValidation(t, err, msgContains)
-> *errs.ValidationError // shorthand for CategoryValidation +
// SubtypeInvalidArgument; lets callers
// also assert .Param / .Params / .Cause
8 sites moved to typed assertions across runner_jq_test.go,
mcp_client_test.go, drive_media_upload_typed_test.go, and
runner_input_test.go (the input tests already used a typed-param helper;
this just retargets the substring follow-up onto the typed Message).
Sites intentionally left as substring + comment (production returns raw
fmt.Errorf, not a typed envelope):
- runner_botinfo_test.go (6 sites): BotInfo / fetchBotInfo wrap upstream
errors with fmt.Errorf so the SDK-level message ([99991], 403,
invalid character, etc.) shows through.
- runner_args_test.go (4 sites in 2 tests): rejectPositionalArgs returns
raw fmt.Errorf to satisfy cobra's PositionalArgs contract.
- permission_grant_test.go (2 sites): assert on stderr / hint strings,
not error messages — already out of the err.Error() substring class.
No production code changes.
Verified: go test ./shortcuts/common/... passes;
golangci-lint --new-from-rev=origin/main ./shortcuts/common/... reports
0 issues.
* fix(sheets): plug four +table-put / +table-get correctness gaps flagged in CR
Four review-flagged bugs, all in lark_sheet_table_io.go (bundled because
they touch the same file and the same +table-put / +table-get domain):
1. +table-get --dry-run dropped the --sheet-id / --sheet-name selector
from the get_cell_ranges body, while Execute always passed it. Agents
that validate the dry-run shape and then run live would see a request
shape mismatch. The dry-run now calls sheetSelectorForToolInput so
the body matches Execute.
2. isDateNumberFormat used a simple `strings.ContainsRune(_, 'y')` so
number formats like "JPY #,##0" (a currency prefix that happens to
contain a lone 'Y') were misread as date formats — round-tripping
integer cells out as ISO dates. The detector is now token-aware:
it skips quoted "...", `\\x`-escaped, and `[...]` bracket sections,
and only fires on an unescaped `yy` (a real Excel year token).
3. sheetCreateDims sized new append-mode sheets by `headerOn(s)` only,
but writeSheetData forces a header on empty append sheets when
Header == nil. Near 50000 rows / 200 cols this created the sheet one
row short and the follow-up set_cell_range bounced off the backend
ceiling. Size now matches the forced-header logic exactly.
4. tableGetTargets fallback paths (read-failure / selector mismatch on
--sheet-id) returned a target with name="" — already corrected for
--sheet-id structure-success path in
|
||
|
|
898e6d4b3b | fix: prefix docs resource shortcuts (#1564) | ||
|
|
7df37ed715 |
feat(base): Add Base URL and title resolve shortcuts (#1338)
* feat(base): add URL and title resolve shortcuts * docs: clarify base coordinate resolution * fix(base): address resolve shortcut ci * fix(base): format resolved record share hint * fix(base): simplify record share hint data * fix(base): use field ids in resolved record data * fix(base): guide record share resolve to update record * fix(base): include record upsert example in resolve hint * fix(base): reject add-record urls in resolver * fix(base): validate title resolve query length * fix(base): hide resolve alias flags from help * fix(base): prefer title flag for title resolve * docs(base): clarify token resolution wording |
||
|
|
b46e60c156 |
feat: add task event consumer (#1510)
* feat: add task event consumer * fix: address task event review feedback * feat: remove legacy task event subscription shortcut * test: strengthen task preconsume error assertions |
||
|
|
d71bab0061 |
docs(im): clarify audio message opus requirement (#1271)
Fix IM shortcut behavior for audio messages to match the Feishu/Lark file upload API: --audio is for voice messages and supports only Opus audio. Non-Opus local/URL inputs such as mp3 and wav are now rejected before upload with an actionable typed validation error. Users can still send those files as attachments with --file |
||
|
|
e4248d1154 |
fix: harden lark-apps +init/+html-publish and skill guidance (#1517)
* fix: reject +init into a different app's project directory * fix: reject single HTML files larger than 10MB in +html-publish * docs: clarify publish visibility, domain routing, and role/permission boundary |
||
|
|
c4106f50b2 |
fix(mail): resolve folder/label filter once per +triage list call (#1512)
buildListParams used to re-call resolveFolderID / resolveFolderName (and the label counterparts) on every list page to assemble folder_id / label_id. Because resolveListFilter already resolves the filter once before the pagination loop, the second pass hit the folders/labels list API again on every page — 1 + page_count calls total, which easily trips rate limits. buildListParams now only assembles API params from the already-resolved FolderID / LabelID produced by resolveListFilter; it no longer resolves names or aliases. The default folder_id=INBOX is still applied when no explicit filter is present, and only overridden when the caller supplied a canonical folder ID. The runtime / mailboxID / dryRun parameters are kept for signature stability (resolveListFilter and buildSearchParams share the same call shape). Adds TestMailTriageCustomFolderResolvesOnceAcrossListPages: a custom-folder filter forced across two messages-list pages, with a non-reusable folders list stub so any second folders API call fails the test. Updated the two existing buildListParams alias tests to run resolveListFilter first, mirroring the real DryRun/Execute call order. sprint: S1 Co-authored-by: xukuncx <283114605+xukuncx@users.noreply.github.com> |
||
|
|
5efaf65aec |
feat: surface search API notices (#1413)
* feat: surface search API notices sa: safe doc: none cfg: none test: unit test * fix: surface search notices in default output * docs: add search notice doc comments * docs: expand search notice doc comments |
||
|
|
0991da7446 | fix: add missing CLI headers for git credential helper (#1539) | ||
|
|
80bea45c6a |
feat: support base record comments (#1043)
* feat: support base record comments * fix: tighten base comment validation * fix: validate wiki base comment flags |
||
|
|
9d4ae94394 | feat(slides):slide screenshot | ||
|
|
815cdb8f1c |
feat(im/convert): support content_v2 blocks in post message conversion (#1411)
Support content_v2 post message conversion in IM shortcuts so newer post payloads render with the expected markdown, mention, and image formats while preserving fallback compatibility with legacy content. |
||
|
|
96d70143c5 |
feat: support message recieve event card format (#1480)
Previously, im.message.receive events with message_type: interactive surfaced the raw JSON payload as content, requiring callers to manually parse the card schema. This PR introduces a user_dsl renderer (ConvertInteractiveEventContent) that converts interactive card content into structured human-readable text — consistent with how text, post, image, and other message types are already handled. The output format is <card title="..." subtitle="...">...</card>, with each card element type serialised to a readable representation (markdown body, button links, table rows, chart summaries, etc.). |
||
|
|
83db15907f |
Improve OKR shortcuts (#1487)
* feat(okr): add +batch-create, +reorder, +weight shortcuts Add three new OKR shortcuts for managing objectives and key results: - +batch-create: Bulk create objectives with key results, with automatic rollback on failure - +reorder: Adjust position of objectives or key results within a cycle/objective - +weight: Adjust weights of objectives or key results with automatic normalization using fixed-point arithmetic to avoid float precision issues Key implementation details: - API paths use underscore separators (/objectives_position, /objectives_weight) - Weight normalization uses json.Number for precise JSON serialization - Items are sorted by position before API calls to match backend requirements - Full unit test coverage and dry-run/live E2E tests - Skill documentation with usage examples and parameter descriptions Change-Id: I92b658e0cc42ffa8cbdaec2ec628a079bcfc38f5 * fix: skill simplify & minor fix Change-Id: I3f27a01cdae2122f26e48ee2acb7f334f2bab7d2 * fix: CR issue Change-Id: Id9fab84e06f0d67e9f79c1fb9946b6b633200592 * fix: CR issue 2 Change-Id: I6a5e57dd4b10dc79f8681ec614354fbba82abc04 * fix: error handle of +weight shortcut Change-Id: I6e2a39269e62e3b504e681110843b2ccc315a527 |
||
|
|
76f5419a0d |
feat: add +session-messages-list for session turn reply messages (#1402)
* feat(apps): add +message-get to fetch session turn reply messages * docs(apps): add +message-get skill reference * fix(apps): drop Required flags on +message-get so missing ids return structured exit-2 envelope * docs(apps): route turn reply-message queries to +message-get in SKILL.md * docs(apps): guide cloud-dev to read live turn progress via +message-get * docs(apps): note +message-get reads a still-running turn incrementally * docs(apps): route live-turn reply queries to +message-get in SKILL.md * refactor(apps): rename +message-get to +session-messages-list with page_token paging * refactor(apps): use typed errs validation in +session-messages-list * docs(apps): clarify +session-messages-list paging stops on has_more, not token |
||
|
|
c5b5aece33 |
refactor: retire legacy error envelopes and enforce typed contract (#1449)
* refactor: retire legacy error envelopes and enforce typed contract
Consolidate all command error reporting onto the typed errs.* contract, remove
the legacy error surface that predated it, and tighten the lint guards so the
contract holds across the whole repository going forward.
Every failure now reaches stderr as one envelope shape: a category, an
optional subtype, a human- and agent-readable message, and a recovery hint,
with invalid parameters listed under `params`. The legacy ExitError envelope,
its constructors, and the boundary bridge that promoted untyped config and
authorization errors are deleted, leaving a single path from error to wire.
Predicate commands keep their silent-exit behavior through a dedicated signal
that carries only an exit code.
Infrastructure paths that still emitted ad-hoc envelopes — flag parsing,
unknown commands and subcommands, plugin and policy guards, confirmation
prompts, and auth/config failures — now classify into the same taxonomy.
Business, API, auth, and config exit codes are preserved; the one behavioral
change is that Cobra usage failures (missing required flag, unknown command,
bad arguments) now emit the typed validation envelope and exit 2, matching the
explicit flag and subcommand guards, instead of Cobra's plain-text exit 1.
Enforcement is repo-wide rather than per-path:
- The errscontract guards run by default everywhere instead of through a
migration allowlist, so legacy envelopes cannot be reintroduced anywhere.
- errorlint runs across the whole repository: every error wrap must use %w and
every comparison must use errors.Is/errors.As, so interior wraps stay legal
but can no longer break the chain the typed boundary relies on.
- The errs-no-bare-wrap guard is keyed by structural prefix instead of an
explicit per-domain allowlist, so new shortcut domains are covered without
editing a list. It runs where forbidigo is enabled (the shortcut domains and
the auth/config/service command groups); repo-wide chain integrity for the
remaining command paths is carried by errorlint above.
* test: align cli_e2e success assertions to the ok envelope
The api and service success path now emits the {"ok":true} envelope, so the
cli_e2e workflow assertions that still expected the old {"code":0} shape via
AssertStdoutStatus(t, 0) fail once they run with live credentials. Switch those
workflow assertions to AssertStdoutStatus(t, true); the fake-payload helper test
in core_test.go keeps its code-shape assertion.
|
||
|
|
4a4c3344c8 | fix: align api success envelopes (#1489) | ||
|
|
c61acb5264 | feat: add ci quality gate | ||
|
|
7eeb111a2d | fix: reject out-of-range base pagination flags (#1495) | ||
|
|
4464ba7660 |
fix: validate drive import folder target (#1485)
Change-Id: I43755c3966b0daa06b708d2b3d03294f439547fa |
||
|
|
bb03c8ac4d |
feat(vc): support agent meeting event workflows (#1483)
* feat: support vc agent active meetings
* docs: clarify vc agent active meeting flow
* fix: align active meeting shortcut scope
* docs: clarify active meeting id fields
* fix: reject meeting numbers for vc events
* docs: clarify vc agent active meeting flow
* docs: refine vc agent meeting flow guidance
* docs: address vc agent skill review feedback
* docs: clarify vc meeting product wording
* docs: align vc agent skill with quality guidelines
* docs: trim vc agent skill token budget
* Revert "docs: trim vc agent skill token budget"
This reverts commit
|
||
|
|
3feb70b32a |
feat(drive): 支持导出 Base 结构快照 (#1481)
1. 为 drive +export 增加 --only-schema 参数,并透传 only_schema 到导出任务请求。 2. 限制该参数仅用于 bitable 导出 .base,并补充单测与 dry-run E2E 覆盖。 Change-Id: I736cebf5841cc1c6acaa8a3ab16be51ba4cb355d |
||
|
|
64b1b3f3ed | feat(docs): support lang for fetch v2 (#1459) | ||
|
|
a0e83c7e59 |
feat(docs): add docx cover resource commands (#1468)
Spec source: active@bd186a6373948acc76d8b0872334b1a53ad40f5645b1a4e129937d7a51f5596c |
||
|
|
cf35d1e499 |
feat(mail): auto-attach default signature on send/reply/forward (#1415)
* feat(mail): auto-attach default signature on send/reply/forward - Add exported PlainTextFromHTML wrapper in draft/htmltext.go - Add DefaultSendID/DefaultReplyID in signature/provider.go - Add noSignatureFlag, autoResolveSignatureID, validateNoSignatureConflict, injectPlainTextSignature in signature_compose.go; remove validateSignatureWithPlainText - mail_send, mail_draft_create: add --no-signature flag, auto-resolve default signature when no --signature-id given, inject plain-text sig in plain-text branch - mail_reply, mail_reply_all, mail_forward: same flag/validate changes + timing fix (resolveSignature moved to after senderEmail is finalized) - Update 5 reference docs: add --no-signature row, update --plain-text and --signature-id descriptions --------- Co-authored-by: xzcong0820 <278082089+xzcong0820@users.noreply.github.com> |
||
|
|
6217bd2c29 | fix docs fetch and update ergonomics (#1466) | ||
|
|
72c294712c |
feat: 【larksuite/cli】【drive 搜索支持 original_creator_ids】 M-7074213537 (#1046)
sa: none fg: none cfg: none doc: none test: ppe Change-Id: I88bedd02a5daa3307b05c9b6f94748e1544d279a |
||
|
|
0fbfe68726 | docs: drop Miaoda brand word from apps command help text (#1399) | ||
|
|
693e299589 |
docs(mail): clarify message read shortcuts (#1261)
* docs(mail): clarify message read shortcuts Update mail read shortcut help, docs, and triage guidance so single-message and multi-message reads are routed to the right commands. Add focused tests for help text, dry-run copy, triage stderr hints, and batch_get chunking behavior. sprint: S1 * docs(mail): align batch_get limit with gateway config * docs(mail): use shell-safe batch message id examples * docs(mail): trim batch_get pagination wording * docs(mail): use placeholder style for message ids * docs(mail): hide batch_get internals from help |
||
|
|
1cd7a88597 | fix: read release error_logs from data.error_logs in apps +release-get (#1436) |