recker 1.0.15 → 1.0.17
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 +86 -97
- package/dist/ai/providers/anthropic.d.ts.map +1 -1
- package/dist/ai/providers/anthropic.js +4 -1
- package/dist/ai/providers/base.d.ts.map +1 -1
- package/dist/ai/providers/base.js +7 -2
- package/dist/ai/rate-limiter.d.ts.map +1 -1
- package/dist/ai/rate-limiter.js +4 -1
- package/dist/bench/generator.d.ts.map +1 -1
- package/dist/bench/generator.js +8 -3
- package/dist/bench/stats.d.ts +15 -1
- package/dist/bench/stats.d.ts.map +1 -1
- package/dist/bench/stats.js +117 -5
- package/dist/cache/memory-storage.d.ts.map +1 -1
- package/dist/cache/memory-storage.js +3 -2
- package/dist/cli/handler.js +14 -14
- package/dist/cli/index.js +602 -48
- package/dist/cli/presets.js +5 -5
- package/dist/cli/tui/ai-chat.js +10 -10
- package/dist/cli/tui/load-dashboard.d.ts.map +1 -1
- package/dist/cli/tui/load-dashboard.js +127 -32
- package/dist/cli/tui/scroll-buffer.d.ts +43 -0
- package/dist/cli/tui/scroll-buffer.d.ts.map +1 -0
- package/dist/cli/tui/scroll-buffer.js +162 -0
- package/dist/cli/tui/search-panel.d.ts +41 -0
- package/dist/cli/tui/search-panel.d.ts.map +1 -0
- package/dist/cli/tui/search-panel.js +420 -0
- package/dist/cli/tui/shell.d.ts +14 -0
- package/dist/cli/tui/shell.d.ts.map +1 -1
- package/dist/cli/tui/shell.js +424 -46
- package/dist/cli/tui/websocket.js +17 -17
- package/dist/contract/index.js +3 -2
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +18 -26
- package/dist/core/errors.d.ts +109 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +214 -1
- package/dist/core/request-promise.d.ts.map +1 -1
- package/dist/core/request-promise.js +5 -6
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +5 -6
- package/dist/dns/index.d.ts +1 -0
- package/dist/dns/index.d.ts.map +1 -1
- package/dist/dns/index.js +1 -0
- package/dist/dns/propagation.d.ts +21 -0
- package/dist/dns/propagation.d.ts.map +1 -0
- package/dist/dns/propagation.js +169 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +10 -11
- package/dist/mcp/embeddings-loader.d.ts +18 -0
- package/dist/mcp/embeddings-loader.d.ts.map +1 -0
- package/dist/mcp/embeddings-loader.js +162 -0
- package/dist/mcp/geoip-loader.d.ts +11 -0
- package/dist/mcp/geoip-loader.d.ts.map +1 -0
- package/dist/mcp/geoip-loader.js +107 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/ip-intel.d.ts +28 -0
- package/dist/mcp/ip-intel.d.ts.map +1 -0
- package/dist/mcp/ip-intel.js +209 -0
- package/dist/mcp/search/hybrid-search.d.ts.map +1 -1
- package/dist/mcp/search/hybrid-search.js +59 -38
- package/dist/mcp/search/math.d.ts.map +1 -1
- package/dist/mcp/search/math.js +5 -1
- package/dist/mcp/server.d.ts +6 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +122 -2
- package/dist/plugins/compression.js +4 -2
- package/dist/plugins/har-player.d.ts.map +1 -1
- package/dist/plugins/har-player.js +8 -11
- package/dist/plugins/odata.d.ts.map +1 -1
- package/dist/plugins/odata.js +5 -2
- package/dist/protocols/ftp.d.ts.map +1 -1
- package/dist/protocols/ftp.js +69 -16
- package/dist/protocols/sftp.d.ts.map +1 -1
- package/dist/protocols/sftp.js +13 -3
- package/dist/protocols/telnet.d.ts.map +1 -1
- package/dist/protocols/telnet.js +25 -6
- package/dist/recker.d.ts +47 -0
- package/dist/recker.d.ts.map +1 -0
- package/dist/recker.js +99 -0
- package/dist/transport/base-udp.d.ts.map +1 -1
- package/dist/transport/base-udp.js +7 -4
- package/dist/transport/udp-response.d.ts.map +1 -1
- package/dist/transport/udp-response.js +10 -3
- package/dist/transport/udp.d.ts.map +1 -1
- package/dist/transport/udp.js +5 -1
- package/dist/transport/undici.d.ts.map +1 -1
- package/dist/transport/undici.js +75 -63
- package/dist/utils/agent-manager.d.ts +1 -0
- package/dist/utils/agent-manager.d.ts.map +1 -1
- package/dist/utils/agent-manager.js +11 -0
- package/dist/utils/client-pool.d.ts.map +1 -1
- package/dist/utils/client-pool.js +4 -1
- package/dist/utils/colors.d.ts +16 -0
- package/dist/utils/colors.d.ts.map +1 -1
- package/dist/utils/colors.js +16 -0
- package/dist/utils/dns-toolkit.d.ts +88 -1
- package/dist/utils/dns-toolkit.d.ts.map +1 -1
- package/dist/utils/dns-toolkit.js +704 -6
- package/dist/utils/doh.d.ts.map +1 -1
- package/dist/utils/doh.js +13 -16
- package/dist/utils/download.d.ts.map +1 -1
- package/dist/utils/download.js +10 -11
- package/dist/utils/rdap.d.ts +9 -0
- package/dist/utils/rdap.d.ts.map +1 -1
- package/dist/utils/rdap.js +78 -9
- package/dist/utils/security-grader.d.ts +47 -0
- package/dist/utils/security-grader.d.ts.map +1 -0
- package/dist/utils/security-grader.js +637 -0
- package/dist/utils/sparkline.d.ts +18 -0
- package/dist/utils/sparkline.d.ts.map +1 -0
- package/dist/utils/sparkline.js +55 -0
- package/dist/utils/sse.d.ts.map +1 -1
- package/dist/utils/sse.js +5 -6
- package/dist/utils/system-metrics.d.ts +26 -0
- package/dist/utils/system-metrics.d.ts.map +1 -0
- package/dist/utils/system-metrics.js +81 -0
- package/dist/utils/tls-inspector.d.ts +6 -0
- package/dist/utils/tls-inspector.d.ts.map +1 -1
- package/dist/utils/tls-inspector.js +35 -1
- package/dist/webrtc/index.d.ts.map +1 -1
- package/dist/webrtc/index.js +21 -7
- package/dist/websocket/client.d.ts.map +1 -1
- package/dist/websocket/client.js +13 -16
- package/package.json +4 -3
- package/dist/mcp/data/embeddings.json +0 -1
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { createInterface } from 'readline';
|
|
2
|
+
import { getShellSearch } from './shell-search.js';
|
|
3
|
+
import { readFileSync, existsSync } from 'fs';
|
|
4
|
+
import { join, dirname } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import colors from '../../utils/colors.js';
|
|
7
|
+
const ESC = '\x1b';
|
|
8
|
+
const CLEAR_SCREEN = `${ESC}[2J`;
|
|
9
|
+
const CURSOR_HOME = `${ESC}[H`;
|
|
10
|
+
const CURSOR_HIDE = `${ESC}[?25l`;
|
|
11
|
+
const CURSOR_SHOW = `${ESC}[?25h`;
|
|
12
|
+
const CLEAR_LINE = `${ESC}[2K`;
|
|
13
|
+
const BOX = {
|
|
14
|
+
topLeft: '┌',
|
|
15
|
+
topRight: '┐',
|
|
16
|
+
bottomLeft: '└',
|
|
17
|
+
bottomRight: '┘',
|
|
18
|
+
horizontal: '─',
|
|
19
|
+
vertical: '│',
|
|
20
|
+
verticalRight: '├',
|
|
21
|
+
verticalLeft: '┤',
|
|
22
|
+
horizontalDown: '┬',
|
|
23
|
+
horizontalUp: '┴',
|
|
24
|
+
cross: '┼',
|
|
25
|
+
};
|
|
26
|
+
export class SearchPanel {
|
|
27
|
+
rl = null;
|
|
28
|
+
state;
|
|
29
|
+
docsPath;
|
|
30
|
+
running = false;
|
|
31
|
+
termWidth = 80;
|
|
32
|
+
termHeight = 24;
|
|
33
|
+
leftPanelWidth = 0;
|
|
34
|
+
rightPanelWidth = 0;
|
|
35
|
+
contentHeight = 0;
|
|
36
|
+
previewContent = [];
|
|
37
|
+
constructor(options = {}) {
|
|
38
|
+
this.state = {
|
|
39
|
+
query: options.initialQuery || '',
|
|
40
|
+
results: [],
|
|
41
|
+
selectedIndex: 0,
|
|
42
|
+
scrollOffset: 0,
|
|
43
|
+
previewScrollOffset: 0,
|
|
44
|
+
isSearching: false,
|
|
45
|
+
error: null,
|
|
46
|
+
};
|
|
47
|
+
this.docsPath = options.docsPath || this.findDocsPath();
|
|
48
|
+
}
|
|
49
|
+
findDocsPath() {
|
|
50
|
+
const candidates = [
|
|
51
|
+
join(process.cwd(), 'docs'),
|
|
52
|
+
join(dirname(fileURLToPath(import.meta.url)), '../../../docs'),
|
|
53
|
+
join(dirname(fileURLToPath(import.meta.url)), '../../../../docs'),
|
|
54
|
+
];
|
|
55
|
+
for (const p of candidates) {
|
|
56
|
+
if (existsSync(p))
|
|
57
|
+
return p;
|
|
58
|
+
}
|
|
59
|
+
return candidates[0];
|
|
60
|
+
}
|
|
61
|
+
async open() {
|
|
62
|
+
this.running = true;
|
|
63
|
+
this.updateDimensions();
|
|
64
|
+
this.rl = createInterface({
|
|
65
|
+
input: process.stdin,
|
|
66
|
+
output: process.stdout,
|
|
67
|
+
terminal: true,
|
|
68
|
+
});
|
|
69
|
+
if (process.stdin.isTTY) {
|
|
70
|
+
process.stdin.setRawMode(true);
|
|
71
|
+
}
|
|
72
|
+
process.stdout.on('resize', () => {
|
|
73
|
+
this.updateDimensions();
|
|
74
|
+
this.render();
|
|
75
|
+
});
|
|
76
|
+
process.stdin.on('data', this.handleKeyInput.bind(this));
|
|
77
|
+
if (this.state.query) {
|
|
78
|
+
await this.performSearch();
|
|
79
|
+
}
|
|
80
|
+
this.render();
|
|
81
|
+
return new Promise((resolve) => {
|
|
82
|
+
const checkInterval = setInterval(() => {
|
|
83
|
+
if (!this.running) {
|
|
84
|
+
clearInterval(checkInterval);
|
|
85
|
+
resolve();
|
|
86
|
+
}
|
|
87
|
+
}, 100);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
close() {
|
|
91
|
+
this.running = false;
|
|
92
|
+
if (process.stdin.isTTY) {
|
|
93
|
+
process.stdin.setRawMode(false);
|
|
94
|
+
}
|
|
95
|
+
process.stdout.write(CURSOR_SHOW);
|
|
96
|
+
process.stdout.write(CLEAR_SCREEN);
|
|
97
|
+
process.stdout.write(CURSOR_HOME);
|
|
98
|
+
if (this.rl) {
|
|
99
|
+
this.rl.close();
|
|
100
|
+
this.rl = null;
|
|
101
|
+
}
|
|
102
|
+
process.stdin.removeAllListeners('data');
|
|
103
|
+
process.stdout.removeAllListeners('resize');
|
|
104
|
+
}
|
|
105
|
+
updateDimensions() {
|
|
106
|
+
this.termWidth = process.stdout.columns || 80;
|
|
107
|
+
this.termHeight = process.stdout.rows || 24;
|
|
108
|
+
this.leftPanelWidth = Math.max(30, Math.floor(this.termWidth * 0.4));
|
|
109
|
+
this.rightPanelWidth = this.termWidth - this.leftPanelWidth - 1;
|
|
110
|
+
this.contentHeight = this.termHeight - 6;
|
|
111
|
+
}
|
|
112
|
+
async handleKeyInput(data) {
|
|
113
|
+
const key = data.toString();
|
|
114
|
+
if (key === '\x1b' || key === '\x03') {
|
|
115
|
+
this.close();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (key === '\x1b[A') {
|
|
119
|
+
this.navigateUp();
|
|
120
|
+
}
|
|
121
|
+
else if (key === '\x1b[B') {
|
|
122
|
+
this.navigateDown();
|
|
123
|
+
}
|
|
124
|
+
else if (key === '\x1b[C') {
|
|
125
|
+
this.scrollPreview(5);
|
|
126
|
+
}
|
|
127
|
+
else if (key === '\x1b[D') {
|
|
128
|
+
this.scrollPreview(-5);
|
|
129
|
+
}
|
|
130
|
+
else if (key === '\x1b[5~') {
|
|
131
|
+
this.scrollPreview(-this.contentHeight);
|
|
132
|
+
}
|
|
133
|
+
else if (key === '\x1b[6~') {
|
|
134
|
+
this.scrollPreview(this.contentHeight);
|
|
135
|
+
}
|
|
136
|
+
else if (key === '\r' || key === '\n') {
|
|
137
|
+
}
|
|
138
|
+
else if (key === '\x7f' || key === '\b') {
|
|
139
|
+
if (this.state.query.length > 0) {
|
|
140
|
+
this.state.query = this.state.query.slice(0, -1);
|
|
141
|
+
await this.performSearch();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else if (key.length === 1 && key >= ' ') {
|
|
145
|
+
this.state.query += key;
|
|
146
|
+
await this.performSearch();
|
|
147
|
+
}
|
|
148
|
+
this.render();
|
|
149
|
+
}
|
|
150
|
+
navigateUp() {
|
|
151
|
+
if (this.state.selectedIndex > 0) {
|
|
152
|
+
this.state.selectedIndex--;
|
|
153
|
+
this.state.previewScrollOffset = 0;
|
|
154
|
+
if (this.state.selectedIndex < this.state.scrollOffset) {
|
|
155
|
+
this.state.scrollOffset = this.state.selectedIndex;
|
|
156
|
+
}
|
|
157
|
+
this.loadPreview();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
navigateDown() {
|
|
161
|
+
if (this.state.selectedIndex < this.state.results.length - 1) {
|
|
162
|
+
this.state.selectedIndex++;
|
|
163
|
+
this.state.previewScrollOffset = 0;
|
|
164
|
+
const visibleItems = this.contentHeight - 2;
|
|
165
|
+
if (this.state.selectedIndex >= this.state.scrollOffset + visibleItems) {
|
|
166
|
+
this.state.scrollOffset = this.state.selectedIndex - visibleItems + 1;
|
|
167
|
+
}
|
|
168
|
+
this.loadPreview();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
scrollPreview(delta) {
|
|
172
|
+
const maxScroll = Math.max(0, this.previewContent.length - this.contentHeight + 2);
|
|
173
|
+
this.state.previewScrollOffset = Math.max(0, Math.min(maxScroll, this.state.previewScrollOffset + delta));
|
|
174
|
+
}
|
|
175
|
+
async performSearch() {
|
|
176
|
+
if (!this.state.query.trim()) {
|
|
177
|
+
this.state.results = [];
|
|
178
|
+
this.state.selectedIndex = 0;
|
|
179
|
+
this.state.scrollOffset = 0;
|
|
180
|
+
this.previewContent = [];
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
this.state.isSearching = true;
|
|
184
|
+
this.state.error = null;
|
|
185
|
+
try {
|
|
186
|
+
const search = getShellSearch();
|
|
187
|
+
this.state.results = await search.search(this.state.query, { limit: 20 });
|
|
188
|
+
this.state.selectedIndex = 0;
|
|
189
|
+
this.state.scrollOffset = 0;
|
|
190
|
+
this.state.previewScrollOffset = 0;
|
|
191
|
+
if (this.state.results.length > 0) {
|
|
192
|
+
this.loadPreview();
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
this.previewContent = [];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
this.state.error = error.message;
|
|
200
|
+
this.state.results = [];
|
|
201
|
+
}
|
|
202
|
+
finally {
|
|
203
|
+
this.state.isSearching = false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
loadPreview() {
|
|
207
|
+
const result = this.state.results[this.state.selectedIndex];
|
|
208
|
+
if (!result) {
|
|
209
|
+
this.previewContent = [];
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const fullPath = join(this.docsPath, result.path);
|
|
213
|
+
if (existsSync(fullPath)) {
|
|
214
|
+
try {
|
|
215
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
216
|
+
this.previewContent = this.formatMarkdown(content);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
this.previewContent = this.formatMarkdown(result.content || result.snippet || 'No preview available');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else if (result.content) {
|
|
223
|
+
this.previewContent = this.formatMarkdown(result.content);
|
|
224
|
+
}
|
|
225
|
+
else if (result.snippet) {
|
|
226
|
+
this.previewContent = this.formatMarkdown(result.snippet);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.previewContent = ['No preview available'];
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
formatMarkdown(text) {
|
|
233
|
+
const lines = [];
|
|
234
|
+
const width = this.rightPanelWidth - 4;
|
|
235
|
+
for (const rawLine of text.split('\n')) {
|
|
236
|
+
let line = rawLine;
|
|
237
|
+
if (line.startsWith('# ')) {
|
|
238
|
+
line = colors.bold(colors.cyan(line.substring(2)));
|
|
239
|
+
}
|
|
240
|
+
else if (line.startsWith('## ')) {
|
|
241
|
+
line = colors.bold(colors.blue(line.substring(3)));
|
|
242
|
+
}
|
|
243
|
+
else if (line.startsWith('### ')) {
|
|
244
|
+
line = colors.bold(colors.green(line.substring(4)));
|
|
245
|
+
}
|
|
246
|
+
else if (line.startsWith('#### ')) {
|
|
247
|
+
line = colors.bold(line.substring(5));
|
|
248
|
+
}
|
|
249
|
+
else if (line.startsWith('```')) {
|
|
250
|
+
line = colors.gray(line);
|
|
251
|
+
}
|
|
252
|
+
else if (line.includes('`')) {
|
|
253
|
+
line = line.replace(/`([^`]+)`/g, (_, code) => colors.cyan(code));
|
|
254
|
+
}
|
|
255
|
+
if (line.includes('**')) {
|
|
256
|
+
line = line.replace(/\*\*([^*]+)\*\*/g, (_, text) => colors.bold(text));
|
|
257
|
+
}
|
|
258
|
+
const wrapped = this.wordWrap(line, width);
|
|
259
|
+
lines.push(...wrapped);
|
|
260
|
+
}
|
|
261
|
+
return lines;
|
|
262
|
+
}
|
|
263
|
+
wordWrap(text, width) {
|
|
264
|
+
if (this.stripAnsi(text).length <= width) {
|
|
265
|
+
return [text];
|
|
266
|
+
}
|
|
267
|
+
const words = text.split(' ');
|
|
268
|
+
const lines = [];
|
|
269
|
+
let currentLine = '';
|
|
270
|
+
for (const word of words) {
|
|
271
|
+
const testLine = currentLine ? `${currentLine} ${word}` : word;
|
|
272
|
+
if (this.stripAnsi(testLine).length <= width) {
|
|
273
|
+
currentLine = testLine;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
if (currentLine)
|
|
277
|
+
lines.push(currentLine);
|
|
278
|
+
currentLine = word;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (currentLine)
|
|
282
|
+
lines.push(currentLine);
|
|
283
|
+
return lines;
|
|
284
|
+
}
|
|
285
|
+
stripAnsi(text) {
|
|
286
|
+
return text.replace(/\x1b\[[0-9;]*m/g, '');
|
|
287
|
+
}
|
|
288
|
+
render() {
|
|
289
|
+
const output = [];
|
|
290
|
+
output.push(CURSOR_HIDE);
|
|
291
|
+
output.push(CLEAR_SCREEN);
|
|
292
|
+
output.push(CURSOR_HOME);
|
|
293
|
+
output.push(this.renderHeader());
|
|
294
|
+
output.push(this.renderSearchInput());
|
|
295
|
+
output.push(this.renderDivider());
|
|
296
|
+
output.push(...this.renderContent());
|
|
297
|
+
output.push(this.renderFooter());
|
|
298
|
+
process.stdout.write(output.join(''));
|
|
299
|
+
}
|
|
300
|
+
renderHeader() {
|
|
301
|
+
const title = ' Documentation Search ';
|
|
302
|
+
const padding = Math.max(0, Math.floor((this.termWidth - title.length) / 2));
|
|
303
|
+
const line = BOX.horizontal.repeat(this.termWidth);
|
|
304
|
+
return (colors.cyan(BOX.topLeft + line.slice(0, padding - 1)) +
|
|
305
|
+
colors.bold(colors.cyan(title)) +
|
|
306
|
+
colors.cyan(line.slice(padding + title.length - 1) + BOX.topRight) +
|
|
307
|
+
'\n');
|
|
308
|
+
}
|
|
309
|
+
renderSearchInput() {
|
|
310
|
+
const prefix = colors.cyan(BOX.vertical) + ' ' + colors.yellow('Search: ');
|
|
311
|
+
const query = this.state.query;
|
|
312
|
+
const cursor = colors.cyan('_');
|
|
313
|
+
const status = this.state.isSearching
|
|
314
|
+
? colors.gray(' (searching...)')
|
|
315
|
+
: this.state.results.length > 0
|
|
316
|
+
? colors.gray(` (${this.state.results.length} results)`)
|
|
317
|
+
: '';
|
|
318
|
+
const contentWidth = this.termWidth - 4;
|
|
319
|
+
const inputLine = query + cursor + status;
|
|
320
|
+
const padding = Math.max(0, contentWidth - this.stripAnsi(inputLine).length);
|
|
321
|
+
return prefix + inputLine + ' '.repeat(padding) + colors.cyan(BOX.vertical) + '\n';
|
|
322
|
+
}
|
|
323
|
+
renderDivider() {
|
|
324
|
+
const leftPart = BOX.horizontal.repeat(this.leftPanelWidth - 1);
|
|
325
|
+
const rightPart = BOX.horizontal.repeat(this.rightPanelWidth);
|
|
326
|
+
return (colors.cyan(BOX.verticalRight) +
|
|
327
|
+
colors.cyan(leftPart) +
|
|
328
|
+
colors.cyan(BOX.horizontalDown) +
|
|
329
|
+
colors.cyan(rightPart) +
|
|
330
|
+
colors.cyan(BOX.verticalLeft) +
|
|
331
|
+
'\n');
|
|
332
|
+
}
|
|
333
|
+
renderContent() {
|
|
334
|
+
const lines = [];
|
|
335
|
+
for (let i = 0; i < this.contentHeight; i++) {
|
|
336
|
+
const leftContent = this.renderLeftPanelLine(i);
|
|
337
|
+
const rightContent = this.renderRightPanelLine(i);
|
|
338
|
+
lines.push(colors.cyan(BOX.vertical) +
|
|
339
|
+
leftContent +
|
|
340
|
+
colors.cyan(BOX.vertical) +
|
|
341
|
+
rightContent +
|
|
342
|
+
colors.cyan(BOX.vertical) +
|
|
343
|
+
'\n');
|
|
344
|
+
}
|
|
345
|
+
return lines;
|
|
346
|
+
}
|
|
347
|
+
renderLeftPanelLine(lineIndex) {
|
|
348
|
+
const width = this.leftPanelWidth - 2;
|
|
349
|
+
const resultIndex = this.state.scrollOffset + lineIndex;
|
|
350
|
+
if (resultIndex >= this.state.results.length) {
|
|
351
|
+
return ' '.repeat(width);
|
|
352
|
+
}
|
|
353
|
+
const result = this.state.results[resultIndex];
|
|
354
|
+
const isSelected = resultIndex === this.state.selectedIndex;
|
|
355
|
+
const score = Math.round(result.score * 100);
|
|
356
|
+
const indexStr = ` ${resultIndex + 1}. `;
|
|
357
|
+
const scoreStr = ` (${score}%)`;
|
|
358
|
+
const maxTitleLen = width - indexStr.length - scoreStr.length - 1;
|
|
359
|
+
let title = result.title;
|
|
360
|
+
if (title.length > maxTitleLen) {
|
|
361
|
+
title = title.slice(0, maxTitleLen - 1) + '…';
|
|
362
|
+
}
|
|
363
|
+
let line = indexStr + title + scoreStr;
|
|
364
|
+
const padding = width - this.stripAnsi(line).length;
|
|
365
|
+
line += ' '.repeat(Math.max(0, padding));
|
|
366
|
+
if (isSelected) {
|
|
367
|
+
return colors.bgBlue(colors.white(colors.bold(line)));
|
|
368
|
+
}
|
|
369
|
+
return colors.white(indexStr) + colors.white(title) + colors.gray(scoreStr) + ' '.repeat(Math.max(0, padding));
|
|
370
|
+
}
|
|
371
|
+
renderRightPanelLine(lineIndex) {
|
|
372
|
+
const width = this.rightPanelWidth - 1;
|
|
373
|
+
const contentIndex = this.state.previewScrollOffset + lineIndex;
|
|
374
|
+
if (this.state.results.length === 0) {
|
|
375
|
+
if (lineIndex === Math.floor(this.contentHeight / 2) - 1) {
|
|
376
|
+
const msg = this.state.query ? 'No results found' : 'Type to search documentation';
|
|
377
|
+
const padding = Math.floor((width - msg.length) / 2);
|
|
378
|
+
return ' '.repeat(padding) + colors.gray(msg) + ' '.repeat(width - padding - msg.length);
|
|
379
|
+
}
|
|
380
|
+
return ' '.repeat(width);
|
|
381
|
+
}
|
|
382
|
+
if (contentIndex >= this.previewContent.length) {
|
|
383
|
+
return ' '.repeat(width);
|
|
384
|
+
}
|
|
385
|
+
let line = ' ' + this.previewContent[contentIndex];
|
|
386
|
+
const visibleLen = this.stripAnsi(line).length;
|
|
387
|
+
if (visibleLen > width) {
|
|
388
|
+
line = line.slice(0, width - 1) + '…';
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
line += ' '.repeat(width - visibleLen);
|
|
392
|
+
}
|
|
393
|
+
return line;
|
|
394
|
+
}
|
|
395
|
+
renderFooter() {
|
|
396
|
+
const bottomLine = BOX.horizontal.repeat(this.termWidth - 2);
|
|
397
|
+
const helpText = ' ↑↓ Navigate ←→ Scroll preview ESC Close ';
|
|
398
|
+
const pathText = this.state.results[this.state.selectedIndex]
|
|
399
|
+
? ` ${this.state.results[this.state.selectedIndex].path} `
|
|
400
|
+
: '';
|
|
401
|
+
const footerLine = colors.cyan(BOX.bottomLeft) +
|
|
402
|
+
colors.cyan(bottomLine) +
|
|
403
|
+
colors.cyan(BOX.bottomRight) +
|
|
404
|
+
'\n' +
|
|
405
|
+
colors.gray(helpText) +
|
|
406
|
+
' '.repeat(Math.max(0, this.termWidth - helpText.length - pathText.length)) +
|
|
407
|
+
colors.cyan(pathText);
|
|
408
|
+
return (colors.cyan(BOX.verticalRight) +
|
|
409
|
+
colors.cyan(BOX.horizontal.repeat(this.leftPanelWidth - 1)) +
|
|
410
|
+
colors.cyan(BOX.horizontalUp) +
|
|
411
|
+
colors.cyan(BOX.horizontal.repeat(this.rightPanelWidth)) +
|
|
412
|
+
colors.cyan(BOX.verticalLeft) +
|
|
413
|
+
'\n' +
|
|
414
|
+
footerLine);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
export async function openSearchPanel(query) {
|
|
418
|
+
const panel = new SearchPanel({ initialQuery: query });
|
|
419
|
+
await panel.open();
|
|
420
|
+
}
|
package/dist/cli/tui/shell.d.ts
CHANGED
|
@@ -10,6 +10,9 @@ export declare class RekShell {
|
|
|
10
10
|
private initialized;
|
|
11
11
|
private currentDoc;
|
|
12
12
|
private currentDocUrl;
|
|
13
|
+
private scrollBuffer;
|
|
14
|
+
private originalStdoutWrite;
|
|
15
|
+
private inScrollMode;
|
|
13
16
|
constructor();
|
|
14
17
|
private ensureInitialized;
|
|
15
18
|
private getPrompt;
|
|
@@ -17,6 +20,13 @@ export declare class RekShell {
|
|
|
17
20
|
private getRootDomain;
|
|
18
21
|
private completer;
|
|
19
22
|
start(): Promise<void>;
|
|
23
|
+
private setupScrollCapture;
|
|
24
|
+
private cleanupScrollCapture;
|
|
25
|
+
private setupScrollKeyHandler;
|
|
26
|
+
private handleScrollKey;
|
|
27
|
+
private enterScrollMode;
|
|
28
|
+
private exitScrollMode;
|
|
29
|
+
private renderScrollView;
|
|
20
30
|
private prompt;
|
|
21
31
|
private handleCommand;
|
|
22
32
|
private runInteractiveMode;
|
|
@@ -32,7 +42,11 @@ export declare class RekShell {
|
|
|
32
42
|
private executeRequest;
|
|
33
43
|
private runWhois;
|
|
34
44
|
private runTLS;
|
|
45
|
+
private runSecurityGrader;
|
|
46
|
+
private runIpIntelligence;
|
|
35
47
|
private runDNS;
|
|
48
|
+
private runDNSPropagation;
|
|
49
|
+
private runDnsEmailCheck;
|
|
36
50
|
private runRDAP;
|
|
37
51
|
private runPing;
|
|
38
52
|
private runScrap;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/cli/tui/shell.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/cli/tui/shell.ts"],"names":[],"mappings":"AAyCA,qBAAa,QAAQ;IACnB,OAAO,CAAC,EAAE,CAAsB;IAChC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,mBAAmB,CAA4C;IACvE,OAAO,CAAC,YAAY,CAAkB;;YAgBxB,iBAAiB;IAe/B,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,SAAS;IAcJ,KAAK;IA8ClB,OAAO,CAAC,kBAAkB;IA2B1B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,qBAAqB;IAqE7B,OAAO,CAAC,eAAe;IAmEvB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,MAAM;YAKA,aAAa;YA6Mb,kBAAkB;YAkBlB,SAAS;YAkBT,WAAW;IA0DzB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,QAAQ;IAoCV,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM;IA6CnC,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,UAAU;YAeJ,cAAc;YAyEd,QAAQ;YA8GR,MAAM;YA4FN,iBAAiB;YAqDjB,iBAAiB;YAkDjB,MAAM;YA2EN,iBAAiB;YAuBjB,gBAAgB;YAwEhB,OAAO;YA+DP,OAAO;YA0CP,QAAQ;YAoER,SAAS;YAsCT,aAAa;YA8Bb,aAAa;YA+Bb,aAAa;YA6Bb,cAAc;YAkCd,eAAe;YA+Ef,gBAAgB;YAmEhB,YAAY;YAiEZ,mBAAmB;YAsFnB,QAAQ;YA0FR,YAAY;YAoCZ,YAAY;YA6CZ,WAAW;IA6CzB,OAAO,CAAC,UAAU;IA4GlB,OAAO,CAAC,WAAW;YAgFL,eAAe;YAkBf,cAAc;YAgDd,SAAS;YAgBT,UAAU;YAuBV,UAAU;IAwBxB,OAAO,CAAC,aAAa;IAuCrB,OAAO,CAAC,SAAS;CA8ElB"}
|