shsu 0.0.7 → 0.0.8

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/bin/shsu.mjs +85 -12
  2. package/package.json +1 -1
package/bin/shsu.mjs CHANGED
@@ -465,7 +465,18 @@ async function cmdMcp() {
465
465
  switch (name) {
466
466
  case 'deploy': {
467
467
  if (!config.server || !config.remotePath) {
468
- return { content: [{ type: 'text', text: 'Error: server and remotePath must be configured. Run "shsu init" first.' }] };
468
+ return { content: [{ type: 'text', text: `Error: server and remotePath must be configured.
469
+
470
+ To fix, add to package.json:
471
+ {
472
+ "shsu": {
473
+ "server": "root@your-server.com",
474
+ "remotePath": "/data/coolify/services/xxx/volumes/functions"
475
+ }
476
+ }
477
+
478
+ Find remotePath by running on your server:
479
+ docker inspect $(docker ps -q --filter 'name=edge') | grep -A 5 "Mounts"` }] };
469
480
  }
470
481
  const funcName = args.name;
471
482
  const noRestart = args.noRestart || false;
@@ -476,7 +487,9 @@ async function cmdMcp() {
476
487
  } else {
477
488
  const funcPath = join(config.localPath, funcName);
478
489
  if (!existsSync(funcPath)) {
479
- return { content: [{ type: 'text', text: `Error: Function not found: ${funcPath}` }] };
490
+ return { content: [{ type: 'text', text: `Error: Function not found: ${funcPath}
491
+
492
+ To fix, create the function first using the 'new' tool with name: "${funcName}"` }] };
480
493
  }
481
494
  output = captureExec(`rsync -avz "${funcPath}/" "${config.server}:${config.remotePath}/${funcName}/"`);
482
495
  }
@@ -490,7 +503,18 @@ async function cmdMcp() {
490
503
 
491
504
  case 'list': {
492
505
  if (!config.server || !config.remotePath) {
493
- return { content: [{ type: 'text', text: 'Error: server and remotePath must be configured.' }] };
506
+ return { content: [{ type: 'text', text: `Error: server and remotePath must be configured.
507
+
508
+ To fix, add to package.json:
509
+ {
510
+ "shsu": {
511
+ "server": "root@your-server.com",
512
+ "remotePath": "/data/coolify/services/xxx/volumes/functions"
513
+ }
514
+ }
515
+
516
+ Find remotePath by running on your server:
517
+ docker inspect $(docker ps -q --filter 'name=edge') | grep -A 5 "Mounts"` }] };
494
518
  }
495
519
  const remote = captureExec(`ssh ${config.server} "ls -1 ${config.remotePath} 2>/dev/null"`) || '(none)';
496
520
  let local = '(none)';
@@ -505,10 +529,19 @@ async function cmdMcp() {
505
529
 
506
530
  case 'invoke': {
507
531
  if (!config.url) {
508
- return { content: [{ type: 'text', text: 'Error: url must be configured for invoke.' }] };
532
+ return { content: [{ type: 'text', text: `Error: url must be configured for invoke.
533
+
534
+ To fix, add to package.json:
535
+ {
536
+ "shsu": {
537
+ "url": "https://your-supabase.example.com"
538
+ }
539
+ }` }] };
509
540
  }
510
541
  if (!args.name) {
511
- return { content: [{ type: 'text', text: 'Error: function name is required.' }] };
542
+ return { content: [{ type: 'text', text: `Error: function name is required.
543
+
544
+ Usage: invoke tool with { "name": "function-name", "data": "{\\"key\\": \\"value\\"}" }` }] };
512
545
  }
513
546
  const data = args.data || '{}';
514
547
  const output = captureExec(`curl -s -X POST "${config.url}/functions/v1/${args.name}" -H "Content-Type: application/json" -d '${data}'`);
@@ -517,7 +550,14 @@ async function cmdMcp() {
517
550
 
518
551
  case 'restart': {
519
552
  if (!config.server) {
520
- return { content: [{ type: 'text', text: 'Error: server must be configured.' }] };
553
+ return { content: [{ type: 'text', text: `Error: server must be configured.
554
+
555
+ To fix, add to package.json:
556
+ {
557
+ "shsu": {
558
+ "server": "root@your-server.com"
559
+ }
560
+ }` }] };
521
561
  }
522
562
  const output = captureExec(`ssh ${config.server} "docker restart \\$(docker ps -q --filter 'name=${config.edgeContainer}')"`);
523
563
  return { content: [{ type: 'text', text: `Restarted edge-runtime\n\n${output}` }] };
@@ -525,11 +565,15 @@ async function cmdMcp() {
525
565
 
526
566
  case 'new': {
527
567
  if (!args.name) {
528
- return { content: [{ type: 'text', text: 'Error: function name is required.' }] };
568
+ return { content: [{ type: 'text', text: `Error: function name is required.
569
+
570
+ Usage: new tool with { "name": "my-function-name" }` }] };
529
571
  }
530
572
  const funcPath = join(config.localPath, args.name);
531
573
  if (existsSync(funcPath)) {
532
- return { content: [{ type: 'text', text: `Error: Function already exists: ${args.name}` }] };
574
+ return { content: [{ type: 'text', text: `Error: Function already exists: ${args.name}
575
+
576
+ The function already exists at ${funcPath}. To update it, edit the code and use the 'deploy' tool.` }] };
533
577
  }
534
578
  mkdirSync(funcPath, { recursive: true });
535
579
  writeFileSync(
@@ -565,16 +609,35 @@ async function cmdMcp() {
565
609
 
566
610
  case 'migrate': {
567
611
  if (!config.server) {
568
- return { content: [{ type: 'text', text: 'Error: server must be configured.' }] };
612
+ return { content: [{ type: 'text', text: `Error: server must be configured.
613
+
614
+ To fix, add to package.json:
615
+ {
616
+ "shsu": {
617
+ "server": "root@your-server.com"
618
+ }
619
+ }` }] };
569
620
  }
570
621
  if (!existsSync(config.migrationsPath)) {
571
- return { content: [{ type: 'text', text: `Error: Migrations folder not found: ${config.migrationsPath}` }] };
622
+ return { content: [{ type: 'text', text: `Error: Migrations folder not found: ${config.migrationsPath}
623
+
624
+ To fix, create the migrations directory and add .sql files:
625
+ mkdir -p ${config.migrationsPath}
626
+
627
+ Then add migration files like:
628
+ ${config.migrationsPath}/001_create_tables.sql
629
+ ${config.migrationsPath}/002_add_indexes.sql` }] };
572
630
  }
573
631
  const migrations = readdirSync(config.migrationsPath)
574
632
  .filter((f) => f.endsWith('.sql'))
575
633
  .sort();
576
634
  if (migrations.length === 0) {
577
- return { content: [{ type: 'text', text: 'No migration files found.' }] };
635
+ return { content: [{ type: 'text', text: `No migration files found in ${config.migrationsPath}
636
+
637
+ Add .sql files to the migrations folder, e.g.:
638
+ ${config.migrationsPath}/001_create_tables.sql
639
+
640
+ Files are executed alphabetically, so use numeric prefixes for ordering.` }] };
578
641
  }
579
642
  let output = `Found ${migrations.length} migration(s): ${migrations.join(', ')}\n\n`;
580
643
  // Sync migrations
@@ -582,7 +645,17 @@ async function cmdMcp() {
582
645
  // Find db container
583
646
  const dbContainer = captureExec(`ssh ${config.server} "docker ps -q --filter 'name=${config.dbContainer}'"`);
584
647
  if (!dbContainer) {
585
- return { content: [{ type: 'text', text: `Error: Database container not found (filter: ${config.dbContainer})` }] };
648
+ return { content: [{ type: 'text', text: `Error: Database container not found (filter: ${config.dbContainer})
649
+
650
+ To fix:
651
+ 1. SSH to your server and run: docker ps
652
+ 2. Find the postgres container name (e.g., abc123-supabase-db-1)
653
+ 3. Update dbContainer in package.json to match a unique part of the name:
654
+ {
655
+ "shsu": {
656
+ "dbContainer": "supabase-db"
657
+ }
658
+ }` }] };
586
659
  }
587
660
  // Run migrations
588
661
  for (const migration of migrations) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shsu",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "CLI for deploying and managing Supabase Edge Functions on self-hosted Supabase (Coolify, Docker Compose). Sync functions via rsync, stream logs, and invoke endpoints.",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"