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.
@@ -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
+ };