shsu 0.0.7 → 0.0.9

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 +113 -12
  2. package/package.json +1 -1
package/bin/shsu.mjs CHANGED
@@ -465,7 +465,22 @@ 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
+ "url": "https://your-supabase.example.com",
476
+ "edgeContainer": "edge",
477
+ "dbContainer": "postgres"
478
+ }
479
+ }
480
+
481
+ To find the values, SSH to your server and run:
482
+ docker ps # Find container names (e.g., xxx-supabase-edge-1)
483
+ docker inspect <container> # Find volume paths in "Mounts" section` }] };
469
484
  }
470
485
  const funcName = args.name;
471
486
  const noRestart = args.noRestart || false;
@@ -476,7 +491,9 @@ async function cmdMcp() {
476
491
  } else {
477
492
  const funcPath = join(config.localPath, funcName);
478
493
  if (!existsSync(funcPath)) {
479
- return { content: [{ type: 'text', text: `Error: Function not found: ${funcPath}` }] };
494
+ return { content: [{ type: 'text', text: `Error: Function not found: ${funcPath}
495
+
496
+ To fix, create the function first using the 'new' tool with name: "${funcName}"` }] };
480
497
  }
481
498
  output = captureExec(`rsync -avz "${funcPath}/" "${config.server}:${config.remotePath}/${funcName}/"`);
482
499
  }
@@ -490,7 +507,22 @@ async function cmdMcp() {
490
507
 
491
508
  case 'list': {
492
509
  if (!config.server || !config.remotePath) {
493
- return { content: [{ type: 'text', text: 'Error: server and remotePath must be configured.' }] };
510
+ return { content: [{ type: 'text', text: `Error: server and remotePath must be configured.
511
+
512
+ To fix, add to package.json:
513
+ {
514
+ "shsu": {
515
+ "server": "root@your-server.com",
516
+ "remotePath": "/data/coolify/services/xxx/volumes/functions",
517
+ "url": "https://your-supabase.example.com",
518
+ "edgeContainer": "edge",
519
+ "dbContainer": "postgres"
520
+ }
521
+ }
522
+
523
+ To find the values, SSH to your server and run:
524
+ docker ps # Find container names (e.g., xxx-supabase-edge-1)
525
+ docker inspect <container> # Find volume paths in "Mounts" section` }] };
494
526
  }
495
527
  const remote = captureExec(`ssh ${config.server} "ls -1 ${config.remotePath} 2>/dev/null"`) || '(none)';
496
528
  let local = '(none)';
@@ -505,10 +537,23 @@ async function cmdMcp() {
505
537
 
506
538
  case 'invoke': {
507
539
  if (!config.url) {
508
- return { content: [{ type: 'text', text: 'Error: url must be configured for invoke.' }] };
540
+ return { content: [{ type: 'text', text: `Error: url must be configured for invoke.
541
+
542
+ To fix, add to package.json:
543
+ {
544
+ "shsu": {
545
+ "server": "root@your-server.com",
546
+ "remotePath": "/data/coolify/services/xxx/volumes/functions",
547
+ "url": "https://your-supabase.example.com",
548
+ "edgeContainer": "edge",
549
+ "dbContainer": "postgres"
550
+ }
551
+ }` }] };
509
552
  }
510
553
  if (!args.name) {
511
- return { content: [{ type: 'text', text: 'Error: function name is required.' }] };
554
+ return { content: [{ type: 'text', text: `Error: function name is required.
555
+
556
+ Usage: invoke tool with { "name": "function-name", "data": "{\\"key\\": \\"value\\"}" }` }] };
512
557
  }
513
558
  const data = args.data || '{}';
514
559
  const output = captureExec(`curl -s -X POST "${config.url}/functions/v1/${args.name}" -H "Content-Type: application/json" -d '${data}'`);
@@ -517,7 +562,22 @@ async function cmdMcp() {
517
562
 
518
563
  case 'restart': {
519
564
  if (!config.server) {
520
- return { content: [{ type: 'text', text: 'Error: server must be configured.' }] };
565
+ return { content: [{ type: 'text', text: `Error: server must be configured.
566
+
567
+ To fix, add to package.json:
568
+ {
569
+ "shsu": {
570
+ "server": "root@your-server.com",
571
+ "remotePath": "/data/coolify/services/xxx/volumes/functions",
572
+ "url": "https://your-supabase.example.com",
573
+ "edgeContainer": "edge",
574
+ "dbContainer": "postgres"
575
+ }
576
+ }
577
+
578
+ To find the values, SSH to your server and run:
579
+ docker ps # Find container names (e.g., xxx-supabase-edge-1)
580
+ docker inspect <container> # Find volume paths in "Mounts" section` }] };
521
581
  }
522
582
  const output = captureExec(`ssh ${config.server} "docker restart \\$(docker ps -q --filter 'name=${config.edgeContainer}')"`);
523
583
  return { content: [{ type: 'text', text: `Restarted edge-runtime\n\n${output}` }] };
@@ -525,11 +585,15 @@ async function cmdMcp() {
525
585
 
526
586
  case 'new': {
527
587
  if (!args.name) {
528
- return { content: [{ type: 'text', text: 'Error: function name is required.' }] };
588
+ return { content: [{ type: 'text', text: `Error: function name is required.
589
+
590
+ Usage: new tool with { "name": "my-function-name" }` }] };
529
591
  }
530
592
  const funcPath = join(config.localPath, args.name);
531
593
  if (existsSync(funcPath)) {
532
- return { content: [{ type: 'text', text: `Error: Function already exists: ${args.name}` }] };
594
+ return { content: [{ type: 'text', text: `Error: Function already exists: ${args.name}
595
+
596
+ The function already exists at ${funcPath}. To update it, edit the code and use the 'deploy' tool.` }] };
533
597
  }
534
598
  mkdirSync(funcPath, { recursive: true });
535
599
  writeFileSync(
@@ -565,16 +629,43 @@ async function cmdMcp() {
565
629
 
566
630
  case 'migrate': {
567
631
  if (!config.server) {
568
- return { content: [{ type: 'text', text: 'Error: server must be configured.' }] };
632
+ return { content: [{ type: 'text', text: `Error: server must be configured.
633
+
634
+ To fix, add to package.json:
635
+ {
636
+ "shsu": {
637
+ "server": "root@your-server.com",
638
+ "remotePath": "/data/coolify/services/xxx/volumes/functions",
639
+ "url": "https://your-supabase.example.com",
640
+ "edgeContainer": "edge",
641
+ "dbContainer": "postgres"
642
+ }
643
+ }
644
+
645
+ To find the values, SSH to your server and run:
646
+ docker ps # Find container names (e.g., xxx-supabase-edge-1)
647
+ docker inspect <container> # Find volume paths in "Mounts" section` }] };
569
648
  }
570
649
  if (!existsSync(config.migrationsPath)) {
571
- return { content: [{ type: 'text', text: `Error: Migrations folder not found: ${config.migrationsPath}` }] };
650
+ return { content: [{ type: 'text', text: `Error: Migrations folder not found: ${config.migrationsPath}
651
+
652
+ To fix, create the migrations directory and add .sql files:
653
+ mkdir -p ${config.migrationsPath}
654
+
655
+ Then add migration files like:
656
+ ${config.migrationsPath}/001_create_tables.sql
657
+ ${config.migrationsPath}/002_add_indexes.sql` }] };
572
658
  }
573
659
  const migrations = readdirSync(config.migrationsPath)
574
660
  .filter((f) => f.endsWith('.sql'))
575
661
  .sort();
576
662
  if (migrations.length === 0) {
577
- return { content: [{ type: 'text', text: 'No migration files found.' }] };
663
+ return { content: [{ type: 'text', text: `No migration files found in ${config.migrationsPath}
664
+
665
+ Add .sql files to the migrations folder, e.g.:
666
+ ${config.migrationsPath}/001_create_tables.sql
667
+
668
+ Files are executed alphabetically, so use numeric prefixes for ordering.` }] };
578
669
  }
579
670
  let output = `Found ${migrations.length} migration(s): ${migrations.join(', ')}\n\n`;
580
671
  // Sync migrations
@@ -582,7 +673,17 @@ async function cmdMcp() {
582
673
  // Find db container
583
674
  const dbContainer = captureExec(`ssh ${config.server} "docker ps -q --filter 'name=${config.dbContainer}'"`);
584
675
  if (!dbContainer) {
585
- return { content: [{ type: 'text', text: `Error: Database container not found (filter: ${config.dbContainer})` }] };
676
+ return { content: [{ type: 'text', text: `Error: Database container not found (filter: ${config.dbContainer})
677
+
678
+ To fix:
679
+ 1. SSH to your server and run: docker ps
680
+ 2. Find the postgres container name (e.g., abc123-supabase-db-1)
681
+ 3. Update dbContainer in package.json to match a unique part of the name:
682
+ {
683
+ "shsu": {
684
+ "dbContainer": "supabase-db"
685
+ }
686
+ }` }] };
586
687
  }
587
688
  // Run migrations
588
689
  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.9",
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"