@powerhousedao/ph-cli 0.41.3 → 2.5.0-dev.1

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 (76) hide show
  1. package/README.md +122 -18
  2. package/dist/package.json +13 -1
  3. package/dist/scripts/generate-commands-md.ts +84 -0
  4. package/dist/scripts/generate-version.ts +22 -0
  5. package/dist/scripts/manage-environment +190 -0
  6. package/dist/scripts/setup-environment +423 -0
  7. package/dist/scripts/setup-environment.ps1 +313 -0
  8. package/dist/scripts/setup.sh +24 -0
  9. package/dist/src/cli.js +17 -2
  10. package/dist/src/cli.js.map +1 -1
  11. package/dist/src/commands/connect.d.ts +1 -1
  12. package/dist/src/commands/connect.d.ts.map +1 -1
  13. package/dist/src/commands/connect.js +39 -9
  14. package/dist/src/commands/connect.js.map +1 -1
  15. package/dist/src/commands/index.d.ts.map +1 -1
  16. package/dist/src/commands/index.js +3 -1
  17. package/dist/src/commands/index.js.map +1 -1
  18. package/dist/src/commands/install.d.ts +2 -1
  19. package/dist/src/commands/install.d.ts.map +1 -1
  20. package/dist/src/commands/install.js +39 -10
  21. package/dist/src/commands/install.js.map +1 -1
  22. package/dist/src/commands/list.d.ts.map +1 -1
  23. package/dist/src/commands/list.js +2 -2
  24. package/dist/src/commands/list.js.map +1 -1
  25. package/dist/src/commands/reactor.d.ts +9 -0
  26. package/dist/src/commands/reactor.d.ts.map +1 -0
  27. package/dist/src/commands/reactor.js +39 -0
  28. package/dist/src/commands/reactor.js.map +1 -0
  29. package/dist/src/commands/service.d.ts +1 -1
  30. package/dist/src/commands/service.d.ts.map +1 -1
  31. package/dist/src/commands/service.js +48 -126
  32. package/dist/src/commands/service.js.map +1 -1
  33. package/dist/src/commands/switchboard.d.ts +5 -5
  34. package/dist/src/commands/switchboard.d.ts.map +1 -1
  35. package/dist/src/commands/switchboard.js +18 -12
  36. package/dist/src/commands/switchboard.js.map +1 -1
  37. package/dist/src/commands/uninstall.d.ts.map +1 -1
  38. package/dist/src/commands/uninstall.js +10 -1
  39. package/dist/src/commands/uninstall.js.map +1 -1
  40. package/dist/src/help.d.ts +15 -3
  41. package/dist/src/help.d.ts.map +1 -1
  42. package/dist/src/help.js +80 -15
  43. package/dist/src/help.js.map +1 -1
  44. package/dist/src/services/connect.js +1 -1
  45. package/dist/src/services/connect.js.map +1 -1
  46. package/dist/src/services/dev.d.ts.map +1 -1
  47. package/dist/src/services/dev.js +2 -2
  48. package/dist/src/services/dev.js.map +1 -1
  49. package/dist/src/services/generate.js +1 -1
  50. package/dist/src/services/generate.js.map +1 -1
  51. package/dist/src/services/inspect.d.ts.map +1 -1
  52. package/dist/src/services/inspect.js +3 -2
  53. package/dist/src/services/inspect.js.map +1 -1
  54. package/dist/src/services/reactor.d.ts +32 -0
  55. package/dist/src/services/reactor.d.ts.map +1 -0
  56. package/dist/src/services/reactor.js +66 -0
  57. package/dist/src/services/reactor.js.map +1 -0
  58. package/dist/src/services/switchboard.d.ts +2 -31
  59. package/dist/src/services/switchboard.d.ts.map +1 -1
  60. package/dist/src/services/switchboard.js +24 -58
  61. package/dist/src/services/switchboard.js.map +1 -1
  62. package/dist/src/utils.d.ts +11 -3
  63. package/dist/src/utils.d.ts.map +1 -1
  64. package/dist/src/utils.js +8 -7
  65. package/dist/src/utils.js.map +1 -1
  66. package/dist/src/version.d.ts +1 -1
  67. package/dist/src/version.d.ts.map +1 -1
  68. package/dist/src/version.js +1 -1
  69. package/dist/src/version.js.map +1 -1
  70. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  71. package/dist/vitest.config.d.ts +3 -0
  72. package/dist/vitest.config.d.ts.map +1 -0
  73. package/dist/vitest.config.js +7 -0
  74. package/dist/vitest.config.js.map +1 -0
  75. package/package.json +20 -8
  76. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,423 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # =============================================================================
4
+ # Configuration
5
+ # =============================================================================
6
+ TARGET_TAG=${1:-"latest"}
7
+ PROJECT_NAME=${2:-"global"}
8
+
9
+ # =============================================================================
10
+ # OS Detection and Windows Handling
11
+ # =============================================================================
12
+ if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
13
+ if [ -f "$0.ps1" ]; then
14
+ powershell -ExecutionPolicy Bypass -File "$0.ps1" -TARGET_TAG "$TARGET_TAG"
15
+ else
16
+ echo "Error: Windows setup script (setup-environment.ps1) not found"
17
+ exit 1
18
+ fi
19
+ else
20
+ # =============================================================================
21
+ # Package Installation
22
+ # =============================================================================
23
+ sudo apt install -y postgresql postgresql-contrib nginx nginx-module-brotli
24
+ sudo ln -sf /usr/share/nginx/modules-available/mod-brotli.conf /etc/nginx/modules-enabled/50-mod-brotli.conf
25
+
26
+ # =============================================================================
27
+ # Interactive Package Installation
28
+ # =============================================================================
29
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
30
+ echo " Package Installation"
31
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
32
+ while true; do
33
+ read -p "Enter package name to install (or press Enter to skip): " package_name
34
+ if [ -z "$package_name" ]; then
35
+ break
36
+ fi
37
+ ph install "$package_name"
38
+ done
39
+
40
+ # =============================================================================
41
+ # Connect Build
42
+ # =============================================================================
43
+ ph connect build
44
+ cp -r .ph/connect-build/dist /var/www/html/$PROJECT_NAME
45
+
46
+ # =============================================================================
47
+ # Database Configuration
48
+ # =============================================================================
49
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
50
+ echo " Database Configuration"
51
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
52
+ echo "Choose database type:"
53
+ echo "1) Local PostgreSQL database"
54
+ echo "2) Remote PostgreSQL database"
55
+ read -p "Enter your choice (1 or 2): " db_choice
56
+
57
+ if [ "$db_choice" = "1" ]; then
58
+ echo "Setting up local PostgreSQL database..."
59
+
60
+ # Generate database credentials
61
+ DB_PASSWORD="powerhouse"
62
+ DB_USER="powerhouse"
63
+ # Convert to lowercase, replace dots with underscores, replace special chars with underscore, ensure starts with letter
64
+ DB_NAME="powerhouse_$(echo "${PROJECT_NAME}" | tr '[:upper:]' '[:lower:]' | sed 's/\./_/g' | sed 's/[^a-z0-9]/_/g' | sed 's/^[^a-z]/p_/' | cut -c1-63)"
65
+
66
+ # Check if database already exists
67
+ if sudo -u postgres psql -lqt | cut -d \| -f 1 | grep -qw $DB_NAME; then
68
+ echo "Database $DB_NAME already exists"
69
+ read -p "Do you want to recreate it? (y/n): " recreate_db
70
+ if [ "$recreate_db" = "y" ]; then
71
+ sudo -u postgres psql -c "DROP DATABASE $DB_NAME;"
72
+ else
73
+ echo "Using existing database"
74
+ fi
75
+ fi
76
+
77
+ # Create database and user if they don't exist
78
+ sudo -u postgres psql << EOF
79
+ DO
80
+ \$do\$
81
+ BEGIN
82
+ IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '$DB_USER') THEN
83
+ CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';
84
+ END IF;
85
+ END
86
+ \$do\$;
87
+
88
+ CREATE DATABASE $DB_NAME OWNER $DB_USER;
89
+ GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
90
+ EOF
91
+
92
+ # Configure PostgreSQL
93
+ sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = 'localhost'/" /etc/postgresql/*/main/postgresql.conf
94
+
95
+ # Set DATABASE_URL for local database
96
+ DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost:5432/$DB_NAME"
97
+
98
+ echo "Local database configured successfully!"
99
+ echo "Database URL: $DATABASE_URL"
100
+ echo "Please save these credentials securely!"
101
+ else
102
+ echo "Enter remote PostgreSQL URL (format: postgresql://user:password@host:port/db)"
103
+ echo "Example: postgresql://powerhouse:password@db.example.com:5432/powerhouse"
104
+ read -p "DATABASE_URL: " DATABASE_URL
105
+ fi
106
+
107
+ # Save DATABASE_URL to .env file
108
+ echo "DATABASE_URL=$DATABASE_URL" | sudo tee -a .env
109
+
110
+ # =============================================================================
111
+ # SSL Configuration
112
+ # =============================================================================
113
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
114
+ echo " SSL Configuration"
115
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
116
+ echo "Choose SSL configuration:"
117
+ echo "1) Let's Encrypt certificates for domains"
118
+ echo "2) Self-signed certificate for machine hostname"
119
+ read -p "Enter your choice (1 or 2): " ssl_choice
120
+
121
+ if [ "$ssl_choice" = "1" ]; then
122
+ # Install certbot
123
+ sudo apt install -y certbot python3-certbot-nginx
124
+
125
+ # =============================================================================
126
+ # Domain Setup
127
+ # =============================================================================
128
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
129
+ echo " Domain Setup"
130
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
131
+ read -p "Enter Connect domain (e.g. connect.google.com): " connect_domain
132
+ read -p "Enter Switchboard domain (e.g. switchboard.google.com): " switchboard_domain
133
+
134
+ echo "Using domains:"
135
+ echo "Connect: $connect_domain"
136
+ echo "Switchboard: $switchboard_domain"
137
+
138
+ # Generate temporary SSL certificates
139
+ echo "Generating temporary SSL certificates..."
140
+ sudo mkdir -p /etc/nginx/ssl
141
+ sudo openssl req -x509 -nodes -days 1 -newkey rsa:2048 \
142
+ -keyout /etc/nginx/ssl/temp.key \
143
+ -out /etc/nginx/ssl/temp.crt \
144
+ -subj "/CN=$connect_domain" \
145
+ -addext "subjectAltName = DNS:$connect_domain,DNS:$switchboard_domain"
146
+
147
+ # Check if Nginx configuration already exists
148
+ if [ -f "/etc/nginx/sites-available/$PROJECT_NAME" ]; then
149
+ echo "Nginx configuration for $PROJECT_NAME already exists"
150
+ read -p "Do you want to overwrite it? (y/n): " overwrite_nginx
151
+ if [ "$overwrite_nginx" != "y" ]; then
152
+ echo "Keeping existing Nginx configuration"
153
+ else
154
+ # Create Nginx configuration for domains
155
+ echo "Creating Nginx configuration..."
156
+ sudo tee /etc/nginx/sites-available/$PROJECT_NAME > /dev/null << EOF
157
+ # Security headers
158
+ add_header Strict-Transport-Security "max-age=63072000" always;
159
+ add_header X-Frame-Options DENY;
160
+ add_header X-Content-Type-Options nosniff;
161
+ add_header X-XSS-Protection "1; mode=block";
162
+
163
+ # Compression settings
164
+ brotli on;
165
+ brotli_comp_level 6;
166
+ brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
167
+ brotli_static on;
168
+
169
+ gzip on;
170
+ gzip_vary on;
171
+ gzip_proxied any;
172
+ gzip_comp_level 6;
173
+ gzip_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
174
+ gzip_min_length 1000;
175
+ gzip_buffers 16 8k;
176
+
177
+ server {
178
+ listen 80;
179
+ server_name $connect_domain $switchboard_domain;
180
+ return 301 https://\$host\$request_uri;
181
+ }
182
+
183
+ server {
184
+ listen 443 ssl http2;
185
+ server_name $connect_domain;
186
+
187
+ ssl_certificate /etc/nginx/ssl/temp.crt;
188
+ ssl_certificate_key /etc/nginx/ssl/temp.key;
189
+
190
+ # SSL configuration
191
+ ssl_protocols TLSv1.2 TLSv1.3;
192
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
193
+ ssl_prefer_server_ciphers off;
194
+ ssl_session_timeout 1d;
195
+ ssl_session_cache shared:SSL:50m;
196
+ ssl_session_tickets off;
197
+ ssl_stapling on;
198
+ ssl_stapling_verify on;
199
+
200
+ if (\$http_x_forwarded_proto = "http") {
201
+ return 301 https://\$server_name\$request_uri;
202
+ }
203
+
204
+ location / {
205
+ root $PWD/.ph/connect-build/dist;
206
+ try_files \$uri \$uri/ /index.html;
207
+ add_header Cache-Control "no-cache";
208
+ add_header X-Forwarded-Proto \$scheme;
209
+ add_header X-Forwarded-Host \$host;
210
+ add_header X-Forwarded-Port \$server_port;
211
+ }
212
+ }
213
+
214
+ server {
215
+ listen 443 ssl http2;
216
+ server_name $switchboard_domain;
217
+
218
+ ssl_certificate /etc/nginx/ssl/temp.crt;
219
+ ssl_certificate_key /etc/nginx/ssl/temp.key;
220
+
221
+ location / {
222
+ proxy_pass http://localhost:4001;
223
+ proxy_http_version 1.1;
224
+ proxy_set_header Upgrade \$http_upgrade;
225
+ proxy_set_header Connection 'upgrade';
226
+ proxy_set_header Host \$host;
227
+ proxy_cache_bypass \$http_upgrade;
228
+ proxy_set_header X-Real-IP \$remote_addr;
229
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
230
+ proxy_set_header X-Forwarded-Proto \$scheme;
231
+ }
232
+ }
233
+ EOF
234
+ fi
235
+ else
236
+ # Create Nginx configuration for domains
237
+ echo "Creating Nginx configuration..."
238
+ sudo tee /etc/nginx/sites-available/$PROJECT_NAME > /dev/null << EOF
239
+ # Security headers
240
+ add_header Strict-Transport-Security "max-age=63072000" always;
241
+ add_header X-Frame-Options DENY;
242
+ add_header X-Content-Type-Options nosniff;
243
+ add_header X-XSS-Protection "1; mode=block";
244
+
245
+ # Compression settings
246
+ brotli on;
247
+ brotli_comp_level 6;
248
+ brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
249
+ brotli_static on;
250
+
251
+ gzip on;
252
+ gzip_vary on;
253
+ gzip_proxied any;
254
+ gzip_comp_level 6;
255
+ gzip_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
256
+ gzip_min_length 1000;
257
+ gzip_buffers 16 8k;
258
+
259
+ server {
260
+ listen 80;
261
+ server_name $connect_domain $switchboard_domain;
262
+ return 301 https://\$host\$request_uri;
263
+ }
264
+
265
+ server {
266
+ listen 443 ssl http2;
267
+ server_name $connect_domain;
268
+
269
+ ssl_certificate /etc/nginx/ssl/temp.crt;
270
+ ssl_certificate_key /etc/nginx/ssl/temp.key;
271
+
272
+ # SSL configuration
273
+ ssl_protocols TLSv1.2 TLSv1.3;
274
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
275
+ ssl_prefer_server_ciphers off;
276
+ ssl_session_timeout 1d;
277
+ ssl_session_cache shared:SSL:50m;
278
+ ssl_session_tickets off;
279
+ ssl_stapling on;
280
+ ssl_stapling_verify on;
281
+
282
+ if (\$http_x_forwarded_proto = "http") {
283
+ return 301 https://\$server_name\$request_uri;
284
+ }
285
+
286
+ location / {
287
+ root /var/www/html/$PROJECT_NAME;
288
+ try_files \$uri \$uri/ /index.html;
289
+ add_header Cache-Control "no-cache";
290
+ add_header X-Forwarded-Proto \$scheme;
291
+ add_header X-Forwarded-Host \$host;
292
+ add_header X-Forwarded-Port \$server_port;
293
+ }
294
+ }
295
+
296
+ server {
297
+ listen 443 ssl http2;
298
+ server_name $switchboard_domain;
299
+
300
+ ssl_certificate /etc/nginx/ssl/temp.crt;
301
+ ssl_certificate_key /etc/nginx/ssl/temp.key;
302
+
303
+ location / {
304
+ proxy_pass http://localhost:4001;
305
+ proxy_http_version 1.1;
306
+ proxy_set_header Upgrade \$http_upgrade;
307
+ proxy_set_header Connection 'upgrade';
308
+ proxy_set_header Host \$host;
309
+ proxy_cache_bypass \$http_upgrade;
310
+ proxy_set_header X-Real-IP \$remote_addr;
311
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
312
+ proxy_set_header X-Forwarded-Proto \$scheme;
313
+ }
314
+ }
315
+ EOF
316
+ fi
317
+
318
+ # Enable the site
319
+ sudo ln -sf /etc/nginx/sites-available/$PROJECT_NAME /etc/nginx/sites-enabled/
320
+ sudo rm -f /etc/nginx/sites-enabled/default
321
+
322
+ # Test Nginx configuration
323
+ sudo nginx -t
324
+
325
+ # Obtain SSL certificates
326
+ echo "Obtaining SSL certificates..."
327
+ sudo certbot --nginx -d $connect_domain -d $switchboard_domain --non-interactive --agree-tos --email admin@$connect_domain
328
+
329
+ # Remove temporary certificates
330
+ sudo rm -f /etc/nginx/ssl/temp.*
331
+
332
+ else
333
+ # Get machine hostname
334
+ hostname=$(hostname)
335
+
336
+ # Generate self-signed certificate
337
+ echo "Generating self-signed certificate for $hostname..."
338
+ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
339
+ -keyout /etc/ssl/private/$hostname.key \
340
+ -out /etc/ssl/certs/$hostname.crt \
341
+ -subj "/CN=$hostname" \
342
+ -addext "subjectAltName = DNS:$hostname"
343
+
344
+ # Create Nginx configuration for self-signed
345
+ echo "Creating Nginx configuration..."
346
+ sudo tee /etc/nginx/sites-available/$PROJECT_NAME > /dev/null << EOF
347
+ # Security headers
348
+ add_header Strict-Transport-Security "max-age=63072000" always;
349
+ add_header X-Frame-Options DENY;
350
+ add_header X-Content-Type-Options nosniff;
351
+ add_header X-XSS-Protection "1; mode=block";
352
+
353
+ # Compression settings
354
+ brotli on;
355
+ brotli_comp_level 6;
356
+ brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
357
+ brotli_static on;
358
+
359
+ gzip on;
360
+ gzip_vary on;
361
+ gzip_proxied any;
362
+ gzip_comp_level 6;
363
+ gzip_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
364
+ gzip_min_length 1000;
365
+ gzip_buffers 16 8k;
366
+
367
+ server {
368
+ listen 80;
369
+ server_name $hostname;
370
+ return 301 https://\$host\$request_uri;
371
+ }
372
+
373
+ server {
374
+ listen 443 ssl http2;
375
+ server_name $hostname;
376
+
377
+ ssl_certificate /etc/ssl/certs/$hostname.crt;
378
+ ssl_certificate_key /etc/ssl/private/$hostname.key;
379
+
380
+ location /connect {
381
+ proxy_pass http://localhost:3000;
382
+ proxy_http_version 1.1;
383
+ proxy_set_header Upgrade \$http_upgrade;
384
+ proxy_set_header Connection 'upgrade';
385
+ proxy_set_header Host \$host;
386
+ proxy_cache_bypass \$http_upgrade;
387
+ proxy_set_header X-Real-IP \$remote_addr;
388
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
389
+ proxy_set_header X-Forwarded-Proto \$scheme;
390
+ }
391
+
392
+ location /switchboard {
393
+ proxy_pass http://localhost:4001;
394
+ proxy_http_version 1.1;
395
+ proxy_set_header Upgrade \$http_upgrade;
396
+ proxy_set_header Connection 'upgrade';
397
+ proxy_set_header Host \$host;
398
+ proxy_cache_bypass \$http_upgrade;
399
+ proxy_set_header X-Real-IP \$remote_addr;
400
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
401
+ proxy_set_header X-Forwarded-Proto \$scheme;
402
+ }
403
+ }
404
+ EOF
405
+
406
+ # Enable the site
407
+ sudo ln -sf /etc/nginx/sites-available/$PROJECT_NAME /etc/nginx/sites-enabled/
408
+ sudo rm -f /etc/nginx/sites-enabled/default
409
+
410
+ # Test Nginx configuration
411
+ sudo nginx -t
412
+ fi
413
+
414
+ # =============================================================================
415
+ # Database Schema Setup
416
+ # =============================================================================
417
+ pnpm prisma db push --schema node_modules/document-drive/dist/prisma/schema.prisma
418
+
419
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
420
+ echo " Environment setup complete!"
421
+ echo " Use 'ph service start' to start services"
422
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
423
+ fi