refactor(todo): 去除 MySQL 依赖,改为 JSON 本地存储

- 数据存储: ~/.local/share/todo/tasks.json 纯字符串数组
- 操作简化: 仅保留 add/list/done,无状态/优先级/归档
- 新增 scripts/validate.py 校验脚本 (格式/结构/去重)
- 新增 schema/tasks.schema.json
- 删除 references/setup.md (MySQL 配置指南)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-09-03 21:06:21 +08:00
parent 654ad53db2
commit 4b56297498
4 changed files with 240 additions and 273 deletions
+82 -167
View File
@@ -1,197 +1,112 @@
---
name: todo
description: |
任务待办管理 skill。通过自然语言操作 MySQL 数据库中的待办事项。
当用户提到待办、任务管理、todo list、添加任务、查看任务、标记完成、
清理任务、归档旧任务时,使用此 skill。
支持增删改查和基于 LRU 策略的自动归档。
极简任务管理 skill。通过 JSON 文件本地存储任务列表,仅记录任务的有与无。
当用户提到待办、任务管理、todo list、添加任务、查看任务、标记完成时,使用此 skill。
支持添加、查看、完成三个操作,参数歧义时与用户确认。
---
# 任务待办管理
# 极简任务管理
通过自然语言管理 MySQL 数据库中的待办事项,支持 LRU 自动淘汰。
通过自然语言管理本地 JSON 文件中的任务列表。任务只有「存在」和「不存在」两种状态。
## 工具说明
## 数据存储
本 skill 依赖 **MySQL MCP 工具** `mysql_query`。所有数据库操作都通过该工具执行。
- 文件路径:`~/.local/share/todo/tasks.json`
- 数据格式:
调用方式:使用 `execute_shell_command` 执行 MySQL MCP 查询,或直接使用 MCP 工具(如可用)。
如果 MCP 工具不可用,引导用户参考 `references/setup.md` 完成配置。
## 表结构
```sql
CREATE TABLE IF NOT EXISTS todos (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(500) NOT NULL,
description TEXT,
status ENUM('pending', 'in_progress', 'done', 'archived') NOT NULL DEFAULT 'pending',
priority ENUM('low', 'medium', 'high', 'urgent') NOT NULL DEFAULT 'medium',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
last_accessed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
access_count INT UNSIGNED NOT NULL DEFAULT 1
);
```json
{
"tasks": [
"买菜",
"写周报",
"锻炼30分钟"
]
}
```
- 任务为纯字符串数组,无 ID、无状态、无优先级、无时间戳
## 校验脚本
每次读写 JSON 前后,使用 `<skill_dir>/scripts/validate.py` 校验数据完整性。
```bash
# 校验数据文件
python3 <skill_dir>/scripts/validate.py
# 校验指定文件
python3 <skill_dir>/scripts/validate.py <文件路径>
```
校验内容:JSON 格式合法性、结构合规(tasks 数组 + 字符串元素)、任务去重(大小写不敏感)。
退出码 0 = 通过,1 = 失败。失败时 stderr 输出具体错误。
## 操作指南
### 添加任务
触发词:添加任务 / 新建待办 / 提醒我做 / 记一下
触发词:添加任务 / 新建待办 / 提醒我做 / 记一下 / add
```sql
INSERT INTO todos (title, description, priority) VALUES ('<标题>', '<描述>', '<优先级>');
流程:
1. 确认数据文件存在,不存在则创建 `{"tasks": []}`
2. 运行 `validate.py` 校验当前数据
3. 将新任务追加到 `tasks` 数组
4. 运行 `validate.py` 校验写入后的数据(去重检查)
5. 校验失败则回滚,输出错误信息
### 查看任务
触发词:我的待办 / 有什么任务 / 今天要做什么 / 列出任务 / list
流程:
1. 运行 `validate.py` 校验数据
2. 读取并展示所有任务,带序号
输出格式:
```
📋 任务列表
1. 买菜
2. 写周报
3. 锻炼30分钟
```
- 优先级默认 `medium`
- 用户说"紧急/urgent/马上/ASAP" → `urgent`
- 用户说"重要" → `high`
- 用户说"不急/有空/low" → `low`
- 添加后执行 LRU 检查(见下方淘汰策略)
### 完成任务(移除)
### 查看待办
触发词:完成 XXX / 做完了 / 搞定 / done
触发词:我的待办 / 有什么任务 / 今天要做什么 / 列出任务
```sql
SELECT id, title, status, priority, DATE_FORMAT(updated_at, '%m-%d') AS updated
FROM todos
WHERE status IN ('pending', 'in_progress')
ORDER BY
FIELD(priority, 'urgent', 'high', 'medium', 'low'),
last_accessed_at DESC;
```
查看后刷新访问时间:
```sql
UPDATE todos SET last_accessed_at = NOW(), access_count = access_count + 1
WHERE id IN (<id 列表>);
```
### 查看已完成
触发词:已完成的任务 / 做完了哪些
```sql
SELECT id, title, priority, DATE_FORMAT(updated_at, '%m-%d %H:%i') AS completed
FROM todos WHERE status = 'done'
ORDER BY updated_at DESC;
```
### 标记完成
触发词:完成 XXX / 标记为完成 / 做完了
```sql
UPDATE todos SET status = 'done', last_accessed_at = NOW(), access_count = access_count + 1
WHERE id = <id>;
```
按标题匹配:
```sql
UPDATE todos SET status = 'done', last_accessed_at = NOW(), access_count = access_count + 1
WHERE title LIKE '%<关键词>%' AND status != 'done';
```
流程:
1. 运行 `validate.py` 校验数据
2. 按序号或模糊匹配找到目标任务
3. 从 `tasks` 数组中移除
4. 运行 `validate.py` 校验写入后的数据
5. 校验失败则回滚,输出错误信息
- 匹配多条时列出匹配项让用户确认
- 用 `SELECT` 先查再改,避免误操作
- 完成即移除,不做归档
### 标记进行中
## 参数歧义处理
触发词:开始做 XXX / 进行中
以下情况必须与用户确认,不可自行猜测:
- **无参数调用**:`/todo` 不带任何参数 → 询问用户意图(查看 / 添加 / 完成)
- **仅操作词无目标**:`/todo done` 未指定具体任务 → 列出任务列表让用户选择
- **语义模糊**:`/todo 买菜` 不明确是「添加」还是「完成」→ 默认理解为添加,但需确认
- **模糊匹配多条**:关键词匹配到多个任务 → 列出候选项让用户确认
确认时使用简洁的提问,例如:
```sql
UPDATE todos SET status = 'in_progress', last_accessed_at = NOW(), access_count = access_count + 1
WHERE id = <id>;
```
### 更新任务
触发词:修改 XXX 的描述/优先级/标题
```sql
UPDATE todos SET <字段> = '<新值>', last_accessed_at = NOW(), access_count = access_count + 1
WHERE id = <id>;
你想对「买菜」做什么?
1. 添加为新任务
2. 标记完成(移除)
```
可更新字段:`title`、`description`、`priority`、`status`
### 删除任务
触发词:删除任务 / 去掉这个待办
**软删除(推荐)**:
```sql
UPDATE todos SET status = 'archived' WHERE id = <id>;
```
**硬删除**(用户明确要求时):
```sql
DELETE FROM todos WHERE id = <id>;
```
- 硬删除前必须列出将被删除的事项并确认
- 默认用软删除
### 搜索任务
触发词:找一下关于 XXX 的任务 / 有没有 XXX
```sql
SELECT id, title, status, priority
FROM todos
WHERE title LIKE '%<关键词>%' OR description LIKE '%<关键词>%'
ORDER BY FIELD(status, 'in_progress', 'pending', 'done', 'archived'), priority;
```
## LRU 淘汰策略
每次 INSERT 后检查总数:
```sql
SELECT COUNT(*) AS total FROM todos WHERE status != 'archived';
```
如果超过 100 条,执行归档:
```sql
-- 1. 归档最久未访问的已完成事项(最旧 10 条)
UPDATE todos SET status = 'archived'
WHERE status = 'done'
ORDER BY last_accessed_at ASC LIMIT 10;
-- 2. 仍超标则归档最久未访问的待办事项
UPDATE todos SET status = 'archived'
WHERE status = 'pending'
ORDER BY last_accessed_at ASC LIMIT 10;
```
**保护规则**:不归档 `in_progress` 状态的事项。
## 交互原则
- **模糊匹配时确认**:关键词匹配多条任务,列出选项让用户选
- **操作前预览**:删除/归档前,先 `SELECT` 显示受影响的事项
- **自然语言理解**:用户说"帮我记一下明天要买菜" → 添加任务"买菜"
- **状态转换合理**:不允许 archived → in_progress 等不合理跳转
## 输出格式
查询结果用表格展示:
```
| ID | 标题 | 状态 | 优先级 | 更新时间 |
|----|------|------|--------|----------|
| 1 | xxx | 待办 | 高 | 08-31 |
```
操作结果用简洁确认:
- ✓ 已添加任务:XXX
- ✓ 已完成任务:XXX
- ✓ 已归档 5 条旧任务
- **确认优先**:参数歧义时绝不猜测,主动询问
- **操作前校验**:每次读写前后运行 validate.py
- **失败回滚**:校验失败时恢复原数据,告知用户错误原因
- **简洁输出**:操作结果用 ✓ 前缀确认,如 `✓ 已添加任务:买菜`