mirror of
https://github.com/larksuite/cli.git
synced 2026-09-14 18:42:53 +08:00
codex/block-replace-range
182 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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 |
||
|
|
0d6f2c65d7 | fix(im): harden resource downloads with validated ranged streams (#2223) | ||
|
|
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>
|
||
|
|
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. |
||
|
|
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 |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
fcdef499bb | feat(event): compile the catalog and harden the consume pipeline (#2142) | ||
|
|
43fe6c8787 |
fix: surface retry metadata for TAT rate limits (#2200)
Co-authored-by: liangshuo-1 <266696938+liangshuo-1@users.noreply.github.com> |
||
|
|
960bdf6d71 | feat: migrate application and IM guidance to affordance (#2199) | ||
|
|
47c9741ce0 | feat: profile selection from environment with source-aware errors (#2198) | ||
|
|
09feefe96b | fix: make agent recovery and concealment reliable (#2189) | ||
|
|
8e884928f6 |
feat: add Base table copy shortcuts (#2019)
* feat: add Base table copy shortcuts * test: cover Base table copy edge cases * fix: preserve table copy task state * fix: align table copy recovery with API errors * fix: preserve table copy auth recovery * test: verify copied table schema --------- Co-authored-by: fongwave <272393974+fongwave@users.noreply.github.com> |
||
|
|
ebdeda854d | feat(extension): present restricted commands as absent and trim skills (#1837) | ||
|
|
2a1613484a |
feat: add framework flag aliases and unified IM pagination (#2146)
* feat: add framework flag aliases and unified IM pagination Introduce declarative exact-name flag aliases at the shortcut framework boundary while keeping semantic compatibility domain-owned. Add a shared, format-aware IM pagination pipeline with consistent flags, metadata, safety bounds, resumable cursors, and request throttling. * fix: align alias attribution and pagination contracts * fix: align alias contracts and documentation * test: remove environment-dependent contact bot e2e * test: restore contact bot e2e * docs: reduce IM pagination guidance noise --------- Co-authored-by: liangshuo-1 <266696938+liangshuo-1@users.noreply.github.com> |
||
|
|
40a0a9de66 | feat(enhancement): centralize HTTP transport policies (#2021) | ||
|
|
cfe76ad56a |
ci: add protected public domain allowlists (#2111)
Co-authored-by: HanShaoshuai-k <268785735+HanShaoshuai-k@users.noreply.github.com> |
||
|
|
4a16139348 |
fix(base): resolve Base URL block types accurately (#2099)
* fix: resolve Base URL block types accurately * fix: resolve Base block selection from Wiki URLs * fix(base): guide resolved folder and docx blocks * fix(base): avoid field fallback for untyped URL blocks * docs(base): specify URL example fence language * test(base): cover unmatched URL block resolution |
||
|
|
c167163d70 | feat: propagate invocation metadata (#2097) | ||
|
|
e7d5ecdd01 |
feat: add risk-control protection (#1910)
1. Add baseline safe protection for Feishu/Lark API endpoints. 2. Add lark-cli config risk-control on|off|default command for workspace-level safety protection control. |
||
|
|
b8f56dbc0b | feat(apps): support absolute and relative upload paths (#2005) | ||
|
|
4c1a92caa6 |
refactor: converge success output through a single Emitter that owns the write (#1899)
* refactor: add output emitter contract and differential harness Introduce a leaf Emitter in internal/output that composes the existing output primitives (content-safety scan, envelope, jq, format rendering, notice) behind a single command-scoped port. The emitter is unwired: no production caller is migrated, so CLI output stays byte-for-byte unchanged. A differential test harness drives the real legacy entry points (RuntimeContext.Out/OutRaw/OutFormat/..., WriteSuccessEnvelope and the pagination formatter) and asserts byte-identical stdout/stderr plus typed errors, locking behavior before later slices migrate callers. * refactor: tighten emitter API and cover pagination with real tests - split Emitter.Success/PartialFailure and drop EmitOptions.OK so a missing ok flag can no longer silently emit ok:false - give StreamPage its own StreamOptions (format + pretty) instead of reusing EmitOptions, making "jq needs aggregation" a compile-time fact - pin the Emitter jq-error contract (returns error, writes no stderr); the caller adapter re-emits the legacy stderr line on migration - add in-package tests driving the real apiPaginate/servicePaginate over a mock transport: multi-page aggregation, empty-result fallback, MarkRaw handling, and the business-error raw-response red line * test: use standard TestFactory harness for pagination tests Replace the hand-rolled RoundTripper + APIClient construction in the apiPaginate/servicePaginate tests with cmdutil.TestFactory and its httpmock.Registry, and isolate LARKSUITE_CLI_CONFIG_DIR to t.TempDir(), matching the repo's standard HTTP-mocked test convention. Assertions and coverage (multi-page aggregation, empty-result fallback, MarkRaw, and the business-error raw-response red line) are unchanged. * refactor: route success output through the single Emitter port Migrate the success-output surfaces onto internal/output's Emitter, byte-for-byte identical (proven by frozen golden diffs and the real paginate/HandleResponse tests): - RuntimeContext.Out/OutRaw/OutFormat/OutFormatRaw/OutPartialFailure now build an Emitter and call Success/PartialFailure; emit and outFormat are removed. An adapter maps the returned error back to the legacy outputErrOnce / jq-error stderr / exit-code behavior. - WriteSuccessEnvelope degrades to a thin Emitter.Success delegate; its 8 callers are unchanged. - apiPaginate/servicePaginate stream pages via Emitter.StreamPage; the aggregate and business-error raw-response branches are untouched. - HandleResponse routes its non-JSON structured-response branch through Emitter.Success. Frozen golden fixtures replace the runtime legacy oracles so the differential harness cannot go self-referential after migration. * fix: keep _notice on struct payloads in Emitter's unknown-format fallback printLegacyDataJSON now normalizes via toGeneric first (matching FormatValue), so a struct / named-map payload retains its injected _notice on the unknown-format -> JSON fallback rather than dropping it silently. Add a regression test that fails against the pre-fix path. * refactor: make the Emitter own write failures and stop mutating inputs Route every Emitter stdout path through a render-to-buffer-then-copy helper so a marshal/render failure leaves stdout empty and surfaces a typed internal error (with cause), and a stdout write failure is propagated instead of silently swallowed. Leaf writers gain error-returning Write* cores; the legacy Print*/FormatValue wrappers keep their exact behavior for unmigrated callers. - handleEmitterError now captures every error, not only the jq/safety branches; flip OutRaw's write-error test to assert propagation. - Clone the map before injecting _notice so a caller's payload is never mutated and an existing _notice is never overwritten. - Preserve jq's own typed error (validation/api) on a bad expression or runtime failure; only wrap genuine stdout write failures. - Split tests: normative emitter_contract_test.go vs frozen emitter_legacy_compat_test.go (base SHA recorded, self-update env vars removed). * fix: satisfy license-header and forbidigo lint on the emitter changes - Move the base-SHA note below the copyright header in the renamed legacy-compat test so the license-header check sees a valid header at the top. - Route the leaf wrappers' marshal/format stderr messages through a single legacyStderrf helper (one //nolint:forbidigo) instead of bare os.Stderr, preserving exact legacy behavior for unmigrated direct callers while passing forbidigo; drop the now-unused os imports. * fix: stop legacy CSV wrappers reporting write failures to stderr Align FormatAsCSV/FormatAsCSVPaginated and FormatValue/FormatPage's CSV branch with the other leaf wrappers: report only marshal failures, swallow write failures. Previously they emitted a 'csv write error' for the (empty) line and the JSON-fallback write failures that the pre-refactor code ignored, and mislabeled a JSON write failure as a CSV one. Failure-path only; success output is unchanged (golden double-diff still byte-for-byte). |
||
|
|
577ff035c3 | fix: allow jq examples in quality gate dry-runs | ||
|
|
d8fb368ce4 | test: isolate unit tests from user state (#1883) | ||
|
|
9dd355a52d | test: synchronize temporary Git maintenance (#1946) | ||
|
|
21cff2e2dd | fix: reduce public content credential fixture false positives | ||
|
|
baf6050f8e | feat(apps): add role management shortcuts (#1881) | ||
|
|
37d490a198 |
fix: unify dry-run output contract (#1870)
* fix: unify dry-run output contract
* fix: address dry-run review feedback
* fix(dryrun): tighten preview contract and unify data shape
- transcribe HTTP method verbatim in previews (HEAD/OPTIONS were
reported as GET); reject an empty method in api with a typed error
- unify the dry-run data payload across api/service/shortcut paths:
{api, context?: {app_id, user_open_id}}; drop data.as — the envelope
top-level identity is the single identity source
- mark pretty dry-run stdout with '# dry-run: request not sent' so logs
that drop stderr still show it was a preview
- extract the shared preview builder, collapse PrintDryRunWithFile's
loose params into FileUploadMeta, and fail loudly on nil previews
- revert description-marker identity parsing: stale prose must not
override corrected accessTokens (blocks legal user calls on
images.create); identity gating keys off accessTokens only
- pin the new contracts with tests: verbatim method, three-way context
parity, nil-preview error, empty-context omission, marker line
* docs(agents): add typed-data, faithful-transcription, and contract-test conventions
- typed struct at the boundary over map[string]interface{} threading;
distinct types where values could swap silently (internal/meta.Token)
- transcribe input verbatim in previews/transformations; reject
unhonorable flag combinations with typed errors instead of silently
substituting behavior
- contract tests must fail when the implementation is reverted
* test: migrate dry-run tests grown on main to the envelope format
main gained raw-format dry-run readers while the PR was in flight
(wiki drive export #1802, drive list comments #1845, slash commands,
sheets history, docs fetch, mail draft-send/triage, vc meeting events).
Migrate them to the envelope accessors (clie2e.DryRunGet / data-wrapped
decoders) and drop the now-redundant DryRunData extractions in files
unified on DryRunGet.
---------
Co-authored-by: guokexin.02 <264159873+Tantanz20020918@users.noreply.github.com>
|
||
|
|
e79d49e7e4 |
Merge lark sheets development branch (#1833)
* feat(sheets): support font_family in cell styles (#1549) Add a font_family field to cell_styles so a cell's font name can be set and read back through every style entry point: - +cells-set (--cells JSON) and +cells-set-style / +cells-batch-set-style gain a font_family field / --font-family flat flag - +workbook-create / +table-put --styles accept font_family in cell_styles - +cells-get returns font_family helpers.go buildCellStyleFromFlags reads the --font-family flag; lark_sheet_workbook.go allows font_family in the --styles cell_styles whitelist; data/ + skills/ are synced from sheet-skill-spec. * docs(sheets): inline editing rules into SKILL.md and clarify flag descriptions - Move cross-cutting editing rules and execution notes into the root SKILL.md and drop the now-redundant core-operations reference - Clarify flag descriptions: offset must be explicit inside +batch-update, range prefixes written bare (no quotes), chart requires a dim index, untyped --values lose date/number types, ungroup level semantics - Sync the corresponding reference docs * feat(sheets): add --type bitable to +sheet-create for creating bitable sub-sheets (#1520) * perf(sheets): cap fan-out cell-matrix materialization to prevent OOM (#1578) * perf(sheets): cap fan-out cell-matrix materialization to prevent OOM The +cells-set-style / +dropdown-set / +cells-batch-set-style / +dropdown-update shortcuts expand a single A1 range into a rows×cols matrix of per-cell maps client-side (the backing set_cell_range tool takes an explicit cells matrix). rangeDimensions() had no upper bound, so a tiny input like "A1:Z100000" balloons into ~2.6M heap maps (~900MB, doubled again by json.Marshal) and can OOM the process before the request is even sent. Add a 50000-cell safety cap (checkStampMatrixBudget) gating every fan-out materialization point, matching the documented but never-wired --max-cells default. Oversized ranges now fail fast with a clear validation error instead of allocating. Also preallocate the per-op slices now that the range count is known up front. Adds benchmarks + a boundary test as regression guards. * perf(sheets): cap table-put/batch fan-out materialization (siblings of the cell-matrix cap) The single-range fan-out cap (maxStampMatrixCells) left three sibling ingress paths uncapped, each able to materialize an unbounded matrix or op set in memory before the request leaves: - +table-put / +workbook-create --sheets/--values: buildSheetMatrix builds the whole rows×cols matrix before slicing it into per-write batches; tablePutMaxCellsPerWrite only bounds the batch size, not the total input. Add tablePayload.checkCellBudget (1M-cell guardrail), enforced in validate() and in buildValuesPayload (the --values path bypasses validate()). - batch fan-out (+cells-batch-set-style / +dropdown-update): per-range checkStampMatrixBudget can't stop many ranges from summing past the cap. Add an aggregate cell budget (checkBatchStampBudget) and a shared maxBatchRanges (100) count cap in validateDropdownRanges — covering all fan-out commands and replacing the now-redundant +dropdown-delete count check. - +batch-update: cap --operations at maxBatchOperations (100) in translateBatchOperations. Adds boundary regression tests for each cap. go vet + gofmt clean; full shortcuts/sheets + backward suites green. * test(sheets): measure table-put matrix materialization cost Add BenchmarkBuildSheetMatrix_* and TestTablePutMatrixPeakMemory mirroring the fan-out probes. Confirms the +table-put/+workbook-create ingress has the same OOM profile as the single-range stamp: 2.6M cells → ~917 MB / 5.3M allocs (+875 MB resident heap) materialized before the first write — now rejected up front by checkCellBudget. * feat(pivot): lark-sheets pivot reference 补 +pivot-list info 说明与落点覆盖校验 +pivot-list 返回 info(page_range/content_range/error_state 等): 1) 判断目标单元格在透视表内(改配置 +pivot-update)还是区域外(改值 +cells-set); 2) 透视表展开后会覆盖已有数据,落点强烈优先默认自动新建子表; 3) 创建后用 info.error_state / content_range 校验有没有覆盖/冲突。 * feat(sheets): add +formula-verify shortcut for verify_formula tool Wraps the new verify_formula read tool in a CLI shortcut so AI agents can run write-then-zero-error verification end-to-end: lark-cli sheets +formula-verify --url <url> Scans formulas + cell error states across one or more sub-sheets and returns a JSON status report (success / errors_found / partial). Aggregates all 7 Excel error categories (#REF! / #DIV/0! / #VALUE! / #NAME? / #NULL! / #NUM! / #N/A) plus compile failures into one envelope; the tool always reports every error in the scan window — callers needing a subset filter the returned error_summary client-side. The internal scan cap is hidden from callers; when it trips the response sets has_more=true and includes a warning_message asking the caller to narrow --range / split --sheet-id and continue. Flags follow the lark-sheets convention: - --url / --spreadsheet-token (XOR public) - --sheet-id / --sheet-name (repeat or comma-separate; mutually exclusive) - --range (repeatable A1) - --max-locations (default 20) - --exit-on-error (CI gate: status='errors_found' → exit 2 with failed_precondition) Generated artifacts (skills/lark-sheets/{SKILL.md, references/ lark-sheets-formula-verify.md}, shortcuts/sheets/data/flag-defs.json, shortcuts/sheets/flag_defs_gen.go) are mirrored from sheet-skill-spec generated/ via 'npm run sync:cli'. shortcuts.go registers FormulaVerify alongside the other lark_sheet_formula_verify skill shortcuts so +formula-verify is discoverable from 'lark-cli sheets --help'. Tests cover the dry-run wire shape (excel_id + sheet_ids/sheet_names/ ranges/max_locations packing), the read scope (invoke_read URL), the mutually-exclusive selector validation, the non-positive --max-locations guard, and the --exit-on-error status matrix (success/partial/errors_found/unknown). * feat(sheets): add +history-list / +history-revert / +history-revert-status shortcuts BE-1 + BE-2 (larksuite/cli lark-sheets) for spec sheet-history-revert. Three thin callTool wrappers over facade-agg history tools, following the existing sheets Validate/DryRun/Execute + --url/--spreadsheet-token(/--token) locator convention: - +history-list (read, history_list): passes the tool output through verbatim; facade-agg already does the minor_histories/4-field/RFC3339 transform. - +history-revert (write, history_revert): --history-version-id required, enforced at Validate stage with a typed *errs.ValidationError (no request on missing); returns the async receipt. - +history-revert-status (read, history_revert_status): polls in-progress / success / failure. Flags declared inline (not via *_gen.go) — flag_defs_gen.go / data/flag-defs.json are synced from sheet-skill-spec (BE-3) and must not be hand-edited. Notes: - history_revert / history_revert_status depend on facade-agg's downstream RPC wiring, a DEFERRED follow-up; the tools return a "not wired yet" guard today. These CLI wrappers are correct and go live when the backend follow-up lands. +history-list is fully functional now. - TestFlagDefsGen_MatchesJSON fails on baseline (pre-existing BE-3 gen/json drift); resolves once BE-3 sync:cli regenerates flag defs for these shortcuts. Validation: go build ./shortcuts/sheets/... PASS; new tests (TestHistoryShortcuts_DryRun, TestHistoryRevert_MissingVersionID) PASS. Spec source: active@2acd94a24ac3f835357a274a02344f78435bcc1c39ad0d695ce587f0cbddfb21 * chore(sheets): sync lark_sheet_history skill + flag defs from sheet-skill-spec (BE-3) Synced artifacts for the history shortcuts from ee/sheet-skill-spec (SSOT), landed surgically (history-only) to avoid regressing this branch's newer skills/lark-sheets content: - skills/lark-sheets/references/lark-sheets-history.md (new, mirrored). - skills/lark-sheets/SKILL.md: + Lark Sheet History references-table row only. - shortcuts/sheets/data/flag-defs.json: + 3 history shortcuts (additive; no existing entries touched). - shortcuts/sheets/flag_defs_gen.go: regenerated via go generate ./shortcuts/sheets/... (this also resolves the pre-existing flag-defs/gen drift — TestFlagDefsGen_MatchesJSON now passes). NOT a full mirror: the rest of skills/lark-sheets/ + flag-schemas.json on this branch (feat/lark-sheets-develop) are NEWER than the sheet-skill-spec worktree's canonical (e.g. /wiki/ URL support, schema_version 3). A wholesale sync:cli would have reverted them, so only the history delta is taken here. Full re-sync should happen once sheet-skill-spec canonical is realigned with this branch. Validation: go generate clean; go test ./shortcuts/sheets/ (TestFlagDefsGen_MatchesJSON, TestHistory*) PASS. Spec source: active@2acd94a24ac3f835357a274a02344f78435bcc1c39ad0d695ce587f0cbddfb21 * fix(sheets): +history-revert-status keys on --transaction-id, not version id BE-2 gap surfaced by PPE E2E: +history-revert-status sent history_version_id, but the facade-agg history_revert_status tool keys on transaction_id (the async receipt returned by +history-revert), so it returned "[40400] transaction_id is required". Give the status shortcut its own --transaction-id flag + input (excel_id + transaction_id); revert keeps --history-version-id. Tests updated. * fix(sheets): align history flag-defs with inline shortcuts (green TestFlagsFor) TestFlagsFor_EveryRegisteredCommandHasDefs was RED: generated flag-defs drifted from the hand-written history shortcuts. - +history-revert-status: flag-defs had --history-version-id; the BE-2 fix switched the shortcut to --transaction-id. Updated the entry to transaction-id. - +history-revert / -status --history-version-id were marked required="required", but the inline flags are cobra-optional (requiredness enforced in Validate). Set required="optional" to match. Regenerated flag_defs_gen.go. NOTE: canonical source is sheet-skill-spec (BE-3); apply the same change upstream or the next sync:cli will regress this. * chore(sheets): sync lark-sheets-history reference from spec (BE-2 transaction-id) Mirror the upstream BE-2 fix in canonical-spec/references/lark_sheet_history/ cli-reference.md: +history-revert-status now uses --transaction-id (taken from the async receipt returned by +history-revert), and +history-revert's --history-version-id flips required→optional (Validate enforces requiredness at runtime). This file is the only history-only delta from the upstream sheet-skill-spec sync; the rest of skills/lark-sheets/ stays on the cli's newer baseline (/wiki/ URL support, +cells-set-image / +float-image-create, etc.) to match commit 8ae516db's history-only mirror policy. Spec source companion change: feat/sheet-history-revert in ee/sheet-skill-spec, canonical-spec/{tool-shortcut-map.json,references/ lark_sheet_history/cli-reference.md}. * feat(sheets): +history-list --end-version for backward pagination Spec follow-up sheet-history-revert: thread the history_list pagination contract through the +history-list shortcut. - shortcuts/sheets/lark_sheet_history_list.go: + --end-version (int, optional). Mapped to the tool input's `end_version` only when explicitly set (so the server treats absence as "first page / latest"), via runtime.Changed / runtime.Int (matches the +formula-verify --max-locations precedent). + Tip: pass next_end_version from the response on the next call; capture exits the pagination loop when the server omits the field. - shortcuts/sheets/lark_sheet_history_test.go: + dry-run case asserting --end-version 12345 lands as input.end_version=12345 (post-JSON unmarshal float64). - skills/lark-sheets/references/lark-sheets-history.md: synced from ee/sheet-skill-spec (commit 39c6b61). Adds the "倒序分页" caveat row + --end-version flag + pagination Examples line. Drops the internal MajorHistory.Version implementation detail per spec follow-up. - shortcuts/sheets/data/flag-defs.json: synced from spec (+history-list +--end-version int optional). - shortcuts/sheets/flag_defs_gen.go: regenerated via `go generate ./shortcuts/sheets/...`. Companion changes: - ee/sheet-skill-spec MR !37: spec-tables + tool-schemas pagination contract (commits 09e8604, 39c6b61). - ee/sheet-facade-agg MR !1028: history_list tool plumbs end_version, emits next_end_version + has_more (omitted at earliest page), defaults PageSize=20 to datarpc. Validation: - go build ./shortcuts/sheets/... PASS - go test ./shortcuts/sheets/... PASS (sheets + backward) - TestHistoryShortcuts_DryRun (5 cases incl. new --end-version case): PASS - TestHistoryRevert_MissingRequiredFlag: PASS - TestFlagsFor_EveryRegisteredCommandHasDefs: PASS - TestFlagDefsGen_MatchesJSON: PASS * fix(sheets): make +history-revert --history-version-id cobra-required + revert max-cells default drift Two issues surfaced during MR !37 review: 1) +history-revert --history-version-id requiredness was set as "optional" in the spec table (BE-2 fix dc5fe0ea) so cobra wouldn't block before Validate. Per upstream review the flag should be required-by-cobra so the user gets the standard "required flag(s)" gate immediately and the runtime contract matches the JSON shape. - shortcuts/sheets/lark_sheet_history_revert.go: historyVersionIDFlag now sets Required: true. Validate keeps a trim/empty-string guard so '--history-version-id ""' still fails as a typed *errs.ValidationError (cobra accepts empty strings as "set"). - shortcuts/sheets/data/flag-defs.json: +history-revert --history-version-id required: optional -> required. - shortcuts/sheets/flag_defs_gen.go: regenerated. - shortcuts/sheets/lark_sheet_history_test.go: TestHistoryRevert_MissingRequiredFlag split into per-shortcut subtests; +history-revert asserts cobra's "required flag(s)" contract (raw err — the test rig calls cmd.Execute directly so it doesn't see the cmd dispatcher's typed envelope wrap); +history-revert-status keeps the typed *errs.ValidationError contract (its --transaction-id stays cobra-optional + Validate-enforced). 2) max-cells safety cap was accidentally rewritten from 200000 to 50000 by the last sync from sheet-skill-spec (the spec canonical side fell out of date — fixed separately on the spec MR follow-up). Restore desc: "Safety cap; default 200000" / default: "200000" so +cells-get / +csv-get keep the documented cap. Validation: - go test ./shortcuts/sheets/... PASS - TestHistoryRevert_MissingRequiredFlag (both subtests) PASS - TestHistoryShortcuts_DryRun (incl. +history-list pagination case) PASS - TestFlagsFor_EveryRegisteredCommandHasDefs PASS - TestFlagDefsGen_MatchesJSON PASS * fix(sheets): make +history-revert-status --transaction-id cobra-required (match +history-revert) Companion to commit 6ca35b06: same gating model now applies to both history receipts. - shortcuts/sheets/lark_sheet_history_revert.go: transactionIDFlag.Required=true. Validate keeps a trim/empty-string guard for '--transaction-id ""'. - shortcuts/sheets/data/flag-defs.json: +history-revert-status --transaction-id required: optional -> required (synced from sheet-skill-spec @9ca814d). - shortcuts/sheets/flag_defs_gen.go: regenerated. - shortcuts/sheets/lark_sheet_history_test.go: TestHistoryRevert_MissingRequiredFlag/+history-revert-status moved to the cobra "required flag(s)" text contract (the test rig invokes the shortcut via cmd.Execute, which sees the raw cobra error directly without the dispatcher's typed wrap). Drop now-unused `errors` and `errs` imports. Validation: - go test ./shortcuts/sheets/... PASS (sheets + backward) - TestFlagsFor_EveryRegisteredCommandHasDefs: PASS - TestFlagDefsGen_MatchesJSON: PASS - TestHistoryRevert_MissingRequiredFlag (both subtests): PASS * docs(sheets): sync history skill reference required badges from spec Companion to commit 9fa73312 (transaction-id) and 6ca35b06 (history-version-id): the two flag tables in skills/lark-sheets/references/lark-sheets-history.md still showed 'optional' even though the canonical contract — and shortcuts/sheets/data/ flag-defs.json — already moved to 'required'. The earlier syncs only picked up the data file from spec; the skill markdown drift slipped through. Pull in the spec-side regenerated reference (ee/sheet-skill-spec @9ca814d) so the human-readable doc matches the wire contract. * fix(sheets): lower cells-set --max-cells default to 50000 * docs(sheets): clarify workbook-import over read-then-recreate in skill * docs(sheets): bump lark-sheets skill version to 3.0.1 * docs(sheets): clarify number-vs-text typing and copy-to-range template guidance in references * docs(sheets): type by data nature, add pre-write reference column and chart/cond-format/filter rows - SKILL.md quick-reference: add a "read before acting" column pointing each intent at its reference doc; add chart / cond-format / filter rows. - Reframe number-vs-text decision to follow the data's nature (measure vs identifier), not whether the current task happens to sort/sum; a leaderboard/report "display only" use does not make a percentage text. - write-cells reference: mirror the same rule and the +cells-set fallback for layouts +table-put cannot express. * docs(sheets): tighten number-vs-text guidance and dedupe write-cells reference * Feat/lark sheets develop wzz (#1719) * feat(sheets): add +changeset-get shortcut for changeset review Wrap the get_changeset read tool: fetch the raw changeset (edit actions) between two versions to review whether an AI edit fulfilled the request. --start-revision required, --end-revision optional (defaults to latest), gap capped at 100. Adds flag-defs entry + regenerated gen, the ChangesetGet shortcut + tests, and skill docs. * feat(sheets): add +get-revision shortcut Return a spreadsheet's current document revision without pulling the full sub-sheet listing. +get-revision is a read-only derivative over get_workbook_structure (the lightest read — token only, no range) that projects the response down to the single revision field. Adds flag-defs entries and a unit test for the projection helper. * feat: 同步 spec 修改 * feat(sheets): rename +get-revision to +revision-get * feat: 移除 ppe 环境请求头 --------- Co-authored-by: wenzhuozhen <wenzhuozhen@bytedance.com> * docs(sheets): dedupe +changeset-get flag def and skill reference entry * feat(sheets): accept local_office_ token prefix for image parent_type The synthetic token prefix for imported office spreadsheets is being renamed from fake_office_ to local_office_. Accept either prefix when mapping a spreadsheet token to the drive media parent_type so image uploads keep working across the rename (main package and backward compat copy). * fix(sheets): replace undefined common.FlagErrorf with sheetsValidationForFlag changesetRevisions called common.FlagErrorf, which does not exist, breaking the build. Use sheetsValidationForFlag so the errors carry the offending flag param like the rest of the sheets validation paths. Also reword two doc comments in lark_sheet_history_revert.go that used '' for an empty shell string: gofmt (Go 1.19+) rewrites '' in doc comments to a curly quote, leaving the file permanently unformatted. * fix(sheets): satisfy errs-no-bare-wrap forbidigo and errorlint rules from main main introduced the errs-no-bare-wrap forbidigo rule and errorlint coverage that flag 27 issues in existing sheets code after the merge: - Replace direct *errs.ValidationError type assertions with errors.As in sheetsInputStatError and validateSheetMediaUploadFile so wrapped errors still match (errorlint). - Type the embedded flag-schemas.json parse failure as an InternalError with cause; it reaches the user directly via --print-schema. - Annotate genuine intermediate errors (recursive schema validator, batch sub-op raw type checks, A1 range/position parsers) with //nolint:forbidigo; every caller wraps them into typed flag validation errors. * docs: tighten formula verify workflow guidance * docs: align formula verify refs with file names * feat(sheets): let typed writes style blank cells past the data extent +workbook-create / +table-put apply cell_styles by writing them into the in-memory matrix, whose size was fixed to the data (cols × rows). A style range reaching past that extent was rejected as "outside the write range", so blank cells (reserved regions, decorative headers, empty borders) could not be styled on the typed --sheets path — only the untyped --values path padded for it. Pad the matrix down/right to cover every cell_styles range before applying (empty cells appended for the uncovered positions), mirroring the --values behavior. writeSheetData now derives the written width/range from the padded matrix; both dry-run previews and sheetCreateDims account for the style extent so the physical grid and the plan match Execute. Ranges above/left of the write anchor stay rejected (the matrix only grows down/right). * docs(sheets): warn that +csv-put silently coerces numeric-looking labels Add guidance that +csv-put numericizes date-like/ID-like columns whose values are all digits (12.10 becomes 12.1 losing the trailing zero, 001 becomes 1 losing the leading zero); recommend +table-put with dtypes=object/datetime64 or +cells-set + number_format="@". Also fix the batch-update example to use sheet_name instead of sheet_id. * docs(sheets): steer import-vs-append onto sheet-copy for existing workbooks * docs(sheets): warn that cells-clear --scope all is irreversibly destructive * docs(sheets): sync chart schema and labels guidance (#1716) * chore(sheets): update chart flag schema * docs(sheets): clarify chart labels field is presence-toggle, not value-toggle Synced from sheet-skill-spec. Chart labels (plotArea.plot.labels and per-series labels) are toggled by object existence — passing labels at all turns data labels on, even when value/category/series/percentage are all false (server falls back to showing value). Models repeatedly try `{ value: false, category: false, series: false }` to disable, which silently shows the value fallback. The reference doc now spells out both directions: pass labels to show, omit the whole labels field to hide. Also picks up earlier spec-side drift not yet propagated: - pivot-table reference: +pivot-list info return + overlap validation - flag-defs: cell-matrix fan-out cap default 200000 -> 50000 (#1578) * feat(sheets): drop pre-refactor aliases from `sheets --help` listing The refactored + commands have been the default for over a month. Hide the deprecated pre-refactor aliases from `sheets --help` via a custom cobra usage template that skips the deprecated group. Aliases stay registered and executable: their own `sheets <alias> --help` still shows the (→ +new-command) pointer, unknown-subcommand suggestions still span them, and execution still returns the _notice. * feat(sheets): let +csv-put fall back to piped stdin when --csv is omitted Agents routinely redirect a CSV into stdin but forget the `--csv -`, so `+csv-put ... < data.csv` failed its first try on a missing --csv and cost an extra round-trip (error, then --help, then retry). Relax --csv's cobra required-gate in the shortcut's PostMount and install a PreRunE that defaults an omitted --csv to "-" when stdin is a non-interactive pipe, so the standard stdin-resolution path reads it. The pipe guard keeps an interactive terminal from blocking on stdin, and a genuine miss (no piped data) still surfaces csvPutInput's typed "--csv is required" instead of cobra's bare "required flag(s) ... not set". Scoped entirely to the sheets domain — no changes to the shared runner or the flag schema. * feat(sheets): rework +rows-resize / +cols-resize to --height / --width 从上游 sheet-skill-spec 同步:+cols-resize 用 --width、+rows-resize 用 --height 直接给像素值, --type 变为可选(省略等价于 pixel)。--type standard/auto 走非像素模式,不能与像素 flag 同传; --type pixel 与 --width/--height 共存时视为等价形式。--size 已删除。 * docs(sheets): 更新 lark-sheets skill 版本至 3.0.2 将 SKILL.md 版本号从 3.0.1 升至 3.0.2,同步近期 sheets 命令改动(+rows-resize/+cols-resize 改 --height/--width、 +csv-put 支持 stdin 回退等)后的技能版本。 * feat(sheets): add --widths / --heights map form for per-column/row sizes 从上游 sheet-skill-spec 同步:+cols-resize --widths / +rows-resize --heights 接收 JSON map(键为单行列或闭区间,值为像素或 "standard"/"auto"),CLI 按起始位置排序后 展开为一次原子 batch_update 的多个 resize_range 操作,多列不同宽 / 多行不同高一次 调用完成,不再需要 +batch-update。map 形态与 --range/--width/--height/--type 互斥, 不可作为 +batch-update 子操作嵌入(batch_update 不支持嵌套)。列宽 < 20px 拒绝并提示 Excel 字符单位换算(px ≈ 字符数×8+16);--print-schema --flag-name widths/heights 可查 schema。 * fix(sheets): sync flag input/enum fixes from sheet-skill-spec 上游修复 spec-table 的 Input/Enum 字符串惯例后重新生成:--widths/--heights 现在带 file/stdin 输入声明,+sheet-create --type 的枚举正确进入 flag defs 与文档。 * feat(sheets): add sheets-scoped flag ergonomics via PostMount Two recovery loops from the edit-eval traces burn agent round-trips: hallucinated flag names (--cols for --range) whose unknown-flag error only points at --help, and enum values imported from CSS/Excel vocabulary ("center" for the vertical alignment Lark spells "middle"). - unknown-flag errors now inline the full valid-flag list (semantic guesses aren't rankable by edit distance; kills the --help round trip) - enum values with an unambiguous canonical form (casing, known alias) are normalized in place and the call proceeds; edit-distance typos stay errors with a did-you-mean hint and are never auto-applied Both ride the existing PostMount composition (same pattern as withTokenAlias), so the common framework is untouched and no other domain's behavior shifts. * feat(sheets): make validation errors prescriptive for hot failure modes Driven by the edit-eval-extra-35Q reports: ~70% of lark-cli sheets errors were missing-required / JSON-shape / wrong-value classes whose messages said what broke but not how to fix it, pushing agents into --help / --print-schema probe loops. - composite JSON shape errors inline a compact skeleton auto-generated from the schema (e.g. --cells -> [[{"value": ...}]]) when the type mismatch is shallow container confusion - +batch-update: missing 'shortcut' shows the entry template; a disallowed shortcut inlines the full allow-list; exceeding the 100-op cap says how many batches to split into; sub-op translator failures append the shortcut's complete input-key contract - +table-put: dtypes/formats keys that miss every column call out the A1-letter habit and inline the declared column names; empty cells in a date-typed column name the three ways out - schema enum errors suggest across casing, vocabulary aliases, and edit distance * fix(common): steer rejected @file paths to stdin instead of cd The absolute-path rejection hint said "cd to the target directory first" - advice the lark-sheets skill explicitly tells agents not to follow (it pollutes the working directory). The stdin-contention hint also demonstrated @file with an absolute path, which would itself be rejected. - @file failures on stdin-capable flags now show the equivalent stdin invocation (--csv - < /tmp/x.csv) - the path error recommends a relative path or stdin, not cd - the stdin-contention example uses a relative @file path Message-text only; no control-flow change for any domain. * chore(sheets): suppress forbidigo on csv-put stdin pipe detection os.Stdin.Stat is intentional here - pipe detection needs the real process fd; IOStreams.In is a plain io.Reader without Stat. Clears the lint failure left by the stdin-fallback commit. * fix(sheets): pass spreadsheet token to changeset tool (#1839) * fix(sheets): hide bitable sheet creation (#1843) * fix(sheets): resolve revision wiki URLs * fix(sheets): reject overlapping resize ranges * fix(sheets): address remaining review feedback * fix(sheets): avoid credential scanner false positive * fix(sheets): import mislabeled .xls workbooks by sniffing content Local .xls files that are actually OOXML (an .xlsx exported or renamed to .xls) failed +workbook-import with a cryptic backend "xml_version_not_support" because the CLI trusted the file name extension. +workbook-import now sniffs the file's leading magic bytes (PK -> xlsx, OLE2 -> xls) and passes the true extension to the drive import core via a new optional ImportParams.FileExtension override, correcting both the file_extension and the staged media file name (the latter avoids the backend's "import file extension not match", code 1069910). A declared Excel file whose bytes match neither container is rejected locally with a prescriptive error instead of the opaque backend failure. The drive import core gains only the neutral FileExtension override (empty = infer from the file name, i.e. unchanged behavior for drive +import); all Excel sniffing/correction policy lives in the sheets shortcut. * fix(ci): keep semantic waiver fixture active * fix(sheets): close remaining safety gaps * fix(sheets): align history shortcuts with generated flags Use generated flag defs for history revert commands, enforce control-character validation, and sync the refreshed lark-sheets references from sheet-skill-spec. * fix(sheets): require confirmation for history revert * fix(sheets): require explicit csv input --------- Co-authored-by: xiongyuanwen-byted <xiongyuanwen@bytedance.com> Co-authored-by: wuyanchun.anunwu <wuyanchun.anunwu@bytedance.com> Co-authored-by: wenzhuozhen <wenzhuozhen@bytedance.com> |
||
|
|
fc8d212a4f | feat: add application domain with slash command management shortcuts (#1806) | ||
|
|
e96c4fa581 | test: isolate semantic waiver fixtures from wall clock | ||
|
|
4847f06ca8 | fix: route brand-sensitive endpoints through the resolver (#1836) | ||
|
|
80fadf1801 | fix(drive): abort push on parent sibling limit (#1813) | ||
|
|
cdd9d3409b | feat(affordance): usage guidance for shortcuts and per-command skills (#1793) | ||
|
|
06f6b0b18c |
fix: preserve original filename in multipart file upload (#1767)
* chore: bump oapi-sdk-go/v3 to v3.7.2 for filename-aware multipart upload * fix: preserve original filename in multipart file upload BuildFormdata read local files into a bytes.Reader before handing them to the SDK, so the SDK's part-filename detection (which only reads *os.File) fell back to "unknown-file" for every local --file upload. Use AddFileWithName with the file's basename instead. |
||
|
|
f98dbfe247 | Improve agent-facing error guidance for drive, markdown, and wiki (#1779) | ||
|
|
f0b6f35fee |
fix: resolve schema against runtime metadata in plugin builds; gate cache overlay by version (#1764)
* fix(schema): fall back to runtime catalog when no embedded metadata Binaries built from the bare Go module (plugin builds) embed only the empty meta_data_default.json stub because meta_data.json is gitignored and fetched at build time. The schema command, its completion, and the affordance command-form resolver read the embedded-only catalog, so every schema lookup failed with "Unknown service" even though the runtime registry had already sync-fetched full metadata. Add registry.SchemaCatalog(): embedded when compiled in (official builds unchanged, still deterministic), otherwise the merged runtime catalog seeded from cache or remote fetch. When neither source has data (offline plugin build with a cold cache), schema now returns a failed_precondition error with an actionable hint instead of "Unknown service" with an empty candidate list. * fix(registry): gate cached meta overlay on version newer than embedded The cached remote meta was overlaid onto the embedded meta_data.json unconditionally, so after a CLI upgrade an equal- or older-version cache kept shadowing the freshly shipped embedded definitions until a later refresh happened to rewrite it. Only overlay when the cache version is strictly newer than the embedded baseline. The bare-module stub baseline is "0.0.0", so plugin builds without compiled metadata still take any real cached version (TestOverlayGate_StubEmbedded_OverlaysRealCache) and the schema runtime fallback keeps working offline from a warm cache. Ports #1376 onto the typed meta model. --------- Co-authored-by: liangshuo-1 <266696938+liangshuo-1@users.noreply.github.com> |
||
|
|
91d785f92f |
refactor(envvars): consolidate agent env value access (#1757)
* feat(envvars): add LARKSUITE_CLI_AGENT_NAME accessor envvars.AgentName() reads LARKSUITE_CLI_AGENT_NAME so business code can identify the agent driving the CLI. Value is sanitised (trim, reject control chars, 128-byte cap) and returns "" when unset or invalid. Local-only; not sent to the server. * refactor(envvars): consolidate agent env accessors, dedupe sanitize Move agent-trace reading from cmdutil.AgentTraceValue into envvars.AgentTrace(), symmetric with AgentName and sharing one sanitizeSingleLine. secheader.go now only assembles headers (BaseSecurityHeaders calls envvars.AgentTrace()); the duplicated sanitize and its os/unicode imports are gone. The X-Agent-Trace header and its behaviour are unchanged. --------- Co-authored-by: liangshuo-1 <266696938+liangshuo-1@users.noreply.github.com> |
||
|
|
e621c6e50f | fix: support pnpm global installs in self-update (#1705) | ||
|
|
efa3439e01 |
fix(update): increase npm registry fetch timeout from 5s to 15s (#1724)
The update checker fetches https://registry.npmjs.org/@larksuite/cli/latest with a 5-second HTTP client timeout. Under high-latency network conditions (TUN-mode proxies, VPNs, transcontinental routes), TLS handshake alone can take 4-6 seconds, causing the check to fail with: context deadline exceeded (Client.Timeout exceeded while awaiting headers) Measured example behind a Clash TUN proxy (US node from China): DNS resolve: ~0ms (fake-ip) TCP connect: ~0ms (local TUN) TLS handshake: 4.3-5.9s <-- bottleneck Total: 4.7-6.3s curl succeeds because it has no default connect timeout, but the Go HTTP client with Timeout=5s is too tight. The registry endpoint returns a tiny JSON payload (<1KB), so 15s is more than enough headroom while still failing fast on genuinely unreachable networks. Co-authored-by: 王伟达 <weida.wang@m.com> |
||
|
|
578e2db4e0 | fix: point permission-apply link at official /page/scope-apply entry (#1722) | ||
|
|
440867f1b4 | fix: reduce public content token false positives | ||
|
|
d0cde9a414 |
Improve secure label error handling (#1707)
* Improve secure label error handling * Address secure label review feedback |
||
|
|
a6797ac2e4 | Improve drive batch failure handling (#1703) | ||
|
|
e8bfbab4a5 | fix: reduce public content credential false positives (#1700) | ||
|
|
bdffffb368 | feat: interactive upgrade prompt for bare lark-cli (#1498) | ||
|
|
6f2cddfce1 | fix(identity): correct identity diagnosis under external credential providers (#1693) | ||
|
|
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> |
||
|
|
ebb0b6fe73 | feat(affordance): per-command usage guidance system (markdown source) (#1565) |