@cacinie/cace-timer 1.0.0 → 1.3.1

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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +372 -220
  3. package/dist/commands/delete.d.ts +4 -0
  4. package/dist/commands/delete.js +48 -0
  5. package/dist/commands/export.d.ts +4 -0
  6. package/dist/commands/export.js +104 -0
  7. package/dist/commands/help.d.ts +1 -0
  8. package/dist/commands/help.js +73 -0
  9. package/dist/commands/list.d.ts +5 -0
  10. package/dist/commands/list.js +42 -0
  11. package/dist/commands/mark.d.ts +1 -0
  12. package/dist/commands/mark.js +27 -0
  13. package/dist/commands/pomodoro.d.ts +6 -0
  14. package/dist/commands/pomodoro.js +135 -0
  15. package/dist/commands/resume.d.ts +4 -0
  16. package/dist/commands/resume.js +54 -0
  17. package/dist/commands/search.d.ts +1 -0
  18. package/dist/commands/search.js +36 -0
  19. package/dist/commands/start.d.ts +4 -0
  20. package/dist/commands/start.js +47 -0
  21. package/dist/commands/status.d.ts +1 -0
  22. package/dist/commands/status.js +48 -0
  23. package/dist/commands/stop.d.ts +3 -0
  24. package/dist/commands/stop.js +104 -0
  25. package/dist/commands/summary.d.ts +6 -0
  26. package/dist/commands/summary.js +128 -0
  27. package/dist/commands/sync.d.ts +1 -0
  28. package/dist/commands/sync.js +62 -0
  29. package/dist/data.d.ts +18 -0
  30. package/dist/data.js +161 -0
  31. package/dist/i18n.d.ts +7 -0
  32. package/dist/i18n.js +418 -0
  33. package/dist/index.js +142 -492
  34. package/dist/mascot.d.ts +9 -0
  35. package/dist/mascot.js +200 -0
  36. package/dist/parser.d.ts +6 -0
  37. package/dist/parser.js +45 -0
  38. package/dist/tui/countdown.d.ts +8 -0
  39. package/dist/tui/countdown.js +135 -0
  40. package/dist/tui/dashboard.d.ts +2 -0
  41. package/dist/tui/dashboard.js +135 -0
  42. package/dist/tui/index.d.ts +2 -0
  43. package/dist/tui/index.js +8 -0
  44. package/dist/tui/lifecycle.d.ts +28 -0
  45. package/dist/tui/lifecycle.js +82 -0
  46. package/dist/tui/reflection.d.ts +5 -0
  47. package/dist/tui/reflection.js +71 -0
  48. package/dist/types.d.ts +24 -0
  49. package/dist/types.js +2 -0
  50. package/dist/utils.d.ts +5 -0
  51. package/dist/utils.js +44 -0
  52. package/package.json +39 -6
package/dist/i18n.js ADDED
@@ -0,0 +1,418 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setLocale = setLocale;
4
+ exports.getLocale = getLocale;
5
+ exports.detectLocale = detectLocale;
6
+ exports.resolveLocale = resolveLocale;
7
+ exports.t = t;
8
+ let currentLocale = 'zh';
9
+ function setLocale(locale) {
10
+ currentLocale = locale;
11
+ }
12
+ function getLocale() {
13
+ return currentLocale;
14
+ }
15
+ // ---- Locale detection ----
16
+ function detectLocale() {
17
+ const intlLocale = Intl.DateTimeFormat().resolvedOptions().locale;
18
+ if (intlLocale.startsWith('zh'))
19
+ return 'zh';
20
+ return 'en';
21
+ }
22
+ function resolveLocale(cliFlag, storedLang) {
23
+ if (cliFlag === 'zh' || cliFlag === 'en')
24
+ return cliFlag;
25
+ if (storedLang === 'zh' || storedLang === 'en')
26
+ return storedLang;
27
+ return detectLocale();
28
+ }
29
+ // ---- String maps ----
30
+ const strings = {
31
+ zh: {
32
+ // Greetings
33
+ 'greeting.lateNight': '夜深了',
34
+ 'greeting.morning': '早上好',
35
+ 'greeting.afternoon': '下午好',
36
+ 'greeting.evening': '晚上好',
37
+ // Common
38
+ 'common.noActiveTask': '当前没有进行中的任务',
39
+ 'common.useStartToBegin': '使用 tk start "任务名" 开始新任务',
40
+ 'common.alreadyActive': '已有进行中的任务,请先使用 tk stop 结束',
41
+ 'common.useStopFirst': '请先使用 tk stop 结束当前任务',
42
+ 'common.noHistory': '暂无记录',
43
+ 'common.notFound': '未找到匹配记录',
44
+ 'common.noData': '无数据',
45
+ 'common.deleted': '已删除',
46
+ 'common.resumed': '已恢复',
47
+ 'common.task': '任务',
48
+ 'common.tags': '标签',
49
+ 'common.start': '开始',
50
+ 'common.duration': '时长',
51
+ 'common.marks': '标记',
52
+ 'common.estimate': '预计',
53
+ 'common.running': '进行中',
54
+ 'common.id': 'ID',
55
+ 'common.idle': '😴 当前没有进行中的任务',
56
+ // cmd: start
57
+ 'cmd.start.recording': '开始记录',
58
+ 'cmd.start.taskLabel': '任务',
59
+ 'cmd.start.tagLabel': '标签',
60
+ 'cmd.start.estimateLabel': '预计',
61
+ 'cmd.start.startLabel': '开始',
62
+ 'cmd.start.unnamedTask': '未命名任务',
63
+ // cmd: mark
64
+ 'cmd.mark.marked': '✓ 已标记',
65
+ 'cmd.mark.markPoint': '标记点',
66
+ 'cmd.mark.elapsed': '已用时',
67
+ 'cmd.mark.noActive': '没有进行中的任务,请先用 tk start 开始',
68
+ // cmd: stop
69
+ 'cmd.stop.taskComplete': '任务完成!',
70
+ 'cmd.stop.taskSummary': '📊 任务总结',
71
+ 'cmd.stop.efficiencyScore': '效率分',
72
+ 'cmd.stop.noEstimate': '未设置预估时长,无法计算效率分',
73
+ 'cmd.stop.noActive': '没有进行中的任务',
74
+ 'cmd.stop.marksCount': '个',
75
+ // cmd: status
76
+ 'cmd.status.inProgress': '🔥 进行中',
77
+ 'cmd.status.idle': '当前没有进行中的任务',
78
+ 'cmd.status.useStartToBegin': '使用 tk start "任务名" 开始新任务',
79
+ // cmd: list
80
+ 'cmd.list.historyTitle': '历史记录',
81
+ 'cmd.list.noRecords': '📭 暂无记录',
82
+ // cmd: search
83
+ 'cmd.search.searchFor': '搜索: "{keyword}"',
84
+ 'cmd.search.found': '找到 {count} 条记录:',
85
+ 'cmd.search.noMatch': '🔍 未找到匹配记录',
86
+ // cmd: sync
87
+ 'cmd.sync.configured': '同步已配置',
88
+ 'cmd.sync.syncPath': '📂 同步路径: {path}',
89
+ 'cmd.sync.syncTip': '💡 提示: 可将文件放在 Dropbox/iCloud/OneDrive 等同步目录',
90
+ 'cmd.sync.emptyPath': '⚠ 请提供同步文件路径',
91
+ 'cmd.sync.dirNotExist': '⚠ 目录不存在: {dir}',
92
+ // cmd: help
93
+ 'cmd.help.title': 'CACE TIMER - 命令帮助',
94
+ 'cmd.help.start': 'tk start <任务名> [选项]',
95
+ 'cmd.help.startDesc': '开始新任务',
96
+ 'cmd.help.startTag': '--tag <标签> 添加标签(可多个: --tag dev --tag api 或 --tag dev,api)',
97
+ 'cmd.help.startEstimate': '--estimate <分钟> 预估时长',
98
+ 'cmd.help.mark': 'tk mark <备注>',
99
+ 'cmd.help.markDesc': '记录时间点',
100
+ 'cmd.help.stop': 'tk stop',
101
+ 'cmd.help.stopDesc': '结束当前任务(显示效率评分)',
102
+ 'cmd.help.status': 'tk status',
103
+ 'cmd.help.statusDesc': '查看当前状态',
104
+ 'cmd.help.list': 'tk list [选项]',
105
+ 'cmd.help.listDesc': '查看历史记录',
106
+ 'cmd.help.listToday': '--today 仅今天',
107
+ 'cmd.help.listTag': '--tag <标签> 按标签筛选',
108
+ 'cmd.help.listLimit': '--limit <数量> 限制数量',
109
+ 'cmd.help.search': 'tk search <关键词>',
110
+ 'cmd.help.searchDesc': '搜索记录',
111
+ 'cmd.help.sync': 'tk sync <文件路径>',
112
+ 'cmd.help.syncDesc': '设置同步文件路径',
113
+ 'cmd.help.summary': 'tk summary [选项]',
114
+ 'cmd.help.summaryDesc': '统计报表',
115
+ 'cmd.help.summaryToday': '--today 仅今天',
116
+ 'cmd.help.summaryWeek': '--week 本周',
117
+ 'cmd.help.summaryMonth': '--month 本月',
118
+ 'cmd.help.summaryTag': '--tag <标签> 按标签筛选',
119
+ 'cmd.help.delete': 'tk delete <id | --last>',
120
+ 'cmd.help.deleteDesc': '删除记录',
121
+ 'cmd.help.resume': 'tk resume <id | --last>',
122
+ 'cmd.help.resumeDesc': '恢复任务',
123
+ 'cmd.help.export': 'tk export [选项]',
124
+ 'cmd.help.exportDesc': '导出数据',
125
+ 'cmd.help.exportFormat': '--format csv|markdown 输出格式(默认 csv)',
126
+ 'cmd.help.exportOutput': '--output <文件> 输出到文件',
127
+ 'cmd.help.pomodoro': 'tk pomodoro <任务名> [选项]',
128
+ 'cmd.help.pomodoroDesc': '番茄钟',
129
+ 'cmd.help.pomodoroWork': '--work <分钟> 工作时长(默认 25)',
130
+ 'cmd.help.pomodoroBreak': '--break <分钟> 休息时长(默认 5)',
131
+ 'cmd.help.pomodoroRounds': '--rounds <数量> 轮数(默认 4)',
132
+ 'cmd.help.pomodoroTag': '--tag <标签> 添加标签',
133
+ 'cmd.help.lang': '--lang zh|en 设置语言',
134
+ 'cmd.help.help': 'tk help',
135
+ 'cmd.help.helpDesc': '显示帮助',
136
+ // cmd: summary
137
+ 'cmd.summary.title': '统计报表',
138
+ 'cmd.summary.totalSessions': '总会话数',
139
+ 'cmd.summary.totalDuration': '总时长',
140
+ 'cmd.summary.avgDuration': '平均时长',
141
+ 'cmd.summary.tagBreakdown': '标签分布',
142
+ 'cmd.summary.dailyHours': '每日时长',
143
+ 'cmd.summary.dailyHoursLabel': '近 7 天',
144
+ 'cmd.summary.top5': '最长任务 Top 5',
145
+ 'cmd.summary.noData': '暂无统计数据',
146
+ 'cmd.summary.sessions': '个会话',
147
+ // cmd: delete
148
+ 'cmd.delete.specify': '请指定要删除的会话 ID 或使用 --last',
149
+ 'cmd.delete.notFound': '未找到该会话',
150
+ 'cmd.delete.deleted': '已删除会话: {task}',
151
+ 'cmd.delete.deletedLast': '已删除最近一条记录: {task}',
152
+ 'cmd.delete.noHistory': '暂无记录可删除',
153
+ // cmd: resume
154
+ 'cmd.resume.specify': '请指定要恢复的会话 ID 或使用 --last',
155
+ 'cmd.resume.notFound': '未找到该会话',
156
+ 'cmd.resume.resumed': '已恢复任务: {task}',
157
+ 'cmd.resume.noHistory': '暂无记录可恢复',
158
+ // cmd: export
159
+ 'cmd.export.noData': '暂无数据可导出',
160
+ 'cmd.export.exportedTo': '已导出到: {path}',
161
+ 'cmd.export.unsupportedFormat': '不支持的格式,请使用 csv 或 markdown',
162
+ 'cmd.export.defaultOutput': '输出到 stdout',
163
+ // cmd: pomodoro
164
+ 'cmd.pomodoro.round': '第 {round}/{total} 轮',
165
+ 'cmd.pomodoro.workPhase': '工作',
166
+ 'cmd.pomodoro.breakPhase': '休息',
167
+ 'cmd.pomodoro.workDone': '工作阶段完成!',
168
+ 'cmd.pomodoro.breakDone': '休息结束',
169
+ 'cmd.pomodoro.breakTime': '休息时间',
170
+ 'cmd.pomodoro.complete': '番茄钟全部完成!',
171
+ 'cmd.pomodoro.totalWork': '总工作时间',
172
+ 'cmd.pomodoro.totalBreak': '总休息时间',
173
+ 'cmd.pomodoro.roundsCompleted': '完成轮数',
174
+ 'cmd.pomodoro.interrupted': '番茄钟已中断',
175
+ 'cmd.pomodoro.starting': '番茄钟开始',
176
+ // Score / Level / Streak
177
+ 'score.earned': '+{points} 积分',
178
+ 'score.total': '总积分',
179
+ 'score.level': '等级',
180
+ 'score.progress': '{current}/{needed} 升级',
181
+ 'score.streak': '连续打卡',
182
+ 'score.streakDays': '{days} 天',
183
+ 'score.streakFire': '🔥 连续 {days} 天!',
184
+ 'score.newStreak': '🎉 开始新的打卡记录!',
185
+ // Reflection
186
+ 'cmd.stop.reflection': '💭 心得感悟(可选,按 Enter 跳过)',
187
+ 'cmd.stop.reflectionSaved': '心得已保存',
188
+ // Focus shortcut
189
+ 'cmd.focus.alias': '快捷专注',
190
+ 'cmd.focus.start': '开始专注: {task} ({minutes}分钟)',
191
+ 'cmd.focus.encourage1': '💪 加油,专注就是力量!',
192
+ 'cmd.focus.encourage2': '🎯 保持专注,你在进步!',
193
+ 'cmd.focus.encourage3': '⭐ 你做得很棒!继续!',
194
+ 'cmd.focus.encourage4': '🚀 专注中的你最有魅力!',
195
+ 'cmd.focus.encourage5': '🌸 每一分钟的专注都算数!',
196
+ 'cmd.focus.encourage6': '✨ 深呼吸,继续前进!',
197
+ // Guardian / Mascot moods
198
+ 'mascot.encourage1': 'CACE 正在注视着你...',
199
+ 'mascot.encourage2': 'CACE 相信你可以的!',
200
+ 'mascot.encourage3': 'CACE: 坚持住!',
201
+ 'mascot.focused': '😤 专注中...',
202
+ 'mascot.celebrating': '🎉 太棒了!',
203
+ 'mascot.disappointed': '😴 别灰心,明天再来!',
204
+ // Status enhancements
205
+ 'cmd.status.level': '📊 Lv.{level} | {score} pts',
206
+ 'cmd.status.streak': '{fire} 连续 {days} 天',
207
+ 'cmd.status.noStreak': '今天开始打卡吧!',
208
+ // Help additions
209
+ 'cmd.help.focus': 'tk focus <5|15|30|60> [任务名]',
210
+ 'cmd.help.focusDesc': '快捷专注(等同于番茄钟)',
211
+ 'cmd.help.stopReflection': ' --reflection <text> 记录心得感悟',
212
+ // Error
213
+ 'error.unknownCommand': '未知命令: {command}',
214
+ 'error.useHelp': '使用 tk help 查看帮助',
215
+ },
216
+ en: {
217
+ // Greetings
218
+ 'greeting.lateNight': 'Late night',
219
+ 'greeting.morning': 'Good morning',
220
+ 'greeting.afternoon': 'Good afternoon',
221
+ 'greeting.evening': 'Good evening',
222
+ // Common
223
+ 'common.noActiveTask': 'No active task',
224
+ 'common.useStartToBegin': 'Use tk start "task name" to begin',
225
+ 'common.alreadyActive': 'Already have an active task, use tk stop first',
226
+ 'common.useStopFirst': 'Please stop the current task first with tk stop',
227
+ 'common.noHistory': 'No records yet',
228
+ 'common.notFound': 'No matching records found',
229
+ 'common.noData': 'No data',
230
+ 'common.deleted': 'Deleted',
231
+ 'common.resumed': 'Resumed',
232
+ 'common.task': 'Task',
233
+ 'common.tags': 'Tags',
234
+ 'common.start': 'Start',
235
+ 'common.duration': 'Duration',
236
+ 'common.marks': 'Marks',
237
+ 'common.estimate': 'Estimate',
238
+ 'common.running': 'Running',
239
+ 'common.id': 'ID',
240
+ 'common.idle': '😴 No active task',
241
+ // cmd: start
242
+ 'cmd.start.recording': 'Recording',
243
+ 'cmd.start.taskLabel': 'Task',
244
+ 'cmd.start.tagLabel': 'Tags',
245
+ 'cmd.start.estimateLabel': 'Estimate',
246
+ 'cmd.start.startLabel': 'Start',
247
+ 'cmd.start.unnamedTask': 'Untitled task',
248
+ // cmd: mark
249
+ 'cmd.mark.marked': '✓ Marked',
250
+ 'cmd.mark.markPoint': 'Mark point',
251
+ 'cmd.mark.elapsed': 'Elapsed',
252
+ 'cmd.mark.noActive': 'No active task, use tk start first',
253
+ // cmd: stop
254
+ 'cmd.stop.taskComplete': 'Task complete!',
255
+ 'cmd.stop.taskSummary': '📊 Task Summary',
256
+ 'cmd.stop.efficiencyScore': 'Efficiency',
257
+ 'cmd.stop.noEstimate': 'No estimate set, cannot calculate efficiency',
258
+ 'cmd.stop.noActive': 'No active task',
259
+ 'cmd.stop.marksCount': 'marks',
260
+ // cmd: status
261
+ 'cmd.status.inProgress': '🔥 In progress',
262
+ 'cmd.status.idle': 'No active task',
263
+ 'cmd.status.useStartToBegin': 'Use tk start "task name" to begin',
264
+ // cmd: list
265
+ 'cmd.list.historyTitle': 'History',
266
+ 'cmd.list.noRecords': '📭 No records yet',
267
+ // cmd: search
268
+ 'cmd.search.searchFor': 'Search: "{keyword}"',
269
+ 'cmd.search.found': 'Found {count} records:',
270
+ 'cmd.search.noMatch': '🔍 No matching records',
271
+ // cmd: sync
272
+ 'cmd.sync.configured': 'Sync configured',
273
+ 'cmd.sync.syncPath': '📂 Sync path: {path}',
274
+ 'cmd.sync.syncTip': '💡 Tip: Place the file in a synced folder like Dropbox/iCloud/OneDrive',
275
+ 'cmd.sync.emptyPath': '⚠ Please provide a sync file path',
276
+ 'cmd.sync.dirNotExist': '⚠ Directory does not exist: {dir}',
277
+ // cmd: help
278
+ 'cmd.help.title': 'CACE TIMER - Help',
279
+ 'cmd.help.start': 'tk start <task> [options]',
280
+ 'cmd.help.startDesc': 'Start a new task',
281
+ 'cmd.help.startTag': '--tag <tag> Add tag(s) (--tag dev --tag api or --tag dev,api)',
282
+ 'cmd.help.startEstimate': '--estimate <min> Estimated duration',
283
+ 'cmd.help.mark': 'tk mark <note>',
284
+ 'cmd.help.markDesc': 'Record a time checkpoint',
285
+ 'cmd.help.stop': 'tk stop',
286
+ 'cmd.help.stopDesc': 'Stop current task (show efficiency score)',
287
+ 'cmd.help.status': 'tk status',
288
+ 'cmd.help.statusDesc': 'Show current status',
289
+ 'cmd.help.list': 'tk list [options]',
290
+ 'cmd.help.listDesc': 'View history',
291
+ 'cmd.help.listToday': '--today Today only',
292
+ 'cmd.help.listTag': '--tag <tag> Filter by tag',
293
+ 'cmd.help.listLimit': '--limit <n> Limit count',
294
+ 'cmd.help.search': 'tk search <keyword>',
295
+ 'cmd.help.searchDesc': 'Search records',
296
+ 'cmd.help.sync': 'tk sync <file-path>',
297
+ 'cmd.help.syncDesc': 'Set sync file path',
298
+ 'cmd.help.summary': 'tk summary [options]',
299
+ 'cmd.help.summaryDesc': 'Statistics report',
300
+ 'cmd.help.summaryToday': '--today Today only',
301
+ 'cmd.help.summaryWeek': '--week This week',
302
+ 'cmd.help.summaryMonth': '--month This month',
303
+ 'cmd.help.summaryTag': '--tag <tag> Filter by tag',
304
+ 'cmd.help.delete': 'tk delete <id | --last>',
305
+ 'cmd.help.deleteDesc': 'Delete a record',
306
+ 'cmd.help.resume': 'tk resume <id | --last>',
307
+ 'cmd.help.resumeDesc': 'Resume a task',
308
+ 'cmd.help.export': 'tk export [options]',
309
+ 'cmd.help.exportDesc': 'Export data',
310
+ 'cmd.help.exportFormat': '--format csv|markdown Output format (default: csv)',
311
+ 'cmd.help.exportOutput': '--output <file> Output to file',
312
+ 'cmd.help.pomodoro': 'tk pomodoro <task> [options]',
313
+ 'cmd.help.pomodoroDesc': 'Pomodoro timer',
314
+ 'cmd.help.pomodoroWork': '--work <min> Work duration (default: 25)',
315
+ 'cmd.help.pomodoroBreak': '--break <min> Break duration (default: 5)',
316
+ 'cmd.help.pomodoroRounds': '--rounds <n> Number of rounds (default: 4)',
317
+ 'cmd.help.pomodoroTag': '--tag <tag> Add tag(s)',
318
+ 'cmd.help.lang': '--lang zh|en Set language',
319
+ 'cmd.help.help': 'tk help',
320
+ 'cmd.help.helpDesc': 'Show help',
321
+ // cmd: summary
322
+ 'cmd.summary.title': 'Statistics',
323
+ 'cmd.summary.totalSessions': 'Total sessions',
324
+ 'cmd.summary.totalDuration': 'Total duration',
325
+ 'cmd.summary.avgDuration': 'Average duration',
326
+ 'cmd.summary.tagBreakdown': 'Tag breakdown',
327
+ 'cmd.summary.dailyHours': 'Daily hours',
328
+ 'cmd.summary.dailyHoursLabel': 'Last 7 days',
329
+ 'cmd.summary.top5': 'Top 5 longest tasks',
330
+ 'cmd.summary.noData': 'No data for this period',
331
+ 'cmd.summary.sessions': 'sessions',
332
+ // cmd: delete
333
+ 'cmd.delete.specify': 'Specify a session ID or use --last',
334
+ 'cmd.delete.notFound': 'Session not found',
335
+ 'cmd.delete.deleted': 'Session deleted: {task}',
336
+ 'cmd.delete.deletedLast': 'Deleted most recent record: {task}',
337
+ 'cmd.delete.noHistory': 'No records to delete',
338
+ // cmd: resume
339
+ 'cmd.resume.specify': 'Specify a session ID or use --last',
340
+ 'cmd.resume.notFound': 'Session not found',
341
+ 'cmd.resume.resumed': 'Task resumed: {task}',
342
+ 'cmd.resume.noHistory': 'No records to resume',
343
+ // cmd: export
344
+ 'cmd.export.noData': 'No data to export',
345
+ 'cmd.export.exportedTo': 'Exported to: {path}',
346
+ 'cmd.export.unsupportedFormat': 'Unsupported format, use csv or markdown',
347
+ 'cmd.export.defaultOutput': 'Output to stdout',
348
+ // cmd: pomodoro
349
+ 'cmd.pomodoro.round': 'Round {round}/{total}',
350
+ 'cmd.pomodoro.workPhase': 'Work',
351
+ 'cmd.pomodoro.breakPhase': 'Break',
352
+ 'cmd.pomodoro.workDone': 'Work phase done!',
353
+ 'cmd.pomodoro.breakDone': 'Break over',
354
+ 'cmd.pomodoro.breakTime': 'Break time',
355
+ 'cmd.pomodoro.complete': 'All pomodoro rounds complete!',
356
+ 'cmd.pomodoro.totalWork': 'Total work time',
357
+ 'cmd.pomodoro.totalBreak': 'Total break time',
358
+ 'cmd.pomodoro.roundsCompleted': 'Rounds completed',
359
+ 'cmd.pomodoro.interrupted': 'Pomodoro interrupted',
360
+ 'cmd.pomodoro.starting': 'Pomodoro starting',
361
+ // Score / Level / Streak
362
+ 'score.earned': '+{points} pts',
363
+ 'score.total': 'Total score',
364
+ 'score.level': 'Level',
365
+ 'score.progress': '{current}/{needed} to next',
366
+ 'score.streak': 'Streak',
367
+ 'score.streakDays': '{days} days',
368
+ 'score.streakFire': '🔥 {days} day streak!',
369
+ 'score.newStreak': '🎉 New streak started!',
370
+ // Reflection
371
+ 'cmd.stop.reflection': '💭 Reflection (optional, press Enter to skip)',
372
+ 'cmd.stop.reflectionSaved': 'Reflection saved',
373
+ // Focus shortcut
374
+ 'cmd.focus.alias': 'Quick focus',
375
+ 'cmd.focus.start': 'Focus: {task} ({minutes}min)',
376
+ 'cmd.focus.encourage1': '💪 Keep going, focus is power!',
377
+ 'cmd.focus.encourage2': '🎯 Stay focused, you are improving!',
378
+ 'cmd.focus.encourage3': '⭐ You are doing great! Keep it up!',
379
+ 'cmd.focus.encourage4': '🚀 You shine brightest when focused!',
380
+ 'cmd.focus.encourage5': '🌸 Every minute of focus counts!',
381
+ 'cmd.focus.encourage6': '✨ Take a deep breath, keep going!',
382
+ // Guardian / Mascot moods
383
+ 'mascot.encourage1': 'CACE is watching you...',
384
+ 'mascot.encourage2': 'CACE believes in you!',
385
+ 'mascot.encourage3': 'CACE: Hang in there!',
386
+ 'mascot.focused': '😤 Focused...',
387
+ 'mascot.celebrating': '🎉 Awesome!',
388
+ 'mascot.disappointed': '😴 Don\'t worry, try again tomorrow!',
389
+ // Status enhancements
390
+ 'cmd.status.level': '📊 Lv.{level} | {score} pts',
391
+ 'cmd.status.streak': '{fire} {days} day streak',
392
+ 'cmd.status.noStreak': 'Start your streak today!',
393
+ // Help additions
394
+ 'cmd.help.focus': 'tk focus <5|15|30|60> [task]',
395
+ 'cmd.help.focusDesc': 'Quick focus (same as pomodoro)',
396
+ 'cmd.help.stopReflection': ' --reflection <text> Save reflection',
397
+ // Error
398
+ 'error.unknownCommand': 'Unknown command: {command}',
399
+ 'error.useHelp': 'Use tk help for help',
400
+ },
401
+ };
402
+ // ---- t() lookup ----
403
+ function t(key, params) {
404
+ const map = strings[currentLocale];
405
+ let result = map[key];
406
+ if (result === undefined) {
407
+ // Fallback to zh if key missing in current locale
408
+ result = strings.zh[key];
409
+ }
410
+ if (result === undefined)
411
+ return key;
412
+ if (params) {
413
+ for (const [k, v] of Object.entries(params)) {
414
+ result = result.replace(new RegExp(`\\{${k}\\}`, 'g'), String(v));
415
+ }
416
+ }
417
+ return result;
418
+ }