dws

package module
v1.0.54 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

README

DingTalk Workspace CLI (dws)

dws — DingTalk Workspace on the command line, built for humans and AI agents.

DWS Product Overview

License Apache-2.0 Latest Release CI Coverage

中文版 · English · Reference · Changelog

[!IMPORTANT] Co-creation Phase: This project accesses DingTalk enterprise data and requires enterprise admin authorization. Join the DingTalk DWS co-creation group for support and updates. See Getting Started below.

dws Open Source Community DingTalk Group QR Code
Table of Contents

Why dws?

  • For humans--help for usage, --dry-run to preview requests, -f table/json/raw for output formats.
  • For AI agents — structured JSON responses + built-in Agent Skills, ready out of the box.
  • For enterprise admins — zero-trust architecture: OAuth device-flow auth + domain allowlisting + least-privilege scoping. Not a single byte can bypass authentication and audit.

Installation

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.ps1 | iex
Skill mode: mono vs multi

The installer ships skills in one of two layouts. CLI commands (dws aitable ..., dws calendar ...) are identical in both modes — only the agent-side skill layout differs.

Mode What gets installed Best for
mono (stable, default) One dws skill covering all products Cross-product workflows; single entry point
multi 🧪 EXPERIMENTAL Per-product skills (dingtalk-aitable, dingtalk-calendar, dingtalk-chat, ...) Single-product tasks; smaller context per call

🧪 multi is currently EXPERIMENTAL / preview. All product-scoped skills pass the dispatch verifier, but interface, naming and cross-skill references may change in future releases. For production / shared environments, prefer mono. File issues if you hit problems.

How to pick:

  • Quick install (one-liner above): non-interactive, installs mono.
  • TTY install (download then run): curl -O .../install.sh && bash install.sh — prompts 1) mono 2) multi (default 1).
  • Override via env: DWS_SKILL_MODE=multi curl -fsSL ... | sh.
  • Switch later: dws skill setup --mode multi (or --mode mono) — re-run any time.
Other install methods

npm (requires Node.js (npm/npx)):

npm install -g dingtalk-workspace-cli

Install the latest beta:

npm install -g dingtalk-workspace-cli@beta

Homebrew (macOS / Linux):

brew tap DingTalk-Real-AI/dingtalk-workspace-cli https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git
brew install dingtalk-workspace-cli

The Formula lives in this repository, so the first tap command must include the explicit repository URL. Afterwards, use brew upgrade dingtalk-workspace-cli normally.

Install the keg-only Homebrew beta without replacing the stable Formula:

brew install dingtalk-workspace-cli-beta
$(brew --prefix dingtalk-workspace-cli-beta)/bin/dws version

To make the beta dws the default for the current shell, prepend $(brew --prefix dingtalk-workspace-cli-beta)/bin to PATH.

Pre-built binary: download from GitHub Releases.

macOS users: If you see "cannot be opened because Apple cannot check it for malicious software", run:

xattr -d com.apple.quarantine /path/to/dws

Build from source:

git clone https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git
cd dingtalk-workspace-cli
go build -o dws ./cmd       # build to current directory
cp dws ~/.local/bin/         # install to PATH

Static endpoint data is generated from the Wukong baseline and committed in this repository under internal/syncdata, so source builds do not require a sibling data checkout.

Requires Go 1.25+. Use make package to cross-compile for all platforms (macOS / Linux / Windows x amd64 / arm64).

China mirror

For users in mainland China, the following channels avoid GitHub network issues. By default (without setting these environment variables) the installer pulls from GitHub.

1. Install script + pre-built binary (Gitee mirror):

Repository mirror: https://gitee.com/DingTalk-Real-AI/dingtalk-workspace-cli

DWS_GITEE_REPO=DingTalk-Real-AI/dingtalk-workspace-cli curl -fsSL https://gitee.com/DingTalk-Real-AI/dingtalk-workspace-cli/raw/main/scripts/install.sh | sh

With DWS_GITEE_REPO set, the installer resolves the latest version and every release asset (binary, checksums, skills) from the Gitee API instead of GitHub. If it is unset, installation defaults to GitHub.

2. npm package (npmmirror mirror):

npm install -g dingtalk-workspace-cli --registry=https://registry.npmmirror.com

npmmirror automatically syncs public packages from the public npm registry, so this works directly in China.

3. Skills only (Gitee mirror):

DWS_GITEE_REPO=DingTalk-Real-AI/dingtalk-workspace-cli curl -fsSL https://gitee.com/DingTalk-Real-AI/dingtalk-workspace-cli/raw/main/scripts/install-skills.sh | sh

With DWS_GITEE_REPO set, install-skills.sh resolves the version and skills package from Gitee; it also auto-falls back to the Gitee mirror when GitHub is unreachable.

Upgrade

Requires v1.0.7 or later. For earlier versions, please re-run the install script to upgrade.

dws has built-in self-upgrade capability. Updates are pulled directly from GitHub Releases with SHA256 integrity verification and automatic backup.

dws upgrade                    # interactive upgrade to latest version
dws upgrade --check            # check for new versions without installing
dws upgrade --list             # list stable release versions
dws upgrade --beta             # upgrade to the latest beta pre-release
dws upgrade --check --beta     # check the beta track without installing
dws upgrade --list --beta      # list beta pre-release versions
dws upgrade --version v1.0.7   # upgrade to a specific version
dws upgrade --version v1.0.8-beta.1  # upgrade to a specific beta version
dws upgrade --rollback         # rollback to the previous version
dws upgrade -y                 # skip confirmation prompt

By default, dws upgrade follows the stable release track. Use --beta only when you explicitly want the newest GitHub pre-release build.

Six-channel post-release verification

Maintainers and release validators can run the release-quality smoke checks for curl, PowerShell, npm stable, npm beta, Homebrew, and dws upgrade:

git clone https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git /tmp/dws-verify
cd /tmp/dws-verify/verify
bash verify-all-channels.sh

The verifier uses isolated directories and does not replace the dws on the current PATH. It reports PASS, FAIL, and SKIP; a platform skip is not a pass and must be covered on the matching host. See verify/README.md for the platform matrix.

How it works

The upgrade process follows a two-phase atomic flow to ensure consistency:

  1. Prepare — downloads the platform-specific binary and skill packages to a temporary directory, verifies SHA256 checksums, and extracts/validates all files. If any step fails, the upgrade aborts without modifying the existing installation.
  2. Apply — only after all preparations succeed, the binary is replaced and skill packages are installed to all detected agent directories (~/.agents/skills/dws, ~/.claude/skills/dws, ~/.cursor/skills/dws, etc.).

A backup of the current version is automatically created before each upgrade. Use dws upgrade --rollback to restore the previous version if needed.

Flag Description
--check Check for updates without installing
--list List available stable release versions with changelogs
--beta Use the beta pre-release track for upgrade, --check, or --list
--version Upgrade to a specific version (e.g. v1.0.7 or v1.0.8-beta.1)
--rollback Rollback to the previous backed-up version
--force Force reinstall even if already on the latest version
--skip-skills Skip skill package update
-y Skip confirmation prompt

Getting Started

dws auth login            # browser opens automatically
dws auth login --device   # for headless environments (Docker, SSH, CI)

Select your organization and authorize. That's it.

If your organization hasn't enabled CLI access, you'll be prompted to send an access request to your admin. Once approved, re-run dws auth login.

Organization hasn't enabled CLI access?
  1. After selecting your organization, click "Apply Now" to notify the admin
  2. The admin receives a request card and can approve with one click
  3. Once approved, re-run dws auth login

Apply for Access

Admin: Enable CLI access for your organization

Go to Developer Platform → "CLI Access Management" → Enable.

CLI Access Management

Custom App mode (CI/CD, ISV integration)

For enterprise-managed scenarios, create your own DingTalk app:

  1. Open Platform Console → Create App
  2. Security Settings → Add redirect URLs: http://127.0.0.1,https://login.dingtalk.com
  3. Publish the app
  4. Login:
dws auth login --client-id <your-app-key> --client-secret <your-app-secret>

Credentials are securely persisted after first login (Keychain). Subsequent runs auto-refresh tokens.

Multiple organizations (profiles)

dws can stay logged in to several DingTalk accounts at once, including multiple accounts in the same organization. A profile is uniquely identified by corpId:userId; the current profile decides which identity a command runs as.

dws auth login                              # add or refresh one account
dws profile list                            # list every logged-in account
dws profile switch <corpId:userId>          # persistently switch; use - to toggle back
dws profile switch "<corpName>:<userName>"  # friendly input; names must be unique
dws --profile <corpId> contact user search --query "..."        # use that org's explicitly recorded current account
dws --profile <corpId:userId> contact user search --query "..." # use one exact account without changing the default

Selectors support corpId:userId, corpId:userName, corpName:userId, and corpName:userName. Friendly names are input aliases only; use the stable profile value returned by profile list for automation. Duplicate organization or account names fail with explicit corpId:userId candidates. If an organization has multiple accounts but no recorded current account, --profile <corpId> fails instead of choosing the first or most recently used account.

currentProfile, previousProfile, and per-organization defaults are stored as exact identities. primaryProfile remains in JSON only for compatibility and is not used for selection. profile list reads status and expiry from each real identity Token without refreshing it. auth logout --profile <corpId> removes all local accounts in that organization; an exact selector or local profile name removes one account.

Cross-org reads are orchestrated by the agent rather than a built-in --all-orgs: list profiles, group by corpId, and use the unique isOrgCurrent=true account for each organization. If a multi-account organization has no default, ask the user to choose an account first. Writes default to the current account — confirm both organization and account before cross-org writes.

On macOS, an unreadable registered token slot blocks a new OAuth login rather than risking a mixed Keychain/file-DEK state. If normal terminal commands can still read the login while a sandbox using DWS_DISABLE_KEYCHAIN=1 cannot, migrate the legacy and profile auth entries without exposing tokens:

env -u DWS_DISABLE_KEYCHAIN dws auth migrate-keychain --to file-dek --dry-run --format json
env -u DWS_DISABLE_KEYCHAIN dws auth migrate-keychain --to file-dek --yes --format json
DWS_DISABLE_KEYCHAIN=1 dws auth status --format json

The migration validates every selected auth ciphertext before writing, ignores unrelated application secrets, and can be rerun after an interrupted commit. If validation identifies genuinely damaged ciphertext, remove only the affected account with dws auth logout --profile <corpId:userId>, or all accounts in one organization with --profile <corpId>, then log in again. Use dws auth reset only when you intend to discard every local profile.

Migrate auth between Linux sandboxes

Copying only ~/.dws/app.json does not carry the refresh token; access tokens expire after ~2 hours. Use the official export/import flow:

# Sandbox A (already logged in)
dws auth export -o /tmp/dws-auth.tar.gz
# Or for copy/paste: dws auth export --base64 -o /tmp/dws-auth.b64

# Sandbox B
dws auth import -i /tmp/dws-auth.tar.gz
# Or: dws auth import -i /tmp/dws-auth.b64 --base64
dws auth status   # confirm "Refresh Token: valid"

The bundle includes the encrypted keychain under ~/.local/share/dws-cli (with auth-token.enc and dek) plus required ~/.dws config files. Windows export and import are intentionally rejected before credentials or bundles are read: Windows stores credentials as DPAPI-protected HKCU Registry values, and the current file-DEK bundle has no safe DPAPI-to-portable conversion.

Quick Start

dws contact user search --query "engineering"      # search contacts
dws calendar event list                            # list today's calendar events
dws doc search --query "quarterly"                 # search DingTalk Docs
dws minutes list mine                              # list AI meeting notes I created
dws drive list                                     # list DingTalk drive files
dws todo task create --title "Quarterly report" --executors "<your-userId>"   # create a todo (replace <your-userId>)
dws todo task list --dry-run                       # preview without executing

Full command list: docs/command-index.md — all commands with descriptions and when-to-use guidance.

Using with Agents

dws is designed as an AI-native CLI. Complete Installation and Getting Started first, then configure your agent:

Agent Invocation Patterns

# Use --yes to skip confirmation prompts (required for agents)
dws todo task create --title "Review PR" --executors "<your-userId>" --yes

# Use --dry-run to preview operations (safe execution)
dws contact user search --query "engineering" --dry-run

# Use --jq to extract precisely (save tokens)
dws contact user get-self --jq '.result[0].orgEmployeeModel | {name: .orgUserName, dept: .depts[0].deptName, userId}'

Command Help and Schema

Use Cobra help and Schema for different parts of the command contract:

  • dws <path> --help is the source of truth for whether a command exists and which flags the binary accepts.
  • dws schema "<path>" is the Agent contract for command selection, parameter mappings and constraints, risk, and confirmation semantics.
  • If Help and Schema disagree, treat it as contract drift: pass only flags accepted by Cobra and use the more conservative safety semantics.
  • Schema describes commands; it does not read or search DingTalk business data. Execute the real product command after discovery.
# Confirm that the command exists and inspect accepted flags
dws aitable record query --help

# Discover within a product, then inspect the selected leaf contract
dws schema aitable
dws schema "aitable record query"

# Execute the real business query
dws aitable record query --base-id BASE_ID --table-id TABLE_ID --limit 10

dws schema --all exports the complete contract for tooling, CI, audits, and compatibility baselines. Agents should prefer product/group discovery followed by a leaf query to avoid loading the full Catalog into context.

Agent Skills

The repo ships a complete Agent Skill system under skills/, organized into two layouts:

  • skills/mono/ — single-skill layout (one SKILL.md + references/products/), recommended default.
  • skills/multi/ — per-product skills (dingtalk-aitable/, dingtalk-calendar/, dingtalk-chat/, ...), each with its own SKILL.md. 🧪 EXPERIMENTAL / preview — see banner in each multi SKILL.md for caveats.

Shared reviewed inputs for Schema generation live separately under internal/cli/schema_hints/. They are not Agent Skills and are excluded from binaries and release skill bundles.

After installing, AI tools like Claude Code / Cursor can operate DingTalk directly through natural language:

# Install skills into current project (defaults to mono)
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install-skills.sh | sh

install.sh installs to $HOME/.agents/skills/dws (global); install-skills.sh installs to ./.agents/skills/dws (current project).

China users: prefix DWS_GITEE_REPO to use the Gitee mirror — see China mirror.

Switching or re-installing with dws skill setup:

# Interactive: prompts for mode + target agents
dws skill setup

# Install mono skill to every detected agent home (claude / cursor / codex / opencode / qoder)
dws skill setup --mode mono --target all --yes

# Install multi skills to a single agent home
dws skill setup --mode multi --target cursor --yes

# Point at a local source tree (e.g. a fork or work-in-progress)
DWS_SKILL_SOURCE=/path/to/skills dws skill setup --mode multi
Flag Values Description
--mode mono | multi Skill layout; defaults to interactive prompt
--target all | claude | cursor | codex | opencode | qoder Where to install; all covers every detected agent home
--source path Local source directory (overrides bundled skills)
--yes Skip confirmation prompts

Env vars: DWS_SKILL_MODE=mono|multi (also honored by install.sh / install.ps1), DWS_SKILL_SOURCE=<path>.

What's included (mono layout):

Component Path Description
Master Skill skills/mono/SKILL.md Intent routing, decision tree, safety rules, error handling
Product references skills/mono/references/products/*.md Per-product command reference (aitable, chat, calendar, etc.)
Intent guide skills/mono/references/intent-guide.md Disambiguation for confusing scenarios (e.g. report vs todo)
Global reference skills/mono/references/global-reference.md Auth, output formats, global flags
Error codes skills/mono/references/error-codes.md Error codes + debugging workflows
Recovery guide skills/mono/references/recovery-guide.md RECOVERY_EVENT_ID handling
Ready-made scripts skills/mono/scripts/*.py 13 batch operation scripts (see below)
Ready-made scripts — 13 Python scripts for common multi-step workflows
Script Description
calendar_schedule_meeting.py Create event + add participants + find & book available meeting room
calendar_free_slot_finder.py Find common free slots across multiple people, recommend best meeting time
calendar_today_agenda.py View today/tomorrow/this week's schedule
import_records.py Batch import records from CSV/JSON into AITable
bulk_add_fields.py Batch add fields to an AITable data table
upload_attachment.py Upload attachment to AITable attachment field
todo_batch_create.py Batch create todos from JSON (with priority, due date, executors)
todo_daily_summary.py Summarize today/this week's incomplete todos
todo_overdue_check.py Scan overdue todos and output overdue list
contact_dept_members.py Search department by name and list all members
attendance_my_record.py View my attendance records for today/this week/specific date
attendance_team_shift.py Query team shift schedules and attendance statistics
report_inbox_today.py View today's received reports with details

ISV Integration: Author your own Agent Skills and orchestrate them with dws skills for cross-product workflows: ISV Skill → dws Skill → DingTalk Open Platform API (enforced auth + full audit).

Features

Personal Event Subscription — real-time DingTalk messages for event-driven agents

dws event consume subscribes as the currently logged-in user over a managed Stream WebSocket and emits each event as one NDJSON line on stdout. The public catalog currently covers messages that mention the current user, one-to-one messages with a specified user, and messages in a specified group.

The default ndjson, json, and pretty output preserves the transport envelope (type, event_type, string data, and headers) for existing scripts; compact retains its existing processor. Add --flatten to emit the stable top-level business fields used by Agent workflows. --format controls JSON serialization; --flatten controls the data structure and cannot be combined with -f raw or --debug-raw-events.

Prerequisite: run dws auth login. Personal identity is resolved from the OAuth token and cannot be supplied through command-line identity flags.

For an event-focused installation, use the official convenience installer:

curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install-event.sh | sh
# Inspect the public personal event catalog and schema
dws event list
dws event schema user_im_message_receive_o2o --flatten

# Listen for messages that mention the current user
dws event consume user_im_message_receive_at --flatten -f ndjson

# Listen for one-to-one messages with a specified user
dws event consume user_im_message_receive_o2o --user <userId> --flatten -f ndjson

# Listen by openDingtalkId (external contact, bot, or cross-organization identity)
dws event consume user_im_message_receive_o2o --open-dingtalk-id <openDingtalkId> --flatten -f ndjson

# Listen for messages in a specified group
dws event consume user_im_message_receive_group --group <openConversationId> --flatten -f ndjson

# Inspect local consumers and cancel a subscription
dws event status
dws event stop <subscribe_id>

For one-to-one and specified-sender events, use exactly one target identity: --user for an internal userId, or --open-dingtalk-id for an openDingtalkId. The CLI does not infer or convert between these identity types.

Feature Details
Managed lifecycle consume creates or reuses the personal subscription; stop cancels it and cleans local state
Shared connection Consumers for the same user share one local bus and cloud connection
Subscription isolation Normal consumers match both event type and subscribe_id
Agent-friendly output Stream events are written to stdout as NDJSON; status and diagnostics use stderr
Observability status shows remote subscriptions, the personal bus, and local consumers
Cross-platform Unix Socket on macOS/Linux, Windows Named Pipe on Windows

See skills/multi/dingtalk-event/SKILL.md for the Agent workflow and supported event parameters.

Raw API Access — call any DingTalk OpenAPI directly

dws api lets you call any DingTalk OpenAPI without an SDK. Tokens are automatically acquired and refreshed.

Prerequisite: Must login with your own app credentials (see Custom App mode). Encrypted tokens from MCP default-credential login are not supported for raw API calls.

# Login (first time only)
dws auth login --client-id <APP_KEY> --client-secret <APP_SECRET>

# === api.dingtalk.com ===

# List all enterprise apps
dws api GET /v1.0/microApp/allApps

# Search users (POST + JSON body)
dws api POST /v1.0/contact/users/search \
  --data '{"queryWord":"engineering","offset":0,"size":10}'

# === oapi.dingtalk.com ===

# Get user details (use --base-url to specify domain)
dws api POST /topapi/v2/user/get \
  --base-url https://oapi.dingtalk.com \
  --data '{"userid":"<USER_ID>"}'

# Or use the full URL directly
dws api POST https://oapi.dingtalk.com/topapi/v2/user/get \
  --data '{"userid":"<USER_ID>"}'

# === General ===
dws api GET /v1.0/microApp/allApps --page-all   # auto-paginate
dws api GET /v1.0/microApp/allApps --dry-run     # preview request
dws api GET /v1.0/microApp/allApps --jq '.agentId'  # jq filtering
Feature Details
Dual-form auto-detection Automatically selects api.dingtalk.com (header auth) or oapi.dingtalk.com (query-param auth) based on URL
Automatic token management App-level accessToken is fetched on first call, cached while valid, auto-refreshed on expiry
Domain allowlist Only api.dingtalk.com and oapi.dingtalk.com permitted — prevents token leakage
Auto-pagination --page-all iterates all pages. --page-limit caps the maximum (default 10, set to 0 for unlimited, hard cap at 500 to prevent infinite loops)
Smart Input Correction — auto-corrects common AI model parameter mistakes

Built-in pipeline engine that normalizes flag names, splits sticky arguments, and fuzzy-matches typos:

# Naming convention auto-conversion (camelCase / snake_case / UPPER -> kebab-case)
dws aitable record query --baseId BASE_ID --tableId TABLE_ID         # auto-corrected to --base-id --table-id

# Sticky argument splitting
dws contact user search --query "engineering" --timeout30           # auto-split to --timeout 30

# Fuzzy flag name matching
dws aitable record query --base-id BASE_ID --tabel-id TABLE_ID       # --tabel-id -> --table-id

# Value normalization (boolean / number / date / enum)
# "yes" -> true, "1,000" -> 1000, "2024/03/29" -> "2024-03-29", "ACTIVE" -> "active"
Agent Output dws Auto-Corrects To
--userId --user-id
--limit100 --limit 100
--tabel-id --table-id
--USER-ID --user-id
--user_name --user-name
jq Filtering & Field Selection — fine-grained output control to reduce token consumption
# Built-in jq expressions
dws aitable record query --base-id BASE_ID --table-id TABLE_ID --jq '.invocation.params'
dws schema "dev app create" --jq '.tool.required'

# Return only specific fields
dws aitable record query --base-id BASE_ID --table-id TABLE_ID --fields invocation,response
Schema Introspection — Agent command discovery and execution contracts
dws schema aitable                                      # discover product commands
dws schema "aitable record query"                       # view the selected leaf contract
dws schema "aitable record query" --jq '.tool.required' # view required fields
dws schema --all                                        # full export for CI/audit/baselines
Pipe & File Input — read flag values from files or stdin
# Read message body from a file
dws chat message send-by-bot --robot-code BOT_CODE --group GROUP_ID \
  --title "Weekly Report" --text @report.md

# Pipe content via stdin
cat report.md | dws chat message send-by-bot --robot-code BOT_CODE --group GROUP_ID \
  --title "Weekly Report"

# Read from stdin explicitly
dws chat message send-by-bot --robot-code BOT_CODE --group GROUP_ID \
  --title "Weekly Report" --text @-

Note: @ is treated as the @<path> file-injection prefix only when the next character is an ASCII path-shaped character (A-Z / a-z / 0-9 / . / / / ~ / _ / -), or @- for stdin. Chat-bot payloads like --text "@所有人 周报" or --text "@张三 看一下" pass through unchanged, so literal mentions reach the API as-is.

DingTalk bot — connect a robot to your local AI

dws dev connect bridges a DingTalk robot to a local AI CLI (Claude Code / Codex / opencode / Qoder / Gemini, or any tool via --agent-cmd): @-mention the bot in a chat and it answers using your local agent, keeping per-conversation multi-turn memory.

dws dev connect --channel auto --unified-app-id <unifiedAppId>

--unified-app-id resolves clientSecret at runtime via dev app credentials get, so the secret never appears in argv (ps / journald / shell history). The legacy --robot-client-id <id> --robot-client-secret <secret> still works but the CLI will warn you.

In-chat session commands (send the bare command as the whole message — no agent turn, no tokens):

Command Effect
/new (aliases /start, /reset) Start a fresh session; the previous one is left intact (resumable where the agent supports it)
/clear Wipe the current session — disposed through the agent's real session op (opencode issues DELETE /session/:id); channels whose agent exposes no delete primitive fall back to a reset

See docs/robot-quickstart.md for the full 4-step walkthrough (install → create robot → connect → add to a group).

Key Services

Service Command Capabilities
Contact contact Look up users, departments, labels, roster profiles and dismissals; create enterprises and enterprise accounts; invite employees
Chat / IM chat (im) Send / reply / search messages, group & member management, bot & webhook messaging, reactions, recall
Calendar calendar Events CRUD, attendees, meeting rooms, free/busy & time suggestions
Todo todo Create / list / update / complete tasks and comments
Approval oa Approve / reject / revoke / transfer; query pending / initiated / CC instances and forms
Attendance attendance Clock-in records, shifts, summaries, group rules (read-only)
Ding ding Send / recall DING messages
Report report Create / submit logs, inbox & outbox, templates, statistics
AI Tables aitable Bases / tables / records / fields / views, permissions & roles, automation, charts & dashboards, import / export
Doc doc Search / read / write docs, block-level editing, comments, permissions, media, up / download
Drive drive List / search / download, folders, upload, copy / move / rename, permissions
Minutes minutes AI meeting notes: list, summary / keywords / transcription / todos, mind map, speakers, tags
Mail mail Mailboxes, KQL search, read / send, drafts, folders, templates, contacts
Sheet sheet Online spreadsheets: worksheet & range read / write, filters, conditional format, images, CSV
Wiki wiki Knowledge bases: spaces, members, node tree, docs & files
DevDoc devdoc Search the Open Platform docs and diagnose API errors
AI Search aisearch Enterprise people search by name / dept / role / duty / supervisor / phone / job-number
Live live List my live streams
Raw API api Call any DingTalk OpenAPI directly, with managed app-level token

Full command listing with usage scenarios: docs/command-index.md. Run dws --help for the top-level tree, or dws <service> --help for any service's subcommands.

Note on chat bot: bot capabilities (send-by-bot / recall-by-bot / add-bot / send-by-webhook / bot search) are merged into the relevant chat subtrees (e.g. dws chat message send-by-bot, dws chat group members add-bot) so the agent-facing command surface stays flat and discoverable. There is no longer a separate top-level bot product.

Coming soon
  • conference (video meetings)
  • Multi-skill mode (experimental) — per-product skills under skills/multi/; opt in via dws skill setup --mode multi

Security by Design

dws treats security as a first-class architectural concern, not an afterthought. Credentials never touch disk, tokens never leave trusted domains, permissions never exceed grants, operations never escape audit — every API call must pass through DingTalk Open Platform's authentication and audit chain, no exceptions.

For Developers
Mechanism Details
Encrypted token storage PBKDF2 + AES-256-GCM encryption, keyed by device physical MAC address; cross-platform Keychain/DPAPI integration provides additional protection — tokens cannot be decrypted on another machine
Input security Path traversal protection (symlink resolution + working directory containment), CRLF injection blocking, Unicode visual spoofing filtering — prevents AI Agents from being tricked by malicious instructions
Domain allowlist DWS_TRUSTED_DOMAINS defaults to *.dingtalk.com; bearer tokens are never sent to non-allowlisted domains
HTTPS enforced All requests require TLS; HTTP only permitted for loopback during development
Dry-run preview --dry-run shows call parameters without executing, preventing accidental mutations
Zero credential persistence Client ID / Secret used in memory only — never written to config files or logs
For Enterprise Admins
Mechanism Details
OAuth device-flow auth Users must authenticate through an admin-authorized DingTalk application
Least-privilege scoping CLI can only invoke APIs granted to the application — no privilege escalation
Allowlist gating Admin confirmation required during co-creation phase; self-service approval planned
Full-chain audit Every data read/write passes through the DingTalk Open Platform API — enterprise admins can trace complete call logs in real time; no anomalous operation can hide
For ISVs
Mechanism Details
Tenant data isolation Operates under authorized app identity; cross-tenant access is impossible
Skill sandbox Agent Skills are Markdown documents (SKILL.md) — prompt descriptions only, no arbitrary code execution
Zero blind spots Every API call during ISV–dws skill orchestration is forced through DingTalk Open Platform authentication — full call chain is traceable with no bypass path

Found a vulnerability? Report via GitHub Security Advisories. See SECURITY.md.

Reference & Docs

  • Command Index — every runtime command with description and when-to-use guidance
  • Reference — environment variables, exit codes, output formats, shell completion
  • Architecture — static endpoint pipeline, command surface, transport layer
  • Open Platform App Command Routing — yulan dev app command design, MCP overlay, permission flow, and Agent routing
  • Changelog — release history and migration notes

Contributing

See CONTRIBUTING.md for build instructions, testing, and development workflow.

License

Apache-2.0

Documentation

Overview

Package dws is the module-root package. Its sole purpose is to bake the skills/ documentation tree into the binary at build time so that `dws skill setup` installs the skill version shipped with THIS binary, independent of any local checkout. See internal/app/skill_setup.go.

Index

Constants

This section is empty.

Variables

View Source
var EmbeddedSkills embed.FS

EmbeddedSkills holds only the installable mono and multi skill trees compiled into the binary. Build-only inputs such as internal/cli/schema_hints are intentionally excluded. The `all:` prefix is required so dot/underscore entries — e.g. references/best_practices/_common — are included rather than skipped.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
cmd
interface-snapshot command
interface-snapshot is an internal CI helper.
interface-snapshot is an internal CI helper.
internal
apiclient
Package apiclient provides a lightweight HTTP client for calling DingTalk OpenAPI (https://api.dingtalk.com) directly, bypassing the MCP JSON-RPC transport.
Package apiclient provides a lightweight HTTP client for calling DingTalk OpenAPI (https://api.dingtalk.com) directly, bypassing the MCP JSON-RPC transport.
app
auth
agent_code_detect.go resolves the agent_code — which agent HOST is driving dws (claudecode / qoder / cursor / vscode / openclaw / hermes / ...).
agent_code_detect.go resolves the agent_code — which agent HOST is driving dws (claudecode / qoder / cursor / vscode / openclaw / hermes / ...).
cli
cobracmd
Package cobracmd provides shared Cobra command utilities used across multiple internal packages (app, cli, compat, helpers).
Package cobracmd provides shared Cobra command utilities used across multiple internal packages (app, cli, compat, helpers).
event
Package event implements the DingTalk Stream event subscription pipeline for dws.
Package event implements the DingTalk Stream event subscription pipeline for dws.
event/bus
Package bus implements the daemon side of the dws event subsystem: one long-lived process per ClientID that holds the single cloud connection and fans out events to N local consumers over IPC.
Package bus implements the daemon side of the dws event subsystem: one long-lived process per ClientID that holds the single cloud connection and fans out events to N local consumers over IPC.
event/busctl
Package busctl glues the consume client to the bus daemon.
Package busctl glues the consume client to the bus daemon.
event/consume
Package consume implements the consumer-side process of `dws event consume`: dial the bus, send Hello, read Event frames, format them, and write them out (stdout / file / dir).
Package consume implements the consumer-side process of `dws event consume`: dial the bus, send Hello, read Event frames, format them, and write them out (stdout / file / dir).
event/dedup
Package dedup implements a fixed-capacity LRU set used by the bus to suppress duplicate events that the DingTalk Stream SDK redelivers on reconnect (see plan invariant #2).
Package dedup implements a fixed-capacity LRU set used by the bus to suppress duplicate events that the DingTalk Stream SDK redelivers on reconnect (see plan invariant #2).
event/lock
Package lock implements a cross-platform exclusive file lock primitive used by the bus daemon to enforce the "single bus per ClientID" invariant (plan invariant #3).
Package lock implements a cross-platform exclusive file lock primitive used by the bus daemon to enforce the "single bus per ClientID" invariant (plan invariant #3).
event/process
Package process provides cross-platform process-existence checks.
Package process provides cross-platform process-existence checks.
event/registry
Package registry holds two cross-cutting reference data sets used by daemon, consume, and the cobra command layer:
Package registry holds two cross-cutting reference data sets used by daemon, consume, and the cobra command layer:
event/source
Package source wraps the open-dingtalk Stream SDK and exposes a small blocking Start interface plus a connection state machine.
Package source wraps the open-dingtalk Stream SDK and exposes a small blocking Start interface plus a connection state machine.
event/transport
Package transport implements the cross-platform local IPC between the bus daemon and consume clients.
Package transport implements the cross-platform local IPC between the bus daemon and consume clients.
generator/cmd_schema_registry_smoke command
Command cmd_schema_registry_smoke emits the complete public binary-smoke vector from EffectiveCommandRegistry.
Command cmd_schema_registry_smoke emits the complete public binary-smoke vector from EffectiveCommandRegistry.
generator/outputguard
Package outputguard prevents generators from overwriting reviewed or generated inputs that participate in the same one-way build graph.
Package outputguard prevents generators from overwriting reviewed or generated inputs that participate in the same one-way build graph.
i18n
Package i18n provides lightweight internationalization for the DWS CLI.
Package i18n provides lightweight internationalization for the DWS CLI.
interfacesnapshot
Package interfacesnapshot captures and compares the public Cobra command surface without executing commands or contacting runtime services.
Package interfacesnapshot captures and compares the public Cobra command surface without executing commands or contacting runtime services.
ir
keychain
Package keychain provides cross-platform secure storage for secrets.
Package keychain provides cross-platform secure storage for secrets.
logging
Package logging provides file-based structured logging for diagnostics.
Package logging provides file-based structured logging for diagnostics.
pat
Package pat implements the "dws pat" command group for PAT (Personal Action Token) authorization management.
Package pat implements the "dws pat" command group for PAT (Personal Action Token) authorization management.
plugin
Package plugin implements the DWS CLI plugin system.
Package plugin implements the DWS CLI plugin system.
shortcut
Package shortcut provides a declarative framework for high-fidelity CLI commands (shortcuts) on top of the DingTalk MCP runtime.
Package shortcut provides a declarative framework for high-fidelity CLI commands (shortcuts) on top of the DingTalk MCP runtime.
shortcut/aitable
Package aitable provides declarative shortcuts for the DingTalk AI 表格 (aitable) service: Base / table / field / record / view / form / dashboard / chart / workflow / advanced-permission / section management.
Package aitable provides declarative shortcuts for the DingTalk AI 表格 (aitable) service: Base / table / field / record / view / form / dashboard / chart / workflow / advanced-permission / section management.
shortcut/attendance
Package attendance provides declarative shortcuts for the DingTalk attendance (考勤) service: attendance records, check results/records, approvals, shifts, schedules, class/group/rule management, statistics, settings, reports and vacation.
Package attendance provides declarative shortcuts for the DingTalk attendance (考勤) service: attendance records, check results/records, approvals, shifts, schedules, class/group/rule management, statistics, settings, reports and vacation.
shortcut/builtin
Package builtin aggregates all built-in shortcut service packages via blank imports so their init() registrations run, then re-exports the compiled cobra commands.
Package builtin aggregates all built-in shortcut service packages via blank imports so their init() registrations run, then re-exports the compiled cobra commands.
shortcut/calendar
Package calendar declares the declarative shortcut (+command) layer for the DingTalk calendar MCP product.
Package calendar declares the declarative shortcut (+command) layer for the DingTalk calendar MCP product.
shortcut/chat
Package chat provides declarative shortcuts for the DingTalk chat service (群聊 / 会话 / 消息 / 机器人).
Package chat provides declarative shortcuts for the DingTalk chat service (群聊 / 会话 / 消息 / 机器人).
shortcut/contact
Package contact provides declarative shortcuts for the DingTalk contact (通讯录) service: user / department / role / relation queries and the HR roster (花名册) lookups.
Package contact provides declarative shortcuts for the DingTalk contact (通讯录) service: user / department / role / relation queries and the HR roster (花名册) lookups.
shortcut/devapp
Package devapp declares high-fidelity shortcuts for the DingTalk open-platform developer application ("devapp") MCP service, for the apps command surface.
Package devapp declares high-fidelity shortcuts for the DingTalk open-platform developer application ("devapp") MCP service, for the apps command surface.
shortcut/ding
Package ding holds the built-in DING (钉) shortcuts.
Package ding holds the built-in DING (钉) shortcuts.
shortcut/doc
Package doc declares the high-fidelity `dws doc +<command>` shortcuts.
Package doc declares the high-fidelity `dws doc +<command>` shortcuts.
shortcut/drive
Package drive declares high-fidelity shortcuts for the DingTalk drive (钉盘) service: file/folder listing, metadata, download link, folder creation, upload credentials, search, recycle bin, internet publish and the document space proxy operations (copy/move/rename/permission/recent).
Package drive declares high-fidelity shortcuts for the DingTalk drive (钉盘) service: file/folder listing, metadata, download link, folder creation, upload credentials, search, recycle bin, internet publish and the document space proxy operations (copy/move/rename/permission/recent).
shortcut/mail
Package mail provides declarative shortcuts for the DingTalk mail (邮箱) service: mailbox / message / draft / thread / folder / tag / user / attachment / template / contact / auto-reply / rule operations.
Package mail provides declarative shortcuts for the DingTalk mail (邮箱) service: mailbox / message / draft / thread / folder / tag / user / attachment / template / contact / auto-reply / rule operations.
shortcut/minutes
Package minutes contains declarative shortcuts for DingTalk AI 听记 (minutes).
Package minutes contains declarative shortcuts for DingTalk AI 听记 (minutes).
shortcut/oa
Package oa registers declarative shortcuts for the DingTalk OA approval service, wrapping the raw MCP tools exposed by the dws oa helper.
Package oa registers declarative shortcuts for the DingTalk OA approval service, wrapping the raw MCP tools exposed by the dws oa helper.
shortcut/report
Package report declares declarative shortcuts for the DingTalk "报告/日志" (OA 周报应用) MCP tools.
Package report declares declarative shortcuts for the DingTalk "报告/日志" (OA 周报应用) MCP tools.
shortcut/sheet
Package sheet declares high-fidelity shortcuts for the DingTalk sheet MCP product.
Package sheet declares high-fidelity shortcuts for the DingTalk sheet MCP product.
shortcut/smart
Package smart holds genuine multi-step / intelligent shortcuts — commands that orchestrate several MCP calls or resolve names to IDs, so they are NOT a 1:1 wrapper over a single tool.
Package smart holds genuine multi-step / intelligent shortcuts — commands that orchestrate several MCP calls or resolve names to IDs, so they are NOT a 1:1 wrapper over a single tool.
shortcut/todo
Package todo declares high-fidelity shortcuts for the DingTalk "todo" (personal todo) MCP service.
Package todo declares high-fidelity shortcuts for the DingTalk "todo" (personal todo) MCP service.
shortcut/usage
Package usage records the SHAPE of MCP tool calls (which product/tool, which argument keys, and a redacted sample of ID/enum-like values) so that the shortcut layer can later mine high-frequency patterns and suggest distilling them into custom shortcuts (see docs/shortcut-p2-design.md).
Package usage records the SHAPE of MCP tool calls (which product/tool, which argument keys, and a redacted sample of ID/enum-like values) so that the shortcut layer can later mine high-frequency patterns and suggest distilling them into custom shortcuts (see docs/shortcut-p2-design.md).
shortcut/userdef
Package userdef loads user-defined shortcuts from ~/.dws/shortcuts/*.yaml and compiles them into the same shortcut.Shortcut model as the built-ins, so a distilled high-frequency operation behaves exactly like a native `+command`.
Package userdef loads user-defined shortcuts from ~/.dws/shortcuts/*.yaml and compiles them into the same shortcut.Shortcut model as the built-ins, so a distilled high-frequency operation behaves exactly like a native `+command`.
shortcut/wiki
Package wiki declares high-fidelity shortcuts for the DingTalk wiki (knowledge base) service: space management, member management and node management.
Package wiki declares high-fidelity shortcuts for the DingTalk wiki (knowledge base) service: space management, member management and node management.
syncdata
Package syncdata holds the wukong product registry, synced from dws-wukong.
Package syncdata holds the wukong product registry, synced from dws-wukong.
tui
upgrade
Package upgrade provides self-update functionality for the DWS CLI using GitHub Releases as the data source.
Package upgrade provides self-update functionality for the DWS CLI using GitHub Releases as the data source.
pkg
asynctask
Package asynctask 封装"提交 → 渐进式退避轮询 → (可选) 下载"模式,复用给 doc export / sheet export / aitable export 三个产品。
Package asynctask 封装"提交 → 渐进式退避轮询 → (可选) 下载"模式,复用给 doc export / sheet export / aitable export 三个产品。
authretry
Package authretry exposes the AuthRefreshRequired marker error used by edition overlays (in separate Go modules) to signal "the current access token was rejected by the server; please run a force-refresh and retry".
Package authretry exposes the AuthRefreshRequired marker error used by edition overlays (in separate Go modules) to signal "the current access token was rejected by the server; please run a force-refresh and retry".
cli
Package cli exposes public entry points for the DWS CLI so that external overlay modules can embed and launch the CLI after customising edition hooks.
Package cli exposes public entry points for the DWS CLI so that external overlay modules can embed and launch the CLI after customising edition hooks.
cmdutil
Package cmdutil provides reusable CLI helper functions for Cobra commands.
Package cmdutil provides reusable CLI helper functions for Cobra commands.
config
Package config provides shared constants used across multiple internal packages.
Package config provides shared constants used across multiple internal packages.
configmeta
Package configmeta provides a central registry of all environment-variable based configuration items used by the DWS CLI.
Package configmeta provides a central registry of all environment-variable based configuration items used by the DWS CLI.
convert
Package convert provides shared type conversion helpers used across multiple internal packages (cli, compat).
Package convert provides shared type conversion helpers used across multiple internal packages (cli, compat).
edition
Package edition provides an extension-point mechanism that allows private overlay modules (e.g.
Package edition provides an extension-point mechanism that allows private overlay modules (e.g.
editiontest
Package editiontest provides contract-test helpers that any edition.Hooks implementation (open-source or overlay) must satisfy.
Package editiontest provides contract-test helpers that any edition.Hooks implementation (open-source or overlay) must satisfy.
paging
Package paging 提供跨产品复用的"自动翻页"工具,封装"取一页 → 取下一页 cursor → 继续取"循环。
Package paging 提供跨产品复用的"自动翻页"工具,封装"取一页 → 取下一页 cursor → 继续取"循环。
runtimetoken
Package runtimetoken resolves API bearer tokens for features that bypass the MCP runner (e.g.
Package runtimetoken resolves API bearer tokens for features that bypass the MCP runner (e.g.
validate
Package validate provides input sanitization and validation functions to prevent injection attacks (control characters, CRLF, Unicode spoofing, ANSI escape sequences) at the CLI boundary.
Package validate provides input sanitization and validation functions to prevent injection attacks (control characters, CRLF, Unicode spoofing, ANSI escape sequences) at the CLI boundary.
scripts
policy/coverage-gate command
Command coverage-gate enforces non-regressing overall coverage and a strict threshold for executable statements changed by the current PR.
Command coverage-gate enforces non-regressing overall coverage and a strict threshold for executable statements changed by the current PR.
policy/interface-baseline command
Command interface-baseline snapshots and checks the backwards-compatible public Cobra surface of DWS CLI.
Command interface-baseline snapshots and checks the backwards-compatible public Cobra surface of DWS CLI.
policy/schema-compat command
Command schema-compat normalizes and checks the backwards-compatible execution contract returned by `dws schema --all --format json`.
Command schema-compat normalizes and checks the backwards-compatible execution contract returned by `dws schema --all --format json`.
policy/skill-command-check command
Command skill-command-check verifies that executable `dws ...` references in published skill Markdown resolve against the current Cobra command tree.
Command skill-command-check verifies that executable `dws ...` references in published skill Markdown resolve against the current Cobra command tree.
Package skills embeds the dws skill sources into the binary so that `dws skill setup` always installs the skill set matching the running binary version, regardless of the working directory.
Package skills embeds the dws skill sources into the binary so that `dws skill setup` always installs the skill set matching the running binary version, regardless of the working directory.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL