@lanonasis/cli 1.5.2 → 2.0.1
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 +12 -3
- package/dist/core/achievements.d.ts +102 -0
- package/dist/core/achievements.js +425 -0
- package/dist/core/architecture.d.ts +145 -0
- package/dist/core/architecture.js +355 -0
- package/dist/core/dashboard.d.ts +71 -0
- package/dist/core/dashboard.js +569 -0
- package/dist/core/error-handler.d.ts +97 -0
- package/dist/core/error-handler.js +380 -0
- package/dist/core/power-mode.d.ts +118 -0
- package/dist/core/power-mode.js +460 -0
- package/dist/core/progress.d.ts +160 -0
- package/dist/core/progress.js +428 -0
- package/dist/core/welcome.d.ts +40 -0
- package/dist/core/welcome.js +466 -0
- package/dist/enhanced-cli.d.ts +15 -0
- package/dist/enhanced-cli.js +296 -0
- package/dist/index-simple.js +11 -3
- package/dist/utils/mcp-client.js +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Indicators and Feedback System
|
|
3
|
+
* Provides real-time visual feedback for long-running operations
|
|
4
|
+
*/
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import cliProgress from 'cli-progress';
|
|
8
|
+
import { performance } from 'perf_hooks';
|
|
9
|
+
export class ProgressIndicator {
|
|
10
|
+
spinner;
|
|
11
|
+
progressBar;
|
|
12
|
+
startTime;
|
|
13
|
+
/**
|
|
14
|
+
* Show a spinner for indeterminate progress
|
|
15
|
+
*/
|
|
16
|
+
startSpinner(message, options) {
|
|
17
|
+
this.startTime = performance.now();
|
|
18
|
+
this.spinner = ora({
|
|
19
|
+
text: message,
|
|
20
|
+
spinner: (options?.spinner || 'dots12'),
|
|
21
|
+
color: (options?.color || 'cyan'),
|
|
22
|
+
prefixText: options?.prefix,
|
|
23
|
+
indent: options?.indent || 0
|
|
24
|
+
}).start();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Update spinner text
|
|
28
|
+
*/
|
|
29
|
+
updateSpinner(message) {
|
|
30
|
+
if (this.spinner) {
|
|
31
|
+
this.spinner.text = message;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Complete spinner with success
|
|
36
|
+
*/
|
|
37
|
+
succeedSpinner(message) {
|
|
38
|
+
if (this.spinner) {
|
|
39
|
+
const elapsed = this.getElapsedTime();
|
|
40
|
+
const finalMessage = message || this.spinner.text;
|
|
41
|
+
this.spinner.succeed(`${finalMessage} ${chalk.dim(`(${elapsed}ms)`)}`);
|
|
42
|
+
this.spinner = undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Complete spinner with failure
|
|
47
|
+
*/
|
|
48
|
+
failSpinner(message) {
|
|
49
|
+
if (this.spinner) {
|
|
50
|
+
const elapsed = this.getElapsedTime();
|
|
51
|
+
const finalMessage = message || this.spinner.text;
|
|
52
|
+
this.spinner.fail(`${finalMessage} ${chalk.dim(`(${elapsed}ms)`)}`);
|
|
53
|
+
this.spinner = undefined;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Complete spinner with warning
|
|
58
|
+
*/
|
|
59
|
+
warnSpinner(message) {
|
|
60
|
+
if (this.spinner) {
|
|
61
|
+
const elapsed = this.getElapsedTime();
|
|
62
|
+
const finalMessage = message || this.spinner.text;
|
|
63
|
+
this.spinner.warn(`${finalMessage} ${chalk.dim(`(${elapsed}ms)`)}`);
|
|
64
|
+
this.spinner = undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Stop spinner without status
|
|
69
|
+
*/
|
|
70
|
+
stopSpinner() {
|
|
71
|
+
if (this.spinner) {
|
|
72
|
+
this.spinner.stop();
|
|
73
|
+
this.spinner = undefined;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Show a progress bar for determinate progress
|
|
78
|
+
*/
|
|
79
|
+
startProgressBar(total, options) {
|
|
80
|
+
this.startTime = performance.now();
|
|
81
|
+
const format = options?.format ||
|
|
82
|
+
'{title} |' + chalk.cyan('{bar}') + '| {percentage}% | {value}/{total} | {duration}s | {eta}s remaining';
|
|
83
|
+
this.progressBar = new cliProgress.SingleBar({
|
|
84
|
+
format,
|
|
85
|
+
barCompleteChar: '█',
|
|
86
|
+
barIncompleteChar: '░',
|
|
87
|
+
hideCursor: true,
|
|
88
|
+
clearOnComplete: options?.clearOnComplete || false,
|
|
89
|
+
stopOnComplete: true
|
|
90
|
+
}, cliProgress.Presets.shades_classic);
|
|
91
|
+
this.progressBar.start(total, 0, {
|
|
92
|
+
title: options?.title || 'Progress'
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Update progress bar
|
|
97
|
+
*/
|
|
98
|
+
updateProgressBar(current, payload) {
|
|
99
|
+
if (this.progressBar) {
|
|
100
|
+
this.progressBar.update(current, payload);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Increment progress bar
|
|
105
|
+
*/
|
|
106
|
+
incrementProgressBar(amount = 1) {
|
|
107
|
+
if (this.progressBar) {
|
|
108
|
+
this.progressBar.increment(amount);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Complete progress bar
|
|
113
|
+
*/
|
|
114
|
+
stopProgressBar() {
|
|
115
|
+
if (this.progressBar) {
|
|
116
|
+
this.progressBar.stop();
|
|
117
|
+
this.progressBar = undefined;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Execute operation with spinner
|
|
122
|
+
*/
|
|
123
|
+
async withSpinner(operation, message, options) {
|
|
124
|
+
this.startSpinner(message, options);
|
|
125
|
+
try {
|
|
126
|
+
const result = await operation();
|
|
127
|
+
this.succeedSpinner();
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
this.failSpinner();
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Execute operation with progress tracking
|
|
137
|
+
*/
|
|
138
|
+
async withProgress(operation, total, options) {
|
|
139
|
+
this.startProgressBar(total, options);
|
|
140
|
+
const tracker = {
|
|
141
|
+
update: (current, payload) => {
|
|
142
|
+
this.updateProgressBar(current, payload);
|
|
143
|
+
},
|
|
144
|
+
increment: (amount) => {
|
|
145
|
+
this.incrementProgressBar(amount);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
try {
|
|
149
|
+
const result = await operation(tracker);
|
|
150
|
+
this.stopProgressBar();
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
this.stopProgressBar();
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get elapsed time since start
|
|
160
|
+
*/
|
|
161
|
+
getElapsedTime() {
|
|
162
|
+
if (!this.startTime)
|
|
163
|
+
return '0';
|
|
164
|
+
const elapsed = Math.round(performance.now() - this.startTime);
|
|
165
|
+
return elapsed.toString();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Multi-step progress indicator
|
|
170
|
+
*/
|
|
171
|
+
export class MultiStepProgress {
|
|
172
|
+
steps;
|
|
173
|
+
currentStep = 0;
|
|
174
|
+
progressIndicator;
|
|
175
|
+
constructor(steps) {
|
|
176
|
+
this.steps = steps;
|
|
177
|
+
this.progressIndicator = new ProgressIndicator();
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Start the multi-step process
|
|
181
|
+
*/
|
|
182
|
+
start() {
|
|
183
|
+
this.render();
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Complete current step and move to next
|
|
187
|
+
*/
|
|
188
|
+
nextStep(success = true) {
|
|
189
|
+
if (this.currentStep < this.steps.length) {
|
|
190
|
+
this.steps[this.currentStep].status = success ? 'completed' : 'failed';
|
|
191
|
+
this.currentStep++;
|
|
192
|
+
this.render();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Complete all steps
|
|
197
|
+
*/
|
|
198
|
+
complete() {
|
|
199
|
+
for (let i = this.currentStep; i < this.steps.length; i++) {
|
|
200
|
+
this.steps[i].status = 'completed';
|
|
201
|
+
}
|
|
202
|
+
this.currentStep = this.steps.length;
|
|
203
|
+
this.render();
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Render the multi-step progress
|
|
207
|
+
*/
|
|
208
|
+
render() {
|
|
209
|
+
console.clear();
|
|
210
|
+
const progressBar = this.renderProgressBar();
|
|
211
|
+
const stepList = this.renderStepList();
|
|
212
|
+
console.log(chalk.bold('Progress\n'));
|
|
213
|
+
console.log(progressBar);
|
|
214
|
+
console.log();
|
|
215
|
+
console.log(stepList);
|
|
216
|
+
if (this.currentStep < this.steps.length) {
|
|
217
|
+
console.log();
|
|
218
|
+
console.log(chalk.cyan(`→ ${this.steps[this.currentStep].name}...`));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Render progress bar
|
|
223
|
+
*/
|
|
224
|
+
renderProgressBar() {
|
|
225
|
+
const completed = this.steps.filter(s => s.status === 'completed').length;
|
|
226
|
+
const total = this.steps.length;
|
|
227
|
+
const percentage = Math.round((completed / total) * 100);
|
|
228
|
+
const barLength = 40;
|
|
229
|
+
const filled = Math.round((completed / total) * barLength);
|
|
230
|
+
const bar = '█'.repeat(filled) + '░'.repeat(barLength - filled);
|
|
231
|
+
return `[${chalk.cyan(bar)}] ${percentage}%`;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Render step list
|
|
235
|
+
*/
|
|
236
|
+
renderStepList() {
|
|
237
|
+
return this.steps.map((step, index) => {
|
|
238
|
+
let icon;
|
|
239
|
+
let color;
|
|
240
|
+
switch (step.status) {
|
|
241
|
+
case 'completed':
|
|
242
|
+
icon = chalk.green('✓');
|
|
243
|
+
color = chalk.green;
|
|
244
|
+
break;
|
|
245
|
+
case 'failed':
|
|
246
|
+
icon = chalk.red('✗');
|
|
247
|
+
color = chalk.red;
|
|
248
|
+
break;
|
|
249
|
+
case 'pending':
|
|
250
|
+
icon = chalk.gray('○');
|
|
251
|
+
color = chalk.gray;
|
|
252
|
+
break;
|
|
253
|
+
case 'active':
|
|
254
|
+
icon = chalk.blue('●');
|
|
255
|
+
color = chalk.blue;
|
|
256
|
+
break;
|
|
257
|
+
default:
|
|
258
|
+
icon = chalk.gray('○');
|
|
259
|
+
color = chalk.gray;
|
|
260
|
+
}
|
|
261
|
+
const stepNumber = `[${index + 1}]`;
|
|
262
|
+
const name = color(step.name);
|
|
263
|
+
const description = step.description ? chalk.dim(` - ${step.description}`) : '';
|
|
264
|
+
return `${icon} ${stepNumber} ${name}${description}`;
|
|
265
|
+
}).join('\n');
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Smart suggestions system
|
|
270
|
+
*/
|
|
271
|
+
export class SmartSuggestions {
|
|
272
|
+
userContext;
|
|
273
|
+
commandHistory = [];
|
|
274
|
+
constructor(userContext) {
|
|
275
|
+
this.userContext = userContext;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get suggestions based on current context
|
|
279
|
+
*/
|
|
280
|
+
getSuggestions(input) {
|
|
281
|
+
const suggestions = [];
|
|
282
|
+
// Command completion suggestions
|
|
283
|
+
if (input.startsWith('onasis ')) {
|
|
284
|
+
suggestions.push(...this.getCommandSuggestions(input));
|
|
285
|
+
}
|
|
286
|
+
// Natural language interpretation
|
|
287
|
+
if (!input.startsWith('onasis')) {
|
|
288
|
+
suggestions.push(...this.getNaturalLanguageSuggestions(input));
|
|
289
|
+
}
|
|
290
|
+
// Historical suggestions
|
|
291
|
+
suggestions.push(...this.getHistoricalSuggestions(input));
|
|
292
|
+
// Context-based suggestions
|
|
293
|
+
suggestions.push(...this.getContextualSuggestions());
|
|
294
|
+
return this.rankSuggestions(suggestions).slice(0, 5);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get command-based suggestions
|
|
298
|
+
*/
|
|
299
|
+
getCommandSuggestions(input) {
|
|
300
|
+
const commands = [
|
|
301
|
+
{ command: 'memory create', description: 'Create a new memory' },
|
|
302
|
+
{ command: 'memory search', description: 'Search memories' },
|
|
303
|
+
{ command: 'memory list', description: 'List all memories' },
|
|
304
|
+
{ command: 'topic create', description: 'Create a new topic' },
|
|
305
|
+
{ command: 'api-keys create', description: 'Create API key' },
|
|
306
|
+
{ command: 'auth login', description: 'Authenticate' },
|
|
307
|
+
{ command: 'config set', description: 'Update configuration' }
|
|
308
|
+
];
|
|
309
|
+
const partial = input.replace('onasis ', '').toLowerCase();
|
|
310
|
+
return commands
|
|
311
|
+
.filter(cmd => cmd.command.startsWith(partial))
|
|
312
|
+
.map(cmd => ({
|
|
313
|
+
text: `onasis ${cmd.command}`,
|
|
314
|
+
description: cmd.description,
|
|
315
|
+
type: 'command',
|
|
316
|
+
score: 0.8
|
|
317
|
+
}));
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Get natural language suggestions
|
|
321
|
+
*/
|
|
322
|
+
getNaturalLanguageSuggestions(input) {
|
|
323
|
+
const suggestions = [];
|
|
324
|
+
const lower = input.toLowerCase();
|
|
325
|
+
if (lower.includes('remember') || lower.includes('save')) {
|
|
326
|
+
suggestions.push({
|
|
327
|
+
text: 'onasis memory create',
|
|
328
|
+
description: 'Create a new memory from your input',
|
|
329
|
+
type: 'natural',
|
|
330
|
+
score: 0.9
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
if (lower.includes('find') || lower.includes('search')) {
|
|
334
|
+
suggestions.push({
|
|
335
|
+
text: `onasis memory search "${input.replace(/find|search/gi, '').trim()}"`,
|
|
336
|
+
description: 'Search for memories',
|
|
337
|
+
type: 'natural',
|
|
338
|
+
score: 0.9
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
if (lower.includes('help') || lower.includes('how')) {
|
|
342
|
+
suggestions.push({
|
|
343
|
+
text: 'onasis help',
|
|
344
|
+
description: 'Show help and documentation',
|
|
345
|
+
type: 'natural',
|
|
346
|
+
score: 0.85
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
return suggestions;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Get historical suggestions
|
|
353
|
+
*/
|
|
354
|
+
getHistoricalSuggestions(input) {
|
|
355
|
+
return this.commandHistory
|
|
356
|
+
.filter(cmd => cmd.startsWith(input))
|
|
357
|
+
.map(cmd => ({
|
|
358
|
+
text: cmd,
|
|
359
|
+
description: 'Previously used command',
|
|
360
|
+
type: 'history',
|
|
361
|
+
score: 0.7
|
|
362
|
+
}));
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Get contextual suggestions
|
|
366
|
+
*/
|
|
367
|
+
getContextualSuggestions() {
|
|
368
|
+
const suggestions = [];
|
|
369
|
+
const now = new Date();
|
|
370
|
+
const hour = now.getHours();
|
|
371
|
+
// Time-based suggestions
|
|
372
|
+
if (hour >= 9 && hour <= 11) {
|
|
373
|
+
suggestions.push({
|
|
374
|
+
text: 'onasis memory create --type meeting',
|
|
375
|
+
description: 'Create morning meeting notes',
|
|
376
|
+
type: 'contextual',
|
|
377
|
+
score: 0.6
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
else if (hour >= 16 && hour <= 18) {
|
|
381
|
+
suggestions.push({
|
|
382
|
+
text: 'onasis memory list --today',
|
|
383
|
+
description: "Review today's memories",
|
|
384
|
+
type: 'contextual',
|
|
385
|
+
score: 0.6
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
// User behavior suggestions
|
|
389
|
+
if (!this.userContext.hasCreatedMemoryToday) {
|
|
390
|
+
suggestions.push({
|
|
391
|
+
text: 'onasis memory create',
|
|
392
|
+
description: "You haven't created a memory today",
|
|
393
|
+
type: 'contextual',
|
|
394
|
+
score: 0.75
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
return suggestions;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Rank suggestions by relevance
|
|
401
|
+
*/
|
|
402
|
+
rankSuggestions(suggestions) {
|
|
403
|
+
return suggestions.sort((a, b) => b.score - a.score);
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Add command to history
|
|
407
|
+
*/
|
|
408
|
+
addToHistory(command) {
|
|
409
|
+
this.commandHistory.unshift(command);
|
|
410
|
+
if (this.commandHistory.length > 100) {
|
|
411
|
+
this.commandHistory.pop();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Display suggestions
|
|
416
|
+
*/
|
|
417
|
+
displaySuggestions(suggestions) {
|
|
418
|
+
if (suggestions.length === 0)
|
|
419
|
+
return;
|
|
420
|
+
console.log(chalk.dim('\n💡 Suggestions:'));
|
|
421
|
+
suggestions.forEach((suggestion, index) => {
|
|
422
|
+
const number = chalk.cyan(`${index + 1}.`);
|
|
423
|
+
const text = chalk.bold(suggestion.text);
|
|
424
|
+
const desc = chalk.dim(suggestion.description);
|
|
425
|
+
console.log(` ${number} ${text} - ${desc}`);
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Welcome and Onboarding Experience
|
|
3
|
+
* Provides first-time user experience and guided setup
|
|
4
|
+
*/
|
|
5
|
+
import { StateManager } from './architecture.js';
|
|
6
|
+
export declare class WelcomeExperience {
|
|
7
|
+
private stateManager;
|
|
8
|
+
private isFirstRun;
|
|
9
|
+
constructor(stateManager: StateManager);
|
|
10
|
+
show(): Promise<void>;
|
|
11
|
+
private displayWelcomeBanner;
|
|
12
|
+
private showMainMenu;
|
|
13
|
+
private handleMenuChoice;
|
|
14
|
+
private startInteractiveSetup;
|
|
15
|
+
private goToDashboard;
|
|
16
|
+
private showDocumentation;
|
|
17
|
+
private showAbout;
|
|
18
|
+
private showSettings;
|
|
19
|
+
private showHelp;
|
|
20
|
+
private checkAuthentication;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Interactive Setup Flow
|
|
24
|
+
*/
|
|
25
|
+
export declare class InteractiveSetup {
|
|
26
|
+
private stateManager;
|
|
27
|
+
private setupProgress;
|
|
28
|
+
constructor(stateManager: StateManager);
|
|
29
|
+
run(): Promise<void>;
|
|
30
|
+
private showProgressHeader;
|
|
31
|
+
private renderProgressBar;
|
|
32
|
+
private setupConnection;
|
|
33
|
+
private setupAuthentication;
|
|
34
|
+
private authenticateWithVendorKey;
|
|
35
|
+
private authenticateWithBrowser;
|
|
36
|
+
private authenticateWithEmail;
|
|
37
|
+
private setupConfiguration;
|
|
38
|
+
private showSetupComplete;
|
|
39
|
+
private simulateDelay;
|
|
40
|
+
}
|