Commit Graph

1030 Commits

Author SHA1 Message Date
陈兴炀 d7873bda96 feat(apps): add standalone database commands and extend the db family
Aily × PaaS 独立数据库的 CLI 落地:9 条新命令 + 5 条存量命令支持独立库。
命令面全部对齐设计文档 https://bytedance.larkoffice.com/docx/UwqJd0yt6oCB2Ox8pglcQe2BnEe

新增 9 条
- 生命周期:+db-create / +db-list / +db-delete
- 权限:    +db-permission-list / -set / -revoke(只认 --database-id)
- MCP:     +db-mcp-enable / -disable / -get(--app-id 或 --database-id 二选一)

存量 5 条支持独立库(+db-execute / +db-table-list / +db-table-get /
+db-data-import / +db-data-export)
- 新增 --database-id,与 --app-id 二选一,统一走 requireDBResource;--app-id 的
  Required 随之去掉,否则 cobra 会在二选一判定之前拒掉只传 --database-id 的调用
- 路由按标识分流:两套 path 函数并列,不在存量函数里加 if
- App 支路行为逐字不变(BOE e2e 291 用例验证,见下)

几个刻意的设计点
- 独立库无环境概念:这些命令不带 env 键,显式传 --environment 在 Validate 阶段拒;
  判据用 Changed() 而非取值,否则「吃到默认值」会被误判成显式传参
- 表名不进路径段:独立库走 /table?table=xxx。url.PathEscape 挡不住 "..",让它进
  路径段会被规范化到上一级、打到别的接口上(App 支路的 /tables/{table} 属存量债)
- DryRun 与 Execute 共用同一个分派函数:dry-run 是 agent 唯一的自检手段
- +db-execute 独立库支路不发 transactional:该接口固定 DBA 模式,给个恒为 false 的
  参数只会让人以为传 true 能拿到事务
- +db-mcp-* 两支路径域段不对称:/databases/{id}/mcp vs /apps/{id}/db/mcp(多一段 db/)
- 输出不伪造服务端状态:+db-delete 的 deleted、+db-mcp-* 的 enabled 都取服务端结果

errclass 登记 3 个业务码(400002900 / 400002901 / 500002901)。这批是设计文档里的
占位码,服务端发号后需回来对齐真值;未命中时框架兜底成 api/unknown。

测试:新增 10 个测试文件(一命令一测),apps 域命令数断言 96 → 105。
BOE e2e(存量套件、只走 App 支路)291 用例 287 通过,2 个失败是 BOE 审计链路的
服务端故障(dataloom 调火山 ModifyTransmissionTask 返 400 及其级联),与本次改动无关。

服务端接口尚未实现(IDL 见 idl-larkgw 的 feat/standalone_db),故 --database-id
支路目前只能验到 dry-run 与参数校验层。
2026-08-13 21:08:51 +08:00
zgz2048 e1f9872c56 chore: add Base skill code owner (#2303)
* chore: add Base skill code owner

* chore: add another Base skill code owner
2026-08-11 20:36:15 +08:00
zgz2048 8b824b03ae feat(base): add typed NDJSON workflows for professional data analysis (#2196)
* feat(base): add typed NDJSON data analysis workflow

* docs(base): simplify cloud pagination guidance

* docs(base): clarify Link relation IDs

* feat(base): query NDJSON records with jq

* docs(base): route analysis through built-in jq

* docs: clarify per-table local analysis limit

* docs: simplify base analysis guidance

* docs: centralize base analysis routing

* docs(base): refine cell value and datetime guidance

* test(base): align ignored field fixtures

* docs(base): add semantic analysis routing

* feat(base): improve NDJSON analysis workflow

* docs(base): centralize filter predicate examples

* feat(base): clarify record get export scope

* feat(base): improve ndjson analysis workflow

* docs(base): refine local analysis guidance

* feat(base): resolve record search limit by format

* refactor(base): keep ndjson jq handling local
2026-08-11 20:27:37 +08:00
liangshuo-1 defd27b9d2 chore: release v1.0.86 (#2301) v1.0.86 2026-08-11 19:54:24 +08:00
ethan-zhx 7436a53afc feat(slides): inline slides reference docs into help output (#2181) 2026-08-11 19:29:57 +08:00
木杉 4488da0b14 feat(apps): add +user-id-convert shortcut for Miaoda↔Feishu ID conversion (#2270)
* feat(apps): add +user-id-convert shortcut for Miaoda↔Feishu ID conversion

Wrap the platform id_convert OpenAPI as a read-only shortcut that maps
Miaoda user_id ↔ Feishu open platform IDs (open_id / union_id / Feishu
user_id). It does one thing — conversion — with no local mapping table,
caching, permission pre-check, or direction guessing.

- --convert-type enum → server id_convert_type (10/11/20/21/40)
- --ids: csv / @file / stdin, 1-100 per call, not de-duped, input order
- reconstructs data.missed by diffing input positions against returned
  source_ids (server silently drops unresolved IDs), keyed by 0-based index
- meta counters (total/hit_count/missed_count) via pointer fields on
  output.Meta so an explicit missed_count: 0 survives omitempty

* test(apps): address review feedback on +user-id-convert

- reject empty --ids CSV entries (e.g. "a,,b") with a typed validation
  error instead of silently dropping them, since a dropped entry shifts
  every later result's 0-based index and breaks the position-keyed
  items/missed contract; add an interior-empty-element test
- reuse common.GetSlice / common.GetString for response projection
  (house convention) instead of local asSlice/asString helpers
- requireConvertValidation now asserts CategoryValidation +
  SubtypeInvalidArgument via errs.ProblemOf, keeping ValidationError.Param
- table-drive TestResolveConvertType over all five directions so every
  --convert-type → id_convert_type mapping (10/11/20/21/40) is protected

* fix(apps): split newline-delimited --ids for +user-id-convert @file/stdin

@file and - (stdin) input arrives verbatim from the framework as
one-ID-per-line text, but parseConvertIDs only split on commas, so such a
block was sent as a single malformed request ID. Treat a newline as
equivalent to a comma, tolerating a file's trailing newline while still
rejecting interior empty entries so position-keyed result indices stay
aligned. Add @file and stdin tests asserting the request body's ids are
split into discrete IDs.

* fix(apps): stringify numeric JSON IDs in +user-id-convert results

Responses decode with json.Number (client.ParseJSONResponse uses
dec.UseNumber()), so a server that emits source_id/target_id as bare
numbers — plausible for the numeric Miaoda user_id form — was silently
coerced to "" by buildConvertResult's strict string assertion: the
source_id got dropped (false not_found) and the target_id blanked
(false success).

Add common.GetStringLoose, which stringifies string/json.Number/int64/
float64 via literal text (large integer IDs keep full precision, never
routed through a lossy float64), and use it for both id reads. Cover it
with a package-level table test plus an end-to-end regression asserting a
numeric-JSON response yields intact, non-blank ids and no false miss.

Also exercise resolveConvertType's non-empty "not a valid direction"
branch directly, since the runner's enum gate preempts it in normal flow.

* test(common): tighten GetStringLoose numeric coverage

Add an int-branch case (was only covering int64) and swap the float64
fixture from 42 — which no formatter would render in exponent form — to
1e-7, whose fixed-point rendering "0.0000001" fails under the 'g' verb.
This turns the "no scientific notation" case into a real guard for the
'f' verb choice, per CodeRabbit review on c64cca39.
2026-08-11 19:14:52 +08:00
guokexin.02 115357d5c5 ci: verify release Go toolchain (#2256) 2026-08-11 18:24:17 +08:00
jinjiuzhe 158d15b3fd feat: add apps database sync shortcuts for Base-to-database import (#2251)
* feat: add apps database sync shortcuts

Add Base-to-database sync shortcuts for preview, create, list, get, enable, disable, update, and delete flows.

Cover OpenAPI request contracts, typed sync error classification, dry-run E2E coverage, and lark-apps skill guidance.

Co-authored-by: TRAE CLI <noreply@bytedance.com>

* fix(apps): send db-sync task_id and config in request body

The enable/disable/delete/update sync commands placed task_id (and
update's config) in query params, but the OpenAPI contract binds these
fields via api.json (request body). BOE testing returned
"field validation failed" (99992402) because the body was empty.

Move task_id to the request body for enable/disable/delete, and move
both task_id and config to the body for update. Dry-run previews now
render these under body, and unit tests pin the body binding so a
regression to query params fails.

* fix(apps): use POST for db-sync-delete action endpoint

The delete command issued an HTTP DELETE to db/sync_del, but the
action-style endpoint is registered as POST (like sync_create and
sync_disable). The method mismatch made the gateway return a plaintext
404, surfacing as "API returned a non-object JSON response".

Switch the request and dry-run preview to POST, and pin the method in
the delete unit tests so a regression to DELETE fails.

* test: pin db-sync update base_url as optional contract

* test: pin db-sync update omits base_url without silent default

* docs(skills): clarify db-sync source.base_url create-required update-optional contract

* fix(apps): send db-sync env in request body not query params

The +db-sync-create and +db-sync-update endpoints read env from the
request body (peer of config/preview/task_id), not the query string.
Placing env in query params left the body env empty, so the server
treated every request as online and rejected DDL operations
(code 500002776: forbid ddl/dcl operation in online env), making it
impossible to create/update sync tasks against a dev environment.

Move env into the request body via a new dbEnvBody helper that mirrors
dbEnvParams' omit-empty contract, so unset env still lets the server
auto-select the branch. Pin the contract in unit and e2e dry-run tests
by asserting body.env and that env is absent from query params.

* test: align db-sync operate/delete e2e with request-body contract

The enable/disable/delete dry-run e2e still asserted the pre-migration
wire shape: delete on DELETE and task_id in query params. The shortcuts
now POST these actions with task_id in the request body (commits moving
task_id and the delete verb), so the stale assertions failed against a
current binary.

Assert POST + body.task_id and that task_id is absent from query params,
pinning the same body-over-query contract the env fix established.

* fix(apps): improve db-sync create ergonomics and error guidance

Refine +db-sync-create/update validation, error hints, and docs so AI
agents recover from common Base-to-database sync failures without guessing:

- source.table.name: document that a user-named table must be set, name
  takes precedence over the base_url ?table= token; fix test fixtures that
  used a fictional source.table.url instead of source.base_url.
- Preflight source table locate: reject create locally when base_url has no
  ?table= and source.table.name is empty, pointing at base +table-list.
- Online DDL ban: attach a precise hint for code 500002776 + subcode
  k_dl_4000001 telling multi-env apps to create tables on --environment dev.
- Missing record-id column: extend the 500002783 hint to add a unique text
  column via +db-execute before retrying.
- Optional field_maps on create: allow omitted or empty field_maps so the
  server auto-matches and creates the task; keep update requiring an enabled
  mapping and still reject an all-disabled array.
- Environment default: db-sync commands use online when --environment is
  omitted; align help text, comments, and skill docs.

* fix(apps): migrate db-sync error codes to the 4xx client-error range

The backend moved the seven db-sync error codes from the 5000027xx
server-error range to the 4000024xx client-input range to reflect that
they are client-input errors. Mirror the new codes in the CLI so error
classification and recovery hints keep matching:

- 500002783 -> 400002477 (mapping invalid)
- 500002784 -> 400002478 (target schema mismatch)
- 500002785 -> 400002479 (operation not allowed)
- 500002786 -> 400002480 (task not found)
- 500002787 -> 400002481 (invalid task id)
- 500002788 -> 400002482 (source table not found)
- 500002789 -> 400002483 (target table not found)

Category, subtype, hint text, and behavior are unchanged; 500002776
(online DDL ban) is untouched.

* fix(apps): tighten db-sync preview validation and pretty output

Address review follow-ups on the db-sync shortcuts:

- +db-sync-get pretty output no longer prints <nil> for a missing
  schema_only nor Go map syntax for statistics; render a bare bool and
  deterministic key=value pairs instead.
- Reject a non-array field_maps in +db-sync-create --preview as well as
  commit, so the malformed shape is caught locally rather than forwarded
  to the backend.
- Clarify in lark-apps-db.md that +db-sync-create --preview needs no
  confirmation and only a real create requires --yes.
- Harden the db-sync dry-run validation tests to assert exit code 2 and
  the structured stderr envelope (type/subtype/param), and add coverage
  for the preview non-array field_maps rejection and batch pretty output.

* fix(apps): guard db-sync preview output and neutralize update hint

Address the next db-sync review round:

- +db-sync-create --preview --output no longer writes a "null" file and
  exits success when the response omits data.config; project config into
  a typed object and return internal/invalid_response without writing.
- Make the 400002482 code hint command-neutral so +db-sync-update is not
  steered into a create-only recovery path that risks duplicate tasks.
- lark-apps-db.md: carry --environment on the update lifecycle examples
  and split failure recovery by streaming (can update) vs batch (cannot
  update; recreate instead), removing the batch/update contradiction.

---------

Co-authored-by: TRAE CLI <noreply@bytedance.com>
2026-08-11 18:21:32 +08:00
SongHantian 5028c2e6ff feat(drive): document copy workflow guidance (#2184)
* docs(drive): streamline copy workflow guidance

* docs(drive): clarify copy recovery and search pagination

* docs(drive): clarify copy then prepend workflow

* docs(drive): generalize copy workflow guidance

* docs(drive): clarify copy post-processing boundaries

* docs(drive): restore shared skill prerequisites

* docs(drive): simplify copy workflow guidance

* docs(drive): trim redundant copy workflow guidance

* docs(drive): focus copy guidance on title search

* docs(drive): centralize title-copy routing
2026-08-11 17:56:21 +08:00
ILUO b9cced677a feat: expose compact task fields (#2109)
* docs: define task compact field projection

* docs: add task compact fields implementation plan

* feat: add task output field projector

* feat: expose missing fields in task summaries

* feat: expand task write result fields

* feat: expose fields in nested task results

* chore: remove internal planning artifacts

* docs: require progressive task command discovery

* docs: require schema-backed task create data
2026-08-11 17:54:06 +08:00
R0bynZhu 169e30c6b8 docs(slides): use built-in --jq in cli examples and fix workflow link labels (#2286)
* docs(slides): use built-in --jq in cli examples and fix workflow link labels

* docs(slides): use built-in --jq instead of external jq pipe for output filtering
2026-08-11 17:53:03 +08:00
calendar-assistant a80c8103bc docs(calendar): clarify identity selection for scheduling (#2280)
Agents misread colloquial pronouns when creating events. Two fixes in
the calendar skill:

- SKILL.md: pronouns that are field values (attendees, meeting owner)
  do not participate in `--as` identity selection, so "会议 owner 为我"
  no longer flips bot-identity creation to user identity. "我" = the
  logged-in user, "你" = the application (bot).
- create.md: the raw calendar events/attendees API does not auto-add the
  calling identity as +create does; guide callers to add the caller's
  open_id as a user attendee when using the full API flow.
2026-08-11 16:55:33 +08:00
liangshuo-1 79eb16c50b feat(affordance): support domain skill lists (#2291)
Co-authored-by: liangshuo-1 <266696938+liangshuo-1@users.noreply.github.com>
2026-08-11 16:27:37 +08:00
zhangjun-bytedance 6d6b6889a9 feat: support bot identity (#2288) 2026-08-11 15:43:58 +08:00
liujinkun2025 b1167a15ff fix(wiki): clarify resource permission recovery (#2281) 2026-08-11 15:05:18 +08:00
fangshuyu-768 82e628bf79 fix(drive): harden export and push failure recovery (#2279) 2026-08-11 14:20:42 +08:00
CarolSum d289566ad0 feat(base): require --fields on +table-create (#2221)
* feat(base): require --fields on +table-create

A table created without --fields gets the platform default schema. Those
default fields then sit in the table alongside every field the caller adds
afterwards, and no field command removes them all, so the only clean recovery
is to drop the table and start over.

Make --fields required so the schema is declared up front, the way
+base-create already recommends via --table-name + --fields.

- Mark --fields Required on +table-create, and reject blank / non-array /
  empty-array values in Validate: cobra's MarkFlagRequired only checks that the
  flag was set, so --fields "" and --fields "[]" would still reach the API with
  no fields body and fall back to the default schema.
- Validate runs ahead of the dry-run branch, so --dry-run can no longer preview
  an invocation the real call would reject.
- Update the lark-base skill, e2e coverage notes and the live e2e helper.

BREAKING CHANGE: `lark-cli base +table-create --base-token <t> --name <n>`
without --fields now fails with a validation error instead of creating a
default-schema table. Callers that relied on create-empty-then-add-fields must
pass the schema to --fields.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(base): pin typed metadata on the invalid-schema rejection

Address review feedback on the +table-create schema validation.

- The invalid-fields-JSON rejection now asserts category, subtype and param
  through assertInvalidArgumentValidation, plus the preserved *json.SyntaxError
  cause, instead of only asserting that some error came back.
- Document why the missing-flag test asserts cobra's text rather than errs
  metadata, and pin that layer boundary: cobra's ValidateRequiredFlags emits a
  plain error and the dispatcher types it later (cmd/root_test.go). The test now
  fails if that boundary moves, so the weaker assertion cannot silently outlive
  its reason.
- Reword the --fields tip and the lark-base skill note: both described the
  fieldless path as if it were still reachable through +table-create. They now
  say the command rejects omitted / blank / empty schemas up front, while
  keeping why the schema must be declared here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs(base): enrich +table-create field example and drop redundant tips

The cobra Required declaration and flag Desc already advertise the
--fields requirement, so the tips paragraph restating it (and its
SKILL.md / coverage.md echoes) is dropped. The select-field example
now carries multiple/hue/lightness so agents copy a complete option
shape.

* chore: remove useless example

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 10:56:41 +08:00
liujinkun2025 a18ccd6c4e feat(wiki): improve node creation and terminal errors (#2266) 2026-08-11 10:05:11 +08:00
zhicong666-bytedance 841953496b feat: support shared vc live references and document context (#2249)
* feat: parse document context meeting events

Source-Branch: features/F-larksuite-cli-document-context
Source-Commit: 427cbd6492
Source-Subject: fix: normalize mail triage filters (#2068)
Repo: larksuite-cli
Synced-By: bytedance
Timestamp: 20260803_093803Z

* test: assert ndjson section path semantically

Source-Branch: features/F-larksuite-cli-document-context
Source-Commit: 9b8bafeff4a5063347aa1e0c32e501669381e217
Source-Subject: feat: parse document context meeting events
Repo: larksuite-cli
Synced-By: bytedance
Timestamp: 20260803_095353Z

* fix: nest document context output and align slides aliases

Source-Branch: features/F-larksuite-cli-document-context
Source-Commit: 94ad66b5d4
Source-Subject: test: assert ndjson section path semantically
Repo: larksuite-cli
Synced-By: bytedance
Timestamp: 20260803_124142Z

* fix: preserve meeting event output contract

* fix: remove document context fallback projection

* refactor: reuse meeting event actor extraction

* refactor: simplify document context event handling

* refactor: reuse meeting timeline ordering

* test: align document context timeline order

* feat: support BOE endpoint overrides

* feat: share vc meeting references across skills

* docs: clarify shared document event correlation

* revert: remove local BOE endpoint overrides

* fix: compact document context events consistently

* docs: prefer pretty format for meeting events

* fix: harden document context event rendering

* docs: clarify active meeting discovery in vc skill

* fix: improve vc meeting event guidance

* fix: clarify live meeting content routing

* fix: require pretty output for meeting content

* docs: explain meeting event json cost

* fix: compact transcript speaker labels

* fix: correct vc identity guidance

---------

Co-authored-by: renaocheng <renaocheng@bytedance.com>
2026-08-10 23:25:56 +08:00
ethan-zhx ed650498bc fix(slides): move add-slide and delete-slide reference docs to cli/ directory (#2272)
These two files are CLI command references, not XML schema references.
Move them from references/xml/ to references/cli/ and update all cross-file
links in SKILL.md, cli/*.md, workflow/*.md, and the compatibility stubs.
2026-08-10 21:50:16 +08:00
zhaojiaxing-coding bd38b9b3c4 feat(drive): add +member-remove shortcut (#1994)
Add drive +member-remove for removing one collaborator permission from Drive documents, files, folders, wiki nodes, and Miaoda apps. The shortcut validates resource and member contracts before issuing the high-risk DELETE request, preserves structured CLI errors, and documents identity and wiki permission behavior.

Key features:

- Resolve resource type from supported URLs or require it for bare tokens

- Accept Miaoda apps via /page/ URLs or explicit --type=apps

- Support user and bot identities with member-type-specific validation

- Require explicit confirmation and return stable removal metadata

- Reject unsupported slash-containing tokens and member IDs before API calls

- Add unit, dry-run E2E, live workflow, and skill documentation coverage
2026-08-10 21:23:26 +08:00
ethan-zhx 70ca6e2309 docs: document supported image formats in lark-slides media-upload (#2269)
The --file parameter only accepts png, jpeg, gif, bmp, tiff, and webp.
Server returns 4000150 for unsupported formats.
2026-08-10 19:54:27 +08:00
liangshuo-1 8a5afa976f docs: improve agent contribution guidance (#2259) 2026-08-10 19:38:19 +08:00
tianyouskrrr 7cfbea68d9 feat(slides): normalize replace-slide part aliases (#2225)
Normalize deterministic +replace-slide part aliases (replace→block_replace,
target_id→block_id, and payload field folding), and reject semantically
different actions up front.

Point whole-page actions at +update-slide now that it is GA:
- page_replace / slide_replace recovery guidance and the reference error
  table now direct callers to `slides +update-slide` (in-place whole-page
  rewrite) instead of the deprecated +replace-pages.
- drop the +replace-pages reference doc, completing the #2227 deprecation
  (the command stays; its deprecation signal is carried by --help and the
  output JSON `deprecated` field).

Generalize whole-page validation gating to the behavior rather than a
command name (SKILL.md, workflow/validation-xml.md): "整页写回后" instead of
"每次通过 +update-slide 整页写回后". Folds in PR #2255.
2026-08-10 19:28:03 +08:00
zhoujunteng-max 5b734238d7 feat: report upload file events (#2093)
* feat: report upload file events

* test(drive): skip import workflow without tenant token

* docs: document upload report helpers

* docs: improve function documentation coverage

* docs: complete incremental function documentation

* docs: complete function documentation coverage

* fix: report every upload file event

* refactor: move file event reporting to internal package

* fix: harden upload file event reporting

* fix: omit upload mode from file event reports

* test: fix workbook import dry-run token assertion
2026-08-10 19:12:38 +08:00
ethan-zhx 2016120bd0 chore: prune unsupported iconpark index entries (#2252) 2026-08-10 12:53:19 +08:00
ethan-zhx 199762bc0c refactor: reorganize lark slides skill references (#2207) 2026-08-10 11:14:24 +08:00
zcc 7be247614d feat(drive): add wiki url/token support to +download and +preview (#2220)
Extend +download and +preview to accept --url and --wiki-token in
addition to --file-token (mutually exclusive). Wiki nodes are resolved
to their underlying object; only file-backed nodes are supported, and
non-file documents (docx/sheet/bitable/slides) return a typed
validation error hinting to use +export.
2026-08-08 11:02:16 +08:00
fangshuyu-768 fb4fc26d58 fix(wiki): correct copy semantics and rename routing (#2238) 2026-08-08 10:26:20 +08:00
liangshuo-1 13305ae51b chore: release v1.0.85 (#2242) v1.0.85 2026-08-07 19:19:20 +08:00
wangweiming-01 0f82591303 feat: preflight export permission for downloads (#2218)
Check Drive export permission before file and document media downloads, while preserving whiteboard behavior and adding actionable preview and rate-limit recovery hints.

Spec source: active@ddbecbafcf0d68cc115faf3fcf0214fb6edc30b284147d33e5c9934e7bad82b4
2026-08-07 18:41:34 +08:00
SunPeiYang996 a6f3e635d4 feat(docs): add local authoring and resource workflows (#1921)
* feat(docs): add local authoring and resource workflows

Add docs +script workflows for isolated draft initialization and tolerant XML/Markdown profiling.

Support local and remote document resources across create and update flows with safe, bounded-concurrency uploads, binding verification, and cleanup.

Synchronize shared credential-source selection during concurrent uploads, refresh lark-doc guidance, and expand unit, dry-run, and live E2E coverage.

* docs(lark-doc): clarify genre reference paths

* fix(docs): address PR validation feedback

* docs(lark-doc): clarify remote image handling

* feat: streamline docs draft workflow

* fix(docs): clarify script input and resource cleanup

* fix(docs): align script dry-run test with auth flow

* fix(docs): authenticate local script e2e test

* fix(docs): refine script diagnostics and image preflight

* fix(docs): align draft workspace cleanup with VFS

* fix(docs): route workspace cleanup through FileIO

* docs(lark-doc): simplify profile check guidance
2026-08-07 18:15:28 +08:00
liangshuo-1 0d6f2c65d7 fix(im): harden resource downloads with validated ranged streams (#2223) 2026-08-07 17:45:40 +08:00
BD-ZERO 771ff44def fix: align slides xml-get skill flags (#2237)
Document the --raw, --slide-id, and --slide-number flags for slides +xml-get, including their mutual-exclusion rules and usage examples.

Clarify single-slide versus full-presentation output behavior, and remove the shallow documentation-only regression test.
2026-08-07 17:24:30 +08:00
R0bynZhu 46e2186adf feat(slides): accept slide XML files in +create (#2197)
Assembling the --slides JSON array by hand is what callers keep getting
wrong. A page of SML is multi-line and quote-heavy, and shell has no
built-in way to JSON-escape it, so callers reached for `jq -n --rawfile`
to build the array. In environments without jq the substitution silently
became an empty string and the command ran on to create an empty deck,
or the half-escaped XML reached the backend and came back as an opaque
3350001 after the presentation already existed.

Two input forms remove the escaping step:

  --slides now declares Input{file, stdin}, so a finished array can be
  read with `--slides @deck.json` or piped in with `--slides -`.

  --slide is repeatable, takes one complete <slide> document (or @path),
  and the CLI assembles the array. Repetition order is page order.

The forms are mutually exclusive: merging them would make page order
depend on flag-parsing rules nobody wants to reason about.

Notes on the repeatable flag: the framework only resolves Flag.Input for
single-valued string flags, so --slide resolves @path itself, through
the same cmdutil.ReadInputFile the framework uses, keeping the
"relative path under the current directory" rule identical. It rejects
"-" outright, because a process has one stdin and that cannot mean "this
occurrence" on a repeatable flag; the error names both forms that work.

Structural validation now runs on the assembled array, so both forms
fail the same way, and it runs before the create call so a malformed
page can no longer leave an orphaned empty presentation behind.

Three inputs the first round of review found still slipping through are
now rejected or normalized before the create call. `--slides null` is
valid JSON for a slice, so it parsed without error and left the array
nil, which read as "no pages given" and produced the blank deck
reported as success that the empty-value check exists to prevent. An
`<?xml ...?>` prolog is well-formed XML, so the parser accepted it and
only the backend rejected it, with 4001000 buildSnNode, after the
presentation already existed; it is now caught in the shared slide
validator, which covers +add-slide and +replace-pages too. And a
leading UTF-8 BOM made `--slide @page.xml` reject a file that
`--slides @deck.json` accepted, because the framework strips it for
Input flags and the repeatable flag resolved @path itself;
StripUTF8BOM is exported so both paths normalize the same way.

Also threads the source flag name through uploadSlidesPlaceholders,
which previously reported +add-slide upload failures as --slides.

Docs: the create/troubleshooting references now teach the file inputs
instead of the jq array-building template, and the follow-up snippet
uses the CLI's own --jq instead of piping to an external jq.
The lint gate in SKILL.md now names `slides +create` as a whole rather
than only its --slide form.
2026-08-07 17:03:03 +08:00
tianyouskrrr bc0ba2252a fix(slides): restore update-slide skill guidance (#2227) 2026-08-07 16:36:17 +08:00
yxy-bd db102ab314 feat (apps): add miaoda app collaborator management (#2230)
* feat: add miaoda app collaborator management

* refactor: remove collaborator list pagination

* fix: make external invite setting read-only

* fix: make Miaoda copy setting read-only

* docs: record BOE collaborator verification

* fix: remove unsupported Miaoda setting flags
2026-08-07 16:20:02 +08:00
huarenmin13 7c4f6c023f fix(base): improve field creation and query guidance (#2114)
* fix(base): improve field creation and query guidance

1. Document batch field creation in shortcut help and the delivered Base skill.
2. Choose field types from stored values instead of business-purpose names.
3. Add generic common filter values to the data-query quick guide with contract tests.

说明:
- Combines the accepted fixes for base_table_096, base_table_028, and base_table_087;
    MR 1275 contributes round 4 only.

```ai-signature
改动范围: Base field-create 帮助与 Skill 指南、data-query 快速指南,以及对应的 shortcuts/base 契约测试
思考过程: 保留三个实验的最终通用规则,合并 public main 上新增的字段读回提示,并排除没有 benchmark 支撑的 MR 1275 round6
改动原因: 让代理发现批量字段接口、按存储值选择字段类型,并用常见通用形状构造 data-query 过滤条件
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: a53fdb6b6b82d74e4deff5e6d32591ec897cd2dc6ad662885c961a27e67d4666

* test(base): strengthen guidance contracts

1. Assert every common filter fragment introduced by the data-query quick guide.
2. Keep the field-create argument table compliant with markdown table spacing.

```ai-signature
改动范围: data-query 指南契约测试与 field-create Markdown 表格后的空行
思考过程: 逐条核对 CodeRabbit 建议,只补会防止新增指南片段回退的断言和确定性的 MD058 格式问题,不改生产提示语义
改动原因: 关闭 PR 2114 的两条有效自动审查意见并保持变更可回归
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 81096f474001f2c9c59af48ee64150f205101710ebcf3b909ab9d300a019f46f

* fix(base): generalize data-query filter guidance

1. Replace the date-and-status scenario template with reusable Condition.value shape rules.
2. Update the contract test to require relative-date guidance and reject evaluation-shaped placehold
    ers.

```ai-signature
改动范围: lark-base data-query quick guide 与对应 shortcuts/base 契约测试
思考过程: 保留 select、datetime、empty 的通用 value shape,删除日期字段和状态字段组合模板,避免将 base_table_087 的解题路径固化到公共指南
改动原因: benchmark 显示当前文案能引导目标题,但组合示例与测试过度贴合单题,需要收敛为跨场景可复用的不变量
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 7b6916f05dccf6489dce65610fe757f7b346bcd0f8f5500cfbfb1f30c60471f3

* fix(base): generalize creation guidance

* fix(base): report partial field-create results

* fix(base): preserve partial field-create recovery metadata

* fix(base): separate partial field recovery

* perf(base): 缩短字段批量创建的空等

1. 将固定 1 秒批次等待改为 500ms 最小请求起点间隔,并让请求耗时抵扣等待
2. 新增节流计算契约测试,覆盖首次请求、快速响应和慢响应
3. 同输入 150 字段 A/B 从 269.64s 降至 118.80s,且两侧均创建 150/150

说明:
- 保持同表写入串行和 partial failure 输出不变

```ai-signature
改动范围: shortcuts/base/field_ops.go 与 shortcuts/base/base_execute_test.go,仅调整 field-create 数组批次的串行节流计算和回归测试
思考过程: 保留同表串行写入,以 500ms 作为请求起点最小间隔,并把请求耗时计入间隔,避免固定空等同时降低写冲突风险
改动原因: PR 引导 Agent 使用数组批量创建后触发既有每项固定 1 秒等待,导致 150 字段用例产生约 149 秒可归因耗时回退
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 69b888d362d2f484c4ce6ad050bdbfe2de7368948eb79ba516bcaa6806ec9107

* fix(base): 收紧不支持字段行为的终止边界

1. 派生、自动、同步或回填行为只使用已记录能力,无法实现时禁止探测、占位或虚假完成
2. 删除 data-query 契约测试对旧题模板占位符的反向黑名单,只保留原子规则和真实 case 污染检查
3. field-create 指引替换前后均为 36 个英文词,不扩大该帮助项的词数

```ai-signature
改动范围: shortcuts/base/field_create.go、base_shortcuts_test.go 与 data_query_guide_contract_test.go,仅收口通用终止规则和测试泛化
思考过程: 采纳 review 中可独立闭环的两点,不增加翻译专用规则,不修改运行时能力;用等词数替换避免帮助上下文继续增长
改动原因: 当前规则能阻止按业务名猜字段类型,却仍允许退化成普通文本占位;同时测试记住旧题模板会阻碍未来合理示例
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 759b7f4044c6381b963c8ea299b70967e634ab9d43b6ebfbe94ef38bb69ba46a

* perf(base): 压缩字段批量创建的评测开销

1. 批量成功与部分失败仅返回字段 id/name/type,保留恢复所需身份并减少大响应上下文
2. 引导数组在调用方超时范围内一次提交,并为生成的大数组推荐 @file 或 argv-safe 调用
3. 字段列表默认页大小提升到 API 上限 200,避免百字段以上场景的帮助查询与重试

说明:
- 同口径 case032:raw token 432292→428304,weighted token 126408→117761,耗时 272675ms→235022ms,两侧均读回 154 字段

```ai-signature
改动范围: Base field-create 批量输出、帮助提示、field-list 默认分页及对应契约测试与 Skill 返回说明
思考过程: 从同口径 trace 定位固定分块、大字段对象回传、100 条分页和 shell 双重转义四个确定性开销,保持单字段与部分失败恢复语义不变并逐项用测试锁定
改动原因: PR 引导数组批量创建后虽降低耗时,但多回合大输出会推高 raw token;需要在不牺牲正确率和恢复信息的前提下同时压缩 token 与耗时
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 8a2bd2d79c9abdb1e36ae45822dd04b2a3384498a1dc268cffcd47cff00d94ed

* perf(base): 收敛字段批量创建的上下文

1. 大数组成功路径推荐保留摘要的 --jq 投影,失败路径仍原样保留部分失败明细
2. 为一个或多个简单 text 字段提供 help fast path,并让 next_step:done 终止默认回读
3. 补充 Skill、帮助与执行结果契约测试,锁定有界输出和可恢复失败语义

说明:
- 最新 main 同题 A/B:两侧均回读 154 字段,raw token 下降 5.9%,耗时下降 19.3%,峰值上下文下降 13.3%,工具调用下降 20%

```ai-signature
改动范围: Base field-create 帮助、简单字段成功提示、lark-base Skill 路由与对应契约测试
思考过程: 从最终 A/B trace 分别定位批量成功展开 150 项、简单 text 读取冗余指南和成功后整表回读三类可控上下文开销,用成功摘要与失败全量明细分流来保留恢复能力
改动原因: 继续优化 PR 2114 的 token 和耗时,同时要求任何回退不能归因到 PR;需要让大批量成功路径有界且不削弱正确性或部分失败恢复
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 626b288a7f5444dfecb872e6cd29d4fe0788404f5001dcb47aac64e2d55d9b5a

* fix(base): 恢复批量字段输出与分页默认契约

1. 批量创建完整成功时保留服务端字段元数据,部分失败仍返回精简 identity
2. 将 +field-list 默认页大小恢复为 100,继续支持显式 --limit 200
3. 补充回归测试与字段创建文档,保留 --jq 有界输出指导

说明:
- 定向、Base 全量、race、仓库单测、构建、vet 与 lint 均通过

```ai-signature
改动范围: Base 批量字段创建成功输出、字段列表默认分页、对应测试与文档
思考过程: 先用契约测试复现完整字段元数据丢失和默认分页翻倍,再只恢复主干既有成功输出与默认值,同时锁定部分失败精简输出不变
改动原因: 移除可归因到 PR 的兼容性和 token 回退,并保留显式 jq 投影、节流、快速路径及部分失败恢复带来的通用收益
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 6351ed9d228611e3b6f5bc30faf278835b463e07f4eb020f225abd41e264399c

* fix(base): present batch field errors before partial output

1. Project the typed field-create error through Runtime.PresentError before copying result fields
2. Read Error, ProblemOf, and permission extensions from the presented clone
3. Cover visible scoped authorization and concealed recovery without fabricating missing_scopes

说明:
- Targeted, Base, full race, build, vet, format, lint, and module checks pass

```ai-signature
改动范围: Base 批量字段创建部分失败的错误呈现,以及 visible 和 concealed 恢复契约测试
思考过程: 先在最新 main 合并树上复现无 scope 授权提示和隐藏命令泄露,再复用兄弟批量命令的 PresentError 边界,仅替换 payload 复制时的错误来源
改动原因: OutPartialFailure 不会再次呈现根错误,必须在复制 typed error 字段前应用命令 scope 与发行隐藏策略
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: deee600dc8d4bb889629895178c1f217ba7762fbd5b3163da3b9d621c8585ac0

* fix(base): allow recovery before retrying failed field writes

1. Clarify that retryable gates unchanged automatic retries, not corrected resubmissions
2. Classify Base error 1254291 as a retryable conflict with canonical wait guidance
3. Cover authorization recovery, write conflicts, and reference contract consistency

```ai-signature
改动范围: internal/errclass/codemeta_base.go、shortcuts/base/field_ops.go、对应 Base 回归测试与 field-create 参考文档
思考过程: 将 retryable 限定为同一请求原样自动重试资格,保留授权或输入修正后重新提交,并复用现有 conflict 恢复提示
改动原因: 部分失败顶层提示会与权限恢复 hint 冲突,且 1254291 未分类导致等待重试规则无法由结构化错误驱动
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 65cd95f24968c5e0b0c43cf858ed787eabb6d9d63b3d5199a294bd284816c35e

* fix(base): preserve partial field recovery contracts

1. Preserve presented typed-error extensions without allowing them to overwrite batch ledger fields
2. Align field creation guidance with command-specific name semantics and caller-timeout recovery
3. Cover security challenges, extension collisions, and storage-type selection with regression tests

```ai-signature
改动范围: shortcuts/base 的 field-create 部分失败输出、命令提示、Base Skill 写入规则、field-create reference 与对应回归测试
思考过程: 复用 Runtime.PresentError 后 concrete typed error 的 JSON wire shape 作为扩展字段单源;对批次账本自有键统一生成无冲突 error_ 别名,并只收敛已证实的同名、fast path 与 timeout 契约矛盾
改动原因: 部分失败会丢失 challenge_url 等恢复字段,自定义 typed error 还可覆盖 status/index/error 导致错误账本;过度绝对的字段类型、同名和超时文案也会形成可归因正确率回退
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 02377560f14202ea652f530389ac102647189923e45548337814ec3871f5a4de

---------

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
2026-08-07 16:19:19 +08:00
liuxin-0319 4ff2bd1fb5 docs(doc): clarify history edit time format (#1962) 2026-08-07 15:43:49 +08:00
chenxingyang1019 6402080328 fix(apps): detect the no-database failure by code or message (#2217)
* fix(apps): detect the no-database failure by code or message

The recovery flow for "db command against an app that has no database"
keyed on one business code (500002759). The server has since renumbered
that case to 400002465, which silently disabled the flow: users now see
the raw internal message about workspace / app-id mapping and lose the
cloud-development recovery steps entirely.

Nothing catches the regression. There is no compile error, the unit tests
compare against the same constant they set, and the dry-run E2E does not
exercise a real response — the failure only shows up against a server that
has already renumbered.

Detect on code OR message instead. Both known codes are kept, plus narrow
lowercase markers of the server's internal wording. The two channels have
opposite failure modes: a code is precise but gets renumbered, a message
survives renumbering but breaks on rewording or localization. Requiring
either to match means one channel changing degrades nothing, and only a
simultaneous change of both regresses.

Markers stay deliberately narrow. "no db branch" in particular must not
also swallow env-pull's "invalid db branch" case, which needs its own
hint; a comment records that widening them requires a test proving the
neighbours still pass through.

Classification and the cause chain are untouched: the helper still mutates
the problem in place and returns the same error value.

* test(apps): assert the full typed-error contract in no-database cases

Review feedback: the new subtests checked only Message and Hint, so a
change that reclassified the failure — or replaced the error value and
dropped the cause chain — would still have passed.

Each case now asserts Category, Subtype and Code are untouched by the
rewrite, and that the helper returns the same error value. Inputs use a
concrete subtype rather than Unknown, so a clobbered classification is
actually observable. One new case wraps a cause and asserts errors.Is
still finds it through the rewrite.

Also covers the predicate's defensive nil guard, which withAppsHint cannot
reach on its own (ProblemOf returns ok=false for untyped errors), closing
the two uncovered lines the coverage report flagged. Both withAppsHint and
isAppNoDatabaseError are now at 100%.

* fix(errclass): classify the db-domain business codes

Three codes reaching the Apps db commands were absent from the Spark
table, so BuildAPIError fell through to the CategoryAPI + SubtypeUnknown
catch-all and the envelope carried no usable classification.

"App has no database yet" registers as Validation / FailedPrecondition:
the app resolves fine and the request is well-formed, but a prerequisite
the caller must create first is missing, so retrying unchanged can never
succeed. This moves its exit code from 1 to 2 — "fix the state" rather
than "the call failed" — and a test pins that so a future
reclassification has to be deliberate. Two codes cover it because the
server renumbered the case into the 4xx band; the legacy one stays for
older servers.

"Table does not exist" registers as API / NotFound, an ordinary
missing-resource lookup with no exit-code change. SubtypeNotFound has no
APIHint default, which matters here: the Apps layer fills its
command-scoped hint only when the classifier left Hint empty, so a
context-free default would displace the more actionable one. A test
guards that too.
2026-08-07 15:13:31 +08:00
xiongyuanwen-byted be2a96f490 feat(sheets): harden error prescriptions, batch updates, and read workflows
Aggregate the sheets work from feat/lark-sheets-develop:

- Improve validation errors with schema hints, aggregated issues, enum guidance, and prescriptive flag/style-field messages.
- Harden +batch-update input contracts, key normalization, style vocabulary handling, and resource-budget checks.
- Add read offload and truncation handling for cells, csv, and table-get, with typed output-path errors and safer jq/output-path semantics.
- Correct freeze semantics by emitting full-state freeze/unfreeze operations and adding --rows/--cols for +dim-freeze.
- Improve +styles-put and shared --styles parsing for styles, merges, row/column sizing, freeze, and sheet-prefixed range validation.
- Fix dim-insert inherit-style mapping, table-get date/time handling, table-put style anchors, and CSV path-shaped input guards.
- Update lark-sheets skill docs, scripts, tests, and generated flag data.

Tested with:
- go test ./shortcuts/common ./shortcuts/sheets/...
- go test ./shortcuts/... ./internal/...
- python3 -m py_compile skills/lark-sheets/scripts/*.py
2026-08-07 11:21:12 +08:00
木杉 5919e861cc feat: add frontend as third app type for apps domain (#2072)
* feat: accept frontend app-type in apps +create

* feat: accept frontend app-type filter in apps +list

* docs: clarify frontend app-type handling in apps +init

* docs: note FRONTEND in queryAppType comment

* docs: add frontend app-type guidance to lark-apps skill

* docs: add frontend app-type to lark-apps command references

SKILL.md's routing table already covered frontend, but the per-command
reference docs still enumerated only html/full_stack. Update create/list/get
enum values, add a frontend local-dev section, and note frontend in the
release-create entry so agents document the third app type consistently.

* docs: address CodeRabbit feedback on frontend app-type refs

- create.md: state the app-type enum is matched exactly (lowercase), drop
  the incorrect claim that the CLI normalizes case
- local-dev.md: scope database debugging to full_stack (frontend/html have
  no DB) and add the +release-get finished-status poll to the frontend flow

* docs: align app-type enum in apps E2E coverage and test comments

The E2E coverage table and two test comments still described the --app-type
enum as html/full_stack after frontend was added. Update them to
html/frontend/full_stack for consistency; assertions are unaffected (they
match on substrings, not the full enum set).

* docs(lark-apps): cloud-dev honors routed app_type instead of hardcoding full_stack

The main SKILL.md router declares app_type and dev-method orthogonal and
routes no-database interactive tools to frontend, but cloud-dev/create
references still hardcoded `+create --app-type full_stack` for cloud
generation. This forced a frontend-routed request into a full_stack app
(unrecoverable since apps have no +delete).

Align with the 2026-07-24 design decision: cloud generation also splits by
database need — full_stack when persistence is required, frontend by default
when unstated. Verified on BOE that a frontend app runs the full cloud
session+chat pipeline to completed.
2026-08-07 00:11:11 +08:00
liujinkun2025 f7d0326bfe fix: reject truncated wiki node tokens (#2203) 2026-08-06 22:08:26 +08:00
Zheng Kenghong 27ab8fbea3 docs(skills): sync lark whiteboard skill (#2215)
* docs(skills): sync lark whiteboard skill

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* docs(skills): clarify whiteboard input formats

Co-authored-by: TRAE CLI <traecli@bytedance.com>

---------

Co-authored-by: zhengkenghong <zhengkenghong@bytedance.com>
Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-08-06 21:19:44 +08:00
sang-neo03 164d3ccd27 fix(registry): describe the attendance and mindnotes domains (#2210)
Both are registered, reachable business domains — `lark-cli attendance
user_tasks query` and `lark-cli mindnotes nodes create` run, and both appear in
`auth login --domain` — but neither had an entry in
service_descriptions.json. GetServiceTitle/GetServiceDescription returned "",
so buildDomainMeta fell back to the typed service spec, which carries one
string for both languages. The result was visible in `--help`: mindnotes
rendered its Chinese description in the English domain list, and attendance
rendered "attendance record query", a lowercase fragment shown in both locales.

Both keep their own scope namespaces (attendance:task:readonly,
mindnote:node:create/read) and stay independent auth domains, so no
auth_domain is set. whiteboard remains the only domain folded into docs.

TestGetDomainMetadata_HasTitleAndDescription could not catch this: it asserts
on buildDomainMeta's output, which the fallback had already made non-empty.
The new reconciliation test walks EmbeddedServicesTyped plus AllShortcuts and
asserts both languages resolve from the config itself, before any fallback.
EmbeddedServicesTyped is the overlay-free parse, so the test does not depend on
what remote_meta.json happens to hold on the machine — a domain that only ever
arrives via remote overlay stays out of its reach.
2026-08-06 19:02:21 +08:00
kiraWangRuilong 9f713e60f7 fix(auth): harden token refresh and concurrency handling (#2135)
1. Improve retry behavior for refresh failures.
2. Improve authentication token refresh reliability during concurrent activity.
 - Add a token-storage writability probe before refresh.
 - Add generation-safe token updates.
 - Add lock for all set/update/delete token operation.
2026-08-06 17:50:45 +08:00
zcc d92ad6ea2c feat(drive): add +copy shortcut (#2129)
Wrap the Drive file-copy endpoint as drive +copy. Accept a document URL
(recommended) or bare token + --type for the source; the target takes a
folder token, a folder URL, or the my_space constant, which resolves the
caller's My Space root folder via the root-folder-meta endpoint (absent
from platform metadata, works for both user and bot). Repeatable --extra
key=value pairs are forwarded verbatim for special copy semantics (e.g.
target_type=docx to convert a legacy doc during copy). Source and folder
tokens are validated with validate.ResourceName before path
interpolation. Reject wiki URLs/tokens with a typed validation error
whose hint carries a wiki +node-copy command template using a fixed
<node-token> placeholder, because a Drive copy of a wiki-backed document
would land in Drive space instead of the wiki tree. In bot mode the CLI
auto-grants the current CLI user full_access on the new copy (same
behavior as +upload/+import), reporting the outcome in the
permission_grant output field without failing the copy.

Declare docs:document:copy (the narrowest scope in the endpoint's any-of
set) plus a conditional drive:drive.metadata:readonly for my_space
resolution. Cover the shortcut with unit tests, dry-run e2e and a
self-contained live workflow (upload -> copy -> download-verify ->
my_space copy -> cleanup), and register it in
tests/cli_e2e/drive/coverage.md. Route copy intents in the lark-drive
skill to the shortcut instead of the raw files copy service command.
2026-08-06 17:45:22 +08:00
wenzhuozhen 69459321dd feat(sheets): add ai formula verify (#1959)
* feat(sheets): add --ai-only to +formula-verify for AI formula status polling

BE-2: +formula-verify gains --ai-only, mapping to verify_formula tool
input ai_only=true. AI formulas (AI_WRITE / AI_CLASSIFY / …) compute
asynchronously; --ai-only is a single-shot polling probe (no built-in
wait/timeout) that skips the ordinary 7-Excel-error scan and returns
current AI-formula compute status. Coexists with --sheet-id/--range and
honors --exit-on-error.

BE-4: mirror sheet-skill-spec SoT docs (AI formula list in
lark-sheets-formula-translation, --ai-only + async polling section in
lark-sheets-formula-verify) and regenerate flag_defs_gen.go.

Spec source: active@6fe4ea7389c6d0631dc8279ee7506c357d0600325e28ffabdc97d9a66339e762

* docs(sheets): mirror enriched AI formula params + --ai-only verify wording

Mirror from sheet-skill-spec SoT (ee/sheet-skill-spec MR!55):
- formula-translation: full AI function param details (range rules,
  AI_TRANSLATE language keys, AI_EXTRACT type, AI_CLASSIFY modes,
  AI_INFER/AI_IMPORTDATA array semantics)
- formula-verify: clarify --ai-only convergence expectation, drop
  implementation-leaking phrasing

* docs(sheets): mirror unified AI() formula docs from spec

Sync the lark-sheets AI formula skill from sheet-skill-spec (SoT) after
the product change that merges all AI formulas into one AI() function:

- formula-translation reference: single =AI(prompt, [range]) function with
  syntax (incl. variadic =AI(part1, part2, ...) concatenation), per-case
  usage table (translate / sentiment / classify / extract / summarize /
  rewrite / generate / cleanup / keywords / multi-cell prompt), and
  prompt best practices
- formula-verify reference + --ai-only flag def: unified AI() wording
- flag_defs_gen.go regenerated from flag-defs.json
- lark_sheet_formula_verify.go: drop stale AI_WRITE / AI_CLASSIFY names
  in the ai_only comment, reference the unified AI() function

* docs(sheets): sync lark-sheets skill from spec

Mirror the lark-sheets generated artifacts from sheet-skill-spec dwc/lark-sheet-ai:
- update AI formula verification delivery guidance
- add read-data inspection/profile helper scripts
- refresh generated flag definitions for +formula-verify --ai-only

* docs(sheets): sync updated AI formula guidance

Mirror the latest lark-sheets generated docs from sheet-skill-spec dwc/lark-sheet-ai after c292420:
- clarify that #ERROR/readback issues can be formula-write escaping failures rather than AI compute failures
- recommend +cells-set JSON formula writes for AI() formulas containing commas and quotes
- document <=1000-row serial batching for AI formula copy-to-range workflows

* docs(sheets): add license headers to helper scripts

Add the repository-standard copyright and SPDX headers to the generated lark-sheets helper scripts so the license-header check passes.

* docs(sheets): regenerate sheet flag defs

Regenerate shortcuts/sheets/flag_defs_gen.go after the latest sheet-skill-spec sync updated flag-defs.json.

* docs(sheets): revert lark-sheets skill sync
2026-08-06 17:20:00 +08:00
zcc 010029cfe4 feat(drive): add +update-title shortcut (#2172) 2026-08-06 17:10:40 +08:00
liangshuo-1 9759167542 fix(im): unpin search identity after bot support landed (#2208)
#2194 extended `im +messages-search` to `AuthTypes: {user, bot}` but left the
affordance example and the skill reference asserting user-only, so the
dual-identity guard added by #2199 fails on main.
2026-08-06 15:36:59 +08:00