myshell-tools 1.0.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/LICENSE +21 -0
  3. package/README.md +318 -0
  4. package/data/orchestrator.json +113 -0
  5. package/package.json +49 -0
  6. package/src/auth/recovery.mjs +328 -0
  7. package/src/auth/refresh.mjs +373 -0
  8. package/src/chef.mjs +348 -0
  9. package/src/cli/doctor.mjs +568 -0
  10. package/src/cli/reset.mjs +447 -0
  11. package/src/cli/status.mjs +379 -0
  12. package/src/cli.mjs +429 -0
  13. package/src/commands/doctor.mjs +375 -0
  14. package/src/commands/help.mjs +324 -0
  15. package/src/commands/status.mjs +331 -0
  16. package/src/monitor/health.mjs +486 -0
  17. package/src/monitor/performance.mjs +442 -0
  18. package/src/monitor/report.mjs +535 -0
  19. package/src/orchestrator/classify.mjs +391 -0
  20. package/src/orchestrator/confidence.mjs +151 -0
  21. package/src/orchestrator/handoffs.mjs +231 -0
  22. package/src/orchestrator/review.mjs +222 -0
  23. package/src/providers/balance.mjs +201 -0
  24. package/src/providers/claude.mjs +236 -0
  25. package/src/providers/codex.mjs +255 -0
  26. package/src/providers/detect.mjs +185 -0
  27. package/src/providers/errors.mjs +373 -0
  28. package/src/providers/select.mjs +162 -0
  29. package/src/repl-enhanced.mjs +417 -0
  30. package/src/repl.mjs +321 -0
  31. package/src/state/archive.mjs +366 -0
  32. package/src/state/atomic.mjs +116 -0
  33. package/src/state/cleanup.mjs +440 -0
  34. package/src/state/recovery.mjs +461 -0
  35. package/src/state/session.mjs +147 -0
  36. package/src/ui/errors.mjs +456 -0
  37. package/src/ui/formatter.mjs +327 -0
  38. package/src/ui/icons.mjs +318 -0
  39. package/src/ui/progress.mjs +468 -0
  40. package/templates/prompts/confidence-format.txt +14 -0
  41. package/templates/prompts/ic-with-feedback.txt +41 -0
  42. package/templates/prompts/ic.txt +13 -0
  43. package/templates/prompts/manager-review.txt +40 -0
  44. package/templates/prompts/manager.txt +14 -0
  45. package/templates/prompts/worker.txt +12 -0
@@ -0,0 +1,379 @@
1
+ /**
2
+ * status.mjs — Current session and system status display
3
+ */
4
+
5
+ import { detectEnvironment, getAvailableModels } from '../providers/detect.mjs';
6
+ import { getSessionSummary, loadSession } from '../state/session.mjs';
7
+ import { getRecoveryStatus, getPlans } from '../state/recovery.mjs';
8
+ import { getStorageStats } from '../state/cleanup.mjs';
9
+ import { listArchives } from '../state/archive.mjs';
10
+ import { loadRefreshState } from '../auth/refresh.mjs';
11
+
12
+ /**
13
+ * Colors for terminal output
14
+ */
15
+ const colors = {
16
+ red: '\x1b[31m',
17
+ green: '\x1b[32m',
18
+ yellow: '\x1b[33m',
19
+ blue: '\x1b[34m',
20
+ magenta: '\x1b[35m',
21
+ cyan: '\x1b[36m',
22
+ white: '\x1b[37m',
23
+ reset: '\x1b[0m',
24
+ bold: '\x1b[1m',
25
+ dim: '\x1b[2m'
26
+ };
27
+
28
+ /**
29
+ * Status icons
30
+ */
31
+ const icons = {
32
+ healthy: '✅',
33
+ warning: '⚠️ ',
34
+ error: '❌',
35
+ info: 'ℹ️ ',
36
+ active: '🟢',
37
+ inactive: '⚪',
38
+ working: '🔄',
39
+ archive: '📦'
40
+ };
41
+
42
+ /**
43
+ * Display comprehensive status information
44
+ */
45
+ export function displayStatus(workspace = process.cwd(), options = {}) {
46
+ const { verbose = false, format = 'table' } = options;
47
+
48
+ console.log(`${colors.bold}${colors.blue}📊 Cortex Status Report${colors.reset}\n`);
49
+
50
+ const statusData = gatherStatusData(workspace);
51
+
52
+ if (format === 'json') {
53
+ console.log(JSON.stringify(statusData, null, 2));
54
+ return statusData;
55
+ }
56
+
57
+ // Display in human-readable format
58
+ displaySystemStatus(statusData.system);
59
+ displaySessionStatus(statusData.session);
60
+ displayProviderStatus(statusData.providers);
61
+ displayWorkStatus(statusData.work);
62
+ displayStorageStatus(statusData.storage);
63
+
64
+ if (verbose) {
65
+ displayDetailedStatus(statusData);
66
+ }
67
+
68
+ return statusData;
69
+ }
70
+
71
+ /**
72
+ * Gather all status information
73
+ */
74
+ function gatherStatusData(workspace) {
75
+ const env = detectEnvironment();
76
+ const models = getAvailableModels(env);
77
+ const sessionSummary = getSessionSummary(workspace);
78
+ const recoveryStatus = getRecoveryStatus(workspace);
79
+ const storageStats = getStorageStats(workspace);
80
+ const refreshState = loadRefreshState();
81
+ const archives = listArchives(workspace);
82
+ const plans = getPlans(null, workspace);
83
+
84
+ return {
85
+ timestamp: new Date().toISOString(),
86
+ workspace,
87
+ system: {
88
+ environment: env,
89
+ models,
90
+ healthy: env.hasProviders && models.manager.length > 0
91
+ },
92
+ session: {
93
+ summary: sessionSummary,
94
+ active: sessionSummary.messageCount > 0,
95
+ lastActivity: sessionSummary.lastMessage?.timestamp || null
96
+ },
97
+ providers: {
98
+ claude: {
99
+ installed: env.claude.installed,
100
+ authenticated: env.claude.authed,
101
+ version: env.claude.version,
102
+ models: env.claude.models
103
+ },
104
+ codex: {
105
+ installed: env.codex.installed,
106
+ authenticated: env.codex.authed,
107
+ path: env.codex.path,
108
+ models: env.codex.models
109
+ }
110
+ },
111
+ auth: {
112
+ refreshState,
113
+ lastRefresh: refreshState?.lastRefresh || null,
114
+ nextRefreshDue: refreshState?.nextRefreshDue || null
115
+ },
116
+ work: {
117
+ plans: plans.length,
118
+ interrupted: recoveryStatus.hasInterruptedWork,
119
+ interruptedCount: recoveryStatus.interruptedCount,
120
+ canRecover: recoveryStatus.canAutoRecover
121
+ },
122
+ storage: {
123
+ stats: storageStats,
124
+ archives: archives.length,
125
+ totalSize: storageStats.totalSize,
126
+ breakdown: storageStats.breakdown
127
+ }
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Display system status
133
+ */
134
+ function displaySystemStatus(system) {
135
+ console.log(`${colors.bold}System${colors.reset}`);
136
+
137
+ // Overall health
138
+ const healthIcon = system.healthy ? icons.healthy : icons.error;
139
+ const healthStatus = system.healthy ? `${colors.green}Healthy${colors.reset}` : `${colors.red}Needs Attention${colors.reset}`;
140
+ console.log(` ${healthIcon} Status: ${healthStatus}`);
141
+
142
+ // Model tiers
143
+ const tierCounts = {
144
+ manager: system.models.manager.length,
145
+ ic: system.models.ic.length,
146
+ worker: system.models.worker.length
147
+ };
148
+
149
+ console.log(` 🏗️ Model Tiers: M:${tierCounts.manager} IC:${tierCounts.ic} W:${tierCounts.worker}`);
150
+
151
+ // Platform info
152
+ console.log(` 💻 Platform: ${process.platform}/${process.arch}, Node ${process.version}`);
153
+ console.log();
154
+ }
155
+
156
+ /**
157
+ * Display session status
158
+ */
159
+ function displaySessionStatus(session) {
160
+ console.log(`${colors.bold}Current Session${colors.reset}`);
161
+
162
+ if (session.active) {
163
+ const duration = session.summary.duration ?
164
+ formatDuration(session.summary.duration) : 'unknown';
165
+
166
+ console.log(` ${icons.active} Active session with ${session.summary.messageCount} messages`);
167
+ console.log(` 💬 Messages: ${session.summary.userMessageCount} user, ${session.summary.assistantMessageCount} assistant`);
168
+ console.log(` ⏱️ Duration: ${duration}`);
169
+
170
+ if (session.lastActivity) {
171
+ const lastTime = new Date(session.lastActivity).toLocaleTimeString();
172
+ console.log(` 🕐 Last activity: ${lastTime}`);
173
+ }
174
+ } else {
175
+ console.log(` ${icons.inactive} No active session`);
176
+ }
177
+
178
+ console.log();
179
+ }
180
+
181
+ /**
182
+ * Display provider status
183
+ */
184
+ function displayProviderStatus(providers) {
185
+ console.log(`${colors.bold}Providers${colors.reset}`);
186
+
187
+ // Claude status
188
+ const claudeIcon = providers.claude.authenticated ? icons.healthy :
189
+ providers.claude.installed ? icons.warning : icons.error;
190
+ const claudeStatus = providers.claude.authenticated ? 'Authenticated' :
191
+ providers.claude.installed ? 'Not authenticated' : 'Not installed';
192
+ const claudeColor = providers.claude.authenticated ? colors.green :
193
+ providers.claude.installed ? colors.yellow : colors.red;
194
+
195
+ console.log(` ${claudeIcon} Claude: ${claudeColor}${claudeStatus}${colors.reset}`);
196
+ if (providers.claude.version) {
197
+ console.log(` ${colors.dim}Version: ${providers.claude.version}${colors.reset}`);
198
+ }
199
+
200
+ // Codex status
201
+ const codexIcon = providers.codex.authenticated ? icons.healthy :
202
+ providers.codex.installed ? icons.warning : icons.error;
203
+ const codexStatus = providers.codex.authenticated ? 'Authenticated' :
204
+ providers.codex.installed ? 'Not authenticated' : 'Not installed';
205
+ const codexColor = providers.codex.authenticated ? colors.green :
206
+ providers.codex.installed ? colors.yellow : colors.red;
207
+
208
+ console.log(` ${codexIcon} Codex: ${codexColor}${codexStatus}${colors.reset}`);
209
+ if (providers.codex.path) {
210
+ console.log(` ${colors.dim}Path: ${providers.codex.path}${colors.reset}`);
211
+ }
212
+
213
+ console.log();
214
+ }
215
+
216
+ /**
217
+ * Display work status
218
+ */
219
+ function displayWorkStatus(work) {
220
+ console.log(`${colors.bold}Work State${colors.reset}`);
221
+
222
+ if (work.interrupted) {
223
+ console.log(` ${icons.warning} ${work.interruptedCount} interrupted session(s)`);
224
+ const recoverStatus = work.canRecover ? 'automatic' : 'manual intervention needed';
225
+ console.log(` 🔄 Recovery: ${recoverStatus}`);
226
+ } else {
227
+ console.log(` ${icons.healthy} No interrupted work`);
228
+ }
229
+
230
+ if (work.plans > 0) {
231
+ console.log(` 📋 Plans: ${work.plans} total`);
232
+ }
233
+
234
+ console.log();
235
+ }
236
+
237
+ /**
238
+ * Display storage status
239
+ */
240
+ function displayStorageStatus(storage) {
241
+ console.log(`${colors.bold}Storage${colors.reset}`);
242
+
243
+ const totalMB = Math.round(storage.totalSize / 1024 / 1024);
244
+ const storageColor = totalMB < 50 ? colors.green :
245
+ totalMB < 200 ? colors.yellow : colors.red;
246
+
247
+ console.log(` 💾 Total: ${storageColor}${totalMB}MB${colors.reset}`);
248
+
249
+ // Breakdown
250
+ if (storage.breakdown.sessions > 0) {
251
+ const sessionsMB = Math.round(storage.breakdown.sessions / 1024 / 1024);
252
+ console.log(` Sessions: ${sessionsMB}MB`);
253
+ }
254
+
255
+ if (storage.breakdown.archives > 0) {
256
+ const archivesMB = Math.round(storage.breakdown.archives / 1024 / 1024);
257
+ console.log(` ${icons.archive} Archives: ${archivesMB}MB (${storage.archives} files)`);
258
+ }
259
+
260
+ console.log();
261
+ }
262
+
263
+ /**
264
+ * Display detailed status (verbose mode)
265
+ */
266
+ function displayDetailedStatus(statusData) {
267
+ console.log(`${colors.bold}${colors.cyan}Detailed Information${colors.reset}\n`);
268
+
269
+ // Authentication details
270
+ if (statusData.auth.refreshState) {
271
+ console.log(`${colors.bold}Authentication${colors.reset}`);
272
+ const lastRefresh = statusData.auth.lastRefresh ?
273
+ new Date(statusData.auth.lastRefresh).toLocaleString() : 'Never';
274
+ console.log(` Last token refresh: ${lastRefresh}`);
275
+
276
+ if (statusData.auth.nextRefreshDue) {
277
+ const nextRefresh = new Date(statusData.auth.nextRefreshDue).toLocaleString();
278
+ console.log(` Next refresh due: ${nextRefresh}`);
279
+ }
280
+ console.log();
281
+ }
282
+
283
+ // Recent session activity
284
+ if (statusData.session.active) {
285
+ console.log(`${colors.bold}Recent Activity${colors.reset}`);
286
+ const recentMessages = loadSession().slice(-5); // Last 5 messages
287
+
288
+ recentMessages.forEach((msg, index) => {
289
+ const time = new Date(msg.timestamp).toLocaleTimeString();
290
+ const role = msg.role === 'user' ? '👤' : msg.role === 'assistant' ? '🤖' : '⚙️ ';
291
+ const preview = msg.content.length > 50 ?
292
+ msg.content.substring(0, 50) + '...' : msg.content;
293
+
294
+ console.log(` ${role} ${colors.dim}${time}${colors.reset} ${preview}`);
295
+ });
296
+ console.log();
297
+ }
298
+
299
+ // Storage breakdown
300
+ console.log(`${colors.bold}Storage Breakdown${colors.reset}`);
301
+ Object.entries(statusData.storage.breakdown).forEach(([category, size]) => {
302
+ if (size > 0) {
303
+ const sizeMB = (size / 1024 / 1024).toFixed(1);
304
+ const percentage = ((size / statusData.storage.totalSize) * 100).toFixed(1);
305
+ console.log(` ${category}: ${sizeMB}MB (${percentage}%)`);
306
+ }
307
+ });
308
+ console.log();
309
+
310
+ // Model availability
311
+ console.log(`${colors.bold}Available Models${colors.reset}`);
312
+ ['manager', 'ic', 'worker'].forEach(tier => {
313
+ const models = statusData.system.models[tier];
314
+ if (models.length > 0) {
315
+ console.log(` ${tier.toUpperCase()}:`);
316
+ models.forEach(model => {
317
+ console.log(` ${model.provider}/${model.model}`);
318
+ });
319
+ } else {
320
+ console.log(` ${tier.toUpperCase()}: ${colors.red}None available${colors.reset}`);
321
+ }
322
+ });
323
+ console.log();
324
+ }
325
+
326
+ /**
327
+ * Get quick status summary for other commands
328
+ */
329
+ export function getQuickStatus(workspace = process.cwd()) {
330
+ const env = detectEnvironment();
331
+ const sessionSummary = getSessionSummary(workspace);
332
+
333
+ return {
334
+ healthy: env.hasProviders,
335
+ activeSession: sessionSummary.messageCount > 0,
336
+ providers: {
337
+ claude: env.claude.authed,
338
+ codex: env.codex.authed
339
+ },
340
+ lastActivity: sessionSummary.lastMessage?.timestamp || null
341
+ };
342
+ }
343
+
344
+ /**
345
+ * Display status bar (compact format)
346
+ */
347
+ export function displayStatusBar(workspace = process.cwd()) {
348
+ const status = getQuickStatus(workspace);
349
+
350
+ const healthIcon = status.healthy ? '🟢' : '🔴';
351
+ const sessionIcon = status.activeSession ? '💬' : '💤';
352
+
353
+ const providerStatus = [];
354
+ if (status.providers.claude) providerStatus.push('C');
355
+ if (status.providers.codex) providerStatus.push('O');
356
+
357
+ const providerStr = providerStatus.length > 0 ?
358
+ providerStatus.join('') : 'None';
359
+
360
+ console.log(`${healthIcon} ${sessionIcon} [${providerStr}]`);
361
+ }
362
+
363
+ /**
364
+ * Format duration in human-readable form
365
+ */
366
+ function formatDuration(ms) {
367
+ const minutes = Math.floor(ms / 60000);
368
+ const seconds = Math.floor((ms % 60000) / 1000);
369
+
370
+ if (minutes > 60) {
371
+ const hours = Math.floor(minutes / 60);
372
+ const remainingMinutes = minutes % 60;
373
+ return `${hours}h ${remainingMinutes}m`;
374
+ } else if (minutes > 0) {
375
+ return `${minutes}m ${seconds}s`;
376
+ } else {
377
+ return `${seconds}s`;
378
+ }
379
+ }