@backtomyfuture/exchange-cli 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +7 -7
  2. package/skills/SKILL.md +29 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backtomyfuture/exchange-cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "On-premises Exchange Server CLI for email, calendar, tasks, and contacts.",
5
5
  "bin": {
6
6
  "exchange-cli": "bin/exchange-cli.js"
@@ -14,12 +14,12 @@
14
14
  "skills/"
15
15
  ],
16
16
  "optionalDependencies": {
17
- "@backtomyfuture/exchange-cli-darwin-arm64": "0.2.2",
18
- "@backtomyfuture/exchange-cli-darwin-x64": "0.2.2",
19
- "@backtomyfuture/exchange-cli-linux-x64": "0.2.2",
20
- "@backtomyfuture/exchange-cli-linux-arm64": "0.2.2",
21
- "@backtomyfuture/exchange-cli-win32-x64": "0.2.2",
22
- "@backtomyfuture/exchange-cli-win32-ia32": "0.2.2"
17
+ "@backtomyfuture/exchange-cli-darwin-arm64": "0.2.3",
18
+ "@backtomyfuture/exchange-cli-darwin-x64": "0.2.3",
19
+ "@backtomyfuture/exchange-cli-linux-x64": "0.2.3",
20
+ "@backtomyfuture/exchange-cli-linux-arm64": "0.2.3",
21
+ "@backtomyfuture/exchange-cli-win32-x64": "0.2.3",
22
+ "@backtomyfuture/exchange-cli-win32-ia32": "0.2.3"
23
23
  },
24
24
  "engines": {
25
25
  "node": ">=14"
package/skills/SKILL.md CHANGED
@@ -36,6 +36,8 @@ exchange-cli --format text email list
36
36
  # 也支持人类习惯:
37
37
  exchange-cli email list --format text
38
38
  exchange-cli --config /path/to/config email list
39
+ # 链路追踪(Agent 推荐每次调用透传或由 CLI 自动生成):
40
+ exchange-cli --request-id 12345-uuid email list
39
41
  ```
40
42
 
41
43
  ## 授权与安全规则
@@ -48,6 +50,9 @@ exchange-cli --config /path/to/config email list
48
50
  - 带 `--attendees` 且会发邀请的 `calendar create`
49
51
  - `--notify all` 的 `calendar update` / `calendar delete`
50
52
 
53
+ 高危写操作安全预演(`--dry-run`):
54
+ 以上写命令(`email send`、`email reply`、`email forward`、`email delete`、`calendar create`、`calendar delete`、`draft send`、`draft delete`、`task delete`)均支持 `--dry-run`。`--dry-run` 不会连接 Exchange 网络,不要求 `--confirm`,返回结构化预览(如附件大小、收件人列表、正文长度、是否需要 confirm),Agent 在向用户汇报前可用 `--dry-run` 预演校验入参。
55
+
51
56
  `CONFIRMATION_REQUIRED` 只表示缺少 CLI 参数,不代表用户已经授权。不要为了让命令成功而自行补上 `--confirm`。
52
57
 
53
58
  其他写操作——创建草稿、创建无参会人的日程、更新日程、创建/更新/完成任务——没有 CLI 确认参数,但仍只能在用户明确要求后执行。
@@ -104,15 +109,15 @@ exchange-cli config show
104
109
  自动化始终使用默认 JSON;`--format text` 仅供人工阅读。
105
110
 
106
111
  ```json
107
- {"ok": true, "data": {"id": "AAMk..."}}
108
- {"ok": true, "count": 2, "data": [{"id": "A"}, {"id": "B"}]}
109
- {"ok": false, "error": "...", "code": "CONNECTION_ERROR", "retryable": true}
112
+ {"ok": true, "data": {"id": "AAMk..."}, "meta": {"request_id": "94cef4ee-...", "elapsed_ms": 12.34}}
113
+ {"ok": true, "count": 2, "data": [{"id": "A"}, {"id": "B"}], "meta": {"request_id": "..."}}
114
+ {"ok": false, "error": "...", "code": "CONNECTION_ERROR", "retryable": true, "request_id": "..."}
110
115
  ```
111
116
 
112
117
  处理规则:
113
118
 
114
- - 先判断 `ok`,再读取 `data` 或 `error`;列表数量读取 `count`。
115
- - 错误时读取 `code`、`retryable` 和可选 `details`,不要靠错误文本做控制流。
119
+ - 先判断 `ok`,再读取 `data` 或 `error`;列表数量读取 `count`;耗时与请求追踪读取 `meta.elapsed_ms` 与 `meta.request_id`。
120
+ - 错误时读取 `code`、`retryable`、`request_id` 和可选 `details`,不要靠错误文本做控制流。
116
121
  - 仅当 `retryable=true` 时做有限次数、带退避的重试。认证、配置、权限、输入、确认错误和 `WRITE_OUTCOME_UNKNOWN` 不要自动重试。
117
122
  - `NOT_FOUND` 时重新列出资源获取 ID,不要猜测 ID。
118
123
  - `CONFIG_KEY_MISSING` 或 `CONFIG_DECRYPT_FAILED` 时停止并请求用户处理;不要擅自删除或覆盖配置与密钥。
@@ -122,13 +127,15 @@ exchange-cli config show
122
127
 
123
128
  `email read MESSAGE_ID` 的 `data` 除基础邮件字段外,还会稳定返回以下详情字段:
124
129
 
125
- - `body`:按 `--body-format` 输出的正文;默认是 Markdown,`--body-format html` 时是 HTML。
126
- - `body_html`:完整原始 HTML 正文,不受 `--body-format` 影响。
127
- - `unique_body_html`:EWS 返回的本轮新增 HTML 正文;服务器未提供时为 `null`。它不能替代 `body_html`。
130
+ - `body`:按 `--body-format` 输出的正文;默认是清洗后的 Markdown,`--body-format html` 时是 HTML。
131
+ - `body_length`:正文实际字符长度。
132
+ - `body_truncated`:布尔值,是否被 `--max-body-length` 截断。
133
+ - `body_html`:完整原始 HTML 正文(默认省略以节省 Token,需传入 `--include-html` 或在 `--fields` 中指定)。
134
+ - `unique_body_html`:EWS 返回的本轮新增 HTML 正文(需传入 `--include-html` 或在 `--fields` 中指定)。
128
135
  - `conversation_id`:Exchange 会话 ID;不可用时为 `null`。
129
136
  - `internet_message_id`:邮件的 RFC Message-ID(通常带尖括号);不可用时为 `null`。
130
137
 
131
- `id` 是 EWS ItemId,不能替代 `internet_message_id`。`email list`、`email search` 与 `email watch` 仍只返回摘要,不承诺携带这些详情/会话字段。需要判断回复或转发的本轮变化时,先用 `email read` 获取 `unique_body_html`;其为 `null` 时再由调用方基于 `body_html` 做正文分界兜底。
138
+ `id` 是 EWS ItemId,不能替代 `internet_message_id`。`email list`、`email search` 与 `email watch` 仍只返回摘要,不承诺携带这些详情/会话字段。需要判断回复或转发的本轮变化时,使用 `email read --include-html` 获取 `unique_body_html`;其为 `null` 时再由调用方基于 `body_html` 做正文分界兜底。
132
139
 
133
140
  ## 命令地图
134
141
 
@@ -148,7 +155,8 @@ exchange-cli config show
148
155
 
149
156
  - 邮件 `--folder` 接受 `inbox`、`sent`、`drafts`、`trash`、`junk`,也可以是文件夹路径或文件夹 ID。
150
157
  - 邮件、草稿、日历、任务和联系人的 `--limit` 范围为 `1..200`。列表结果带 `truncated`。
151
- - `email watch --backfill-minutes` 范围为 `1..1440`;可用 `--duration` `--max-events` 停止。
158
+ - `email watch` 必须传 `--duration <seconds>`(范围 `1..86400`)或 `--forever`,杜绝 Agent 子进程挂死;`--backfill-minutes` 范围为 `1..1440`。
159
+ - `email search` 支持关键字 `query`、`--from` 发件人、`--has-attachments` 仅含附件,以及 RFC 3339(如 `2026-09-12T10:00:00Z`)或 `YYYY-MM-DD` 格式的 `--start`/`--end`(EWS 底层不支持对收件人列表字段的检索过滤)。
152
160
  - `calendar update` 和 `task update` 至少提供一个更新字段。
153
161
  - `email send`、`email reply`、`draft create` 至少提供 `--body` 或 `--body-file`;同时提供时 `--body-file` 优先。
154
162
  - 任务状态使用 Exchange 标准值:`NotStarted`、`InProgress`、`Completed`、`WaitingOnOthers`、`Deferred`。`--status` 在客户端筛选。
@@ -167,6 +175,8 @@ exchange-cli config show
167
175
  ```bash
168
176
  exchange-cli email list --folder inbox --unread --limit 20
169
177
  exchange-cli email read MESSAGE_ID
178
+ exchange-cli email read MESSAGE_ID --max-body-length 1000
179
+ exchange-cli email read MESSAGE_ID --include-html
170
180
  exchange-cli email read MESSAGE_ID --fields id,subject,body
171
181
  exchange-cli email read MESSAGE_ID --body-format html
172
182
  exchange-cli email read MESSAGE_ID --save-attachments ./downloads
@@ -180,11 +190,16 @@ exchange-cli email delete MESSAGE_ID --permanent --confirm
180
190
 
181
191
  ```bash
182
192
  exchange-cli email search "关键词" --folder inbox --start "YYYY-MM-DD" --end "YYYY-MM-DD"
193
+ # 多维度精准搜索与 RFC 3339 时区支持:
194
+ exchange-cli email search "发票" --from "finance@example.com" --has-attachments --start "2026-09-01T00:00:00Z"
183
195
  ```
184
196
 
185
- 发送、回复和转发;执行前先完成用户确认:
197
+ 发送、回复和转发;执行前先完成用户确认(或先用 `--dry-run` 预演):
186
198
 
187
199
  ```bash
200
+ # 安全预演(不发网络请求,免 confirm):
201
+ exchange-cli email send --to "user@example.com" --subject "主题" --body "正文" --dry-run
202
+ # 获得用户明确授权后正式发送:
188
203
  exchange-cli email send --to "user@example.com" --subject "主题" --body-file ./body.txt --confirm
189
204
  exchange-cli email reply MESSAGE_ID --body "回复内容" --all --confirm
190
205
  exchange-cli email forward MESSAGE_ID --to "user@example.com" --body "补充说明" --confirm
@@ -194,6 +209,7 @@ exchange-cli email forward MESSAGE_ID --to "user@example.com" --body "补充说
194
209
 
195
210
  ```bash
196
211
  exchange-cli draft create --to "user@example.com" --subject "主题" --body "正文"
212
+ exchange-cli draft send DRAFT_ID --dry-run
197
213
  exchange-cli draft send DRAFT_ID --confirm
198
214
  ```
199
215
 
@@ -219,7 +235,8 @@ exchange-cli contact search "张三" --limit 20
219
235
  ## 实时监听
220
236
 
221
237
  ```bash
222
- exchange-cli email watch --folder inbox --backfill-minutes 10 --duration 60 --max-events 20
238
+ # Agent 必须指定 --duration --forever,避免子进程无响应死锁:
239
+ exchange-cli email watch --folder inbox --duration 60 --max-events 20
223
240
  ```
224
241
 
225
242
  输出是 NDJSON,每行仍使用 `{"ok": true, "data": ...}` 外层。不要把所有 `ok=true` 都当成新邮件,应检查 `data.event_type`: