myshell-tools 1.0.0 โ 2.0.0-alpha.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/CHANGELOG.md +44 -69
- package/LICENSE +21 -21
- package/README.md +178 -318
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +106 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/cost.d.ts +36 -0
- package/dist/commands/cost.js +103 -0
- package/dist/commands/cost.js.map +1 -0
- package/dist/commands/doctor.d.ts +36 -0
- package/dist/commands/doctor.js +115 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/core/assess.d.ts +25 -0
- package/dist/core/assess.js +142 -0
- package/dist/core/assess.js.map +1 -0
- package/dist/core/classify.d.ts +19 -0
- package/dist/core/classify.js +80 -0
- package/dist/core/classify.js.map +1 -0
- package/dist/core/escalate.d.ts +32 -0
- package/dist/core/escalate.js +57 -0
- package/dist/core/escalate.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/orchestrate.d.ts +42 -0
- package/dist/core/orchestrate.js +439 -0
- package/dist/core/orchestrate.js.map +1 -0
- package/dist/core/policy.d.ts +9 -0
- package/dist/core/policy.js +27 -0
- package/dist/core/policy.js.map +1 -0
- package/dist/core/prompt.d.ts +26 -0
- package/dist/core/prompt.js +125 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/review.d.ts +46 -0
- package/dist/core/review.js +148 -0
- package/dist/core/review.js.map +1 -0
- package/dist/core/route.d.ts +28 -0
- package/dist/core/route.js +52 -0
- package/dist/core/route.js.map +1 -0
- package/dist/core/types.d.ts +141 -0
- package/dist/core/types.js +14 -0
- package/dist/core/types.js.map +1 -0
- package/dist/infra/atomic.d.ts +53 -0
- package/dist/infra/atomic.js +171 -0
- package/dist/infra/atomic.js.map +1 -0
- package/dist/infra/clock.d.ts +9 -0
- package/dist/infra/clock.js +15 -0
- package/dist/infra/clock.js.map +1 -0
- package/dist/infra/index.d.ts +9 -0
- package/dist/infra/index.js +7 -0
- package/dist/infra/index.js.map +1 -0
- package/dist/infra/ledger.d.ts +49 -0
- package/dist/infra/ledger.js +90 -0
- package/dist/infra/ledger.js.map +1 -0
- package/dist/infra/paths.d.ts +28 -0
- package/dist/infra/paths.js +38 -0
- package/dist/infra/paths.js.map +1 -0
- package/dist/infra/pricing.d.ts +47 -0
- package/dist/infra/pricing.js +151 -0
- package/dist/infra/pricing.js.map +1 -0
- package/dist/infra/session.d.ts +28 -0
- package/dist/infra/session.js +61 -0
- package/dist/infra/session.js.map +1 -0
- package/dist/interface/render.d.ts +27 -0
- package/dist/interface/render.js +134 -0
- package/dist/interface/render.js.map +1 -0
- package/dist/interface/repl.d.ts +23 -0
- package/dist/interface/repl.js +90 -0
- package/dist/interface/repl.js.map +1 -0
- package/dist/interface/run.d.ts +20 -0
- package/dist/interface/run.js +31 -0
- package/dist/interface/run.js.map +1 -0
- package/dist/providers/claude-parse.d.ts +24 -0
- package/dist/providers/claude-parse.js +113 -0
- package/dist/providers/claude-parse.js.map +1 -0
- package/dist/providers/claude.d.ts +45 -0
- package/dist/providers/claude.js +122 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex-parse.d.ts +32 -0
- package/dist/providers/codex-parse.js +145 -0
- package/dist/providers/codex-parse.js.map +1 -0
- package/dist/providers/codex.d.ts +44 -0
- package/dist/providers/codex.js +124 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/detect.d.ts +49 -0
- package/dist/providers/detect.js +125 -0
- package/dist/providers/detect.js.map +1 -0
- package/dist/providers/errors.d.ts +49 -0
- package/dist/providers/errors.js +189 -0
- package/dist/providers/errors.js.map +1 -0
- package/dist/providers/index.d.ts +9 -0
- package/dist/providers/index.js +7 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/port.d.ts +74 -0
- package/dist/providers/port.js +16 -0
- package/dist/providers/port.js.map +1 -0
- package/dist/providers/registry.d.ts +21 -0
- package/dist/providers/registry.js +34 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/ui/banner.d.ts +19 -0
- package/dist/ui/banner.js +32 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/spinner.d.ts +27 -0
- package/dist/ui/spinner.js +67 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/theme.d.ts +32 -0
- package/dist/ui/theme.js +56 -0
- package/dist/ui/theme.js.map +1 -0
- package/package.json +55 -49
- package/data/orchestrator.json +0 -113
- package/src/auth/recovery.mjs +0 -328
- package/src/auth/refresh.mjs +0 -373
- package/src/chef.mjs +0 -348
- package/src/cli/doctor.mjs +0 -568
- package/src/cli/reset.mjs +0 -447
- package/src/cli/status.mjs +0 -379
- package/src/cli.mjs +0 -429
- package/src/commands/doctor.mjs +0 -375
- package/src/commands/help.mjs +0 -324
- package/src/commands/status.mjs +0 -331
- package/src/monitor/health.mjs +0 -486
- package/src/monitor/performance.mjs +0 -442
- package/src/monitor/report.mjs +0 -535
- package/src/orchestrator/classify.mjs +0 -391
- package/src/orchestrator/confidence.mjs +0 -151
- package/src/orchestrator/handoffs.mjs +0 -231
- package/src/orchestrator/review.mjs +0 -222
- package/src/providers/balance.mjs +0 -201
- package/src/providers/claude.mjs +0 -236
- package/src/providers/codex.mjs +0 -255
- package/src/providers/detect.mjs +0 -185
- package/src/providers/errors.mjs +0 -373
- package/src/providers/select.mjs +0 -162
- package/src/repl-enhanced.mjs +0 -417
- package/src/repl.mjs +0 -321
- package/src/state/archive.mjs +0 -366
- package/src/state/atomic.mjs +0 -116
- package/src/state/cleanup.mjs +0 -440
- package/src/state/recovery.mjs +0 -461
- package/src/state/session.mjs +0 -147
- package/src/ui/errors.mjs +0 -456
- package/src/ui/formatter.mjs +0 -327
- package/src/ui/icons.mjs +0 -318
- package/src/ui/progress.mjs +0 -468
- package/templates/prompts/confidence-format.txt +0 -14
- package/templates/prompts/ic-with-feedback.txt +0 -41
- package/templates/prompts/ic.txt +0 -13
- package/templates/prompts/manager-review.txt +0 -40
- package/templates/prompts/manager.txt +0 -14
- package/templates/prompts/worker.txt +0 -12
package/src/cli.mjs
DELETED
|
@@ -1,429 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* cli.mjs โ NPX Cortex main entry point
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { detectEnvironment, getAvailableModels } from './providers/detect.mjs';
|
|
8
|
-
import { startREPL } from './repl.mjs';
|
|
9
|
-
import { startEnhancedREPL } from './repl-enhanced.mjs';
|
|
10
|
-
import { backgroundRefresh, displayRefreshStatus } from './auth/refresh.mjs';
|
|
11
|
-
import { autoRecovery } from './auth/recovery.mjs';
|
|
12
|
-
import { runDoctorCheck } from './commands/doctor.mjs';
|
|
13
|
-
import { displayStatus, getQuickStatus } from './commands/status.mjs';
|
|
14
|
-
import { displayHelp } from './commands/help.mjs';
|
|
15
|
-
import { performReset, previewReset, getResetLevels } from './cli/reset.mjs';
|
|
16
|
-
import { recoverInterruptedWork, resumePlan } from './state/recovery.mjs';
|
|
17
|
-
import { performStateCleanup } from './state/cleanup.mjs';
|
|
18
|
-
import { generateSessionReport, generateTrendsReport, displayQuickSummary } from './monitor/report.mjs';
|
|
19
|
-
import { endPerformanceSession } from './monitor/performance.mjs';
|
|
20
|
-
import { fmt, box, createTree, formatModel } from './ui/formatter.mjs';
|
|
21
|
-
import { status, tier, provider as providerIcons } from './ui/icons.mjs';
|
|
22
|
-
import { displayError, displayWarning, displaySuccess, handleError } from './ui/errors.mjs';
|
|
23
|
-
import { createSpinner, withSpinner } from './ui/progress.mjs';
|
|
24
|
-
|
|
25
|
-
const VERSION = '1.0.0';
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Get provider usage balance for today (mockup for now)
|
|
29
|
-
*/
|
|
30
|
-
export function getProviderBalance() {
|
|
31
|
-
// TODO: Replace with actual usage tracking
|
|
32
|
-
// This would read from usage logs and calculate today's balance
|
|
33
|
-
return {
|
|
34
|
-
claude: 45,
|
|
35
|
-
openai: 55,
|
|
36
|
-
total: 12,
|
|
37
|
-
label: 'Well balanced'
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Display enhanced banner and system status (inspired by dual-brain polish)
|
|
43
|
-
*/
|
|
44
|
-
export function displayBanner(env, models) {
|
|
45
|
-
// Enhanced header with gradient-like effect
|
|
46
|
-
console.log(box(`๐ง Cortex v${VERSION}\nAI Org Chart in Your Shell`, {
|
|
47
|
-
borderColor: fmt.brightBlue(''),
|
|
48
|
-
textColor: fmt.bold(''),
|
|
49
|
-
padding: 1,
|
|
50
|
-
margin: 1
|
|
51
|
-
}));
|
|
52
|
-
|
|
53
|
-
// Provider status line (dual-brain style)
|
|
54
|
-
const claudeStatus = env.claude.authed ? status.success : env.claude.installed ? status.warning : status.error;
|
|
55
|
-
const codexStatus = env.codex.authed ? status.success : env.codex.installed ? status.warning : status.error;
|
|
56
|
-
|
|
57
|
-
console.log(` ${providerIcons.claude} Claude ${claudeStatus} ${providerIcons.codex} Codex ${codexStatus}`);
|
|
58
|
-
|
|
59
|
-
// Status summary line
|
|
60
|
-
if (env.claude.authed && env.codex.authed) {
|
|
61
|
-
console.log(` ${fmt.green('Dual-brain mode active โ full AI orchestration available')}`);
|
|
62
|
-
} else if (env.claude.authed) {
|
|
63
|
-
console.log(` ${fmt.yellow('Claude ready')} ${fmt.dim('ยท Add Codex for dual-brain features')}`);
|
|
64
|
-
} else if (env.codex.authed) {
|
|
65
|
-
console.log(` ${fmt.yellow('Codex ready')} ${fmt.dim('ยท Add Claude for full features')}`);
|
|
66
|
-
} else {
|
|
67
|
-
console.log(` ${fmt.red('No providers authenticated')} ${fmt.dim('ยท Run: cortex --doctor')}`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Provider balance bar (dual-brain inspired)
|
|
71
|
-
const balance = getProviderBalance();
|
|
72
|
-
if (balance.total > 0) {
|
|
73
|
-
console.log(` ${fmt.providerBalanceBar(balance.claude, balance.openai)}`);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
console.log('');
|
|
77
|
-
|
|
78
|
-
// Compact org chart hierarchy (dual-brain style)
|
|
79
|
-
console.log(fmt.bold('Org Chart:'));
|
|
80
|
-
const tiers = [
|
|
81
|
-
{ name: 'MANAGER', key: 'manager', icon: tier.manager, color: fmt.redBold },
|
|
82
|
-
{ name: 'IC', key: 'ic', icon: tier.ic, color: fmt.yellowBold },
|
|
83
|
-
{ name: 'WORKER', key: 'worker', icon: tier.worker, color: fmt.blueBold }
|
|
84
|
-
];
|
|
85
|
-
|
|
86
|
-
for (const tierInfo of tiers) {
|
|
87
|
-
const tierModels = models[tierInfo.key] || [];
|
|
88
|
-
const count = tierModels.length;
|
|
89
|
-
const modelSummary = count > 0
|
|
90
|
-
? fmt.dim(`${count} model${count !== 1 ? 's' : ''}`)
|
|
91
|
-
: fmt.red('none');
|
|
92
|
-
|
|
93
|
-
console.log(` ${tierInfo.icon} ${tierInfo.color(tierInfo.name.padEnd(7))} ${modelSummary}`);
|
|
94
|
-
|
|
95
|
-
if (count > 0 && tierModels.length <= 3) {
|
|
96
|
-
// Show models inline for small lists
|
|
97
|
-
const modelList = tierModels.map(m => `${m.provider}/${m.model}`).join(', ');
|
|
98
|
-
console.log(` ${fmt.dim('โโ ' + modelList)}`);
|
|
99
|
-
} else if (count > 3) {
|
|
100
|
-
// Show summary for large lists
|
|
101
|
-
console.log(` ${fmt.dim(`โโ ${tierModels[0].provider}/${tierModels[0].model} +${count-1} more`)}`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
console.log(`\n${fmt.dim('๐ก Type your request and press Enter โ AI will route automatically')}`);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Display enhanced installation guidance for missing CLIs
|
|
110
|
-
*/
|
|
111
|
-
function displayInstallationHelp(env) {
|
|
112
|
-
console.log('\n' + fmt.bold('๐ Getting Started:'));
|
|
113
|
-
console.log('');
|
|
114
|
-
|
|
115
|
-
const steps = [];
|
|
116
|
-
|
|
117
|
-
if (!env.claude.installed) {
|
|
118
|
-
steps.push({
|
|
119
|
-
text: fmt.orange('Install Claude CLI:'),
|
|
120
|
-
children: [
|
|
121
|
-
{ text: fmt.cyan('pip install anthropic-cli') },
|
|
122
|
-
{ text: fmt.cyan('claude auth login') }
|
|
123
|
-
]
|
|
124
|
-
});
|
|
125
|
-
} else if (!env.claude.authed) {
|
|
126
|
-
steps.push({
|
|
127
|
-
text: fmt.yellow('Authenticate Claude CLI:'),
|
|
128
|
-
children: [
|
|
129
|
-
{ text: fmt.cyan('claude auth login') }
|
|
130
|
-
]
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (!env.codex.installed) {
|
|
135
|
-
steps.push({
|
|
136
|
-
text: fmt.green('Install Codex CLI:'),
|
|
137
|
-
children: [
|
|
138
|
-
{ text: fmt.cyan('npm install -g @openai/codex') },
|
|
139
|
-
{ text: fmt.cyan('codex login') }
|
|
140
|
-
]
|
|
141
|
-
});
|
|
142
|
-
} else if (!env.codex.authed) {
|
|
143
|
-
steps.push({
|
|
144
|
-
text: fmt.yellow('Authenticate Codex CLI:'),
|
|
145
|
-
children: [
|
|
146
|
-
{ text: fmt.cyan('codex login') }
|
|
147
|
-
]
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (steps.length > 0) {
|
|
152
|
-
const helpTree = createTree(steps);
|
|
153
|
-
helpTree.forEach(line => console.log(line));
|
|
154
|
-
console.log('');
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
console.log(fmt.warning('You need at least one authenticated CLI to use Cortex.'));
|
|
158
|
-
console.log(fmt.dim('Both CLIs enable different model tiers and redundancy.'));
|
|
159
|
-
console.log('');
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Handle command line arguments
|
|
164
|
-
*/
|
|
165
|
-
function parseArgs(argv) {
|
|
166
|
-
const args = {
|
|
167
|
-
help: false,
|
|
168
|
-
version: false,
|
|
169
|
-
doctor: false,
|
|
170
|
-
status: false,
|
|
171
|
-
reset: null,
|
|
172
|
-
resetForce: false,
|
|
173
|
-
resetPreview: false,
|
|
174
|
-
cleanup: false,
|
|
175
|
-
resume: null,
|
|
176
|
-
recovery: false,
|
|
177
|
-
verbose: false,
|
|
178
|
-
report: null,
|
|
179
|
-
trends: null
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
for (let i = 0; i < argv.length; i++) {
|
|
183
|
-
const arg = argv[i];
|
|
184
|
-
|
|
185
|
-
switch (arg) {
|
|
186
|
-
case '--help':
|
|
187
|
-
case '-h':
|
|
188
|
-
args.help = true;
|
|
189
|
-
break;
|
|
190
|
-
case '--version':
|
|
191
|
-
case '-v':
|
|
192
|
-
args.version = true;
|
|
193
|
-
break;
|
|
194
|
-
case '--doctor':
|
|
195
|
-
args.doctor = true;
|
|
196
|
-
break;
|
|
197
|
-
case '--status':
|
|
198
|
-
args.status = true;
|
|
199
|
-
break;
|
|
200
|
-
case '--reset':
|
|
201
|
-
args.reset = argv[i + 1] || 'sessions';
|
|
202
|
-
i++; // Skip next arg since it's the reset level
|
|
203
|
-
break;
|
|
204
|
-
case '--force':
|
|
205
|
-
args.resetForce = true;
|
|
206
|
-
break;
|
|
207
|
-
case '--preview':
|
|
208
|
-
args.resetPreview = true;
|
|
209
|
-
break;
|
|
210
|
-
case '--cleanup':
|
|
211
|
-
args.cleanup = true;
|
|
212
|
-
break;
|
|
213
|
-
case '--resume':
|
|
214
|
-
args.resume = argv[i + 1] || true;
|
|
215
|
-
if (argv[i + 1] && !argv[i + 1].startsWith('--')) i++;
|
|
216
|
-
break;
|
|
217
|
-
case '--recovery':
|
|
218
|
-
args.recovery = true;
|
|
219
|
-
break;
|
|
220
|
-
case '--verbose':
|
|
221
|
-
args.verbose = true;
|
|
222
|
-
break;
|
|
223
|
-
case '--report':
|
|
224
|
-
args.report = true;
|
|
225
|
-
break;
|
|
226
|
-
case '--trends':
|
|
227
|
-
args.trends = argv[i + 1] || '7';
|
|
228
|
-
if (argv[i + 1] && !argv[i + 1].startsWith('--')) i++;
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return args;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Help display is now handled by the enhanced help command
|
|
237
|
-
|
|
238
|
-
// Doctor check is now handled by the enhanced doctor command
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Main entry point
|
|
242
|
-
*/
|
|
243
|
-
async function main() {
|
|
244
|
-
const args = parseArgs(process.argv.slice(2));
|
|
245
|
-
|
|
246
|
-
if (args.version) {
|
|
247
|
-
console.log(`Cortex v${VERSION}`);
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
if (args.help) {
|
|
252
|
-
displayHelp();
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Detect environment and available models
|
|
257
|
-
const env = detectEnvironment();
|
|
258
|
-
const models = getAvailableModels(env);
|
|
259
|
-
|
|
260
|
-
if (args.doctor) {
|
|
261
|
-
await runDoctorCheck();
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (args.status) {
|
|
266
|
-
displayStatus(process.cwd(), { verbose: args.verbose });
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (args.reset) {
|
|
271
|
-
if (args.resetPreview) {
|
|
272
|
-
previewReset(args.reset);
|
|
273
|
-
} else {
|
|
274
|
-
await performReset(args.reset, { force: args.resetForce, verbose: args.verbose });
|
|
275
|
-
}
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (args.cleanup) {
|
|
280
|
-
console.log('๐งน Running state cleanup...\n');
|
|
281
|
-
const cleanupResults = performStateCleanup({ verbose: args.verbose });
|
|
282
|
-
console.log(`\nโ
Cleanup completed. Saved ${Math.round(cleanupResults.spaceSaved / 1024)}KB`);
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (args.recovery) {
|
|
287
|
-
const recovery = await recoverInterruptedWork();
|
|
288
|
-
if (!recovery.hasInterrupted) {
|
|
289
|
-
console.log('โ
No interrupted work found');
|
|
290
|
-
}
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (args.resume) {
|
|
295
|
-
if (args.resume === true) {
|
|
296
|
-
// Show available sessions to resume
|
|
297
|
-
const recovery = await recoverInterruptedWork();
|
|
298
|
-
return;
|
|
299
|
-
} else {
|
|
300
|
-
// Resume specific plan
|
|
301
|
-
try {
|
|
302
|
-
const plan = resumePlan(args.resume);
|
|
303
|
-
console.log(`โ
Resumed plan: ${plan.description}`);
|
|
304
|
-
} catch (error) {
|
|
305
|
-
console.log(`โ Failed to resume: ${error.message}`);
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (args.report) {
|
|
312
|
-
await generateSessionReport();
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (args.trends) {
|
|
317
|
-
const days = parseInt(args.trends) || 7;
|
|
318
|
-
await generateTrendsReport(process.cwd(), days);
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Background token refresh (non-blocking) with visual feedback
|
|
323
|
-
if (env.hasProviders) {
|
|
324
|
-
const refreshSpinner = createSpinner('Refreshing credentials...', 'dots');
|
|
325
|
-
refreshSpinner.start();
|
|
326
|
-
|
|
327
|
-
backgroundRefresh()
|
|
328
|
-
.then((result) => {
|
|
329
|
-
refreshSpinner.success('Credentials refreshed');
|
|
330
|
-
displayRefreshStatus(result);
|
|
331
|
-
})
|
|
332
|
-
.catch(() => {
|
|
333
|
-
refreshSpinner.stop(); // Silent failure for background refresh
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Display banner and status
|
|
338
|
-
displayBanner(env, models);
|
|
339
|
-
|
|
340
|
-
// Check if we can run
|
|
341
|
-
if (!env.hasProviders) {
|
|
342
|
-
displayInstallationHelp(env);
|
|
343
|
-
|
|
344
|
-
// Try auto-recovery with enhanced feedback
|
|
345
|
-
console.log('');
|
|
346
|
-
const recoveryResult = await withSpinner(
|
|
347
|
-
autoRecovery(env),
|
|
348
|
-
'๐ง Attempting auto-recovery...',
|
|
349
|
-
{
|
|
350
|
-
successText: 'Auto-recovery completed',
|
|
351
|
-
errorText: 'Auto-recovery failed'
|
|
352
|
-
}
|
|
353
|
-
);
|
|
354
|
-
|
|
355
|
-
if (!recoveryResult.recovered) {
|
|
356
|
-
displayError(new Error('No authenticated providers found'), {
|
|
357
|
-
operation: 'system startup',
|
|
358
|
-
suggestions: ['Run: cortex --doctor', 'Authenticate at least one provider']
|
|
359
|
-
});
|
|
360
|
-
process.exit(1);
|
|
361
|
-
} else {
|
|
362
|
-
displaySuccess('Auto-recovery successful', { nextStep: 'Continuing startup...' });
|
|
363
|
-
// Re-detect after recovery
|
|
364
|
-
const newEnv = detectEnvironment();
|
|
365
|
-
const newModels = getAvailableModels(newEnv);
|
|
366
|
-
if (!newEnv.hasProviders) {
|
|
367
|
-
console.log('โ Recovery failed: Still no authenticated providers');
|
|
368
|
-
process.exit(1);
|
|
369
|
-
}
|
|
370
|
-
// Update context with recovered environment
|
|
371
|
-
env.claude = newEnv.claude;
|
|
372
|
-
env.codex = newEnv.codex;
|
|
373
|
-
env.hasProviders = newEnv.hasProviders;
|
|
374
|
-
models.worker = newModels.worker;
|
|
375
|
-
models.ic = newModels.ic;
|
|
376
|
-
models.manager = newModels.manager;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
if (models.manager.length === 0 && models.ic.length === 0 && models.worker.length === 0) {
|
|
381
|
-
handleError(new Error('No models available in any tier'), {
|
|
382
|
-
operation: 'model detection',
|
|
383
|
-
tier: 'all'
|
|
384
|
-
});
|
|
385
|
-
process.exit(1);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// Start the REPL with context
|
|
389
|
-
const context = {
|
|
390
|
-
environment: env,
|
|
391
|
-
availableModels: models,
|
|
392
|
-
options: {
|
|
393
|
-
timeoutMs: 120000 // 2 minutes
|
|
394
|
-
}
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
await startEnhancedREPL(context);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Handle uncaught errors gracefully with rich formatting
|
|
401
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
402
|
-
console.log(''); // Add spacing
|
|
403
|
-
handleError(reason instanceof Error ? reason : new Error(String(reason)), {
|
|
404
|
-
operation: 'async operation',
|
|
405
|
-
context: 'unhandled promise rejection'
|
|
406
|
-
});
|
|
407
|
-
process.exit(1);
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
process.on('uncaughtException', (error) => {
|
|
411
|
-
console.log(''); // Add spacing
|
|
412
|
-
handleError(error, {
|
|
413
|
-
operation: 'system operation',
|
|
414
|
-
context: 'uncaught exception'
|
|
415
|
-
});
|
|
416
|
-
process.exit(1);
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
// Run the CLI with enhanced error handling
|
|
420
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
421
|
-
main().catch(error => {
|
|
422
|
-
console.log(''); // Add spacing
|
|
423
|
-
handleError(error, {
|
|
424
|
-
operation: 'CLI startup',
|
|
425
|
-
context: 'main execution'
|
|
426
|
-
});
|
|
427
|
-
process.exit(1);
|
|
428
|
-
});
|
|
429
|
-
}
|