版本:v1.0 | 作者:Spark | 创建时间:2026-04-04
临时心跳任务管理器 - 允许用户设置一次性临时心跳任务,在指定时间后执行,执行完成后自动删除
核心使命: 提供灵活的心跳任务机制,避免 HEARTBEAT.md 永久化配置,适合临时提醒、定时任务等场景
/heart - 标准触发临时心跳 - 中文触发temp heartbeat - 英文触发定时任务 - 定时触发目标: 理解用户的临时心跳需求
检查清单:
输出:
markdown
## 📋 临时心跳任务
**任务类型:** [提醒/检查/执行]
**执行时间:** [X 分钟后/具体时间点]
**任务内容:** [一句话描述]
**重复性:** 一次性(执行后删除)
支持的时间格式:
格式示例解析结果相对时间10 分钟后当前时间 + 10 分钟相对时间1 小时后当前时间 + 1 小时相对时间30 分钟后当前时间 + 30 分钟相对时间2 天后当前时间 + 2 天绝对时间今晚 8 点今天 20:00绝对时间明天上午 10 点明天 10:00绝对时间2026-04-05 15:00指定日期时间
时间单位支持:
输出:
markdown
## ⏰ 执行时间
**用户输入:** [原始时间描述]
**解析结果:** [ISO 8601 格式]
**距离现在:** [X 分钟/小时/天]
**执行时间:** [YYYY-MM-DD HH:mm:ss]
目标: 创建临时心跳任务文件
文件位置:
text
memory/temp-heartbeat-{timestamp}.md
文件内容模板:
markdown
# Temp Heartbeat Task
> ⚠️ 此任务为临时心跳,执行后自动删除
## Task Info
- **Created At:** {创建时间}
- **Execute At:** {执行时间}
- **Task ID:** {唯一 ID}
- **Status:** pending
## Task Content
{任务内容}
## Execution
- [ ] 任务已执行
- [ ] 结果已记录
- [ ] 文件已删除
输出:
markdown
## ✅ 临时心跳任务已创建
**任务 ID:** `{task_id}`
**执行时间:** {执行时间}
**任务内容:** {任务内容}
**提示:**
- 任务将在指定时间自动执行
- 执行完成后自动删除
- 输入 `/heart list` 查看所有临时心跳
支持的管理命令:
命令功能示例/heart创建临时心跳/heart 10 分钟后提醒我开会``/heart list查看所有临时心跳列出所有待执行任务/heart cancel {ID}取消指定心跳/heart cancel task_123``/heart cancel all取消所有心跳清空所有临时任务
输出示例(list):
markdown
## 📋 临时心跳任务列表
| 任务 ID | 执行时间 | 任务内容 | 状态 |
|--------|----------|----------|------|
| task_123 | 2026-04-04 10:30 | 提醒开会 | 待执行 |
| task_456 | 2026-04-04 15:00 | 检查 API 状态 | 待执行 |
**共 X 个任务**
**管理命令:**
- 取消单个:`/heart cancel {任务 ID}`
- 取消所有:`/heart cancel all`
触发条件:
执行流程:
输出:
markdown
## ✅ 临时心跳任务已执行
**任务 ID:** `{task_id}`
**执行时间:** {实际执行时间}
**任务内容:** {任务内容}
**执行结果:**
{任务执行的具体内容}
---
*此临时心跳任务已完成并删除*
markdown
## ✅ 临时心跳任务已创建
**任务 ID:** `task_{timestamp}_{random}`
**执行时间:** {YYYY-MM-DD HH:mm:ss}
**距离现在:** {X 分钟/小时}
**任务内容:** {任务描述}
**提示:**
- ✅ 任务已保存到 `memory/temp-heartbeat-{timestamp}.md`
- ⏰ 将在指定时间自动执行
- 🗑️ 执行完成后自动删除
- 📋 输入 `/heart list` 查看所有任务
**取消任务:**
- 取消单个:`/heart cancel {任务 ID}`
- 取消所有:`/heart cancel all`
markdown
## 📋 临时心跳任务列表
| 任务 ID | 执行时间 | 剩余时间 | 任务内容 | 操作 |
|--------|----------|----------|----------|------|
| task_123 | 10:30 | 25 分钟 | 提醒开会 | `/heart cancel task_123` |
| task_456 | 15:00 | 5 小时 | 检查 API | `/heart cancel task_456` |
**共 {X} 个任务**
**下次执行:** {最近的任务时间}
markdown
## ⏰ 临时心跳任务触发
**任务 ID:** `task_123`
**计划执行:** 10:30
**实际执行:** 10:30:05
## 📋 任务内容
{任务描述}
## ✅ 执行结果
{执行的具体内容}
---
*临时心跳任务已完成,文件已删除*
typescript
function parseTime(timeStr: string): Date | null {
// 相对时间解析
const relativePatterns = [
/(\d+)\s*分钟后?/,
/(\d+)\s*小时后?/,
/(\d+)\s*天后?/,
/in\s+(\d+)\s*minutes?/,
/in\s+(\d+)\s*hours?/,
/in\s+(\d+)\s*days?/,
];
for (const pattern of relativePatterns) {
const match = timeStr.match(pattern);
if (match) {
const value = parseInt(match[1]);
const now = new Date();
if (pattern.toString().includes('分钟')) {
now.setMinutes(now.getMinutes() + value);
} else if (pattern.toString().includes('小时')) {
now.setHours(now.getHours() + value);
} else if (pattern.toString().includes('天')) {
now.setDate(now.getDate() + value);
}
return now;
}
}
// 绝对时间解析
const absolutePatterns = [
/今晚\s*(\d+)[点時]/,
/明天\s*(\d+)[点時]/,
/(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})/,
];
for (const pattern of absolutePatterns) {
const match = timeStr.match(pattern);
if (match) {
// 解析绝对时间
// ...
}
}
return null;
}
typescript
async function createTempHeartbeat(
executeAt: Date,
content: string
): Promise<TaskInfo> {
const taskId = `task_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`;
const filePath = `memory/temp-heartbeat-${Date.now()}.md`;
const taskContent = `# Temp Heartbeat Task
> ⚠️ 此任务为临时心跳,执行后自动删除
## Task Info
- **Created At:** ${new Date().toISOString()}
- **Execute At:** ${executeAt.toISOString()}
- **Task ID:** ${taskId}
- **Status:** pending
## Task Content
${content}
## Execution
- [ ] 任务已执行
- [ ] 结果已记录
- [ ] 文件已删除
`;
await writeFile(filePath, taskContent);
return {
id: taskId,
executeAt,
content,
filePath,
status: 'pending',
};
}
typescript
async function checkAndExecuteTasks(): Promise<void> {
const tempHeartbeatFiles = await glob('memory/temp-heartbeat-*.md');
const now = new Date();
for (const file of tempHeartbeatFiles) {
const content = await readFile(file, 'utf-8');
const executeAtMatch = content.match(/Execute At:\s*(.+)/);
const statusMatch = content.match(/Status:\s*(.+)/);
if (!executeAtMatch || statusMatch?.[1] !== 'pending') {
continue;
}
const executeAt = new Date(executeAtMatch[1]);
if (now >= executeAt) {
// 执行任务
await executeTask(file, content);
// 删除文件
await unlink(file);
}
}
}
typescript
async function listTempHeartbeats(): Promise<TaskInfo[]> {
const tempHeartbeatFiles = await glob('memory/temp-heartbeat-*.md');
const tasks: TaskInfo[] = [];
for (const file of tempHeartbeatFiles) {
const content = await readFile(file, 'utf-8');
const taskIdMatch = content.match(/Task ID:\s*(.+)/);
const executeAtMatch = content.match(/Execute At:\s*(.+)/);
const contentMatch = content.match(/## Task Content\n\n(.+)/s);
if (taskIdMatch && executeAtMatch && contentMatch) {
tasks.push({
id: taskIdMatch[1].trim(),
executeAt: new Date(executeAtMatch[1].trim()),
content: contentMatch[1].trim(),
filePath: file,
status: 'pending',
});
}
}
// 按执行时间排序
return tasks.sort((a, b) => a.executeAt.getTime() - b.executeAt.getTime());
}
用户输入:
text
/heart 10 分钟后提醒我开会
输出:
markdown
## ✅ 临时心跳任务已创建
**任务 ID:** `task_1775245200000_abc123`
**执行时间:** 2026-04-04 10:40:00
**距离现在:** 10 分钟
**任务内容:** 提醒我开会
**提示:**
- ✅ 任务已保存到 `memory/temp-heartbeat-1775245200000.md`
- ⏰ 将在 10 分钟后自动执行
- 🗑️ 执行完成后自动删除
- 📋 输入 `/heart list` 查看所有任务
**取消任务:**
- 取消单个:`/heart cancel task_1775245200000_abc123`
- 取消所有:`/heart cancel all`
10 分钟后自动执行:
markdown
## ⏰ 临时心跳任务触发
**任务 ID:** `task_1775245200000_abc123`
**任务内容:** 提醒我开会
## ✅ 执行结果
🔔 提醒:您有一个会议要参加!
---
*临时心跳任务已完成,文件已删除*
用户输入:
text
/heart 1 小时后检查 GitHub API 限流状态
输出:
markdown
## ✅ 临时心跳任务已创建
**任务 ID:** `task_1775248800000_def456`
**执行时间:** 2026-04-04 11:40:00
**距离现在:** 1 小时
**任务内容:** 检查 GitHub API 限流状态
...
1 小时后自动执行:
markdown
## ⏰ 临时心跳任务触发
**任务内容:** 检查 GitHub API 限流状态
## ✅ 执行结果
**GitHub API 状态:**
- 剩余:58/60
- 重置时间:2026-04-04 12:00
---
*临时心跳任务已完成,文件已删除*
用户输入:
text
/heart list
输出:
markdown
## 📋 临时心跳任务列表
| 任务 ID | 执行时间 | 剩余时间 | 任务内容 | 操作 |
|--------|----------|----------|----------|------|
| task_abc123 | 10:40 | 10 分钟 | 提醒开会 | `/heart cancel task_abc123` |
| task_def456 | 11:40 | 1 小时 | 检查 API | `/heart cancel task_def456` |
| task_ghi789 | 明天 09:00 | 14 小时 | 每日检查 | `/heart cancel task_ghi789` |
**共 3 个任务**
**下次执行:** 10 分钟后 (task_abc123)
用户输入:
text
/heart cancel task_abc123
输出:
markdown
## ✅ 临时心跳任务已取消
**任务 ID:** `task_abc123`
**原计划执行:** 2026-04-04 10:40:00
**任务内容:** 提醒开会
**操作:**
- ✅ 任务文件已删除
- ✅ 任务已从列表中移除
用户输入:
text
/heart cancel all
输出:
markdown
## ✅ 已取消所有临时心跳任务
**取消任务数:** 3 个
**取消列表:**
1. task_abc123 - 提醒开会
2. task_def456 - 检查 API
3. task_ghi789 - 每日检查
**操作:**
- ✅ 所有任务文件已删除
- ✅ 任务列表已清空
版本日期更新内容v1.02026-04-04初始版本,临时心跳管理
Temp Heartbeat Skill 开发完成 · 让临时任务更灵活