@nbtca/prompt 1.0.23 → 1.0.25

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 (83) hide show
  1. package/dist/config/data.js +5 -1
  2. package/dist/config/paths.js +24 -0
  3. package/dist/config/preferences.js +4 -15
  4. package/dist/core/icons.js +18 -5
  5. package/dist/core/logo.js +1 -2
  6. package/dist/core/menu.js +7 -122
  7. package/dist/core/text.js +23 -14
  8. package/dist/core/ui.js +16 -1
  9. package/dist/core/vim-keys.js +11 -6
  10. package/dist/features/calendar.js +66 -16
  11. package/dist/features/docs.js +270 -131
  12. package/dist/features/links.js +37 -0
  13. package/dist/features/settings.js +120 -0
  14. package/dist/features/status.js +28 -32
  15. package/dist/features/theme.js +9 -101
  16. package/dist/features/update.js +74 -0
  17. package/dist/i18n/index.js +20 -21
  18. package/dist/i18n/locales/en.json +43 -54
  19. package/dist/i18n/locales/zh.json +43 -54
  20. package/dist/index.js +115 -84
  21. package/dist/main.js +13 -14
  22. package/package.json +13 -11
  23. package/dist/config/data.d.ts +0 -23
  24. package/dist/config/data.d.ts.map +0 -1
  25. package/dist/config/data.js.map +0 -1
  26. package/dist/config/preferences.d.ts +0 -14
  27. package/dist/config/preferences.d.ts.map +0 -1
  28. package/dist/config/preferences.js.map +0 -1
  29. package/dist/config/theme.d.ts +0 -23
  30. package/dist/config/theme.d.ts.map +0 -1
  31. package/dist/config/theme.js +0 -25
  32. package/dist/config/theme.js.map +0 -1
  33. package/dist/core/icons.d.ts +0 -3
  34. package/dist/core/icons.d.ts.map +0 -1
  35. package/dist/core/icons.js.map +0 -1
  36. package/dist/core/logo.d.ts +0 -9
  37. package/dist/core/logo.d.ts.map +0 -1
  38. package/dist/core/logo.js.map +0 -1
  39. package/dist/core/menu.d.ts +0 -14
  40. package/dist/core/menu.d.ts.map +0 -1
  41. package/dist/core/menu.js.map +0 -1
  42. package/dist/core/text.d.ts +0 -7
  43. package/dist/core/text.d.ts.map +0 -1
  44. package/dist/core/text.js.map +0 -1
  45. package/dist/core/ui.d.ts +0 -38
  46. package/dist/core/ui.d.ts.map +0 -1
  47. package/dist/core/ui.js.map +0 -1
  48. package/dist/core/vim-keys.d.ts +0 -8
  49. package/dist/core/vim-keys.d.ts.map +0 -1
  50. package/dist/core/vim-keys.js.map +0 -1
  51. package/dist/features/calendar.d.ts +0 -29
  52. package/dist/features/calendar.d.ts.map +0 -1
  53. package/dist/features/calendar.js.map +0 -1
  54. package/dist/features/docs.d.ts +0 -8
  55. package/dist/features/docs.d.ts.map +0 -1
  56. package/dist/features/docs.js.map +0 -1
  57. package/dist/features/repair.d.ts +0 -10
  58. package/dist/features/repair.d.ts.map +0 -1
  59. package/dist/features/repair.js +0 -29
  60. package/dist/features/repair.js.map +0 -1
  61. package/dist/features/status.d.ts +0 -31
  62. package/dist/features/status.d.ts.map +0 -1
  63. package/dist/features/status.js.map +0 -1
  64. package/dist/features/theme.d.ts +0 -8
  65. package/dist/features/theme.d.ts.map +0 -1
  66. package/dist/features/theme.js.map +0 -1
  67. package/dist/features/website.d.ts +0 -30
  68. package/dist/features/website.d.ts.map +0 -1
  69. package/dist/features/website.js +0 -48
  70. package/dist/features/website.js.map +0 -1
  71. package/dist/i18n/index.d.ts +0 -209
  72. package/dist/i18n/index.d.ts.map +0 -1
  73. package/dist/i18n/index.js.map +0 -1
  74. package/dist/index.d.ts +0 -5
  75. package/dist/index.d.ts.map +0 -1
  76. package/dist/index.js.map +0 -1
  77. package/dist/main.d.ts +0 -12
  78. package/dist/main.d.ts.map +0 -1
  79. package/dist/main.js.map +0 -1
  80. package/dist/types.d.ts +0 -48
  81. package/dist/types.d.ts.map +0 -1
  82. package/dist/types.js +0 -6
  83. package/dist/types.js.map +0 -1
@@ -7,35 +7,20 @@
7
7
  "loading": "Loading...",
8
8
  "error": "Error",
9
9
  "success": "Success",
10
- "goodbye": "Goodbye!"
10
+ "goodbye": "Goodbye!",
11
+ "current": "current"
11
12
  },
12
13
  "menu": {
13
- "title": "Choose an action",
14
- "events": "Recent Events",
15
- "eventsDesc": "View upcoming events in next 30 days",
16
- "repair": "Repair Service",
17
- "repairDesc": "Computer repair and software installation",
18
- "docs": "Knowledge Base",
19
- "docsDesc": "Technical docs and tutorials",
20
- "website": "Official Website",
21
- "websiteDesc": "Visit NBTCA homepage",
22
- "github": "GitHub",
23
- "githubDesc": "Open source projects and code",
24
- "roadmap": "Roadmap",
25
- "roadmapDesc": "Open NBTCA roadmap project board",
14
+ "events": "Events",
15
+ "eventsDesc": "Upcoming activities",
16
+ "docs": "Docs",
17
+ "docsDesc": "Knowledge base",
18
+ "status": "Status",
19
+ "statusDesc": "Service health",
26
20
  "links": "Links",
27
- "linksDesc": "Website | GitHub | Roadmap",
28
- "chooseLink": "Choose a link:",
29
- "about": "About",
30
- "aboutDesc": "Project info and help",
31
- "status": "Service Status",
32
- "statusDesc": "Check service health in terminal",
33
- "language": "Language",
34
- "languageDesc": "Change display language",
35
- "theme": "Theme",
36
- "themeDesc": "Configure icons and color mode",
37
- "navigationHint": "Navigation: j/k or up/down | Jump: g/G | Quit: q or Ctrl+C",
38
- "quickCommandHint": "Tip: use `nbtca <command> --help` for script-friendly mode",
21
+ "linksDesc": "Website, GitHub, Roadmap",
22
+ "settings": "Settings",
23
+ "settingsDesc": "Language, theme, about",
39
24
  "chooseAction": "Choose an action"
40
25
  },
41
26
  "about": {
@@ -50,8 +35,6 @@
50
35
  "author": "Author"
51
36
  },
52
37
  "calendar": {
53
- "title": "Recent Events",
54
- "subtitle": "(Next 30 days)",
55
38
  "loading": "Loading event calendar...",
56
39
  "noEvents": "No upcoming events",
57
40
  "error": "Failed to load event calendar",
@@ -59,11 +42,14 @@
59
42
  "eventsFound": "events found",
60
43
  "dateTime": "Date & Time",
61
44
  "eventName": "Event Name",
62
- "location": "Location"
45
+ "location": "Location",
46
+ "untitledEvent": "Untitled Event",
47
+ "tbdLocation": "TBD",
48
+ "subscribeHint": "Subscribe to calendar",
49
+ "viewDetail": "Select an event for details:",
50
+ "noDescription": "No additional details"
63
51
  },
64
52
  "docs": {
65
- "title": "Knowledge Base",
66
- "subtitle": "Browse documentation from terminal or open in browser",
67
53
  "loading": "Loading documentation list...",
68
54
  "loadingDir": "Loading directory",
69
55
  "categoryTutorial": "Tutorials",
@@ -95,33 +81,27 @@
95
81
  "browserError": "Failed to open browser",
96
82
  "browserErrorHint": "Please visit manually: https://docs.nbtca.space",
97
83
  "retry": "Retry?",
98
- "pagerNotAvailable": "Pager not available, using standard output",
99
84
  "endOfDocument": "End of document - Press q to quit",
100
- "terminalProfile": "Terminal profile",
101
- "terminalSupport": "Support",
102
- "terminalBasic": "Basic",
103
- "terminalEnhanced": "Enhanced",
104
- "terminalAdvanced": "Advanced",
105
- "navigationHint": "Navigation: j/k or up/down | Enter: open | q/Ctrl+C: quit",
106
85
  "githubRateLimited": "GitHub API rate limit reached. Resets at {time}.",
107
86
  "githubForbidden": "GitHub API access denied (403).",
108
87
  "githubTokenHint": "Tip: set GITHUB_TOKEN for a higher rate limit.",
109
88
  "fetchDirFailed": "Failed to fetch directory: {error}",
110
- "fetchFileFailed": "Failed to fetch file: {error}"
111
- },
112
- "repair": {
113
- "title": "Repair Service",
114
- "subtitle": "Computer repair and software installation support",
115
- "opening": "Opening repair service page...",
116
- "opened": "Repair service page opened in browser",
117
- "error": "Failed to open browser",
118
- "errorHint": "Please visit manually: https://nbtca.space/repair"
89
+ "fetchFileFailed": "Failed to fetch file: {error}",
90
+ "searchPrompt": "Search documents by title:",
91
+ "searchPlaceholder": "Enter keyword...",
92
+ "searching": "Searching documents...",
93
+ "searchResults": "results found",
94
+ "searchNoResults": "No documents match your search"
119
95
  },
120
- "website": {
121
- "opening": "Opening website...",
96
+ "links": {
97
+ "choose": "Open a link:",
98
+ "website": "Official Website",
99
+ "github": "GitHub",
100
+ "roadmap": "Roadmap",
101
+ "repair": "Repair Service",
102
+ "opening": "Opening...",
122
103
  "opened": "Opened in browser",
123
- "error": "Failed to open browser",
124
- "errorHint": "Please visit manually"
104
+ "error": "Failed to open browser"
125
105
  },
126
106
  "status": {
127
107
  "checking": "Checking service status...",
@@ -134,6 +114,11 @@
134
114
  "url": "URL",
135
115
  "up": "UP",
136
116
  "down": "DOWN",
117
+ "serviceWebsite": "Website",
118
+ "serviceDocs": "Docs",
119
+ "serviceCalendar": "Calendar",
120
+ "serviceGithub": "GitHub",
121
+ "serviceRoadmap": "Roadmap",
137
122
  "watchStarted": "Starting status watch (every {seconds}s)",
138
123
  "watchUpdated": "Last updated",
139
124
  "watchHint": "Press Ctrl+C to stop",
@@ -146,7 +131,7 @@
146
131
  },
147
132
  "theme": {
148
133
  "current": "Current theme settings",
149
- "chooseAction": "Theme settings",
134
+ "chooseAction": "Settings",
150
135
  "chooseIconMode": "Choose icon mode:",
151
136
  "chooseColorMode": "Choose color mode:",
152
137
  "modeAuto": "Auto",
@@ -165,12 +150,16 @@
165
150
  "invalidValue": "Invalid value. Use one of:"
166
151
  },
167
152
  "language": {
168
- "title": "Language Settings",
169
- "currentLanguage": "Current Language",
170
153
  "selectLanguage": "Select a language:",
171
154
  "zh": "简体中文 (Simplified Chinese)",
172
155
  "en": "English",
173
156
  "changed": "Language changed successfully",
174
157
  "changedSessionOnly": "Language changed for this session only (failed to save config)"
158
+ },
159
+ "update": {
160
+ "available": "Update available: {current} → {latest}",
161
+ "upToDate": "You are on the latest version ({version})",
162
+ "checkFailed": "Could not check for updates",
163
+ "command": "Run: npm i -g @nbtca/prompt"
175
164
  }
176
165
  }
@@ -7,35 +7,20 @@
7
7
  "loading": "加载中...",
8
8
  "error": "错误",
9
9
  "success": "成功",
10
- "goodbye": "再见!"
10
+ "goodbye": "再见!",
11
+ "current": "当前"
11
12
  },
12
13
  "menu": {
13
- "title": "选择操作",
14
- "events": "近期活动",
15
- "eventsDesc": "查看未来30天的活动",
16
- "repair": "维修服务",
17
- "repairDesc": "电脑维修和软件安装",
18
- "docs": "知识库",
19
- "docsDesc": "技术文档和教程",
20
- "website": "官方网站",
21
- "websiteDesc": "访问 NBTCA 主页",
22
- "github": "GitHub",
23
- "githubDesc": "开源项目和代码",
24
- "roadmap": "Roadmap 看板",
25
- "roadmapDesc": "打开 NBTCA 路线图项目看板",
14
+ "events": "活动",
15
+ "eventsDesc": "近期活动安排",
16
+ "docs": "文档",
17
+ "docsDesc": "知识库",
18
+ "status": "状态",
19
+ "statusDesc": "服务健康检查",
26
20
  "links": "链接",
27
- "linksDesc": "主页 / GitHub / 路线图",
28
- "chooseLink": "选择链接:",
29
- "about": "关于",
30
- "aboutDesc": "项目信息和帮助",
31
- "status": "服务状态",
32
- "statusDesc": "在终端检查服务健康状态",
33
- "language": "切换语言",
34
- "languageDesc": "更改显示语言",
35
- "theme": "主题设置",
36
- "themeDesc": "配置图标和颜色模式",
37
- "navigationHint": "导航: j/k 或 up/down | 跳转: g/G | 退出: q 或 Ctrl+C",
38
- "quickCommandHint": "提示: 使用 `nbtca <command> --help` 获取可脚本化模式",
21
+ "linksDesc": "官网、GitHub、路线图",
22
+ "settings": "设置",
23
+ "settingsDesc": "语言、主题、关于",
39
24
  "chooseAction": "选择一个操作"
40
25
  },
41
26
  "about": {
@@ -50,8 +35,6 @@
50
35
  "author": "作者"
51
36
  },
52
37
  "calendar": {
53
- "title": "近期活动",
54
- "subtitle": "(最近30天)",
55
38
  "loading": "正在获取活动日历...",
56
39
  "noEvents": "近期暂无活动安排",
57
40
  "error": "无法获取活动日历",
@@ -59,11 +42,14 @@
59
42
  "eventsFound": "个活动",
60
43
  "dateTime": "日期时间",
61
44
  "eventName": "活动名称",
62
- "location": "地点"
45
+ "location": "地点",
46
+ "untitledEvent": "未命名活动",
47
+ "tbdLocation": "待定",
48
+ "subscribeHint": "订阅日历",
49
+ "viewDetail": "选择活动查看详情:",
50
+ "noDescription": "暂无详细信息"
63
51
  },
64
52
  "docs": {
65
- "title": "知识库",
66
- "subtitle": "从终端浏览文档或在浏览器中打开",
67
53
  "loading": "正在加载文档列表...",
68
54
  "loadingDir": "正在加载目录",
69
55
  "categoryTutorial": "教程",
@@ -95,33 +81,27 @@
95
81
  "browserError": "无法打开浏览器",
96
82
  "browserErrorHint": "请手动访问: https://docs.nbtca.space",
97
83
  "retry": "是否重试?",
98
- "pagerNotAvailable": "Pager不可用,使用标准输出",
99
84
  "endOfDocument": "文档结束 - 按 q 退出",
100
- "terminalProfile": "终端类型",
101
- "terminalSupport": "支持",
102
- "terminalBasic": "基础",
103
- "terminalEnhanced": "增强",
104
- "terminalAdvanced": "高级",
105
- "navigationHint": "导航: j/k 或 up/down | Enter: 打开 | q/Ctrl+C: 退出",
106
85
  "githubRateLimited": "GitHub API 速率限制已达上限,将在 {time} 重置。",
107
86
  "githubForbidden": "GitHub API 拒绝访问 (403)。",
108
87
  "githubTokenHint": "提示: 设置 GITHUB_TOKEN 环境变量可获得更高的速率限制。",
109
88
  "fetchDirFailed": "无法获取目录内容: {error}",
110
- "fetchFileFailed": "无法获取文件内容: {error}"
111
- },
112
- "repair": {
113
- "title": "维修服务",
114
- "subtitle": "电脑维修和软件安装支持",
115
- "opening": "正在打开维修服务页面...",
116
- "opened": "已在浏览器中打开维修服务页面",
117
- "error": "无法打开浏览器",
118
- "errorHint": "请手动访问: https://nbtca.space/repair"
89
+ "fetchFileFailed": "无法获取文件内容: {error}",
90
+ "searchPrompt": "按标题搜索文档:",
91
+ "searchPlaceholder": "输入关键词...",
92
+ "searching": "正在搜索文档...",
93
+ "searchResults": "个结果",
94
+ "searchNoResults": "未找到匹配的文档"
119
95
  },
120
- "website": {
121
- "opening": "正在打开网站...",
96
+ "links": {
97
+ "choose": "打开链接:",
98
+ "website": "官方网站",
99
+ "github": "GitHub",
100
+ "roadmap": "路线图",
101
+ "repair": "维修服务",
102
+ "opening": "正在打开...",
122
103
  "opened": "已在浏览器中打开",
123
- "error": "无法打开浏览器",
124
- "errorHint": "请手动访问"
104
+ "error": "无法打开浏览器"
125
105
  },
126
106
  "status": {
127
107
  "checking": "正在检查服务状态...",
@@ -134,6 +114,11 @@
134
114
  "url": "URL",
135
115
  "up": "正常",
136
116
  "down": "异常",
117
+ "serviceWebsite": "官网",
118
+ "serviceDocs": "文档",
119
+ "serviceCalendar": "日历",
120
+ "serviceGithub": "GitHub",
121
+ "serviceRoadmap": "看板",
137
122
  "watchStarted": "开始监控服务状态(每 {seconds} 秒)",
138
123
  "watchUpdated": "最近更新",
139
124
  "watchHint": "按 Ctrl+C 停止",
@@ -146,7 +131,7 @@
146
131
  },
147
132
  "theme": {
148
133
  "current": "当前主题设置",
149
- "chooseAction": "主题设置",
134
+ "chooseAction": "设置",
150
135
  "chooseIconMode": "选择图标模式:",
151
136
  "chooseColorMode": "选择颜色模式:",
152
137
  "modeAuto": "自动",
@@ -165,12 +150,16 @@
165
150
  "invalidValue": "无效取值,可选:"
166
151
  },
167
152
  "language": {
168
- "title": "语言设置",
169
- "currentLanguage": "当前语言",
170
153
  "selectLanguage": "选择语言:",
171
154
  "zh": "简体中文",
172
155
  "en": "English",
173
156
  "changed": "语言已切换",
174
157
  "changedSessionOnly": "语言仅在当前会话生效(无法写入配置文件)"
158
+ },
159
+ "update": {
160
+ "available": "有新版本可用: {current} → {latest}",
161
+ "upToDate": "已是最新版本 ({version})",
162
+ "checkFailed": "无法检查更新",
163
+ "command": "运行: npm i -g @nbtca/prompt"
175
164
  }
176
165
  }
package/dist/index.js CHANGED
@@ -2,18 +2,18 @@
2
2
  * NBTCA Prompt entry point
3
3
  */
4
4
  import chalk from 'chalk';
5
+ import open from 'open';
5
6
  import { main } from './main.js';
6
- import { runMenuAction } from './core/menu.js';
7
7
  import { fetchEvents, renderEventsTable, serializeEvents } from './features/calendar.js';
8
8
  import { checkServices, countServiceHealth, hasServiceFailures, renderServiceStatusTable, serializeServiceStatus } from './features/status.js';
9
9
  import { pickIcon } from './core/icons.js';
10
10
  import { applyColorModePreference } from './config/preferences.js';
11
11
  import { openDocsInBrowser } from './features/docs.js';
12
12
  import { runThemeCommand } from './features/theme.js';
13
- import { REPAIR_URL } from './features/repair.js';
14
- import { WEBSITE_URLS } from './features/website.js';
15
- import { setLanguage, t } from './i18n/index.js';
16
- import { clearScreen } from './core/ui.js';
13
+ import { setLanguage, t, fmt } from './i18n/index.js';
14
+ import { clearScreen, handleGracefulExit } from './core/ui.js';
15
+ import { APP_INFO, URLS } from './config/data.js';
16
+ import { runUpdateCheck } from './features/update.js';
17
17
  const ACTION_ALIASES = {
18
18
  events: 'events',
19
19
  event: 'events',
@@ -30,13 +30,13 @@ const ACTION_ALIASES = {
30
30
  status: 'status',
31
31
  };
32
32
  const URL_ACTIONS = {
33
- repair: REPAIR_URL,
34
- website: WEBSITE_URLS.homepage,
35
- github: WEBSITE_URLS.github,
36
- roadmap: WEBSITE_URLS.roadmap
33
+ repair: URLS.repair,
34
+ website: URLS.homepage,
35
+ github: URLS.github,
36
+ roadmap: URLS.roadmap
37
37
  };
38
- const KNOWN_FLAGS = new Set(['--help', '--open', '--json', '--plain', '--no-logo', '--watch']);
39
- const KNOWN_FLAG_PREFIXES = ['--interval=', '--timeout=', '--retries='];
38
+ const KNOWN_FLAGS = new Set(['--help', '--version', '--open', '--json', '--plain', '--no-logo', '--watch', '--today']);
39
+ const KNOWN_FLAG_PREFIXES = ['--interval=', '--timeout=', '--retries=', '--next='];
40
40
  const STATUS_WATCH_INTERVAL_MIN = 3;
41
41
  const STATUS_WATCH_INTERVAL_MAX = 300;
42
42
  const STATUS_TIMEOUT_MIN = 1000;
@@ -67,21 +67,20 @@ function getAllowedFlagsFor(command) {
67
67
  const allowed = new Set(['--help', '--plain']);
68
68
  if (!command) {
69
69
  allowed.add('--no-logo');
70
+ allowed.add('--version');
70
71
  return allowed;
71
72
  }
72
- if (command === 'lang' || command === 'language') {
73
+ if (command === 'lang' || command === 'language')
73
74
  return allowed;
74
- }
75
- if (command === 'theme') {
75
+ if (command === 'theme')
76
76
  return allowed;
77
- }
78
77
  const action = ACTION_ALIASES[command];
79
- if (!action) {
78
+ if (!action)
80
79
  return allowed;
81
- }
82
80
  switch (action) {
83
81
  case 'events':
84
82
  allowed.add('--json');
83
+ allowed.add('--today');
85
84
  return allowed;
86
85
  case 'status':
87
86
  allowed.add('--json');
@@ -103,9 +102,10 @@ function getAllowedFlagPrefixesFor(command) {
103
102
  if (!command)
104
103
  return [];
105
104
  const action = ACTION_ALIASES[command];
106
- if (action === 'status') {
105
+ if (action === 'events')
106
+ return ['--next='];
107
+ if (action === 'status')
107
108
  return ['--interval=', '--timeout=', '--retries='];
108
- }
109
109
  return [];
110
110
  }
111
111
  function validateFlags(command, flags) {
@@ -136,36 +136,55 @@ function printHelp() {
136
136
  console.log(chalk.bold('NBTCA Prompt'));
137
137
  console.log();
138
138
  console.log('Usage:');
139
- console.log(' nbtca Start interactive menu');
140
- console.log(' nbtca <command> [flags] Run one command directly');
141
- console.log(' nbtca lang <zh|en> Set language preference');
142
- console.log(' nbtca theme ... Configure icon and color mode');
139
+ console.log(' nbtca Interactive menu');
140
+ console.log(' nbtca <command> [flags] Run a command');
143
141
  console.log();
144
142
  console.log('Commands:');
145
- console.log(' events | status | repair | docs | website | github | roadmap | about | theme');
143
+ console.log(' events Upcoming activities');
144
+ console.log(' docs Knowledge base');
145
+ console.log(' status Service health');
146
+ console.log(' website Official website URL');
147
+ console.log(' github GitHub organization URL');
148
+ console.log(' roadmap Project roadmap URL');
149
+ console.log(' repair Repair service URL');
150
+ console.log(' theme View or set theme');
151
+ console.log(' lang <zh|en> Set language');
152
+ console.log(' update Check for updates');
146
153
  console.log();
147
154
  console.log('Flags:');
148
- console.log(' --help Show help');
149
- console.log(' --open Open browser for URL commands');
150
- console.log(' --json JSON output (supported by `events`, `status`)');
151
- console.log(' --watch Continuously refresh status output (`status` only)');
152
- console.log(' --interval=<seconds> Refresh interval for `status --watch` (3-300)');
153
- console.log(' --timeout=<ms> HTTP timeout for status checks (1000-20000)');
154
- console.log(' --retries=<n> Retry count for transient status failures (0-5)');
155
- console.log(' --plain Disable color output');
156
- console.log(' --no-logo Skip startup logo in menu mode');
157
- console.log();
158
- console.log('Examples:');
159
- console.log(' nbtca events --json');
160
- console.log(' nbtca status --json');
161
- console.log(' nbtca status --watch --interval=10');
162
- console.log(' nbtca status --timeout=8000 --retries=2');
163
- console.log(' nbtca theme icon ascii');
164
- console.log(' nbtca roadmap');
165
- console.log(' nbtca roadmap --open');
155
+ console.log(' --version Show version');
156
+ console.log(' --help Show help');
157
+ console.log(' --open Open in browser (URL commands)');
158
+ console.log(' --json JSON output (events, status)');
159
+ console.log(' --today Today only (events)');
160
+ console.log(' --next=<n> Limit to next N (events)');
161
+ console.log(' --watch Live refresh (status)');
162
+ console.log(' --interval=<s> Refresh interval (status --watch)');
163
+ console.log(' --timeout=<ms> HTTP timeout (status)');
164
+ console.log(' --retries=<n> Retry count (status)');
165
+ console.log(' --plain No color');
166
+ console.log(' --no-logo Skip logo');
166
167
  }
167
168
  async function runEventsCommand(flags) {
168
- const events = await fetchEvents();
169
+ let events = await fetchEvents();
170
+ if (flags.has('--today')) {
171
+ const now = new Date();
172
+ events = events.filter(e => {
173
+ const d = e.startDate;
174
+ return d.getFullYear() === now.getFullYear() &&
175
+ d.getMonth() === now.getMonth() &&
176
+ d.getDate() === now.getDate();
177
+ });
178
+ }
179
+ const nextFlag = Array.from(flags).find(f => f.startsWith('--next='));
180
+ if (nextFlag) {
181
+ const n = Number.parseInt(nextFlag.split('=')[1] || '', 10);
182
+ if (!Number.isInteger(n) || n < 1) {
183
+ console.error(chalk.red('Invalid --next value. Use --next=<number> (>= 1).'));
184
+ process.exit(1);
185
+ }
186
+ events = events.slice(0, n);
187
+ }
169
188
  if (flags.has('--json')) {
170
189
  process.stdout.write(JSON.stringify(serializeEvents(events), null, 2) + '\n');
171
190
  return;
@@ -187,26 +206,19 @@ async function runStatusCommand(flags) {
187
206
  process.exit(1);
188
207
  }
189
208
  if (!Number.isInteger(timeoutMs) || timeoutMs < STATUS_TIMEOUT_MIN || timeoutMs > STATUS_TIMEOUT_MAX) {
190
- console.error(chalk.red(trans.status.invalidTimeout
191
- .replace('{min}', String(STATUS_TIMEOUT_MIN))
192
- .replace('{max}', String(STATUS_TIMEOUT_MAX))));
209
+ console.error(chalk.red(fmt(trans.status.invalidTimeout, { min: STATUS_TIMEOUT_MIN, max: STATUS_TIMEOUT_MAX })));
193
210
  process.exit(1);
194
211
  }
195
212
  if (!Number.isInteger(retries) || retries < STATUS_RETRIES_MIN || retries > STATUS_RETRIES_MAX) {
196
- console.error(chalk.red(trans.status.invalidRetries
197
- .replace('{min}', String(STATUS_RETRIES_MIN))
198
- .replace('{max}', String(STATUS_RETRIES_MAX))));
213
+ console.error(chalk.red(fmt(trans.status.invalidRetries, { min: STATUS_RETRIES_MIN, max: STATUS_RETRIES_MAX })));
199
214
  process.exit(1);
200
215
  }
201
216
  if (watch && flags.has('--json')) {
202
217
  console.error(chalk.red(trans.status.watchJsonConflict));
203
218
  process.exit(1);
204
219
  }
205
- if (watch &&
206
- (!Number.isInteger(intervalSeconds) || intervalSeconds < STATUS_WATCH_INTERVAL_MIN || intervalSeconds > STATUS_WATCH_INTERVAL_MAX)) {
207
- console.error(chalk.red(trans.status.invalidInterval
208
- .replace('{min}', String(STATUS_WATCH_INTERVAL_MIN))
209
- .replace('{max}', String(STATUS_WATCH_INTERVAL_MAX))));
220
+ if (watch && (!Number.isInteger(intervalSeconds) || intervalSeconds < STATUS_WATCH_INTERVAL_MIN || intervalSeconds > STATUS_WATCH_INTERVAL_MAX)) {
221
+ console.error(chalk.red(fmt(trans.status.invalidInterval, { min: STATUS_WATCH_INTERVAL_MIN, max: STATUS_WATCH_INTERVAL_MAX })));
210
222
  process.exit(1);
211
223
  }
212
224
  if (watch && !hasInteractiveTerminal()) {
@@ -215,18 +227,16 @@ async function runStatusCommand(flags) {
215
227
  }
216
228
  if (watch) {
217
229
  let stopped = false;
218
- const onSigint = () => {
219
- stopped = true;
220
- };
230
+ const onSigint = () => { stopped = true; };
221
231
  process.once('SIGINT', onSigint);
222
- console.log(chalk.dim(`${trans.status.watchStarted.replace('{seconds}', String(intervalSeconds))} | ${trans.status.watchHint}`));
232
+ console.log(chalk.dim(`${fmt(trans.status.watchStarted, { seconds: intervalSeconds })} | ${trans.status.watchHint}`));
223
233
  try {
224
234
  while (!stopped) {
225
235
  const services = await checkServices({ timeoutMs, retries });
226
236
  const hasFailures = hasServiceFailures(services);
227
237
  const health = countServiceHealth(services);
228
238
  clearScreen();
229
- console.log(chalk.bold(`${pickIcon('📡', '[status]')} ${trans.status.watchUpdated}: ${new Date().toLocaleString()}`));
239
+ console.log(chalk.bold(`${trans.status.watchUpdated}: ${new Date().toLocaleString()}`));
230
240
  console.log(chalk.dim(`${trans.status.up}: ${health.up} | ${trans.status.down}: ${health.down} | ${trans.status.watchHint}`));
231
241
  console.log();
232
242
  const useColor = !flags.has('--plain') && !!process.stdout.isTTY;
@@ -280,11 +290,15 @@ function maybeDisableColor(flags) {
280
290
  async function runCommandMode(argv) {
281
291
  const { command, args, flags } = parseArgs(argv);
282
292
  maybeDisableColor(flags);
283
- validateFlags(command, flags);
293
+ if (flags.has('--version') || command === '--version' || command === '-v' || command === 'version') {
294
+ console.log(APP_INFO.version);
295
+ return;
296
+ }
284
297
  if (flags.has('--help') || command === '--help' || command === '-h' || command === 'help') {
285
298
  printHelp();
286
299
  return;
287
300
  }
301
+ validateFlags(command, flags);
288
302
  if (!command) {
289
303
  if (!hasInteractiveTerminal()) {
290
304
  console.error(chalk.red('Interactive mode requires a TTY terminal.'));
@@ -320,6 +334,10 @@ async function runCommandMode(argv) {
320
334
  }
321
335
  return;
322
336
  }
337
+ if (command === 'update') {
338
+ await runUpdateCheck();
339
+ return;
340
+ }
323
341
  const action = ACTION_ALIASES[command];
324
342
  if (!action) {
325
343
  console.error(chalk.red(`Unknown command: ${command}`));
@@ -332,39 +350,52 @@ async function runCommandMode(argv) {
332
350
  }
333
351
  if (action === 'status') {
334
352
  const ok = await runStatusCommand(flags);
335
- if (!ok) {
353
+ if (!ok)
336
354
  process.exit(1);
337
- }
338
355
  return;
339
356
  }
340
- if (action === 'docs' && !hasInteractiveTerminal()) {
341
- if (flags.has('--open')) {
342
- await openDocsInBrowser();
357
+ if (action === 'docs') {
358
+ if (!hasInteractiveTerminal()) {
359
+ if (flags.has('--open')) {
360
+ await openDocsInBrowser();
361
+ }
362
+ else {
363
+ process.stdout.write(URLS.docs + '\n');
364
+ }
343
365
  }
344
366
  else {
345
- process.stdout.write(WEBSITE_URLS.docs + '\n');
367
+ const { showDocsMenu } = await import('./features/docs.js');
368
+ await showDocsMenu();
346
369
  }
347
370
  return;
348
371
  }
372
+ if (action === 'about') {
373
+ const { note } = await import('@clack/prompts');
374
+ const { padEndV } = await import('./core/text.js');
375
+ const pad = 12;
376
+ const row = (label, value) => `${chalk.dim(padEndV(label, pad))}${value}`;
377
+ const link = (label, url) => row(label, chalk.cyan(url));
378
+ const trans = t();
379
+ const content = [
380
+ row(trans.about.project, APP_INFO.name),
381
+ row(trans.about.version, `v${APP_INFO.version}`),
382
+ '',
383
+ link(trans.about.github, APP_INFO.repository),
384
+ link(trans.about.website, URLS.homepage),
385
+ ].join('\n');
386
+ note(content, trans.about.title);
387
+ return;
388
+ }
389
+ // URL actions: repair, website, github, roadmap
349
390
  const mappedUrl = URL_ACTIONS[action];
350
- if (mappedUrl && !flags.has('--open')) {
351
- process.stdout.write(mappedUrl + '\n');
391
+ if (mappedUrl) {
392
+ if (flags.has('--open')) {
393
+ await open(mappedUrl);
394
+ }
395
+ else {
396
+ process.stdout.write(mappedUrl + '\n');
397
+ }
352
398
  return;
353
399
  }
354
- await runMenuAction(action);
355
400
  }
356
- runCommandMode(process.argv.slice(2)).catch((err) => {
357
- if (err?.message?.includes('SIGINT') || err?.message?.includes('User force closed')) {
358
- console.log();
359
- console.log(chalk.dim(t().common.goodbye));
360
- process.exit(0);
361
- }
362
- if (err?.message) {
363
- console.error(err.message);
364
- }
365
- else {
366
- console.error('Error occurred:', err);
367
- }
368
- process.exit(1);
369
- });
370
- //# sourceMappingURL=index.js.map
401
+ runCommandMode(process.argv.slice(2)).catch(handleGracefulExit);