@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,142 @@
1
+ # tt-cli 设计文档
2
+
3
+ > 滴答清单(TickTick)命令行工具,TypeScript 实现
4
+
5
+ ## 项目信息
6
+
7
+ | 项 | 值 |
8
+ |---|---|
9
+ | 项目名 | `tt-cli` |
10
+ | npm 包名 | `@wangjs-jacky/tt-cli` |
11
+ | CLI 命令 | `tt` |
12
+ | 仓库 | `/Users/jiashengwang/jacky-github/tt-cli` |
13
+ | GitHub | `https://github.com/wangjs-jacky/tt-cli` |
14
+
15
+ ## 技术栈
16
+
17
+ | 包 | 用途 |
18
+ |---|------|
19
+ | `cac` | CLI 命令框架 |
20
+ | `@clack/prompts` | 终端交互 UI |
21
+ | `picocolors` | 终端颜色 |
22
+ | `tsup` | 构建打包 |
23
+ | `open` | 打开浏览器 |
24
+ | `conf` | 跨平台配置存储(基于 XDG) |
25
+
26
+ ## 项目结构
27
+
28
+ ```
29
+ tt-cli/
30
+ ├── src/
31
+ │ ├── index.ts # 入口,cac 命令注册
32
+ │ ├── commands/
33
+ │ │ └── auth.ts # tt login / tt logout
34
+ │ ├── api/
35
+ │ │ ├── client.ts # HTTP 客户端,自动附带 token
36
+ │ │ └── oauth.ts # OAuth2 流程(本地回调服务器)
37
+ │ ├── utils/
38
+ │ │ ├── config.ts # token 存储管理 (~/.tt-cli/config.json)
39
+ │ │ ├── server.ts # 临时本地回调服务器
40
+ │ │ └── open.ts # 打开浏览器
41
+ │ └── types.ts # TypeScript 类型定义
42
+ ├── bin/
43
+ │ └── cli.ts # #!/usr/bin/env node 入口
44
+ ├── package.json
45
+ ├── tsconfig.json
46
+ ├── tsup.config.ts
47
+ └── README.md
48
+ ```
49
+
50
+ ## Token 存储
51
+
52
+ 位置:`~/.tt-cli/config.json`
53
+
54
+ ```json
55
+ {
56
+ "accessToken": "...",
57
+ "refreshToken": "...",
58
+ "expiresAt": 1712121600000,
59
+ "clientId": "...",
60
+ "clientSecret": "..."
61
+ }
62
+ ```
63
+
64
+ ## OAuth2 认证流程
65
+
66
+ ### tt login
67
+
68
+ 1. 检测 `~/.tt-cli/config.json` 是否有有效 token
69
+ 2. 首次使用:提示输入 Client ID + Client Secret
70
+ 3. 启动本地服务器 `http://localhost:{随机端口}/callback`
71
+ 4. 生成 state(防 CSRF),拼接授权 URL
72
+ 5. 自动打开浏览器 → 用户登录并授权
73
+ 6. TickTick 重定向到 `localhost/callback?code=xxx&state=yyy`
74
+ 7. 本地服务器捕获 code,验证 state
75
+ 8. `POST https://ticktick.com/oauth/token` 换取 access_token(Authorization: Basic base64(clientId:clientSecret))
76
+ 9. 保存 token 到 config.json
77
+ 10. 终端显示登录成功,关闭本地服务器
78
+
79
+ ### Token 刷新(自动)
80
+
81
+ 1. API 调用前检查 expiresAt
82
+ 2. 即将过期时自动 `POST https://ticktick.com/oauth/token`,grant_type=refresh_token
83
+ 3. 更新 config.json 中的 token
84
+
85
+ ### tt logout
86
+
87
+ 删除 config.json 中的 token 数据。
88
+
89
+ ## CLI 命令(鉴权阶段)
90
+
91
+ ```bash
92
+ tt login # OAuth2 登录,获取 token
93
+ tt logout # 登出,清除 token
94
+ tt whoami # 显示当前登录状态和用户信息
95
+ tt config # 查看/设置 Client ID 和 Client Secret
96
+ ```
97
+
98
+ ### tt login 交互流程
99
+
100
+ ```
101
+ ◈ 滴答清单 CLI 登录
102
+
103
+ ◇ 尚未配置 OAuth 凭证
104
+ │ 首次使用需要注册 TickTick 开发者应用
105
+ │ 请访问 https://developer.ticktick.com/app 注册
106
+ │ Redirect URI 设置为: http://localhost:3000/callback
107
+
108
+ ◇ 请输入 Client ID: ________
109
+ ◇ 请输入 Client Secret: ________
110
+
111
+ ◆ 正在打开浏览器进行授权...
112
+ │ 如果浏览器没有自动打开,请访问:
113
+ │ https://ticktick.com/oauth/authorize?...
114
+
115
+ ✔ 登录成功!欢迎, <用户名>
116
+ ```
117
+
118
+ ### tt whoami 输出
119
+
120
+ ```
121
+ ✔ 已登录
122
+ 用户: jacky
123
+ Token 有效期: 2026-04-03 18:30 (剩余 6 小时)
124
+ ```
125
+
126
+ ## TickTick OAuth2 关键参数
127
+
128
+ | 参数 | 值 |
129
+ |---|---|
130
+ | 授权 URL | `https://ticktick.com/oauth/authorize` |
131
+ | Token URL | `https://ticktick.com/oauth/token` |
132
+ | API Base | `https://api.ticktick.com/open/v1/` |
133
+ | Scopes | `tasks:read tasks:write` |
134
+ | Redirect URI | `http://localhost:{port}/callback` |
135
+
136
+ ## 后续阶段(本次不实现)
137
+
138
+ - `tt tasks` — 查看今日/明日任务
139
+ - `tt add` — 创建任务
140
+ - `tt done` — 完成任务
141
+ - `tt projects` — 查看项目清单
142
+ - `tt review` — 日程复盘
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@wangjs-jacky/ticktick-cli",
3
+ "version": "0.1.0",
4
+ "description": "滴答清单(TickTick)命令行工具",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "tt": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsup",
12
+ "dev": "tsup --watch",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "ticktick",
19
+ "dida",
20
+ "cli",
21
+ "todo",
22
+ "task"
23
+ ],
24
+ "author": "wangjs-jacky",
25
+ "license": "MIT",
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/wangjs-jacky/tt-cli.git"
32
+ },
33
+ "dependencies": {
34
+ "@clack/prompts": "^1.2.0",
35
+ "cac": "^7.0.0",
36
+ "open": "^11.0.0",
37
+ "picocolors": "^1.1.1"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^25.5.0",
41
+ "tsup": "^8.5.1",
42
+ "typescript": "^6.0.2",
43
+ "vitest": "^4.1.2"
44
+ }
45
+ }
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: tt-cli-guide
3
+ description: "滴答清单(TickTick)CLI 使用助手 — 将自然语言意图自动映射为 tt 命令并执行"
4
+ ---
5
+
6
+ <role>
7
+ 你是 tt-cli(滴答清单命令行工具)的使用助手。将用户的自然语言请求翻译为正确的 `tt` 命令并执行,返回清晰的结果。
8
+ </role>
9
+
10
+ <purpose>
11
+ 当用户用自然语言表达任务管理需求时,自动解析意图、补全参数、构建并执行对应的 tt-cli 命令。
12
+ </purpose>
13
+
14
+ <trigger>
15
+ ```
16
+ 帮我查看任务 / 今天的任务 / 明天要做什么
17
+ 创建任务 / 新建任务 / 添加任务
18
+ 完成 / 删除 / 修改任务
19
+ 查看项目 / 创建项目
20
+ tt / 滴答清单 / ticktick / todo
21
+ 任务管理 / 待办事项
22
+ ```
23
+ </trigger>
24
+
25
+ <yolo:config>
26
+ <yolo:mode>auto-advance</yolo:mode>
27
+ <yolo:safety-gates>
28
+ <gate>删除任务(tt task-delete)</gate>
29
+ <gate>删除项目(tt project-delete)</gate>
30
+ <gate>批量完成全部任务(tt task-batch-done --all)</gate>
31
+ <gate>批量完成带 --force 跳过确认</gate>
32
+ <gate>认证变更(tt login / logout / config --region)</gate>
33
+ </yolo:safety-gates>
34
+ </yolo:config>
35
+
36
+ <gsd:workflow>
37
+ <gsd:meta>
38
+ <name>tt-cli-guide</name>
39
+ <trigger>任务管理、待办、tt 命令、滴答清单</trigger>
40
+ <requires>Bash</requires>
41
+ <checkpoints>
42
+ <checkpoint order="1">登录状态已验证</checkpoint>
43
+ <checkpoint order="2">意图已解析,参数已补全</checkpoint>
44
+ <checkpoint order="3">安全门操作已确认</checkpoint>
45
+ </checkpoints>
46
+ <constraints>
47
+ <constraint>所有相对日期必须转为绝对日期(YYYY-MM-DD)再传入命令</constraint>
48
+ <constraint>安全门操作必须等待用户确认后才执行</constraint>
49
+ <constraint>用户说项目名称时,先 tt project-list 查找 ID</constraint>
50
+ <constraint>用户只说任务名称时,先 tt task-search 查找 projectId 和 taskId</constraint>
51
+ <constraint>YOLO 模式下安全门操作仍需人工确认</constraint>
52
+ </constraints>
53
+ </gsd:meta>
54
+
55
+ <gsd:goal>将用户的自然语言任务管理请求准确映射为 tt-cli 命令,执行并返回结果</gsd:goal>
56
+
57
+ <gsd:phase name="preflight" order="1">
58
+ <gsd:step>运行 tt whoami 验证登录状态</gsd:step>
59
+ <gsd:checkpoint>已登录且 Token 有效,否则引导 tt login</gsd:checkpoint>
60
+ </gsd:phase>
61
+
62
+ <gsd:phase name="parse" order="2">
63
+ <gsd:step>从用户输入中提取:操作类型、标题、日期、项目名、优先级</gsd:step>
64
+ <gsd:step>将相对日期(今天/昨天/这周等)转换为绝对日期</gsd:step>
65
+ <gsd:step>将项目名称解析为 projectId(需要时查 tt project-list)</gsd:step>
66
+ <gsd:step>将任务名称解析为 taskId + projectId(需要时查 tt task-search)</gsd:step>
67
+ <gsd:checkpoint>所有必需参数已就绪</gsd:checkpoint>
68
+ </gsd:phase>
69
+
70
+ <gsd:phase name="execute" order="3">
71
+ <gsd:step>根据意图映射表构建完整命令</gsd:step>
72
+ <gsd:step>安全门操作暂停等待用户确认</gsd:step>
73
+ <gsd:step>执行命令</gsd:step>
74
+ </gsd:phase>
75
+
76
+ <gsd:phase name="verify" order="4">
77
+ <gsd:step>检查命令执行结果</gsd:step>
78
+ <gsd:step>以清晰格式呈现给用户</gsd:step>
79
+ <gsd:step>建议可跟进的操作</gsd:step>
80
+ </gsd:phase>
81
+ </gsd:workflow>
82
+
83
+ # tt-cli 使用助手
84
+
85
+ > YOLO 模式 — 自动推进查询和创建操作。删除和批量操作会暂停确认。
86
+
87
+ ## 执行流程
88
+
89
+ ### Phase 1: 预检
90
+
91
+ **目标**:确认登录状态有效
92
+
93
+ **步骤**:
94
+ 1. 运行 `tt whoami`
95
+ 2. 未登录 → 提示 `tt login` 并停止
96
+ 3. 已登录 → 继续
97
+
98
+ ### Phase 2: 解析意图
99
+
100
+ **目标**:从自然语言中提取所有必需参数
101
+
102
+ **步骤**:
103
+ 1. **识别操作类型**:查询 / 创建 / 更新 / 完成 / 删除 / 项目管理 / 认证
104
+ 2. **转换日期**:参考 `references/intent-mapping.md` 日期转换规则,将相对日期转为 `YYYY-MM-DD`
105
+ 3. **解析项目**:用户说了项目名称 → `tt project-list` 查找对应 ID
106
+ 4. **解析任务**:用户只说了任务名称 → `tt task-search "关键词"` 获取 taskId 和 projectId
107
+ 5. **映射优先级**:紧急/重要→5,一般→3,不急→1
108
+
109
+ ### Phase 3: 执行命令
110
+
111
+ **目标**:构建并执行 tt 命令
112
+
113
+ **步骤**:
114
+ 1. 根据 `references/intent-mapping.md` 意图映射表构建命令
115
+ 2. 安全门检查(删除、批量 --all、认证变更)→ 暂停等用户确认
116
+ 3. 执行命令
117
+
118
+ ### Phase 4: 验证与呈现
119
+
120
+ **目标**:清晰展示结果并建议后续操作
121
+
122
+ **步骤**:
123
+ 1. 检查命令输出,格式化呈现
124
+ 2. 根据结果建议可跟进操作(如:查到任务后建议完成/修改)
125
+
126
+ ## 快速意图识别
127
+
128
+ | 关键词 | 操作 | 命令 |
129
+ |--------|------|------|
130
+ | 查看/看看/有什么/列出 | 查询 | `tt task-undone` / `tt task-list` / `tt task-search` |
131
+ | 创建/新建/添加/安排 | 创建 | `tt task-add` |
132
+ | 修改/更新/改 | 更新 | `tt task-update` |
133
+ | 完成/做完/勾掉 | 完成 | `tt task-done` |
134
+ | 删除/移除 | 删除 | `tt task-delete` |
135
+ | 搜索/找一下 | 搜索 | `tt task-search` |
136
+ | 项目/清单 | 项目 | `tt project-*` |
137
+ | 登录/登出/配置 | 认证 | `tt login` / `tt logout` / `tt config` |
138
+
139
+ ## 错误处理
140
+
141
+ | 场景 | 处理 |
142
+ |------|------|
143
+ | 未登录 | 提示 `tt login` |
144
+ | 找不到项目 | 列出所有项目供选择 |
145
+ | 找不到任务 | 建议 `tt task-search "关键词"` |
146
+ | Token 过期 | 提示 `tt login` |
147
+ | 命令失败 | 展示错误,分析原因,给修复建议 |
148
+
149
+ ## 详细参考
150
+
151
+ - 意图映射表、日期规则、Prompt 模板 → [references/intent-mapping.md](references/intent-mapping.md)
152
+ - CLI 完整命令文档 → [docs/Reference/cli-usage-guide.md](../../docs/Reference/cli-usage-guide.md)
@@ -0,0 +1,169 @@
1
+ # tt-cli 意图映射参考表
2
+
3
+ > 本文件为 `tt-cli-guide` skill 的详细参考,包含所有自然语言到命令的映射关系。
4
+
5
+ ## 日期转换规则
6
+
7
+ **所有相对日期必须先转换为绝对日期(格式 `YYYY-MM-DD`)**,用 JavaScript `new Date()` 获取当前日期计算。
8
+
9
+ | 用户说法 | 转换规则 | 示例(假设今天是 2026-04-04) |
10
+ |----------|----------|------|
11
+ | 今天 | 当天日期 | `2026-04-04` |
12
+ | 昨天 | 当天 -1 | `2026-04-03` |
13
+ | 前天 | 当天 -2 | `2026-04-02` |
14
+ | 明天 | 当天 +1 | `2026-04-05` |
15
+ | 后天 | 当天 +2 | `2026-04-06` |
16
+ | 这周 | 本周一 ~ 本周日 | `2026-03-30` ~ `2026-04-05` |
17
+ | 上周 | 上周一 ~ 上周日 | `2026-03-23` ~ `2026-03-29` |
18
+ | 下周 | 下周一 ~ 下周日 | `2026-04-06` ~ `2026-04-12` |
19
+ | 本月 | 本月1日 ~ 月末 | `2026-04-01` ~ `2026-04-30` |
20
+ | 上月 | 上月1日 ~ 上月末 | `2026-03-01` ~ `2026-03-31` |
21
+
22
+ ### 日期预设快捷值
23
+
24
+ `tt task-undone --query` 支持以下预设(无需计算日期):
25
+
26
+ | 预设值 | 含义 |
27
+ |--------|------|
28
+ | `today` | 今天 |
29
+ | `tomorrow` | 明天 |
30
+ | `last24hour` | 过去 24 小时 |
31
+ | `next24hour` | 未来 24 小时 |
32
+ | `last7day` | 过去 7 天 |
33
+ | `next7day` | 未来 7 天 |
34
+
35
+ > `--query` 与 `--start/--end` 互斥,优先使用 `--query`。
36
+
37
+ ---
38
+
39
+ ## 意图映射表
40
+
41
+ ### 查询任务
42
+
43
+ | 用户意图 | 命令 | 说明 |
44
+ |----------|------|------|
45
+ | 查看今天的任务 | `tt task-undone --query today` | 今日未完成 |
46
+ | 查看明天的任务 | `tt task-undone --query tomorrow` | 明日未完成 |
47
+ | 未来一周的任务 | `tt task-undone --query next7day` | 未来 7 天 |
48
+ | 过去一周的任务 | `tt task-undone --query last7day` | 过去 7 天 |
49
+ | 查看昨天的任务 | `tt task-undone --start "YYYY-MM-DD" --end "YYYY-MM-DD"` | 需计算日期 |
50
+ | 查看前天的任务 | `tt task-undone --start "YYYY-MM-DD" --end "YYYY-MM-DD"` | 需计算日期 |
51
+ | 查看某天的任务 | `tt task-undone --start "日期" --end "日期"` | 日期范围查询 |
52
+ | 查看已完成任务 | `tt task-completed` | 默认所有 |
53
+ | 某段时间完成的任务 | `tt task-completed --start "开始" --end "结束"` | 带日期范围 |
54
+ | 所有未完成任务 | `tt task-list --status 0` | 全部待办 |
55
+ | 高优先级任务 | `tt task-list --status 0 --priority 5` | 高优先级待办 |
56
+ | 按关键词搜索 | `tt task-search "关键词"` | 模糊搜索标题和内容 |
57
+ | 某项目的任务 | `tt project-tasks <projectId>` | 需先知道项目 ID |
58
+ | 任务详情 | `tt task-find <taskId>` | 按 ID 查找 |
59
+
60
+ ### 创建任务
61
+
62
+ | 用户意图 | 命令模板 |
63
+ |----------|----------|
64
+ | 创建任务(只说标题) | `tt task-add "标题"` |
65
+ | 创建到指定项目 | `tt task-add "标题" -p <projectId>` |
66
+ | 高优先级任务 | `tt task-add "标题" --priority 5` |
67
+ | 带截止日期 | `tt task-add "标题" --due-date "YYYY-MM-DDTHH:mm:ss.000Z"` |
68
+ | 全天任务 | `tt task-add "标题" --all-day` |
69
+ | 带详细内容 | `tt task-add "标题" --content "详细说明"` |
70
+ | 完整创建 | `tt task-add "标题" -p <projectId> --priority 3 --start-date "..." --due-date "..."` |
71
+
72
+ **创建规则**:
73
+ - 用户没指定项目 → 不加 `-p`,让 CLI 交互选择
74
+ - 用户说了项目名称(非 ID)→ 先 `tt project-list` 查找 ID
75
+ - 用户说了项目 ID → 直接使用
76
+
77
+ ### 更新任务
78
+
79
+ | 用户意图 | 命令模板 |
80
+ |----------|----------|
81
+ | 修改标题 | `tt task-update <taskId> -p <projectId> --title "新标题"` |
82
+ | 修改优先级 | `tt task-update <taskId> -p <projectId> --priority 3` |
83
+ | 修改截止日期 | `tt task-update <taskId> -p <projectId> --due-date "..."` |
84
+ | 修改内容 | `tt task-update <taskId> -p <projectId> --content "新内容"` |
85
+
86
+ **更新规则**:如果用户只提供了任务名称,先用 `tt task-search` 查找,获取 `projectId` 和 `taskId`。
87
+
88
+ ### 完成和删除
89
+
90
+ | 用户意图 | 命令模板 | 风险等级 |
91
+ |----------|----------|----------|
92
+ | 完成任务 | `tt task-done <projectId> <taskId>` | 低 |
93
+ | 删除任务 | `tt task-delete <projectId> <taskId>` | **高** |
94
+ | 批量完成(指定) | `tt task-batch-done <projectId> --task-ids "id1,id2,id3"` | 中 |
95
+ | 批量完成(全部) | `tt task-batch-done <projectId> --all` | **高** |
96
+
97
+ ### 项目管理
98
+
99
+ | 用户意图 | 命令模板 |
100
+ |----------|----------|
101
+ | 查看所有项目 | `tt project-list` |
102
+ | 查看项目详情 | `tt project-get <projectId>` |
103
+ | 创建项目 | `tt project-create "项目名"` |
104
+ | 修改项目名称 | `tt project-update <projectId> --name "新名称"` |
105
+ | 删除项目 | `tt project-delete <projectId>` | **高** |
106
+
107
+ ### 认证和配置
108
+
109
+ | 用户意图 | 命令模板 |
110
+ |----------|----------|
111
+ | 登录 | `tt login` |
112
+ | 登出 | `tt logout` |
113
+ | 查看登录状态 | `tt whoami` |
114
+ | 查看配置 | `tt config` |
115
+ | 切换到国内版 | `tt config --region cn` |
116
+ | 切换到国际版 | `tt config --region global` |
117
+ | 查看用户偏好 | `tt user-pref` |
118
+
119
+ ---
120
+
121
+ ## 优先级映射
122
+
123
+ | 值 | 含义 | 触发词 |
124
+ |----|------|--------|
125
+ | `0` | 无优先级 | (默认) |
126
+ | `1` | 低优先级 | "低优先级"、"不急" |
127
+ | `3` | 中优先级 | "中优先级"、"一般" |
128
+ | `5` | 高优先级 | "高优先级"、"紧急"、"重要" |
129
+
130
+ ## 任务状态
131
+
132
+ | 值 | 含义 | 图标 |
133
+ |----|------|------|
134
+ | `0` | 待办 | ○ |
135
+ | `2` | 已完成 | ✓ |
136
+
137
+ ---
138
+
139
+ ## 常用 Prompt 模板
140
+
141
+ 以下是用户可以直接使用的自然语言示例:
142
+
143
+ ### 查询类
144
+ - "帮我查看今天的任务"
145
+ - "今天有什么待办事项"
146
+ - "看看我明天要做什么"
147
+ - "未来一周有哪些任务"
148
+ - "昨天的任务完成了吗"
149
+ - "帮我查一下上周完成了哪些任务"
150
+ - "有哪些高优先级的任务还没完成"
151
+ - "搜索一下关于 XX 的任务"
152
+ - "看看 XX 项目里有什么任务"
153
+
154
+ ### 创建类
155
+ - "帮我创建一个任务:明天开会"
156
+ - "新建一个高优先级任务:提交报告,截止到本周五"
157
+ - "在'工作'项目下添加任务:准备会议材料"
158
+ - "帮我安排明天的任务:上午开会,下午写文档"
159
+
160
+ ### 操作类
161
+ - "帮我把 XX 任务标记为完成"
162
+ - "完成今天所有的任务"
163
+ - "把 XX 任务移到'生活'项目"
164
+ - "修改 XX 任务的截止日期到下周一"
165
+
166
+ ### 分析类
167
+ - "帮我统计一下这周完成了多少任务"
168
+ - "看看我哪些任务快到期了"
169
+ - "帮我整理一下当前所有未完成的任务,按优先级排序"
@@ -0,0 +1,61 @@
1
+ import { getOAuth, getToken, isTokenValid, getRegion } from '../utils/config.js';
2
+ import { getEndpoints } from '../utils/endpoints.js';
3
+ import { refreshAccessToken } from './oauth.js';
4
+
5
+ /** 获取有效的 access token(自动刷新) */
6
+ async function getValidToken(): Promise<string> {
7
+ const oauth = getOAuth();
8
+ const token = getToken();
9
+
10
+ if (!oauth || !token) {
11
+ throw new Error('未登录,请先运行 tt login');
12
+ }
13
+
14
+ if (isTokenValid()) {
15
+ return token.accessToken;
16
+ }
17
+
18
+ const newToken = await refreshAccessToken();
19
+ return newToken.accessToken;
20
+ }
21
+
22
+ /** 发送 API 请求 */
23
+ export async function apiRequest<T>(path: string, options?: RequestInit): Promise<T> {
24
+ const token = await getValidToken();
25
+ const endpoints = getEndpoints(getRegion());
26
+
27
+ const response = await fetch(`${endpoints.apiBase}${path}`, {
28
+ ...options,
29
+ headers: {
30
+ 'Authorization': `Bearer ${token}`,
31
+ 'Content-Type': 'application/json',
32
+ ...options?.headers,
33
+ },
34
+ });
35
+
36
+ if (!response.ok) {
37
+ const text = await response.text();
38
+ throw new Error(`API 请求失败: ${response.status} ${text}`);
39
+ }
40
+
41
+ if (response.status === 204) {
42
+ return undefined as T;
43
+ }
44
+
45
+ // 读取响应文本,处理空 body(TickTick 部分 API 返回 200 + 空 body)
46
+ const text = await response.text();
47
+ if (!text || text.trim() === '') {
48
+ return undefined as T;
49
+ }
50
+
51
+ try {
52
+ return JSON.parse(text) as T;
53
+ } catch {
54
+ throw new Error(
55
+ `API 响应 JSON 解析失败 (HTTP ${response.status})\n` +
56
+ `路径: ${path}\n` +
57
+ `原始响应: ${text.substring(0, 500)}\n` +
58
+ `建议: 请检查 API 端点是否正确,或尝试 tt task-search 验证数据`
59
+ );
60
+ }
61
+ }