@wangjs-jacky/ticktick-cli 0.1.0

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 (40) hide show
  1. package/.github/workflows/npm-publish.yml +26 -0
  2. package/CLAUDE.md +34 -0
  3. package/README.md +62 -0
  4. package/README_CN.md +62 -0
  5. package/bin/cli.ts +2 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +1490 -0
  8. package/dist/index.js.map +1 -0
  9. package/docs/oauth-credential-pre-validation.md +253 -0
  10. package/docs/reference/cli-usage-guide.md +587 -0
  11. package/docs/reference/dida365-open-api-zh.md +999 -0
  12. package/docs/reference/dida365-open-api.md +999 -0
  13. package/docs/reference/project-guide.md +63 -0
  14. package/docs/superpowers/plans/2026-04-03-tt-cli-auth.md +1110 -0
  15. package/docs/superpowers/specs/2026-04-03-tt-cli-design.md +142 -0
  16. package/package.json +45 -0
  17. package/skills/tt-cli-guide/SKILL.md +152 -0
  18. package/skills/tt-cli-guide/references/intent-mapping.md +169 -0
  19. package/src/api/client.ts +61 -0
  20. package/src/api/oauth.ts +146 -0
  21. package/src/api/resources.ts +291 -0
  22. package/src/commands/auth.ts +218 -0
  23. package/src/commands/project.ts +303 -0
  24. package/src/commands/task.ts +806 -0
  25. package/src/commands/user.ts +43 -0
  26. package/src/index.ts +46 -0
  27. package/src/types.ts +211 -0
  28. package/src/utils/config.ts +88 -0
  29. package/src/utils/endpoints.ts +22 -0
  30. package/src/utils/format.ts +71 -0
  31. package/src/utils/server.ts +81 -0
  32. package/tests/config.test.ts +87 -0
  33. package/tests/format.test.ts +56 -0
  34. package/tests/oauth.test.ts +42 -0
  35. package/tests/parity-fields.test.ts +89 -0
  36. package/tests/parity-map.ts +184 -0
  37. package/tests/parity.test.ts +101 -0
  38. package/tsconfig.json +22 -0
  39. package/tsup.config.ts +12 -0
  40. package/vitest.config.ts +7 -0
@@ -0,0 +1,587 @@
1
+ # tt-cli 操作手册
2
+
3
+ > tt-cli 是滴答清单(TickTick)的命令行工具,支持国内版(dida365.com)和国际版(ticktick.com)双区域。
4
+
5
+ ## 目录
6
+
7
+ - [前置准备](#前置准备)
8
+ - [认证命令](#认证命令)
9
+ - [项目命令](#项目命令)
10
+ - [任务命令](#任务命令)
11
+ - [用户命令](#用户命令)
12
+ - [配置说明](#配置说明)
13
+ - [常见问题](#常见问题)
14
+
15
+ ---
16
+
17
+ ## 前置准备
18
+
19
+ ### 1. 获取 OAuth 凭证
20
+
21
+ 在首次使用前,需要先注册应用获取 OAuth 凭证:
22
+
23
+ - 国内版:访问 [滴答清单开发者中心](https://developer.dida365.com/manage)
24
+ - 国际版:访问 [TickTick Developer Center](https://developer.ticktick.com/app)
25
+
26
+ 注册时将 **Redirect URI** 设置为 `http://localhost:3000/callback`。
27
+
28
+ ### 2. 安装
29
+
30
+ ```bash
31
+ npm install -g @wangjs-jacky/ticktick-cli
32
+ ```
33
+
34
+ ### 3. 首次登录
35
+
36
+ ```bash
37
+ tt login
38
+ ```
39
+
40
+ 登录时 CLI 会引导你输入 Client ID 和 Client Secret,然后自动打开浏览器完成 OAuth 授权。
41
+
42
+ ---
43
+
44
+ ## 认证命令
45
+
46
+ ### `tt login` — 登录
47
+
48
+ 启动 OAuth2 授权流程,打开浏览器完成登录。
49
+
50
+ ```bash
51
+ tt login
52
+ ```
53
+
54
+ **交互流程**:
55
+ 1. 检查是否已登录(已登录则提示无需重复登录)
56
+ 2. 如果凭证区域与当前区域不匹配,提示重新配置
57
+ 3. 如果未保存凭证,引导输入 Client ID 和 Client Secret
58
+ 4. 打开浏览器进行授权
59
+ 5. 授权成功后自动获取 Token 并保存
60
+
61
+ **登录失败处理**:
62
+ - 凭证无效或区域不匹配时,提供三个选项:
63
+ - 切换到另一个区域
64
+ - 重新输入当前区域的凭证
65
+ - 退出
66
+
67
+ ### `tt logout` — 登出
68
+
69
+ 清除本地保存的 Token(保留 OAuth 凭证)。
70
+
71
+ ```bash
72
+ tt logout
73
+ ```
74
+
75
+ ### `tt whoami` — 查看登录状态
76
+
77
+ 验证当前 Token 是否有效,显示剩余有效期。
78
+
79
+ ```bash
80
+ tt whoami
81
+ ```
82
+
83
+ **输出示例**:
84
+ ```
85
+ ✔ 已登录 [国内版(滴答清单)]
86
+ Token 有效期: 剩余 23 小时 45 分钟
87
+ ```
88
+
89
+ ### `tt config` — 查看/设置配置
90
+
91
+ 查看当前配置信息或切换区域。
92
+
93
+ ```bash
94
+ # 查看当前配置
95
+ tt config
96
+
97
+ # 切换区域(cn=国内版,global=国际版)
98
+ tt config --region cn
99
+ tt config --region global
100
+ ```
101
+
102
+ **查看配置输出**:
103
+ ```
104
+ 区域: 国内版(滴答清单)
105
+ Client ID: xxxxxxxx
106
+ Client Secret: xxxxxxxx********
107
+ Token: xxxxxxxx...
108
+ 过期时间: 2026/4/5 14:30:00
109
+ ```
110
+
111
+ > **注意**:切换区域会清除 Token,需要重新运行 `tt login`。
112
+
113
+ ---
114
+
115
+ ## 项目命令
116
+
117
+ ### `tt project-list` — 列出所有项目
118
+
119
+ ```bash
120
+ tt project-list
121
+ ```
122
+
123
+ **输出示例**:
124
+ ```
125
+ 工作 abc123def456
126
+ 类型: TASK 视图: list 活跃
127
+ 生活 ghi789jkl012
128
+ 类型: TASK 视图: kanban 活跃
129
+ 归档 mno345pqr678
130
+ 类型: NOTE 视图: list 已关闭
131
+ ```
132
+
133
+ ### `tt project-get <id>` — 获取项目详情
134
+
135
+ ```bash
136
+ tt project-get abc123def456
137
+ ```
138
+
139
+ **输出字段**:名称、ID、颜色、类型、视图模式、状态、分组、权限。
140
+
141
+ ### `tt project-tasks <id>` — 获取项目下的所有任务
142
+
143
+ ```bash
144
+ tt project-tasks abc123def456
145
+ ```
146
+
147
+ **输出示例**:
148
+ ```
149
+ ○ 完成周报 高
150
+ 本周五前提交
151
+ ✓ 修复登录 Bug 中
152
+ ○ 需求评审 无
153
+ ```
154
+
155
+ ### `tt project-create [name]` — 创建项目
156
+
157
+ ```bash
158
+ # 交互式输入名称
159
+ tt project-create
160
+
161
+ # 直接指定名称
162
+ tt project-create "新项目"
163
+
164
+ # 带选项创建
165
+ tt project-create "新项目" --color "#F18181" --view-mode kanban --kind TASK
166
+ ```
167
+
168
+ | 选项 | 说明 | 可选值 |
169
+ |------|------|--------|
170
+ | `--color <color>` | 项目颜色 | 如 `#F18181` |
171
+ | `--view-mode <mode>` | 视图模式 | `list` / `kanban` / `timeline` |
172
+ | `--kind <kind>` | 项目类型 | `TASK` / `NOTE` |
173
+
174
+ ### `tt project-update <id>` — 更新项目
175
+
176
+ ```bash
177
+ tt project-update abc123def456 --name "新名称"
178
+ tt project-update abc123def456 --color "#00FF88" --view-mode timeline
179
+ ```
180
+
181
+ | 选项 | 说明 |
182
+ |------|------|
183
+ | `--name <name>` | 修改项目名称 |
184
+ | `--color <color>` | 修改项目颜色 |
185
+ | `--view-mode <mode>` | 修改视图模式 |
186
+ | `--kind <kind>` | 修改项目类型 |
187
+
188
+ > 不指定任何选项会提示用法,不会发出请求。
189
+
190
+ ### `tt project-delete <id>` — 删除项目
191
+
192
+ ```bash
193
+ tt project-delete abc123def456
194
+ ```
195
+
196
+ > 会弹出确认提示,防止误删。此操作不可撤销。
197
+
198
+ ---
199
+
200
+ ## 任务命令
201
+
202
+ ### 基础操作
203
+
204
+ #### `tt task-add [title]` — 创建任务
205
+
206
+ ```bash
207
+ # 交互式创建(输入标题 + 选择项目)
208
+ tt task-add
209
+
210
+ # 直接创建
211
+ tt task-add "完成设计稿"
212
+
213
+ # 带完整参数
214
+ tt task-add "完成设计稿" \
215
+ -p abc123def456 \
216
+ --content "移动端首页设计" \
217
+ --priority 5 \
218
+ --start-date "2026-04-04T09:00:00.000Z" \
219
+ --due-date "2026-04-06T18:00:00.000Z" \
220
+ --all-day
221
+ ```
222
+
223
+ | 选项 | 说明 | 可选值 |
224
+ |------|------|--------|
225
+ | `-p, --project <id>` | 项目 ID | 不指定则交互选择 |
226
+ | `--content <text>` | 任务详细内容 | 任意文本 |
227
+ | `--priority <n>` | 优先级 | `0`(无) / `1`(低) / `3`(中) / `5`(高) |
228
+ | `--start-date <date>` | 开始日期 | ISO 8601 格式 |
229
+ | `--due-date <date>` | 截止日期 | ISO 8601 格式 |
230
+ | `--all-day` | 全天任务 | 标志位,无需值 |
231
+
232
+ #### `tt task-get <projectId> <taskId>` — 获取任务详情
233
+
234
+ ```bash
235
+ tt task-get abc123def456 task123abc456
236
+ ```
237
+
238
+ **输出字段**:标题、ID、项目、优先级、状态、全天、开始/截止时间、时区、类型、内容、标签、子任务列表。
239
+
240
+ #### `tt task-update <taskId>` — 更新任务
241
+
242
+ ```bash
243
+ tt task-update task123abc456 -p abc123def456 --title "新标题"
244
+ tt task-update task123abc456 -p abc123def456 --priority 3 --due-date "2026-04-10T18:00:00.000Z"
245
+ ```
246
+
247
+ | 选项 | 说明 |
248
+ |------|------|
249
+ | `-p, --project <id>` | 项目 ID(**必填**) |
250
+ | `--title <title>` | 修改标题 |
251
+ | `--content <text>` | 修改内容 |
252
+ | `--priority <n>` | 修改优先级 |
253
+ | `--start-date <date>` | 修改开始日期 |
254
+ | `--due-date <date>` | 修改截止日期 |
255
+
256
+ > 项目 ID 为必填参数,用于定位任务所属项目。
257
+
258
+ #### `tt task-done <projectId> <taskId>` — 完成任务
259
+
260
+ ```bash
261
+ tt task-done abc123def456 task123abc456
262
+ ```
263
+
264
+ #### `tt task-delete <projectId> <taskId>` — 删除任务
265
+
266
+ ```bash
267
+ tt task-delete abc123def456 task123abc456
268
+ ```
269
+
270
+ > 会弹出确认提示,防止误删。
271
+
272
+ #### `tt task-move <taskId>` — 移动任务到其他项目
273
+
274
+ ```bash
275
+ tt task-move task123abc456 -f abc123def456 -t xyz789ghi012
276
+ ```
277
+
278
+ | 选项 | 说明 |
279
+ |------|------|
280
+ | `-f, --from <id>` | 源项目 ID(**必填**) |
281
+ | `-t, --to <id>` | 目标项目 ID(**必填**) |
282
+
283
+ ### 查询操作
284
+
285
+ #### `tt task-list` — 筛选任务
286
+
287
+ ```bash
288
+ # 获取所有任务
289
+ tt task-list
290
+
291
+ # 按项目筛选
292
+ tt task-list -p abc123def456
293
+
294
+ # 按日期范围
295
+ tt task-list --start "2026-04-01" --end "2026-04-30"
296
+
297
+ # 按状态和优先级
298
+ tt task-list --status 0 --priority 5
299
+
300
+ # 多条件组合
301
+ tt task-list -p abc123def456 --status 0,2 --priority 1,3,5 --tag "工作,重要"
302
+ ```
303
+
304
+ | 选项 | 说明 | 可选值 |
305
+ |------|------|--------|
306
+ | `-p, --project <id>` | 按项目筛选 | 项目 ID |
307
+ | `--start <date>` | 开始日期 | ISO 8601 |
308
+ | `--end <date>` | 结束日期 | ISO 8601 |
309
+ | `--status <n>` | 按状态筛选,逗号分隔 | `0`(待办) / `2`(已完成) |
310
+ | `--priority <n>` | 按优先级筛选,逗号分隔 | `0` / `1` / `3` / `5` |
311
+ | `--tag <tag>` | 按标签筛选,逗号分隔 | 标签名称 |
312
+
313
+ #### `tt task-completed` — 查看已完成任务
314
+
315
+ ```bash
316
+ # 查看所有已完成任务
317
+ tt task-completed
318
+
319
+ # 按项目和日期范围
320
+ tt task-completed -p abc123def456 --start "2026-04-01" --end "2026-04-30"
321
+ ```
322
+
323
+ | 选项 | 说明 |
324
+ |------|------|
325
+ | `-p, --project <id>` | 按项目筛选 |
326
+ | `--start <date>` | 开始日期 |
327
+ | `--end <date>` | 结束日期 |
328
+
329
+ #### `tt task-undone` — 查看未完成任务
330
+
331
+ ```bash
332
+ # 按预设查询
333
+ tt task-undone --query today
334
+ tt task-undone --query next7day
335
+
336
+ # 按自定义日期范围
337
+ tt task-undone --start "2026-04-01" --end "2026-04-30"
338
+
339
+ # 按项目筛选
340
+ tt task-undone --query today -p abc123def456
341
+ ```
342
+
343
+ | 选项 | 说明 | 可选值 |
344
+ |------|------|--------|
345
+ | `--query <preset>` | 预设查询 | `today` / `tomorrow` / `last24hour` / `next24hour` / `last7day` / `next7day` |
346
+ | `--start <date>` | 自定义开始日期 | ISO 8601 |
347
+ | `--end <date>` | 自定义结束日期 | ISO 8601 |
348
+ | `-p, --project <id>` | 按项目筛选 | 项目 ID |
349
+
350
+ > `--query` 与 `--start/--end` 互斥,优先使用 `--query`。
351
+
352
+ #### `tt task-search <keyword>` — 搜索任务
353
+
354
+ ```bash
355
+ tt task-search "设计稿"
356
+ ```
357
+
358
+ 在任务的标题和内容中搜索关键词,匹配的关键词会高亮显示。
359
+
360
+ #### `tt task-find <taskId>` — 按 ID 查找任务
361
+
362
+ ```bash
363
+ tt task-find task123abc456
364
+ ```
365
+
366
+ 不需要提供项目 ID,直接通过任务 ID 查找(内部遍历所有任务匹配)。
367
+
368
+ ### 批量操作
369
+
370
+ #### `tt task-batch-add [jsonFile]` — 批量创建任务
371
+
372
+ ```bash
373
+ # 从文件读取
374
+ tt task-batch-add tasks.json
375
+
376
+ # 从标准输入读取
377
+ echo '[{"title":"任务1","projectId":"abc123"},{"title":"任务2","projectId":"abc123"}]' | tt task-batch-add --stdin
378
+ ```
379
+
380
+ **JSON 文件格式**(数组,每个元素为创建参数):
381
+ ```json
382
+ [
383
+ {
384
+ "title": "任务标题",
385
+ "projectId": "项目ID",
386
+ "content": "任务内容(可选)",
387
+ "priority": 5,
388
+ "startDate": "2026-04-04T09:00:00.000Z",
389
+ "dueDate": "2026-04-06T18:00:00.000Z",
390
+ "isAllDay": false
391
+ }
392
+ ]
393
+ ```
394
+
395
+ #### `tt task-batch-update [jsonFile]` — 批量更新任务
396
+
397
+ ```bash
398
+ # 从文件读取
399
+ tt task-batch-update updates.json
400
+
401
+ # 从标准输入读取
402
+ cat updates.json | tt task-batch-update --stdin
403
+ ```
404
+
405
+ **JSON 文件格式**(数组,每个元素必须包含 `id` 和 `projectId`):
406
+ ```json
407
+ [
408
+ {
409
+ "id": "任务ID",
410
+ "projectId": "项目ID",
411
+ "title": "新标题",
412
+ "priority": 3
413
+ }
414
+ ]
415
+ ```
416
+
417
+ #### `tt task-batch-done <projectId>` — 批量完成任务
418
+
419
+ ```bash
420
+ # 指定任务 ID
421
+ tt task-batch-done abc123def456 --task-ids "task1,task2,task3"
422
+
423
+ # 完成项目下所有未完成任务
424
+ tt task-batch-done abc123def456 --all
425
+
426
+ # 跳过确认提示
427
+ tt task-batch-done abc123def456 --all --force
428
+ ```
429
+
430
+ | 选项 | 说明 |
431
+ |------|------|
432
+ | `--task-ids <ids>` | 任务 ID 列表,逗号分隔 |
433
+ | `--all` | 完成项目下所有未完成任务 |
434
+ | `--force` | 跳过确认提示 |
435
+
436
+ > `--task-ids` 和 `--all` 二选一,必须指定一个。
437
+
438
+ ---
439
+
440
+ ## 用户命令
441
+
442
+ ### `tt user-pref` — 查看用户偏好
443
+
444
+ ```bash
445
+ tt user-pref
446
+ ```
447
+
448
+ **输出字段**:时区、日期格式、语言、主题。
449
+
450
+ ---
451
+
452
+ ## 配置说明
453
+
454
+ ### 配置文件位置
455
+
456
+ ```
457
+ ~/.tt-cli/config.json
458
+ ```
459
+
460
+ ### 配置文件结构
461
+
462
+ ```json
463
+ {
464
+ "oauth": {
465
+ "clientId": "xxxxxxxx",
466
+ "clientSecret": "xxxxxxxx",
467
+ "region": "cn"
468
+ },
469
+ "token": {
470
+ "accessToken": "xxxxxxxx",
471
+ "refreshToken": "xxxxxxxx",
472
+ "expiresAt": 1712345678000
473
+ },
474
+ "region": "cn"
475
+ }
476
+ ```
477
+
478
+ ### 区域系统
479
+
480
+ | 区域 | 值 | API 地址 | 开发者中心 |
481
+ |------|-----|---------|-----------|
482
+ | 国内版 | `cn` | `api.dida365.com` | `developer.dida365.com` |
483
+ | 国际版 | `global` | `api.ticktick.com` | `developer.ticktick.com` |
484
+
485
+ ### 优先级对照表
486
+
487
+ | 值 | 含义 | 显示颜色 |
488
+ |----|------|---------|
489
+ | `0` | 无优先级 | 灰色 |
490
+ | `1` | 低优先级 | 蓝色 |
491
+ | `3` | 中优先级 | 黄色 |
492
+ | `5` | 高优先级 | 红色 |
493
+
494
+ ### 任务状态对照表
495
+
496
+ | 值 | 含义 | 图标 |
497
+ |----|------|------|
498
+ | `0` | 待办 | ○ |
499
+ | `2` | 已完成 | ✓ |
500
+
501
+ ---
502
+
503
+ ## 命令速查表
504
+
505
+ ### 认证
506
+
507
+ | 命令 | 说明 |
508
+ |------|------|
509
+ | `tt login` | 登录 |
510
+ | `tt logout` | 登出 |
511
+ | `tt whoami` | 查看登录状态 |
512
+ | `tt config` | 查看配置 |
513
+ | `tt config --region cn` | 切换到国内版 |
514
+ | `tt config --region global` | 切换到国际版 |
515
+
516
+ ### 项目
517
+
518
+ | 命令 | 说明 |
519
+ |------|------|
520
+ | `tt project-list` | 列出所有项目 |
521
+ | `tt project-get <id>` | 获取项目详情 |
522
+ | `tt project-tasks <id>` | 获取项目下的任务 |
523
+ | `tt project-create "名称"` | 创建项目 |
524
+ | `tt project-update <id> --name "新名"` | 更新项目 |
525
+ | `tt project-delete <id>` | 删除项目 |
526
+
527
+ ### 任务 — 基础
528
+
529
+ | 命令 | 说明 |
530
+ |------|------|
531
+ | `tt task-add "标题" -p <项目ID>` | 创建任务 |
532
+ | `tt task-get <项目ID> <任务ID>` | 获取任务详情 |
533
+ | `tt task-update <任务ID> -p <项目ID>` | 更新任务 |
534
+ | `tt task-done <项目ID> <任务ID>` | 完成任务 |
535
+ | `tt task-delete <项目ID> <任务ID>` | 删除任务 |
536
+ | `tt task-move <任务ID> -f <源> -t <目标>` | 移动任务 |
537
+
538
+ ### 任务 — 查询
539
+
540
+ | 命令 | 说明 |
541
+ |------|------|
542
+ | `tt task-list` | 筛选任务 |
543
+ | `tt task-completed` | 查看已完成任务 |
544
+ | `tt task-undone --query today` | 今日未完成 |
545
+ | `tt task-undone --query next7day` | 未来 7 天未完成 |
546
+ | `tt task-search "关键词"` | 搜索任务 |
547
+ | `tt task-find <任务ID>` | 按 ID 查找 |
548
+
549
+ ### 任务 — 批量
550
+
551
+ | 命令 | 说明 |
552
+ |------|------|
553
+ | `tt task-batch-add tasks.json` | 批量创建 |
554
+ | `tt task-batch-update updates.json` | 批量更新 |
555
+ | `tt task-batch-done <项目ID> --all` | 批量完成 |
556
+
557
+ ### 用户
558
+
559
+ | 命令 | 说明 |
560
+ |------|------|
561
+ | `tt user-pref` | 查看用户偏好 |
562
+
563
+ ---
564
+
565
+ ## 常见问题
566
+
567
+ ### 登录时提示"凭证无效或与区域不匹配"
568
+
569
+ 1. 确认凭证是在对应区域的开发者中心注册的
570
+ 2. 使用 `tt config --region cn` 或 `tt config --region global` 切换到正确区域
571
+ 3. 重新运行 `tt login`,选择"重新输入当前区域的凭证"
572
+
573
+ ### Token 过期怎么办
574
+
575
+ tt-cli 会在发送请求前自动检查 Token 有效性,过期会自动刷新,无需手动处理。如果刷新也失败(如 refresh token 过期),重新运行 `tt login` 即可。
576
+
577
+ ### 端口 3000 被占用
578
+
579
+ 登录时会在本地启动 HTTP 服务器监听端口 3000。如果端口被占用:
580
+ - 关闭占用该端口的程序
581
+ - 或等待占用程序释放后重试
582
+
583
+ ### 命令无输出静默退出
584
+
585
+ 这通常是命令名未被正确识别。确保使用连字符格式:
586
+ - 正确:`tt task-list`、`tt project-create`
587
+ - CLI 会自动将 `tt task list` 转换为 `tt task-list`,但建议直接使用连字符格式