* chore: update coverage badge [skip ci] * chore: update coverage badge [skip ci] * chore: update coverage badge [skip ci] * chore: update coverage badge [skip ci] * chore: update coverage badge [skip ci] * 1.0.19 changelog --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
44 KiB
Changelog
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.
[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