phewsh 0.11.8 → 0.11.10
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/commands/session.js +93 -12
- package/package.json +1 -1
package/commands/session.js
CHANGED
|
@@ -214,13 +214,26 @@ async function main() {
|
|
|
214
214
|
console.log('');
|
|
215
215
|
|
|
216
216
|
if (!config?.apiKey) {
|
|
217
|
-
console.log(` ${
|
|
218
|
-
console.log(` ${g('
|
|
219
|
-
console.log(
|
|
217
|
+
console.log(` ${b(w('Welcome to PHEWSH.'))}`);
|
|
218
|
+
console.log(` ${g('Your AI knows your project. No more re-explaining.')}`);
|
|
219
|
+
console.log('');
|
|
220
|
+
console.log(` ${w('To chat, you need an API key.')} ${g('(not a subscription)')}`);
|
|
221
|
+
console.log(` ${g('ChatGPT Plus / Claude Pro are separate — API keys are pay-as-you-go.')}`);
|
|
222
|
+
console.log('');
|
|
223
|
+
console.log(` ${cyan('1')} ${b('Anthropic')} ${g('(recommended)')}`);
|
|
224
|
+
console.log(` ${g('console.anthropic.com/settings/keys')}`);
|
|
225
|
+
console.log(` ${g('Direct access to Claude. Best quality. ~$0.01/message.')}`);
|
|
226
|
+
console.log('');
|
|
227
|
+
console.log(` ${cyan('2')} ${b('OpenRouter')}`);
|
|
228
|
+
console.log(` ${g('openrouter.ai/keys')}`);
|
|
229
|
+
console.log(` ${g('One key, many models (Claude, GPT, Gemini, etc.)')}`);
|
|
230
|
+
console.log('');
|
|
231
|
+
console.log(` ${g('Got a key? Type')} /key ${g('to paste it in.')}`);
|
|
232
|
+
console.log(` ${g('Want cloud sync too?')} /login ${g('connects your identity.')}`);
|
|
220
233
|
console.log('');
|
|
221
234
|
} else if (!config.apiKey.startsWith('sk-')) {
|
|
222
|
-
console.log(` ${yellow('
|
|
223
|
-
console.log(` ${g('Run')} /key ${g('to set a
|
|
235
|
+
console.log(` ${yellow('!')} Stored API key looks invalid.`);
|
|
236
|
+
console.log(` ${g('Run')} /key ${g('to set a new one')}`);
|
|
224
237
|
console.log('');
|
|
225
238
|
config.apiKey = null; // Don't try to use a bad key
|
|
226
239
|
}
|
|
@@ -256,7 +269,11 @@ async function main() {
|
|
|
256
269
|
}
|
|
257
270
|
|
|
258
271
|
console.log('');
|
|
259
|
-
|
|
272
|
+
if (!config?.apiKey) {
|
|
273
|
+
console.log(` ${g('type')} /key ${g('to get started · /help for all commands · /quit to exit')}`);
|
|
274
|
+
} else {
|
|
275
|
+
console.log(` ${g('type naturally · /help for commands · /quit to exit')}`);
|
|
276
|
+
}
|
|
260
277
|
console.log('');
|
|
261
278
|
|
|
262
279
|
const rl = readline.createInterface({
|
|
@@ -317,6 +334,7 @@ async function main() {
|
|
|
317
334
|
${g('/model')} ${d('<name>')} Switch model (sonnet, opus, haiku)
|
|
318
335
|
${g('/models')} List available models
|
|
319
336
|
${g('/provider')} Show current provider info
|
|
337
|
+
${g('/update')} Update phewsh to the latest version
|
|
320
338
|
|
|
321
339
|
${w('debug')}
|
|
322
340
|
${g('/system')} Show current system prompt
|
|
@@ -534,20 +552,52 @@ async function main() {
|
|
|
534
552
|
}
|
|
535
553
|
|
|
536
554
|
if (cmd === 'key') {
|
|
555
|
+
if (cmdArg) {
|
|
556
|
+
// Inline: /key sk-ant-...
|
|
557
|
+
const apiKey = cmdArg.trim();
|
|
558
|
+
config = loadConfig() || {};
|
|
559
|
+
if (apiKey.startsWith('sk-ant-') || apiKey.startsWith('sk-')) {
|
|
560
|
+
config.apiKey = apiKey;
|
|
561
|
+
config.provider = 'anthropic';
|
|
562
|
+
saveConfig(config);
|
|
563
|
+
console.log(` ${green('●')} Anthropic API key saved. You're ready to go — just type.\n`);
|
|
564
|
+
} else if (apiKey.startsWith('sk-or-')) {
|
|
565
|
+
config.apiKey = apiKey;
|
|
566
|
+
config.provider = 'openrouter';
|
|
567
|
+
saveConfig(config);
|
|
568
|
+
console.log(` ${green('●')} OpenRouter API key saved. You're ready to go — just type.\n`);
|
|
569
|
+
} else {
|
|
570
|
+
config.apiKey = apiKey;
|
|
571
|
+
saveConfig(config);
|
|
572
|
+
console.log(` ${green('●')} API key saved. You're ready to go — just type.\n`);
|
|
573
|
+
}
|
|
574
|
+
rl.prompt();
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
console.log('');
|
|
578
|
+
console.log(` ${b('Where to get an API key:')}`);
|
|
579
|
+
console.log('');
|
|
580
|
+
console.log(` ${cyan('Anthropic')} ${g('(recommended)')}`);
|
|
581
|
+
console.log(` ${g('1.')} Go to ${w('console.anthropic.com/settings/keys')}`);
|
|
582
|
+
console.log(` ${g('2.')} Create key → copy it (starts with sk-ant-)`)
|
|
583
|
+
console.log('');
|
|
584
|
+
console.log(` ${cyan('OpenRouter')} ${g('(multi-model)')}`);
|
|
585
|
+
console.log(` ${g('1.')} Go to ${w('openrouter.ai/keys')}`);
|
|
586
|
+
console.log(` ${g('2.')} Create key → copy it (starts with sk-or-)`)
|
|
587
|
+
console.log('');
|
|
537
588
|
const keyRl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
538
|
-
keyRl.question(
|
|
589
|
+
keyRl.question(` Paste your API key\n > `, (apiKey) => {
|
|
539
590
|
keyRl.close();
|
|
540
591
|
apiKey = apiKey.trim();
|
|
541
592
|
if (!apiKey) {
|
|
542
593
|
console.log(` ${g('Cancelled')}\n`);
|
|
543
|
-
} else if (!apiKey.startsWith('sk-ant-') && !apiKey.startsWith('sk-')) {
|
|
544
|
-
console.log(` ${yellow('!')} That doesn't look like an Anthropic API key.`);
|
|
545
|
-
console.log(` ${g('Anthropic keys start with sk-ant- — get one at console.anthropic.com')}\n`);
|
|
546
594
|
} else {
|
|
547
595
|
config = loadConfig() || {};
|
|
548
596
|
config.apiKey = apiKey;
|
|
597
|
+
if (apiKey.startsWith('sk-or-')) config.provider = 'openrouter';
|
|
598
|
+
else config.provider = 'anthropic';
|
|
549
599
|
saveConfig(config);
|
|
550
|
-
console.log(
|
|
600
|
+
console.log(`\n ${green('●')} API key saved. You're ready — just type naturally.\n`);
|
|
551
601
|
}
|
|
552
602
|
rl.prompt();
|
|
553
603
|
});
|
|
@@ -599,6 +649,31 @@ async function main() {
|
|
|
599
649
|
return;
|
|
600
650
|
}
|
|
601
651
|
|
|
652
|
+
if (cmd === 'update' || cmd === 'upgrade') {
|
|
653
|
+
console.log(`\n ${g('Checking for updates...')}`);
|
|
654
|
+
try {
|
|
655
|
+
const pkg = require('../../package.json');
|
|
656
|
+
const res = await fetch(`https://registry.npmjs.org/${pkg.name}/latest`, { signal: AbortSignal.timeout(5000) });
|
|
657
|
+
const data = await res.json();
|
|
658
|
+
if (!data.version || data.version === pkg.version) {
|
|
659
|
+
console.log(` ${green('●')} Already on the latest version (${pkg.version})\n`);
|
|
660
|
+
rl.prompt();
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
console.log(` ${cyan(pkg.version)} → ${cyan(data.version)}`);
|
|
664
|
+
console.log(` ${g('Installing...')}\n`);
|
|
665
|
+
const { execSync } = require('child_process');
|
|
666
|
+
execSync(`npm install -g ${pkg.name}@latest`, { stdio: 'inherit' });
|
|
667
|
+
console.log(`\n ${green('●')} Updated to ${data.version}`);
|
|
668
|
+
console.log(` ${g('Restart phewsh to use the new version.')}\n`);
|
|
669
|
+
} catch (err) {
|
|
670
|
+
console.log(` ${yellow('!')} Update failed: ${err.message}`);
|
|
671
|
+
console.log(` ${g('You can update manually:')} npm install -g phewsh\n`);
|
|
672
|
+
}
|
|
673
|
+
rl.prompt();
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
602
677
|
if (cmd === 'run') {
|
|
603
678
|
if (!cmdArg) {
|
|
604
679
|
console.log(` ${g('Usage:')} /run <prompt>`);
|
|
@@ -646,7 +721,13 @@ async function main() {
|
|
|
646
721
|
|
|
647
722
|
// Regular input → send to AI
|
|
648
723
|
if (!config?.apiKey) {
|
|
649
|
-
console.log(
|
|
724
|
+
console.log('');
|
|
725
|
+
console.log(` ${yellow('Almost there!')} You need an API key to chat.`);
|
|
726
|
+
console.log(` Type ${w('/key')} and paste one in — takes 10 seconds.`);
|
|
727
|
+
console.log('');
|
|
728
|
+
console.log(` ${g('Get a key:')} ${cyan('console.anthropic.com/settings/keys')}`);
|
|
729
|
+
console.log(` ${g('Or try:')} ${cyan('openrouter.ai/keys')}`);
|
|
730
|
+
console.log('');
|
|
650
731
|
rl.prompt();
|
|
651
732
|
return;
|
|
652
733
|
}
|