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.
Files changed (2) hide show
  1. package/commands/session.js +93 -12
  2. package/package.json +1 -1
@@ -214,13 +214,26 @@ async function main() {
214
214
  console.log('');
215
215
 
216
216
  if (!config?.apiKey) {
217
- console.log(` ${yellow('')} No API key configured.`);
218
- console.log(` ${g('Run')} /login ${g('to set up identity + API key')}`);
219
- console.log(` ${g('Or')} /key ${g('to add an API key directly')}`);
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('')} Stored API key looks invalid (doesn't start with sk-).`);
223
- console.log(` ${g('Run')} /key ${g('to set a valid Anthropic API key')}`);
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
- console.log(` ${g('type naturally · /help for commands · /quit to exit')}`);
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(`\n Anthropic API key (starts with sk-ant-)\n > `, (apiKey) => {
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(` ${green('●')} API key saved\n`);
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(`\n ${yellow('')} No API key configured. Run /key to set one.\n`);
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phewsh",
3
- "version": "0.11.8",
3
+ "version": "0.11.10",
4
4
  "description": "Turn intent into action. Structure your thinking, execute your next step.",
5
5
  "bin": {
6
6
  "phewsh": "bin/phewsh.js"