@zsc-glitch/habit-tracker 1.0.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.
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # Habit Tracker 🔥
2
+
3
+ 习惯追踪器 - 记录习惯、追踪连续天数、养成好习惯
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install @zsc-glitch/habit-tracker
9
+ ```
10
+
11
+ ## 使用
12
+
13
+ ### 添加习惯
14
+ - "添加习惯:每天运动"
15
+ - "新习惯:阅读30分钟"
16
+
17
+ ### 打卡
18
+ - "打卡运动"
19
+ - "完成了阅读"
20
+
21
+ ### 查看状态
22
+ - "习惯状态"
23
+ - "我的streak"
24
+
25
+ ## 功能
26
+
27
+ - ✅ 习惯记录
28
+ - ✅ Streak 追踪
29
+ - ✅ 统计报告
30
+ - ✅ 目标设置
31
+
32
+ ## 工具
33
+
34
+ - `habit_add` - 添加习惯
35
+ - `habit_checkin` - 打卡
36
+ - `habit_status` - 查看状态
37
+ - `habit_report` - 生成报告
38
+ - `habit_delete` - 删除习惯
39
+
40
+ ## 数据存储
41
+
42
+ ```
43
+ ~/.habit-tracker/
44
+ ├── habits.json # 习惯配置
45
+ ├── checkins/ # 打卡记录
46
+ └── stats.json # 统计数据
47
+ ```
48
+
49
+ ## License
50
+
51
+ MIT
52
+
53
+ ---
54
+
55
+ Made with 🔥 by 小影
package/SKILL.md ADDED
@@ -0,0 +1,122 @@
1
+ # Habit Tracker 🔥
2
+
3
+ 习惯追踪器 - 记录习惯、追踪连续天数、养成好习惯
4
+
5
+ ## 功能
6
+
7
+ - ✅ **习惯记录** - 快速打卡,记录完成情况
8
+ - ✅ **连续追踪** - 自动计算 streak,激励坚持
9
+ - ✅ **目标设置** - 设置每日/每周目标
10
+ - ✅ **统计报告** - 习惯完成率、趋势分析
11
+ - ✅ **提醒功能** - 可配置定时提醒
12
+ - ✅ **数据可视化** - 日历视图,一目了然
13
+
14
+ ## 使用
15
+
16
+ ### 添加习惯
17
+
18
+ 对我说:
19
+ - "添加习惯:每天运动"
20
+ - "新习惯:阅读30分钟"
21
+ - "我要养成冥想的习惯"
22
+
23
+ ### 打卡
24
+
25
+ 对我说:
26
+ - "打卡运动"
27
+ - "完成了阅读"
28
+ - "今天冥想了"
29
+
30
+ ### 查看状态
31
+
32
+ 对我说:
33
+ - "习惯状态"
34
+ - "我的streak"
35
+ - "本周习惯完成情况"
36
+
37
+ ## 预设习惯模板
38
+
39
+ | 类别 | 习惯 |
40
+ |------|------|
41
+ | 健康 | 运动、喝水、早睡、早起 |
42
+ | 学习 | 阅读、学英语、编程 |
43
+ | 心理 | 冥想、写日记、感恩 |
44
+ | 生活 | 整理、记账、复盘 |
45
+
46
+ ## 工具
47
+
48
+ ### habit_add
49
+ 添加新习惯:`habit_add(name, category?, frequency?, goal?)`
50
+
51
+ ### habit_checkin
52
+ 打卡:`habit_checkin(name, note?)`
53
+
54
+ ### habit_status
55
+ 查看状态:`habit_status(name?)`
56
+
57
+ ### habit_report
58
+ 生成报告:`habit_report(period)`
59
+
60
+ ### habit_edit
61
+ 编辑习惯:`habit_edit(name, updates)`
62
+
63
+ ### habit_delete
64
+ 删除习惯:`habit_delete(name)`
65
+
66
+ ## 数据存储
67
+
68
+ 习惯数据存储在 `~/.habit-tracker/` 目录:
69
+
70
+ ```
71
+ ~/.habit-tracker/
72
+ ├── habits.json # 习惯配置
73
+ ├── checkins/ # 打卡记录
74
+ │ ├── 2026-03-30.json
75
+ │ └── ...
76
+ └── stats.json # 统计数据
77
+ ```
78
+
79
+ ## Streak 计算
80
+
81
+ - **当前 streak**:连续打卡天数
82
+ - **最长 streak**:历史最长连续记录
83
+ - **断掉后重置**:一天未打卡,streak 归零
84
+
85
+ ## 安装
86
+
87
+ ```bash
88
+ npm install @zsc-glitch/habit-tracker
89
+ ```
90
+
91
+ 或通过 ClawHub:
92
+
93
+ ```bash
94
+ npx clawhub@latest install habit-tracker
95
+ ```
96
+
97
+ ## 配置
98
+
99
+ ```json
100
+ {
101
+ "skills": {
102
+ "entries": {
103
+ "habit_tracker": {
104
+ "enabled": true,
105
+ "config": {
106
+ "dataDir": "~/.habit-tracker",
107
+ "reminderEnabled": true,
108
+ "reminderTime": "21:00"
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }
114
+ ```
115
+
116
+ ## License
117
+
118
+ MIT
119
+
120
+ ---
121
+
122
+ Made with 🔥 by 小影
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Habit Tracker Plugin
3
+ * 习惯追踪器 - 记录习惯、追踪连续天数、养成好习惯
4
+ */
5
+ declare const _default: {
6
+ id: string;
7
+ name: string;
8
+ description: string;
9
+ configSchema: import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginConfigSchema;
10
+ register: NonNullable<import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginDefinition["register"]>;
11
+ } & Pick<import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginDefinition, "kind">;
12
+ export default _default;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;;;;;;;;AA0OH,wBAkZG"}
package/dist/index.js ADDED
@@ -0,0 +1,541 @@
1
+ /**
2
+ * Habit Tracker Plugin
3
+ * 习惯追踪器 - 记录习惯、追踪连续天数、养成好习惯
4
+ */
5
+ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
6
+ import { Type } from "@sinclair/typebox";
7
+ import * as fs from "fs/promises";
8
+ import * as path from "path";
9
+ import * as os from "os";
10
+ // 获取数据目录
11
+ function getDataDir(config) {
12
+ const dir = config?.dataDir || process.env.HABIT_TRACKER_DIR || "~/.habit-tracker";
13
+ return dir.replace("~", os.homedir());
14
+ }
15
+ // 获取今天的日期字符串
16
+ function getTodayDate() {
17
+ return new Date().toISOString().slice(0, 10);
18
+ }
19
+ // 获取昨天的日期字符串
20
+ function getYesterdayDate() {
21
+ const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000);
22
+ return yesterday.toISOString().slice(0, 10);
23
+ }
24
+ // 生成习惯 ID
25
+ function generateId() {
26
+ return `habit-${Math.random().toString(36).slice(2, 6)}`;
27
+ }
28
+ // 确保目录存在
29
+ async function ensureDir(dir) {
30
+ try {
31
+ await fs.mkdir(dir, { recursive: true });
32
+ }
33
+ catch {
34
+ // 目录已存在
35
+ }
36
+ }
37
+ // 读取 JSON 文件
38
+ async function readJsonFile(filepath, defaultValue) {
39
+ try {
40
+ const content = await fs.readFile(filepath, "utf-8");
41
+ return JSON.parse(content);
42
+ }
43
+ catch {
44
+ return defaultValue;
45
+ }
46
+ }
47
+ // 写入 JSON 文件
48
+ async function writeJsonFile(filepath, data) {
49
+ await fs.writeFile(filepath, JSON.stringify(data, null, 2), "utf-8");
50
+ }
51
+ // 获取习惯文件路径
52
+ function getHabitsFilePath(dataDir) {
53
+ return path.join(dataDir, "habits.json");
54
+ }
55
+ // 获取打卡文件路径
56
+ function getCheckinsFilePath(dataDir, date) {
57
+ return path.join(dataDir, "checkins", `${date}.json`);
58
+ }
59
+ // 获取统计文件路径
60
+ function getStatsFilePath(dataDir) {
61
+ return path.join(dataDir, "stats.json");
62
+ }
63
+ // 加载所有习惯
64
+ async function loadHabits(dataDir) {
65
+ return readJsonFile(getHabitsFilePath(dataDir), []);
66
+ }
67
+ // 保存习惯列表
68
+ async function saveHabits(dataDir, habits) {
69
+ await ensureDir(dataDir);
70
+ await writeJsonFile(getHabitsFilePath(dataDir), habits);
71
+ }
72
+ // 加载指定日期的打卡记录
73
+ async function loadCheckins(dataDir, date) {
74
+ return readJsonFile(getCheckinsFilePath(dataDir, date), []);
75
+ }
76
+ // 保存打卡记录
77
+ async function saveCheckins(dataDir, date, checkins) {
78
+ const checkinsDir = path.join(dataDir, "checkins");
79
+ await ensureDir(checkinsDir);
80
+ await writeJsonFile(getCheckinsFilePath(dataDir, date), checkins);
81
+ }
82
+ // 加载统计数据
83
+ async function loadStats(dataDir) {
84
+ return readJsonFile(getStatsFilePath(dataDir), {});
85
+ }
86
+ // 保存统计数据
87
+ async function saveStats(dataDir, stats) {
88
+ await ensureDir(dataDir);
89
+ await writeJsonFile(getStatsFilePath(dataDir), stats);
90
+ }
91
+ // 计算 streak
92
+ async function calculateStreak(dataDir, habitId) {
93
+ const checkinsDir = path.join(dataDir, "checkins");
94
+ let currentStreak = 0;
95
+ let longestStreak = 0;
96
+ let tempStreak = 0;
97
+ try {
98
+ const files = await fs.readdir(checkinsDir);
99
+ const dates = files
100
+ .filter(f => f.endsWith(".json"))
101
+ .map(f => f.replace(".json", ""))
102
+ .sort()
103
+ .reverse();
104
+ // 检查今天或昨天是否打卡
105
+ const today = getTodayDate();
106
+ const yesterday = getYesterdayDate();
107
+ let hasRecentCheckin = false;
108
+ for (const date of dates) {
109
+ const checkins = await loadCheckins(dataDir, date);
110
+ const hasCheckin = checkins.some(c => c.habitId === habitId);
111
+ if (hasCheckin) {
112
+ if (date === today || date === yesterday) {
113
+ hasRecentCheckin = true;
114
+ }
115
+ tempStreak++;
116
+ if (tempStreak > longestStreak) {
117
+ longestStreak = tempStreak;
118
+ }
119
+ }
120
+ else {
121
+ // 断了,重置临时 streak
122
+ if (tempStreak > 0 && !hasRecentCheckin) {
123
+ // 如果已经断开了,停止计算当前 streak
124
+ break;
125
+ }
126
+ tempStreak = 0;
127
+ }
128
+ }
129
+ // 当前 streak 从今天/昨天开始计算
130
+ if (hasRecentCheckin) {
131
+ currentStreak = tempStreak;
132
+ }
133
+ }
134
+ catch {
135
+ // 目录不存在
136
+ }
137
+ return { current: currentStreak, longest: longestStreak };
138
+ }
139
+ // 获取习惯的 emoji
140
+ function getCategoryEmoji(category) {
141
+ const emojis = {
142
+ health: "💪",
143
+ learning: "📚",
144
+ mindfulness: "🧘",
145
+ life: "🏠",
146
+ custom: "⭐",
147
+ };
148
+ return emojis[category];
149
+ }
150
+ // 频率 Schema
151
+ const FrequencySchema = Type.Union([
152
+ Type.Literal("daily"),
153
+ Type.Literal("weekly"),
154
+ ]);
155
+ // 类别 Schema
156
+ const CategorySchema = Type.Union([
157
+ Type.Literal("health"),
158
+ Type.Literal("learning"),
159
+ Type.Literal("mindfulness"),
160
+ Type.Literal("life"),
161
+ Type.Literal("custom"),
162
+ ]);
163
+ // 报告周期 Schema
164
+ const ReportPeriodSchema = Type.Union([
165
+ Type.Literal("week"),
166
+ Type.Literal("month"),
167
+ Type.Literal("year"),
168
+ ]);
169
+ // 插件入口
170
+ export default definePluginEntry({
171
+ id: "habit-tracker",
172
+ name: "Habit Tracker",
173
+ description: "习惯追踪器 - 记录习惯、追踪连续天数、养成好习惯",
174
+ register(api) {
175
+ const config = api.pluginConfig;
176
+ // 添加习惯
177
+ api.registerTool({
178
+ name: "habit_add",
179
+ label: "添加习惯",
180
+ description: "添加一个新习惯进行追踪",
181
+ parameters: Type.Object({
182
+ name: Type.String(),
183
+ category: Type.Optional(CategorySchema),
184
+ frequency: Type.Optional(FrequencySchema),
185
+ goal: Type.Optional(Type.Number()),
186
+ emoji: Type.Optional(Type.String()),
187
+ }),
188
+ async execute(toolCallId, params) {
189
+ try {
190
+ const dataDir = getDataDir(config);
191
+ const habits = await loadHabits(dataDir);
192
+ // 检查是否已存在同名习惯
193
+ if (habits.some(h => h.name.toLowerCase() === params.name.toLowerCase())) {
194
+ return {
195
+ content: [
196
+ {
197
+ type: "text",
198
+ text: `⚠️ 习惯 "${params.name}" 已存在`,
199
+ },
200
+ ],
201
+ details: { exists: true },
202
+ };
203
+ }
204
+ const habit = {
205
+ id: generateId(),
206
+ name: params.name,
207
+ category: params.category || "custom",
208
+ frequency: params.frequency || "daily",
209
+ goal: params.goal,
210
+ createdAt: new Date().toISOString(),
211
+ emoji: params.emoji || getCategoryEmoji(params.category || "custom"),
212
+ };
213
+ habits.push(habit);
214
+ await saveHabits(dataDir, habits);
215
+ // 初始化统计
216
+ const stats = await loadStats(dataDir);
217
+ stats[habit.id] = {
218
+ habitId: habit.id,
219
+ currentStreak: 0,
220
+ longestStreak: 0,
221
+ totalCheckins: 0,
222
+ };
223
+ await saveStats(dataDir, stats);
224
+ return {
225
+ content: [
226
+ {
227
+ type: "text",
228
+ text: `✅ 已添加习惯\n\n${habit.emoji} **${habit.name}**\n类别: ${habit.category}\n频率: ${habit.frequency === "daily" ? "每日" : "每周"}${habit.goal ? `\n目标: ${habit.goal}次/${habit.frequency === "daily" ? "周" : "月"}` : ""}`,
229
+ },
230
+ ],
231
+ details: { id: habit.id },
232
+ };
233
+ }
234
+ catch (error) {
235
+ return {
236
+ content: [
237
+ {
238
+ type: "text",
239
+ text: `❌ 添加失败: ${error instanceof Error ? error.message : String(error)}`,
240
+ },
241
+ ],
242
+ details: { error: true },
243
+ };
244
+ }
245
+ },
246
+ }, { optional: true });
247
+ // 打卡
248
+ api.registerTool({
249
+ name: "habit_checkin",
250
+ label: "习惯打卡",
251
+ description: "完成习惯打卡",
252
+ parameters: Type.Object({
253
+ name: Type.String(),
254
+ note: Type.Optional(Type.String()),
255
+ }),
256
+ async execute(toolCallId, params) {
257
+ try {
258
+ const dataDir = getDataDir(config);
259
+ const habits = await loadHabits(dataDir);
260
+ // 查找习惯
261
+ const habit = habits.find(h => h.name.toLowerCase() === params.name.toLowerCase());
262
+ if (!habit) {
263
+ return {
264
+ content: [
265
+ {
266
+ type: "text",
267
+ text: `❌ 未找到习惯 "${params.name}"\n\n使用 "habit_add" 添加新习惯`,
268
+ },
269
+ ],
270
+ details: { notFound: true },
271
+ };
272
+ }
273
+ const today = getTodayDate();
274
+ const checkins = await loadCheckins(dataDir, today);
275
+ // 检查今天是否已打卡
276
+ if (checkins.some(c => c.habitId === habit.id)) {
277
+ return {
278
+ content: [
279
+ {
280
+ type: "text",
281
+ text: `✅ 今天已打卡 ${habit.emoji} **${habit.name}**`,
282
+ },
283
+ ],
284
+ details: { alreadyChecked: true },
285
+ };
286
+ }
287
+ // 添加打卡记录
288
+ const checkin = {
289
+ habitId: habit.id,
290
+ date: today,
291
+ timestamp: new Date().toISOString(),
292
+ note: params.note,
293
+ };
294
+ checkins.push(checkin);
295
+ await saveCheckins(dataDir, today, checkins);
296
+ // 更新统计
297
+ const stats = await loadStats(dataDir);
298
+ const habitStats = stats[habit.id] || {
299
+ habitId: habit.id,
300
+ currentStreak: 0,
301
+ longestStreak: 0,
302
+ totalCheckins: 0,
303
+ };
304
+ habitStats.totalCheckins++;
305
+ habitStats.lastCheckin = today;
306
+ // 重新计算 streak
307
+ const { current, longest } = await calculateStreak(dataDir, habit.id);
308
+ habitStats.currentStreak = current;
309
+ habitStats.longestStreak = Math.max(longest, habitStats.longestStreak);
310
+ stats[habit.id] = habitStats;
311
+ await saveStats(dataDir, stats);
312
+ return {
313
+ content: [
314
+ {
315
+ type: "text",
316
+ text: `🔥 打卡成功!\n\n${habit.emoji} **${habit.name}**\n当前连续: ${habitStats.currentStreak} 天\n最长连续: ${habitStats.longestStreak} 天\n总打卡: ${habitStats.totalCheckins} 次`,
317
+ },
318
+ ],
319
+ details: { streak: habitStats.currentStreak },
320
+ };
321
+ }
322
+ catch (error) {
323
+ return {
324
+ content: [
325
+ {
326
+ type: "text",
327
+ text: `❌ 打卡失败: ${error instanceof Error ? error.message : String(error)}`,
328
+ },
329
+ ],
330
+ details: { error: true },
331
+ };
332
+ }
333
+ },
334
+ }, { optional: true });
335
+ // 查看状态
336
+ api.registerTool({
337
+ name: "habit_status",
338
+ label: "习惯状态",
339
+ description: "查看习惯状态和连续打卡天数",
340
+ parameters: Type.Object({
341
+ name: Type.Optional(Type.String()),
342
+ }),
343
+ async execute(toolCallId, params) {
344
+ try {
345
+ const dataDir = getDataDir(config);
346
+ const habits = await loadHabits(dataDir);
347
+ const stats = await loadStats(dataDir);
348
+ const today = getTodayDate();
349
+ const todayCheckins = await loadCheckins(dataDir, today);
350
+ if (params.name) {
351
+ // 查看单个习惯
352
+ const habit = habits.find(h => h.name.toLowerCase() === params.name.toLowerCase());
353
+ if (!habit) {
354
+ return {
355
+ content: [
356
+ { type: "text", text: `❌ 未找到习惯 "${params.name}"` },
357
+ ],
358
+ details: { notFound: true },
359
+ };
360
+ }
361
+ const habitStats = stats[habit.id] || { currentStreak: 0, longestStreak: 0, totalCheckins: 0 };
362
+ const checkedToday = todayCheckins.some(c => c.habitId === habit.id);
363
+ return {
364
+ content: [
365
+ {
366
+ type: "text",
367
+ text: `${habit.emoji} **${habit.name}**\n\n今日: ${checkedToday ? "✅ 已打卡" : "⬜ 未打卡"}\n当前连续: ${habitStats.currentStreak} 天 🔥\n最长连续: ${habitStats.longestStreak} 天\n总打卡: ${habitStats.totalCheckins} 次`,
368
+ },
369
+ ],
370
+ details: { stats: habitStats },
371
+ };
372
+ }
373
+ // 查看所有习惯
374
+ if (habits.length === 0) {
375
+ return {
376
+ content: [
377
+ { type: "text", text: "📭 暂无习惯记录\n\n使用 \"添加习惯: xxx\" 开始追踪" },
378
+ ],
379
+ details: { count: 0 },
380
+ };
381
+ }
382
+ const habitList = habits.map(h => {
383
+ const s = stats[h.id] || { currentStreak: 0, longestStreak: 0, totalCheckins: 0 };
384
+ const checked = todayCheckins.some(c => c.habitId === h.id);
385
+ return `${checked ? "✅" : "⬜"} ${h.emoji} ${h.name} - 🔥${s.currentStreak}天`;
386
+ }).join("\n");
387
+ const checkedCount = habits.filter(h => todayCheckins.some(c => c.habitId === h.id)).length;
388
+ return {
389
+ content: [
390
+ {
391
+ type: "text",
392
+ text: `📊 习惯状态 (${checkedCount}/${habits.length} 今日已完成)\n\n${habitList}`,
393
+ },
394
+ ],
395
+ details: { count: habits.length, checkedToday: checkedCount },
396
+ };
397
+ }
398
+ catch (error) {
399
+ return {
400
+ content: [
401
+ {
402
+ type: "text",
403
+ text: `❌ 获取状态失败: ${error instanceof Error ? error.message : String(error)}`,
404
+ },
405
+ ],
406
+ details: { error: true },
407
+ };
408
+ }
409
+ },
410
+ }, { optional: true });
411
+ // 生成报告
412
+ api.registerTool({
413
+ name: "habit_report",
414
+ label: "习惯报告",
415
+ description: "生成习惯完成情况报告",
416
+ parameters: Type.Object({
417
+ period: ReportPeriodSchema,
418
+ }),
419
+ async execute(toolCallId, params) {
420
+ try {
421
+ const dataDir = getDataDir(config);
422
+ const habits = await loadHabits(dataDir);
423
+ const stats = await loadStats(dataDir);
424
+ if (habits.length === 0) {
425
+ return {
426
+ content: [
427
+ { type: "text", text: "📭 暂无习惯记录" },
428
+ ],
429
+ details: { count: 0 },
430
+ };
431
+ }
432
+ // 计算日期范围
433
+ const days = params.period === "week" ? 7 : params.period === "month" ? 30 : 365;
434
+ const periodLabel = params.period === "week" ? "本周" : params.period === "month" ? "本月" : "今年";
435
+ // 收集打卡数据
436
+ const checkinsDir = path.join(dataDir, "checkins");
437
+ let totalCheckins = 0;
438
+ const habitCheckins = {};
439
+ try {
440
+ const files = await fs.readdir(checkinsDir);
441
+ const cutoffDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
442
+ for (const file of files) {
443
+ const date = file.replace(".json", "");
444
+ if (date >= cutoffDate) {
445
+ const checkins = await loadCheckins(dataDir, date);
446
+ totalCheckins += checkins.length;
447
+ for (const c of checkins) {
448
+ habitCheckins[c.habitId] = (habitCheckins[c.habitId] || 0) + 1;
449
+ }
450
+ }
451
+ }
452
+ }
453
+ catch {
454
+ // 目录不存在
455
+ }
456
+ // 排序习惯按打卡次数
457
+ const sortedHabits = [...habits].sort((a, b) => {
458
+ const aCount = habitCheckins[a.id] || 0;
459
+ const bCount = habitCheckins[b.id] || 0;
460
+ return bCount - aCount;
461
+ });
462
+ const habitReport = sortedHabits.map(h => {
463
+ const count = habitCheckins[h.id] || 0;
464
+ const s = stats[h.id] || { currentStreak: 0, longestStreak: 0 };
465
+ return `${h.emoji} ${h.name}: ${count}次 | 🔥${s.currentStreak}天`;
466
+ }).join("\n");
467
+ // 计算完成率
468
+ const expectedCheckins = habits.length * days;
469
+ const completionRate = expectedCheckins > 0 ? Math.round((totalCheckins / expectedCheckins) * 100) : 0;
470
+ return {
471
+ content: [
472
+ {
473
+ type: "text",
474
+ text: `📊 ${periodLabel}习惯报告\n\n总打卡: ${totalCheckins} 次\n完成率: ${completionRate}%\n习惯数: ${habits.length}\n\n详细:\n${habitReport}`,
475
+ },
476
+ ],
477
+ details: { totalCheckins, completionRate, period: params.period },
478
+ };
479
+ }
480
+ catch (error) {
481
+ return {
482
+ content: [
483
+ {
484
+ type: "text",
485
+ text: `❌ 生成报告失败: ${error instanceof Error ? error.message : String(error)}`,
486
+ },
487
+ ],
488
+ details: { error: true },
489
+ };
490
+ }
491
+ },
492
+ }, { optional: true });
493
+ // 删除习惯
494
+ api.registerTool({
495
+ name: "habit_delete",
496
+ label: "删除习惯",
497
+ description: "删除一个习惯(不会删除历史打卡记录)",
498
+ parameters: Type.Object({
499
+ name: Type.String(),
500
+ }),
501
+ async execute(toolCallId, params) {
502
+ try {
503
+ const dataDir = getDataDir(config);
504
+ const habits = await loadHabits(dataDir);
505
+ const index = habits.findIndex(h => h.name.toLowerCase() === params.name.toLowerCase());
506
+ if (index === -1) {
507
+ return {
508
+ content: [
509
+ { type: "text", text: `❌ 未找到习惯 "${params.name}"` },
510
+ ],
511
+ details: { notFound: true },
512
+ };
513
+ }
514
+ const deleted = habits.splice(index, 1)[0];
515
+ await saveHabits(dataDir, habits);
516
+ return {
517
+ content: [
518
+ {
519
+ type: "text",
520
+ text: `🗑️ 已删除习惯 ${deleted.emoji} **${deleted.name}**\n\n历史打卡记录已保留`,
521
+ },
522
+ ],
523
+ details: { deleted: deleted.id },
524
+ };
525
+ }
526
+ catch (error) {
527
+ return {
528
+ content: [
529
+ {
530
+ type: "text",
531
+ text: `❌ 删除失败: ${error instanceof Error ? error.message : String(error)}`,
532
+ },
533
+ ],
534
+ details: { error: true },
535
+ };
536
+ }
537
+ },
538
+ }, { optional: true });
539
+ },
540
+ });
541
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ {
2
+ "id": "habit-tracker",
3
+ "name": "Habit Tracker",
4
+ "description": "习惯追踪器 - 记录习惯、追踪连续天数、养成好习惯",
5
+ "version": "1.0.0",
6
+ "author": "zsc-glitch",
7
+ "homepage": "https://github.com/zsc-glitch/habit-tracker",
8
+ "skills": ["./SKILL.md"],
9
+ "configSchema": {
10
+ "type": "object",
11
+ "properties": {
12
+ "dataDir": {
13
+ "type": "string",
14
+ "description": "数据存储目录",
15
+ "default": "~/.habit-tracker"
16
+ },
17
+ "reminderEnabled": {
18
+ "type": "boolean",
19
+ "description": "启用提醒",
20
+ "default": false
21
+ },
22
+ "reminderTime": {
23
+ "type": "string",
24
+ "description": "提醒时间",
25
+ "default": "21:00"
26
+ }
27
+ },
28
+ "additionalProperties": false
29
+ }
30
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@zsc-glitch/habit-tracker",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "习惯追踪器 - 记录习惯、追踪连续天数、养成好习惯",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "dev": "tsc --watch"
11
+ },
12
+ "keywords": [
13
+ "openclaw",
14
+ "plugin",
15
+ "habit",
16
+ "tracker",
17
+ "streak",
18
+ "productivity"
19
+ ],
20
+ "author": "zsc-glitch",
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/zsc-glitch/habit-tracker.git"
25
+ },
26
+ "openclaw": {
27
+ "extensions": ["./dist/index.js"]
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "openclaw.plugin.json",
32
+ "SKILL.md",
33
+ "README.md"
34
+ ],
35
+ "peerDependencies": {
36
+ "openclaw": ">=2026.0.0",
37
+ "@sinclair/typebox": ">=0.34.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^22.0.0",
41
+ "typescript": "^5.0.0"
42
+ },
43
+ "engines": {
44
+ "node": ">=22.0.0"
45
+ }
46
+ }