Skip to content

Commit d2632d1

Browse files
committed
feat: fix Knowledge Base module and add pager-style viewer
## Fixed - GitHub API 403 rate limiting error when browsing documentation - Added GitHub token authentication (GITHUB_TOKEN/GH_TOKEN env vars) - Improved error messages with rate limit info and reset time - Increased limit from 60 to 5000 requests/hour with token ## Added - Pager-style document viewer (vim/journalctl/less style) - Natural scrolling with arrow keys, Space, j/k, q to quit - Better reading experience for long documents - Auto-fallback to direct output if pager unavailable - Re-read document option after viewing - Environment variable support for PAGER customization ## Improved - Enhanced error handling with detailed rate limit diagnostics - Better user feedback when rate limits are reached - Clear instructions for resolving authentication issues ## Updated - README.md with GitHub token configuration instructions - CHANGELOG.md with complete v1.0.5 release notes - Version bumped to 1.0.5 Fixes #1: Knowledge Base 403 error Fixes #2: Hard to read documents before pager implementation
1 parent 9b8f384 commit d2632d1

File tree

4 files changed

+178
-23
lines changed

4 files changed

+178
-23
lines changed

CHANGELOG.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,53 @@
11
# CHANGELOG
22

3+
## [1.0.5] - 2025-12-10
4+
5+
### Fixed
6+
- **Knowledge Base 403 Error**: Resolved GitHub API rate limiting issue that caused 403 errors when browsing documentation
7+
- Added GitHub token authentication support via `GITHUB_TOKEN` or `GH_TOKEN` environment variables
8+
- Improved error messages with rate limit information and reset time
9+
- Increased rate limit from 60 to 5000 requests per hour when using a token
10+
11+
### Added
12+
- **Pager-Style Document Viewer**: Documents now open in a pager (similar to vim/journalctl/less)
13+
- Natural scrolling navigation with arrow keys, Space, j/k (vim-style), and q to quit
14+
- Content doesn't flood the terminal anymore
15+
- Better reading experience for long documents
16+
- Automatic fallback to direct output if pager is unavailable
17+
- **Re-read Document Option**: Added ability to re-read a document after viewing without going back to the list
18+
- **Environment Variable Support**:
19+
- `GITHUB_TOKEN` or `GH_TOKEN` for GitHub API authentication
20+
- `PAGER` for custom pager selection (defaults to `less`)
21+
22+
### Improved
23+
- Enhanced error handling with detailed rate limit diagnostics
24+
- Better user feedback when rate limits are reached
25+
- Clearer instructions for resolving authentication issues
26+
27+
### Technical Details
28+
- Added `displayInPager()` function for spawning system pager processes
29+
- Enhanced `fetchGitHubDirectory()` with conditional token authentication
30+
- Updated documentation viewer workflow for better UX
31+
32+
## [1.0.4] - 2025-12-10
33+
34+
### Enhanced
35+
- **Smooth Slogan Animation**: Implemented true color interpolation for buttery smooth gradient animation
36+
- Increased frame rate from 24 to 60 FPS for ultra-smooth motion
37+
- Changed easing from cubic to sine wave for more natural transitions
38+
- Dynamically generate gradients per frame instead of using pre-defined set
39+
- Eliminates staggered/jumping effect in the slogan text animation
40+
41+
### Technical Details
42+
- Added `hexToRgb()`, `rgbToHex()`, and `interpolateColor()` functions for mathematical color blending
43+
- Implemented `easeInOutSine()` easing function for smooth acceleration/deceleration
44+
- Each frame now uses unique, mathematically interpolated colors
45+
46+
## [1.0.3] - 2025-11-27
47+
48+
### Changed
49+
- Version alignment and bug fixes
50+
351
## [1.0.2] - 2025-11-27
452

553
### Added

README.md

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ NBTCA Prompt is a minimalist command-line interface tool designed for the Comput
1313

1414
- View upcoming association events (30-day calendar)
1515
- Access repair service information
16-
- Browse technical documentation from terminal
16+
- Browse technical documentation from terminal with pager support (vim/journalctl style)
1717
- Quick links to official website and GitHub
1818
- Minimalist design with maximum terminal compatibility
19+
- Smooth gradient animations for enhanced visual experience
1920

2021
## Installation
2122

@@ -131,11 +132,25 @@ src/
131132

132133
The knowledge base viewer features:
133134

134-
- Direct GitHub repository access
135+
- Direct GitHub repository access with authentication support
136+
- Pager-style document reading (similar to vim/journalctl/less)
135137
- VitePress syntax cleaning
136-
- Terminal Markdown rendering
138+
- Terminal Markdown rendering with color support
137139
- Browser fallback option
138140
- Directory tree navigation
141+
- Improved error handling with rate limit detection
142+
143+
### GitHub Token Configuration (Optional)
144+
145+
To avoid GitHub API rate limits when browsing documentation, you can set a GitHub token:
146+
147+
```bash
148+
export GITHUB_TOKEN="your_github_token_here"
149+
# or
150+
export GH_TOKEN="your_github_token_here"
151+
```
152+
153+
Without a token, you have 60 requests per hour. With a token, you get 5000 requests per hour.
139154

140155
### Supported Formats
141156

@@ -163,6 +178,10 @@ ASCII-based UI elements ensure rendering on any terminal emulator.
163178

164179
## Common Issues
165180

181+
### Q: Getting 403 error when browsing documentation?
182+
183+
A: This is due to GitHub API rate limiting. Set a `GITHUB_TOKEN` environment variable to increase your rate limit from 60 to 5000 requests per hour. See the [GitHub Token Configuration](#github-token-configuration-optional) section above.
184+
166185
### Q: Auto-restart when using `pnpm run dev:watch`?
167186

168187
A: This is expected behavior. Use `pnpm run dev` for interactive testing.
@@ -171,6 +190,10 @@ A: This is expected behavior. Use `pnpm run dev` for interactive testing.
171190

172191
A: Select the Exit option from menu, or press Ctrl+C.
173192

193+
### Q: How to navigate documents in the pager?
194+
195+
A: Use arrow keys, Space (page down), 'j/k' (vim-style), or 'q' to quit the pager.
196+
174197
### Q: Changes not reflected?
175198

176199
A: If using `pnpm start`, rebuild with `pnpm run build` first.
@@ -206,6 +229,25 @@ MIT License - See LICENSE file for details
206229

207230
## Changelog
208231

232+
### v1.0.5 (2025-12-10)
233+
234+
- **Fixed**: Knowledge Base 403 error due to GitHub API rate limiting
235+
- **Added**: GitHub token authentication support (GITHUB_TOKEN/GH_TOKEN)
236+
- **Added**: Pager-style document viewer (vim/journalctl/less style)
237+
- **Added**: "Re-read document" option after viewing
238+
- **Improved**: Better error messages with rate limit information
239+
- **Improved**: Document reading experience with scroll navigation
240+
241+
### v1.0.4 (2025-12-10)
242+
243+
- **Enhanced**: Smooth slogan animation with true color interpolation
244+
- **Improved**: 60 FPS animation with sine easing for natural transitions
245+
- **Technical**: Added hexToRgb, rgbToHex, and interpolateColor functions
246+
247+
### v1.0.3 (2025-11-27)
248+
249+
- Version alignment and bug fixes
250+
209251
### v1.0.1 (2025-11-27)
210252

211253
- Added terminal documentation viewer

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nbtca/prompt",
3-
"version": "1.0.4",
3+
"version": "1.0.5",
44
"type": "module",
55
"main": "dist/index.js",
66
"bin": {

src/features/docs.ts

Lines changed: 84 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import chalk from 'chalk';
1010
import open from 'open';
1111
import inquirer from 'inquirer';
1212
import { error, info, success, warning } from '../core/ui.js';
13+
import { spawn } from 'child_process';
1314

1415
// 配置marked使用终端渲染器
1516
marked.setOptions({
@@ -26,6 +27,12 @@ const GITHUB_REPO = {
2627
branch: 'main'
2728
};
2829

30+
/**
31+
* GitHub Token (可选 - 用于避免 API 速率限制)
32+
* 从环境变量读取,如果没有则使用未认证请求
33+
*/
34+
const GITHUB_TOKEN = process.env['GITHUB_TOKEN'] || process.env['GH_TOKEN'];
35+
2936
/**
3037
* 文档结构类型
3138
*/
@@ -56,12 +63,19 @@ async function fetchGitHubDirectory(path: string = ''): Promise<DocItem[]> {
5663
const url = `https://api.github.com/repos/${GITHUB_REPO.owner}/${GITHUB_REPO.repo}/contents/${path}?ref=${GITHUB_REPO.branch}`;
5764

5865
try {
66+
const headers: any = {
67+
'Accept': 'application/vnd.github.v3+json',
68+
'User-Agent': 'NBTCA-CLI'
69+
};
70+
71+
// 如果有 GitHub Token,添加认证头以避免速率限制
72+
if (GITHUB_TOKEN) {
73+
headers['Authorization'] = `Bearer ${GITHUB_TOKEN}`;
74+
}
75+
5976
const response = await axios.get(url, {
6077
timeout: 10000,
61-
headers: {
62-
'Accept': 'application/vnd.github.v3+json',
63-
'User-Agent': 'NBTCA-CLI'
64-
}
78+
headers
6579
});
6680

6781
return response.data
@@ -90,6 +104,17 @@ async function fetchGitHubDirectory(path: string = ''): Promise<DocItem[]> {
90104
return a.name.localeCompare(b.name);
91105
});
92106
} catch (err: any) {
107+
// 提供更详细的错误信息
108+
if (err.response?.status === 403) {
109+
const rateLimitRemaining = err.response.headers['x-ratelimit-remaining'];
110+
const rateLimitReset = err.response.headers['x-ratelimit-reset'];
111+
112+
if (rateLimitRemaining === '0') {
113+
const resetDate = new Date(parseInt(rateLimitReset) * 1000);
114+
throw new Error(`GitHub API 速率限制已达上限,将在 ${resetDate.toLocaleTimeString()} 重置。\n提示: 设置 GITHUB_TOKEN 环境变量可获得更高的速率限制。`);
115+
}
116+
throw new Error(`GitHub API 拒绝访问 (403)。\n提示: 尝试设置 GITHUB_TOKEN 环境变量。`);
117+
}
93118
throw new Error(`无法获取目录内容: ${err.message}`);
94119
}
95120
}
@@ -231,6 +256,50 @@ async function browseDirectory(dirPath: string = ''): Promise<void> {
231256
}
232257
}
233258

259+
/**
260+
* 使用系统pager (less/more) 显示内容
261+
* 提供类似vim/journalctl的阅读体验
262+
*/
263+
async function displayInPager(content: string, title: string): Promise<boolean> {
264+
return new Promise((resolve) => {
265+
// 检测可用的pager程序
266+
const pager = process.env['PAGER'] || 'less';
267+
268+
// 为内容添加标题
269+
const fullContent = `${chalk.cyan.bold(`>> ${title}`)}\n${chalk.gray('='.repeat(80))}\n\n${content}\n\n${chalk.gray('='.repeat(80))}\n${chalk.dim('End of document - Press q to quit')}\n`;
270+
271+
// less的参数: -R (支持颜色), -F (如果内容少于一屏则直接显示), -X (退出时不清屏)
272+
const lessArgs = ['-R', '-F', '-X'];
273+
274+
try {
275+
const child = spawn(pager, lessArgs, {
276+
stdio: ['pipe', 'inherit', 'inherit'],
277+
shell: true
278+
});
279+
280+
// 将内容写入pager的stdin
281+
child.stdin.write(fullContent);
282+
child.stdin.end();
283+
284+
child.on('exit', (code) => {
285+
resolve(code === 0);
286+
});
287+
288+
child.on('error', () => {
289+
// 如果pager失败,回退到直接输出
290+
console.error(chalk.yellow('⚠ Pager不可用,使用标准输出'));
291+
console.log(fullContent);
292+
resolve(false);
293+
});
294+
295+
} catch {
296+
// 回退方案: 直接输出
297+
console.log(fullContent);
298+
resolve(false);
299+
}
300+
});
301+
}
302+
234303
/**
235304
* 查看Markdown文件
236305
*/
@@ -247,23 +316,15 @@ async function viewMarkdownFile(path: string): Promise<void> {
247316
// 提取标题
248317
const title = extractDocTitle(cleanedContent) || path.split('/').pop() || path;
249318

250-
console.clear();
251-
console.log();
252-
console.log(chalk.cyan.bold(`>> ${title}`));
253-
console.log(chalk.gray(` ${path}`));
254-
console.log();
255-
console.log(chalk.gray('='.repeat(80)));
256-
console.log();
257-
258319
// 渲染Markdown到终端
259-
const rendered = marked(cleanedContent);
260-
console.log(rendered);
261-
console.log();
262-
console.log(chalk.gray('='.repeat(80)));
263-
console.log();
264-
console.log(chalk.dim(' Note: Some features are only available in browser'));
265-
console.log();
320+
const rendered = await marked(cleanedContent);
321+
322+
console.log('\r' + ' '.repeat(60) + '\r'); // 清除加载提示
323+
324+
// 使用pager显示文档 (类似vim/journalctl的阅读体验)
325+
await displayInPager(rendered, `${title}\n${chalk.gray(` ${path}`)}`);
266326

327+
console.log(); // 添加空行
267328
success('文档加载完成');
268329
console.log();
269330

@@ -275,13 +336,17 @@ async function viewMarkdownFile(path: string): Promise<void> {
275336
message: '选择操作:',
276337
choices: [
277338
{ name: '[ <] Back to docs list', value: 'back' },
339+
{ name: '[ ↻] Re-read document', value: 'reread' },
278340
{ name: '[ *] Open in browser', value: 'browser' }
279341
]
280342
}
281343
]);
282344

283345
if (action === 'browser') {
284346
await openDocsInBrowser(path);
347+
} else if (action === 'reread') {
348+
// 重新阅读文档
349+
await viewMarkdownFile(path);
285350
}
286351

287352
} catch (err: any) {

0 commit comments

Comments
 (0)