scorpion-cli 0.1.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 +152 -0
- package/install.ps1 +22 -0
- package/install.sh +19 -0
- package/package.json +44 -0
- package/src/agent.js +226 -0
- package/src/commands.js +193 -0
- package/src/index.js +86 -0
- package/src/ollama.js +126 -0
- package/src/registry.js +112 -0
- package/src/tools/context.js +432 -0
- package/src/tools/deep-research.js +425 -0
- package/src/tools/documents.js +299 -0
- package/src/tools/filesystem.js +402 -0
- package/src/tools/shell.js +134 -0
- package/src/tools/system.js +379 -0
- package/src/tools/web.js +433 -0
- package/src/ui/charts.js +213 -0
- package/src/ui/export.js +141 -0
- package/src/ui/formatter.js +365 -0
- package/src/ui/images.js +153 -0
- package/src/ui/panels.js +150 -0
- package/src/ui/progress.js +131 -0
- package/src/ui/repl.js +477 -0
- package/src/ui/spinner.js +99 -0
- package/src/ui/table.js +145 -0
package/src/ui/panels.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Box and Panel Components
|
|
3
|
+
* Create beautiful boxed content for terminal
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { colors, chalk } from './formatter.js';
|
|
7
|
+
import boxen from 'boxen';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create a boxed panel
|
|
11
|
+
* @param {string} content - Panel content
|
|
12
|
+
* @param {Object} options - Boxen options
|
|
13
|
+
*/
|
|
14
|
+
export function createPanel(content, options = {}) {
|
|
15
|
+
const {
|
|
16
|
+
title = null,
|
|
17
|
+
borderColor = 'cyan',
|
|
18
|
+
borderStyle = 'round',
|
|
19
|
+
padding = 1,
|
|
20
|
+
margin = { top: 1, bottom: 1, left: 2, right: 0 }
|
|
21
|
+
} = options;
|
|
22
|
+
|
|
23
|
+
return boxen(content, {
|
|
24
|
+
title,
|
|
25
|
+
titleAlignment: 'center',
|
|
26
|
+
borderColor,
|
|
27
|
+
borderStyle,
|
|
28
|
+
padding,
|
|
29
|
+
margin
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create an info panel
|
|
35
|
+
* @param {string} content - Content
|
|
36
|
+
* @param {string} title - Title
|
|
37
|
+
*/
|
|
38
|
+
export function infoPanel(content, title = 'ℹ Info') {
|
|
39
|
+
return createPanel(content, {
|
|
40
|
+
title,
|
|
41
|
+
borderColor: 'blue',
|
|
42
|
+
borderStyle: 'round'
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create a success panel
|
|
48
|
+
* @param {string} content - Content
|
|
49
|
+
* @param {string} title - Title
|
|
50
|
+
*/
|
|
51
|
+
export function successPanel(content, title = '✓ Success') {
|
|
52
|
+
return createPanel(content, {
|
|
53
|
+
title,
|
|
54
|
+
borderColor: 'green',
|
|
55
|
+
borderStyle: 'round'
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create an error panel
|
|
61
|
+
* @param {string} content - Content
|
|
62
|
+
* @param {string} title - Title
|
|
63
|
+
*/
|
|
64
|
+
export function errorPanel(content, title = '✗ Error') {
|
|
65
|
+
return createPanel(content, {
|
|
66
|
+
title,
|
|
67
|
+
borderColor: 'red',
|
|
68
|
+
borderStyle: 'round'
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create a response panel (main AI response)
|
|
74
|
+
* @param {string} content - Content
|
|
75
|
+
*/
|
|
76
|
+
export function responsePanel(content) {
|
|
77
|
+
return createPanel(content, {
|
|
78
|
+
title: chalk.bold.cyan('◆ Response'),
|
|
79
|
+
borderColor: 'cyan',
|
|
80
|
+
borderStyle: 'round',
|
|
81
|
+
padding: { top: 1, bottom: 1, left: 2, right: 2 }
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Create a section divider with title
|
|
87
|
+
* @param {string} title - Section title
|
|
88
|
+
* @param {string} icon - Optional icon
|
|
89
|
+
*/
|
|
90
|
+
export function sectionDivider(title, icon = '◆') {
|
|
91
|
+
const line = '─'.repeat(60);
|
|
92
|
+
const titleText = `${icon} ${title}`;
|
|
93
|
+
console.log();
|
|
94
|
+
console.log(colors.accent(` ${titleText}`));
|
|
95
|
+
console.log(colors.dim(` ${line}`));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Create a stats card
|
|
100
|
+
* @param {Object} stats - Stats object
|
|
101
|
+
* @param {string} title - Card title
|
|
102
|
+
*/
|
|
103
|
+
export function statsCard(stats, title = '📊 Stats') {
|
|
104
|
+
const lines = [];
|
|
105
|
+
|
|
106
|
+
for (const [key, value] of Object.entries(stats)) {
|
|
107
|
+
const formattedKey = key.charAt(0).toUpperCase() + key.slice(1).replace(/_/g, ' ');
|
|
108
|
+
lines.push(`${chalk.dim(formattedKey + ':')} ${chalk.cyan(value)}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return createPanel(lines.join('\n'), {
|
|
112
|
+
title,
|
|
113
|
+
borderColor: 'magenta',
|
|
114
|
+
borderStyle: 'round',
|
|
115
|
+
padding: 1
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Create a quote/callout box
|
|
121
|
+
* @param {string} content - Quote content
|
|
122
|
+
* @param {string} type - Type (info, warning, tip)
|
|
123
|
+
*/
|
|
124
|
+
export function calloutBox(content, type = 'info') {
|
|
125
|
+
const styles = {
|
|
126
|
+
info: { icon: 'ℹ', color: 'blue', title: 'Info' },
|
|
127
|
+
warning: { icon: '⚠', color: 'yellow', title: 'Warning' },
|
|
128
|
+
tip: { icon: '💡', color: 'green', title: 'Tip' },
|
|
129
|
+
note: { icon: '📝', color: 'cyan', title: 'Note' }
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const style = styles[type] || styles.info;
|
|
133
|
+
|
|
134
|
+
return createPanel(content, {
|
|
135
|
+
title: `${style.icon} ${style.title}`,
|
|
136
|
+
borderColor: style.color,
|
|
137
|
+
borderStyle: 'round'
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export default {
|
|
142
|
+
createPanel,
|
|
143
|
+
infoPanel,
|
|
144
|
+
successPanel,
|
|
145
|
+
errorPanel,
|
|
146
|
+
responsePanel,
|
|
147
|
+
sectionDivider,
|
|
148
|
+
statsCard,
|
|
149
|
+
calloutBox
|
|
150
|
+
};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live Progress Module for Deep Research
|
|
3
|
+
* Shows real-time status as sources are fetched
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { colors, chalk } from './formatter.js';
|
|
7
|
+
|
|
8
|
+
let currentOperation = null;
|
|
9
|
+
let sourcesFetched = 0;
|
|
10
|
+
let totalSources = 0;
|
|
11
|
+
let startTime = null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Start research progress tracking
|
|
15
|
+
* @param {number} total - Total number of sources
|
|
16
|
+
*/
|
|
17
|
+
export function startResearch(total) {
|
|
18
|
+
currentOperation = 'research';
|
|
19
|
+
sourcesFetched = 0;
|
|
20
|
+
totalSources = total;
|
|
21
|
+
startTime = Date.now();
|
|
22
|
+
|
|
23
|
+
console.log();
|
|
24
|
+
console.log(colors.accent(' 🔬 ') + colors.bold.white('Deep Research Started'));
|
|
25
|
+
console.log(colors.dim(' ─'.repeat(30)));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Update progress when searching a specific source
|
|
30
|
+
* @param {string} source - Source name (arXiv, HN, Wikipedia)
|
|
31
|
+
*/
|
|
32
|
+
export function searchingSource(source) {
|
|
33
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
34
|
+
console.log(colors.dim(' ├─ ') + colors.cyan(`Searching ${source}...`) + colors.dim(` (${elapsed}s)`));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Show found results from a source
|
|
39
|
+
* @param {string} source - Source name
|
|
40
|
+
* @param {number} count - Number of results found
|
|
41
|
+
*/
|
|
42
|
+
export function foundResults(source, count) {
|
|
43
|
+
if (count > 0) {
|
|
44
|
+
console.log(colors.dim(' │ ') + colors.success(`✓ Found ${count} results from ${source}`));
|
|
45
|
+
} else {
|
|
46
|
+
console.log(colors.dim(' │ ') + colors.muted(`⊗ No results from ${source}`));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Update progress when fetching a specific URL
|
|
52
|
+
* @param {string} url - URL being fetched
|
|
53
|
+
* @param {number} index - Current index
|
|
54
|
+
*/
|
|
55
|
+
export function fetchingSource(url, index) {
|
|
56
|
+
sourcesFetched = index;
|
|
57
|
+
const progress = `${index}/${totalSources}`;
|
|
58
|
+
const domain = url.replace(/^https?:\/\//, '').split('/')[0].slice(0, 30);
|
|
59
|
+
|
|
60
|
+
console.log(colors.dim(' ├─ ') + colors.info(`[${progress}] `) + colors.white(`Fetching: ${domain}...`));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Show when source fetch completes
|
|
65
|
+
* @param {string} title - Source title
|
|
66
|
+
* @param {boolean} success - Whether it succeeded
|
|
67
|
+
*/
|
|
68
|
+
export function sourceCompleted(title, success = true) {
|
|
69
|
+
if (success) {
|
|
70
|
+
console.log(colors.dim(' │ ') + colors.success(`✓ `) + colors.dim(title.slice(0, 60)));
|
|
71
|
+
} else {
|
|
72
|
+
console.log(colors.dim(' │ ') + colors.error(`✗ `) + colors.dim('Failed to fetch'));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Show report generation status
|
|
78
|
+
*/
|
|
79
|
+
export function generatingReport() {
|
|
80
|
+
console.log(colors.dim(' ├─ ') + colors.accent('Generating report...'));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Complete research and show final stats
|
|
85
|
+
* @param {Object} stats - Research statistics
|
|
86
|
+
*/
|
|
87
|
+
export function completeResearch(stats) {
|
|
88
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
89
|
+
|
|
90
|
+
console.log(colors.dim(' └─ ') + colors.success('Research Complete!'));
|
|
91
|
+
console.log();
|
|
92
|
+
console.log(colors.dim(' 📊 Stats:'));
|
|
93
|
+
console.log(colors.dim(' • ') + `Sources: ${chalk.cyan(stats.sources)}`);
|
|
94
|
+
console.log(colors.dim(' • ') + `Confidence: ${chalk.cyan(stats.confidence + '%')}`);
|
|
95
|
+
console.log(colors.dim(' • ') + `Time: ${chalk.cyan(elapsed + 's')}`);
|
|
96
|
+
console.log();
|
|
97
|
+
|
|
98
|
+
// Reset
|
|
99
|
+
currentOperation = null;
|
|
100
|
+
sourcesFetched = 0;
|
|
101
|
+
totalSources = 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Show sub-query being explored
|
|
106
|
+
* @param {string} query - Sub-query
|
|
107
|
+
* @param {string} type - Query type
|
|
108
|
+
*/
|
|
109
|
+
export function exploringQuery(query, type) {
|
|
110
|
+
console.log(colors.dim(' ├─ ') + colors.info(`Exploring [${type}]: `) + colors.dim('"') + colors.white(query.slice(0, 50)) + colors.dim('"'));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get current progress percentage
|
|
115
|
+
*/
|
|
116
|
+
export function getProgress() {
|
|
117
|
+
if (totalSources === 0) return 0;
|
|
118
|
+
return Math.round((sourcesFetched / totalSources) * 100);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export default {
|
|
122
|
+
startResearch,
|
|
123
|
+
searchingSource,
|
|
124
|
+
foundResults,
|
|
125
|
+
fetchingSource,
|
|
126
|
+
sourceCompleted,
|
|
127
|
+
generatingReport,
|
|
128
|
+
completeResearch,
|
|
129
|
+
exploringQuery,
|
|
130
|
+
getProgress
|
|
131
|
+
};
|