@startanaicompany/cli 1.4.16 → 1.4.18

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/CLAUDE.md CHANGED
@@ -275,6 +275,71 @@ saac create web -s web -r git@git... -t abc123 \
275
275
  - Saves project config to `.saac/config.json` after successful creation
276
276
  - Displays next steps and useful commands
277
277
 
278
+ **Deployment Behavior (NEW):**
279
+
280
+ The `create` command now **waits for the initial deployment to complete** (up to 5 minutes) before returning.
281
+
282
+ **Response Time:**
283
+ - Typical: 30-120 seconds
284
+ - Maximum: 5 minutes (timeout)
285
+
286
+ **Success Response:**
287
+ ```json
288
+ {
289
+ "success": true,
290
+ "coolify_app_uuid": "...",
291
+ "app_name": "my-app",
292
+ "domain": "https://myapp.startanaicompany.com",
293
+ "deployment_status": "finished",
294
+ "deployment_uuid": "...",
295
+ "git_branch": "master"
296
+ }
297
+ ```
298
+
299
+ **Failure Response (HTTP 200 with success: false):**
300
+ ```json
301
+ {
302
+ "success": false,
303
+ "coolify_app_uuid": "...",
304
+ "app_name": "my-app",
305
+ "deployment_status": "failed",
306
+ "message": "Port 8080 is already in use. Remove host port bindings...",
307
+ "errors": [
308
+ {
309
+ "type": "PORT_CONFLICT",
310
+ "message": "Port 8080 is already in use...",
311
+ "detail": "Bind for 0.0.0.0:8080 failed..."
312
+ }
313
+ ],
314
+ "relevant_logs": [...],
315
+ "last_logs": [...]
316
+ }
317
+ ```
318
+
319
+ **Error Types:**
320
+ - `PORT_CONFLICT` - Host port binding conflict in docker-compose.yml
321
+ - `BUILD_FAILED` - Build process returned non-zero exit code
322
+ - `TIMEOUT` - Deployment didn't complete in 5 minutes
323
+ - `UNKNOWN` - Generic deployment failure
324
+
325
+ **Important Notes:**
326
+ 1. **Application is created even if deployment fails** - the UUID is saved to `.saac/config.json`
327
+ 2. Failed deployments return HTTP 200 (not 4xx) with `success: false`
328
+ 3. CLI must check the `success` field, not just HTTP status code
329
+ 4. Detailed error information is displayed with actionable advice
330
+ 5. User can fix the issue and run `saac deploy` to retry
331
+
332
+ **Error Display:**
333
+ The CLI displays comprehensive error information:
334
+ - Error summary message
335
+ - Structured error details with types
336
+ - Relevant error logs (filtered)
337
+ - Last log lines for context
338
+ - Actionable advice based on error type:
339
+ - `PORT_CONFLICT`: Remove host port bindings from docker-compose.yml
340
+ - `BUILD_FAILED`: Check Dockerfile, run `docker build .` locally
341
+ - `TIMEOUT`: Check `saac status` and `saac logs`, may still be running
342
+
278
343
  ### Update Command Implementation
279
344
 
280
345
  The `update` command allows modifying application configuration after deployment using `PATCH /api/v1/applications/:uuid`.
@@ -373,7 +438,7 @@ saac git disconnect git.startanaicompany.com
373
438
 
374
439
  ### Deploy Command Implementation
375
440
 
376
- The `deploy` command triggers deployment for the current application.
441
+ The `deploy` command triggers deployment and **waits for completion** (up to 5 minutes).
377
442
 
378
443
  **Usage:**
379
444
  ```bash
@@ -385,13 +450,57 @@ saac deploy --force
385
450
  1. Validates authentication (session token not expired)
386
451
  2. Checks for project config (`.saac/config.json`)
387
452
  3. Makes POST request to `/api/v1/applications/:uuid/deploy`
388
- 4. Displays deployment status and deployment ID
389
- 5. Shows command to follow logs: `saac logs --follow`
453
+ 4. **Waits for deployment to complete** (up to 5 minutes)
454
+ 5. Displays deployment status with detailed error information on failure
390
455
 
391
- **Response Fields:**
392
- - `status` - Application status after deployment triggered
393
- - `domain` - Application domain (if available)
394
- - `deployment_id` - Unique ID for this deployment
456
+ **Response Time:**
457
+ - Typical: 30-120 seconds
458
+ - Maximum: 5 minutes (timeout)
459
+
460
+ **Success Response:**
461
+ ```json
462
+ {
463
+ "success": true,
464
+ "status": "finished",
465
+ "deployment_uuid": "...",
466
+ "git_branch": "master",
467
+ "domain": "https://myapp.startanaicompany.com",
468
+ "traefik_status": "queued"
469
+ }
470
+ ```
471
+
472
+ **Failure Response:**
473
+ ```json
474
+ {
475
+ "success": false,
476
+ "status": "failed",
477
+ "message": "Build failed with exit code 1",
478
+ "errors": [
479
+ {
480
+ "type": "BUILD_FAILED",
481
+ "message": "Build failed with exit code 1",
482
+ "detail": "npm ERR! code ELIFECYCLE..."
483
+ }
484
+ ],
485
+ "relevant_logs": [...],
486
+ "last_logs": [...]
487
+ }
488
+ ```
489
+
490
+ **Error Types:**
491
+ - `PORT_CONFLICT` - Host port binding conflict
492
+ - `BUILD_FAILED` - Build process failed
493
+ - `TIMEOUT` - Deployment didn't complete in 5 minutes
494
+ - `UNKNOWN` - Generic failure
495
+
496
+ **Error Display:**
497
+ The CLI displays:
498
+ 1. Error summary message
499
+ 2. Structured error details with types
500
+ 3. Relevant logs (filtered error logs)
501
+ 4. Last 5 log lines for context
502
+ 5. Actionable advice based on error type
503
+ 6. Suggestion to view full logs with `saac logs --follow`
395
504
 
396
505
  **Note:** The `--force` flag is defined in the CLI but not currently used by the API.
397
506
 
@@ -542,16 +651,361 @@ Uses the same status display logic as the status command (see "Application Statu
542
651
  - Domains fallback to `{subdomain}.startanaicompany.com` if not set
543
652
  - Branch defaults to 'master' if not specified
544
653
 
545
- ### Incomplete Commands
654
+ ### Deployments Command Implementation
655
+
656
+ The `deployments` command displays deployment history for the current application in a formatted table.
657
+
658
+ **Usage:**
659
+ ```bash
660
+ saac deployments
661
+ saac deploys # Alias
662
+
663
+ # With pagination
664
+ saac deployments --limit 10
665
+ saac deployments --limit 20 --offset 20
666
+ ```
667
+
668
+ **How It Works:**
669
+ 1. Validates authentication (session token not expired)
670
+ 2. Checks for project config (`.saac/config.json`)
671
+ 3. Fetches deployment history from `/api/v1/applications/:uuid/deployments`
672
+ 4. Displays table with columns: UUID, Status, Branch, Commit, Duration, Trigger, Date
673
+ 5. Shows pagination info if more deployments available
674
+
675
+ **Options:**
676
+ - `-l, --limit <number>` - Number of deployments to show (default: 20)
677
+ - `-o, --offset <number>` - Offset for pagination (default: 0)
678
+
679
+ **Status Display:**
680
+ - ✅ `finished` - Displayed in green
681
+ - ✗ `failed` - Displayed in red
682
+ - ⏳ `running`, `queued` - Displayed in yellow
683
+ - `unknown` - Displayed in gray
684
+
685
+ **Table Formatting:**
686
+ - UUID truncated to 26 characters for readability
687
+ - Commit SHA truncated to 7 characters
688
+ - Duration shown in seconds
689
+ - Date formatted with `toLocaleString()`
690
+
691
+ **Response Fields:**
692
+ ```json
693
+ {
694
+ "deployments": [
695
+ {
696
+ "deployment_uuid": "...",
697
+ "status": "finished",
698
+ "git_branch": "master",
699
+ "git_commit": "abc1234",
700
+ "duration_seconds": 45,
701
+ "triggered_by": "api",
702
+ "started_at": "2024-01-20T12:00:00Z"
703
+ }
704
+ ],
705
+ "total": 100
706
+ }
707
+ ```
708
+
709
+ **Next Steps:**
710
+ After viewing deployment history, use:
711
+ - `saac logs --deployment` - View latest deployment logs
712
+ - `saac logs --deployment <uuid>` - View specific deployment logs
713
+
714
+ ### Logs Command Implementation
715
+
716
+ The `logs` command displays application logs with support for both deployment logs (build logs) and runtime logs (container logs).
717
+
718
+ **Usage:**
719
+ ```bash
720
+ # View latest deployment logs (build logs)
721
+ saac logs --deployment
722
+ saac logs -d
723
+
724
+ # View specific deployment logs
725
+ saac logs --deployment abc123-def456-...
726
+ saac logs abc123-def456-... --deployment
727
+
728
+ # View deployment logs in raw format
729
+ saac logs --deployment --raw
730
+
731
+ # View runtime logs (container logs)
732
+ saac logs
733
+ saac logs --tail 200
734
+ saac logs --follow
735
+ saac logs --since 1h
736
+ ```
737
+
738
+ **Two Modes:**
739
+
740
+ **1. Deployment Logs Mode (Build Logs)**
741
+ - Enabled with `--deployment` flag
742
+ - Shows logs from the build/deployment process
743
+ - Includes build output, errors, and deployment status
744
+ - Supports both parsed (colorized) and raw formats
745
+
746
+ **Options:**
747
+ - `--deployment [uuid]` - View deployment logs (omit UUID for latest)
748
+ - `--raw` - Show raw log output (no parsing or colorization)
749
+ - `--include-hidden` - Include hidden log lines
750
+
751
+ **Display:**
752
+ - Header with deployment UUID, status, commit, duration
753
+ - Parsed logs with stderr highlighted in red
754
+ - Error summary if deployment failed
755
+ - Structured error information with types and details
756
+
757
+ **2. Runtime Logs Mode (Container Logs)**
758
+ - Default mode when no `--deployment` flag
759
+ - Shows logs from the running container
760
+ - Real-time application output
761
+
762
+ **Options:**
763
+ - `-t, --tail <lines>` - Number of lines to show (default: 100)
764
+ - `-f, --follow` - Follow log output (not yet implemented)
765
+ - `--since <time>` - Show logs since timestamp
766
+
767
+ **Error Handling:**
768
+ - 404 error → No deployments found, suggests `saac deploy`
769
+ - 501 error → Runtime logs not implemented, suggests deployment logs
770
+
771
+ **Response Fields (Deployment Logs):**
772
+ ```json
773
+ {
774
+ "deployment_uuid": "...",
775
+ "status": "finished",
776
+ "commit": "abc1234",
777
+ "commit_message": "Fix bug",
778
+ "started_at": "2024-01-20T12:00:00Z",
779
+ "finished_at": "2024-01-20T12:02:00Z",
780
+ "duration_seconds": 120,
781
+ "log_count": 150,
782
+ "logs": [
783
+ {
784
+ "type": "stdout",
785
+ "output": "Installing dependencies..."
786
+ },
787
+ {
788
+ "type": "stderr",
789
+ "output": "npm WARN deprecated package@1.0.0"
790
+ }
791
+ ],
792
+ "raw_logs": "...",
793
+ "errors": [
794
+ {
795
+ "type": "BUILD_FAILED",
796
+ "message": "Build failed with exit code 1",
797
+ "detail": "npm ERR! code ELIFECYCLE"
798
+ }
799
+ ]
800
+ }
801
+ ```
546
802
 
547
- Several commands still need implementation:
548
- - `src/commands/env.js` - Not implemented (stub only)
549
- - `src/commands/domain.js` - Not implemented (stub only)
550
- - `src/commands/logs.js` - Not implemented (stub only)
551
- - `src/commands/delete.js` - Not implemented (stub only)
552
- - `src/commands/whoami.js` - Not implemented (stub only)
803
+ ### Local Development Commands (NEW in 1.5.0)
553
804
 
554
- **Important:** The `env` and `domain` commands need to export OBJECTS with subcommand methods (e.g., `module.exports = { set, get, list }`), not simple functions. See `bin/saac.js:189-219` for how these are called.
805
+ #### Run Command Implementation
806
+
807
+ The `run` command allows executing local commands with remote environment variables from the deployed application.
808
+
809
+ **Usage:**
810
+ ```bash
811
+ saac run <command> # Run command with remote env vars
812
+ saac run npm start # Start app with production env
813
+ saac run --sync npm run build # Force refresh env vars (skip cache)
814
+ saac run -q npm test # Quiet mode (suppress warnings)
815
+ ```
816
+
817
+ **Implementation Details:**
818
+ - Fetches env vars from `GET /applications/:uuid/env/export`
819
+ - Uses 5-minute in-memory cache (TTL: 300 seconds)
820
+ - Creates temp file at `/tmp/saac-env-{uuid}.sh` with 0600 permissions
821
+ - Sources env file and executes command in subshell
822
+ - Automatic cleanup on exit (SIGINT/SIGTERM handlers)
823
+ - Rate limit handling (10 requests/minute per user)
824
+
825
+ **Security Features:**
826
+ - Temp files with 0600 permissions (owner read-write only)
827
+ - Automatic cleanup on process exit
828
+ - Warning message about exposed secrets
829
+ - Cache reduces API calls (rate limit protection)
830
+
831
+ **Error Handling:**
832
+ - 429 Rate Limit: Shows retry time, mentions caching
833
+ - 403 Forbidden: User doesn't own application
834
+ - 404 Not Found: Application doesn't exist
835
+ - Network failures: Graceful error messages
836
+
837
+ **Location:** `src/commands/run.js`
838
+
839
+ ---
840
+
841
+ #### Shell Command Implementation
842
+
843
+ The `shell` command opens an interactive shell with remote environment variables loaded.
844
+
845
+ **Usage:**
846
+ ```bash
847
+ saac shell # Open shell (uses $SHELL or /bin/bash)
848
+ saac shell --cmd zsh # Use specific shell
849
+ saac shell --sync # Force refresh env vars (skip cache)
850
+ ```
851
+
852
+ **Implementation Details:**
853
+ - Fetches env vars from `GET /applications/:uuid/env/export`
854
+ - Uses 5-minute in-memory cache (same as `run`)
855
+ - Creates temp file for env vars at `/tmp/saac-env-{uuid}.sh`
856
+ - Special handling for bash and zsh (custom RC files)
857
+ - Sources environment before shell starts
858
+ - Automatic cleanup when shell exits
859
+
860
+ **Shell-Specific Behavior:**
861
+ - **bash:** Uses `--rcfile` with temporary RC that sources env + user's `.bashrc`
862
+ - **zsh:** Uses `ZDOTDIR` with temporary `.zshrc` that sources env + user's `.zshrc`
863
+ - **other:** Fallback to bash with source then exec
864
+
865
+ **Security Features:**
866
+ - Same as `run` command (0600 permissions, cleanup, warnings)
867
+ - Sets environment variables: `SAAC_ENV_LOADED=1`, `SAAC_APP_NAME`, `SAAC_APP_UUID`
868
+
869
+ **User Experience:**
870
+ ```bash
871
+ $ saac shell
872
+ ✓ Environment variables retrieved
873
+
874
+ 🚀 Opening shell with 6 environment variables loaded
875
+
876
+ Application: my-app
877
+ Shell: bash
878
+ Variables: 6
879
+
880
+ ⚠️ Secrets are exposed on local machine
881
+ Temporary file: /tmp/saac-env-abc123.sh (will be deleted on exit)
882
+
883
+ Type "exit" or press Ctrl+D to close the shell
884
+ ────────────────────────────────────────────────────────────────
885
+
886
+ bash-5.0$ echo $NODE_ENV
887
+ production
888
+ bash-5.0$ exit
889
+
890
+ ✓ Shell closed, environment variables cleared
891
+ ```
892
+
893
+ **Location:** `src/commands/shell.js`
894
+
895
+ ---
896
+
897
+ ### Remote Execution Commands (NEW in 1.6.0)
898
+
899
+ #### Exec Command Implementation
900
+
901
+ The `exec` command allows executing commands directly in the deployed application's container.
902
+
903
+ **Usage:**
904
+ ```bash
905
+ saac exec "npm run db:migrate" # Run database migrations
906
+ saac exec "npm run build" --timeout 120 # With custom timeout
907
+ saac exec "python manage.py collectstatic" --workdir /app/backend
908
+ saac exec --history # View execution history
909
+ saac exec --history --limit 50 # Show more history
910
+ ```
911
+
912
+ **Implementation Details:**
913
+ - Sends command to `POST /applications/:uuid/exec`
914
+ - Backend validates command against allowlist
915
+ - Python daemon executes via Docker API (no shell interpretation!)
916
+ - Returns: execution_id, exit_code, stdout, stderr, duration
917
+ - Command runs in container as detected user (not root)
918
+
919
+ **Architecture:**
920
+ ```
921
+ CLI → Backend API → Database (exec_requests table) → Python Daemon → Docker Container
922
+ ```
923
+
924
+ **Security Features:**
925
+ - ✅ **3-layer validation:** Backend allowlist + daemon validation + Docker array execution
926
+ - ✅ **Command allowlist:** npm, node, python, bash, etc. (dangerous commands blocked)
927
+ - ✅ **Dangerous pattern detection:** Blocks `rm -rf`, `| sh`, `$(...)`, etc.
928
+ - ✅ **Rate limiting:** 30 requests per 5 minutes per user
929
+ - ✅ **No shell interpretation:** Commands executed as arrays, not strings
930
+ - ✅ **Non-root execution:** Commands run as app user, never privileged
931
+ - ✅ **Audit logging:** All executions logged with user, command, exit code
932
+
933
+ **Allowed Commands:**
934
+ - Node.js: `npm`, `node`, `npx`, `yarn`, `pnpm`
935
+ - Python: `python`, `python3`, `pip`, `poetry`
936
+ - Ruby: `bundle`, `rake`, `rails`
937
+ - Build tools: `make`, `cmake`, `go`, `cargo`
938
+ - Shell: `sh`, `bash`, `echo`, `cat`, `ls`, `pwd`, `env`
939
+ - Database: `psql`, `mysql`, `mongosh`
940
+
941
+ **Error Handling:**
942
+ - 400 Validation Error: Command not in allowlist or dangerous pattern detected
943
+ - 408 Timeout: Command exceeded timeout limit (default: 30s, max: 300s)
944
+ - 429 Rate Limit: Too many exec requests (30 per 5 minutes)
945
+ - 503 Container Not Running: Application container is not active
946
+ - 500 Execution Failed: Container error or daemon issue
947
+
948
+ **Example Output:**
949
+ ```bash
950
+ $ saac exec "echo 'Hello from container!'"
951
+
952
+ Executing Command: myapp
953
+ ──────────────────────────
954
+
955
+ Command: echo 'Hello from container!'
956
+ Working Directory: /app
957
+ Timeout: 30s
958
+
959
+ ✓ Command executed
960
+
961
+ ✓ Execution ID: eb41b197-e215-4f9e-87ac-80ce57e732a6
962
+
963
+ Exit Code: 0
964
+ Duration: 3531ms
965
+ Started: 1/28/2026, 8:55:37 PM
966
+ Completed: 1/28/2026, 8:55:41 PM
967
+
968
+ Standard Output:
969
+ ────────────────────────────────────────────────────────────
970
+ Hello from container!
971
+ ────────────────────────────────────────────────────────────
972
+ ```
973
+
974
+ **History Command:**
975
+ ```bash
976
+ $ saac exec --history
977
+
978
+ Execution History: myapp
979
+ ────────────────────────
980
+
981
+ ╔══════════╤═══════════╤═════════════╤═══════════╤══════════╤═══════════════╗
982
+ ║ ID │ Command │ Status │ Exit Code │ Duration │ Started ║
983
+ ╠══════════╪═══════════╪═════════════╪═══════════╪══════════╪═══════════════╣
984
+ ║ eb41b197 │ echo '...'│ ✓ completed │ 0 │ 0s │ 1/28/26, 8:55 ║
985
+ ║ a3f2c891 │ npm run...│ ✗ completed │ 1 │ 5s │ 1/28/26, 8:50 ║
986
+ ╚══════════╧═══════════╧═════════════╧═══════════╧══════════╧═══════════════╝
987
+
988
+ Showing 2 of 5 executions
989
+ ```
990
+
991
+ **Location:** `src/commands/exec.js`
992
+
993
+ **Backend Implementation:**
994
+ - Database table: `exec_requests` (status: pending → running → completed/failed/timeout)
995
+ - Python daemon: `/root/exec-daemon/exec_daemon.py` (polls every 2 seconds)
996
+ - Systemd service: `exec-daemon.service` (auto-restart, logs to `/var/log/exec-daemon.log`)
997
+
998
+ ---
999
+
1000
+ **Backend Requirements (Implemented):**
1001
+ - `GET /api/v1/applications/:uuid/env/export` - Export endpoint (deployed 2026-01-28)
1002
+ - Returns: `environment` (object), `export_script` (bash format), `dotenv_format` (dotenv format)
1003
+ - Rate limit: 10 requests/minute per user
1004
+ - Authentication: X-Session-Token or X-API-Key
1005
+ - Response includes `expires_in: 300` (5-minute cache recommendation)
1006
+ - `POST /api/v1/applications/:uuid/exec` - Execute command in container (deployed 2026-01-28)
1007
+ - `GET /api/v1/applications/:uuid/exec/history` - View execution history (deployed 2026-01-28)
1008
+ - Rate limit: 30 requests per 5 minutes per user
555
1009
 
556
1010
  **Implementation Pattern for New Commands:**
557
1011
  1. Require flags, no interactive prompts (exception: `init` uses inquirer for app selection)
@@ -560,15 +1014,6 @@ Several commands still need implementation:
560
1014
  4. Use spinners for async operations
561
1015
  5. Handle errors with descriptive messages
562
1016
 
563
- **Example Module Structure for env.js:**
564
- ```javascript
565
- async function set(vars) { /* implementation */ }
566
- async function get(key) { /* implementation */ }
567
- async function list() { /* implementation */ }
568
-
569
- module.exports = { set, get, list };
570
- ```
571
-
572
1017
  ### MailHog Integration
573
1018
 
574
1019
  The system uses MailHog for email verification in development:
@@ -588,7 +1033,7 @@ The wrapper API expects Git repositories to be hosted on the StartAnAiCompany Gi
588
1033
  - During registration, Gitea username can be auto-detected or manually provided
589
1034
  - Applications reference repositories in the format: `git@git.startanaicompany.com:user/repo.git`
590
1035
 
591
- ## Current Status - Version 1.4.16
1036
+ ## Current Status - Version 1.6.0
592
1037
 
593
1038
  ### Completed Features
594
1039
 
@@ -619,17 +1064,28 @@ The wrapper API expects Git repositories to be hosted on the StartAnAiCompany Gi
619
1064
  - ✅ `saac update` - Update application configuration (PATCH endpoint)
620
1065
  - ✅ `saac init` - Link existing application to current directory (interactive)
621
1066
  - ✅ `saac deploy` - Trigger deployment for current application
1067
+ - ✅ `saac deployments` - List deployment history with table display
1068
+ - ✅ `saac logs` - View deployment logs (build logs) or runtime logs (container logs)
622
1069
  - ✅ `saac list` - List all applications with table display
623
1070
  - ✅ `saac status` - Show login status, user info, and applications
1071
+ - ✅ `saac delete` - Delete application with confirmation prompt
1072
+ - ✅ `saac whoami` - Show current user information
1073
+
1074
+ **Environment & Domain Management:**
1075
+ - ✅ `saac env set/get/list` - Manage environment variables (fully implemented)
1076
+ - ✅ `saac domain set/show` - Manage application domain (fully implemented)
1077
+
1078
+ **Local Development (NEW in 1.5.0):**
1079
+ - ✅ `saac run <command>` - Execute local command with remote environment variables
1080
+ - ✅ `saac shell` - Open interactive shell with remote environment variables
1081
+ - Features: 5-minute caching, secure temp files (0600), automatic cleanup, rate limit handling
1082
+
1083
+ **Remote Execution (NEW in 1.6.0):**
1084
+ - ✅ `saac exec <command>` - Execute commands in remote container
1085
+ - ✅ `saac exec --history` - View execution history
1086
+ - Features: Command allowlist, dangerous pattern detection, rate limiting (30/5min), audit logging
624
1087
 
625
- **Incomplete Commands:**
626
- - ⏳ `saac logs` - Not implemented (stub only)
627
- - ⏳ `saac env` - Not implemented (stub only, needs to export object with set/get/list methods)
628
- - ⏳ `saac domain` - Not implemented (stub only, needs to export object with set/show methods)
629
- - ⏳ `saac delete` - Not implemented (stub only)
630
- - ⏳ `saac whoami` - Not implemented (stub only)
631
- - ✅ `saac deploy` - Fully implemented
632
- - ✅ `saac list` - Fully implemented
1088
+ **All Commands Implemented!** ✅ No incomplete commands remain
633
1089
 
634
1090
  ### Critical Learnings & Bug Fixes
635
1091
 
@@ -671,7 +1127,7 @@ The wrapper API expects Git repositories to be hosted on the StartAnAiCompany Gi
671
1127
 
672
1128
  ### API Endpoint Reference
673
1129
 
674
- **Correct Endpoint Paths (v1.4.12):**
1130
+ **Correct Endpoint Paths (v1.5.0):**
675
1131
  - `POST /api/v1/users/register` - Register (email only, git_username optional)
676
1132
  - `POST /api/v1/users/verify` - Verify email with code
677
1133
  - `POST /api/v1/auth/login` - Login with API key, get session token
@@ -687,7 +1143,10 @@ The wrapper API expects Git repositories to be hosted on the StartAnAiCompany Gi
687
1143
  - `GET /api/v1/applications` - List applications
688
1144
  - `PATCH /api/v1/applications/:uuid` - Update application
689
1145
  - `POST /api/v1/applications/:uuid/deploy` - Deploy application
690
- - `GET /api/v1/applications/:uuid/logs` - Get logs
1146
+ - `GET /api/v1/applications/:uuid/deployments` - Get deployment history (NEW in 1.4.17)
1147
+ - `GET /api/v1/applications/:uuid/deployment-logs` - Get deployment logs (NEW in 1.4.17)
1148
+ - `GET /api/v1/applications/:uuid/logs` - Get runtime logs (container logs)
1149
+ - `GET /api/v1/applications/:uuid/env/export` - Export environment variables (NEW in 1.5.0)
691
1150
  - `DELETE /api/v1/applications/:uuid` - Delete application
692
1151
 
693
1152
  **Important:** OAuth endpoints (`/oauth/*`) do NOT have the `/api/v1` prefix!
@@ -808,4 +1267,4 @@ Before publishing to npm:
808
1267
  - `dotenv` - Environment variables
809
1268
  - `open` - Open browser for OAuth (v8.4.2 for compatibility with chalk v4)
810
1269
 
811
- **Version:** 1.4.16 (current)
1270
+ **Version:** 1.5.0 (current)
package/bin/saac.js CHANGED
@@ -22,6 +22,7 @@ const init = require('../src/commands/init');
22
22
  const create = require('../src/commands/create');
23
23
  const update = require('../src/commands/update');
24
24
  const deploy = require('../src/commands/deploy');
25
+ const deployments = require('../src/commands/deployments');
25
26
  const logs = require('../src/commands/logs');
26
27
  const env = require('../src/commands/env');
27
28
  const domain = require('../src/commands/domain');
@@ -30,6 +31,9 @@ const list = require('../src/commands/list');
30
31
  const status = require('../src/commands/status');
31
32
  const whoami = require('../src/commands/whoami');
32
33
  const manual = require('../src/commands/manual');
34
+ const run = require('../src/commands/run');
35
+ const shell = require('../src/commands/shell');
36
+ const execCmd = require('../src/commands/exec');
33
37
 
34
38
  // Configure CLI
35
39
  program
@@ -200,12 +204,62 @@ program
200
204
  .action(deploy);
201
205
 
202
206
  program
203
- .command('logs')
204
- .description('View application logs')
205
- .option('-t, --tail <lines>', 'Number of lines to show', '100')
206
- .option('-f, --follow', 'Follow log output')
207
+ .command('deployments')
208
+ .alias('deploys')
209
+ .description('List deployment history')
210
+ .option('-l, --limit <number>', 'Number of deployments to show', '20')
211
+ .option('-o, --offset <number>', 'Offset for pagination', '0')
212
+ .action(deployments);
213
+
214
+ program
215
+ .command('logs [deploymentUuid]')
216
+ .description('View application logs (runtime or deployment logs)')
217
+ .option('-d, --deployment [uuid]', 'View deployment logs (build logs)')
218
+ .option('--raw', 'Show raw log output (deployment logs only)')
219
+ .option('--include-hidden', 'Include hidden log lines (deployment logs only)')
220
+ .option('-t, --tail <lines>', 'Number of lines to show (runtime logs only)', '100')
221
+ .option('-f, --follow', 'Follow log output (runtime logs only)')
222
+ .option('--since <time>', 'Show logs since timestamp (runtime logs only)')
207
223
  .action(logs);
208
224
 
225
+ // Local development commands
226
+ program
227
+ .command('run <command>')
228
+ .description('Run local command with remote environment variables')
229
+ .option('--sync', 'Force refresh environment variables (skip cache)')
230
+ .option('-q, --quiet', 'Quiet mode (suppress warnings)')
231
+ .action(run);
232
+
233
+ program
234
+ .command('shell')
235
+ .description('Open interactive shell with remote environment variables')
236
+ .option('--cmd <shell>', 'Shell to use (default: $SHELL or /bin/bash)')
237
+ .option('--sync', 'Force refresh environment variables (skip cache)')
238
+ .action(shell);
239
+
240
+ // Remote execution commands
241
+ program
242
+ .command('exec [command]')
243
+ .description('Execute command in remote container')
244
+ .option('--workdir <path>', 'Working directory (default: /app)')
245
+ .option('--timeout <seconds>', 'Timeout in seconds (default: 30, max: 300)', '30')
246
+ .option('--history', 'View execution history')
247
+ .option('--limit <number>', 'Limit for history (default: 20, max: 100)', '20')
248
+ .option('--offset <number>', 'Offset for history pagination (default: 0)', '0')
249
+ .action((command, options) => {
250
+ if (options.history) {
251
+ execCmd.history(options);
252
+ } else if (command) {
253
+ execCmd.exec(command, options);
254
+ } else {
255
+ console.error('Error: command is required (unless using --history)');
256
+ console.log('\nUsage:');
257
+ console.log(' saac exec <command> Execute command');
258
+ console.log(' saac exec --history View execution history');
259
+ process.exit(1);
260
+ }
261
+ });
262
+
209
263
  // Environment variable commands
210
264
  const envCommand = program
211
265
  .command('env')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startanaicompany/cli",
3
- "version": "1.4.16",
3
+ "version": "1.4.18",
4
4
  "description": "Official CLI for StartAnAiCompany.com - Deploy AI recruitment sites with ease",
5
5
  "main": "src/index.js",
6
6
  "bin": {