Changelog
September 11, 2026 · View on GitHub
All notable changes to this project will be documented in this file.
The format is inspired by Keep a Changelog and this project follows Semantic Versioning.
[Unreleased]
[1.0.62-beta.8] - 2026-09-11
Added
-
OA approval template management (#1346) — add
dws oa approval template listanddetail --template-code <code>for querying manageable approval templates, form schemas, and process configuration. -
Interactive card callback events (Aone 86136546) —
dws event consume user_card_action_triggeredreuses the personal-event subscription lifecycle with the same empty-object filter rule as IM/OA. Its flattened schema describes typed answers and questions underpayload.body.actionData.context, business/conversation/operator fields underpayload.body, and millisecond timestamps while preserving unknown fields for forward compatibility. -
AI 表格记录评论 — 新增评论的分页查询、创建、回复、完整更新和删除命令,支持纯文本、@人员及已上传图片。
-
Calendar event options — adds
--is-all-dayand--add-online-meetingtocalendar event createandupdate, with omission-preserving boolean updates. Explicit all-day state changes require both start and end values, validated as dates or timezone-bearing date-times for the selected state. -
A2UI card options — adds optional
--a2ui-annotationsJSON object arrays to card creation and updates, and--support-forwardto creation (defaults to false). -
Public Agent Skills CLI —
npx skills add DingTalk-Real-AI/dingtalk-workspace-cli -ginstalls the per-productdingtalk-*skills after confirming the skills, target directories, and existing same-named content handling. The all-in-one monodwsskill is markedmetadata.internal: trueso it is not a default installable skill.dws skill setupremains the China / upgrade / ownership path. -
Schema 时间格式声明 — 支持字符串参数以
anyOf声明多个格式,并为日历创建/更新的date-time到date/date-time扩展及全天状态条件必填提供精确、基线持有的迁移校验;其他格式和条件必填变更仍被拦截。 -
Standalone whiteboard export — adds
whiteboard exportandwhiteboard export-getto download PNG/PDF exports. Both commands support request-only dry-run previews. Signed URL query strings do not affect filenames; downloads validate their file signatures before atomic publication and never overwrite existing files. Failed tasks retain recovery instructions with the job ID, format, and output directory. Downloads enforce HTTPS/443 public network targets on redirects and actual connections, with a 512 MiB limit for both declared and streamed response sizes.
Changed
-
AI Table CLI safety and compatibility — adds safe entity resolution for view filters, strengthens dashboard, workflow, import, record, and table validation, supports the latest Base copy and share-form protocols, and aligns Runtime Schema and Skill guidance with observable MCP behavior.
-
Update the embedded CLI telemetry SDK to v0.4.0 and send completed command events from a bounded background process, preserving existing telemetry fields and keeping network waits out of command execution.
-
Update the embedded runtime SDK to 20260909 and remove auxiliary ps files from builds and runtime extraction, reducing single-binary package size.
-
Refresh the macOS universal runtime library while retaining the 1 MiB payload slot and using the payload digest to upgrade existing installations of the same resource version.
Fixed
-
Direct-runtime MCP endpoint resolution (#1331) — restore the environment-aware
mcpdevendpoint sodws dev mcpcommands reach the backend instead of failing locally withendpoint_not_resolved. -
Automatic pagination now preserves cancellation when the page-delay timer and context cancellation become ready together, rather than randomly continuing.
-
OA approval list response types (#1351) — normalize
successto a boolean and numeric error codes toerrorCodefor pending, submitted, and copied approval lists while preserving business data and diagnostics. -
Preserve optional
--source-configfor AI Table datasource updates: read and reuse the complete existing configuration when omitted, and stop before updating if the read cannot provide a valid configuration. -
AI Table capability routing — isolates concurrent multi-profile discovery so each
tools/listrequest uses the selected account without changing the process-wide profile. -
Include the available runtime context in manual OAuth and device authorization links, including
--no-browser, so copied links match browser authorization. Display device links outside a frame to keep long URLs copyable on narrow terminals. -
Stop adding the CLI locale as a
langquery parameter to browser, manual, and reauthorization login links. -
Chat read completeness contracts — makes conversation and message reads distinguish normal bounded truncation from terminal pagination, projection, enrichment, and resource-download failures. Incomplete reads retain their canonical partial result and typed retry diagnostics, while newly declared Result and pagination contracts remain in byte-compatible dual validation before activation.
-
Chat routing and bounded discovery — distinguishes conversation categories from real chat groups, aligns reviewed Shortcut owners with runtime selection and references, and steers agents toward narrow leaf Schema before a single exact Help fallback.
-
Public Schema constraint closure — normalizes reviewed hidden aliases to their public parameters and rejects constraints that cannot be represented without exposing hidden runtime inputs.
-
Drive and Wiki agent workflows — align pagination, confirmation, target verification, recovery receipts, and Reference routing with runtime behavior.
-
Stop implicit HTTP retries of MCP tool invocations after gateway or connection failures, preventing duplicate datasource updates and other remote writes. Discovery and explicit read/reconciliation retry policies retain their existing behavior.
-
Minutes artifact evidence — distinguish empty action items, unsupported responses and speaker-task terminal states; preserve list display metadata and complete upload/permission preview options.
-
Minutes export and delivery — remove signed credentials from exported text, keep partial results explicit, and align time conversion, pagination, permissions and cross-product report guidance with verified runtime behavior.
-
Fix the Windows whiteboard export test to compare decoded JSON paths, and run platform app coverage tests in fresh batches while retaining the full test selection, cross-package instrumentation, and coverage gate.
Security
- AI 表格文件导入 (#1349) — 将上传白名单收紧为服务配置的精确 OSS Bucket 主机与导入对象路径,拒绝同区域其他 Bucket、区域根域和路径式 Bucket URL;复用公网传输 IP 策略,在上传前阻止共享地址段、保留地址及特殊 IPv6 目标。
[1.0.62-beta.7] - 2026-09-09
Added
-
Chat active conversations — adds
dws chat +active-conversations --start <time>to auto-page cross-conversation messages and return deduplicated conversation summaries with stable name fields, latest-message time, and completeness metadata. Query boundaries use whole seconds: explicit nonzero fractional seconds are rejected, and the default end is rounded down to exclude the current unfinished second. The effective end must be later than the start and remains fixed across pages, results, and continuation; latest-message timestamps retain millisecond precision. Returned messages are filtered to the fixed[start,end)window before aggregation; pages with no matching messages still follow server pagination. Pagination waits 200ms between pages by default; later-page failures preserve completed summaries and a continuation cursor aspartial_failure(exit 7). Resume with the original time window, page size, and profile, then merge batches by conversation ID. -
Chat shortcut 对齐与查询校验 — 补充兼容别名、创建默认值、消息上下文定位、文本与 Thread 回复、筛选排序及分页控制,保留原入口;共享消息富化并严格区分空集合、不完整结果与失败,增加资源分段重试、版本校验和原子落盘。下游尚未支持或未实测的身份、消息类型与权限范围单独列明。
-
Contact invite/apply administration — adds
dws contact exclusive-account disable|enablefor enterprise-account status, adws contact orginvite/apply group (invite-switch,invite-audit,invite-info,invite-list,apply-list,apply-approve,apply-reject,apply-block,apply-remove), anddws contact dept invite-auditfor department-level join-request auditing. -
Standalone whiteboards — adds OpenNodes-based
whiteboard create-with-contentand extends the existingwhiteboard query/whiteboard updateentry points to operate on standalone boards when--part-idis omitted, while preserving the document-embedded flow when it is explicitly supplied. Standalone reads decode the serviceresultJson, and writes enforce revision and stable request-ID guards with compatible receipt validation and same-type read-back.
Changed
-
CLI auth apply pending page (#1285) — the browser apply flow now lands on a dedicated approval-pending page that polls and auto-redirects after approval; duplicate apply requests are idempotent, and all local callback pages and API responses are served with
Cache-Control: no-storeto avoid stale state after a page refresh. -
CLI access denial copy (#1285) — terminal denial reasons are now split by whether the path is applyable.
cli_not_enabledkeeps the apply flow and shows a personal-scope message ("you do not yet have CLI data access") with the approver picker relabeled to "select approver"; the inline success message was replaced by a redirect to the pending page. The non-applyableuser_forbiddenanduser_not_allowedreasons now share a single consolidated terminal message ("this organization has not enabled CLI data access") across the browser page and both login transports (OAuth browser flow and device flow). -
Chat recent conversations — makes
--startoptional fordws chat +recent-conversations. Omission selects the 24 hours before the effective--end; omitting both boundaries selects the latest 24 hours ending at the current time rounded down to a whole second. Explicit--startretains the existing time formats, whole-second validation, and blank-input rejection. Both effective boundaries stay fixed across pagination and are returned in the result. Non-initial--cursorrequests must explicitly reuse the previous--startand--endto preserve the original query window. -
Chat recent conversations — makes
dws chat +recent-conversationsthe preferred entry and retains+active-conversationsas a hidden executable compatibility entry sharing the same implementation, without deprecation warnings in execution, Help, or Schema. Public Help, Schema primary CLI paths/examples, and Mono/Multi Skills recommend the new name; the stable Schema identitychat.shortcut_active_conversationsand old CLI-path lookup remain supported. Query windows, pagination, and result semantics are unchanged by this rename. -
Runtime context — Refresh the embedded payload to
20260908, verify and materialize owned resources beside the resolved executable with cache fallback, and attach the process context to browser login URLs while keeping terminal links and diagnostics redacted.
Removed
- 移除顶层
dws safechat命令(破坏性变更) — 删除dws safechat selftest与dws safechat decrypt。这两个命令在1.0.62-beta.3(#1051) 交付,但只在显式-tags safechat的源码构建中存在:官方 Release 一直是CGO_ENABLED=0,stub 的newSafeChatCommand()返回nil,因此官方二进制从未包含该命令,受影响的只有自行打 tag 构建并升级的用户。SafeChat 现在是internal/msgcrypto的内部后端,仅通过聊天消息加解密路径暴露,不再提供独立顶层命令。 - 迁移方式 —
dws safechat decrypt的等价入口是dws chat crypto decrypt,它走同一套 SafeChat 后端并按策略解密。dws safechat selftest(真实取码与密钥获取的端到端自检)没有等价命令;需要验证后端可用性时改用dws chat crypto decrypt对一条真实密文做一次解密。
Fixed
-
Contact apply-list safety semantics —
dws contact org apply-listmarks unread join applications as read on the server; its schema safety effect is now declared aswrite(risk stayslow, confirmation staysnot_required) and the selection guidance discloses the read-marking side effect so Agents no longer treat it as a pure read. -
Contact apply-remove safety semantics —
dws contact org apply-removedeletes organization join application records irreversibly; its schema safety effect is now declared asdestructive(riskhigh, confirmationuser_required) and the selection guidance discloses that the deletion is not recoverable so Agents no longer treat it as an ordinary write. -
Contact org list pagination contract —
dws contact org invite-listanddws contact org apply-listnow declare the unified cursor Pagination contract (cursorparameter,meta.paginationmetadata) and their result data schemas no longer leakhasMore/nextCursor. Runtime responses project the server-side cursor fields intometa.paginationso Agents can resume paging from the standard contract. -
Chat recent conversations pagination — adds a shared
--total-timeoutbudget (default 300 seconds, range 1–3600) across all requests, retries and page delays in one invocation. A timeout preserves validated pages in the partial-failure result and returns the failed page's input cursor. Cursor continuation remains caller-managed: reuse the same profile, time window and page size, and merge batches by conversation ID. Progress is not persisted to disk; forcibly terminated queries must be restarted. -
Chat conversation categories — treat
im/list_conversations_by_categoryas the declared single-response interface when its explicit conversation array contains no pagination signal, while continuing to fail closed on partial or non-resumable pagination metadata.+category-list-conversationsand+feed-group-query-itemnow publish the resolved pagination mode and source-exhaustion facts instead of rejecting every live response that omitshasMore. -
SafeChat 默认构建与官方产物 — 支持平台的 CGO 构建无需额外 build tag 即包含 SafeChat 后端,官方六平台 Release 固定使用可校验的交叉编译工具链并拒绝 发布 CGO-disabled stub 二进制。
-
本地
make build/make rebuild默认启用 CGO,并保留显式CGO_ENABLED=0的 stub 构建选择。 -
Linux 官方构建显式使用 glibc 2.17 链接目标,并校验 ELF 符号版本, 防止交叉编译镜像升级隐式提高 Linux 系统要求。
-
install.sh/install-event.sh/install-devapp.sh在下载前识别 musl 发行版(如 Alpine)并明确中止。Linux 产物依赖 glibc 动态加载器,此前这类环境 会安装成功但连dws version都无法启动。判定以ldd --version为准,musl 加载器文件只在ldd不报版本时兜底(Alpine 的 BusyBoxldd仅转发给加载器), 因此额外安装了musl/musl-tools的 glibc 发行版不会被误拒。 -
SafeChat cipher 关闭时会等待进行中的加解密结束,不再与
Close并发访问 vendor client 的初始化状态(go test -race下可复现的数据竞态)。 -
Schema 向后兼容检查 — 允许删除
require_one_of必填组,以支持具备默认值或可自动解析参数的命令;保留新增约束、互斥、参数类型和身份安全检查,并通过基线拥有的两阶段评审机制交付。 -
Skill setup source resolution — accepts an extracted
dws-skills.ziproot for--source/DWS_SKILL_SOURCE, selects itsmonoormultisubtree by mode, and no longer mistakes the compatibilitymonodirectory for a single MultiSkill.
[1.0.62-beta.6] - 2026-09-08
Added
-
AI 表格 PostgreSQL 只读查询 — 新增
dws aitable psql,支持发现逻辑表和列类型,并执行只读SELECT,包括同一 Base 内的多表 JOIN。 -
Native Markdown themes — adds
--themetomarkdown createandmarkdown overwrite, preserving existing Front Matter while safely writing the selected we-markdown theme into a private upload copy.
Fixed
- AI 表格应用模式输入校验错误分类 (#1314) — 将 icon、background、config、layout 等字段的校验失败从
internal错误和退出码5修正为validation错误和退出码3;校验仍在 MCP 调用前完成。
[1.0.62-beta.5] - 2026-09-07
Added
-
AI 表格应用模式命令 (#1264) — 新增
dws aitable app及page/widget子命令,支持 App 获取与更新、页面和 Widget 的创建、查询、更新、删除与排序。 -
文档块批量删除 —
doc block delete的--block-id支持逗号分隔一次删除多个块 (单次最多 50 个)。采用尽力而为语义:单个 blockId 未找到不阻塞其余块的删除, 未找到的在notFoundBlockIds中列出;仅当全部未找到时整体失败。
Fixed
-
markdown @人 写后回读误报 — 写入含
[@姓名](alidocs-mcp://doc/mention?openDingTalkId=…)的 markdown 时,doc +create与doc +update --command append|overwrite会以doc_write_verification_failed报错,而内容其实已正确写入。原因是写后回读把写入原文与服务端改写后的正文比对,而服务端会把该私有协议改写成钉钉个人资料链接。现在写后回读改为按位置配对:只有预期正文中写了 mention 私有协议的那个位置,才允许回读侧是个人资料链接;其余链接——包括作者自己写的普通个人资料链接——仍保留完整目标并严格比对。显示文本与节点顺序照旧参与比对,漏写、改标签或顺序错乱依旧判定失败。原子命令doc update无写后回读,行为不变。 -
@人 目标身份不再被隐含声明为已验证 — 回读能证明 mention 链接落在作者写的位置、显示文本未变,但证明不了它解析到了哪个人:
openDingTalkId与改写后的staffId是不同值且无本地映射。含 mention 的写入结果因此在与verified同级处声明作用域:verificationScope="partial"、unverified=["mention_targets"],verify 步骤状态由success降为partial并带scope="partial"(只按steps[].status推进、不认识 scope 字段的既有消费者因此也不会再把它读成完整核验成功),另有verification.mentionTargetsVerified=false与一条说明性 warning,并把verified置为false(操作本身仍status=success):回读无法确定 @ 到了谁,就不宣称已验证。另有unverifiableLocally=["mention_targets"]表明该缺口不是"还没查"而是"回读查不出来",重读文档不会得到新信息。warning 只透两条事实:@人链接指向的具体人员需用户自行核对,正文其余部分(含该链接的位置与显示文本)均已通过回读校验。不含 mention 的写入输出完全不变。 -
Chat message decrypt fallback — skips crypto policy lookups and decrypt failure ledger fields on chat read paths when the DWS binary does not include the SafeChat backend, while preserving policy-driven decryption after
chat message list --page-allaggregates its pages. -
AI Table view OR filters — allows
aitable view update filterto persist a single top-levelorgroup while preserving flat-array AND behavior, rejecting nested logical groups, and verifying equivalent service readback shapes. -
OA 空页分页兼容 — 待审批、已处理和已发起审批列表兼容成功响应中
values:[]省略hasMore的终页编码,避免空列表误报missing_pagination;保留显式分页值及业务状态、数组结构和其他接口的严格校验。 -
自动合并:修复 Reviewer Router 将可合并但显示
blocked的 PR 持续跳过的问题;恢复 App 的同步合并尝试,并继续由 GitHub 强制执行审批和必需 CI 检查。 -
Schema compatibility checks — accept a new
require_one_ofgroup when a historical unconditional required parameter without a default already guarantees a supplied member. Other incompatible parameter changes remain rejected; CLI runtime behavior is unchanged.
[1.0.62-beta.4] - 2026-09-04
Fixed
- Release dependency checksums (#1288) — removes stale module checksum records so release validation remains reproducible after
go mod tidy.
[1.0.62-beta.3] - 2026-09-04
Added
-
SafeChat message encryption/decryption (#1051) —
dws safechatcommands enable AnHeng SafeDing (安恒密盾) message encryption and decryption. Available only in builds with-tags safechat(requires CGO and platform-specific static libraries). Commands includesafechat selftestfor end-to-end self-check (real authCode fetch and key retrieval) andsafechat decryptto decrypt ciphertext messages. The PR also addsinternal/msgcryptopackage with cipher operations, vendorAuthCode portal integration, and key server client supporting both in-memory and file-based keystores with 0600 permissions on Unix and warning logs on Windows. -
Chat third-party message decrypt (#1150) — adds policy-driven Ding + SafeChat message decryption for core chat read paths, explicit
dws chat crypto decryptdiagnostics, and IM MCP wiring for policy lookup plus Ding batch decrypt. Outbound send encryption anddws chat crypto encryptare intentionally not enabled in this PR. -
html fetch / create / overwrite / patch — full native
.html/.htmfile support in DingPan or the doc space, mirroring the markdown domain.createaccepts a literal string,@file, stdin (-), or an existing local HTML file via--file.fetchdownloads and prints the remote content (optional sanitized--output).overwritereplaces the whole file with before/after preview on command-level--dry-run;patchapplies literal or RE2 replacements with zero-match never writing and an empty result aborting. Routing matches the markdown leaves: explicit--space-id/--workspace, auto domain probe,--folderread-only probe on create. Drive uploads submit thetext/htmlMIME type. Implemented on a shared textfile engine extracted from the markdown leaves (pure refactor, behavior unchanged).
Changed
-
Bounded CI app race fan-out (#1278) — keeps all nine reviewed
internal/apprace-test partitions process-isolated while balancing them across three physical jobs, reducing focused and full-suite runner demand by six jobs without weakening partition coverage or increasing the 20-minute job limit. -
Chat Shortcut-first discovery — prioritizes Featured Shortcuts in
dws chat --help, keeps the complete canonical Shortcut catalog discoverable, and points overlapping atomic command help to the reviewed Shortcut owner.
Fixed
-
aitable record query --all(#1016) — an empty final page that omits therecordskey now ends pagination normally instead of failing withquery_records response is missing records. -
Post-merge CI admission reuse — reuses exact successful full-suite PR evidence for tree-identical protected-main merges and promotes the verified coverage artifact to the merge SHA cache, reducing duplicate runner work without adding jobs or weakening required contexts.
-
Chat role and category routing — resolves natural group names before group-role operations, aligns role assignment guidance with required non-empty role IDs, and publishes a compact shortcut-first category workflow to reduce Help and Catalog discovery without dropping result, safety, or identity constraints.
-
Contract command safety and Skill routing — Contract destructive operations (
archive,subject delete,subject batch-delete,project delete, andaccount delete) now require explicit user confirmation (--yes) before executing, with Schema Safetyconfirmation=user_required. Batch project/subject deletion rejects empty parsed ID lists, subject deletion enforces the 1000-ID service limit, and required project/subject pagination rejects non-positive values before calling MCP. Account-list execution-time filters are documented consistently as ISO-8601 CLI inputs converted to MCP milliseconds. Legal smart-contract guidance is delivered throughdingtalk-miscinstead of a standalone first-level Skill, and the retirededu-contactendpoint is no longer registered as a supplement server. -
Coverage baseline reliability — balances the existing app test partitions across the current coverage runners and reuses the same bounded path for trusted cold-cache recovery, avoiding the long-lived app test process without adding CI matrix jobs.
-
Dlink target routing — teaches Doc, Drive, Sheet, AITable, shared URL routing, and the
doc infoSchema to resolve shortcut targets throughlinkSourceInfofor content operations while preserving the top-level node for explicit shortcut-entry management. -
Main integration reliability — keeps main and release multi-profile E2E validation focused on the isolated profile chain while existing CI shards own the complete Go regressions, avoiding the long-lived runner shutdown window without adding CI jobs.
-
Minutes permission sharing — adds
--member-staff-idstominutes permission addandminutes +share, preserving leading-zero staff IDs while keeping--member-uidsfor DingTalk UIDs. -
Reviewer Router reconciliation — keeps blocked, conflicting, draft, and otherwise unproven merge candidates retriable without letting one expected not-ready PR fail the repository-wide reconciliation batch.
Security
- Published MCP invocation (#1261) - validates fresh bounded input schemas, restricts endpoint trust and redirects, and prevents automatic call replay.
[1.0.62-beta.2] - 2026-09-02
Added
- Chat A2UI cards (#1140) — adds
chat message send-a2ui-cardandchat message update-a2ui-cardas dedicated A2UI commands while preserving the existing streaming card commands. A2UI content is delivered as a JSON string array, and update status accepts enum names plus compatible numbers 1-9. The streaming update status flag is published as a string while preserving its numeric 1-5 inputs and integer RPC payload.
[1.0.62-beta.1] - 2026-09-01
Added
-
Runtime request context (#1221) — packages an optional runtime payload, reports redacted readiness in
dws doctor, and attaches compact context metadata to supported business requests. -
hrbrain talent-pool save — creates or updates a talent pool. Omit
--pool-codeto create a new pool (only--pool-nameis required) or pass--pool-codeto update an existing one; optional--pool-desc,--rule-json(auto in/out rule, validated as a JSON object), and--pool-tags(validated as a non-empty JSON array) are forwarded to thecreate_or_update_poolMCP tool. The write is gated by a confirmation prompt (--yesto skip). -
hrbrain talent-pool move-members — batch-moves staff into or out of a talent pool via the
entering_or_leaving_poolMCP tool. Requires--pool-code,--opt-type(ENTERING/LEAVING), and--staff-ids(comma-separated work numbers), with an optional--remark. The write is gated by a confirmation prompt (--yesto skip).
Changed
- Single-executable runtime payload (#1233) — bundles the platform payload into
dws, removes the sidecar tree from new archives and installers, and retains sidecar discovery for existing installations.
Fixed
-
Chat atomic message results — normalizes message fields across atomic list and search commands, keeps nested search results aligned with top-level messages, and exposes stable send-status workflow references without removing raw response fields.
-
IM message AI provenance — preserves the lower
messageAiSendFlagvalue across message search, list, mget, @-mention, Pin, quoted-message, forwarded-message, and thread-reply projections.
[1.0.61] - 2026-08-31
This release promotes the sealed v1.0.61-beta.3 contents to stable.
Changed
-
Agent-ready command contracts — expands reviewed Help, Schema, safety, selection, result, pagination, and recovery guidance across the CLI, and moves static MCP authoring and published-tool invocation onto explicit
dws dev mcpanddws mcp publishedcommand surfaces. -
Collaboration and event workflows — adds Chat Thread promotion, conversation-file upload, bounded message pagination, safer quoted replies, DingTalk task lifecycle events, and VoIP invite event consumption.
-
Document and data operations — broadens Sheet batch and CSV controls, strengthens AI Table routing and composite verification, hardens Drive and Wiki shortcuts, and adds safer delegated authorization plus URL-only, optional-output, overwrite-protected, and concurrent-writer-safe downloads.
-
Organization and automation commands — adds contact label and custom field management, tightens attendance date handling and DingTalk task workflows, and improves login, Windows Skill installation, and executable doctor recovery guidance.
-
Runtime and connector reliability — preserves compatible document, Markdown, chat, and shortcut result shapes while improving DING, Whiteboard, Qoder Stream, and cross-product verification and failure evidence.
Changes since v1.0.61-beta.3
Added
-
Chat conversation-file upload — adds
chat conversation-file uploadfor local files, returning reusabledentryIdandspaceIdwithout sending a chat message while leaving the retiredchat file uploadpath unchanged. -
Chat message list page-all —
dws chat message listnow accepts--page-allto iterate the time-boundary pagination automatically and return one mergedmessagesarray (withpagesFetched,stopReason,nextPage, and per-page failure diagnostics).--page-limit(default 50),--max-items, and--page-delaytune the sweep; without--page-allthe command keeps its exact single-page behavior. -
Delegation auth capability options — when
--principal-user-idis set, the per-toolcheck_capabilityverification now carries a tool-specificoptionspayload so the server can authorize the exact operation.createsends the create action parameters (name/type/target folder or workspace),upload/get_file_upload_infosend the upload action parameters (file name and size),import/create_import_sessionsend the target node together with file name, suffix, and size,copy/movesend the resolved source node, permission management sends the target members, anddrive publish(set_file_publish) sends the share-scope target (shareScopeSetParam) so making a file internet-public (WEB) is pre-checked. Tools without a mapping continue to check without anoptionskey. -
Permission target members mapping — permission-management delegation checks normalize both the new structured member format and the legacy
--userslist. Legacy user ids are converted into the structured target-member shape using the current logged-in enterprise corpId (resolved through the$corpIdruntime default), keeping old and new invocations equivalent. -
Import and upload dry-run delegation parity —
doc importanddoc uploadnow run the delegation pre-check on their dry-run previews, matching the execution path. A dry-run combined with--principal-user-idis verified against the command's real first delegated call (create_import_session/get_file_upload_info) before any preview is rendered, and a denied principal blocks the preview. -
Import target folder node resolution —
extractNodeIdnow recognizestargetFolderId(the keydoc import --folderuses to carry its destination), so folder-targeted imports resolve a node id and are gated correctly.copy/moveremain unaffected because an explicitnodeIdstill takes precedence over the folder keys. -
Drive download URL-only mode —
dws drive downloadanddws drive download-versionaccept--url-only, a non-downloading mode that returns the temporary signed download URL and required request headers (downloadUrl/headers, plus optionalfileName/fileSize/version) without writing any file locally; the caller (Agent runtime / external system) performs the download itself. Signed URLs keep literal&separators in JSON output so they are copy-paste usable.--url-onlyis mutually exclusive with--output/--overwrite/--part-size/--parallel/--no-resume(explicit combinations fail fast) and stays effective through thedownload --version Ncompatibility routing.
Changed
-
Drive download optional output —
dws drive downloadanddws drive download-versionno longer require--output: when omitted, files are saved to the current directory with the filename inferred from the responsefileName(falling back to the download URL); explicit--outputbehavior (file path or directory) is unchanged. -
Drive download overwrite guard —
dws drive downloadanddws drive download-versionnow reject downloads when the target file already exists, returning a structuredINPUT_FILE_ALREADY_EXISTSerror with recovery guidance; pass--overwriteto proceed. Re-running the same download used to silently overwrite the existing file. The guard is enforced both before the transfer starts and atomically at publish time (no-replace link), so a file that appears during a long download is never silently overwritten. Resume artifacts (.dwspart/.dwspart.meta) are not treated as conflicts.
Fixed
-
AI Table composite verification — accepts the service's real
newRecordIds, view-filter, and workflow-detail response shapes, and retries only idempotent table-copy read-backs so delayed visibility no longer reports a false partial success. -
Workflow deployment status reporting — replaces
resolved.enablewithresolved.enableRequested;verification.runningnow reports the workflow's observed remote state instead of mirroring whether--enablewas requested. -
Chat message reply (#1210) — allows personal and bot quoted replies in ordinary groups when conversation metadata omits
convThreadEnabled, using the matching group searchchannel=falseas positive evidence while continuing to block topic-circle targets. -
DING failure handling and resource identity — stop when robot credentials are missing or the selected robot is invalid, and preserve source message IDs separately from DING IDs. Recall accepts opaque server-returned DING IDs without guessing resource type from their prefixes; callers check identity provenance in the receipt.
-
Whiteboard verification and recovery — validate connector payloads locally, normalize numeric coordinate comparisons, return compact successful update receipts, and preserve committed-write evidence on readback failure without recommending duplicate append operations.
-
DING and Whiteboard guidance — align mono/multi references, clarify product ownership, and reduce redundant discovery and readback without dropping business information.
-
Drive download concurrent-writer safety —
dws drive downloadanddws drive download-versionno longer risk publishing corrupted mixed content when two processes download to the same target concurrently. Streamed (non-ranged) downloads now write to a uniquely created temp file in the target directory instead of the shared<target>.dwspart, so concurrent writers can no longer truncate each other. Ranged/resume downloads keep the fixed.dwspartpath (required for checkpoint reuse) and take a cross-process lock (<target>.dwspart.lock): a second concurrent writer fails fast with holder diagnostics (pid/host/start time) instead of interleaving writes; the atomic no-replace publish still guards the final target either way. -
Drive shortcut verification — adds bounded automatic pagination for list, search, and recent results, preserves existing data fields alongside unified pagination metadata, identifies pagination failures by their actual operation, rejects metadata-only statistics, and preserves committed resource evidence when create or upload read-back names differ.
-
Qoder Stream replies (#1217) — sends Qoder CLI user messages as typed text-content blocks and surfaces
errors[]from failed stream results, preventing successful DingTalk delivery from degrading into “本地 agent 无文本输出”. -
Drive and Wiki shortcut verification — supports workspace-targeted file uploads and strengthens space-type, pagination, node create/copy/move, and imported-name evidence.
-
Workspace uploads now include the final file name and size in the initial credential request so upload-specific authorization can reject the operation before any file bytes are transferred.
[1.0.61-beta.3] - 2026-08-30
Added
-
Static MCP development and invocation — moves MCP authoring under
dws dev mcpand adds revieweddws mcp publishedcommands for inspecting and invoking published tools without dynamic command injection or credential-bearing endpoint caches. -
DingTalk task personal lifecycle events — adds personal Stream subscriptions for task creation, updates, and deletion, with catalog discovery for task events, validated creator/executor/participant role filters, typed flattened payloads, multi-event consumption, and documented DWS-to-task HSF backend routing.
-
VoIP call invite events — adds
user_voip_call_receive_invitesupport todws event consume, including event discovery, Schema, validation, flattened NDJSON output, and mono/multi Skill guidance.
Fixed
- AITable routing and composite recovery — tighten view-filter and reference guidance, recognize reviewed empty-query responses, and make Base copy target validation, rename recovery, and read-back verification deterministic.
[1.0.61-beta.2] - 2026-08-28
Added
-
Chat emotion favorite local image (#85955640) —
dws chat emotion favoritenow accepts--file-pathfor a local image (jpg/jpeg/png/gif/webp/bmp, up to 10MB) as an alternative to--media-id; the CLI validates the file locally, uploads it throughdingtalk-file/upload_media(bizType=chat_emoticon), and reuses the existing favorite flow with the returned mediaId (mediaIdV1 preferred, falling back to mediaIdV2).--media-idbehavior is unchanged. -
Contact label management — adds
dws contact label update,dws contact label delete,dws contact label add-members,dws contact label remove-members, anddws contact label update-member-scopeto modify, delete, add/remove members, and adjust member scope for contact labels (roles). Also updatesdws contact label createto require an explicit--type role|group:--type rolerequires--parent-idwith a real label group ID;--type groupcreates a root-level label group and must omit--parent-id(the CLI passesparentId=-1). -
Contact custom field management — adds
dws contact ext-field create,dws contact ext-field update, anddws contact ext-field deleteto manage organization custom employee fields (add_org_ext_attrs,update_org_ext_attrs,remove_org_ext_attrs).
Changed
- DingTalk task workflows — adds strict write receipts and read-back verification, executable parameter constraints, local dry-run plans for write shortcuts, bounded list scripts, and per-item verification ledgers for batch creation.
Fixed
-
Beta shortcut response contracts (#1167) — fixes HRbrain talent-pool business-page parsing and Mail template draft-mode input, while keeping OA form listing and other incompletely proven operations fail-closed.
-
Doc output compatibility — preserves the empty pagination failure ledger and lets completed import recovery report an unverified result when the original target is unavailable.
-
Markdown routing and diff guidance — makes
markdown create --folderdetect the Drive or Doc destination before upload, clarifiesmarkdown diffparameter validation, and improves mono/multi Agent routing. -
Chat message list result fields — keeps
result.messages[]aligned with the top-levelmessages[], including the stablemessageIdused by edit and recall, while preserving legacy message fields.
[1.0.61-beta.1] - 2026-08-28
Added
-
Chat Thread — adds
chat thread promoteto upgrade an existing group message into a Thread root message. -
Sheet batch operations — expands
sheet batch-updatefrom 16 to 39 CLI operations, adds strict validation for the new P0/P1 inputs, preserves server-generated create IDs inresults[].data, and JSON-encodes translated operations locally so nested number/boolean values survive the MCP transport. -
Sheet batch dimension coordinates — makes
delete-dimensionandmove-dimensionaccept the same public coordinates as their standalone commands (1-based row numbers or column letters) and translates them locally to the batch API's 0-based indexes. -
Sheet CSV type control — adds
sheet csv-put --auto-convert=false(and the matching batch input) to preserve every non-formula CSV field as text while keeping fields beginning with=as formulas.
Changed
- Agent-friendly Help (Aone 85675069) — adds a root Agent Quickstart and Safety model, renders complete Safety plus reviewed command-selection guidance on every Agent-visible leaf, and links service/leaf Help to the corresponding embedded DWS Skill and stable deep documentation.
Fixed
-
Attendance schedule date ranges (#1154) — sends
attendance schedule getdate ranges as upstream datetime strings, expands date-only inputs to full-day boundaries, and rejects reversed ranges before calling the service. -
Login with unreadable token slots (#1172) — after a fresh OAuth, device, PAT, or
--tokenlogin, legacy global, identity, and organization token slots whose ciphertext no longer decrypts with the current data-encryption key are removed so the new credential can be persisted instead of stranding a completed login at the write preflight. -
Windows Skill installation (#1177) — stops the PowerShell installer from rejecting a correct multi/mono Skill publication when the staged copy and the destination carry different inherited Windows ACLs, and makes the transaction record its published paths before verifying them so a failed publication is rolled back instead of leaving the original Skill stranded in
~/.dws/skill-backups. -
Error-to-doctor recovery guidance — links authentication and network failures to the executable
dws doctorhuman entry ordws doctor --jsonAgent entry across legacy JSON, unified-envelope, shortcut, and multi-profile errors, while keeping permission, validation, confirmation, and upstream business errors on their more specific recovery paths.
[1.0.60] - 2026-08-27
This release promotes the sealed v1.0.60-beta.3 contents to stable.
Changed
-
Document, Drive, and Sheet workflows — adds Drive quota, task polling, export, permission, comment, public-link, history-version, revision, floating image, and delegated-access workflows; hardens document import, large Markdown writes, download handling, and readback verification.
-
Collaboration and automation commands — adds dedicated Chat Thread commands, AITable datasource management, Agoal scorecard search, OA approval attachment upload, and reviewed Whiteboard workflows.
-
Agent-safe CLI contracts (#1161) — publishes stricter pagination, result, confirmation, routing, and error contracts across report, Sheet, Minutes, AiSearch, Contact, Task, Wiki, and document commands, plus reviewed argument aliases for Agoal, DevApp, AITable, and Chat shortcuts.
-
DWS OpenAPI escape hatch — supports file-backed parameters and request bodies, multipart uploads, pagination, and bounded binary downloads while tightening redirect, credential-pair, Keychain migration, and error-handling behavior.
-
Supported command surface — removes the retired Education and College vendor extensions and improves command typo guidance, fork admission, and Reviewer Router merge recovery without weakening protected-main checks.
Changes since v1.0.60-beta.3
Added
-
Drive local-file comments (#1151) — adds the complete global comment lifecycle for Drive files through the shared document comment service, including
create-v2,list-v2, reply, update, delete, batch query, direct-reply listing, resolve, restore, and reaction replies. The existingcreateandlistleaves retain their legacy behavior and output contract with deprecation guidance for an explicit migration. -
Markdown comment reads (#1151) — adds comment listing for native Markdown files with global, inline, resolution-status, and cursor filters, and exposes direct-reply listing across the shared Doc and Sheet comment lifecycle.
-
Chat Thread commands — adds thirteen
chat threadleaves for topic-circle creation, Thread publishing, reading, replying, forwarding, recall, emoji reactions, and text emotions. Parameters keep the originalchat group/chat messagenames, including--conversation-id,--topic-id, and the existing forward flags. -
Doc-business delegation auth — the
drive,doc,sheet,wiki, andmarkdowncommand groups now accept a persistent--principal-user-idflag. When set, the first invocation of each doc-business tool key per node within a session is gated by acheck_capabilityverification on behalf of the principal; granting the capability is an out-of-band action the principal completes on the server side, and the CLI never callsgrant_capability. A denied check surfaces the server's denial message and blocks the original call. -
Dry-run consistency —
checkCapabilitynow executes in dry-run mode as well, ensuring preview and execution behaviors are consistent. In dry-run, the check routes through theReadToolchannel (real network request) instead ofCallTool(which would go through EchoRunner and always deny). -
Dry-run pre-check in helpers — dry-run mode now invokes the delegation auth validator before rendering the preview, ensuring commands that would be denied at execution time are also blocked at preview time.
-
Local rejection for node-less commands — commands that lack a node identifier (e.g. search/list/create without nodeId) now return a clear client-side error (
DELEGATION_AUTH_NOT_SUPPORTED, exit code 3) when--principal-user-idis set, instead of forwarding an incomplete request to the server. -
Concurrency safety — the per-session
checkedmap in the delegation auth decorator is now protected by async.Mutex, preventing data races under concurrent tool invocations. -
Markdown dry-run parity — the
markdownfetch/create/overwrite/patch/diff commands now run the samecheck_capabilitydelegation gate on their dry-run previews asdoc/drivedo; a dry-run combined with--principal-user-idis verified against the command's real first delegated call before any preview is rendered, and a denied principal blocks the preview.
Changed
- Report latest lookup — scans bounded, strictly advancing outbox pages, reconciles duplicate IDs, and reads back the uniquely newest report instead of failing on the first continuation page.
- Sheet create-with-data result — returns the already probed
sheetIdat the top level while preserving legacy.result.nodeIdand outerrequestId, avoids repeating the sheet-list probe, keeps the main-compatible single readback check, and reports post-create partial/unknown state without unsafe whole-workflow retries. - Sheet workflow routing — distinguishes local analysis from Excel-to-online import, exposes template discovery and apply routes, and preserves the full data-validation tri-state contract.
- Received-report helper and routing — restores same-profile sender resolution before inbox filtering, keeps Mono and Multi helpers identical, uses bounded complete pagination, renders epoch timestamps in the Shanghai timezone, fails closed instead of returning incomplete data, and keeps midnight query windows valid.
Fixed
-
Minutes pagination results (#1112) — publishes list, search, and transcript continuation and exhaustion evidence through the unified
meta.paginationenvelope, while keeping business-scope completeness separate from endpoint exhaustion. -
Chat Thread create result — returns the created group's
openConversationIdand omits internalopenCid/cidfields, matchingchat group create --thread. -
Doc agent routing and import defaults — aligns document and drive Skill guidance with the executable CLI contract, preserves structured heading and attachment routes, publishes required shortcut arguments, and resolves the current profile's default document target before an import is submitted.
-
Reviewer Router preflight — defers App-owned merge attempts while GitHub reports transiently unknown mergeability, avoiding false reconciliation failures without weakening approval or required-check enforcement.
[1.0.60-beta.3] - 2026-08-26
Added
- Drive sync batch 2 (#1086) — Five synchronized enhancements aligned with closed-source MR 28427926 / 28769810 / 28967420 / 28972632:
- drive quota + quota apps (#573):
drive quotaqueries enterprise storage (org/app/space levels);drive quota appslists application storage usage with pagination and sorting - drive task get + copy/move auto-polling (#543, #496): unified
drive task get --type <export|import|copy|move> --id <taskId>queries async task status viaquery_task(drive MCP);drive copy/movenow auto-pollquery_taskwhen server returnstaskIdand print normalizedTaskResultJSON on completion - drive export (#593): universal export command supporting all doc types (adoc/axls/appt) with auto-format detection, progressive-backoff polling, and optional
--asyncmode;drive export getqueries export task status - publish set password/expire-days (#584):
drive publish setaccepts--password(4-char alphanumeric, empty to clear) and--expire-days(N=days, 0=permanent); client-side validation of --permission/--password/--expire-days runs before the confirmation gate - doc-whiteboard.md (#571): added
skills/mono/references/products/doc/doc-whiteboard.mddocumenting whiteboard card insertion, deletion, and post-insert verification workflow
- drive quota + quota apps (#573):
Changed
-
Download host trust policy — retires the static DingTalk/OSS download host allowlist, the dial-time public-IP refusal, and the IP-literal refusal from both the shared local download path (
drive +download,drive +version-download, doc/minutes artifact downloads) and the chat message-resource path (chat +messages-resource-download,--download-resources). Download URLs only require HTTPS without userinfo and accept non-default HTTPS ports, because every dimension of a dedicated-deployment storage endpoint — custom domain, port, and network location — is decided by the customer deployment and cannot be enumerated or configured client-side. Verified on a dedicated deployment whose storage domain resolves to a customer-intranet address. Downloads align with the official GUI client, which applies no client-side SSRF interception: download URLs only ever come from authenticated service responses (no command accepts a user-supplied URL), TLS hostname verification pins the connection to the requested host, redirects are re-validated per hop, and service credential headers are stripped once a redirect leaves the original origin. -
Upload host trust unchanged — upload target URLs (
drive +upload, minutes audio upload) keep the pre-existing public DingTalk/OSS trusted host requirement through a dedicated upload validator, so removing the download allowlist does not widen where local file bytes can be sent; the validator also keeps the pre-existing default-port-only HTTPS rule (DingTalk/OSS upload endpoints always serve on 443, so non-default ports accepted for dedicated-deployment downloads stay anomalous for uploads). Download credential headers are issued together with the download URL by the same authenticated service response and follow it as-is on the first request; redirects leaving the original host still strip them. -
report entry submit requires recipients —
dws report entry submit(及废弃别名dws report create)的--to-user-ids从可选提升为必填:无接收人的日志提交在服务端仍返回成功,但日志对任何接收人都不可见。openAPIcreate_report的toUserIds参数保持可选不动,规则仅在 dws CLI 侧收紧——Cobra required 拦截未传场景,RunE 内对空值/纯分隔符(如--to-user-ids ",")同样 fail-closed 拒绝。修复 #85724185。
Removed
- Education and college vendor extensions removed — removes
dws edu-contact,dws edu-group,dws edu-app,dws edu-familygroup, anddws college-contactfrom the CLI, Schema, bundled Skills, and open-edition MCP endpoint registry. Future DWS packages no longer expose these five command surfaces.
Fixed
-
Pull request CI scheduling — stops metadata-only auto-merge enable and disable events from restarting the complete admission graph for an unchanged commit, while the base-owned Reviewer Router continues to enforce merge authority.
-
Command typo guidance — returns a validation error with up to three nearest command suggestions and the parent
--helpentry instead of printing the full command list. -
Document shortcut reliability — adds bounded pagination for document and template listings, supports verified paragraph or heading insertion before a reference block, tolerates service-only Markdown layout normalization during write verification, and resolves and verifies the default “My Documents” import target.
-
Fork pull-request admission — keeps the read-only Reviewer Router identity check fail-closed while allowing external contributors' CI to use the reviewed public App slug when GitHub withholds repository variables.
-
Markdown append chunking rewritten around safe split positions — long markdown is now split so that every chunk is a complete, self-contained top-level block sequence, which is what
update_document mode=appendrequires: the server inserts a brand new structure per call and cannot continue the previous one. Split points are chosen strictly by how much they change the rendered document — fully safe boundaries (blank lines, block starts that interrupt a paragraph) before boundaries that need repair (a table's rows now carry a re-emitted header and delimiter row; a fenced code block is closed and reopened with its original marker and info string) before boundaries that merely restructure (long paragraphs, list items) before a hard character cut. Within a tier the latest boundary in the window wins, since all chunks land in the same document. Every boundary that changes the rendered structure is reported in a newdegradationsfield instead of being applied silently. -
Fixed markdown chunking dropping a newline — the previous splitter rebuilt block text from lines and lost one
\nwhenever the content's last line began a heading, table or code fence, so"para\n# Title"was written as"para# Title"and the heading stopped being a heading. Roughly one in five randomly generated documents was affected. The new splitter slices by offset and never rebuilds text, making content preservation structural. -
Fixed oversized tables and code blocks being cut mid-cell and mid-fence — the hard-split path never received the block type, so it cut at arbitrary character boundaries despite claiming to preserve table and code block integrity.
-
Fixed readback verification comparing against content the server never receives —
doc +create/doc +updateverified the readback against the raw input, so any repaired boundary (and, previously, any paragraph split) failed verification on large documents. Verification now compares against the document the chunk plan says the server should hold. -
Unified four markdown write paths onto one splitter —
doc create/doc update,doc +create/doc +updateanddoc +checkpoint-updatenow sharehelpers.SplitMarkdownForAppendand one limit constant (30000 runes), replacing two independent implementations plus one path that never chunked at all.doc +checkpoint-updateaccepts@fileand stdin content, so oversized input was reachable there while the equivalentdoc +updatechunked.doc +doc-appendtakes--textfrom argv only and now rejects oversized input with a pointer todoc +updaterather than sending one oversized call. -
doc update --indexnow fails closed when the content requires chunking — each chunk creates an unpredictable number of blocks, so the insertion point for later chunks is unknowable; the flag was previously accepted and silently ignored. -
Reviewer Router recovery — keeps exact App-owned PRs that are behind
mainretriable when GitHub reports the protected merge denial asResource not accessible by integration, while preserving every other 403 as a hard failure. -
Reviewer Router merge authority — moves fail-closed writer-rule and auto-merge ownership validation into the trusted base-owned Router before App credentials are read, preparing metadata-only auto-merge changes to stop restarting the full CI suite without weakening protected-main admission or exact-SHA cache production.
-
Reviewer Router merge recovery — retries exact App-owned merge intents through a SHA-bound synchronous merge after GitHub has enforced approval and nine GitHub Actions source-bound required checks.
Security
- DWS OpenAPI escape hatch (Aone #84603971) — Preserves the existing
dws api <METHOD> <PATH>command, five HTTP methods, flags and defaults, App Token cache, new/legacy host token injection, raw successful JSON, and paginated page arrays. Adds--params/--data @file, single-file streaming--file [field=]pathmultipart requests, camelCase pagination fields, and officialopen.dingtalk.com/llms.txtdiscovery guidance in the misc and mono Skills. Resolves Client ID and Client Secret only as a complete flag, environment, or app-config pair; one-shot Raw API flag/environment credentials remain ephemeral, while successful custom-app OAuth login persists its exact pair. Migrates plaintext and legacyclient-secret:<clientID>values toappsecret:<clientID>after the canonical reference is durably stored, and fails closed on conflicting values. Dry-run no longer requires credentials and still performs no Keychain, deferred-file, or network access. Pagination now fails closed instead of returning partial pages, and rejects ambiguous continuation request keys. Non-2xx OpenAPI errors expose top-levelcodeand request ID details without treating a successful payload's businesscodefield as an error. Security tightening rejects HTTP, non-443 ports, cross-origin or HTTPS-downgrade redirects, sanitizes server-provided download filenames, bounds JSON/error bodies, and atomically streams binary downloads through a temporary file.
[1.0.60-beta.2] - 2026-08-24
Added
-
Drive permission get-setting (#1056) — adds
dws drive permission get-setting --node <ID>to inspect a document-space node's permission settings (permission mode, share scope, and permission policies) in one call. -
Whiteboard shortcuts (#1082) — adds strict query and confirmed update workflows with stable-target receipts and exact readback verification.
-
Sheet shortcut hardening (#1082) — makes worksheet listing and cell-range reads fail closed on malformed, ambiguous, or truncated responses, publishes a closed reviewed output shape, and preserves non-executing
--dry-runpreviews for range reads. -
Permission and member list pagination (#1085) —
drive/doc permission listandwiki member listnow accept--next-tokento follow the server-side cursor (output carriestotalCount/hasMore/nextToken) and map--limittopageSizecapped at 50 instead of the rejectedmaxResults 200path;permission add/update/removeandwiki member add/update/removeadditionally accept a--membersJSON array covering USER/DEPT/CONVERSATION/TAG grantee types. The optional--notifydefaults tofalseand is omitted from the server request unless passed explicitly, so member grants no longer notify recipients by default. These commands also declare cursor pagination (next-token) in the Agent schema contract, mirroring the internal CLI parity change. Because a single batch remove can revoke access for up to 30 USER/DEPT/CONVERSATION/TAG members — where departments, chats, and role groups can indirectly affect many more users —drive/doc permission removeandwiki member removenow declareconfirmation=user_requiredand gate the actual tool call behind user confirmation (--yes, an interactive yes, or--dry-runpreview); their confirmation-gate failure now also passes through verbatim instead of being reclassified as a permission-denied or unclassified error. -
Agoal scorecard search-entities —
dws agoal scorecard search-entitiessearches scorecard metrics and key items by keyword, returning matching entity info (scorecard ID, entity ID, entity type, title, owning team) with optional--page/--page-sizepagination. -
AITable datasource shortcuts — adds 7 shortcuts for datasource sync management (
+datasource-create,+datasource-update,+datasource-sync,+datasource-sync-status,+datasource-get-config,+datasource-list-sources,+datasource-get-fields) and updates thedingtalk-aitableskill with routing rules and a newaitable-datasource.mdreference guide. -
Doc public-link and historical-version reads —
dws doc readforwards the reviewedpassword(internet-public documents with password protection) andhistoryVersion(read content as of a listed historical version;0denotes the document's initial version) parameters on the markdown, JSONML, and scope read paths via--password/--version;dws doc +fetchgains--passwordand--versionwith the samehistoryVersionforwarding, while--revisionstays rejected with explicit guidance: revision is the document edit revision returned by JSONML reads for+update --expected-revisionconditional writes, not a historical version number. -
Edu & College vendor extensions — adds five hidden vendor extension commands for education scenarios:
dws edu-contact(school/class/family/teacher contact management),dws edu-group(student/class group lifecycle),dws edu-app(homework, notices, report cards, diplomas, class circles),dws edu-familygroup(family group management, child binding, app permissions), anddws college-contact(university dept/employee/alumni/graduate management). All route to dedicated MCP servers viacallMCPToolOnServer. -
OA approval attachment upload —
dws oa approval attachment upload --file <path>uploads a local file as an approval attachment in one command: it initializes the upload credential (MCPoa/init_attachment_upload_info), HTTP PUTs the file to OSS, then commits it (MCPoa/commit_attachment_upload_info).--file-namedefaults to the file's base name and--md5is auto-computed when omitted. -
Sheet revision changesets — adds read-only commands for querying the current workbook revision and reviewing Agent-readable changes between revisions, with guidance for distinguishing revisions from saved history versions and safely selecting rollback targets.
-
Sheet floating images — supports creating or replacing a floating image directly from a local file with
create-float-image --fileandupdate-float-image --file, while retaining the existing--srcworkflow.
Changed
-
AiSearch and Contact shortcuts (#1083) — adds strict people search and reviewed unified results; people results must use the live-reviewed
personsource, and exact mobile lookups normalize accepted formatting before calling the dedicated mobile interface. Agent/public discovery keepscontact +list-roles,contact +list-roster-fields,contact +get-roster, and incomplete Live routes unavailable rather than publishing ambiguous results, while the historical Contact CLI commands retain legacy MCP execution and real error propagation. The legacy role-list projection preserves the service's reviewed null placeholder without exposing that ambiguous row through Agent Result contracts. -
Permission error guidance and error rendering (#1085) — permission-denied responses now exit with the
AUTH_PERMISSION_DENIEDcode instead of a generic business-error rendering; document/wiki-specific errors (the drive-specific codesforbidden.accessDenied/forbidden.no.auth, or the role-threshold wording like “需要您具备 MANAGER 及以上角色”) carry apply-permission guidance (dws drive permission apply-info/dws drive permission apply), while permission failures carrying only generic code names (FORBIDDEN,NO_PERMISSION— also returned by attendance and event-subscription tools) or other products' wording keep their product-specific or product-neutral suggestion instead of a misleading document-permission hint; member-validation failures such as “用户不存在/不属于当前组织” are classified as tool errors with a--members-with-corpIdsuggestion instead of a misleading resource-not-found error; business error output now surfaces the backend message withcode/logIdappended for traceability; and theupdate_permission/remove_permission/update_member/remove_membertools — whose servers return a literalnullon successful no-payload writes — now render{}so downstream JSON consumers do not fail parsingnull; other tools keep rawnulloutput unchanged.
Fixed
- Legacy global slot recovery — recovers a rejected identity refresh from the legacy global keychain slot when the organization mirror is absent, with strict corp/user matching so blank-user legacy tokens only recover for single-account organizations.
[1.0.60-beta.1] - 2026-08-21
Changed
-
OA, DING, and Report shortcuts — hardens response, identity, pagination, and confirmation contracts; publishes verified form search, receiver status, and report read workflows while withholding shortcuts that lack trustworthy downstream evidence.
-
Stable release sealing — directly preparing a stable release now renders and archives release fragments merged after its beta baseline, avoiding a forced extra beta solely to consume pending notes.
Fixed
-
Calendar empty windows (#1074) — returns a legitimate empty result when the service emits its exact exhausted empty-event sentinel.
-
Task update verification (#1074) — compares due-time readback as exact milliseconds so committed updates are no longer reported as failures.
-
Comment reaction validation (#1074) — narrows accepted reaction input to reviewed DingTalk emoji names and rejects Unicode emoji and unsupported names such as
likeandheartbefore the RPC. -
OAuth refresh falls back to the organization mirror — when the server rejects the current identity's
refresh_tokenwith the reviewedinvalidParameter.authCode.notFoundbusiness code,dwsnow retries once with the still-valid token mirrored in the same organization's slot (same corp, matching or backfilled user identity) before giving up, and writes the rotated credential back to both the identity and the organization slots so the fallback stays usable on later refreshes. Transient failures and direct-mode HTTP rejections without a reviewed business code do not trigger the fallback.
[1.0.59] - 2026-08-20
This release promotes the sealed v1.0.59-beta.5 contents to stable.
Changed
-
Chat personal emotions — adds commands to list, send, and favorite the current user's personal favorite emotions.
-
Minutes, DingTalk tasks, and Wiki parameter aliases — adds reviewed parameter-name normalization, ambiguity guards, and end-to-end payload coverage.
-
Shortcut functional workflows — fixes Drive preview accuracy, AITable write verification and deletion accounting, Wiki feeds, and false-success handling across task, Contact, Minutes, and Wiki operations.
[1.0.59-beta.5] - 2026-08-20
Added
-
Chat personal emotions — adds
chat emotion list,chat emotion send, andchat emotion favoritefor current-user personal favorite emotion listing, sending, and favoriting. -
Minutes, DingTalk tasks, and Wiki parameter aliases — adds reviewed parameter-name normalization, ambiguity guards, and end-to-end payload coverage for the three products.
Fixed
- Shortcut functional workflows (#1050) — fixes truthful Drive push/sync previews, strict AITable write verification and deletion accounting, lossless Wiki feeds, and false-success handling across task, Contact, Minutes, and Wiki operations.
[1.0.59-beta.4] - 2026-08-20
Added
-
招聘职位管理 (#976) — 新增招聘职位列表、详情查询和职位创建命令。
-
OA admin approval query —
oa approval list-by-adminqueries approval instances of a template with admin scope, with simple flags and an advanced--requestmode;startTime/endTimeuseyyyy-MM-dd HH:mm:ssstrings per the 2026-08 MCP contract update (ISO-8601 flag inputs auto-convert), and pageSize/time format are validated client-side with localized errors.
Changed
-
Attendance and Mail Shortcuts (#1045) — publishes only capabilities with strict response, identity, pagination, and real-data verification while retaining historical CLI discovery and argument compatibility for commands that remain unavailable to agents. Mailbox auto-resolution now accepts both reviewed string and object response shapes, and Attendance date ranges cover the complete requested end date without dropping cross-midnight punches whose actual check time is inside the requested range. The schedule query remains CLI-compatible but is withheld from the Agent catalog because its downstream service returns a successful process exit with a null body for both populated and empty ranges.
-
Chat group roles (#1058) — exposes the single-value
--role-idflag for assigning one custom group role while preserving hidden--role-idscompatibility. -
CLI compatibility governance — adds a reviewed two-stage path for hiding retained legacy commands or optional
NoOpt=trueboolean flags from Help and Schema when their activated capability moves to a dedicated command, with legacy-leaf, complete parameter/constant mapping, durable runtime constant evidence, protected framework bridges, dry-run preservation, parameter-collision, and fail-closed required-parameter checks.
Fixed
-
Canonical Agent Skills (#996) — installs bundled DWS Skills once under
~/.agents/skills, migrates duplicate Agent copies, and matches the upstream 76-Agent registry across Go, npm, Shell, and PowerShell. Non-universal Agents use directory links — junctions on Windows from the npm and PowerShell installers, symbolic links fromdws upgrade/dws skill setup— with a safe copy fallback when link creation is unavailable (including Windows without Developer Mode); custom/XDG homes and OpenClaw legacy aliases are preserved. Upgrades now back up and restore Skills safely across external volumes by staging, lexically copying links (including dangling links), verifying contents, and deleting the source only after publication succeeds. Atomic no-replace publication and identity-checked quarantine rollback preserve concurrent user changes instead of overwriting or recursively deleting them; filesystems that reject the no-replace flag (NFS, FUSE, overlayfs) keep the no-clobber contract by holding the claimed destination for the entire transaction — renaming over the claim where the platform permits it, otherwise moving the source children into it — instead of unlinking the claim and retrying a plain rename, which opened a window where a concurrent directory could be overwritten. A degraded child-move that cannot consume the emptied source shell fails the publication loudly with the destination retained, so a failed move never silently discards staging data. When the fresh mkdir-claim identity captured by the child-move fallback — dev:ino on POSIX, the volume file ID on Windows — no longer matches the destination, the publication reportsErrSkillPathPublicationUncertainand keeps the destination: the object may belong to a concurrent writer, and the mono/multi upgrade copy fallbacks as well asdws skill setuphonor the sentinel by surfacing the state instead of retrying over (and displacing) it. npm same-volume and cross-volume moves, PowerShell recoverably moves, and npm canonical-link / copied-set confirmation follow the same occupy-then-confirm contract. Same-volume publication and restore use a no-replace primitive (mkdir-claim plus child move, symlink-at-dest, or hard-link plus retract) so a dest that becomes occupied after any pre-check is refused instead of replaced. A rollback that has already quarantined dest re-checks identity in quarantine and restores an unmatched object onto dest with that same no-replace publish, so dest is not left empty with the concurrent object hidden unless the restore itself fails (then both locations are named). The npm installer now proves ownership at dest (inode, device, fingerprint) before any quarantine rename, matching Go: a concurrent replacement is left on the original path, and only a post-quarantine identity change is restored with no-replace. Go identity proofs report a stable file identity on every platform — dev:ino on Linux and macOS, the volume file ID on Windows — with the post-publish content fingerprint as the backstop against inode recycling; Shell copied-set rollback proves dest first with inode, child names, and a recursive content digest (sorted paths, mode bits, file hashes, link targets) for the same reason, so an in-place content edit after publish is preserved rather than retracted as this transaction's object. The npm installer's mono and multi set copy publication claims the destination with an atomic mkdir before moving the staged children into it, and canonical link publication creates the symlink or junction directly at the destination, so a concurrently created file, symlink, or directory is refused atomically instead of being replaced by Node's replacing rename or linked into byln -Pon POSIX or Windows. The standalone event/devapp copy publishers use the same mkdir claim instead ofmving a staging directory onto dest. Shell copied-set and link rollback claim dest into quarantine before deleting, so a concurrent writer's file, symlink, or directory is renamed back instead of being deleted by a path-blindrmafter an inode pre-check. Because that degraded publication has no atomic no-clobber primitive for a link,dws skill setupfalls back to a direct copy when a link fails to publish as well as when it fails to stage, so non-universal Agents are still configured on those filesystems — except when the failure reports the uncertain sentinel, which retains the destination for manual inspection instead of retrying over it. Failing to retire an obsolete Agent copy is now a warning rather than an install failure. Every install surface prunes~/.dws/skill-backupsto the newest 5 batches from earlier runs while never deleting a backup taken by the run in progress, so a migration that retires more than 5 batches stays reversible; stamp roots created before the ownership marker existed are preserved rather than pruned. Standalone installers verify every downloaded release asset againstchecksums.txt, and the npm engine declaration now reflects the actual Node 16.7+ API floor. -
Chat user mentions — preserves literal
<@openDingTalkId>tokens in current-user Markdown messages and rejects mismatches between message-body mentions and mention flags before sending. -
Chat direct media — uses the IM upload target field for current-user direct file, audio, and video uploads, then uses the Chat receiver field for final message delivery.
[1.0.59-beta.3] - 2026-08-19
Added
-
Robot group reference replies (#928) —
chat message send-by-botsupports paired--replyand--ref-senderflags for Markdown replies that quote an existing group message. -
AI Table server-side statistics — adds
dws aitable record statsfor ungrouped record-set metrics throughquery_records_stats, plusdws aitable record group-statsfor grouped, distinct, and advanced aggregation throughquery_stats; both commands validate their JSON aggregation contracts before dispatch. -
Calendar event share-info (#980) — adds
dws calendar event share-infoto fetch a calendar event's share info (title, organizer, location, join info) for sharing with others; supports--calendar-idand--language. -
Calendar and To-do Shortcut workflows — aligns 47 public task-oriented entries with lark-cli where the DingTalk backend supports equivalent semantics, rejects malformed or missing collections instead of returning false empty success, preserves truthful pagination, and requires stable identifiers plus read-back or explicit terminal receipts for writes. Adds deterministic contract coverage, a PII-safe live E2E runner, and a sanitized capability review with documented platform boundaries.
-
Doc and Sheet comment lifecycle commands — adds
comment batch-query,comment resolve,comment restore, and the lightweightcomment react-replyto bothdws docanddws sheet. The two domains share the samedoc-commentMCP capabilities; batch queries preserve input order for repeatedtopicId:commentKeyreferences, while reaction replies require DingTalk reaction names such as憨笑or鼓掌rather than raw Unicode emoji. -
Sheet SourceRange dropdowns — supports range-backed dropdowns across direct, cell, and batch write paths, with structured readback for valid and invalid references. Batch
set-dropdownnow rejects unsupported top-levelcolors/source-colors; Inline colors belong inoptions[].color, while SourceRange color writes remain unsupported. -
Sheet read completion metadata — documents and preserves returned ranges, truncation reasons, and partial-read status for large range and CSV reads.
Changed
-
AI Table parameter aliases — accepts reviewed equivalent spellings for Base, table, workflow, search, pagination, and description parameters while keeping role-changing or semantically ambiguous inputs blocked.
-
Doc/drive description scope — restates the
dingtalk-docdescription as document-entity-and-content operations with an explicit exclusion list, and narrowsdingtalk-driveto file-level management of DingTalk documents, so first-round Agent selection separates content work from file management without changing CLI behavior.
Fixed
-
Aitable pagination and Minutes unshare verification (#1006) — keeps record queries on the service's 20-record page boundary so multi-page reads and mutation readbacks no longer report false retryable failures, preserves
totalCountwhen supplied, validates--dry-runplans before transport, follows active deletion readback continuations before proving absence, and rejects Minutes unshare success until the listening note exists and the service acknowledges the exact task and member targets. -
Document write verification (#960) — avoids false partial-success results when normalized Markdown, paginated blocks, inline images, or version reverts are confirmed by server readback. Document reverts and media inserts now require explicit readback evidence and report partial success when the server cannot prove the requested result.
-
Chat sender identity guards — preserves unverified mixed sender inputs after exact message
senderIdmatches and aligns--sender-querySkill guidance with fail-closed Runtime behavior. -
Windows event bus lifecycle — start event consumers without unsupported inherited file descriptors, stop buses through local IPC with a termination fallback, and preserve subscription cleanup when startup fails.
[1.0.59-beta.2] - 2026-08-17
Added
-
Privacy-safe CLI telemetry (#1009) — reports reviewed command outcomes and profile identity dimensions while excluding command arguments, output, paths, device fingerprints, and automatic system dimensions;
DO_NOT_TRACK=1disables reporting. -
Feedback survey entry in root help (#1019) —
dws --helpnow closes with a Feedback section linking the user-experience survey form. -
Wiki Shortcut workflows — publishes 20 reviewed space, member, node, and activity shortcuts with strict collection validation, cursor handling, write-terminal evidence, safe read-backs where the backend supports them, task-oriented routing, and documented backend boundaries.
Changed
-
Chat IM ID flags (#954) — standardizes chat command entry points on
--conversation-idfor conversation IDs and--message-idfor message IDs, so help, Schema, and Agent recommendations use the same canonical flags. -
Legacy chat flag compatibility (#954) — keeps older chat IM ID flags such as
--group,--id,--chat,--open-conversation-id,--msg-id, and--open-message-idworking as compatibility aliases where applicable, while hiding migrated aliases from recommended help and Schema surfaces. -
Chat group bots target flag (#954) — keeps
dws chat group botson the visible--groupflag; this command does not register--group-name, and--groupaccepts either an openConversationId or a uniquely resolved group name. -
Faster Schema Catalog assembly — projects typed values into payload JSON without re-running a validation scan over documents
json.Marshalhas just produced, cutting roughly a third of the projection work across the full tool set. Untrusted JSON input keeps its existing validation.
Fixed
- Chat card update evidence — distinguishes an accepted update request from an independently verified visible update, preserving the real
bizIdand warning callers not to repeat an unverified write. - Chat command guidance — splits message and group references by task and explains that
--fromis ambiguous between sender and time-range intent.
[1.0.59-beta.1] - 2026-08-14
Added
-
Drive list type/time filtering (#942) —
dws drive listgains--type file|folder,--start, and--endfor client-side filtering by node type and modification time on both the pan and workspace routes. Filtering runs a bounded full scan of the target directory (2000-entry cap, reported viatruncated=true), composes with--latest/--pattern/--depth, and is mutually exclusive with--versions/--cursor/--order-by/--order/--limit. Time values accept relative forms (24h/7d/2w), RFC 3339, zone-less ISO 8601 (Asia/Shanghai), or a plain date. -
Drive folder synchronization — adds
dws drive status,dws drive pull,dws drive push, anddws drive syncfor file-level comparison and transfer between a local folder and a Drive folder. Differences come from exact MD5 by default or from modification time with--quick;statusis read-only,pullandpushare one-directional with--if-exists skip|smart|overwrite, andsyncis bidirectional with--on-conflict remote-wins|local-wins|keep-both|ask. Only regular files are transferred — online documents and shortcuts are skipped, neither side deletes extra files, downloads are staged through a temporary file and committed with an atomic rename, and remote names that would escape--local-folderare reported as failures instead of being written. Every command prints a structured summary on stdout and exits non-zero when any item fails. -
International DingTalk region support — adds
.iologin and MCP routing, pre-release endpoint overrides, and profile-aware gateway selection while preserving the existing.comflow.
Changed
- Chat identity routing — validates explicit
openDingTalkIdinputs and improves name,userId, andopenDingTalkIdrouting for message shortcuts.
Fixed
-
Drive
--latestrefuses incomplete Top-N (#899) —dws drive list --latestused to exit 0 with a "Top-N" computed over a partially scanned tree whenever a directory read failed mid-recursion (permission denied, API error), letting an incomplete set pose as the globally newest files. Truncation at the 2000-item scan cap and mid-recursion directory failures now both fail closed (LATEST_SCAN_TRUNCATED/LATEST_SCAN_INCOMPLETE), report the first failing folder with its depth and reason, and emit a recovery command that reproduces the original candidate set — query domain,--folder,--pattern,--type,--startand--endare all carried over. On POSIX shells each user-supplied value is quoted so a URL query string or a shell metacharacter cannot change how the copied command parses. On Windows no quoting form is safe for bothcmd.exeand PowerShell, so values containing metacharacters are not inlined at all: the command carries a placeholder and the original value is shown on a separate line marked as data rather than an executable command. Unrecoverable errors under--latestreturn the root cause instead of a partial result. Remote-controlled folder names and server error text are stripped of ANSI escapes and control characters before they reach the plain-text stderr message. The internalsortTimesort key no longer leaks intodrive list --depthoutput on any path. -
Drive list pattern filtering (#942) —
dws drive list --patternon the single-layer pan route now filters the returned page by name pattern; the flag was previously accepted but silently ignored. -
Drive list
--type folder --latestcomposition (#942) —--latestnow ranks the filtered entries (folders included when--type folderis set) instead of unconditionally dropping folders, so the documented combination returns the most recently modified folders rather than an empty list. -
Chat message time defaults (#973) — default omitted
chat message list-alltime bounds inAsia/Shanghaiwhen emitting timezone-lessyyyy-MM-dd HH:mm:ssvalues, matching parsing semantics and rejecting reversed windows. -
Doc and Drive parameter aliases — normalizes reviewed identifier, pagination, path, version, and role synonyms while blocking ambiguous values before dispatch.
[1.0.58] - 2026-08-13
This release promotes the sealed v1.0.58-beta.6 contents to stable.
Changed
- Expanded collaborative workflows — adds full AI Table, Sheet, Minutes, approval-event, Drive-comment, document export, and CSV workflow support, including safer validation, explicit confirmation for writes, and machine-readable completion receipts.
- More capable Chat operations — adds robot image/file messages, toolbar management, streaming-card mentions, automatic pagination controls, and clearer post-send ID, Markdown-image, paging, and result-shape guidance.
- Reliable Agent and CLI contracts — expands Agent-visible Chat and Minutes commands, aligns bundled skills, improves schema/result envelopes, and hardens parameter, pagination, runtime-token, and write-result verification so ambiguous or incomplete operations fail closed.
- Multi-skill install and upgrade — makes the multi-skill layout the default for fresh installs and upgrades while preserving an explicit legacy mono option.
- Safer release delivery — strengthens release-equivalent compatibility, sealing, package verification, and evaluation-dispatch checks for more reliable cross-platform releases.
[1.0.58-beta.6] - 2026-08-13
Fixed
- npm package verification for multi-skill installs (#991) — aligns the release verifier with the installer’s concrete Agent skill-root selection, preventing valid multi-skill package layouts from failing release delivery.
Changed
- Release-seal CI classification (#987) — recognizes the reviewed CHANGELOG-and-fragment archival shape while retaining release-contract and lifecycle validation, reducing unrelated CI work for release-seal PRs.
[1.0.58-beta.5] - 2026-08-13
Added
-
Agent version and extended context passthrough (Aone 85384225) — adds validated
DWS_AGENT_VERand sensitive JSONDWS_AGENT_EXTmetadata to ordinary non-plugin MCP requests without forwarding it to A2A, OAuth, Discovery, or third-party plugins. -
Drive file comments (#961) — adds
dws drive comment listanddws drive comment createfor comments on ordinary preview files. -
Chat automatic pagination controls (#970) — adds bounded
--max-itemsand cancellable--page-delaysupport to the core IM list shortcuts, with safe continuation metadata and truncation reporting.
Changed
-
Chat message send help - Clarifies Markdown image syntax for inline mixed text and images.
-
Doc/drive/wiki routing descriptions — clarifies the document-space container-vs-content boundary across the doc, drive, and wiki skill descriptions for more predictable first-round Agent selection, without changing CLI behavior.
[1.0.58-beta.4] - 2026-08-12
Added
- Multi-skill installation and upgrade — fresh installs,
dws skill setup, anddws upgradenow use the multi-skill layout by default. Existing mono installations migrate during upgrade; mono remains an explicit legacy option. - Native streaming-card mentions —
dws chat message send-cardnow accepts--at-open-dingtalk-idsand--at-allfor group cards and forwards them tocreate_and_send_card, matching the existing shortcut behavior without changing single-chat card creation. - Expanded Minutes workflows — 27 public Minutes shortcuts now cover upload, download, export, recording, analysis, sharing, and recovery flows; every write command keeps an explicit confirmation requirement.
- Chat command discovery — 30 existing typed Chat commands are now available in the runtime Schema and Agent catalog, with sensitive writes carrying their required confirmation metadata.
Changed
- Chat read results — typed commands and shortcuts now expose a consistent
top-level
messageslist with stablemessageIdandtextfields while retaining existing response envelopes and fields. - Wiki feed results — Wiki feed list output now formats time fields and
trims excess fields. Its
--limitdefault is 10 and maximum is 20. - Developer command results — the
devand selecteddevappcommands now use the unified result envelope for consistent success, pending, partial, and failure reporting. - Evaluation dispatch hardening —
/evalnow uses a verifiable polling relay instead of direct access from the hosted runner, binding the workflow, comment, PR head, parameters, and result provenance.
Fixed
- Streaming-card update acknowledgement — accepts the pre-production
success: trueresponse fromupdate_streaming_cardas affirmative write evidence while preserving explicit negative, conflicting, and bizId-drift failures, so Agents do not repeat an update that the service already applied. - Text input bounds — literal input, stdin, and
@fileinputs now all enforce the same byte limit; file reads validate the opened descriptor and cannot exceed the limit after a path replacement or file growth. - Evaluation PR comments — restores
/evalPR conversation comments with the least required pull-request write permission and actionable GitHub 403 diagnostics.
[1.0.58-beta.3] - 2026-08-11
Added
- Aitable workflow execution and history — adds
dws aitable workflow runfor confirmed asynchronous execution of scheduled or record-triggered workflows, plusdws aitable workflow historyfor status-, time-, and page-filtered execution records. The commands map directly toaitable/run_workflowandaitable/get_flow_record_list, validate trigger-specific arguments locally, and document theexecutionId/instanceIdcorrelation. - Streaming-card mentions —
chat +messages-send-cardnow accepts--at-open-dingtalk-idsand--at-allfor group cards, passing mention targets to the initial card-creation request and prepending its returnedatTagto the automatic streaming update. - Personal OA approval events — personal event consumers now support task creation, completion, redirection, instance start, termination, and completion events, with typed output and matching usage documentation.
Fixed
- Machine-readable export and download receipts —
dws doc export,dws drive download, anddws drive download --versionnow keep progress logs on stderr under--format jsonand emit one JSON result on stdout after a successful local write. The result includes the saved path and byte size; document exports additionally report the node, requested format, job/task ID, and final status. - IM search and card-write safety — conversation-scoped search now fails closed when the target cannot be verified, and streaming-card updates require business evidence rather than a transport-only success response.
- Document shortcut reliability — document write, readback verification, pagination, template/version discovery, export, media, and local-file workflows now preserve compatibility while rejecting ambiguous write results.
- Event runtime-token handoff — personal
event consume,status,stop, and+listen-imhonor the root--tokenwithout falling back to a stale OAuth profile. Detached buses negotiate an owner-only, memory-only IPC credential channel; tokens are never placed in child argv, environment, profiles, logs, or run-state files.
Changed
- Minutes
permission apply --policytype —--policyis now declared as anintflag and its required check usesFlags().Changed, matching the numeric-parameter convention.--helpreportsintinstead ofstring; accepted values (2/3/4) and gateway behavior are unchanged. - Minutes skill references — document
permission applyin both Minutes skill references: list it in the command trees, describe its policy values and how it differs frompermission add, and add its intent routing. - Chat paging guidance — typed chat message commands now document
--page-all, aggregate result shapes, and cursor behavior in CLI Help and Agent selection examples. - Calendar skill parity — mono and multi Calendar references are aligned to prevent documentation drift without changing CLI behavior.
- Release engineering — CI now shards helper-package changes through the
full race suite, widens a flaky stdio idempotency test budget, governs exact
reviewed CLI/Schema type migrations, and lets authorized maintainers trigger
internal MCP evaluation with a reviewed
/evalPR comment.
[1.0.58-beta.2] - 2026-08-10
Added
dws sheet create-with-data(新命令) — 建表并写入初始数据与样式:--values(二维数组写默认表)/--sheets(typed table 多工作表,二者必须给一个)/--styles(cell_styles/row_sizes/col_sizes/cell_merges,顶层键对齐飞书 snake_case、列表项内字段兼容 camelCase)。所有结构、字段类型与枚举在创建文档之前校验,非法配置不会留下白建的空文档:--sheets按table_put的输入契约逐字段校验(columns必填且列名非空不重复、data为二维且行宽与columns一致、单元格仅限字符串/数字/布尔/null、dtypes/formats的键须是列名、mode/header/allowOverwrite/startCell类型与取值、单表 30000 单元格上限),并拒绝未知键、snake_case 变体、{"sheets":"bad"}这类畸形包装与sheetId(服务端会静默丢弃写错的键,导致"只写了表头却报成功"的静默丢数据);--values校验单元格为标量并受 30000 单元格 / 2000000 字符上限约束;--styles的顶层键与列表项内字段同样拒绝未知键,避免样式只应用一半。写入后回读校验按startCell/header/mode推算的首个预期非空单元格,而非固定 A1。该命令是多步编排(建文档 → 探活 → 定位默认工作表 → 写数据 → 回读 → 可选样式),因此如实声明为独立叶子sheet.create_with_data+interface_mode: composite(附评审 reason,按契约不带interface_ref);dws sheet create保持原样不变——仍是一次create_workspace_sheet直连(interface_mode: mcp),不新增 flag,避免让 Schema 消费者把编排步骤的参数误当成该 RPC 的入参。dws sheet export-csv(新命令) — 同步导出单个工作表为 RFC4180 CSV,支持--sheet-id选表、--range限定范围、--value-render-option选取值模式;--output落盘(为目录时按sheet-export.csv命名,落盘走AtomicWrite原子替换,写入失败时已有文件保持原样;父目录不存在按错误处理,不会自动创建),不传则把纯 CSV 打到 stdout(警告只走 stderr)。数据超出单次读取上限时默认报错、既不输出也不写文件,需--allow-truncated显式接受不完整结果。响应缺csv字段或类型不对一律报错,不会用 0 字节覆盖已有文件。该分支读的是get_range_as_csv、与 xlsx 的异步导出任务毫无关系,因此独立成叶子sheet.export_csv并如实声明interface_mode: mcp+interface_ref: get_range_as_csv;dws sheet export保持原样不变——仍只导 xlsx(interface_ref: submit_export_job),flag 面仍是--node/--output,csv 专属 flag 不会出现在它上面(此前挂在同一条命令上时,漏写--export-format csv会让--range被静默丢弃而导出整篇工作簿)。sheet update-dimension --size-type—pixel/standard(恢复默认行高列宽)/auto(按内容自适应行高,仅 ROWS)。sheet replace --match-formula— 在公式文本中查找替换。sheet range set-style扩展样式维度 — 新增--font-style(斜体)/--font-line(下划线、删除线)/--font-family/--border-styles-json(四边边框;每条边只接受style/color,未知键与非字符串color直接报错,不再静默忽略而画出无颜色的边框,set-style/batch-set-style/create-with-data --styles三条路径同源校验)。sheet range batch-set-style --ranges— 一组样式刷多个带工作表前缀的区域,组装为一次原子batch_update。
Changed
- Chat message post-send ID handoff (#897) — CLI Help and bundled Skills
now document the
send→query-send-status→edit/recallworkflow, so callers can reuse returned task, message, and conversation IDs instead of searching message history by content. - Sheet mono/multi Skill alignment — replaces the oversized mono Sheet reference with the progressive routing layout, aligns all 20 Sheet topic references across the mono and multi bundles, and adds a content-policy guard that prevents the paired topic trees from drifting again.
sheet range set-style后端切换为set_cell_range— 样式统一走 cellStyles 路径(仅设样式、保留原值),这是斜体/下划线删除线/字体族/边框唯一可用的通道。interface_ref由update_range变为set_cell_range,12 个样式 flag 改为 reviewed mapping exclusion。CLI 用法向后兼容、无 flag 删除;schema-compatibility 经 reviewed 豁免判定为兼容(0 changed fields)。sheet range batch-set-style改为单次原子提交 — 由本地循环多次update_range改为一次batch_update,任一项失败默认整批回滚;--continue-on-error由本地控制改为透传服务端。新增批量上限:最多 100 个区域且累计不超过 200000 个单元格。sheet range batch-clear/batch-set-style的--ranges拒绝空白工作表前缀(用户可见行为变更)— 此前只按原始串里!的位置判断," !A1:B2"修剪后工作表名成了空串,操作却照样带着sheetId: ""提交:服务端要么让整批batch_update失败,要么更糟——落到默认工作表而不是用户指定的那张表,且命令报成功。现在工作表名与范围都必须在修剪之后仍非空,否则在发起任何请求之前报错。batch-set-style --batch的纯空白sheetId/range同样拒绝(此前只挡空字符串);--batch下发仍用原值不替用户修剪,因为sheetId可以是允许带首尾空格的工作表名。两条--ranges路径现在共用同一个拆分器。sheet insert-dimension/delete-dimension/update-dimension的--length严格校验(用户可见行为变更)— 解析由fmt.Sscanf("%d")改为strconv.Atoi。此前只消费前缀数字,--length 2x/3foo会被静默当成2/3并对错误的行列数执行操作(删除方向不可回滚);现在整个值必须是合法正整数,否则报错「--length必须为正整数(>= 1)」且不发起任何请求。升级影响:原先依赖这种宽松解析、在传畸形--length的脚本会开始报错,请把参数修正为纯数字。合法数字值行为不变,上限仍为 5000。add-dimension的--length是Int类型 flag,一直由 cobra 严格校验,不受影响。- CLI 接口兼容门禁支持 reviewed flag 类型豁免(无用户可见变更)—
authoritative-interface-integrity与check-command-compatibility.sh此前一律拒绝历史命令的 flag 类型变更,即使新类型只是把同一套校验从 RunE 前移到解析期,也没有任何评审通道。现在两道门禁各带一张精确豁免表:命令路径 + flag 名 + 旧类型 → 新类型四元组全等才命中、方向敏感(string→int与int→string是两个不同的键,只有被评审的方向可用),且仅当该 flag 的其他契约(shorthand / required / hidden / no-opt / scope)纹丝不动时才放行,因此豁免夹带不了别的破坏。首条也是目前唯一一条登记的是dws minutes permission apply --policy的string→int(配合 #912):旧实现在 RunE 里做strconv.ParseInt(v, 10, 64)再校验[2,4],新实现由 pflag 以strconv.ParseInt(s, 0, 64)解析后仍校验[2,4],历史上能成功的调用集是新调用集的子集(base 0 额外接受0x3这类写法,只放宽不收紧),非法值依然失败、只是报错文案与时机前移;flag 默认值由""变"0"是类型的必然结果,两道门禁都不比较默认值,且该 flag 必须显式给出、默认值不可达。两张表必须逐字一致并有守卫测试锚定漂移——重复是被迫的而非选择:check-authoritative-interface-baselines.sh会把整个scripts/policy/interface-baseline目录复制进检出历史版本的 worktree 再编译,那份拷贝不能 import 本分支新增的包。 - Schema 兼容门禁支持 reviewed 参数类型豁免(无用户可见变更)— 接上一条。
schema-compatibility是同一个Interface Integrityjob 里排在两道 CLI 接口门禁之后的第三道检查,此前也一律拒绝已发布参数的type变更。由于前两道先失败、set -e让它从未在 CI 上暴露,上一条豁免只解决了三分之二。现在checkParameterCompatibility也带一张精确豁免表:<product>/<tool id>+ 参数名 + 旧类型 + 新类型四元组全等才命中、方向敏感,且仅当该参数除type外的全部已发布字段逐字段相等时才放行。这里刻意用相等性比较而非「没有产生其他兼容性错误」:放宽required/cli_required、清空required_when、扩宽enum、清空interface_type、经 reviewed mapping exclusion 清空property——这些变化单独看都是兼容的、根本不产生错误,若以错误列表代替相等性检查,它们就能搭着一次已评审的类型迁移一起蒙混过关。结构体整体比较还意味着将来给parameterSchema新增字段时会自动纳入守卫,而不是悄悄放宽每一条既有条目。唯一条目是minutes/minutes.apply_minutes_permission的policy由"string"迁移到"integer"(配合 #912):该type由 Cobra flag 类型投影而来(provenancecobra_flag_type),描述的是 CLI 如何接受取值;消费方据此拼装的是命令行,而--policy 4在两种声明下是同一个 argv,加引号的--policy "4"到 pflag 仍是 4,RunE 也仍校验[2,4]——而且该参数映射的 propertypolicyId一直以数字上报,新声明比旧声明更贴近真实请求。表里的类型值必须是schemaType实际产出的带引号形态("string"而非裸string),守卫测试用schemaType复算并校验类型名属于 JSON Schema 的封闭取值集合——reviewedInterfaceRefRedirect曾因键的书写形态错误两次静默失效,这里不重犯。
Fixed
- Event runtime-token handoff — personal
event consume,status,stop, and+listen-imnow honor the existing root--tokeninstead of falling back to a stale local OAuth profile. Detached personal-event buses negotiate the credential only after an additive capability handshake, receive and rotate it through owner-only local IPC, and keep it in memory; the token is never forwarded through child argv, environment variables, profiles, logs, or run-state files. Existing OAuth and multi-profile behavior is unchanged when--tokenis absent. A new client refuses to send a runtime token to an older bus and leaves its existing consumers and subscriptions untouched; the recovery message asks users to inspectevent status --as user, previewevent stop --as user --all --dry-run, and explicitly confirmevent stop --as user --all --yesbefore retrying.
[1.0.58-beta.1] - 2026-08-07
Added
- Robot image and file messages (#867) —
dws chat message send-by-botnow supports image URLs and local-file uploads through explicit message types, while retaining Markdown as the default and preserving its existing title and text requirements. - Conversation shortcut-bar management (#877) — adds
dws chat toolbarcommands to list, add, hide, sort, and manage custom conversation shortcuts, with validation and confirmation for destructive removal. - Complete AI Table Shortcut surface (#901) — makes all 92 supported AI Table Shortcuts discoverable through Runtime Schema and adds reliable Base, table, record, attachment, view, dashboard, and workflow operations with explicit confirmation and result-verification semantics for writes.
Changed
- Doc import upload fallback —
dws doc importno longer fails on file formats outside the conversion whitelist (html, pdf, zip, extensionless, and any future format): it now hands the file to the document-space upload chain (the same primitive asdws drive upload --workspace), stores the original file at the requested--folder/--workspacetarget, and prints an explicit stderr notice with the supported-format list and the convert-to-md alternative. The fallback shares the import file checks (20MB cap, empty-file guard), keeps--format json/--dry-runoutput as a single JSON document, and marks the machine-readable result withfallback: "upload"andconverted: falseso agents never mistake the stored file for a converted online document. The fallback fails closed unless the commit response parses as JSON and carries a file identity (exposed asdentry_id); empty or unverifiable responses surface as errors instead of fabricated success. Importable formats anddws sheet importvalidation are unchanged. - IM natural-target and history alignment — Chat shortcuts can resolve natural user/group targets before execution, and message-history workflows expose bounded time ranges, ordering, explicit all-page controls, continuation ledgers, safe local export, and thread-reply pagination without treating empty or incomplete reads as successful results. Bundled mono/multi Skills and intent routing now describe the same executable surface.
- Sheet CSV formula writes —
dws sheet csv-putand batchcsv-putnow expose the service contract that CSV fields beginning with=are written as formulas. Prefix the field with an apostrophe to write literal text beginning with=; CSV content continues to pass through unchanged. - Release-equivalent PR compatibility gate (#889) — pull-request
admission now runs command-surface compatibility checks against the current
release baseline before code reaches
main. - Reviewer routing governance (#903) — updates the Reviewer Router pool used for new ready PRs while retaining the existing current-head review and required-check gates.
Fixed
- Fail-closed IM pagination and audit evidence —
+chat-messages,+search-msg,+thread-replies,+at-me,+my-groups, conversation lists, and favorites preserve partial-read failures, reject missing or stalled continuation state, deduplicate page boundaries, and publish completion evidence. The live-audit regression suite now rejects empty projections and incomplete reads instead of promoting them to passing results. - Sheet formula verification (#873) —
dws sheet formula-verifynow calls the registered remote tool nameverify_formula; the previousformula_verifyname failed at gateway dispatch. - CLI and parameter recovery boundaries (#864) — command and parameter recovery now fail closed when an Agent-provided path or flag cannot be reconciled with the executable CLI surface, reducing unsafe hallucinated retries.
[1.0.57-beta.4] - 2026-08-06
Added
- Expanded open CLI workflows (#887) — adds calendar event-instance queries, Drive latest-file selection, Markdown diff, Mail calendar/export/ share-to-chat workflows, and Minutes hot-word, permission, and audio-memo operations, with matching Schema and cross-platform coverage.
Changed
- Multi-skill framework alignment (#887) — folds long-tail skills into
dingtalk-misc, renames the shared package todingtalk-shared, removes stale Preview guidance, and reorganizes shared recipes and routing for more predictable Agent selection. - Bounded Agent Schema delivery (#887) — keeps compact and wire projections
focused on executable contract facts, retires stale MCP metadata candidates,
and teaches Agents to prefer
dws schema --compactfor bounded context.
Deprecated
- Recovery and discovery-cache compatibility surfaces (#887) — keeps
visible Deprecated
dws recoveryanddws cachecompatibility stubs while retiring their former recovery engine and dynamic discovery-cache behavior. Recovery plan/execute/finalize now return an explicit “不再支持” notice, and Skills no longer teach either retired workflow.
Fixed
- Mail share-to-chat confirmation (#887) — requires explicit confirmation before the first remote write, while preserving the confirmed sign-retry flow and covering both direct-success and retry responses.
[1.0.57] - 2026-08-06
This stable release promotes the fully delivered v1.0.57-beta.4 baseline.
It includes the v1.0.57 beta-line command-contract, document, chat, OA, Wiki,
and compatibility improvements, plus the multi-skill framework alignment and
expanded calendar, Drive, Markdown, Mail, and Minutes workflows validated in
the final prerelease.
- Promote v1.0.57-beta.4 — publishes the final validated prerelease
baseline as stable
v1.0.57without adding post-beta product changes.
[1.0.57-beta.3] - 2026-08-06
Added
- Reviewed document shortcuts (#880) — adds public document shortcuts for safe local downloads, content and history, review, media and style, and document access/sharing workflows, while retaining reviewed compatibility identities and confirmation safeguards for writes.
- Mentions in chat replies (#881) —
chat message replynow supports--at-open-dingtalk-idsand--at-all, forwarding reply mention fields and adding any required mention placeholders without changing existing send behavior.
[1.0.57-beta.2] - 2026-08-05
Fixed
- Stable Chat command compatibility (#876) — restores the hidden migration
entries for
chat send,chat history, and theirimaliases, preserving the v1.0.56 command surface while directing callers to the supportedchat message send/listcommands. Legacy flags now reach the same migration hints instead of failing during flag parsing. - Drive download cancellation-test stability (#876) — replaces a timing-sensitive worker-cancellation coverage test with a deterministic seam, reducing flaky CI without changing download behavior.
[1.0.57-beta.1] - 2026-08-05
This beta starts the v1.0.57 line on top of v1.0.56. It packages the unified command-contract and runtime Schema architecture, complete Multi IM Chat coverage, document whiteboard and OA approval workflows, Wiki activity feeds, and compatibility and CI reliability fixes.
Added
- Contact personal-status updates (#872) — adds
contact user update-ownness(aliasset-ownness) for updating a user's personal status text. The write operation maps revieweduserIdandownnessTextparameters to the service contract and requires confirmation unless--yesis explicitly supplied. - Document whiteboard workflows (#861) — adds
doc whiteboard insert,whiteboard query/update, anddoc media upload. These commands support confirmed document-embedded whiteboard creation and updates, structured OpenNodes reads, and preparation of node-bound Vector/SVG resources. - Complete Multi IM Chat coverage (#860) — hardens deterministic group and stable-ID resolution, sending, querying, downloading, pagination, and JSON export. The remaining reviewed Chat Shortcuts enter Schema coverage, with destructive delete and clear operations aligned to confirmation gates.
- OA approval form workflows (#853) — adds OA form-schema lookup,
process forecast, and confirmed approval-instance creation, supporting both
simple flags and complete
--requestpayloads. - Wiki activity-feed queries (#862) — adds
wiki feed listto retrieve workspace document activity, with cursor paging and optional file exclusion.
Changed
- Unified command and Schema contract framework (#830) — Leaf commands and
Shortcuts now use the shared typed
corecmdbase for flags, constraints, confirmation, Help, and runtime Schema projection. Schema delivery assembles from leaf Contract declarations at runtime; the retired hint overlays, pinned MCP metadata, and committed Catalog artifacts are no longer delivery authorities. - Faster macOS CI without reducing native coverage (#857) — narrows the macOS race suite to Keychain, codesign, and Darwin-only tests while adding a reachability contract that prevents native-only tests from being silently excluded.
Fixed
- Chat media-download JSON compatibility (#854) — restores parseable
success,downloadUrl, andoutputfields forchat message download-media --format jsonafter a successful download, without progress output corrupting JSON stdout.
Added
- Document-embedded whiteboard workflows — adds
doc whiteboard insertfor confirmed creation and part-ID verification,whiteboard query/updatefor structured OpenNodes reads and confirmed writes, anddoc media uploadfor preparing node-bound Vector/SVG resources. The public adapter uses an explicit helper-only whiteboard endpoint, validates update envelopes locally, decodesresultJson, and publishes the full command, Schema, Skill, and safety contract migrated fromdws-wukong@e2da8ab947c6. - Robot image and file messages — extends
chat message send-by-botwith public image URL delivery through--msg-type image --image-urland local-file upload/send through--msg-type file --file-path, while preserving Markdown as the default message type.
Changed
- Chat reply mentions —
dws chat message replycan @ specified group members with--at-open-dingtalk-idsor @ everyone with--at-all, forwarding the existingsend_personal_messagemention fields and automatically adding missing current-user<@id>/<@all>placeholders. - Pinned MCP metadata retired — deletes
internal/cli/schema_mcp_metadata.jsonand removes its embed/loader/fallback role from Schema assembly. Catalog now assembles from Contract/ParamDecl/Interface + Cobra only;make fetch-mcp-metadataremains an optional diagnostic dump underartifacts/and refuses the retired pin path. Policy bans the pin from reappearing. - MCP service review retired — deletes
schema_mcp_service_review.jsonand removes its policy jq / outputguard / test disposition gate (notify→out_of_surface, snapshot hash pin). No replacement ledger. - Hints retired; ContractDecl is the leaf Schema source (#830) —
schema_hints/, Manual/Schema hint overlays, andschema_agent_metadata/delivery are removed. Selection, safety, parameters, and interface facts declare on ProductDecl / leafContract(corecmd.ContractDecl+contract.ParamDecl/Safety). Authoring renamedSchemaDecl→ContractDecl; nested fields reusecontract.*directly. - Contract package seam (#830) — types / ProductDecl live under
internal/corecmd/contract(DTO only). Annotate writers live ininternal/corecmd/runtimeannotate; Cobra-keyed ContractFinal store + Register live ininternal/corecmd/contractfinal; homology gates ininternal/cli/homology. All packages importcorecmd/*directly; the formercli/runtimeannotate/cli/contractfinalshim packages are removed, and thecliroot keeps only package-local aliases (runtime_schema_seam.go). Catalog/ResolveMetastay on theclidelivery root.internal/corecmdmust not import anyinternal/clipackage. - CommandMeta cache for ResolveMeta — production
ResolveMeta/ leaf--helpSafety project from the runtime-assembledSchemaRegistryinto amap[cli_path]CommandMetainstalled duringdeliverySchemaCatalogsync.Once. Steady-state lookups are O(1); full Catalog wire maps stay deferred. RegistrySourcestampsruntime-assembled.
Fixed
- Fail-closed IM pagination and audit evidence —
+chat-messages,+search-msg,+thread-replies,+at-me,+my-groups, conversation lists, and favorites preserve partial-read failures, reject missing or stalled continuation state, deduplicate page boundaries, and publish completion evidence. The live-audit regression suite now rejects empty projections and incomplete reads instead of promoting them to passing results. - Unified command safety and Shortcut runtime (H0) — Shortcut leaves now execute through
corecmd.New, sharing the same typed Safety confirmation gate as Leaf commands. EOF / closed stdin returnsconfirmation_required, and interactivenoreturns the existing non-zero cancellation validation error instead of reporting success for an operation that did not run. Pass--yesor--dry-runto skip the prompt. - Constraint "provided" for
at_least_one/exactly_one(H0) — a flag set to an empty string (--flag "") no longer counts as provided; previously bare CobraChangedsatisfied the constraint. Pass a non-blank value for a member of the group. - Chat media download JSON compatibility —
dws chat message download-media --format jsononce again returns a clean{success, downloadUrl, output}result after the file is saved, preserving the temporary URL and resolved local path without progress text corrupting JSON stdout.
[1.0.56] - 2026-08-04
This stable release promotes the fully delivered v1.0.56-beta.4 baseline.
It includes PR #852's resilient multipart Drive download implementation,
together with the v1.0.56 beta-line command, Schema, Skill, and runtime
improvements already validated through the prerelease channel.
Added
- Resilient multipart Drive downloads (#852) —
drive downloadanddrive download-versionsupport parallel chunk transfer, Range probing, fingerprint-validated checkpoint resume, automatic 401/403 credential refresh, and graceful interruption with checkpoint preservation.
[1.0.56-beta.4] - 2026-08-04
This beta adds PR #852 on top of v1.0.56-beta.3. It makes Drive downloads resilient for large files through parallel transfer, validated resumable checkpoints, and automatic credential refresh.
Added
- Multipart Drive downloads (#852) — adds
--part-size,--parallel, and--no-resumetodrive downloadanddrive download-version. Files above the part-size threshold use a Range probe and parallel chunks, resume from a fingerprint-validated checkpoint, refresh credentials on 401/403, and keep the checkpoint when Ctrl+C interrupts a transfer.
[1.0.56-beta.3] - 2026-08-03
This beta adds PRs #846 and #851 on top of v1.0.56-beta.2. It adds a service-provided Aitable workflow-editing reference command and makes local event-bus IPC reliable on shared filesystems by placing Unix sockets in a validated private runtime directory.
Added
- Aitable workflow editing reference (#851) — adds
dws aitable workflow edit-example, a parameter-free read command that returns the service-provided workflow editing documentation andworkflow-dsl/v1examples throughaitable/edit_workflow_example.
Fixed
- Event bus sockets on shared filesystems (#846) — Unix event buses now place their local IPC socket in a private per-user runtime directory (
XDG_RUNTIME_DIRwhen available, otherwise a0700per-UID directory under the system temporary directory) while retaining locks, metadata, logs, and subscription state in the configured Workdir. Listener and dial paths validate directory ownership and permissions before use. This preventsdws event consumefrom failing withbind: errno 524when~/.dwsis hosted on NFS, CSI, FUSE, or another filesystem that does not support Unix Domain Sockets without exposing the socket directly in a shared/tmproot. WhenXDG_RUNTIME_DIRis unavailable, the per-UID directory name is deterministic: ownership validation prevents endpoint hijacking, but another local user can pre-create the directory to deny service; multi-user deployments should provide a privateXDG_RUNTIME_DIR.
[1.0.56-beta.2] - 2026-07-30
This beta adds PRs #831 and #835 on top of v1.0.56-beta.1. It separates Agent Product observability and IM display identity from the stable edition-owned PAT and routing identity, and reduces common-path Skill context loading without changing the public command or Runtime Schema surface.
Changed
- Agent Product identity separation (#831) — sends
DWS_AGENT_PRODUCTthrough the newx-dws-agent-productobservability Header and uses a valid non-empty value for the IMclawTypedisplay label whenever--ai-tagis enabled. Because--ai-tagdefaults totrue, callers that setDWS_AGENT_PRODUCTchange the displayed label by default. With--ai-tag=false, nativechat message send/replycalls preserve their existing wire shape by sending an empty IMclawType, while shortcut calls omit the argument. Unset or empty Product values omit the Header and preserve the active edition's IM display default. - Agent Host dimension convention (#831) — new integrations should send the runtime form (
cloudordesktop) throughDWS_AGENT_HOSTand report the product separately throughDWS_AGENT_PRODUCT. Legacy combined labels such asqwenwork_cloudremain syntactically valid for compatibility. - Reduced common-path Skill context (#835) — keeps the complete 97-command Chat Shortcut inventory in Runtime Catalog and leaf Schema while routing common intents through compact Skill tables and references. When an exact command path is already known, the mono Skill no longer requires eager loading of a complete product reference. The generated Skill policy now detects drift, forced full-reference loading, and context-budget regressions; the common Chat plus shared activation estimate drops from 7,301 to 4,771
o200k_basetokens without changing the 845-tool Schema surface.
Fixed
- Stable PAT/routing identity (#831) — restores the CLI-emitted open-source HTTP
claw-typeand PAThostControl.clawTypeto the edition-fixedopenClawvalue.DWS_AGENT_PRODUCTno longer changes those wire values, and the client continues to derive PAT, authentication, routing, and Discovery behaviour from the existing independent signals. - Portable generated Skill validation (#835) — resolves the mono Skill name by scanning upward from the generated target, keeping
--checkindependent of the repository checkout path and preventing false drift failures when an ancestor directory resembles a Skill name.
[1.0.56-beta.1] - 2026-07-30
This beta starts the v1.0.56 line on top of v1.0.55 and packages PRs #817, #806, and #834, together with release-validation fixes #838 and #839. It closes the remaining Agent-visible IM shortcut gaps, introduces reviewed command-scoped parameter normalization without guessing business identifiers or values, and prevents deterministic personal-event subscription failures from becoming unbounded retry storms.
Added
- Complete IM shortcut workflows (#817) — publishes the previously excluded
+chat-messages,+messages-send,+messages-send-card,+search-msg, and+thread-repliesshortcuts in Runtime Schema. Unified send, streaming-card delivery, advanced search, thread replies, and opt-in resource downloads now share reviewed parameters, selection guidance, and runtime-aligned safety semantics. - Reviewed parameter concept normalization (#806) — adds a closed parameter-concept dictionary and generated command-level alias table, covering reviewed IM synonyms while preserving the boundaries between group, conversation, user, open-user, cursor, and paging identifiers.
Fixed
- Message delivery and resource handling (#817) — resolves direct recipients through exact contact search, preserves rich and nested message resources, avoids same-name download overwrites, and prevents read shortcuts from silently returning empty results on non-interactive input.
- Parameter parsing safety (#806) — rejects ambiguous, blocked, or conflicting aliases before dispatch, normalizes explicit boolean values such as
--dry-run false, and keeps internal pre-parse handler details out of user-visible errors. - Personal-event subscription retry safety (#834) — adds cross-process attempt claims, deterministic backoff and jitter,
Retry-Afterhandling, terminal holds, compare-and-swap completion, and fail-closed state handling across all public personal-event subscriptions, preventing deterministic failures from causing unbounded callback retries. - Scoped CI and release validation reliability (#838, #839) — keeps scoped coverage aligned with intentionally skipped supporting profiles, gives focused race and Multi-profile E2E suites enough time for the current
internal/appworkload, and preserves hidden E2E diagnostics on failure.
[1.0.55-beta.8] - 2026-07-30
This beta revalidates the v1.0.55-beta.7 product baseline through a complete
guarded release delivery. It carries no new product-facing command behavior;
the new version is required because the published beta.7 artifacts succeeded
on GitHub, npm, and Homebrew, but its enabled optional Gitee mirror failed and
left that Release run ineligible for stable promotion.
Changed
- Complete promotion evidence — republishes the validated v1.0.55 command, Runtime Schema, Skill, authentication, and projection changes with the optional Gitee upload fallback disabled, so the release can produce one successful auditable delivery proof before stable promotion.
[1.0.55] - 2026-07-30
This release promotes the validated v1.0.55-beta.8 baseline to stable. It
expands the public Workspace command surface and personal event consumption,
makes the full built-in shortcut catalog available to Agents, and hardens
multi-account routing, authentication compatibility, command safety, and
response projection across the CLI.
Added
- Broader Workspace command surface (#621, #676) — adds roughly 30 reviewed Drive, Doc, Sheet, and Chat leaf commands synchronized from Wukong, including Drive version and permission operations, document styling, Sheet comment/version/formula verification, and in-place text-emotion updates. A reusable declarative
LeafSpecframework now delivers command identity, safety, selection, and guarded Help metadata consistently. - Complete Agent-visible shortcut delivery (#802, #815) — publishes all 210 built-in shortcuts as reviewed Runtime Schema leaves across 16 products, including 88 validated Chat shortcuts, with executable paths, parameters, constraints, selection guidance, dry-run capabilities, and runtime-aligned confirmation semantics.
- Expanded enterprise and event capabilities (#790) — adds the HR Brain talent-pool, employee-profile, and structured-search command families;
dws mcp url getresolves MCP Market endpoints; personal event consumption supports eight additional IM event keys, multi-key consumers, and targeted shutdown. - Agent integration identity (#804, #816) — adds validated
DWS_AGENT_HOSTandDWS_AGENT_PRODUCTlabels for observability and product attribution while keeping them separate from authentication and authorization.
Changed
- Progressive multi-Skill guidance and account safety (#621, #821) — reorganizes bundled product guidance for progressive discovery and restores the mandatory rule that Agents must not guess an account when a multi-account organization has no unique current default.
- Supported Chat file delivery — retires the legacy AppKey/AppSecret-backed
chat media uploadcommand from discovery and routes local files throughchat message send --msg-type file --file-path, while callers with an existing media ID can continue sending images directly. - Guarded release delivery (#791) — strengthens immutable GitHub, npm, Homebrew, optional mirror, recovery, and version-allocation checks while keeping beta and stable publication role-gated and auditable.
Fixed
- Shortcut and message projection correctness (#706, #783, #795) — prevents successful read shortcuts from silently projecting non-empty backend responses to empty results, renders rich, forwarded, and encrypted message forms safely, and fixes group-bot, bot-search, mail-thread, media-ID alias, and Todo paging response handling.
- Command contract edge cases (#803) — makes approval revocation and document rollback honor dry-run before confirmation or preflight, fixes Drive and Doc rename semantics, restores Drive-specific metadata, and validates Todo reminder rules.
- Authentication and external-contact compatibility (#756, #757) — migrates legacy global and organization-scoped credentials without cross-account token borrowing, preserves contacts that expose only
openDingTalkId, and aligns message-resource flags with message-list output fields.
[1.0.55-beta.7] - 2026-07-29
This beta supersedes the unpublished v1.0.55-beta.6 candidate and packages
PRs #621, #676, #757, #815, #816, and #821. It restores the mandatory
multi-account safety rule caught by the sealed-release E2E gate while retaining
the reviewed Wukong capability and multi-Skill synchronization, declarative
command and Schema delivery, hardened Chat shortcuts, external contact
resolution, and Agent product identity on top of the v1.0.55-beta.5 baseline.
Added
- Wukong capability and multi-Skill synchronization (#621) — ports roughly 30 reviewed leaf commands into the open-source CLI across Drive, Doc, Sheet, and Chat, including in-place text-emotion updates, Drive version and permission operations, document styling, and Sheet comment/version/formula verification. The bundled multi-Skill framework is reorganized into progressive product references and routing guidance while retaining current open-source command, response, safety, and Runtime Schema contracts.
- Declarative leaf commands and unified metadata delivery (#676) — adds the reusable
LeafSpeccommand framework and migrates 27 DevApp commands without changing their paths or flags. Runtime consumers now resolve identity, safety, and selection through one embedded Catalog-backed API, and guarded Help output publishes the command's safety/confirmation annotation. - Agent product identity (#816) — adds the optional
DWS_AGENT_PRODUCToverride for the existing HTTPclaw-typeheader while preserving each edition's default when unset. Product and runtime labels are caller-declared signals, not authentication credentials; services must validate supported values and must not grant access solely from them. The override does not change the separate IM message-displayclawTypeparameter controlled by the edition and--ai-tag.
Changed
- Reviewed Chat shortcut delivery (#815) — publishes 88 currently available Chat shortcuts after real-business validation, keeps three confirmed lower-service failures unavailable, strengthens semantic availability and dry-run contracts, and adds safe message-resource download plus group-member listing. Conversation filtering, IM routing/reporting, and member mute resolution are aligned with the validated backend identities.
- Agent identity label hardening (#816) — limits
DWS_AGENT_PRODUCTandDWS_AGENT_HOSTto 64 ASCII bytes, trims only surrounding ASCII spaces and tabs, and rejects other control or Unicode whitespace. QwenWork integrations should report the two dimensions separately asDWS_AGENT_PRODUCT=qwenworkplusDWS_AGENT_HOST=cloudordesktop; previously used combined Host labels such asqwenwork_cloudremain syntactically valid for compatibility.
Fixed
- External-contact and message-resource chaining (#757) — the shared name-to-ID resolver keeps external or cross-organization contacts that expose only
openDingTalkId, applies reviewed display-name fallbacks, and preserves organization-only filtering for commands that requireuserId.chat +messages-resource-urlnow accepts--msg-idand--open-message-idas aliases for--message-id, matching message-list response fields. - Multi-account Skill safety contract (#821) — restores the mandatory rule that an Agent must never choose the first, most recently logged-in, or most recently used account when an organization has multiple accounts without one unique
isOrgCurrent=truedefault. A PR-level embedded-Skill regression test now catches removal before the full sealed-release E2E gate.
[1.0.55-beta.6] - 2026-07-29
This beta packages PRs #621, #676, #757, #815, and #816, validating the Wukong
capability and multi-Skill synchronization, declarative command and Schema
delivery, hardened Chat shortcuts, external contact resolution, and Agent
product identity on top of the v1.0.55-beta.5 baseline.
Added
- Wukong capability and multi-Skill synchronization (#621) — ports roughly 30 reviewed leaf commands into the open-source CLI across Drive, Doc, Sheet, and Chat, including in-place text-emotion updates, Drive version and permission operations, document styling, and Sheet comment/version/formula verification. The bundled multi-Skill framework is reorganized into progressive product references and routing guidance while retaining current open-source command, response, safety, and Runtime Schema contracts.
- Declarative leaf commands and unified metadata delivery (#676) — adds the reusable
LeafSpeccommand framework and migrates 27 DevApp commands without changing their paths or flags. Runtime consumers now resolve identity, safety, and selection through one embedded Catalog-backed API, and guarded Help output publishes the command's safety/confirmation annotation. - Agent product identity (#816) — adds the optional
DWS_AGENT_PRODUCToverride for the existing HTTPclaw-typeheader while preserving each edition's default when unset. Product and runtime labels are caller-declared signals, not authentication credentials; services must validate supported values and must not grant access solely from them. The override does not change the separate IM message-displayclawTypeparameter controlled by the edition and--ai-tag.
Changed
- Reviewed Chat shortcut delivery (#815) — publishes 88 currently available Chat shortcuts after real-business validation, keeps three confirmed lower-service failures unavailable, strengthens semantic availability and dry-run contracts, and adds safe message-resource download plus group-member listing. Conversation filtering, IM routing/reporting, and member mute resolution are aligned with the validated backend identities.
- Agent identity label hardening (#816) — limits
DWS_AGENT_PRODUCTandDWS_AGENT_HOSTto 64 ASCII bytes, trims only surrounding ASCII spaces and tabs, and rejects other control or Unicode whitespace. QwenWork integrations should report the two dimensions separately asDWS_AGENT_PRODUCT=qwenworkplusDWS_AGENT_HOST=cloudordesktop; previously used combined Host labels such asqwenwork_cloudremain syntactically valid for compatibility.
Fixed
- External-contact and message-resource chaining (#757) — the shared name-to-ID resolver keeps external or cross-organization contacts that expose only
openDingTalkId, applies reviewed display-name fallbacks, and preserves organization-only filtering for commands that requireuserId.chat +messages-resource-urlnow accepts--msg-idand--open-message-idas aliases for--message-id, matching message-list response fields.
[1.0.55-beta.5] - 2026-07-28
This beta validates expanded personal event consumption, complete Agent-visible
Runtime Schema coverage for all 210 built-in shortcuts, Agent host
observability, and hardened document, Drive, approval, and Todo command
contracts on top of the v1.0.55-beta.4 baseline.
Added
- Expanded personal event consumption (#790) — adds eight IM personal event keys, supports subscribing to and consuming multiple event keys in one
dws event consumeinvocation, and adds targeted local-consumer shutdown when a subscription is stopped so other consumers can continue on the shared event bus. - Shortcut Runtime Schema delivery (#802) — publishes all 210 public built-in shortcuts as reviewed Agent-visible leaf tools across 16 product groups, with stable canonical identities, executable
+shortcutCLI paths, parameter and cross-parameter constraints, selection guidance, interface metadata, and runtime-aligned safety/confirmation semantics.dws shortcut listremains the lightweight batch-discovery view, while leaf Schema now carries the complete Agent contract; declared string-slice defaults are also preserved consistently in Cobra and Schema. - Agent host observability (#804) — accepts an optional, validated
DWS_AGENT_HOSTlabel and sends it asx-dws-agent-hostfor logs and BI only; invalid values fail before CLI network activity, and the label never participates in authentication or routing.
Fixed
- Command contract edge cases (#803) — approval revocation and document-version rollback now honor
--dry-runbefore confirmation or remote preflight;drive renameremoves only a suffix matching the node's current extension to avoid duplicate extensions whiledoc renamepreserves the caller's exact display name;doc infokeeps its stable MCP contract whiledrive inforestores Drive-only metadata such as a non-nullfileSize; and Todo reminder writes now reject invalid rule JSON while Help, Schema, and Skills distinguish a due time from an independently unreadable reminder rule.
[1.0.55-beta.4] - 2026-07-27
This beta validates the shortcut projection fixes for group bots, bot search,
and mail threads, together with hardened release delivery to Gitee and npm on
top of the v1.0.55-beta.3 baseline.
Fixed
- Shortcut projection fixes (#795) —
chat +chat-botsno longer projects a non-emptylist_group_botsresponse to an empty list,+bot-findrecognizes thesearch_botsresponse shape (result.botsentries withbotOpenDingTalkId), and mail thread listings keeplastUpdatedwhen the backend returnslastModifiedDateTime.
Changed
- Hardened release delivery — the Gitee mirror workflow can synchronize a specific release's assets on demand, release lookup tolerates Gitee's HTTP 200 null-body response for missing releases, npm dist-tag verification waits through slow registry CDN propagation with incremental backoff, and beta/stable release operations are role-enforced (#791).
[1.0.55-beta.3] - 2026-07-24
This beta validates the HR Brain command surface, smoother guarded release
automation, and deterministic Markdown test coverage on top of the
v1.0.55-beta.2 baseline.
Added
- HR Brain (
dws hrbrain) command surface — adds 11 commands across three groups:talent-pool list/detail/employeesfor talent pool browsing,profile metadata/query/labels/career/performancefor employee profile data, andsearch employees/employees-structured/fieldsfor basic and advanced (rule-based) people search. Ships with bundled mono/multi Skill guidance (dingtalk-hrbrain,cli_version: ">=1.0.54");search employees-structuredvalidates--origin-jsonas a JSON object and--fieldsas a JSON array before dispatch.
Changed
- Smoother guarded releases — publishes verified stable and beta Homebrew Formula updates directly from the release workflow, retries transient tag-ref visibility failures, lets an exact same-run retry reuse its sealed tag, and allows machine-verified rebuild recovery without a separate approval wait.
Fixed
- Deterministic Markdown coverage — replaces timing-dependent temporary-file deletion tests with synchronized file-stat failures so release admission no longer flakes on scheduler timing.
Changed
- Faster guarded releases — trusts an independently revalidated, exact
CHANGELOG.md-only successor of an already admittedmaincommit, runs cloud planning alongside governance, and executes sealed-release automation, compatibility, and multi-profile validation in parallel with artifact compilation. Normal cloud publication no longer requires an unshareable local packaging preflight. - Scoped document reads and group mentions —
doc read --content-format jsonmlcan returnoutline,range,section, or custom-tag fragments with depth and block-boundary controls; document comment create, reply, and update can mention groups through--mentioned-open-conversation-id. - Drive overwrite uploads —
drive upload --node <fileId>can replace an existing Drive or document-space file, is mutually exclusive with--folder, supports dry-run, and requires confirmation before writing. - Chat nickname clearing and cross-organization todos — omitting
--nickfromchat group update-nicknow clears the current user's group nickname, whiletodo task list --query-allqueries todos across organizations.
Fixed
- Legacy authentication compatibility (#756) — migrates pre-v1.0.53 global and organization-scoped login state into the identity-aware token store, including all legacy organizations, while keeping unresolved accounts isolated from exact
corpId:userIdcredentials so external or no-directory identities can complete login without borrowing another user's token.
[1.0.55-beta.1] - 2026-07-23
This beta validates MCP Market URL resolution, the supported Wukong local-file send path after retiring the legacy credential-based media upload command from discovery, and reliable message-read rendering for rich content, forwarded records, encrypted messages, and media-download ID aliases.
Added
- MCP URL resolution — adds
dws mcp url get <mcpId>for resolving a DingTalk MCP Market ID to the current user and organization scoped Streamable HTTP URL, while keeping the helper-onlymcp-metaendpoint out of the public product command surface.
Changed
- Chat local-file sending — hides the open-source-only
chat media uploadcompatibility command from Help, Schema, and bundled Skills, and removes its legacy AppKey/AppSecret OAPI path. Historical argv still receives an actionable migration error. Send local images and files throughchat message send --msg-type file --file-path; callers that already hold a mediaId may continue to use--msg-type image --media-id.
Fixed
- Shortcut projection silent-empty returns (#783) — a batch of read shortcuts returned an empty list with exit 0 and no error envelope even when the underlying MCP tool returned data, so agents misread "no data". The projection resolvers now probe the real container keys (
processCodeList,values,wikiSpaces,itemList,groupList,recentItems,emailAccounts,deptUserList,labelUserList,roles,report_list, and the groupedget_org_labelslabels[]), unwrap items nested under a VO wrapper (shiftVO/entityVO/userInfo), andtodo +created-todosuses the shared pager (pageSize=20) because the backend silently returns an empty page forpageSize>20. Affects contact/oa/wiki/drive/minutes/calendar/attendance/chat/report/smart shortcuts, each with a guard test asserting the real response shape projects non-empty.scripts/shortcut_real_result.pyalso gains an upper-vs-lower layer comparison so an exit-0 empty projection over a non-empty backend is scored asprojection-data-lossin the real read-audit path rather thanreal-ok. - Message-read shortcut projection (#706) — the message-list shortcuts (
chat +chat-messages/+messages-list/+messages-list-direct/+at-me/+search-msg/+thread-replies) now render card and out-of-office rich-content JSON as readable text (without ever rewriting ordinary text that merely embeds a JSON fragment), expand a forwarded chat record's nestedforwardMessagesinstead of collapsing to a "[卡片]" summary, and mark undecryptable encrypted card messages as[加密消息]; the speaker is read from the baresenderkey, nested{name:…}sender objects yield their display name, and the literal string"null"is treated as absent. Shared projection helpers now live ininternal/shortcut/chatmsg.chat message download-mediaalso gains--msg-id/--open-message-idaliases for its--message-idflag so agents copying theopenMessageId/msgIdoutput field no longer hit "unknown flag".
[1.0.54] - 2026-07-21
This release promotes the validated v1.0.54-beta.2 baseline to stable. It restores the default transport envelope for personal event output with opt-in flattening, plus Schema CLI path and plugin overlay compatibility fixes.
Changed
- Personal event output compatibility (#743) —
event consumeonce again preserves the transport envelope by default forndjson/json/pretty, while retaining the existingcompactprocessor. New Agent workflows opt into the event-specific top-level DTO with--flatten, which is mutually exclusive with-f rawand--debug-raw-events;event schema --flattendescribes that DTO, while the default schema describestype/event_type/data/headersand points to.data | fromjson.
Fixed
- Schema CLI path compatibility (#738) — user-facing Schema lookups once again accept space-, dot-, and slash-separated CLI paths without weakening strict canonical identity resolution.
- Plugin CLI overlays (#701) — installed plugins register their manifest-authored command trees again for HTTP and stdio servers, and a plugin may now replace a hidden compatibility fallback (for example
conference) instead of being skipped as a distribution conflict.
[1.0.54-beta.2] - 2026-07-21
This beta revalidates the same v1.0.54-beta.1 source through the cloud release path with a sealed OSS-Mirror: deferred policy, because the manually tagged v1.0.54-beta.1 push run failed on the unavailable OSS mirror channel after GitHub and npm delivery.
Changed
- Release delivery only — no source changes since
v1.0.54-beta.1; see that section for the user-visible changes under validation (#743, #738, #701).
[1.0.54-beta.1] - 2026-07-21
This beta validates the restored default transport envelope for personal event output with opt-in flattening, plus Schema CLI path and plugin overlay compatibility fixes, on top of the validated v1.0.53-beta.7 baseline.
Changed
- Personal event output compatibility (#743) —
event consumeonce again preserves the transport envelope by default forndjson/json/pretty, while retaining the existingcompactprocessor. New Agent workflows opt into the event-specific top-level DTO with--flatten, which is mutually exclusive with-f rawand--debug-raw-events;event schema --flattendescribes that DTO, while the default schema describestype/event_type/data/headersand points to.data | fromjson.
Fixed
- Schema CLI path compatibility (#738) — user-facing Schema lookups once again accept space-, dot-, and slash-separated CLI paths without weakening strict canonical identity resolution.
- Plugin CLI overlays (#701) — installed plugins register their manifest-authored command trees again for HTTP and stdio servers, and a plugin may now replace a hidden compatibility fallback (for example
conference) instead of being skipped as a distribution conflict.
[1.0.53] - 2026-07-21
This release promotes the validated v1.0.53-beta.7 baseline to stable. It adds enterprise onboarding, declarative shortcuts, Sheet/Aitable writes, multi-account profiles, and broader personal IM events, while hardening authentication and the guarded release path.
Added
- Enterprise and office command coverage — adds enterprise creation, employee invitation, and account provisioning commands; 366 declarative service shortcuts; Sheet import commands; and Aitable workflow create/update support with reviewed Schema contracts.
- Multiple accounts in one DingTalk organization — profiles can distinguish accounts by organization and user, select them explicitly, and log out one account or an entire organization without overwriting another account's credentials.
- Expanded personal IM event subscriptions (#651) — adds read-receipt, recall, and reaction events for one-to-one and group chats, plus specified-sender subscriptions by staff ID or OpenDingTalk ID.
- Official multi-platform Homebrew channel — ships separate stable and keg-only beta Formulae for macOS and Linux across amd64 and arm64, with isolated update PRs.
Changed
- Personal event output contract (#651) —
event consumenow emits event-specific top-level structured fields; scripts that consumed the former transport envelope must use the flat fields or select-f raw, while--debug-raw-eventsretains the diagnostic envelope. - Guarded release lifecycle — beta/stable publication now uses explicit promotion, immutable delivery proofs, protected recovery, and tag-bound optional OSS policy; an unprovisioned OSS mirror is sealed as
deferredso GitHub, npm, and Homebrew are not blocked. - Relaxed stable promotion contract (#729) — a stable release still requires a delivered, non-withdrawn beta baseline in its commit history, but no longer requires a byte-identical tree with that beta; reviewed commits merged to
mainafter the beta can now ship in the stable release. Local releases now accept any sealed commit contained inmainhistory and push only the release tag, somainis never frozen during the beta-to-stable window.
Fixed
- Authentication and credential reliability — organization-policy denials stop before mutation or polling, long-running clients reload and refresh access tokens consistently, concurrent credential writes are atomic, and Windows portable-auth commands fail before reading or writing unsupported credential bundles.
- Command validation and compatibility — invalid Sheet/task targets fail locally, IM shortcuts preserve AI-tag and alias compatibility, and Aitable import uploads require and forward a positive file size.
- Release publication reliability — GitHub draft publication is bound to one verified release ID and exact assets, preflight uses isolated installer worktrees, guarded local tags remain compatible, cloud planning fingerprints the actual allocated release refs, and npm channel verification waits for bounded registry propagation without moving tags.
- Package-manager version verification (#735) — npm-vendored, Homebrew-installed, and packaged release binaries are now verified by searching their raw bytes for the injected version marker, so a correctly versioned stable binary is no longer rejected when the short version marker coalesces with adjacent printable linker metadata; incorrect or missing markers still fail closed.
[1.0.53-beta.7] - 2026-07-21
This beta validates bounded npm channel verification after registry publication.
Fixed
- npm dist-tag eventual consistency — Release delivery now tolerates a briefly stale
latestorbetaread after publishing by retrying only when npm reports a valid older version. Registry errors, invalid or incomparable tags, and channels that never converge still fail closed without moving any tag during verification.
[1.0.53-beta.6] - 2026-07-21
This beta validates guarded local release compatibility and tag-bound OSS deferral so an unprovisioned mirror cannot block the primary release channels.
Changed
- Tag-bound optional OSS release mirror — Official cloud Release runs no longer block GitHub, npm, and Homebrew delivery when an OSS bucket has not been provisioned. Cloud tags immutably record
OSS-Mirror: enabled|deferred; publication, repair, and withdrawal consume that sealed policy instead of the current repository variable. Enabled releases remain fail-closed, while deferred releases skip the nonexistent channel and cannot be backfilled without a future audited repair proof.
Fixed
- Guarded local release compatibility — The tag-push Release workflow now accepts the
Channel-only annotated tags created by the guarded local release entry while continuing to reject any partial cloud-only seal metadata. - Cloud release tag allocation fingerprint — Release planning now fingerprints the actual
v*andwithdrawn/v*refs fetched from GitHub, matching the seal job's API view instead of hashing an empty non-wildcard ref prefix and rejecting every publish before tag creation.
[1.0.53-beta.5] - 2026-07-21
This beta validates long-running access-token recovery and the faster, recoverable guarded release path introduced after v1.0.53-beta.4.
Changed
- Fast guarded beta and stable releases — successful local release checks now leave a six-hour proof bound to the exact version, commit, repository identity, remote
main, and stable baseline, so the subsequent guarded--publishinvocation revalidates authority without repeating tests and packaging. A default-branch governance smoke uses the same dedicated immutable-release credential as the tag workflow before any tag is allocated. - Protected existing-tag recovery —
dws-release recover <version>can resume a failed, unpublished annotated tag through the normal contract, build, Developer ID signing, immutable GitHub Release, Homebrew, npm, and OSS jobs. Recovery requires the exact tag object, peeled commit, failed tag-push run, typed version confirmation, and the protectedrelease-recoveryenvironment; successful runs are accepted as future beta/stable delivery evidence.
Fixed
- Long-running event authentication recovery — personal and portal event streams resolve the current access token for every ticket request, refresh a server-rejected token with compare-and-refresh semantics, and reconnect with backoff when refresh is temporarily blocked by network failures, rate limits, or 5xx responses.
- Consistent access-token caching and errors — runtime, recovery, Skill, PAT polling, and personal/portal event clients now resolve user access tokens through one expiry- and publication-aware manager, so long-running processes reload rotated credentials while keychain, refresh, parse, permission, and cancellation failures remain observable instead of being collapsed into “not authenticated.”
- Tag-push GitHub Release publication — Draft publication now locks one GitHub Release database ID, verifies its exact tag, channel, notes, recovery marker, asset set, and uploaded bytes, then publishes and rechecks that same ID as immutable. Recovery runs use the trusted default-branch release helpers instead of the sealed tag's historical scripts, fixing the Draft-only
GET /releases/tags/{tag}404 without allowing the release identity to drift during recovery. - Release preflight reliability — source-mode installer tests now use isolated temporary checkouts and HOME directories instead of overwriting and deleting the real repository
dwsbinary, release preflight explicitly rebuilds before policy checks, and the full-suite runner gives the growing script package a non-flaky five-minute per-suite budget.
[1.0.53-beta.4] - 2026-07-17
This beta validates the expanded personal IM event subscriptions and the flattened event consume structured output introduced after v1.0.53-beta.3.
Added
- Expanded personal IM event subscriptions (#651) — adds one-to-one and group events for message read receipts, recalls, and reactions; publishes the specified-sender receive event; and lets one-to-one/sender subscriptions target either a staff
--useror an--open-dingtalk-id. Event Schema now exposes these alternatives through machine-readable parameter constraints.
Changed
- Personal event structured output is now flat (#651) —
event consumeprojects NDJSON/JSON/pretty/compact output into event-specific top-level DTOs, so consumers read fields such ascontent,sender, andconversation_iddirectly instead of parsing.data | fromjson. This is a breaking change for scripts using the former transport envelope; the original server payload remains available through-f raw, while--debug-raw-eventspreserves the full diagnostic envelope.
[1.0.53-beta.3] - 2026-07-17
This beta validates multi-account profile support and the post-v1.0.53-beta.2 compatibility fixes for Windows portable authentication, IM shortcuts, and Aitable import uploads.
Added
- Multiple accounts in one DingTalk organization — profiles are keyed by
corpId:userId,--profileaccepts organization IDs/names plus user IDs/names, and organization-only selection uses its explicitly remembered current account or asks for an exact account when ambiguous.
Changed
- Profile-scoped logout and consistent token storage —
dws auth logout --profilecan remove one account or every account in an organization, while identity token slots remain the source of truth and legacy organization/global mirrors stay compatible without overwriting newer account credentials.
Fixed
- Windows portable-auth contract —
dws auth exportanddws auth importnow fail early without reading credentials, bundles, or writing files instead of claiming portable-bundle support for DPAPI-protected HKCU Registry credentials. - IM shortcut message tags and compatibility aliases (#646) — IM send shortcuts now add the same AI-sent marker as
chat message sendby default, support--ai-tag=falseto opt out, and preserve compatible search, conversation-ID, and page-size aliases. - Aitable import upload file-size validation (#654) —
dws aitable import uploadanddws aitable +import-uploadnow require a positive--file-sizeand always send it to the upload-preparation API, preventing invalid requests without the actual file size.
[1.0.53-beta.2] - 2026-07-16
This beta validates the accumulated post-v1.0.52 command surface, release automation, and runtime hardening changes, including enterprise contact onboarding, declarative shortcuts, Sheet/Aitable writes, multi-platform Homebrew formulas, and credential and target-validation fixes.
Added
- Contact enterprise onboarding commands — adds
contact org create,contact user invite, andcontact account createfor creating a DingTalk enterprise, inviting an employee by mobile, and provisioning an enterprise login account, with reviewed Schema contracts and mono/multi Skill routing. - Declarative shortcut commands (#592) — adds 366
dws <service> +<command>shortcuts across 16 services, including one-to-one MCP wrappers and multi-step smart workflows. Shortcuts publish stable Agent-visible contracts with named flags, validation and confirmation metadata, dry-run protection for writes, catalog/help routing, and optional local YAML extensions and usage recording. - Sheet imports and Aitable workflow writes (#624) — adds
dws sheet import/sheet import createfor converting local xlsx/xls files into new online sheets,sheet import getfor polling import tasks, anddws aitable workflow create/updatefor applying validatedworkflow-dsl/v1definitions, with matching reviewed Agent Schema and bundled Skill guidance. - Official multi-platform Homebrew channel — stable
Formula/dingtalk-workspace-cli.rband keg-onlyFormula/dingtalk-workspace-cli-beta.rblive in this repository and select signed macOS Intel/Apple Silicon or Linux amd64/arm64 artifacts at install time. Stable and beta releases open isolated Formula update PRs after final artifact signing, so beta never replaces the stable Formula. Agent Skills stay underpkgsharewithout mutating the user's home directory, and both tracks are covered by the six-channel post-release verifier.
Changed
- Guarded prerelease and stable automation — adds the guided
dws-releaseentry for one-command CHANGELOG preparation, validation-only and annotated-tag publication flows; promotes only an explicitly validated beta; verifies command-tree compatibility and all six packaged binaries; and serializes immutable GitHub Release, npm channel, OSS, Homebrew, and optional Gitee delivery with fail-closed recovery checks. - Reviewed historical release recovery proofs — release preflight can recognize an explicitly pinned successful recovery delivery for a historical stable tag while still rejecting arbitrary workflow dispatches, mismatched commits, and incomplete release, signing, or publication jobs.
Fixed
- PAT organization-policy denials stop immediately —
PAT_ORG_POLICY_DENIEDnow remains terminal even if a backend also returnsflowId, authorization URLs, or client credentials; the CLI does not mutate process credentials, open a browser, poll, or retry until an organization administrator changes the policy. - Sheet and task invalid-target failures —
sheet range read/getnow rejects a null cell-info response instead of printingnulland exiting successfully, while task completion and attachment listing verify that a task exists before calling lenient backend endpoints. Attachment listing is also published through Runtime Schema for schema-first Agent discovery. - Concurrent credential writes and reentrant CLI execution — secure-token writers now use isolated, exclusive temporary files before atomic replacement so concurrent processes cannot remove each other's in-flight data, and repeated in-process CLI runs close the previous file logger before replacing it instead of retaining the prior log-file handle.
[1.0.52] - 2026-07-14
This release seals the v1.0.52 line with personal event subscriptions, a deterministic 22-product Agent command catalog, local user-operation auditing, expanded Open product commands, safer macOS credentials and release signing, and more reliable Connect and IM delivery.
Added
- Personal event subscriptions (#589) — adds
dws event list/schema/consume/status/stopfor user @ mentions, selected one-to-one chats, and selected group chats.consumecan create or reuse a personal subscription, multiple local consumers share one bus while keeping outputs isolated by event type and subscription, and the mono/multi event Skills ship with the binary. - Open product command capabilities (#608) — adds Sheet table, pivot-table, and gridline commands; Chat message favorites; Drive statistics and shortcuts; and Doc comment update/delete, with matching mono/multi Skill documentation and command-contract coverage.
- Local user-operation audit log (#555) — operations executed through
dwsnow produce redacted daily JSONL records with actor, command and endpoint, result or error category, duration, CLI/platform metadata, and a SHA-256 previous-hash chain for tamper evidence. Writers coordinate through a cross-process file lock and rotate logs safely;dws audit tailinspects recent records,dws audit exportemits date-filtered JSONL or CSV, anddws audit verifyreports the first broken link in a file's hash chain. - Stable Agent command catalog (#598) —
dws schemanow ships a deterministic 22-product / 564-tool catalog generated from the executable Cobra tree, with progressive product/group/leaf queries, complete parameter contracts, reviewed command identity and aliases, safety/confirmation metadata, field provenance, and final-delivery completeness/drift gates. The catalog is embedded at build time and does not require runtime MCPtools/listdiscovery. - Reviewed Schema for local commands (#598, #609) —
event consume/list/schema/status/stopandaudit export/tail/verifyenter the reviewedCommandRegistry, bind to the real Cobra tree at generation time, and ship through the same typedToolSpecand embedded Catalog path as public MCP-backed commands. Leaf, group, product, and--allqueries are projections of that single delivered model. - Safe macOS Keychain → file-DEK migration (#597) —
dws auth migrate-keychain --to file-dekpreflights every legacy/profile auth entry before rewriting, ignores unrelated application secrets, supports side-effect-free--dry-run, requires explicit--yes, and lets sandboxed and normal processes share an existing login without exposing tokens.
Changed
event consumeAI-subprocess contract (#609) — emits a fixed ready line and a final controlled-exit summary, supports parent-pipe stdin EOF as graceful shutdown, forwards--profileto the detached bus, surfaces bus startup errors, and cleans up subscriptions according to ownership so orchestrators can drive event streams without sleeps or leaked server-side subscriptions.- Wukong IM read-result parity (#618) —
chat message listpreserves quoted merged-forward and image context; message-search entitlement failures retain the server-provided friendly hint and action URL; andding message listexposes each DING's content alongside its ID and status. - Developer ID signing for official macOS archives (#605) — official releases now require both Darwin archives to be signed with the configured Apple Developer ID certificate, timestamp, and hardened runtime. The release job validates credentials and signatures and fails closed instead of silently publishing ad-hoc-signed official binaries.
Fixed
- Smart-category mappings and runtime network diagnostics (#591) —
chat category create-smartnow maps category names, group-name keywords, and member OpenDingTalk IDs to the live MCP contract, rejects blank or empty supplied values locally, and reports runtimetools/callconnection failures as actionable API/network errors instead of internal discovery failures. - Connect daemon restart lifecycle (#599) — pins the Stream SDK reconnect-race fix, snapshots the running executable before detaching, uses a real 30-second keepalive, and manages each worker as its own Unix process group so launcher cleanup or worker panics no longer cause restart loops or orphan local-agent processes.
- Complex Connect messages and attachments (#606, #612) — rich-text messages retain all embedded pictures in order, queued turns keep every pending attachment, and unknown or future callback shapes reach each Agent backend with their message type and raw JSON instead of being discarded. Attachment recovery is locator-based, nested
chatRecordpictures/audio/video/files can be recovered from message APIs after Stream ACK, and OpenCode uses a full-duration storyboard for large videos to avoid base64 OOMs while preserving the original download for the turn. - macOS auth survives Keychain mode changes (#597) — credential reads try existing compatible DEKs without creating key material, updates preserve the DEK that decrypted existing ciphertext, unreadable slots fail closed before token exchange, profile slots use the canonical auth backend, and
auth statusreports ciphertext/key mismatches instead of treating them as ordinary logout. Dedicated macOS race and Windows DPAPI coverage protect the cross-platform paths.
[1.0.51] - 2026-07-10
This release promotes the sealed v1.0.51-beta.1 contents to stable. It syncs the hardcoded Wukong command surface, prevents dev connect conversations from blocking on messages received mid-turn, and makes local credential failures diagnosable without mutating key material.
Added
- Agoal product commands (#585) — adds
dws agoalstrategy, contract, scorecard, user-objective, report, and objective-template command groups, together with static routing and the bundled mono/multi Agoal skills. - Wukong chat command parity (#585) — adds
chat group notice create|edit|get|list,group share-invite,text translate,category create-smart, andmessage list-emotion-replies. - Wukong document import commands (#585) — adds
doc importfor starting imports anddoc import getfor querying import tasks. - Wukong mail command parity (#585) — adds mailbox profile, message batch-get, sent-message recall and recall-detail, auto-reply update, plus allow-list and block-list management.
- Wukong sheet grouping commands (#585) — adds
sheet group-dimensionandsheet ungroup-dimensionfor whole-row or whole-column ranges. - Keychain health diagnostics (#578) —
dws doctornow includes a keychain check, whiledws auth statusdistinguishes ordinary logged-out state fromkeychain_unavailableanddek_missingfailures and returns remediation hints in table and JSON output.
Changed
dws pat chmoddefaults to permanent grants (#584) — runningdws pat chmod <scope>without--grant-typenow requests apermanentgrant instead ofsession, aligning the direct CLI path with the recommend-authorization helper. Session grants remain available by passing--grant-type session --session-id <id>.- The
dev connect --channel geminipath now uses the GeminigenerateContentAPI (#587) — configure it withGEMINI_API_KEYorGOOGLE_API_KEY, optionally override the compatible endpoint withGEMINI_API_BASE_URLorGOOGLE_GEMINI_API_BASE_URL, and select a model with--agent-modelorGEMINI_MODEL; a localgeminiexecutable is no longer required.
Fixed
- Non-blocking
dev connectturn scheduling (#587) — stream and@-poll callbacks no longer wait for the active turn to finish. Turns stay serialized per conversation, messages received mid-turn are coalesced into one pending follow-up, and different conversations can continue in parallel. - Connect agent recovery and headless execution (#587) — stale addressable sessions retry once with a fresh session, unsupported Qoder control requests receive an immediate response instead of hanging, OpenCode and bypass-mode channels receive non-interactive permission settings, and backend/API failures are no longer posted as successful assistant replies.
- Side-effect-free credential reads (#578) — keychain reads inspect encrypted credential data before looking up the DEK and never generate a replacement key on a read path. Missing DEKs and unavailable macOS Keychains are surfaced as explicit diagnostic failures instead of silently mutating credential state.
[1.0.50] - 2026-07-08
This release fixes a long-standing gap where the global --jq / --fields output filters were silently ignored on product commands, lands a JSON-mode output path for the sheet batch-style command, and aligns the bundled skill surface with the real command semantics uncovered by the round-2 real-machine QA sweep.
Fixed
- Global
--jq/--fieldsare honored on product commands (#575) —Formatter.PrintJSON/PrintJSONUnescapednow route throughoutput.WriteFilteredwhen either flag is set, so product commands accept the same filters thatdws apihas always supported. The tool-caller adapter exposesFields()/JQ()so helpers can read the flags without re-parsing. skill setup --dry-runis a no-op preview (#575) — it now prints what would be written without touching the skill directory, the registry, or the agent config. Help text and docs are updated to match.- Skill docs alignment to the real command surface (#575) — per-product references and the cross-product intent guide clarify that
--fieldsprojects top-level / list keys only (use--jqfor nested paths);minutes_extract_todos.py,calendar_free_slot_finder.py,chat_export_messages.py/chat_history_with_user.py, andcontact_dept_members.pyare rewritten against the current response shapes;aisearch/aitable/attendance/calendar/chat/contact/dev/doc/doc-comment/doc-file-ops/doc-list/doc-search/drive/mail/minutes/oa/sheet/sheet-export/url-patterns/best_practices/lite-recipes.md/global-reference.md/intent-guide.mdare re-synced; the QA voice ("真机" phrasing) and environment-specific quirks stated as absolute rules are removed from the docs.
Changed
sheet range batch-set-styleemits per-row JSON in JSON mode (#575) — when--format jsonis set, each update is reported as{index, sheetId, range, ok, error}instead of only the final aggregate, so callers can programmatically track partial failures under--continue-on-error.- Command-merge helpers exported —
pkg/cmdutil.LeafMerge*and the provenance helpers are now public so downstream command trees can reuse the same merge semantics.
[1.0.49] - 2026-07-08
This release lands a full real-machine QA sweep across the CLI, helper scripts, and skill docs (#572), and hardens the release pipeline so npm publishing can no longer be blocked by Gitee mirror issues (#570).
Fixed
- Real-machine QA fixes across CLI commands (#572) —
aitable chart/dashboard share update --enablednow takes a string so--enabled falsedisables;chat conversation-info --userresolves openDingTalkId and registers--id/--conversation-id/--chataliases;chat list-all-conversations --limitis capped at 100 and rejects larger values; custom-robot webhook failures surfaceerrcodeinstead of masquerading as success;contactregisters--dept/--deptsas the primary flags so the documented spelling actually works;sheet media-uploadandsheet exportemit clean JSON under--format json(progress lines no longer leak);wiki node create --typeenum is corrected (drops unsupportedasheet, addsaxls/able/appt/adraw/amind);ding message list --typedefaults toALLsince the server rejects empty type. - Helper script fixes (mono and multi) (#572) — aitable import/export flag names and the tableId regex (7-char default tables were rejected); mail search
--limit, contact dept response keys (deptList/deptUserList) anduserInfonesting;attendance_my_recordwhoami compatibility;calendar_schedule_meetingevent-id unwrapping;drive_tree_listrecursion viafileId; report scripts migrated off the deprecatedreport list/report detail. - Skill docs sync (mono and multi) (#572) — command indexes, flag names, enums, return-structure keys and cross-product intent routing are re-aligned to real-machine behavior across all products. Genuinely server-side limitations (permission gates, org-level restrictions, unregistered tool keys) are annotated instead of code-patched, and the cross-cutting hazards (
successalways true,--jq/--fieldscurrently no-op) are documented.
Changed
- Release pipeline unblocks npm publish from Gitee mirror (#570) — the Release workflow now publishes to npm before touching the Gitee mirror, so Gitee upload issues cannot block
npm/latest. GitHub→Gitee attachment upload is disabled by default (unreliable from US runners) and only runs whenENABLE_GITEE_UPLOAD_FALLBACK=true; the legacy upload fallback path is guarded with timeout and retry so it fails fast when re-enabled. - Repair modes for release republish (#570) — the Release workflow gains a repair input and a standalone npm-only repair workflow, used to republish an existing release to npm without re-running the full pipeline.
[1.0.48] - 2026-07-07
This release promotes the sealed remove-discovery delivery from the beta line to the stable v1.0.48 package. It removes dynamic service discovery from the open-edition runtime, keeps legacy CLI compatibility aliases, syncs the open command/help/skill surface with the dws-wukong baseline, and includes the dev connect default-yolo behavior on the stable upgrade track.
Changed
- Remove-discovery delivery is now formal/stable — the beta validation line is ready to cut as
v1.0.48; normal stable channels (dws upgrade, GitHubreleases/latest, install scripts, and npmlatest) should receive this release after the official tag is published. - Static endpoint runtime sealed for stable delivery — the open edition no longer depends on dynamic service discovery at runtime, while preserving legacy command compatibility aliases and the synced help/skill surface from the beta.
contact labelis restored as real wukong-compatible functionality —dws contact label list/get/list-membersnow callget_org_labels,search_label_by_name, andget_label_members_by_labelId;contact roleremains an alias, and the common top-level compatibility entries (contact search/find/list/get/self/me/whoami/get-self) now dispatch to real user/dept/label tools where unambiguous.- Skill docs match the sealed command surface — contact docs again describe the real
contact labelthree-step role lookup flow; video-conference start/invite/share flows remain explicitly unsupported and point users to the DingTalk client.
Fixed
calendar event list --dry-runno longer executes the real list call — the sorted event-list wrapper now respects dry-run and prints thelist_calendar_eventspreview instead of calling the backend.chat file uploadis downlined — the hidden compatibility entry now returns a clear downline message and never callschat/upload_conversation_file_by_url; the supported file path remainschat message send --msg-type file --file-path.- Optional plugin version validation no longer pollutes every command — incompatible local plugins such as conference are skipped at debug level during command-tree construction instead of printing a WARN on unrelated commands.
- PR #45 review follow-ups are folded into the release — doc version rollback pagination now unwraps nested result/content/data envelopes for
nextCursor, mail helper scripts handle{result:{emailAccounts:[...]}}, and the generated attendance.xlsxfixture is removed from the skill scripts.
Tests
- Command-surface regression tests — root-command tests now cover real
contact label/roledry-runs, hidden top-level contact compatibility entries,chat file uploaddownline behavior, andcalendar event list --dry-run. - Release hygiene tests — skill markdown policy still blocks unsupported conference routes, plugin loader tests assert optional validation failures stay quiet at WARN level, and doc version cursor extraction has nested-envelope coverage.
[1.0.47] - 2026-07-05
This release adds connector supervision & health monitoring (dev connect list/status/restart/stop) and fixes bot-to-bot @-mention delivery end-to-end.
Added
dev connect list— PM2-style colored table enumerating all local connectors with state (healthy / degraded / down / not_running), PID, channel, and uptime.dev connect status— panel view with heartbeat, last recv timestamp, session webhook age, and--jsonfor external monitoring.dev connect restart— restarts a daemon via persisteddaemon-state.json(unified-app-id credential fetch, no local secret storage).dev connect stop— graceful SIGTERM shutdown releasing the single-instance lock and Stream connection.- Health watchdog — background goroutine writes
heartbeat.json;status/listderive state from heartbeat freshness + process liveness + pid-reuse detection. --alwaysonflag — opt-in auto-restart: supervisor relaunches the worker on crash (requires--daemon).--notify-staff-id— state-change notifications (start / stop / crash) sent as DingTalk messages to the specified staffId.--unified-app-idcredential flow fordev connect— fetches clientId/clientSecret at startup viadev app credentials get, keeping secrets off the command line and out ofdaemon-state.json.- API-sent file download (
feat(connect): download API-sent files via storage v2 API) — file messages sent viadws chat message send --msg-type file --dentry-id --space-idare now downloaded by the connector through the storage v2getDownloadInfoAPI (dentryId + spaceId → presigned URL → local temp file), so file-based Q&A works regardless of how the file was sent. --at-open-dingtalk-idsforchat message send-by-bot— @-mention bots or cross-org users by openDingTalkId in group messages.
Fixed
- Bot-to-bot @-mention send side —
atOpendingtalkIds(the server's lowercase spelling) is now used instead of the camelCaseatOpenDingTalkIdswhich was silently ignored. The unnecessaryopenDingTalkId → userIdreverse lookup (always failed for bots) is removed; the id is forwarded verbatim. - Bot-to-bot @-mention receive side —
interactiveCardmessages (how DingTalk delivers a bot @-mentioning another bot) are now parsed:extractInteractiveCardTextflattenscardContent[].children[].valueleaves and strips the leading @-mention by leaf boundary. Theemotion/replyreaction (which 500s on bot-sent cards) is skipped forinteractiveCardturns. - Markdown/richText body extraction —
extractCallbackTextgains acardContentfallback so structured-text messages are no longer silently dropped. - Send-by-bot @ chip rendering —
<@id>placeholders in the markdown body are rewritten to@idfor both userIds and openDingTalkIds so the mention chip renders in all cases. - Connector retry on transient network errors —
sendBySessionretries on transient failures instead of dropping the reply. - Orphan worker cleanup & watchdog deadlock — stale workers from a crashed supervisor are detected and cleaned; a channel-capacity fix prevents the watchdog from blocking.
- Idle connector false-down — heartbeat ticker now advances
updatedUnixso a connector with no inbound traffic is not marked degraded. - FD limit check —
checkFDLimitsplit into platform files for Windows cross-compilation. - Default agent timeout removed — no timeout by default (was incorrectly defaulting to a low value).
- keepAlive shortened to 30 µs — aligns with Stream SDK expectations; adds
ulimitcheck for multi-agent stability.
[1.0.46] - 2026-07-01
Fixed
- PAT agentCode grants no longer split from follow-up command checks (
internal/auth/agent_code_detect.go,internal/app/runner.go,internal/pat/chmod_test.go) — explicitDINGTALK_DWS_AGENTCODEdeclarations are now forwarded verbatim as the common cross-host contract, and unknown hosts no longer synthesizecustomintox-dingtalk-dws-agent-code/x-dws-agent-instance-id.pat chmod --agentCoderemains the highest-priority grant target and still wins over the env fallback.
[1.0.45] - 2026-06-29
This release adds multi-organization (profile) support (#500): dws can stay logged in to several DingTalk organizations at once and switch between them, while staying fully backward/forward compatible with the previous single-org token. A profile is one logged-in organization (corp); the current profile decides which org a command runs against. The release also hardens the new credential store for concurrency and corruption recovery, documents the capability in both the mono and multi skill sets, and flips --ai-tag on by default so messages sent through dws carry the DingTalk 「通过AI发送」 badge (#524).
Added
- Multi-organization login &
profilemanagement (internal/auth/profiles.go,internal/app/profile_command.go) —dws auth loginagainst a new organization adds a profile (the first login becomes the primary);dws profile listshows logged-in orgs with primary / current markers, status and validity;dws profile switch <name|corpId|->persistently switches the default org (-toggles back to the previous one, no-arg opens a TUI selector on a terminal);dws profile useis an alias ofswitch.dws auth status [--profile <name>]reports a specific profile. Credentials are stored per organization in keychain slots keyed by corpId (auth-token:<corpId>), with a plaintextprofiles.jsonregistry holding only metadata and the primary/current/previous pointers (no tokens). - Global
--profile <name|corpId>flag — run a single command against a specific organization without changing the default (one-shot; does not move currentProfile). Cross-org reads are orchestrated by the agent (list profiles → query each with--profile→ merge); there is intentionally no built-in--all-orgs. - Backward / forward compatibility with the legacy single token slot — a pre-existing single-slot token is migrated into
auth-token:<corpId>and marked primary on first multi-profile use; the current (or primary) profile's token is mirrored back into the legacy slot so older binaries and the embedded host keep working.profiles.jsonis additive and ignored by older versions. dingtalk-profileanddws-sharedskills + multi-org documentation (skills/) — a standalonedingtalk-profileskill plus a newdws-sharedskill that carries auth, global flags and the multi-org rule, so every multi-mode product skill's PREREQUISITE resolves and all read/search skills inherit cross-org behavior. The mono skill gains a "multi-org / profile" section, trigger conditions, a decision-tree entry and a corrected logout danger note. Multi-mode install now always shipsdws-sharedeven when--skill/--excludenarrows the set.
Changed
--ai-tagnow defaults on — DingTalk 「通过AI发送」 badge for dws-sent messages (internal/helpers/chat.go, #524) —chat message send/replyflip the--ai-tagdefault from false to true, attaching the AIclawTypeby default so messages sent throughdws(and by AI agents) transparently carry the 「通过AI发送」 badge; pass--ai-tag=falseto send as the user with no badge.- Concurrency-safe, self-healing
profiles.json(internal/auth/profiles.go,internal/auth/token.go) — every read-modify-write onprofiles.jsonand the legacy mirror is serialized under the existing dual-layer (process + cross-process) lock, split into public (locking) entry points and lock-free*Lockedvariants so the non-reentrant lock is never re-acquired (the refresh path and the load-path migration use the lock-free savers).profiles.jsonand the token marker are written via per-write random temp names + atomic rename so concurrent writers can no longer corrupt a fixed.tmp. An unparseableprofiles.jsonis quarantined (*.corrupt-*) and rebuilt empty so the CLI self-heals;auth reset/logoutproceed even when it cannot be read and sweep the quarantined files.
Fixed
- No silent fallback to a different org's token (
internal/auth/token.go) — when the resolved current/primary profile's keychain slot fails to read and no--profilewas given, the loader now only falls back to the legacy single slot if it belongs to the same organization; otherwise it surfaces the error instead of acting as a different org. - Legacy mirror no longer wiped on a transient keychain read error (
internal/auth/profiles.go) —SyncLegacyTokenMirrordistinguishes "token genuinely absent" from "keychain momentarily unreadable" and keeps the existing mirror in the latter case, so a host app's login state is not dropped by a transient failure.
[1.0.44] - 2026-06-28
This release hardens the dynamic-command surface and finishes the dws-wukong parity pass for structured input. Phantom override commands whose backing MCP tool isn't deployed are hidden from --help; report entry submit reads --contents-file / stdin natively; structured JSON flags accept @file / @-; and sheet range update / range read now accept the same plain shapes wukong does (scalar cells, flat values, null-clears-cell, a --hyperlinks flag). On the wukong01 sandbox this lifts the full open-edition cli_to_mcp pass rate from 77.6% to 95.5% (sheet 28.5% → 99.8%, report → 100%); the remaining failures are account / org / out-of-scope, not CLI defects.
Added
dingtalk-devskill: image-upload →mediaIdrecipe + per-resource command discovery (skills/multi/dingtalk-dev/references/) — documents how to obtain amediaIdfor app / robot icons via the DingTalk OpenAPI (credentials get→gettoken→/media/upload?type=image→--icon-media-id→ read back), since the dev command set has no upload command; and adds a "discovering commands" block to all 10 product refs pointing at each group's--helpanddws schema dev.app.<group>.<method>(dws schema dev.connectfor connect), so agents inspect commands instead of relying on memory.report entry submit --contents-file <path>/--contents -(stdin) read natively (#514,internal/compat/report_hooks.go) — the envelope publishesentry submit(MCPcreate_report) with a--contents(json_parse, required) flag plus a sibling--contents-filethat had no transform / mapsTo, so a--contents-file-only submit silently sentcontents: [null]and the report failed (only inline--contentsworked, which is whyreport createsucceeded whilereport entry submit --contents-filedid not). A build-time compat hook now resolves the file / stdin natively (10MB cap, UTF-8 check, wukong priority--contents-file>--contents -> inline) and relaxes the individualrequiredon--contentsinto acontents/contents-fileone-of group. No discovery-config change needed.@file/@-input for structured JSON flags (internal/compat/transform.go) —json_parse/json_parse_strictnow expand a leading@before parsing (@-reads stdin,@<path>reads a file), so long / complex payloads (many records, big 2D cell ranges, filter criteria) skip shell-quoting hell. A JSON / YAML value never starts with@, so the sentinel is unambiguous; the error hint that already advertised@path/to/file.jsonis now truthful.sheet's sharedsheetParseJSONFlagroutes throughcli.ResolveInputSourceso the same support reaches--values/--criteria/--sort-keys.sheet range update --hyperlinks(internal/helpers/sheet.go) — a wukong-shaped 2D hyperlink grid ([[{"type":"path","link":"...","text":"..."}]]) overlaid onto the cells grid as each cell'shyperlinkfield;--valuesor--hyperlinksis now required (at least one).
Changed
- Phantom override commands hidden from
--help(#515,internal/compat/dynamic_commands.go) — override leaves whose backing MCP tool isn't actually deployed used to render indws <svc> --helpand then fail at invocation with tool not found. A tool-existence guard now hides them, and command groups left empty by the hidden leaves are collapsed, so--helpreflects only invokable commands. Skill references are re-aligned to the real CLI surface (phantom commands dropped; role/duty "who is responsible" queries routed toaisearch, notcontact). sheet range updateaccepts scalar cells;sheet range readprojects a flatvalues;--values '[[null]]'clears a cell (internal/helpers/sheet.go,internal/helpers/sheet_cell_validation.go) — dws-wukong parity.range update(set_cell_range) auto-wraps a scalar cell (string / number / bool) into{type:text,text:"..."}instead of rejecting it, so the plain[["姓名","部门"]]shape thatsheet appendand wukong's update_range accept now works; a null cell clears content (matching wukong);{}still means keep-original.range read(get_cell_infos) now also exposes a flatvalues2D array next to the richcellspayload, matching wukong's get_range shape without dropping cell styles.- report skill aligned to
entry submit/inbox list/outbox list(skills/multi/dingtalk-report/,skills/mono/references/intent-guide.md) — the multi skill tree was two versions behind and still taught the deprecated flat aliases (report create/sent/list/detail/stats) and falsely claimedreport inboxwas unimplemented. Re-aligned to the canonical resource.verb commands consistently (old aliases still execute with a stderr deprecation notice).
[1.0.43] - 2026-06-26
This release aligns the open edition's CLI surface with dws-wukong across the communication domain (chat / mail / minutes / todo / calendar / contact / aisearch / live / report / ding) and the structured-office domain (aitable / sheet / drive / wiki / doc), and switches the discovery version code from bamboo to cedar so the aligned command tree is served from its own discovery config.
Added
calendar book get|searchandcalendar acl list(cedar discovery overrides) — query a specific calendar (primary via--id primary), fuzzy-search calendars by name, and list a calendar's access-control entries. Maps to the calendar MCPget_calendar/search_calendar/list_aclstools.calendar attendee list|add|delete(internal/helpers/calendar_commands.go) — manage event participants under the wukong-alignedattendeenaming (equivalent to the legacyparticipantgroup; callsget/add/remove_calendar_participant).minutes tag listandminutes tag query --tag-id— list a user's AI-minutes tags and query minutes by tag (query_user_tag_list/query_minutes_by_tag_id).minutes list mine|shared|all(internal/helpers/minutes_commands.go) — list own / shared / all minutes with renamed output fields.mail folder create|update|delete,mail template create|list|get|update|delete,mail contact create|list|update|batch-delete, andmail message list— full mail folder / message-template / contact CRUD plus folder-scoped message listing.chat file upload(internal/helpers/chat_file.go) — upload a local file (init/PUT/commit) or a remote URL to a conversation's file space.todo task add-attachment(internal/helpers/todo_commands.go) — attach a local file to a todo (multi-step upload).- aitable extensions (
internal/helpers/aitable_extra.go) — advanced permission / roles, view sub-commands (lock / duplicate / frozen-cols / row-height / fill-color-rule / card / timebar), section node management, workflow enable/disable, recordupsert/share-url/history-list/ primary-doc, and field search-options. Helper tools route to the hardcodedaitable-helpersupplement endpoint. - sheet, drive, wiki, doc helper coverage synced from dws-wukong (
internal/helpers/sheet.go,drive.go,wiki.go,doc.go).
Changed
- Discovery version code
bamboo→cedar(internal/market/registry.go;discoveryAPIPath = "/cli/discovery/apis/cedar") — version codes step by first letter (bamboo → cedar → …);cedarcarries the dws-wukong alignment. Older binaries keep readingbamboo, so the change is isolated to this release line. All test/mock/generator fixtures updated to the cedar path. - CLI output envelope aligned with wukong for cross-edition parity (
internal/app/runner.go,internal/compat/registry.go) — dry-run prints aDRY-RUN Arguments:line, successful results carrysuccess: true, missing-required-flag wording is unified tomissing required flag(s): --x, and OutputTransform applies to the response content layer. - New flag transforms (
internal/compat/transform.go) —parse_bool(explicit boolean strings so--flag falseis honoured) andattendance_class_check_time(HH:mm→ UTC+8 milliseconds for shift check-times). --calendar-idaccepted on calendar event / participant / room / attachment commands so calendars other than the primary can be targeted.
Fixed
- Client-side validation for calendar recurrence completeness and attendance schedule / class / group inputs, surfacing input errors before they reach the server.
[1.0.42] - 2026-06-25
This release rounds out dws dev connect — bridge a DingTalk robot to your local AI (Claude Code / Codex / opencode / Qoder / …): a generic custom channel for any headless CLI tool, in-chat /new / /clear session commands aligned to each agent's real session op, and a fix for long opencode turns being cut at 30 seconds.
Added
dws devapp robot connect— genericcustomchannel for self-built / unsupported AI tools (issue #37;internal/helpers/devapp_connect.go,internal/helpers/connect_stream.go) — a new--agent-cmd "<command>"flag (andcustomchannel) lets the bot forward to any headless AI CLI that takes a question as its trailing argument and prints the answer to stdout, so tools that aren't built-in (e.g. 网易有道龙虾 LobsterAI) or self-built agents can be onboarded without code changes.--agent-cmdforces thecustomchannel unless--channelis set explicitly; detection also falls back tocustomwhenDWS_AGENT_CMDis present.
Changed
-
robot connectnow hints how to match terminal answer quality (issue #39;internal/helpers/devapp_connect.go) — when neither a work dir nor a knowledge source is configured, the connector prints a one-time note that the bot runs in a clean temp dir without local project context, pointing at--agent-workdir/--knowledge-dir/--knowledge-source/--agent-model. The robot quickstart gains matching FAQ entries, plus a clarification that step 3 (robot connect) produces no approval ticket (issue #19). -
robot connectsession commands/newvs/clearnow use each channel's real session op (PR #20;internal/helpers/connect_opencode.go,internal/helpers/connect_stream.go) —/new(and/start,/reset) opens a fresh session and leaves the previous one intact (resumable where the agent supports it);/clearactively disposes the current session through the agent's real delete primitive — opencode issuesDELETE /session/:id. Channels whose agent exposes no delete in the mode DWS drives it (Codex app-server, Qoder stream, Claude-family exec) fall back to a reset, so/clearbehaves like/newthere. Previously both commands only dropped the localconversationId → sessionIdmapping, so the two were indistinguishable and opencode sessions were never disposed (they leaked).
Fixed
robot connectno longer aborts long opencode turns at 30 seconds (PR #19;internal/helpers/connect_opencode.go) — the shared opencode HTTP client hard-coded a 30sTimeoutthat covered every request, includingPOST /session/{id}/message, so a long agent turn (e.g. a multi-minute research report) was killed mid-flight withcontext deadline exceeded (Client.Timeout exceeded while awaiting headers)even though the per-turn budget (DWS_AGENT_TIMEOUT_MS, default 300s) was far larger. The client-level deadline is removed so the per-request ctx governs the round-trip; only the/global/healthprobe keeps a short 10s timeout so startup detection stays snappy.
[1.0.41] - 2026-06-24
This release makes the installers work from mainland China out of the box (no env var) and keeps the Gitee mirror in sync automatically.
Added
- Auto-fallback to the Gitee mirror when GitHub is unreachable (#492;
scripts/install.sh,scripts/install.ps1,scripts/install-skills.sh) — the installers probe GitHub Releases on startup and, when it is unreachable (typical in mainland China), automatically resolve the version and download every asset (binary,checksums.txt,dws-skills.zip) from the Gitee mirror instead. A plaincurl … | shnow works in China with noDWS_GITEE_REPOneeded. ExplicitDWS_GITEE_REPOstill wins,DWS_NO_FALLBACK=1forces GitHub, and local source-checkout installs skip the probe.
Changed
- CI mirrors repo code to Gitee automatically (#493;
.github/workflows/mirror-to-gitee.yml) — the mirror workflow now pushesmain+ tags to the Gitee mirror over HTTPS usingGITEE_TOKEN(no SSH key), on every push tomainand every tag, keeping the Giteeraw/maininstall scripts and tags in sync without any manualgit push. Gated onGITEE_TOKEN; skips cleanly when unset.
[1.0.40] - 2026-06-24
This release adds China-accessible install mirrors so the CLI installs reliably from mainland China, where GitHub raw + Releases are slow or fail.
Added
- China mirror via Gitee + npmmirror (#486;
scripts/install.sh,scripts/install.ps1,scripts/install-skills.sh,scripts/release/sync-to-gitee.sh,.github/workflows/release.yml,.github/workflows/mirror-to-gitee.yml) — an opt-inDWS_GITEE_REPOenv var makes all three installers resolve the latest version and every release asset (binary,checksums.txt,dws-skills.zip) from the Gitee OpenAPI v5 instead of GitHub; with it unset, installation defaults to GitHub (fully backward compatible). The release pipeline mirrors release attachments to the matching Gitee release after each tag (gated onGITEE_TOKEN/GITEE_REPO), and a hub-mirror workflow keeps the repo code in sync (gated onGITEE_PRIVATE_KEY). README documents three China install channels: Gitee raw script, Gitee release binaries, and the npm package viaregistry.npmmirror.com. - Skills embedded in the binary (#488;
skills_embed.go,internal/app/skill_setup.go,internal/app/skill_setup_embed.go) — theskills/tree (mono + multi) is embedded into thedwsbinary viago:embedanddws skill setupdefaults to the embedded copy, refreshing the installed skill instead of silently reusing a stale copy probed from the current working directory — so skills install offline with no separate download.
[1.0.39] - 2026-06-18
This release makes the AI-sent indicator opt-in. 1.0.38 unconditionally tagged every user-identity send/reply with the edition claw identity, so the IM server rendered a "Send from AI" badge under every message — and on the open edition a stale hardcoded value even leaked the Wukong-branded label (「悟空AI发送」) to external users. The badge is now off by default and shown only when the caller explicitly asks for it.
Added
--ai-tagopt-in flag forchat message send/chat message reply(#477;internal/helpers/chat.go) — by default noclawTypetool argument is attached, so delivered messages carry no "Send from AI" badge. Passing--ai-tagattachesedition.ClawType()so the IM server renders the badge (open editionopenClaw→ 「通过AI发送」; the wukong overlay sets its own value → 「悟空AI发送」). Covers the text/Markdown, rich-media, and--user/--open-dingtalk-iddirect send paths plusreply. Bot (send-by-bot) and webhook sends are intentionally untouched — they already render as bot messages. The badge is opt-in so dws does not brand every message a user sends.
Fixed
dws chat message replyno longer leaks the Wukong AI label on the open edition (#475, fixes #474;internal/helpers/chat.go,pkg/edition/edition.go) — the reply path hardcodedclawType: "wukong", so open-source quoted replies were tagged 「悟空AI发送」 by the IM server, leaking Wukong branding to external users (reported by an external customer integrating via openclaw). The value now derives from the edition via the newedition.ClawType()accessor (open →DefaultOSSClawType=openClaw), and — together with #477 — is only attached when--ai-tagis passed. The earlier fix existed on a branch (PR #450) but was never merged to main; #475 cherry-picked it.
[1.0.38] - 2026-06-16
This release adds client-side agent attribution for usage stats, fixes two commands that silently misbehaved (dws sheet export hanging, dws upgrade --dry-run actually upgrading), hardens the document write path against server-rejected characters, and makes the long-broken --no-browser login flag actually work.
Added
- Client-side
agent_codedetection + per-channel agent instance id for usage stats (#467;internal/auth/agent_code_detect.go,internal/auth/identity.go,docs/agent-code.md) — every MCP request now carriesx-dingtalk-dws-agent-code(which agent host is driving dws — e.g.claudecode/codex/qoder/cursor/hermes/openclaw, falling back tocustom),x-dws-agent-instance-id(a per-machine×channel id,dwsa_<base62(sha256(machineId|agent_code))>), the existing machine-levelx-dws-agent-id, andX-Cli-Version. Detection is a confidence ladder, each signature verified on real hosts / official docs (never guessed; anything unrecognized resolves tocustom): T0 explicitDINGTALK_DWS_AGENTCODE, T1 per-agent env signatures, T2VSCODE_BRANDcovering the whole VS Code fork family, T3 the macOS__CFBundleIdentifiermap, T4custom.identity.jsonmigrates v1 → v2 transparently and keepsx-dws-agent-idmachine-level for continuity. Trust boundary:agent_codeand both ids are client self-reported and forgeable — they are for stats / observability only and must not be used for auth, authorization, rate-limiting, billing, or revocation. Server-side gateway work (header passthrough allowlist + logging the fields into the warehouse) is required before the data lands and is tracked separately.
Fixed
dws sheet exportno longer hangs for the full ~5-minute poll timeout (#462;internal/compat/pipeline.go) — the pipeline poll loop compared the API status againstpollUntilValuewith case-sensitive==, but the API returns"success"while the pipeline config declares"SUCCESS", so the match never fired and the loop spun until timeout. Switched tostrings.EqualFold, aligning with the case-insensitivenormalizeAsyncStatushelper already used fordoc export/aitable export.dws upgrade --dry-runnow previews instead of performing a real upgrade (#416, fixes #364;internal/app/upgrade.go) —newUpgradeCommandregistered no--dry-runflag and never read the global persistent one, so--dry-runfell through and ran a real, irreversible upgrade (download + binary replace), directly contradicting the flag's documented预览操作内容,不实际执行contract. It now resolves the target release and platform asset (so "already latest" / "no build for this platform" is still surfaced), prints the 1–5 steps it would perform via the side-effect-freewriteDryRunPlan, and returns before any backup / download / replace. Covered byTestWriteDryRunPlan_*and an updated help test.dws doc create/dws doc updatestrip server-rejected characters instead of failing (#465;internal/helpers/doc.go,internal/helpers/doc_jsonml.go) — the Markdown write path sent raw content straight through, and the dangerous-Unicode strip only ran on the JSONML branch, so content carrying C0 control characters (anything< 0x20except\t/\n), DEL (0x7F), or zero-width / line-separator codepoints (U+200D,U+2028,U+2029) — common in LLM-generated or copy-pasted text — was rejected by the server-sideRejectControlCharsvalidator and the command failed.stripDocDangerousUnicodeis renamed tostripDocInputUnsafe, extended to match the authoritativeapiclient.rejectDangerousCharsset, and applied on both the Markdown and JSONML node write paths. Tab and newline are preserved. Ported from dws-wukong.dws auth login --no-browseris now honored (#365;internal/app/auth_command.go,internal/auth/device_flow.go,internal/auth/oauth_provider.go) — the flag was already defined (and hidden) but never wired to the login providers, so the browser always opened regardless. The value is now passed intoDeviceFlowProvider.NoBrowser/OAuthProvider.NoBrowserand gates theopenBrowsercall; the flag is also unhidden so headless / remote sessions can discover it.
[1.0.37] - 2026-06-11
This release realigns the npm channel and hardens PAT batch grants. Background on the npm realignment: 1.0.36 was re-cut on GitHub on 2026-06-11 to fold in the canonical-tree poisoned-cache guard (#454), but the npm registry permanently forbids republishing a version number, so the npm package stayed on the original, unguarded cut. 1.0.37 is therefore the first version where every distribution channel — GitHub releases, dws upgrade, the install scripts, and npm — ships the same guarded build. If you installed 1.0.36 from npm, upgrade to this version.
Fixed
- PAT batch grants carry the agent identity and require explicit confirmation (#455;
internal/pat/chmod.go,internal/auth/channel.go,internal/app/runner.go) — an explicit--agentCodeflag or theDINGTALK_DWS_AGENTCODEenv var is now carried into PAT batch plan/grant arguments instead of being dropped, and a missing agentCode is forwarded as absent so the PAT core can apply the server-side default rather than failing. Batch grants now refuse to execute without an explicit--yes(dry-run and single-scope grants keep their existing behavior), closing the gap where a multi-scope grant could fire without a deliberate confirmation. Only the canonical env nameDINGTALK_DWS_AGENTCODEis recognized; draft/reversed spellings from earlier iterations are ignored. Verified against prepub: dry-run, single grant, flag-priority grant, and batch grant all resolve the target agentCode, with the granted rows confirmed server-side. Tests:internal/pat/chmod_test.go,internal/pat/browser_policy_test.go,test/unit/pat_host_owned_signal_test.go.
[1.0.36] - 2026-06-10
This release closes out the poisoned-discovery-cache lock-out for good, with four layers of defense landing together. The lock-out class (seen again on 2026-06-09 as chat_permission_grant flag redefined: params): the dynamic command tree is built from cached discovery data before Cobra dispatches any command, so a pflag panic fed by a poisoned cache aborted every invocation — including dws cache refresh and dws upgrade, the very commands that could repair it. Now: (1) any panic during the build is recovered instead of crashing (#447), (2) the four known envelope shapes that made pflag panic are skipped at registration so they never fire (#449), (3) when an unknown panic class does fire, the CLI quarantines the poisoned cache and rebuilds itself from a fresh fetch — and dws upgrade clears the discovery caches after every binary swap, so simply getting this version onto a machine is enough to escape, no manual cache surgery (#452), and (4) the same guards now also cover the canonical dws mcp tree, which is built even earlier and sat outside all three defenses as originally cut (#454 — this release was re-cut on 2026-06-11 to include it; verified against the preserved real poisoned cache from the 2026-05-25 incident). Also in this release: dws devdoc gains RAG-backed Open Platform doc search and a new error-diagnosis command (#434), and dws doc create stops producing documents with two identical titles (#448).
Escaping a locked-out older binary: a binary ≤1.0.35 bricked by a poisoned cache cannot run dws upgrade. Either bypass the cache for one invocation with DWS_CACHE_DIR=$(mktemp -d) dws upgrade, or delete ~/.dws/cache/<partition>/tools/ by hand, or reinstall via the install script. Once 1.0.36 is on the machine this never needs doing again.
Added
dws devdoc— RAG-backed Open Platform doc search and error diagnosis (#434;internal/helpers/devdoc.go,internal/transport/client.go) —dws devdoc article searchnow routes to the upstreamsearch_open_platform_docs_ragtool, returning structured RAG/reference payloads (the CLI stays a thin invoker; no extra AI analysis layer). Newdws devdoc error diagnose(aliastroubleshoot) routes tosearch_open_error_code_ragfor diagnosing DingTalk Open Platform API errors, with--request-id(hidden--trace-idkept for compatibility),--error-code,--error-message,--api,--context,--query,--page,--size. Transport-side: query parameters required by DingTalk MCP gateway URLs are preserved on the wire but their values are redacted from debug logs. Default MCP / skill hosts stay on productionhttps://mcp.dingtalk.com(prepub remains runtime-configurable). Skill docs (mono + multidingtalk-devdoc) anddocs/command-index.mdupdated alongside.
Fixed
- CLI no longer bricks when the dynamic command build panics — degrades to built-in commands (#447;
internal/app/legacy.go) —buildEnvelopeCommandsSafewraps the envelope-driven build in a localrecover(). On panic the CLI logs it, prints a stderr hint, and falls back to the hardcoded helper commands, soauth/cache/doctor/version/upgradeand the helpers stay alive anddws cache refreshcan rebuild the poisoned cache. Before this, the only recovery from the pre-1.0.32 lock-out class was manually deleting cache files; the duplicate-flag class itself had been fixed at the builder level, but any future panic class in the cache-driven build would have bricked the CLI again. Tests:TestNewLegacyPublicCommandsPanicFallsBackToHelpers,TestNewLegacyPublicCommandsNoPanicKeepsDynamicPath. - Envelope-driven flag registration no longer panics on the four known malformed-envelope shapes (#449;
internal/compat/registry.go) — while reproducing the lock-out byte-for-byte, four envelope shapes were found still forwarded to pflag calls that panic, each bricking every invocation: a flag namedparams/jsoncolliding with the reserved payload flags (the originalflag redefined: params— earlier dedup fixes covered the alias list and Detail-schema path but not the primary name); two bindings resolving to the same long flag name across bindings; two flags claiming the same shorthand; and a multi-character shorthand. Two small guards applied at every registration site (ApplyBindings,registerPositionalAliasFlags):canRegisterFlagskips duplicate/reserved long names (the value stays reachable via--params), andsafeShorthanddrops an invalid or already-taken shorthand while keeping the long flag. The trailing--json/--paramsregistration is now idempotent. Defense in depth with #447: the escape hatch should never trigger for these known vectors. Test:TestBuildDynamicCommandsSurvivesMalformedFlagEnvelope(5 table-driven vectors). - Poisoned discovery cache now self-heals: quarantine + rebuild on panic, and
dws upgradeclears discovery caches (#452;internal/app/legacy.go,internal/app/upgrade.go,internal/cache/store.go) — #447's recovery is upgraded from "degrade and ask the user to rundws cache refresh" to a two-stage self-heal: on the first build panic the partition's discovery cache is moved aside to<partition>.quarantined(kept on disk for inspection; a previous quarantine is replaced so nothing accumulates — newStore.QuarantinePartition) and the build retried once against a fresh fetch. If the retry succeeds the user gets the full dynamic command tree with zero manual steps; only a second panic (remote envelope itself still poisoned, or offline) degrades to helper commands with thecache refreshhint. Additionallydws upgradepurges discovery-derived caches (market/tools/detailacross all partitions — newStore.PurgeDiscoveryData) after a successful binary swap, leaving the co-locateddownloads/cache untouched, so an upgraded binary always rebuilds its command tree from fresh data instead of inheriting snapshots written by the old version. Tests:internal/cache/store_quarantine_test.go, rewritteninternal/app/legacy_panic_fallback_test.go(self-heal success, double-panic degradation, no-cache no-op, happy path). - Canonical
dws mcptree no longer escapes the poisoned-cache guards (#454;internal/cli/canonical.go,internal/app/root.go) — the canonical tree is assembled from cached catalog data before the legacy command build, so a pflag panic there — a tool schema property named after the reserved--paramsflag, exactly what the 2026-05-25 incident cache contained — bypassed #447/#449/#452 entirely and still bricked every invocation, including on this release as originally cut. Two layers, mirroring the existing guards:applyFlagSpecsskips reserved (--json/--params), duplicate, and alias-colliding flag names and sanitizes shorthands (canRegisterToolFlag/safeToolShorthand; a skipped property stays reachable through the reserved JSON payload flags), andnewMCPCommandwraps the build in the #452 recover → quarantine → retry-once → degrade-to-stub sequence. Verified against the preserved real poisoned cache: the original cut locks out on--version/cache refresh/doctor; this build self-heals on first run andcache refreshclears the poison. Tests:internal/cli/canonical_flag_guard_test.go(4 cases),internal/app/canonical_panic_fallback_test.go(4 cases mirroring the legacy fallback suite). dws doc createno longer produces a document with two identical headings (#448;internal/helpers/doc.go) — the platform renders the document name as the page title, and LLM agents habitually repeat# <title>as the markdown body's first line despite the skill docs saying not to, so duplicate-heading documents kept appearing. Thedoc createhelper (which wins the envelope merge viapreferLegacyLeaf) now strips a leading ATX H1 whose text exactly equals--name(trimmed, case-insensitive) before forwarding tocreate_document, printing a stderr note so agents learn the convention. Deliberately conservative: only an exact match is removed (# 背景stays), ATX closing hashes are handled without over-trimming names ending in#(e.g.C#), H2+/setext headings are never touched, and a body that is nothing but the duplicate H1 omits themarkdownparam instead of sending an empty string. JSONML bodies are out of scope. Tests:TestStripLeadingDuplicateTitleHeading(9 cases) plus three end-to-end cobra tests asserting the exactmarkdownparam sent.
[1.0.35] - 2026-06-08
Fixed
chat message send@-mentions not rendered in group / direct chat (#433,internal/helpers/chat.go) — when sending a group message or an openDingTalkId direct message (send_personal_message) as the current user, thecontentbody was packed withjson.Marshal, whose default HTML escaping turns the<>in<@openDingTalkId>/<@all>into<>. The DingTalk client renders @-mentions by matching the literal<@...>token, so after escaping the match fails and the mention shows as plain text — while the API still returnssuccess, masking the bug. Fix: addmarshalMessageContent, which serializes{title,text}withjson.Encoder+SetEscapeHTML(false); both the group and openDingTalkId-directsend_personal_messagepaths now use it, preserving the literal<@...>. Added regression testTestChatMessageSendContentNotHTMLEscapedasserting the content keeps the literal token and is never HTML-escaped. Verified on a real device:@someoneand@allboth render as clickable blue mentions.chatskill docs & scripts aligned to direct-chatlist-direct(#424) —chat message listnow supports group chats only (--user/--open-dingtalk-idremoved); reading a direct chat moves to the dedicatedlist-directcommand, but the skill docs and scripts still taughtchat message list --user, which now errors withunknown flag: --user, also breakingchat_history_with_user.py(listed as the "preferred" way to query direct chats). This update:skills/{mono,multi/dingtalk-chat}/references/products/chat.mdswitchesmessage listto group-only and documents the newlist-directcommand, syncing the intent routing / key-distinction / context-passing tables / caveats;skills/mono/references/best_practices/01-messaging.mdchanges query-private-chat fromlist --usertolist-direct(the multi version was already updated);chat_history_with_user.py(mono + multi) now callslist-directand fixes response parsing (unwrapsresult.messages, alignscreateTime/content/senderfields — it previously crashed on'str' object has no attribute 'get'). Direct-chat sending still useschat message send --user(since v1.0.34 the direct-send rpc is folded into thesendcommand; there is no separatesend-direct). Docs/scripts only; no change to CLI binary behavior.pat chmodbatch authorization did not pass throughagentCode(#414,internal/pat/chmod.go) — the batch plan / grant paths (buildBatchPlanArgs/batchArgs) previously carriedagentCodeonly in the single-granttoolArgs; batch calls omitted it, so a batch authorization with an explicitagentCodewas processed under the default agent. Fix: the batch plan / grant args now also carryagentCode, matching the single-grant path.patJSON output escaped the authorization URL into an unreadable form (#401,internal/pat) — the authorization URL attached to PAT error messages, after default HTML escaping, turned&into&, breaking the link when copied / recognized on mobile. Fix: the PAT error-enrichment JSON output now usesSetEscapeHTML(false)(scoped to PAT JSON only), preserving the readable&separators.
[1.0.34] - 2026-06-03
Changed
- Service discovery path now carries a version-coded segment (
internal/market/registry.go) — the server-list endpoint moves from/cli/discovery/apisto/cli/discovery/apis/bamboo. The path is now a singlediscoveryAPIPathconstant so future version bumps touch one place. Only the path changes; the MCP base host stays on productionhttps://mcp.dingtalk.comand the auth / skill / doctor endpoints are untouched. Discovery via the editionDiscoveryURLhook (full-URLFetchServersFromURL) is unaffected. Server side must serve the new path.
Removed
dws aiapp— AI application product taken offline — removed theaiappproduct surface (create/query/modify) from the CLI: deletedinternal/helpers/aiapp.go, dropped it from the generator coverage targets andknownRegistryProducts, removed theaiappskill references (monoreferences/products/aiapp.md+dingtalk-aiappmulti skill), and unpublished theaiappserver from the service-discovery envelope. Product count drops from 19 to 18.
[1.0.33] - 2026-06-02
This release merges the multi-contributor pre-mcp-discovery feature branch into main as a single squash (#391), bringing a large batch of new product surface — full DingTalk docs (doc), knowledge base (wiki), AI app (aiapp), AI-table forms + import/export, and reworked mail / todo / report command trees — while keeping service discovery pinned to production https://mcp.dingtalk.com (the branch's pre-mcp.dingtalk.com endpoint change was deliberately excluded; the four host constants in skill_command.go / auth/endpoints.go / cli/loader.go / market/registry.go stay on prod). It also folds in the portable auth bundle (dws auth export / import, #357) and PAT batch authorization (#389).
Added
dws doc— full DingTalk document command family (#387, #362, #388, #390;internal/helpers/doc.go,internal/helpers/doc_jsonml.go,internal/helpers/docjsonml/) — search / list / info / read / create / update / upload / download / copy / move / rename, plusfile,folder,block-level editing andcomment(list / create / reply / create-inline). Authoring supports both DocxXML and a JSONML format with a v2 schema validator (docjsonml/jsonml-schema-v2.json+doc_jsonml_validate_v2.go). Document export and OA alignment land here.dws wiki— knowledge base management (internal/helpers/wiki.go,internal/helpers/wiki_proxy.go) — knowledge spacecreate/get/list/searchand memberadd/list/update, routed through a wiki proxy server.dws aiapp— AI application lifecycle (internal/helpers/aiapp.go) —create(with prompt / attachments / skills),queryby task ID,modifyby thread ID.dws aitableforms + import/export (internal/helpers/aitable_form.go,internal/helpers/aitable_export_import.go) — datasheet form management and full record import/export, the latter driven through the async-task helper for large datasets.- Reworked
chat/report/todo/contact/mailcommand trees aligned to the Wukong baseline (#355;internal/compat/mail_hooks.go,internal/compat/todo_hooks.go,internal/helpers/report_readable.go) — mail and todo gain dedicated compat hooks;reportgains a human-readable rendering path alongside the raw JSON, plus deprecation shims for the old report shape. dws auth export/dws auth import(#357) — portable auth bundle for migrating Linux sandbox credentials. Exports the encrypted keychain (~/.local/share/dws-cli, includingauth-token.encanddek) plus required~/.dwsconfig so refresh tokens survive import; copying onlyapp.jsonleaves access tokens expiring after ~2 hours. Supports-o/-itar.gz paths and--base64for copy/paste between sandboxes.dws auth statusnow shows refresh-token validity in table output.- Async-task and paging infrastructure (
pkg/asynctask/,pkg/paging/) — shared helpers underpinning long-running operations (e.g. aitable import/export, doc export) and cursor/page traversal.
Changed
envelopenow registerscli.Aliasesas cobra aliases (#391) — discovery-generated commands expose their declared aliases natively in the command tree, with accompanying command-structure and JSON-parsing cleanups.- Breaking:
dws pat chmodprints a compact authorization summary by default, and gains batch authorization flows (#389;internal/pat/chmod.go) — scripts that parse the raw MCP JSON from stdout must now pass--format jsonor--verboseto keep the machine-readable payload; the default summary keeps grant status, agentCode, grantType, scope counts, and a next-action hint. New batch grant/plan flows (pat.batch_grant/pat.batch_plan) authorize multiple products in one session, fall back to the legacy single-grant path when the server reportsPAT_BATCH_AUTH_UNSUPPORTED, use the server's defaultagentCodewhen none is given, and surface per-tool authorization metadata for grant planning. - Skill packs synced to the Wukong-aligned content across attendance / calendar / minutes / oa / sheet and others (#391).
[1.0.32] - 2026-05-25
Two user-visible regressions resolved plus two AI-agent discoverability fixes. dws drive upload was returning HTTP 403 SignatureDoesNotMatch for any file whose MIME detects to a non-empty value — basically every real file — because the helper added a client-side Content-Type fallback whenever drive.get_upload_info returned an empty headers map. DingTalk drive's OSS presigned PUT URLs are signed against an empty Content-Type at signing time, so any client-supplied header makes the signature OSS recomputes diverge from the server-signed one, and the PUT is rejected (#347). On Apple Silicon, dws upgrade was aborting at the "解压并验证" step with signal: killed because GoReleaser cross-compiles darwin/arm64 binaries on ubuntu-latest with no codesign step, and macOS 11+ amfid SIGKILLs unsigned arm64 binaries on first exec (#339) — the release pipeline now ad-hoc signs every darwin tarball, and the upgrade client self-heals if it ever encounters an unsigned binary again. On the AI-agent discoverability side, dws aitable attachment upload-file (the one-shot prepare + PUT + commit composite) is no longer hidden from --help — agents that only browse the command tree were getting stuck at the prepare-only attachment upload step, which returns an upload URL + fileToken but doesn't actually upload. And dws --help itself now surfaces the missing-command upgrade hint that the custom renderRootHelp had been silently dropping from cobra's root.Long.
Added
dws aitable attachment upload-fileis now visible indws aitable attachment --help(#347,internal/helpers/aitable.go) — the hardcoded one-shot composite (prepare + HTTP PUT + commit, returnsfileTokendirectly) was previously markedHidden:trueand only reachable by agents that readskills/references/products/aitable.md. Agents that only discover commands via--helpwere getting stuck at the sibling envelope-generatedattachment upload(prepare-only): they'd receiveuploadUrl+fileToken, have no idea how to consume the URL, and either write the URL into the attachment field as if it were a token (wrong shape — the field expects[{"fileToken":"ft_xxx"}]) or fall back to "please use the UI" messages, which madedwslook broken even though the capability was fully implemented. Unhiding mirrors the discoverability patternlark-cli base +record-upload-attachmentalready follows.Shortis tightened to explicitly mention the 3 steps it bundles;Longcalls out the prepare-only sibling and recommendsupload-fileas the default for AI agents. The siblingattachment upload(prepare-only) keeps its envelope-generated registration but gets a newLongthat states it is only step 1 of a 3-step flow, lists what an agent must do after (HTTP PUT touploadUrl, then write[{"fileToken":"ft_xxx"}]into the attachment field), and points toupload-fileas the recommended one-shot alternative.TestAITableUploadFileCommandIsDiscoverableininternal/helpers/aitable_upload_file_test.goguards against re-introducingHidden:true.dws --helproot output now surfaces thedws upgradehint when no listed command fits (#347,internal/app/root.go+internal/app/root_help.go) —root.Longis set to"提示: 如果遇到能力缺失、命令报错、新功能未注册、或无法完成任务, 请先用 'dws upgrade' 升级到最新版本后再试. 钉钉 OpenAPI 和 dws CLI 持续迭代, 新能力和 bugfix 会先在新版本上线.". The customrenderRootHelp(which replaces cobra's default template to render the services / utilities sections) had been silently droppingroot.Long; restoring it costs oneFprintlnafter the command list, separated by a blank line. The natural failure mode for both agents and users staring atdws --helpis to give up or hack around when none of the listed commands fit — but in many cases the right action is simplydws upgrade, because new capabilities and bugfixes ship continuously and a missing command is usually a stale-binary issue.TestRenderRootHelpIncludesLongininternal/app/visibility_test.gouses a sentinelLongstring and asserts the rendered output contains it verbatim, so any future rewrite of the help renderer that dropsLongfails this test immediately.
Fixed
dws drive uploadno longer fails withHTTP 403 SignatureDoesNotMatchon any non-empty MIME type (#347,internal/helpers/drive.go) —httpPutDriveFilewas settingreq.Header["Content-Type"] = fallbackMIMEwhenever the prepare_upload response returned an empty headers map. DingTalk drive's OSS presigned URLs signStringToSignagainst an emptyContent-Typeat signing time, so any client-side header makes the signature OSS recomputes at PUT time differ from the server's presignature, and the upload is rejected with403 SignatureDoesNotMatch. This broke everydws drive uploadfor any file whose MIME detects to a non-empty value (image/png,application/pdf, every common binary) — i.e. essentially every real upload. Fix: drop thehasContentType/fallbackMIMEpath entirely, trust the server's headers map as authoritative; empty map means "no client-side headers needed", do not infer.httpPutDriveFile's signature loses thefallbackMIMEparameter. Manual verification:curl -X PUT -H "Content-Type:" --data-binary @file <same-presigned-url>returnsHTTP 200, proving the only difference was the client-sideContent-Type.TestHttpPutDriveFile_NoContentTypeWhenServerHeadersEmptyguards the empty-map path;TestHttpPutDriveFile_PassthroughServerHeadersguards that server-providedContent-Type/x-oss-*headers are forwarded verbatim. Important:internal/helpers/aitable.go'supload-filehelper deliberately keeps itsSet("Content-Type", mimeType)call — its OSS endpoint uses a different signing mode (server includes the client-declared MIME in the signature, verified across 12 file types — all succeed). The two helpers must not be unified without re-validating both endpoints.dws upgradeno longer dies withsignal: killedon Apple Silicon after fetching the new binary (#339) — GoReleaser cross-compilesdarwin/arm64binaries onubuntu-latestwith no codesign step, and macOS 11+ on Apple Silicon requires at least an ad-hoc signature on every arm64 binary;amfidSIGKILLs unsigned arm64 binaries on first exec, which the upgrade client surfaces assignal: killedand aborts at the "解压并验证" step. Two layers of fix:- Release-side ad-hoc signing (
scripts/release/post-goreleaser.sh+.github/workflows/release.yml) — after GoReleaser produces the per-platform tarballs,post-goreleaser.shunpacks eachdws-darwin-*.tar.gz, applies an ad-hoc signature (codesign --force --sign -locally,rcodesignin CI), deterministically repacks the tarball, and rewrites the matching line inchecksums.txtso the checksum stays consistent with the resigned tarball.release.ymlinstallsrcodesign 0.27.0before GoReleaser runs. Every 1.0.32+ tarball ships signed; the install regression is fixed at the source. - Client-side self-heal in
validateNewBinary(internal/app/upgrade.go) — when running the freshly-extracted binary returnssignal: killedon darwin, the validator retries once after runningcodesign --force --sign -on the binary and clearing thecom.apple.quarantinexattr. This keepsdws upgradeworking even if a future release ever skips the signing step again, and covers users upgrading from older unsigned binaries.internal/app/upgrade_test.go(+80 lines) covers the retry path end-to-end: a stripped binary exits 137 on first exec,validateNewBinaryrecovers via ad-hoc sign + xattr clear, the final binary showsSignature=adhocand runs.
- Release-side ad-hoc signing (
[1.0.31] - 2026-05-21
Closes the last drive-surface gap with the Wukong edition: dws drive upload lands as a single-shot composite (drive.get_upload_info → HTTP PUT to OSS → drive.commit_upload) so a local file reaches DingTalk drive in one CLI invocation, no manual three-step orchestration. Two more drive commands — dws drive list-spaces (list visible drive spaces) and dws drive delete (delete a drive file, routed via serverOverride to the doc MCP server) — ship via the portal envelope; dws cache refresh once to pick them up. Companion skill docs teach the agent to recognise dingpan URLs of the form alidocs.dingtalk.com/document/edit?dentryKey=… / …/document/preview?dentryKey=… and pass the whole URL through to --node instead of trying to extract dentryKey by hand (the server interprets dentryKey and a bare nodeId differently — manual extraction was failing).
Added
-
dws drive upload --file <path> [--folder <dentryUuid>] [--space-id <id>] [--file-name <name>] [--mime-type <type>](#335, seeinternal/helpers/drive.go) — composite leaf that runs the full three-step upload internally:drive.get_upload_info— fetch the OSS-signedresourceUrl+uploadId+ per-URL headers.- HTTP
PUTthe file binary to OSS (10-minute timeout, attaches every header returned by step 1). drive.commit_upload— register the new file under the target space / folder.
--dry-runprints the three step invocations as a single JSON payload without making any network calls.--file -is rejected on purpose: this is a local-path upload, not stdin streaming.--folderonly accepts adentryUuid; pure-numeric values are rejected up front (validateDriveParentID) so callers don't accidentally pass a chat-linkdentryId(a different ID namespace) where the drive API expects adentryUuid. Response normalisation handles all the wrapper shapes the upstream returns —content/resultenvelopes,resourceUrls[]arrays, and the flatresourceUrl/uploadUrlfallbacks — so the composite produces a stable JSON shape regardless of which path the upstream takes. The helper only registersupload; the existing six envelope-generated leaves (list/info/download/mkdir/upload-info/commit) keep flowing through dynamic discovery unchanged.pickCommands.MergeHardcodedLeavesguarantees dynamic leaves win on collision, so this helper only fills the upload gap. -
dws drive list-spacesanddws drive delete(envelope rollout) (#335, ships via portal envelope) —list_spacesregisters as a plaincliNamealias on the existing drive MCP server;delete_documentregisters withserverOverride: docso the call routes to the doc MCP server (which owns the delete API), surfacing under the drive command tree for ergonomics. Existing users must rundws cache refreshonce to pick up these two new leaves; no binary upgrade is required for them, but they pair naturally with the v1.0.31 client that shipsupload. -
skills/references/url-patterns.md(#335) — single authority for dispatchingalidocs.dingtalk.comURLs across doc / sheet / wiki. Five-way split:/i/p/<token>short links → expand viadoc info;/i/nodes/<id>node URLs → probe withdoc infoand route bycontentType/extension/nodeType;/spreadsheetv2/...→sheet;/document/edit|preview?dentryKey=<key>(dingpan format) → pass the whole URL to--node, do not stripdentryKeyby hand;/i/share/...(read-only share) → use theread_urlfallback. The "URL precheck" Step 0 inskills/SKILL.mdnow redirects every URL-bearing prompt through this dispatcher before the agent picks a product.
Changed
skills/references/products/doc.md—--nodeaccepts dingpan URLs end-to-end (#335) —dws doc info/dws doc readexamples gain two extra rows showing--node "https://alidocs.dingtalk.com/document/edit?dentryKey=<KEY>"and…/preview?dentryKey=<KEY>as first-class--nodeinputs. The "URL recognition & DOC_ID extraction" table adds thedocument/edit|preview?dentryKey=<key>row, and the extraction rules are split into three explicit clauses so the agent stops manually pullingdentryKeyout of the URL and feeding it as a barenodeId(which the server rejects). The "nodeId dual-format note" upgrades to "nodeId multi-format note" with four equivalent--nodeinput shapes side by side.
[1.0.30] - 2026-05-19
Aligns the open-source CLI with the IM envelope and schema-pipeline plumbing the Wukong edition has been running in pre-prod, plus three user-visible quality-of-life fixes. The most visible one: chat-bot webhook payloads carrying literal Chinese mentions (@所有人 周报来了 / @张三 看一下) no longer fail with file not found — @ is only treated as the @<filename> file-injection prefix when followed by an ASCII path-shaped character. The chat command tree is refactored to lean on the service-discovery envelope: thin wrappers (chat search, chat group rename, chat group members list/add/remove/add-bot, chat bot search) move out of the hardcoded helper and become envelope-generated dynamic commands; the helper keeps only the chat commands with real business logic (intelligent routing, current-user resolution, response normalization, stdin/@file input). A new dws chat message reply joins the existing send / send-by-bot / recall-by-bot / send-by-webhook family. Underneath: transform: invert_bool lets envelopes flip boolean semantics between CLI surface and MCP body (e.g. --off ↔ mute=true); the pipeline executor fail-fast on upstream content.errorCode instead of polling forever; service-discovery dedup keeps two envelope entries that share an MCP endpoint but declare different cli.id as separate descriptors (so the bot-root / bot-message / bot-group trio fronting one MCP server stays as three distinct CLI command roots); and dws chat no longer nests as dws chat chat when two envelope servers both declare the same top-level command name.
Added
transform: invert_boolfor envelope flag overrides (#317, seeinternal/compat/transform.go) — flips a boolean at send time. Stringstrue/1/yes/on→false;false/0/no/off/""→true. Used when the CLI surface and the MCP body have opposite semantics — e.g. envelope declares--offon the CLI but the MCP parameter ismute=truefor "muted". The framework flips at send time so the envelope keeps the natural CLI verb without forcing every caller to remember the inverted mapping. Coverage ininternal/compat/transform_test.go.dws chat message reply(#317, seeinternal/helpers/chat.go) — reply to a chat message. Sits alongsidesend/send-by-bot/recall-by-bot/send-by-webhookunderdws chat message.
Changed
chatcommand tree refactored to lean on the service-discovery envelope (#317, commit6be1247) —internal/helpers/chat.gonow only carries the chat commands that need real business logic on top of the raw MCP call:chat message send(current-user resolution + symmetric direct/group title validation),chat message send-by-bot/recall-by-bot/send-by-webhook(bot routing + stdin/@file input), andchat group create(response normalization). The thin wrappers —chat search,chat group rename,chat group members list/add/remove/add-bot,chat bot search— are now produced by the envelope as dynamic commands. Net diff in the helper:+358 / -71overall (re-aligning to envelope-owned chat structure), andchat_test.godrops 71 lines of test-stubs the dynamic path covers natively. Every previously documented chat command keeps the same flag set and the same MCP tool routing — the surface is just sourced differently.- Pipeline executor fail-fast on
content.errorCode(#317, seeinternal/compat/pipeline.go) — when an upstream tool returns a non-emptycontent.errorCode,executePipelineCallraises a validation error immediately with the upstreamerrorMessageinstead of proceeding into the poll/download phase. Pre-execution cobra validation (MarkFlagRequired) only checks that a flag was set, not that its value was non-empty — so a--required-flag ""reaches the upstream tool and the upstream rejects witherrorCode. Without the short-circuit the pipeline kept polling for a task ID that would never exist, either spinning toPollTimeoutor burning through retries with no actionable error. Exit code 2 (validation), same as any other CLI-layer pre-flight rejection. - Service-discovery dedup keys now include
cli.id(#317, seeinternal/market/registry.go) —NormalizeServersused to dedup envelope entries by endpoint alone (and bydisplayNamein the second pass), which collapsed envelope entries that intentionally split one MCP endpoint into multiple CLI command trees. Thebot-root/bot-message/bot-grouptrio all front the same.../server/4717...MCP endpoint and share the displayName机器人消息, but each declares a distinctcli.idand a distinct CLI command root; the old dedup kept only the last-write and dropped two of them. The dedup key now appends#<cli.id>when present, falling back to endpoint / name when absent so historical envelopes withoutcli.idkeep their existing behaviour. Coverage ininternal/market/registry_test.go.
Fixed
@<text>injection no longer eats Chinese mentions like@所有人/@张三(#317, seeinternal/cli/stdin.go) —ReadFileArgandResolveInputSourceused to treat any value starting with@as the@<filename>injection syntax. Chat-bot webhook payloads commonly contain literal mentions, sodws chat message send-by-bot --text "@所有人 周报"was failing withfile not found: 所有人 周报before the message reached the API. The newlooksLikeFilePathheuristic accepts@followed by an ASCII path-prefix character (A-Z/a-z/0-9/.///~/_/-), or@-for stdin, and passes the value through unchanged otherwise.@A 但接下来都是中文@测试does still attempt a file lookup because the rune right after@is ASCII — this matches the documented@<path>prefix shape. The historical "bare@is an error" behaviour is preserved. Coverage ininternal/cli/stdin_test.go::TestReadFileArgChineseAtMention.dws chatno longer nests asdws chat chatwhen two envelope servers contribute the same top-level command (#317, seeinternal/compat/dynamic_commands.go) —BuildDynamicCommandsused to overwritetopLevel[name]on the second contribution and rely onattachOrMergelater, which then attached the whole incoming command (namedchat) under the existing root, producingdws chat chat <leaf>. The newmergeSubcommandsIntomoves the second contribution's children under the first root and drops the duplicate wrapper, so e.g.group-chat+imenvelopes that both declarecli.command: chatproduce a single flatdws chatsubtree.- Multi-server tool-name authority correction in the runtime runner (#317, see
internal/app/runner.go+internal/app/direct_runtime.go) — when two envelope servers share the samecli.command, the per-product endpoint mapendpoints[cmd]inregisterDynamicServeris second-writer-wins, andcatalog.FindProductmay return the wrong server's endpoint for a tool whose real owner is the other server.runtimeRunner.Runnow cross-checks the canonical tool→endpoint map exposed by the newdirectRuntimeToolEndpoint: when the per-tool endpoint exists and differs from the per-product endpoint the catalog returned, the tool-owner endpoint wins. Pairs with the registry dedup change above so the routing matches the dedup result.
[1.0.29] - 2026-05-17
Three discovery-envelope products land on the open-source surface — aiapp (AI applications), live (DingTalk live streaming), and aisearch (enterprise people search) — closing the gap with the Wukong edition's product list. The aisearch envelope ships rich model-tolerance affordances (short flags, flag aliases, subcommand aliases) so AI agents that hallucinate keyword synonyms (--query / --name / --q / --text / --find) or alias subcommands (search / find / query / user / people / ...) still route to the canonical person tool instead of erroring out. To support that final fragment of agent tolerance, internal/compat/registry.go relaxes the envelope-generated leaf command's Args validator from cobra.NoArgs to cobra.ArbitraryArgs — restoring cobra's own default (legacyArgs returns nil for leaves) so trailing positional words are silently ignored. Plus the previously-shipped credential-isolation fix.
Added
dws aiapp/dws live/dws aisearch— three new products discovered via envelope (no public issue; pre-Diamond rollout) — open-sourcedwsnow exposes:dws aiapp— AI application lifecycle:create --prompt <p> [--attachments <json>] [--skills <csv>]/query --task-id <id>/modify --prompt <p> --thread-id <id> [--skills <csv>]. Backed by upstreamcreate_ai_app/query_ai_app/modify_ai_appMCP tools.dws live stream list— list my DingTalk live streams. Backed by upstreamget_my_lives.dws aisearch person— enterprise people search by keyword + multi-dimension filter. Dimensions:all(default) /name/department/position/duty/supervisor/subordinate/phone/jobNumber— multiple comma-separated (--dimension name,department). Backed by upstreamenterprise_person_search.- The
aisearchenvelope additionally registers-w/-dshort flags (keyword / dimension); hidden flag aliases--query/--name/--q/--text/--findall routing tokeyword; and cobra subcommand aliasessearch/find/query/user/people/search-person/search-user/user-search/lookup/ask/contactall routing toperson. This closes the F-class model-tolerance regression cases indws-wukong/auto-test/cli_to_mcp/testcases/aisearch/test_90_aisearch_param_regression.py(50/50 pass for aiapp + live + aisearch on the pre-mcp build). - Users must run
dws cache refreshonce to pick up the new envelopes; no binary upgrade is required, but pairs naturally with the v1.0.29 client (see Fixed below for the envelope-leaf-Args change).
Fixed
- Envelope-generated leaf commands now tolerate trailing positional args (#306, no public issue) —
NewDirectCommandininternal/compat/registry.gowas hard-codingcobra.NoArgsfor leaves without positional bindings (totalMax == 0). This is stricter than cobra's ownlegacyArgs(cobraargs.go:30-32returnsnilfor any command without subcommands), and surfaced asunknown command "<word>" for "<leaf>"whenever an AI agent passed trailing positional words after a leaf — e.g.dws aisearch person search --keyword "张"ordws aisearch person user search --keyword "张". Switching thetotalMax == 0branch (and the initial value) fromcobra.NoArgstocobra.ArbitraryArgsrestores cobra's natural leaf behavior: trailing positional args are silently ignored. Existing positional-binding paths (MinimumNArgs/RangeArgs/MaximumNArgs) are unchanged. Verified againstdws-wukong/auto-test/cli_to_mcp/testcases— aiapp (9/9) + live (3/3) + aisearch (38/38) = 50/50 pass, vs 48/50 before this patch.
Security
- App credential files are partitioned by edition to prevent cross-edition credential leakage (#300, no public issue; found during internal review) — different
dwseditions sharing the same config directory previously read and wrote the sameapp.json. A sibling edition that pinned its OAuth client ID could persist that ID through the shared post-login path, and the open-source build could later adopt it from the same file. Open-source/empty edition keeps the legacyapp.jsonpath for compatibility; sibling editions now useapp-<edition>.json, matching the existing cache partitioning strategy. This prevents new cross-edition app credential writes and reads from colliding. After a sibling edition saves its new partitioned file, it also best-effort removes a legacy~/.dws/app.jsononly when that file'sclientIdmatches the sibling edition being saved; a different, unparsable, or otherwise unownedapp.jsonis left untouched to avoid deleting open-source credentials. If you previously ran multiple editions in one shared~/.dws, remove any confirmed-stale orphan manually withrm ~/.dws/app.jsonafter verifying it is not the open-source credential file you still need.
[1.0.28] - 2026-05-14
A single symmetric follow-up to 1.0.26's #250: dws chat message send --group <cid> now refuses an empty --title at the CLI layer instead of letting the call fall through to the API and surface a misleading 发群服务窗会话消息失败 error. No other behaviour changes.
Fixed
dws chat message sendrejects missing--titleon group messages (#294, completes #250) —send_message_as_user's schema markstitleas required (just likesend_direct_message_as_user), butbuildChatMessageSendInvocationonly had the pre-validation on the direct-message branches. Group sends without a title were falling through to the API and returning the same misleading发群服务窗会话消息失败that #250 already fixed for direct messages. The check now covers both branches: missing--titleon--groupreturns--title is required for group messages (--group)with exit code 2; missing on--user/--open-dingtalk-idkeeps the original--title is required for direct messages (--user / --open-dingtalk-id). TheLonghelp,--titleflag description, the firstExample, andskills/references/products/chat.md(including the drive→chat workflow example) are realigned to "title is required for both direct and group messages" — the docs previously contradicted themselves (the prose said 群聊可选 while the flag listing said 必填).internal/helpers/chat_test.goadds agroup-without-titlerejection case; the existinggroup/positional-textsuccess cases now pass--titleto stay aligned with the new validation. No API request shape change — the server has always requiredtitle; the CLI now matches.
[1.0.27] - 2026-05-14
Two user-visible fixes plus the schema primitive they're built on. dws doc update now reads Markdown from a file or stdin, so long / multi-line / table-heavy content no longer gets mangled by shell escaping; dws sheet find --query stops returning unknown flag on the open-source build, restoring copy-paste from internal wukong docs. Underneath, schema/discovery envelopes get a generic file_read transform and a CLIFlagOverride.MapsTo field that lets two sibling CLI flags route into the same MCP parameter slot. Also suppresses a noisy WARN on normal stdio-plugin shutdown.
Added
file_readtransform +CLIFlagOverride.MapsTofield (#291, closes #277 #278 #282 #288) — discovery envelopes can now declare a path-typed CLI flag that performs the "file path → file contents string" conversion client-side before the value reaches the upstream MCP parameter.transform: "file_read"(internal/compat/transform.go) — reads the file at the flag's value with UTF-8 validation;-means stdin. Any IO / encoding failure is surfaced as a validation error (exit 2), distinct from the generic transient-failure path (exit 1).CLIFlagOverride.MapsTo(internal/market/registry.go) — redirects the flag's final value (post-transform or literal) into a named MCP parameter slot instead of the defaultparams[propertyName]. This lets a single MCP parameter (e.g.markdown) be fed by two sibling CLI flags — a literal--contentand a file-reading--content-file— paired with the existing tool-levelMutuallyExclusive/RequireOneOfto express "exclusive, at least one".- Wired into the
internal/compat/dynamic_commands.gonormalizer via a separatemapsToRoutescollection + routing pass; emptyMapsTopreserves the legacyparams[propertyName] = valuesemantics, so every pre-existing dynamic_commands test passes unchanged. Pre-prod end-to-end verified across 6 cases (see PR #291's Validation table).
dws doc update --content-file <path>(envelope rollout) — fixes "long Markdown can't reach the doc". The old command only accepted--content "...", so long / multi-line / table-heavy Markdown got mangled by shell escaping and AI agents writing >2KB of content were stuck. The envelope now maps both--content(literal) and--content-file(file_readtransform) to themarkdownparameter, makes them mutually exclusive via cobra'sMarkFlagsMutuallyExclusive, and requires at least one viaRequireOneOf.--content-file -reads from stdin, socat long.md | dws doc update --content-file -works directly. Existing users must rundws cache refreshonce to pick up the new envelope.dws sheet find --queryhidden alias (envelope rollout) — fixes "unknown flag when copy-pasting commands across editions". Users copyingdws sheet find --query "..."from internal wukong docs onto open-sourcedwsgotunknown flag: --query, because the open-source primary flag is named--find. The envelope now registers--queryas a hidden alias of--findviaCLIFlagOverride.Aliases(the field shipped in 1.0.26) — it doesn't show up in--help, but accepts values and writes to the same MCP parameter.--findbehaviour is unchanged. Also requiresdws cache refreshonce.
Fixed
- Noisy
failed to stop stdio client: exit status 1WARN on normal stdio-plugin shutdown (#285) — whenStop()explicitlyKills the subprocess, the non-zero exit code returned bycmd.Wait()is expected behaviour, but it was being propagated as an error and logged to stderr on every CLI exit, polluting agent log parsing.Stop()now returnsnilafter Kill + Wait; the error path is reserved for "process exited on its own with non-zero" (e.g. stdin close without an explicit Kill).internal/transport/stdio.go+stdio_integration_test.goassert "Stop() returns nil after kill".
[1.0.26] - 2026-05-12
Platform-stability round: Windows PAT-auth browser opener no longer truncates URLs at &userCode=, macOS sandbox hosts get an opt-in keychain fallback, and dws doc download rejects axls nodes before requesting drive:download consent. Two new global output formats -f ndjson and -f csv (matching larksuite/cli) land as first-class citizens with real-traffic-verified list detection. The dws doc comment * regression tracked in #240 is also resolved — fix is in the market metadata, users just need dws cache refresh once.
Added
-f ndjsonand-f csvglobal output formats (#259, closes #252) —ndjsonemits one compact JSON record per line (works straight withjq -c/while read/ log pipelines);csvgoes throughencoding/csv(RFC-4180 — quoting, embedded newlines, CJK all handled by stdlib) and reuses the existing-f tablecolumn resolver (normalizePayload/unwrapPrimaryObject/extractRowsFromMap/rowsFromSlice/formatValue) so table and csv stay visually aligned. After a 7-product real-traffic sweep (contact / chat / doc / mail / todo / minutes / schema), thepreferredListKeyswhitelist was extended to cover the actual DingTalk envelope shapes —contact user search(result),chat search(result.value),doc search(documents),mail mailbox list(emailAccounts),todo task list(result.todoCards) — so these commands now degrade into a proper row stream instead of collapsing to a single-linekey,valueblob. Lives ininternal/output/ndjson.go+internal/output/csv.go;--formathelp ininternal/app/flags.gonow listsndjson|csvalongsidejson|table|raw|pretty.
Changed
- Sticky flag splitting is now schema-aware (#272) — PreParse
StickyHandler此前会把任何前缀命中已知 flag 的--flagsuffix一律切成--flag suffix,于是--starttime20260507这类拼错被静默改写成--start time20260507,把假值传到下游。新行为按 flag 的 pflag 类型 / JSON Schemaformat/enum校验 suffix 是否像合法 value(共享逻辑见pkg/cmdutil/sticky_suffix.go),不像就保留原 token 让 cobra 报unknown flag。slice/array/object 类型的 flag 永不切分。首 rune 读取使用utf8.DecodeRuneInString,对中文等多字节 value 安全。
Added
available_flagsfield on unknown-flag errors (#272) —dws -f json的 unknown-flag 错误体里新增available_flags(已排序、过滤掉 hidden 与内部json/params),方便 agent 不解析--help就能恢复。Human-readable 输出会附Flags: ...行,截断在 200 字节内。
Fixed
dws chat message send单聊缺--title时前置校验 (#250) — 单聊(--user/--open-dingtalk-id)的底层工具send_direct_message_as_user在 API 层强制要求 title,缺失时返回误导性的发群服务窗会话消息失败。CLI 现在在buildChatMessageSendInvocation里前置校验,直接返回--title is required for direct messages (--user / --open-dingtalk-id);同时把Longhelp、--titleflag 描述、Example 和skills/references/products/chat.md全部对齐为「单聊必填,群聊可选」。群聊行为不变。- PAT auth URLs were truncated on Windows browser open (#242, fixes #230) —
cmd /c start <url>on Windows interprets&as a command separator, so PAT URLs containing&userCode=...were silently chopped before the userCode segment, and the browser landed on a 0-permission DingTalk page. The retry opener now usesrundll32 url.dll,FileProtocolHandler, which passes the URL through verbatim. The PAT response also exposes a copy-safedata.authorizationUrl(in addition to the service-provideddata.uri, which is preserved as-is), and human-readable PAT output printsPAT_AUTHORIZATION_URL=<full-url>on its own line so OpenClaw-style host wrappers that swallow or reformat stderr can still capture the full link. Legacy DingTalk hash-route shapes (https://open-dev.dingtalk.com/fe/old#%2FpersonalAuthorization%3FflowId=...%26userCode=...) are normalised back into the working/fe/old?hash=...#/personalAuthorization?...&userCode=...form. Regression tests cover the issue-shaped URLs (encoded hash, fragment,&userCode) plus the OpenClaw malformed-hash variant. dws doc downloadtriggereddrive:downloadPAT consent for unsupported axls nodes (#268, fixes #190) — added aget_document_infopreflight beforedownload_file, so online-sheet (axls) nodes are rejected locally with guidance to use sheet range tools instead. The preflight readsextensionfrom deterministic response paths (no recursive payload scan) and routes its own PAT errors back throughhandlePatAuthCheck, preserving device-flow / host-owned PAT behaviour. Costs one extra MCP roundtrip perdoc download— deliberate, so the unsupported path fails before consent. Lives ininternal/app/doc_download_preflight.go; coverage ininternal/app/runner_test.go.- macOS sandbox hosts (Codex App etc.) couldn't read/write tokens via Keychain (#267, fixes #214) — sandboxed macOS environments intercept
security/ Keychain APIs, so every token operation failed. New opt-inDWS_DISABLE_KEYCHAIN=1switches macOS to the same file-DEK path Linux uses (DEK at~/Library/Application Support/dws-cli/dek, mode0600), bypassing the system Keychain. Default behaviour is unchanged — fallback is strictly opt-in because file-DEK is a weaker trust model than Keychain-managed storage (DEK file sits next to ciphertext in the same directory). The Darwin / Linux file-DEK implementation is now shared ininternal/keychain/file_dek.go(Linux path deduplicated by ~40 lines). Documented indocs/reference.md(中英) with the security tradeoff spelt out so users make the choice explicitly. dws doc comment {list,create,create-inline,reply}returnedPARAM_ERROR - 未找到指定工具(fixes #240, also #234) — the four comment tools used to live on an independentdoc-commentMCP server. After the Portal merged comment functionality into thedocserver descriptor, the runtimetools/liston the mergeddocserver didn't include them, so everydws doc comment *call returned the "tool not found" PARAM_ERROR. The market metadata for thedocserver now declaresserverOverride: "doc-comment"on all four commenttoolOverrides, so the existing CLI routing path sendsdws doc comment *to the still-runningdoc-commentMCP server (which has the tools). No CLI code change was required, but existing users must rundws cache refreshonce to pick up the updated descriptor — without that, the stale local market cache keeps pointing the call at the mergeddocserver and the error persists. Verified post-refresh: dry-run resolves tohttps://mcp-gw.dingtalk.com/server/doc-commentwith toollist_comments, real calls return normal business responses (e.g. legitimate cross-org authz errors) instead of未找到指定工具.
[1.0.25] - 2026-05-11
Two generic envelope-schema enhancements that close gaps the cli_to_mcp test suite kept surfacing — both product-agnostic, no hardcoded helper commands. Plus missing skill references for the already-registered sheet and wiki products are now shipped.
Added
sheet(在线电子表格) skill reference + product-overview entry — thesheetproduct registers 34 envelope tools covering worksheet CRUD (create/new/list/info/copy_sheet/update_sheet), range read/write (range read/range update/append), dimension ops (add-dimension/insert-dimension/delete-dimension/move-dimension/update-dimension), merge (merge-cells/unmerge-cells), find/replace (find/replace), filter views (filter-view {create, list, update, delete, update-criteria, delete-criteria}), sheet-level filters (create_filter/get_filter/update_filter/delete_filter/set_filter_criteria/clear_filter_criteria/sort_filter), image write (write-image), and async export (submit_export_job+query_export_job). These were live in the envelope butskills/references/products/sheet.mdhad not shipped andskills/SKILL.md产品总览 didn't listsheet, so agents had no reference to consult and were skipping it during intent routing. This release adds the doc, registerssheetin 产品总览 + 意图判断决策树, extendsdescriptionto include 在线电子表格, adds a Sheet row toREADME.md/README_zh.md"Key Services", and notes the v1.0.25 reality on naming (about a third ofsheettools still expose snake_case cli_names pendingCLIAliases(#246) rollout) and on export (no consolidateddws sheet exportexists in v1.0.25 —submit_export_job+query_export_jobare the atomic primitives; Pipeline (#247) provides the future plumbing).wiki(知识库) skill reference + product-overview entry — the wiki product's 7 envelope tools (wiki.create_wikiSpace,wiki.get_wikiSpace,wiki.list_wikiSpaces,wiki.search_wikiSpaces,wiki.add_member,wiki.list_member,wiki.update_member, surfaced asdws wiki space create / get / list / searchanddws wiki member add / list / update) have been registered for a while, but noskills/references/products/wiki.mdshipped with them, so agents had no per-command reference to consult. This release adds the reference doc, registerswikiinskills/SKILL.md's 产品总览 table and 意图判断决策树, mentions 知识库 in the skilldescriptionfrontmatter, adds a Wiki row toREADME.md/README_zh.md"Key Services", and removeswikifrom the "Coming soon" callout (which was now stale).CLIToolOverride.CLIAliasesenvelope field (#246) — lets a single MCP tool register additional cobra command aliases via envelope JSON (e.g.range readalso acceptsrange get,member listacceptsmember ls). Plumbed through the existingRoute.Aliases → cobra.Command.Aliasespath; sibling conflicts are silently dropped by cobra. Lives ininternal/market/registry.go+internal/compat/dynamic_commands.go.json_parse_stricttransform (#246) — strict-JSON variant ofjson_parsethat does not fall back to YAML. Use when the upstream tool requires a structured array/object and silently coercing a malformed input to a scalar string would mask a real user error (observed:filter-view --criteria 'NOT_VALID_JSON'was being accepted and quietly creating an empty-criteria view). Ininternal/compat/transform.go.CLIToolOverride.Pipeline+ pipeline executor (#247) — a single CLI command can now orchestrate an ordered sequence of MCP tool calls plus optional HTTP-download sinks, declared entirely in envelope JSON. Motivating use case: the "submit-job → poll-status → download-result" pattern (e.g. sheet export) that previously required per-product hardcoded helpers.PipelineStepsupportstype:"call"(with optionalPollUntilField/PollUntilValue/PollIntervalSec/PollTimeoutSecfor polling loops) andtype:"download"(resolvesDownloadURLField, HTTP GETs the body, writes to the path fromOutputFlag, infers filename for directory paths).- Template language:
$flag.<name>resolves a user CLI flag by alias;$step.<idx>.<dotPath>walks a prior step's response (works through wrapped MCP envelopes); literals pass through. CLIFlagOverride.PipelineLocalmarks a flag as CLI-side only soCollectBindingsskips it (value never reaches MCP params); the pipeline executor still reads it viaextractFlagValuesByAlias.- Download step emits machine-parseable plain-text lines (
jobId: <id>\n,downloadUrl: <url>\n) alongside the standard JSON envelope, so shell pipelines and regex-based tests can extract key values without JSON parsing.
[1.0.24] - 2026-05-09
Three small but user-visible safety/usability changes: the embedded distribution now refuses to self-upgrade, the dws auth login help text finally matches the actual default flow (loopback, not device), and the release workflow gains a manual fallback trigger.
Changed
dws upgradeis blocked in embedded distributions (#248) — when the CLI is shipped as an embedded asset (e.g. inside another product),dws upgradewould happily overwrite the host-managed binary. The upgrade entry point now detects the embedded build flag and exits early with a clear message; covered byinternal/app/upgrade_embedded_guard_test.go.
Docs
dws auth loginhelp text reflects the real default (#238, fixes #226) — the long help previously claimed "OAuth 设备流 (默认)", but the actual default starts a 127.0.0.1 loopback listener and only switches to device flow when--deviceis passed. SSH-into-headless-Linux users following the old text hit a dead end (remote-side 127.0.0.1 is unreachable from the local browser). Help and twoflagErrorWithSuggestionsmessages inroot.goare realigned: each method is named after its real flag (OAuth Loopback 流 (默认)/OAuth 设备流 (--device)/直接提供 Token (--token)), with an explicit--deviceexample for SSH/headless. No behaviour change.
CI
workflow_dispatchtrigger added to release workflow as a fallback (#261) — GitHub occasionally drops tag-push events; the release job can now be re-run manually against any tag ref without having to delete and re-push the tag.
[1.0.23] - 2026-05-08
A single fix for HTTP proxy support across the CLI's custom HTTP transports. No behaviour changes elsewhere.
Fixed
HTTP_PROXY/HTTPS_PROXYenvironment variables silently ignored by all custom transports (#237, fixes #236) — the three customhttp.Transportinstances built by the CLI (internal/transport/client.goMCP transport,internal/apiclient/client.goDingTalk OpenAPI client,internal/app/legacy.goIPv4-forcing registry client) all setDialContext/TLSClientConfig/ timeouts but omitted theProxyfield. Per Go'snet/httpcontract, a non-nil Transport without an explicitProxymeans "no proxy" — env vars are silently ignored, breaking sandboxed or air-gapped deployments that route outbound throughHTTP_PROXY/HTTPS_PROXY. All three transports now setProxy: http.ProxyFromEnvironment.
Tests
- Per-package regression test that pointer-compares the Transport's
Proxyfunc againsthttp.ProxyFromEnvironment, avoiding flakiness from Go'senvProxyOncememoisation when running alongside tests that read proxy env early. (#237)
[1.0.22] - 2026-05-07
Two release-blocking bug fixes: dws attendance summary now exposes the server-required --stats-type flag (without it, every call returned C0002), and the install scripts finally populate ~/.hermes/skills/dws/ for users who already have Hermes.
Fixed
dws attendance summaryreturned C0002 (统计类型错误) on every call (#228, fixes #227) — the DingTalk MCP toolget_attendance_summaryrequiresstatsTypeat the business layer even though the schema marks it optional. The CLI did not expose any way to set it, so the command was 100% unusable. A new--stats-typeflag (week/month) is now plumbed through toQueryUserAttendVO.statsType; the flag is documented as required in the long help, flag description, andskills/references/products/attendance.md.- Install scripts skipped
.hermes/skills/when populating skill directories (#221, fixes #188) — theAGENT_DIRSlists acrossbuild/npm/install.js,scripts/install.sh,scripts/install.ps1,scripts/install-skills.shand the four upgrade-path mirrors (8 sources total once review feedback was addressed) did not include.hermes/skills, so users with Hermes installed were not getting~/.hermes/skills/dws/populated automatically. The existing parent-directory gate keeps this zero-side-effect for users without Hermes.
Tests
- New
--stats-typeregression coverage intest/cli_compat/attendance_test.go— verifiesstatsTypeis written toQueryUserAttendVOwhen set tomonthorweek, and is omitted when not provided. (#228)
[1.0.21] - 2026-05-05
A single critical routing fix for dws drive commands. No new commands or behaviour changes elsewhere.
Fixed
dws drive mkdir/dws drive downloadsilently routed to the doc MCP server (#220, fixes #219) — when two MCP servers register tools with the same name (e.g. bothdriveanddocexposecreate_folder), the tool-level endpoint map used last-writer-wins, so drive-side calls landed on the doc endpoint and returned mock-shaped responses (success: truewith a fakefolderId) without actually creating anything.directRuntimeEndpointnow resolves product-level first when the caller already knows the productID, and only falls back to the tool-level lookup when productID is empty. The wrong-server collision and the resulting "succeeded but didn't" behaviour are gone.
[1.0.20] - 2026-05-04
Documentation polish and a login regression fix. No behaviour changes outside the login MCP refresh path.
Fixed
- Login no longer reuses stale
clientIdfrom an old MCP cache (#213) —dws loginnow unconditionally re-fetches the MCP descriptor, so a previously cached client id can't keep producing auth errors after the server rotates it.
Docs
dws chat message listpagination (#218, fixes #195) — clarifies thatnextCursoris opaque and must be passed back as--cursorexactly; warns against parsing or reusing it as an offset.dws contact searchexamples (#209) — switched from the removed--keywordflag to the current--query.dws todohelp text (#205) — expanded field semantics so MCP wrappers generate accurate schemas.dws chat message send-by-botanddws report createhelp (#217, #106, #107) —--robot-code/--title/--textnow carry the(必填)marker;report create --contentsdocuments thekey=field_namerequirement and rewrites examples as atemplate detail → createtwo-step pipeline.- CHANGELOG backfill for 1.0.19 (#204).
[1.0.19] - 2026-04-30
Discovery hardening for edition overlays: edition.SupplementServers / FallbackServers hooks now consistently surface through the runtime catalog loader, not just the static command tree, so overlay products that live outside the Portal envelope (e.g. Wukong gray-release conference) resolve an endpoint on both the cold-cache and tool-not-in-catalog paths. Ships with per-edition cache partitioning to stop cross-edition disk-cache leakage, plus a small todo fix.
Added
pkg/config.EditionPartition(name)(#197) — returns the cache partition key for a given edition. Open-source core (""/"open") keeps usingDefaultPartition(default/default); every other edition gets its own namespace (<edition>/default), preventing cross-edition data leakage in the shared~/.dwsdisk cache. Lives inpkg/configas a leaf helper sointernal/cli,internal/app, andinternal/cachecan all call it without risking import cycles.internal/editionmergeshared package (#197) — single source of truth for convertingedition.ServerInfointomarket.ServerDescriptor(ToDescriptor) and for mergingSupplementServers/FallbackServersinto a descriptor list. Bothinternal/cli(command tree) andinternal/app(runtime catalog) now apply the edition hooks against the same discovery pipeline.
Changed
EnvironmentLoader.loadFromCachehonorsSupplementServerseven on empty registry (#197) — when the Portal registry cache is missing or empty, the catalog loader still materialises the edition'sSupplementServersas endpoint-onlydiscovery.RuntimeServerentries (source:edition_supplement), so hardcoded overlay commands for supplement-only products can still resolve an endpoint via the catalog path. PreviouslyloadFromCacheshort-circuited to an empty catalog whenever the registry snapshot was empty, silently dropping gray-release products.- Cache loader switches from
DefaultPartitiontoEditionPartition(edition.Get().Name)(#197) — the runtime catalog, registry snapshot, and tools snapshot are now partitioned per edition instead of all editions sharingdefault/default. loadFromCacheappends supplement servers alongside fresh-cache servers (#197) — supplement entries whoseCLI.ID/Keyare already present in the cached registry are skipped, so the hook never shadows Portal-published servers; only new products are added.runtimeRunner.Runfalls through todirectRuntimeEndpointfor supplement products (#197) — when the catalog contains the product (e.g. supplied bySupplementServers) but the specific tool is not declared, the runner now trustsdirectRuntimeEndpointto resolve a working endpoint for the tool before returning the explicit catalog-miss error. Supplement entries intentionally carry no tool list, so this is the path that makes overlay-only tools executable.- Legacy
mergeSupplementServers/fallbackToDescriptorsmoved out ofinternal/app/legacy.go(#197) — relocated intointernal/editionmergeand reused by the catalog loader, eliminating the duplicateedition.ServerInfo → market.ServerDescriptorlogic that previously only ran on the static command-tree path.
Fixed
dws todo task getreturns empty (#202) — the helper was callingquery_todo_detail, which is not a valid MCP tool and returns empty. Switched toget_todo_detailas declared indiscovery.json, restoring correct task-detail behaviour.- Conference and other Wukong gray-release products miss endpoint on cold cache (#197) — products registered only via
edition.SupplementServers(not yet in the Portal envelope) now resolve an endpoint through the catalog path in both cold-start and tool-not-declared scenarios.
Tests
internal/editionmerge/merge_test.go— descriptor conversion + supplement/fallback merge semantics.internal/cli/loader_partition_test.go+loader_supplement_test.go— edition-partitioned cache reads and supplement hook surfacing fromloadFromCache(including empty-registry cold path and existing-ID deduplication).internal/app/legacy_wukong_partition_e2e_test.go— end-to-end cache partition isolation for the Wukong edition.internal/app/runner_supplement_fallback_test.go— runner falls through todirectRuntimeEndpointwhen the tool isn't declared by a supplement-sourced catalog entry.pkg/config/constants_test.go—EditionPartitionname handling ("","open", custom edition).
Docs
- CHANGELOG v1.0.18 rewrite (#193) — previous release notes expanded to call out the PAT host-owned A-core flow, exit-code contract change (auth
4, Discovery/cache/protocol6),dws pat chmod/pat browser-policyentry points, stderr-JSON classifier updates, and host-control metadata injection.
[1.0.18] - 2026-04-28
Raw DingTalk OpenAPI access lands as a new dws api surface for both api.dingtalk.com and oapi.dingtalk.com, backed by app-level token caching and guarded host allowlists. PAT enters the host-owned A-core loop: agent hosts can own authorization UI through DINGTALK_DWS_AGENTCODE, parse single-line stderr JSON, call dws pat chmod, and replay the original command. Chat helper regressions are fixed, skill references are brought back in line with shipped commands, and the v1.0.17 Mail release notes are backfilled into README / CHANGELOG.
Breaking
- PAT exit-code contract (#142) — PAT authorization interceptions now use exit code
4; Discovery, cache, and protocol negotiation failures now use exit code6. Downstream scripts that previously treated4as Discovery must update their handling.
Added
dws apiraw DingTalk OpenAPI command (#184) — direct DingTalk OpenAPI calls without writing an MCP wrapper first. SupportsGET/POST/PUT/PATCH/DELETE, JSON--params/--data, stdin input, dry-run previews,--jq, field selection,--page-all,--page-limit,--page-delay, and--base-url.- Dual-form OpenAPI routing (#184) —
api.dingtalk.comrequests use thex-acs-dingtalk-access-tokenheader;oapi.dingtalk.comrequests use the legacyaccess_tokenquery parameter. The raw API client validates the target host before attaching credentials. - App-level token cache for raw API (#184) — custom-app credentials now fetch app access tokens from the unified OAuth endpoint, cache them while valid, and refresh them before expiry. The same token provider works for new-style and legacy OpenAPI calls.
- Host-owned PAT A-core flow (#142) — when
DINGTALK_DWS_AGENTCODEis set, PAT hits returnexit=4plus single-line stderr JSON; the host renders authorization UI, callsdws pat chmod <scope>..., and replays the original command. dws pat chmodauthorization entry point (#142) — grants scopes with--agentCode,--grant-type, and session fallback support;DINGTALK_DWS_AGENTCODEcan supply the agent code when the flag is omitted.- PAT browser-open policy (#142) —
dws pat browser-policy --enabled <true|false> [--agentCode <id>]controls whether the CLI may open a browser, independently from--formatoutput mode.
Changed
- README raw API guide (#184) — English and Chinese READMEs now document custom-app prerequisites, api/oapi examples, auto-pagination, dry-run, jq filtering, security properties, and the new Raw API service-table row.
- Raw API token retrieval path (#184) — token lookup now goes through a single app-token interface; stale auth-refresh retry helpers were removed from the raw API path.
- PAT stderr JSON classifier (#142) — recognizes
code,errorCode, anderror_code, includingPAT_NO_PERMISSION, risk-tier PAT errors,PAT_SCOPE_AUTH_REQUIRED, andAGENT_CODE_NOT_EXISTS. - Host-control metadata injection (#142) — classifier and active-retry paths now share one mutation point for
data.hostControlanddata.openBrowser, keeping host-facing JSON shapes aligned. - Open-edition routing signals (#142) — open edition pins
claw-type: openClaw;DINGTALK_AGENT,DWS_CHANNEL, and host-owned PAT detection are kept as independent signals. - Behavior authorization endpoint fallback (#142) — the PAT runtime can resolve the built-in behavior-authorization MCP endpoint before discovery data is available.
- v1.0.17 documentation backfill (#181) — the previous release notes and README service table now explicitly include the shipped Mail product, update the total to 163 commands across 14 products, and remove Mail from "Coming soon".
Fixed
- CLI auth-denial attribution — local CLI authorization denials are attributed to the channel before falling back to user-scope classification, avoiding user-scope misclassification for channel-level auth failures.
- Opaque authorization URLs (#182, #142) — PAT authorization links are preserved verbatim, including query/hash/fragment content required by the server.
- Polling compatibility (#182, #142) — device-flow result envelopes and no-
flowIddevice-code fallback remain supported, with guarded debug output and envelope priority. - Group chat @-mentions restored (#180) —
dws chat message send --group ...again accepts and forwards--at-users,--at-all, and--at-mobiles; those flags are rejected outside group-chat mode so single-chat sends cannot silently drop @-mention intent. - Explicit members-list command restored (#180) —
dws chat group members list --id <openConversationId>is reachable after the helper/dynamic merge path changed.cmdutil.MergeHardcodedLeavesnow honors higher-priority helper groups when a dynamic envelope contributes a leaf at the same path. - Skill reference command names (#186) —
simple.mdnow uses shipped OA command names (list-pending,list-initiated), removes a non-existent devdocsearch-errorcommand, and marksworkbench.mdas Draft because workbench commands are not available in the runtime. - Empty grant result handling (#142) —
dws pat chmodnow returns an explicit error instead of treating{"Content": null}as success. - Session-id log safety (#142) — raw
DWS_SESSION_ID/REWIND_SESSION_IDvalues are no longer logged when the two env vars disagree.
Tests
- Added raw API coverage for request validation, api/oapi routing, token management, pagination, response handling, dry-run output, JSON parsing, stdin handling, and command wiring. (#184)
- Added chat/cmdutil regression tests for group @-mention forwarding, single-chat rejection,
members list, helper-vs-envelope shape mismatch, and merge-priority behavior. (#180) - Added PAT contract coverage for host-owned signal selection, single-line stderr JSON, chmod env fallback and legacy alias fallback, browser policy, direct-runtime PAT endpoint fallback, and retry/poll behavior. (#142)
- Coverage badge refreshed after the post-v1.0.17 CI runs.
[1.0.17] - 2026-04-27
New Mail product surface (mailbox list, KQL message search, message get, send) brings runtime command count to 163 across 14 products. Plugin command-tree visibility hardening: stdio plugins shipping CLI overlays no longer wait on subprocess discovery to surface their commands, and overlay-registered plugin products are no longer hidden by edition VisibleProducts whitelists. Chat docs clarify that --title is required on dws chat message send.
Added
mailproduct (#167) — new top-level service for DingTalk Mail. Four leaf commands across two subgroups:dws mail mailbox list— list mailbox addresses available to the current user (list_user_mailboxes)dws mail message search— KQL search across folders / sender / date / attachments / read-state (search_emails); supports--cursorpaginationdws mail message get— fetch full message body + headers + attachments by message ID (get_email_by_message_id)dws mail message send— send email to one or more recipients (send_email)- Skill reference at
skills/references/products/mail.mdregistered inskills/SKILL.mdmaster index and intent decision tree
- Stdio plugin overlay-first command registration (#179) — when a stdio plugin's
overlay.jsondeclarestoolOverrides, command trees are built from manifest metadata synchronously at startup, no subprocessInitialize/tools/listhandshake required. Previously, slow or failing subprocesses left plugin commands invisible indws --help. Background discovery still runs to refresh the warm cache for richer flag types on subsequent startups.
Changed
hideNonDirectRuntimeCommands/visibleMCPRootCommands/visibleUtilityRootCommands(#179) — refactored to share a singleresolveVisibleProducts()helper that unions the edition'sVisibleProductshook withDirectRuntimeProductIDs(), so plugins registered viaAppendDynamicServerstay visible indws --helpeven when an edition installs a static product whitelist. Previously the hook fully replaced the dynamic registry, silently hiding plugin commands.dws chat message senddocumentation clarifies--titleis required (#174) — the helper command short text and the chat skill reference now state explicitly that--titleis mandatory for both group and single-chat sends, matching the runtime validation.buildStdioCommandsrefactored to share helpers with the overlay-first path (#179) — overlay parsing (resolveStdioOverlay) and tools→DetailTool conversion (toolsToDetails) extracted as package-level helpers; the legacy discovery-first stdio path now delegates to them, eliminating duplicated overlay JSON / cache-snapshot logic.
Fixed
- Negative-cache poisoning guard for stdio plugin discovery (#179) —
refreshStdioToolsCachenow skipsSaveToolsentirely when discovery returns an empty tool list (transient failure, subprocess not ready, RPC timeout), so a single bad refresh cannot overwrite a previously-good cache and degrade flag enrichment on the next startup.
Tests
- 6 new test cases in
internal/app/plugin_stdio_overlay_test.goandinternal/app/visibility_test.gocover overlay-first registration without discovery, warm-cache flag enrichment fromInputSchema, fallback when overlays lacktoolOverrides, the cache-poisoning guard, and integration cases for plugin visibility under restrictiveVisibleProductswhitelists. - Coverage 49.8% → 52.8%.
[1.0.16] - 2026-04-24
Discovery service abstraction with schema v3 extensions, open-edition helper-subtree restoration, and a defensive device-flow login reset.
Added
internal/discoveryservice abstraction (#156) — encapsulates market registry fetch, MCP runtime negotiation (initialize → tools/list → detailmerge), and multi-level cache fallback.EnvironmentLoadernow does cache-first startup, with degraded-mode reasons (unauthenticated/market_unreachable/runtime_all_failed) andUpdatedAt-based selective re-discovery.- Schema v3 extensions (#156) — positional parameters with typed coercion,
Exampleon--help, flagDefault/RuntimeDefault(with$currentUserId/$nowetc.),BodyWrapper,MutuallyExclusive/RequireOneOfflag groups,OmitWhen, explicitTypeoverride, and detail-schemadefaultpropagation. dws chat message senddestination-flag routing (#170) — open edition gains a hardcoded helper that dispatches by--group(→send_message_as_user) vs--user/--open-dingtalk-id(→send_direct_message_as_user), mirroring the closed-source overlay so single-chat sends finally work end-to-end.
Changed
pickCommands→cmdutil.MergeHardcodedLeaves(#169) — when a top-level product name collides between the dynamic overlay and a helper subtree, helper-only siblings are grafted into the dynamic tree instead of dropped. Restoresdws chat message send-by-bot/recall-by-bot/send-by-webhookanddws chat group members add-bot, which had silently vanished from the open edition.OverridePriority/MergeHardcodedLeavespromoted intopkg/cmdutil(#170) — single source of truth for the merge layer; hardcoded leaves can opt into overriding the dynamic envelope via a strictly higher priority.
Fixed
- Device flow defensively resets credentials before login (#157) —
--devicelogin now clears stale credential state and re-fetchesclientIDfrom the MCP server, regardless of what previous login methods (OAuth scan, PAT) left inapp.json. Fixes the case where a prior OAuth login made--devicefall back to direct mode and demandclientSecret.
[1.0.15] - 2026-04-23
Compat layer gains subcommand merging under shared parents so multiple server entries can contribute into the same dws <parent> <branch> subtree without producing duplicate --help rows. Ships with a fresh auto-generated command index doc, a README sync to 159 commands across 13 products, and a wide-ranging flag-naming cleanup that standardises CLI flags across chat, calendar, drive, minutes, contact, and devdoc commands.
Added
internal/compatsubcommand merging viaattachOrMerge— when two or more server entries attach to the same parent (e.g.parent: "chat") and theircli.commandcollides with an existing subcommand in the parent's tree, the new subcommand's children are merged recursively into the existing one instead of creating a duplicate sibling. Leaf-name collisions resolve first-wins. Fixes the "doublegroup/messagerows indws chat --help" symptom when bot capabilities are distributed acrosschat.group.membersandchat.message.docs/command-index.md— a single, English, auto-generated listing of every runtime command thedwsCLI exposes under the pre environment (159 total). Each entry carries a description and a "when to use" column aimed at AI agents. Replaces the earliercommand-index.pre.*/command-index.full.*ad-hoc snapshots.
Changed
- README Key Services table (
README.md+README_zh.md) fully synced to the shipped command surface:Chat: 20 → 23 (bot capabilities merged in; newlist-all/list-focused/list-unread-conversations/conversation-infoexposed)Calendar: 13 → 14AI Tables: 37 → 41 (chart / dashboard public-share config rows)Doc: 16 → 21 (comment subtree +file create)Minutes: 22 → 19 (single-toolrecord,list query,list-by-keyword-rangepruned)- New
Driverow (6 commands) — promoted out of "Coming soon" Workbenchrow and standaloneBotrow removed- Total revised to 159 commands across 13 products
- Quick Start expanded to 7 examples covering
doc,minutes,drivein addition tocontact,calendar,todo - Coming soon trimmed to 5:
mail,conference,aiapp,live,wiki - Reference & Docs section now leads with a pointer to the new
docs/command-index.md - Flag naming cleanup — CLI flags across chat, calendar, drive, minutes, contact, and devdoc have been standardised so the names users type match the product-skill documentation. Notable flags:
dws contact user search/dws contact dept search/dws devdoc article searchnow take--query(previously--keyword)dws chat message list/dws chat message search/dws chat message list-mentions/dws chat conversation-info/dws chat message sendnow take--groupfor the target conversation (previously--id) and--open-dingtalk-id(previously--open-id)dws chat message list-by-sendernow takes--sender-user-id/--sender-open-dingtalk-id(previously--user/--open-id)dws chat message list-topic-repliesnow takes--group/--topic-id/--limit/--time(previously--id/--topic/--size/--start)dws chat search-commonnow takes--match-mode(previously--mode)dws drive listnow takes--max/--thumbnail(previously--max-results/--with-thumbnail)dws calendar event suggestnow takes--users/--duration/--timezone(previously--attendee-user-ids/--duration-minutes/--time-zone)dws minutes list mine/dws minutes list sharednow take--max(previously--max-results) and gain--query/--start/--enddws minutes list allno longer exposes the legacy--__scope__internal alias
- Flag coverage additions —
dws calendar event create/updategain--attendees,--open-dingtalk-ids,--timezone;dws chat message sendgains file-message flags (--dentry-id,--file-name,--file-size,--file-type,--media-id,--msg-type,--space-id) plus--open-dingtalk-id/--user;dws chat message listgains--open-dingtalk-id/--user;dws aitable table deletegains--reason;dws calendar participant addgains--optional;dws todo task creategains--recurrence.
Tests
- 3 new unit tests in
internal/compat/dynamic_commands_test.go:TestBuildDynamicCommands_ParentMergeSameName— two servers with identicalcommand+parentcollapse into a single merged subcommandTestBuildDynamicCommands_ParentMergeRecursive— recursive merge through nested groups (e.g.chat.group.members)TestBuildDynamicCommands_ParentMergeLeafCollision— identical leaf paths resolve first-wins without producing duplicates
[1.0.14] - 2026-04-22
Docs-only re-tag of v1.0.13. The single commit (#153) backfills the v1.0.13 release notes after the binary was already published; no functional or CLI surface change.
[1.0.13] - 2026-04-22
IM / Messaging capability expansion: the chat (aka im) product surface grows from "group + bot messaging" into a full conversational layer — user-identity messaging, message reading & search, personal messages, topic replies, mentions, focused contacts, unread/top/common conversations, org-wide group creation, and first-class bot lifecycle.
Added
dws imalias —dws imis now registered as an alias ofdws chatfor intent clarity- User-identity messaging (
chat message send) — send group or 1-on-1 messages as the current user- Recipient selection is mutually exclusive:
--group <openConversationId>/--user <userId>/--open-dingtalk-id <openDingTalkId> - Markdown text via
--text(or positional arg), optional--title - Group-only:
--at-allto @everyone,--at-usersfor per-member @mentions - Image messages via
--media-id(obtained fromdt_media_upload)
- Recipient selection is mutually exclusive:
- Personal messages (
chat message send-personal) — sensitive personal-channel send (⚠️ destructive/dangerous op, requires confirmation) - Conversation read paths:
chat message list— pull group / 1-on-1 conversation messageschat message list-all— pull all conversations for the current user in a time rangechat message list-topic-replies— pull group topic reply threadschat message list-by-sender— messages by a specific senderchat message list-mentions— messages where the current user was @-mentionedchat message list-focused— messages from focused / starred contactschat message list-unread-conversations— unread conversation listchat message search— keyword search across conversationschat message info— conversation metadatachat list-top-conversations— pinned conversation list
- Group creation & discovery:
chat group create-org— create an organization-wide groupchat search-common— search groups shared with a nickname list (--nicks,--match-mode AND|OR, cursor-based pagination)
- Bot lifecycle:
chat bot create— create an enterprise botchat bot search-groups— search the groups a bot is present in
Changed
chatskill reference (skills/references/products/chat.md, #148) restructured into three sub-groups —group(9) /message(15) /bot(3) — with refreshed intent-routing table, workflow examples, and context-passing rules aligned withdws-service-endpoints.json(16 new group-chat tool overrides + 2 new bot tool overrides)- README Key Services sync:
Chatrow: 10 → 20 commands; subcommand tags expanded tomessagegroupsearchlist-top-conversationsBotrow: 6 → 7 commands; subcommand tags expanded withcreatesearch-groups- Total raised to 152 commands across 14 products
[1.0.12] - 2026-04-21
Product-surface expansion: first-class doc (DingTalk Docs) and minutes (AI Minutes) skill references, refreshed aitable guide aligned with the shipped binary (including dashboard / chart / export), and a README sync that brings the full command catalog to 141 commands across 14 products.
Added
docskill reference (skills/references/products/doc.md) — 16-command coverage of DingTalk Docs:- Discovery:
search,list,info,read - Authoring:
create,update,folder create - Files:
upload,download - Block-level editing: block
query,insert,update,delete - Comments:
comment list,create,reply - URL →
doc_idextraction rules and nodeId dual-format notes
- Discovery:
minutesskill reference (skills/references/products/minutes.md) — coverage of AI Minutes:- Lists: personal / shared-with-me / all-accessible
- Content: basic info, AI summary, keywords, transcription, extracted todos, batch detail
- Editing: title update
- Recording control: start, pause, resume, stop
- SKILL.md routing:
- Product overview table rows for
docandminutes - Intent decision tree routes —
钉钉文档/云文档/知识库/块级编辑/文档评论→doc;听记/AI听记/会议纪要/转写/摘要/思维导图/发言人/热词→minutes - Danger-op table entries:
doc delete,doc block delete aitabledescription completed with the附件(attachment) group
- Product overview table rows for
aitableskill enhancements:field createsingle-field mode (--name/--type/--config) with examplesbase getURL →baseIdquick-tip- Dedicated "URL → baseId 提取" chapter
- "
--filters筛选语法排错与使用规范" chapter - "相关产品" cross-link section pointing to
doc - "复杂操作" chapter (#141) — dashboard / chart workflow (with two-call sequencing and
chart share getvsdashboard share geterror semantics) and two-stageexport datapolling (scope=all/table/viewparameter constraints)
- README Key Services sync (#140):
- New rows:
doc(16 commands),minutes(22 commands — addshot-word,mind-graph,replace-text,speaker,uploadsubgroups) aitableexpanded from 20 → 37 commands; surfaceschart,dashboard,export,import,viewsubgroups- Total command count updated from 86 → 141 across 14 products
- "Coming soon" list drops
docandminutes
- New rows:
Changed
aitable record querydocs rename--keyword→--queryto match the shipped binaryaitable record querydocs clarify--sortdirection semantics (avoids misuse oforder)aitable base listguidance strengthened — "only for recent browsing; usebase searchfor lookups"; intent decision prioritizesbase searchfor base discovery
[1.0.11] - 2026-04-20
Plugin subsystem hardening: faster cold startup, cleaner lifecycle, stricter isolation, and polished UX for PAT / i18n / error routing.
Added
feat: supports claw-like products— overlay path for Claw-style embedded editionsfeat(plugin): inject user identity (UserID, CorpID) into stdio plugin subprocessesfeat(auth): improve login UX for terminal auth denial cases— clearer messaging + retry affordancefeat: PAT scope error visualization and auto-retry with authorization polling(#113)- Human-readable error output (lark-cli style) with type/message/hint/authorization command
- JSON payload also available via
--format json - Auto-retry once the user completes scope authorization
Changed
perf(plugin): serve plugin MCP tool list from disk cache on startup— hot path skips Initialize+ListTools when snapshot existsperf(plugin): parallelize all plugin discovery and tighten cold timeouts— HTTP cold budget 4s → 700ms (auth) / 500ms (plain); stdio and HTTP fan out concurrentlyperf(plugin): share cache.Store across discovery— single*cache.Storeabove the fan-out instead of per-goroutine instancesrefactor(plugin): remove default/managed plugin privileged mechanism(#124) — third-party plugins install on an equal footing viadws plugin installrefactor(plugin): purge removed plugin settings instead of merely disabling—RemovePluginnow deletesEnabledPluginsandPluginConfigsentries
Fixed
fix(transport): cap plugin MCP startup at ~4s when endpoints are unreachable(#119) — eliminates the 10sdws --helpstall caused by compounding transport timeoutsfix(plugin): stop stdio child processes on exit and before removal— no more orphaned plugin subprocessesfix(pat): avoid shared PAT command state in root registration(#129)fix: -f json 模式下错误 JSON 从 stdout 改为输出到 stderr(#133) — restores CI stderr-based failure assertionsfix(cli): localize plugin/help command strings via i18n(#118, #134) — zh locale now shows consistent Chinese--help; wraps plugin module, help command, and OAuth client-id/secret flag descriptionschore: remove workspace and bundled artifacts(#127) — clean local-only repository leftovers
[1.0.9] - 2026-04-16
Plugin system launch + execution-pipeline overhaul. This is the largest release since 1.0.0: third-party MCP servers become first-class commands, the command pipeline grows to five stages, and the edition overlay gains the hooks needed for embedded hosts.
Added
Plugin system (new)
plugincommand family:install,list,info,enable,disable,remove,create,dev,config set/get/list/unset- Plugin manifest parsing/validation, managed/user directory-based identity
- MCP server conversion and injection into the dynamic routing registry
- Pipeline hook adapter for shell-based hooks
- Stdio transport: subprocess lifecycle,
DWS_PLUGIN_ROOT/DWS_PLUGIN_DATAvariable expansion - Stdio server tools automatically registered as CLI subcommands (e.g.
dws hello greet --name Peter) - Streamable-HTTP MCP tool discovery via
registerHTTPServer - Updater: managed plugin update check on CLI startup (10 s timeout, best-effort)
dws plugin createscaffold (plugin.json, SKILL.md, hooks.json);dws plugin devsource-dir registration without copySyncSkills— copies plugin skills to agent directories on startup- Auth Token Registry: per-server HTTP headers declared in
plugin.jsonfor third-party MCP servers (e.g. Alibaba Cloud Bailian) independent from DingTalk OAuth - Persistent plugin config (
dws plugin config ...): values persisted to~/.dws/settings.json, auto-injected as env vars;${KEY}inplugin.jsonresolves without manualexport - Build lifecycle:
buildfield compiles stdio servers to native binaries at install time - Command-name conflict protection: reserved built-in names (
auth,plugin,cache, …) and plugin-vs-plugin duplicate detection - Parallel service discovery (
sync.WaitGroup) — startup reduced from sequentialN*10sto parallelmax(10s)
Core commands & diagnostics
dws doctor— one-stop environment/auth/network diagnosticsdws config list— centralized view of scattered configuration- Structured perf tracing (upgraded from debug tool to diagnostics output)
feat(skill): restore find/get for legacy skill market API—skill find,skill get;skill addstill uses aihub download
Edition / overlay hooks
edition.Hooks.SaveToken/LoadToken/DeleteToken— delegate token persistence with keychain fallbackedition.Hooks.AuthClientID/AuthClientFromMCP— overlay can override the OAuth client ID and route auth through MCP endpointsedition.Hooks.AfterPersistentPreRun— wire non-MCP clients (e.g. A2A gateway) after root setupedition.Hooks.ClassifyToolResult— custom MCP result classification before the default business-error detection- Token marker file (
token.json) for embedded hosts to detect auth state without keychain access pkg/runtimetoken.ResolveAccessTokenmirroring MCP auth resolution; MCP identity headers exported viapkg/clifor auxiliary HTTP transportsExitCoderinterface — edition-specific errors carry custom exit codesRawStderrErrorinterface — errors that bypass CLI formatting and emit raw stderr (for desktop runtimes)
Changed
- Command execution pipeline: 3 → 5 stages (
Register → PreParse → PostParse → PreRequest → PostResponse) feat(schema): return structured degraded errors instead of silent empty catalog— newCatalogDegradederror with reasonsunauthenticated/market_unreachable/runtime_all_failed; auth pre-check short-circuits doomed MCP connectionsrefactor(auth): unify auxiliary token resolution with MCP cached path— sharedresolveAccessTokenFromDir; overlays reuse the process-level token cachefeat(plugin): improve CLI overlay resolution and plugin install robustnessplugin.jsonclifield now accepts a file path (e.g."cli": "overlay.json") in addition to inline JSONdescriptionfield onCLIToolOverridefor static fallback when MCPtools/listis unavailable- Windows install uses
cmd /Cinstead ofsh -cfor build commands
Fixed
fix(plugin): harden plugin system security boundaries- Reject
file:/// local paths in git URLs; allow onlyhttps/ssh - Reject symlink entries during ZIP extraction (path-traversal defense)
build.outputmust be a relative path within the plugin directory- Reject absolute paths in stdio command declarations
- Block dangerous env var names (
PATH,LD_PRELOAD, …) from plugin config injection
- Reject
fix(plugin): schema flag params, HTTP tool discovery, and integration testsfix(plugin): skip min version check in dev mode
[1.0.8] - 2026-04-07
AITable command surface expansion, installer alignment with npm conventions, and execution-timeout hardening.
Added
- AITable static helper commands (20 commands in total) replacing dynamic routing:
base:list,search,get,create,updatetable:get,create,updatefield:get,create,updaterecord:query,create,updatetemplate:searchattachment:upload
feat(install): align skill dirs with npm and add OpenClaw— skill install paths follow npm conventions; OpenClaw added to supported agents- Label rendering optimization for AITable records (
to #73551688) - README: npm install method documented
- README: note that
dws upgraderequires v1.0.7+
Changed
perf: optimize command timeout handling, instrumentation, and diagnostics
[1.0.7] - 2026-04-02
Self-upgrade, edition overlay foundation, and fail-closed auth enforcement.
Added
dws upgrade— self-upgrade via GitHub Releases; atomic replace; cross-platform (macOS/Linux/Windows)feat: edition layer for Wukong overlay— build-time edition hook lets downstream overlays customize auth UX, config dir, static server list, visible products, and extra root commandspkg/editiondefaults +pkg/editiontestcontract testsMakefiletargetedition-test; CI jobedition-tests- Static server injection skips market discovery when configured
- Deduplicates top-level commands so overlay wins
hideNonDirectRuntimeCommandsrespects editionVisibleProducts- Gated
auth loginsubcommand + hints for embedded editions - Optional token auto-purge; edition
ConfigDiroverride
dws version— human-readable multi-line output plus JSON with edition, architecture, build, commit- Tag reporting for case suites (
to #73551688) feat(auth): unify MCP retry constant and add retry to remaining endpoints
Changed
style(auth): redesign OAuth authorization pages UI
Fixed
fix(auth): switch CLI auth check from fail-open to fail-closed- When
/cli/cliAuthEnabledis unreachable (network error/timeout/5xx), OAuth callback now routes to the permission request page instead of silently marking "enabled" - Device Flow blocks login and asks the user to verify network connectivity
CheckCLIAuthEnabledretries with backoff (3 attempts, 0s/1s/2s) to tolerate transient issues
- When
[1.0.6] - 2026-04-01
Error diagnostics overhaul, destructive-command confirmation, and credential auto-persistence.
Added
- Interactive confirmation for destructive dynamic commands — prompts before delete/remove operations unless
--yesis set - Enhanced error diagnostics
ServerDiagnosticsstruct extractstrace_id,server_error_code,technical_detail,server_retryablefrom MCP responses- Pulls diagnostics from JSON-RPC
error.data, tool call result content, and HTTP headers (X-Trace-Id,X-Request-Id,x-dingtalk-trace-id) - Three verbosity levels for
PrintHuman: Normal (trace ID + server code), Verbose (+ technical detail), Debug (+ RPC code / operation / reason) - Local logging now includes sanitized request body, response body on error, retry attempts, and classification events
TruncateBody/SanitizeArguments/RedactHeadershelpers with sensitive-key substring detection
- Auth credential persistence
feat(auth): enhance device flow with CLI auth check and admin guidancefeat(auth): persist OAuth credentials for reliable token refreshfeat(auth): persist client credentials and optimize keychain access— auto-persist--client-id/--client-secret; keychain credential cache to avoid repeated reads; enhanced logout cleansapp.json+ keychain secrets +token.json
add report helper with flexible date parsing and defaultsfeat: to #73551688 支持消息通知- README: Official App mode (recommended, direct login without creating an app) + Custom App mode; admin guide for enabling CLI access
Changed
- Getting Started simplified with inline login commands; whitelist references removed from the IMPORTANT banner
- Version bump documentation updated to v1.0.5 internal; co-creation group QR code refreshed
Fixed
fix: resolve verbosity flag lookup, FileLogger lazy binding, and business error loggingresolveVerbosityusescmd.Flags()instead ofPersistentFlags()so subcommands inherit--verbose/--debugFileLoggerlazy-binds inexecuteInvocation(afterconfigureLogLevelinit)- Business errors (HTTP 200 +
success=false) now written to the file logger for offline diagnosis
- OAuth callback race condition (write response before sending code)
import path for errors package in skill_command.go
[1.0.4] - 2026-03-30
Token-refresh reliability and onboarding clarity.
Added
feat(auth): persist client credentials for token refresh—--client-id/--client-secretare stored for automatic refresh after expiration; client secret lives in the system Keychain with a file reference- README onboarding flow rewrite with step-by-step first-time setup and more realistic examples
- Agent skill reference polish: clearer examples, updated intent routing patterns, expanded
simple.mdonboarding, cross-skill reference fixes
[1.0.3] - 2026-03-29
Filtering power, schema rendering, and a native todo command family.
Added
- Nested / array-indexed output filtering
--fieldsnow accepts dot-notation (e.g.--fields response.content) and array index access (e.g.response.items[0])- New field-path parser with recursive extraction logic
schemacommand enhancements- Table format output for human consumption
- Product-level endpoint loading in the CLI loader
- Schema-text rendering wired into the runner output pipeline
todotask helper family — staticcreate/update/done/get/deletewithpreferLegacyLeafreplacing dynamic commands- MCP tool alignment:
create_personal_todo,update_todo_task,update_todo_done_status,query_todo_detail,delete_todo - ISO-8601 due-time parsing
- Hidden title aliases and delete confirmation
- Priority field on
todohelper - Expanded zh / en i18n coverage (fixes
en.jsonspacing/wording issues)
- MCP tool alignment:
- README restructured with collapsible feature sections
[1.0.2] - 2026-03-29
Deep workspace tooling upgrade: pipeline-based input correction, output filtering, enhanced stdin handling, and multi-endpoint routing.
Added
- Pipeline engine (
internal/pipeline) for pre-parse and post-parse input correctionAliasHandler: normalises model-generated flag casing (e.g.--userId→--user-id)StickyHandler: splits glued flag values (e.g.--limit100→--limit 100)ParamNameHandler: fixes near-miss flag typos (e.g.--limt→--limit)ParamValueHandler: normalises structured parameter values after parsing
- Output filtering via
--fieldsand--jqglobal flags (internal/output/filter.go)--fields: comma-separated field selection for top-level keys (case-insensitive)--jq: jq expression filtering powered bygojqlibrary
StdinGuardfor safe single-read stdin across multiple flags in one invocationResolveInputSourceunified resolver supporting@file,@-(explicit stdin), and implicit pipe fallback@file/@-syntax support for all string-typed override flags in tool commands- Chat helper support for
@fileinput to read message content from files - Tool-level endpoint routing (
dynamicToolEndpoints) for multi-endpoint products - Comprehensive test suites for pipeline handlers, stdin guard, canonical commands, and chat input
Changed
directRuntimeEndpointnow accepts tool name for finer-grained endpoint resolutioncollectOverridesresolves@file/@-for all string-typed flagsNewRootCommandrefactored toNewRootCommandWithEnginewith optional pipeline engineschemacommand no longer hidden (visible in help output)- Default output format changed from
tabletojson
[1.0.1] - 2026-03-28
Backward-compatible feature and security update after the initial 1.0.0 release.
Added
- JSON output support for
dws auth loginanddws auth status - Cross-platform keychain-backed secure storage and migration helpers
- Atomic file write helpers to avoid partial config and download writes
- Stronger path and input validation helpers for local file operations
- Install-script coverage for local-source installs
Changed
- Improved
auth loginhelp text, hidden compatibility flags, and interactive UX - Added root-level flag suggestions for common compatibility mistakes such as
--jsonand legacy auth flags - Updated AITable upload parsing to accept nested
contentpayloads - Refreshed bundled skills metadata for the new CLI version
[1.0.0] - 2026-03-27
First public release of DingTalk Workspace CLI.
Core
- Discovery-driven CLI pipeline: Market → Discovery → IR → CLI → Transport
- MCP JSON-RPC transport with retries, auth injection, and response size limits
- Disk-based discovery cache with TTL and stale-fallback for offline resilience
- OAuth device flow authentication with PBKDF2 + AES-256-GCM encrypted token storage
- Structured output formats: JSON, table, raw
- Global flags:
--format,--verbose,--debug,--dry-run,--yes,--timeout - Exit codes with structured error payloads (category, reason, hint, actions)
Supported Services
- aitable — AI table: bases, tables, fields, records, templates
- approval — Approval processes, forms, instances
- attendance — Attendance records, shifts, statistics
- calendar — Events, participants, meeting rooms, free-busy
- chat — Bot messaging (group/batch), webhook, bot management
- contact — Users, departments, org structure
- devdoc — Open platform docs search
- ding — DING messages: send, recall
- report — Reports, templates, statistics
- todo — Task management: create, update, complete, delete
- workbench — Workbench app query
Agent Skills
- Bundled
SKILL.mdwith product reference docs, intent routing guide, error codes, and batch scripts - One-line installer for macOS / Linux / Windows
- Skills installed to
~/.agents/skills/dws(home) or./.agents/skills/dws(project)
Packaging
- Pre-built binaries for macOS (arm64/amd64), Linux (arm64/amd64), Windows (amd64)
- One-line install scripts (
install.sh,install.ps1) - Project-level skill installer (
install-skills.sh) - Shell completion: Bash, Zsh, Fish