@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
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# @lanonasis/cli
|
|
1
|
+
# @lanonasis/cli v2.0.0 - Enhanced Interactive CLI Experience
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@lanonasis/cli)
|
|
4
4
|
[](https://www.npmjs.com/package/@lanonasis/cli)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
[](https://api.lanonasis.com/.well-known/onasis.json)
|
|
7
7
|
|
|
8
|
-
Professional command-line interface for LanOnasis Memory as a Service (MaaS) platform with **Golden Contract compliance
|
|
8
|
+
🚀 **NEW IN v2.0**: Revolutionary interactive CLI experience with guided workflows, smart suggestions, achievement system, and power user mode. Professional command-line interface for LanOnasis Memory as a Service (MaaS) platform with **Golden Contract compliance**.
|
|
9
9
|
|
|
10
10
|
## 🚀 Quick Start
|
|
11
11
|
|
|
@@ -344,7 +344,16 @@ onasis health
|
|
|
344
344
|
|
|
345
345
|
## 📝 Version History
|
|
346
346
|
|
|
347
|
-
###
|
|
347
|
+
### v2.0.0 (Current)
|
|
348
|
+
- 🎯 **Interactive Dashboard**: Central command center for all operations
|
|
349
|
+
- 🎉 **Welcome Experience**: Guided onboarding for new users
|
|
350
|
+
- ⚡ **Power Mode**: Streamlined interface for expert users
|
|
351
|
+
- 🤖 **Smart Suggestions**: Context-aware command recommendations
|
|
352
|
+
- 🏆 **Achievement System**: Gamification to track progress
|
|
353
|
+
- 🛡️ **Enhanced Error Handling**: Intelligent error messages with recovery
|
|
354
|
+
- 📊 **Progress Indicators**: Visual feedback for operations
|
|
355
|
+
|
|
356
|
+
### v1.5.2
|
|
348
357
|
- ✅ Golden Contract compliance (Onasis-Core v0.1)
|
|
349
358
|
- ✅ Professional shell completions (bash/zsh/fish)
|
|
350
359
|
- ✅ Enhanced authentication (vendor keys, OAuth, credentials)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Achievement System and Engagement Features
|
|
3
|
+
* Gamification elements to enhance user engagement
|
|
4
|
+
*/
|
|
5
|
+
import { StateManager } from './architecture.js';
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
export interface Achievement {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
icon: string;
|
|
12
|
+
points: number;
|
|
13
|
+
category: 'usage' | 'milestone' | 'special' | 'hidden';
|
|
14
|
+
unlocked: boolean;
|
|
15
|
+
unlockedAt?: Date;
|
|
16
|
+
progress?: number;
|
|
17
|
+
maxProgress?: number;
|
|
18
|
+
condition: (stats: UserStats) => boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface UserStats {
|
|
21
|
+
totalMemories: number;
|
|
22
|
+
totalSearches: number;
|
|
23
|
+
totalTopics: number;
|
|
24
|
+
totalApiCalls: number;
|
|
25
|
+
daysActive: number;
|
|
26
|
+
longestStreak: number;
|
|
27
|
+
currentStreak: number;
|
|
28
|
+
powerModeUsage: number;
|
|
29
|
+
memoriesCreatedToday: number;
|
|
30
|
+
searchAccuracy: number;
|
|
31
|
+
}
|
|
32
|
+
export declare class AchievementSystem extends EventEmitter {
|
|
33
|
+
private stateManager;
|
|
34
|
+
private achievements;
|
|
35
|
+
private userStats;
|
|
36
|
+
private unlockedAchievements;
|
|
37
|
+
constructor(stateManager: StateManager);
|
|
38
|
+
/**
|
|
39
|
+
* Initialize all available achievements
|
|
40
|
+
*/
|
|
41
|
+
private initializeAchievements;
|
|
42
|
+
/**
|
|
43
|
+
* Check for new achievements
|
|
44
|
+
*/
|
|
45
|
+
checkAchievements(): Achievement[];
|
|
46
|
+
/**
|
|
47
|
+
* Update achievement progress
|
|
48
|
+
*/
|
|
49
|
+
private updateProgress;
|
|
50
|
+
/**
|
|
51
|
+
* Unlock an achievement
|
|
52
|
+
*/
|
|
53
|
+
private unlockAchievement;
|
|
54
|
+
/**
|
|
55
|
+
* Show achievement celebration
|
|
56
|
+
*/
|
|
57
|
+
celebrate(achievement: Achievement): void;
|
|
58
|
+
/**
|
|
59
|
+
* Show all achievements
|
|
60
|
+
*/
|
|
61
|
+
showAchievements(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Display single achievement
|
|
64
|
+
*/
|
|
65
|
+
private displayAchievement;
|
|
66
|
+
/**
|
|
67
|
+
* Get category title
|
|
68
|
+
*/
|
|
69
|
+
private getCategoryTitle;
|
|
70
|
+
/**
|
|
71
|
+
* Get total possible points
|
|
72
|
+
*/
|
|
73
|
+
getTotalPoints(): number;
|
|
74
|
+
/**
|
|
75
|
+
* Get unlocked points
|
|
76
|
+
*/
|
|
77
|
+
getUnlockedPoints(): number;
|
|
78
|
+
/**
|
|
79
|
+
* Update user stats
|
|
80
|
+
*/
|
|
81
|
+
updateStats(updates: Partial<UserStats>): void;
|
|
82
|
+
/**
|
|
83
|
+
* Get leaderboard position
|
|
84
|
+
*/
|
|
85
|
+
getLeaderboardPosition(): number;
|
|
86
|
+
/**
|
|
87
|
+
* Load user stats from storage
|
|
88
|
+
*/
|
|
89
|
+
private loadUserStats;
|
|
90
|
+
/**
|
|
91
|
+
* Save user stats to storage
|
|
92
|
+
*/
|
|
93
|
+
private saveUserStats;
|
|
94
|
+
/**
|
|
95
|
+
* Load unlocked achievements from storage
|
|
96
|
+
*/
|
|
97
|
+
private loadUnlockedAchievements;
|
|
98
|
+
/**
|
|
99
|
+
* Save unlocked achievements to storage
|
|
100
|
+
*/
|
|
101
|
+
private saveUnlockedAchievements;
|
|
102
|
+
}
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Achievement System and Engagement Features
|
|
3
|
+
* Gamification elements to enhance user engagement
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import boxen from 'boxen';
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
export class AchievementSystem extends EventEmitter {
|
|
9
|
+
stateManager;
|
|
10
|
+
achievements;
|
|
11
|
+
userStats;
|
|
12
|
+
unlockedAchievements;
|
|
13
|
+
constructor(stateManager) {
|
|
14
|
+
super();
|
|
15
|
+
this.stateManager = stateManager;
|
|
16
|
+
this.achievements = new Map();
|
|
17
|
+
this.unlockedAchievements = new Set();
|
|
18
|
+
this.userStats = this.loadUserStats();
|
|
19
|
+
this.initializeAchievements();
|
|
20
|
+
this.loadUnlockedAchievements();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Initialize all available achievements
|
|
24
|
+
*/
|
|
25
|
+
initializeAchievements() {
|
|
26
|
+
const achievementList = [
|
|
27
|
+
// Usage achievements
|
|
28
|
+
{
|
|
29
|
+
id: 'first_memory',
|
|
30
|
+
name: 'First Step',
|
|
31
|
+
description: 'Create your first memory',
|
|
32
|
+
icon: '🎯',
|
|
33
|
+
points: 10,
|
|
34
|
+
category: 'usage',
|
|
35
|
+
unlocked: false,
|
|
36
|
+
condition: (stats) => stats.totalMemories >= 1
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'memory_collector',
|
|
40
|
+
name: 'Memory Collector',
|
|
41
|
+
description: 'Create 100 memories',
|
|
42
|
+
icon: '📚',
|
|
43
|
+
points: 50,
|
|
44
|
+
category: 'milestone',
|
|
45
|
+
unlocked: false,
|
|
46
|
+
progress: 0,
|
|
47
|
+
maxProgress: 100,
|
|
48
|
+
condition: (stats) => stats.totalMemories >= 100
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'memory_master',
|
|
52
|
+
name: 'Memory Master',
|
|
53
|
+
description: 'Create 1000 memories',
|
|
54
|
+
icon: '🏆',
|
|
55
|
+
points: 200,
|
|
56
|
+
category: 'milestone',
|
|
57
|
+
unlocked: false,
|
|
58
|
+
progress: 0,
|
|
59
|
+
maxProgress: 1000,
|
|
60
|
+
condition: (stats) => stats.totalMemories >= 1000
|
|
61
|
+
},
|
|
62
|
+
// Search achievements
|
|
63
|
+
{
|
|
64
|
+
id: 'first_search',
|
|
65
|
+
name: 'Explorer',
|
|
66
|
+
description: 'Perform your first search',
|
|
67
|
+
icon: '🔍',
|
|
68
|
+
points: 10,
|
|
69
|
+
category: 'usage',
|
|
70
|
+
unlocked: false,
|
|
71
|
+
condition: (stats) => stats.totalSearches >= 1
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'search_pro',
|
|
75
|
+
name: 'Search Professional',
|
|
76
|
+
description: 'Perform 100 searches',
|
|
77
|
+
icon: '🎓',
|
|
78
|
+
points: 50,
|
|
79
|
+
category: 'milestone',
|
|
80
|
+
unlocked: false,
|
|
81
|
+
progress: 0,
|
|
82
|
+
maxProgress: 100,
|
|
83
|
+
condition: (stats) => stats.totalSearches >= 100
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: 'search_ninja',
|
|
87
|
+
name: 'Search Ninja',
|
|
88
|
+
description: 'Achieve 90% search accuracy',
|
|
89
|
+
icon: '🥷',
|
|
90
|
+
points: 100,
|
|
91
|
+
category: 'special',
|
|
92
|
+
unlocked: false,
|
|
93
|
+
condition: (stats) => stats.searchAccuracy >= 90
|
|
94
|
+
},
|
|
95
|
+
// Streak achievements
|
|
96
|
+
{
|
|
97
|
+
id: 'week_streak',
|
|
98
|
+
name: 'Consistent',
|
|
99
|
+
description: 'Maintain a 7-day streak',
|
|
100
|
+
icon: '🔥',
|
|
101
|
+
points: 25,
|
|
102
|
+
category: 'special',
|
|
103
|
+
unlocked: false,
|
|
104
|
+
progress: 0,
|
|
105
|
+
maxProgress: 7,
|
|
106
|
+
condition: (stats) => stats.currentStreak >= 7
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'month_streak',
|
|
110
|
+
name: 'Dedicated',
|
|
111
|
+
description: 'Maintain a 30-day streak',
|
|
112
|
+
icon: '💎',
|
|
113
|
+
points: 100,
|
|
114
|
+
category: 'special',
|
|
115
|
+
unlocked: false,
|
|
116
|
+
progress: 0,
|
|
117
|
+
maxProgress: 30,
|
|
118
|
+
condition: (stats) => stats.currentStreak >= 30
|
|
119
|
+
},
|
|
120
|
+
// API achievements
|
|
121
|
+
{
|
|
122
|
+
id: 'api_integrated',
|
|
123
|
+
name: 'Connected',
|
|
124
|
+
description: 'Successfully integrate API',
|
|
125
|
+
icon: '🔌',
|
|
126
|
+
points: 20,
|
|
127
|
+
category: 'usage',
|
|
128
|
+
unlocked: false,
|
|
129
|
+
condition: (stats) => stats.totalApiCalls >= 1
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: 'api_power_user',
|
|
133
|
+
name: 'API Power User',
|
|
134
|
+
description: 'Make 1000 API calls',
|
|
135
|
+
icon: '⚡',
|
|
136
|
+
points: 75,
|
|
137
|
+
category: 'milestone',
|
|
138
|
+
unlocked: false,
|
|
139
|
+
progress: 0,
|
|
140
|
+
maxProgress: 1000,
|
|
141
|
+
condition: (stats) => stats.totalApiCalls >= 1000
|
|
142
|
+
},
|
|
143
|
+
// Special achievements
|
|
144
|
+
{
|
|
145
|
+
id: 'night_owl',
|
|
146
|
+
name: 'Night Owl',
|
|
147
|
+
description: 'Create memories after midnight',
|
|
148
|
+
icon: '🦉',
|
|
149
|
+
points: 15,
|
|
150
|
+
category: 'special',
|
|
151
|
+
unlocked: false,
|
|
152
|
+
condition: () => new Date().getHours() >= 0 && new Date().getHours() < 5
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: 'early_bird',
|
|
156
|
+
name: 'Early Bird',
|
|
157
|
+
description: 'Create memories before 6 AM',
|
|
158
|
+
icon: '🐦',
|
|
159
|
+
points: 15,
|
|
160
|
+
category: 'special',
|
|
161
|
+
unlocked: false,
|
|
162
|
+
condition: () => new Date().getHours() >= 5 && new Date().getHours() < 6
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
id: 'power_mode_pro',
|
|
166
|
+
name: 'Power Mode Professional',
|
|
167
|
+
description: 'Use power mode 50 times',
|
|
168
|
+
icon: '⚡',
|
|
169
|
+
points: 60,
|
|
170
|
+
category: 'special',
|
|
171
|
+
unlocked: false,
|
|
172
|
+
progress: 0,
|
|
173
|
+
maxProgress: 50,
|
|
174
|
+
condition: (stats) => stats.powerModeUsage >= 50
|
|
175
|
+
},
|
|
176
|
+
// Hidden achievements
|
|
177
|
+
{
|
|
178
|
+
id: 'secret_finder',
|
|
179
|
+
name: '???',
|
|
180
|
+
description: 'Discover a hidden feature',
|
|
181
|
+
icon: '🤫',
|
|
182
|
+
points: 50,
|
|
183
|
+
category: 'hidden',
|
|
184
|
+
unlocked: false,
|
|
185
|
+
condition: () => false // Triggered by specific action
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: 'bug_reporter',
|
|
189
|
+
name: 'Bug Hunter',
|
|
190
|
+
description: 'Report a bug that gets fixed',
|
|
191
|
+
icon: '🐛',
|
|
192
|
+
points: 100,
|
|
193
|
+
category: 'hidden',
|
|
194
|
+
unlocked: false,
|
|
195
|
+
condition: () => false
|
|
196
|
+
}
|
|
197
|
+
];
|
|
198
|
+
achievementList.forEach(achievement => {
|
|
199
|
+
this.achievements.set(achievement.id, achievement);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Check for new achievements
|
|
204
|
+
*/
|
|
205
|
+
checkAchievements() {
|
|
206
|
+
const newlyUnlocked = [];
|
|
207
|
+
this.achievements.forEach((achievement, id) => {
|
|
208
|
+
if (!achievement.unlocked && !this.unlockedAchievements.has(id)) {
|
|
209
|
+
// Update progress if applicable
|
|
210
|
+
if (achievement.maxProgress) {
|
|
211
|
+
this.updateProgress(achievement);
|
|
212
|
+
}
|
|
213
|
+
// Check if condition is met
|
|
214
|
+
if (achievement.condition(this.userStats)) {
|
|
215
|
+
this.unlockAchievement(achievement);
|
|
216
|
+
newlyUnlocked.push(achievement);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
return newlyUnlocked;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Update achievement progress
|
|
224
|
+
*/
|
|
225
|
+
updateProgress(achievement) {
|
|
226
|
+
switch (achievement.id) {
|
|
227
|
+
case 'memory_collector':
|
|
228
|
+
achievement.progress = Math.min(this.userStats.totalMemories, achievement.maxProgress || 0);
|
|
229
|
+
break;
|
|
230
|
+
case 'memory_master':
|
|
231
|
+
achievement.progress = Math.min(this.userStats.totalMemories, achievement.maxProgress || 0);
|
|
232
|
+
break;
|
|
233
|
+
case 'search_pro':
|
|
234
|
+
achievement.progress = Math.min(this.userStats.totalSearches, achievement.maxProgress || 0);
|
|
235
|
+
break;
|
|
236
|
+
case 'week_streak':
|
|
237
|
+
achievement.progress = Math.min(this.userStats.currentStreak, achievement.maxProgress || 0);
|
|
238
|
+
break;
|
|
239
|
+
case 'month_streak':
|
|
240
|
+
achievement.progress = Math.min(this.userStats.currentStreak, achievement.maxProgress || 0);
|
|
241
|
+
break;
|
|
242
|
+
case 'api_power_user':
|
|
243
|
+
achievement.progress = Math.min(this.userStats.totalApiCalls, achievement.maxProgress || 0);
|
|
244
|
+
break;
|
|
245
|
+
case 'power_mode_pro':
|
|
246
|
+
achievement.progress = Math.min(this.userStats.powerModeUsage, achievement.maxProgress || 0);
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Unlock an achievement
|
|
252
|
+
*/
|
|
253
|
+
unlockAchievement(achievement) {
|
|
254
|
+
achievement.unlocked = true;
|
|
255
|
+
achievement.unlockedAt = new Date();
|
|
256
|
+
this.unlockedAchievements.add(achievement.id);
|
|
257
|
+
// Emit event
|
|
258
|
+
this.emit('achievement:unlocked', achievement);
|
|
259
|
+
// Save to storage
|
|
260
|
+
this.saveUnlockedAchievements();
|
|
261
|
+
// Show celebration
|
|
262
|
+
this.celebrate(achievement);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Show achievement celebration
|
|
266
|
+
*/
|
|
267
|
+
celebrate(achievement) {
|
|
268
|
+
const celebration = boxen(`${achievement.icon} ${chalk.bold.yellow('Achievement Unlocked!')}\n\n` +
|
|
269
|
+
`${chalk.bold(achievement.name)}\n` +
|
|
270
|
+
`${chalk.gray(achievement.description)}\n\n` +
|
|
271
|
+
`${chalk.green(`+${achievement.points} points`)}`, {
|
|
272
|
+
padding: 1,
|
|
273
|
+
borderStyle: 'double',
|
|
274
|
+
borderColor: 'yellow',
|
|
275
|
+
align: 'center'
|
|
276
|
+
});
|
|
277
|
+
console.log('\n' + celebration + '\n');
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Show all achievements
|
|
281
|
+
*/
|
|
282
|
+
showAchievements() {
|
|
283
|
+
console.clear();
|
|
284
|
+
console.log(chalk.bold.yellow('🏆 Achievements\n'));
|
|
285
|
+
const categories = ['usage', 'milestone', 'special', 'hidden'];
|
|
286
|
+
const totalPoints = this.getTotalPoints();
|
|
287
|
+
const unlockedPoints = this.getUnlockedPoints();
|
|
288
|
+
// Summary
|
|
289
|
+
console.log(boxen(`Points: ${chalk.bold.green(unlockedPoints)} / ${totalPoints}\n` +
|
|
290
|
+
`Unlocked: ${chalk.bold(this.unlockedAchievements.size)} / ${this.achievements.size}\n` +
|
|
291
|
+
`Completion: ${chalk.bold(Math.round((this.unlockedAchievements.size / this.achievements.size) * 100) + '%')}`, {
|
|
292
|
+
padding: 1,
|
|
293
|
+
borderStyle: 'single',
|
|
294
|
+
borderColor: 'cyan'
|
|
295
|
+
}));
|
|
296
|
+
// Achievements by category
|
|
297
|
+
categories.forEach(category => {
|
|
298
|
+
const categoryAchievements = Array.from(this.achievements.values())
|
|
299
|
+
.filter(a => a.category === category);
|
|
300
|
+
if (categoryAchievements.length === 0)
|
|
301
|
+
return;
|
|
302
|
+
console.log(`\n${chalk.bold(this.getCategoryTitle(category))}\n`);
|
|
303
|
+
categoryAchievements.forEach(achievement => {
|
|
304
|
+
this.displayAchievement(achievement);
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Display single achievement
|
|
310
|
+
*/
|
|
311
|
+
displayAchievement(achievement) {
|
|
312
|
+
const unlocked = achievement.unlocked || this.unlockedAchievements.has(achievement.id);
|
|
313
|
+
const icon = unlocked ? achievement.icon : '🔒';
|
|
314
|
+
const name = unlocked ? chalk.bold(achievement.name) : chalk.dim(achievement.name);
|
|
315
|
+
const description = unlocked ? achievement.description : chalk.dim(achievement.description);
|
|
316
|
+
const points = chalk.green(`${achievement.points}pts`);
|
|
317
|
+
let progressBar = '';
|
|
318
|
+
if (achievement.maxProgress && !unlocked) {
|
|
319
|
+
const progress = achievement.progress || 0;
|
|
320
|
+
const percentage = Math.round((progress / achievement.maxProgress) * 100);
|
|
321
|
+
const barLength = 20;
|
|
322
|
+
const filled = Math.round((progress / achievement.maxProgress) * barLength);
|
|
323
|
+
const bar = '█'.repeat(filled) + '░'.repeat(barLength - filled);
|
|
324
|
+
progressBar = `\n ${chalk.cyan(bar)} ${percentage}% (${progress}/${achievement.maxProgress})`;
|
|
325
|
+
}
|
|
326
|
+
console.log(` ${icon} ${name} ${points}`);
|
|
327
|
+
console.log(` ${description}${progressBar}`);
|
|
328
|
+
if (unlocked && achievement.unlockedAt) {
|
|
329
|
+
console.log(chalk.dim(` Unlocked: ${achievement.unlockedAt.toLocaleDateString()}`));
|
|
330
|
+
}
|
|
331
|
+
console.log();
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Get category title
|
|
335
|
+
*/
|
|
336
|
+
getCategoryTitle(category) {
|
|
337
|
+
const titles = {
|
|
338
|
+
usage: '📊 Usage',
|
|
339
|
+
milestone: '🎯 Milestones',
|
|
340
|
+
special: '⭐ Special',
|
|
341
|
+
hidden: '🔮 Hidden'
|
|
342
|
+
};
|
|
343
|
+
return titles[category] || category;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Get total possible points
|
|
347
|
+
*/
|
|
348
|
+
getTotalPoints() {
|
|
349
|
+
return Array.from(this.achievements.values())
|
|
350
|
+
.reduce((sum, a) => sum + a.points, 0);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Get unlocked points
|
|
354
|
+
*/
|
|
355
|
+
getUnlockedPoints() {
|
|
356
|
+
return Array.from(this.achievements.values())
|
|
357
|
+
.filter(a => a.unlocked || this.unlockedAchievements.has(a.id))
|
|
358
|
+
.reduce((sum, a) => sum + a.points, 0);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Update user stats
|
|
362
|
+
*/
|
|
363
|
+
updateStats(updates) {
|
|
364
|
+
this.userStats = { ...this.userStats, ...updates };
|
|
365
|
+
this.saveUserStats();
|
|
366
|
+
// Check for new achievements
|
|
367
|
+
const newAchievements = this.checkAchievements();
|
|
368
|
+
// Show subtle notification for new achievements
|
|
369
|
+
if (newAchievements.length > 0 && !this.stateManager.getPreferences().expertMode) {
|
|
370
|
+
newAchievements.forEach(achievement => {
|
|
371
|
+
console.log(chalk.yellow(`\n🎉 Achievement unlocked: ${achievement.name}!`));
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Get leaderboard position
|
|
377
|
+
*/
|
|
378
|
+
getLeaderboardPosition() {
|
|
379
|
+
// Simulated leaderboard position
|
|
380
|
+
const points = this.getUnlockedPoints();
|
|
381
|
+
if (points > 1000)
|
|
382
|
+
return 1;
|
|
383
|
+
if (points > 500)
|
|
384
|
+
return Math.floor(Math.random() * 10) + 2;
|
|
385
|
+
if (points > 100)
|
|
386
|
+
return Math.floor(Math.random() * 50) + 11;
|
|
387
|
+
return Math.floor(Math.random() * 900) + 101;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Load user stats from storage
|
|
391
|
+
*/
|
|
392
|
+
loadUserStats() {
|
|
393
|
+
// Would load from storage
|
|
394
|
+
return {
|
|
395
|
+
totalMemories: 0,
|
|
396
|
+
totalSearches: 0,
|
|
397
|
+
totalTopics: 0,
|
|
398
|
+
totalApiCalls: 0,
|
|
399
|
+
daysActive: 0,
|
|
400
|
+
longestStreak: 0,
|
|
401
|
+
currentStreak: 0,
|
|
402
|
+
powerModeUsage: 0,
|
|
403
|
+
memoriesCreatedToday: 0,
|
|
404
|
+
searchAccuracy: 0
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Save user stats to storage
|
|
409
|
+
*/
|
|
410
|
+
saveUserStats() {
|
|
411
|
+
// Would save to storage
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Load unlocked achievements from storage
|
|
415
|
+
*/
|
|
416
|
+
loadUnlockedAchievements() {
|
|
417
|
+
// Would load from storage
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Save unlocked achievements to storage
|
|
421
|
+
*/
|
|
422
|
+
saveUnlockedAchievements() {
|
|
423
|
+
// Would save to storage
|
|
424
|
+
}
|
|
425
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Architecture for Enhanced CLI Experience
|
|
3
|
+
* Implements the layered architecture for state management, interaction, and presentation
|
|
4
|
+
*/
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
export interface NavigationState {
|
|
7
|
+
name: string;
|
|
8
|
+
path: string;
|
|
9
|
+
context: Record<string, any>;
|
|
10
|
+
timestamp: Date;
|
|
11
|
+
}
|
|
12
|
+
export interface UserContext {
|
|
13
|
+
userId?: string;
|
|
14
|
+
email?: string;
|
|
15
|
+
organization?: string;
|
|
16
|
+
preferences: UserPreferences;
|
|
17
|
+
sessionStarted: Date;
|
|
18
|
+
lastAction?: string;
|
|
19
|
+
history: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface UserPreferences {
|
|
22
|
+
theme: 'default' | 'dark' | 'light' | 'auto';
|
|
23
|
+
outputFormat: 'table' | 'json' | 'yaml' | 'minimal';
|
|
24
|
+
verbosity: 'quiet' | 'normal' | 'verbose';
|
|
25
|
+
expertMode: boolean;
|
|
26
|
+
shortcuts: boolean;
|
|
27
|
+
animations: boolean;
|
|
28
|
+
autoComplete: boolean;
|
|
29
|
+
confirmDestructive: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface SessionMemory {
|
|
32
|
+
recentCommands: string[];
|
|
33
|
+
recentMemories: string[];
|
|
34
|
+
searchHistory: string[];
|
|
35
|
+
clipboardHistory: string[];
|
|
36
|
+
undoStack: any[];
|
|
37
|
+
}
|
|
38
|
+
export interface CLIExperienceArchitecture {
|
|
39
|
+
stateManager: StateManager;
|
|
40
|
+
interactionEngine: InteractionEngine;
|
|
41
|
+
presentationLayer: PresentationLayer;
|
|
42
|
+
}
|
|
43
|
+
export declare class StateManager extends EventEmitter {
|
|
44
|
+
private navigationStack;
|
|
45
|
+
private userContext;
|
|
46
|
+
private sessionMemory;
|
|
47
|
+
private preferences;
|
|
48
|
+
constructor();
|
|
49
|
+
private initializeUserContext;
|
|
50
|
+
private initializeSessionMemory;
|
|
51
|
+
private loadPreferences;
|
|
52
|
+
pushNavigation(state: NavigationState): void;
|
|
53
|
+
popNavigation(): NavigationState | undefined;
|
|
54
|
+
getCurrentNavigation(): NavigationState | undefined;
|
|
55
|
+
private renderBreadcrumb;
|
|
56
|
+
updateUserContext(updates: Partial<UserContext>): void;
|
|
57
|
+
getUserContext(): UserContext;
|
|
58
|
+
addToHistory(command: string): void;
|
|
59
|
+
getRecentCommands(limit?: number): string[];
|
|
60
|
+
updatePreference<K extends keyof UserPreferences>(key: K, value: UserPreferences[K]): void;
|
|
61
|
+
getPreferences(): UserPreferences;
|
|
62
|
+
private savePreferences;
|
|
63
|
+
pushToUndoStack(action: any): void;
|
|
64
|
+
popFromUndoStack(): any;
|
|
65
|
+
}
|
|
66
|
+
export declare class InteractionEngine {
|
|
67
|
+
private stateManager;
|
|
68
|
+
private promptSystem;
|
|
69
|
+
private validationEngine;
|
|
70
|
+
private feedbackLoop;
|
|
71
|
+
private helpSystem;
|
|
72
|
+
constructor(stateManager: StateManager);
|
|
73
|
+
prompt(config: PromptConfig): Promise<any>;
|
|
74
|
+
validate(value: any, rules: ValidationRule[]): ValidationResult;
|
|
75
|
+
showFeedback(message: string, type: 'success' | 'error' | 'warning' | 'info'): void;
|
|
76
|
+
getContextualHelp(): string;
|
|
77
|
+
}
|
|
78
|
+
export declare class AdaptivePromptSystem {
|
|
79
|
+
private stateManager;
|
|
80
|
+
constructor(stateManager: StateManager);
|
|
81
|
+
prompt(config: PromptConfig): Promise<any>;
|
|
82
|
+
private expertPrompt;
|
|
83
|
+
private guidedPrompt;
|
|
84
|
+
}
|
|
85
|
+
export declare class ContextualValidator {
|
|
86
|
+
validate(value: any, rules: ValidationRule[]): ValidationResult;
|
|
87
|
+
}
|
|
88
|
+
export declare class RealTimeFeedback {
|
|
89
|
+
private readonly icons;
|
|
90
|
+
show(message: string, type: 'success' | 'error' | 'warning' | 'info'): void;
|
|
91
|
+
private getColorFunction;
|
|
92
|
+
}
|
|
93
|
+
export declare class InlineHelpProvider {
|
|
94
|
+
private stateManager;
|
|
95
|
+
constructor(stateManager: StateManager);
|
|
96
|
+
getHelp(): string;
|
|
97
|
+
private generateHelpText;
|
|
98
|
+
}
|
|
99
|
+
export declare class PresentationLayer {
|
|
100
|
+
private themeEngine;
|
|
101
|
+
private layoutManager;
|
|
102
|
+
private animationController;
|
|
103
|
+
constructor();
|
|
104
|
+
applyTheme(theme: string): void;
|
|
105
|
+
renderLayout(content: any, layout: string): void;
|
|
106
|
+
animate(element: any, animation: string): void;
|
|
107
|
+
}
|
|
108
|
+
export declare class AdaptiveThemeEngine {
|
|
109
|
+
private currentTheme;
|
|
110
|
+
private themes;
|
|
111
|
+
setTheme(theme: string): void;
|
|
112
|
+
getColors(): any;
|
|
113
|
+
}
|
|
114
|
+
export declare class ResponsiveLayoutManager {
|
|
115
|
+
render(content: any, layout: string): void;
|
|
116
|
+
private renderCard;
|
|
117
|
+
private renderTable;
|
|
118
|
+
private renderDashboard;
|
|
119
|
+
}
|
|
120
|
+
export declare class SubtleAnimationController {
|
|
121
|
+
animate(element: any, animation: string): void;
|
|
122
|
+
}
|
|
123
|
+
export interface ValidationRule {
|
|
124
|
+
validate(value: any): {
|
|
125
|
+
valid: boolean;
|
|
126
|
+
message: string;
|
|
127
|
+
severity: 'error' | 'warning';
|
|
128
|
+
suggestion?: string;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export interface ValidationResult {
|
|
132
|
+
valid: boolean;
|
|
133
|
+
errors: string[];
|
|
134
|
+
warnings: string[];
|
|
135
|
+
suggestions: string[];
|
|
136
|
+
}
|
|
137
|
+
export interface PromptConfig {
|
|
138
|
+
type: 'text' | 'select' | 'multiselect' | 'confirm' | 'password';
|
|
139
|
+
message: string;
|
|
140
|
+
choices?: any[];
|
|
141
|
+
default?: any;
|
|
142
|
+
validate?: (value: any) => boolean | string;
|
|
143
|
+
hint?: string;
|
|
144
|
+
}
|
|
145
|
+
export declare function createCLIArchitecture(): CLIExperienceArchitecture;
|