@icarusmx/creta 1.5.12 → 1.5.14

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 (27) hide show
  1. package/bin/creta.js +31 -1
  2. package/lib/data/command-help/aws-ec2.js +34 -0
  3. package/lib/data/command-help/grep.js +76 -0
  4. package/lib/data/command-help/index.js +11 -1
  5. package/lib/data/command-help/lz.js +57 -0
  6. package/lib/executors/CommandHelpExecutor.js +6 -1
  7. package/lib/exercises/.claude/settings.local.json +12 -0
  8. package/lib/exercises/01-developing-muscle-for-nvim.md +528 -0
  9. package/lib/exercises/{iterm2-pane-navigation.md → 02-iterm2-pane-navigation.md} +1 -1
  10. package/lib/exercises/05-svelte-first-steps.md +1340 -0
  11. package/lib/exercises/{curl-and-pipes.md → 06-curl-and-pipes.md} +187 -72
  12. package/lib/exercises/07-claude-api-first-steps.md +855 -0
  13. package/lib/exercises/08-playwright-svelte-guide.md +1384 -0
  14. package/lib/exercises/09-docker-first-steps.md +1475 -0
  15. package/lib/exercises/{railway-deployment.md → 10-railway-deployment.md} +1 -0
  16. package/lib/exercises/{aws-billing-detective.md → 11-aws-billing-detective.md} +215 -35
  17. package/lib/exercises/12-install-skills.md +755 -0
  18. package/lib/exercises/13-shell-aliases.md +134 -0
  19. package/lib/exercises/README.md +187 -0
  20. package/lib/exercises/utils/booklet-2up.js +133 -0
  21. package/lib/exercises/utils/booklet-manual-duplex.js +159 -0
  22. package/lib/exercises/utils/booklet-simple.js +136 -0
  23. package/lib/exercises/utils/create-booklet.js +116 -0
  24. package/lib/scripts/aws-ec2-all.sh +58 -0
  25. package/package.json +3 -2
  26. /package/lib/exercises/{git-stash-workflow.md → 03-git-stash-workflow.md} +0 -0
  27. /package/lib/exercises/{array-object-manipulation.md → 04-array-object-manipulation.md} +0 -0
@@ -10,6 +10,45 @@ This document uses fold markers `{{{` and `}}}` for organized reading.
10
10
 
11
11
  }}}
12
12
 
13
+ ## 📜 What is curl? {{{
14
+
15
+ **curl** stands for "Client URL" - a command-line tool for transferring data with URLs.
16
+
17
+ **Created:** 1997 by Daniel Stenberg (Swedish developer)
18
+ **Original purpose:** Transfer files over networks without GUI
19
+ **Today's use:** The universal tool for testing APIs, downloading files, and debugging HTTP requests
20
+
21
+ **Why curl won:**
22
+ - Pre-installed on macOS, Linux, and Windows 10+
23
+ - Supports HTTP, HTTPS, FTP, and 20+ protocols
24
+ - Scriptable, pipe-friendly, and lightweight
25
+ - Used by millions of developers daily
26
+
27
+ **Fun fact:** curl powers more devices than you think - from smart cars to Mars rovers to your terminal.
28
+
29
+ }}}
30
+
31
+ ## 🔑 Essential curl Flags (Quick Overview) {{{
32
+
33
+ Before diving into real-world scenarios, here are the flags you'll use 90% of the time:
34
+
35
+ | Flag | Purpose | Example |
36
+ |------|---------|---------|
37
+ | `-s` | Silent (no progress bar) | `curl -s https://api.github.com` |
38
+ | `-L` | Follow redirects | `curl -sL https://icarus.mx/creta` |
39
+ | `-i` | Include HTTP headers | `curl -si https://api.github.com` |
40
+ | `-H` | Add custom header | `curl -H "Authorization: Bearer $TOKEN"` |
41
+ | `-w` | Custom output format | `curl -s -w "%{http_code}"` |
42
+
43
+ **Pattern you'll see everywhere:**
44
+ ```bash
45
+ curl -sL [URL] | grep [pattern]
46
+ ```
47
+
48
+ **Translation:** "Silently fetch this URL, follow redirects, and filter the output."
49
+
50
+ }}}
51
+
13
52
  ## 🚨 Problem: Need Quick API Insights Without Postman {{{
14
53
 
15
54
  You're debugging an API and need to:
@@ -42,8 +81,8 @@ curl [API] | [filter] | [process] | [output]
42
81
 
43
82
  **Real example:**
44
83
  ```bash
45
- # Count active users in one line
46
- curl -s https://api.example.com/users | grep "active" | wc -l
84
+ # Count lines in Creta README
85
+ curl -sL https://icarus.mx/creta/README.md | wc -l
47
86
  ```
48
87
 
49
88
  **Benefits:**
@@ -92,19 +131,19 @@ curl -si https://api.github.com/users/fake123 | head -n 1
92
131
 
93
132
  ### -L (Follow Redirects) {{{
94
133
 
95
- **Problem:** Short URLs redirect, curl doesn't follow by default
134
+ **Problem:** URLs redirect, curl doesn't follow by default
96
135
 
97
136
  ```bash
98
137
  # Without -L (stops at redirect)
99
- curl -s https://bit.ly/example
100
- # <redirect HTML>
138
+ curl -s https://icarus.mx/creta/README.md
139
+ # <HTML redirect page>
101
140
 
102
141
  # With -L (follows to final destination)
103
- curl -sL https://bit.ly/example
104
- # <actual content>
142
+ curl -sL https://icarus.mx/creta/README.md
143
+ # # Creta - Tu Compañero de Terminal...
105
144
  ```
106
145
 
107
- **Use:** Essential for shortened URLs, CDN redirects, HTTPS upgrades.
146
+ **Use:** Essential for CDN redirects, HTTPS upgrades, URL shorteners.
108
147
 
109
148
  }}}
110
149
 
@@ -114,16 +153,16 @@ curl -sL https://bit.ly/example
114
153
 
115
154
  ```bash
116
155
  # Add authorization header
117
- curl -s -H "Authorization: Bearer $TOKEN" https://api.example.com/protected
156
+ curl -s -H "Authorization: Bearer $TOKEN" https://api.icarus.mx/admin/students
118
157
 
119
158
  # Specify JSON content type
120
- curl -s -H "Content-Type: application/json" https://api.example.com/data
159
+ curl -s -H "Content-Type: application/json" https://api.icarus.mx/config
121
160
 
122
161
  # Multiple headers
123
162
  curl -s \
124
163
  -H "Authorization: Bearer $TOKEN" \
125
164
  -H "Accept: application/json" \
126
- https://api.example.com/users
165
+ https://api.icarus.mx/students
127
166
  ```
128
167
 
129
168
  }}}
@@ -294,10 +333,10 @@ curl -s https://jsonplaceholder.typicode.com/posts | grep "userId" | sort | uniq
294
333
 
295
334
  ```bash
296
335
  # Check status code
297
- curl -s -w "%{http_code}" -o /dev/null https://api.myapp.com/health
336
+ curl -s -w "%{http_code}" -o /dev/null https://api.icarus.mx/health
298
337
 
299
338
  # One-liner health check
300
- if [ $(curl -s -w "%{http_code}" -o /dev/null https://api.myapp.com/health) -eq 200 ]; then
339
+ if [ $(curl -s -w "%{http_code}" -o /dev/null https://api.icarus.mx/health) -eq 200 ]; then
301
340
  echo "✅ API is healthy"
302
341
  else
303
342
  echo "❌ API is down"
@@ -314,13 +353,13 @@ fi
314
353
 
315
354
  ```bash
316
355
  # Count ERROR lines in logs API
317
- curl -s https://logs.myapp.com/last-hour | grep "ERROR" | wc -l
356
+ curl -s https://logs.icarus.mx/last-hour | grep "ERROR" | wc -l
318
357
 
319
358
  # Find critical errors only
320
- curl -s https://logs.myapp.com/last-hour | grep "CRITICAL" | wc -l
359
+ curl -s https://logs.icarus.mx/last-hour | grep "CRITICAL" | wc -l
321
360
 
322
361
  # Group by error type
323
- curl -s https://logs.myapp.com/last-hour | grep "ERROR" | cut -d':' -f2 | sort | uniq -c
362
+ curl -s https://logs.icarus.mx/last-hour | grep "ERROR" | cut -d':' -f2 | sort | uniq -c
324
363
  ```
325
364
 
326
365
  **Use case:** Incident response, debugging production issues.
@@ -333,14 +372,14 @@ curl -s https://logs.myapp.com/last-hour | grep "ERROR" | cut -d':' -f2 | sort |
333
372
 
334
373
  ```bash
335
374
  # Test: Does response contain expected field?
336
- curl -s https://api.myapp.com/config | grep -q "version" && echo "✅ Pass" || echo "❌ Fail"
375
+ curl -s https://api.icarus.mx/config | grep -q "version" && echo "✅ Pass" || echo "❌ Fail"
337
376
 
338
- # Test: Is there at least one user?
339
- USER_COUNT=$(curl -s https://api.myapp.com/users | grep "\"id\":" | wc -l)
340
- if [ $USER_COUNT -gt 0 ]; then
341
- echo "✅ Users endpoint working"
377
+ # Test: Is there at least one student?
378
+ STUDENT_COUNT=$(curl -s https://api.icarus.mx/students | grep "\"id\":" | wc -l)
379
+ if [ $STUDENT_COUNT -gt 0 ]; then
380
+ echo "✅ Students endpoint working"
342
381
  else
343
- echo "❌ No users returned"
382
+ echo "❌ No students returned"
344
383
  fi
345
384
  ```
346
385
 
@@ -353,18 +392,18 @@ fi
353
392
  **Problem:** Download API data, filter active records, save to file
354
393
 
355
394
  ```bash
356
- # Extract active users to file
357
- curl -s https://api.myapp.com/users | grep "\"status\": \"active\"" > active-users.json
395
+ # Extract active students to file
396
+ curl -s https://api.icarus.mx/students | grep "\"status\": \"active\"" > active-students.json
358
397
 
359
- # Extract and count
360
- curl -s https://api.myapp.com/orders | grep "\"status\": \"pending\"" | wc -l > pending-orders.txt
398
+ # Extract and count pending submissions
399
+ curl -s https://api.icarus.mx/submissions | grep "\"status\": \"pending\"" | wc -l > pending-submissions.txt
361
400
 
362
- # Multi-step pipeline
363
- curl -s https://api.github.com/users/github/repos \
401
+ # Multi-step pipeline: Get all lesson names
402
+ curl -s https://api.icarus.mx/lessons \
364
403
  | grep "\"name\":" \
365
404
  | sed 's/.*"name": "\(.*\)".*/\1/' \
366
405
  | sort \
367
- > repo-names.txt
406
+ > lesson-names.txt
368
407
  ```
369
408
 
370
409
  **Use case:** ETL jobs, data exports, scheduled reports.
@@ -398,10 +437,10 @@ curl -si https://api.github.com/users/github \
398
437
 
399
438
  ```bash
400
439
  # Get response from v1
401
- curl -s https://api.myapp.com/v1/users > v1-response.json
440
+ curl -s https://api.icarus.mx/v1/students > v1-response.json
402
441
 
403
442
  # Get response from v2
404
- curl -s https://api.myapp.com/v2/users > v2-response.json
443
+ curl -s https://api.icarus.mx/v2/students > v2-response.json
405
444
 
406
445
  # Compare
407
446
  diff v1-response.json v2-response.json
@@ -519,10 +558,10 @@ curl -s https://jsonplaceholder.typicode.com/users \
519
558
 
520
559
  ```bash
521
560
  # ❌ Bad: progress bar interferes with grep
522
- curl https://api.example.com | grep "name"
561
+ curl https://api.icarus.mx/students | grep "name"
523
562
 
524
563
  # ✅ Good: clean output
525
- curl -s https://api.example.com | grep "name"
564
+ curl -s https://api.icarus.mx/students | grep "name"
526
565
  ```
527
566
 
528
567
  }}}
@@ -533,10 +572,10 @@ curl -s https://api.example.com | grep "name"
533
572
 
534
573
  ```bash
535
574
  # ❌ Bad: processes error HTML as JSON
536
- curl -s https://api.example.com/fake | grep "name"
575
+ curl -s https://api.icarus.mx/fake | grep "name"
537
576
 
538
577
  # ✅ Good: check status first
539
- RESPONSE=$(curl -s -w "\n%{http_code}" https://api.example.com/users)
578
+ RESPONSE=$(curl -s -w "\n%{http_code}" https://api.icarus.mx/students)
540
579
  STATUS=$(echo "$RESPONSE" | tail -n 1)
541
580
  BODY=$(echo "$RESPONSE" | head -n -1)
542
581
 
@@ -556,13 +595,13 @@ fi
556
595
 
557
596
  ```bash
558
597
  # Pipes: Quick field search
559
- curl -s https://api.example.com/users | grep "email"
598
+ curl -s https://api.icarus.mx/students | grep "email"
560
599
 
561
600
  # jq: Proper JSON parsing
562
- curl -s https://api.example.com/users | jq '.[].email'
601
+ curl -s https://api.icarus.mx/students | jq '.[].email'
563
602
 
564
603
  # jq: Complex queries
565
- curl -s https://api.example.com/users | jq '.[] | select(.id > 5) | .name'
604
+ curl -s https://api.icarus.mx/students | jq '.[] | select(.id > 5) | .name'
566
605
  ```
567
606
 
568
607
  **Rule of thumb:** If you need more than 2-3 greps/seds, switch to jq.
@@ -575,15 +614,15 @@ curl -s https://api.example.com/users | jq '.[] | select(.id > 5) | .name'
575
614
 
576
615
  ```bash
577
616
  # ❌ Bad: hits API every time you test
578
- curl -s https://api.example.com/users | grep "name"
579
- curl -s https://api.example.com/users | grep "email"
580
- curl -s https://api.example.com/users | grep "phone"
617
+ curl -s https://api.icarus.mx/students | grep "name"
618
+ curl -s https://api.icarus.mx/students | grep "email"
619
+ curl -s https://api.icarus.mx/students | grep "phone"
581
620
 
582
621
  # ✅ Good: save once, test multiple times
583
- curl -s https://api.example.com/users > users.json
584
- cat users.json | grep "name"
585
- cat users.json | grep "email"
586
- cat users.json | grep "phone"
622
+ curl -s https://api.icarus.mx/students > students.json
623
+ cat students.json | grep "name"
624
+ cat students.json | grep "email"
625
+ cat students.json | grep "phone"
587
626
  ```
588
627
 
589
628
  }}}
@@ -594,7 +633,7 @@ cat users.json | grep "phone"
594
633
 
595
634
  ```bash
596
635
  # Store response
597
- RESPONSE=$(curl -s https://api.example.com/users)
636
+ RESPONSE=$(curl -s https://api.icarus.mx/students)
598
637
 
599
638
  # Check if empty
600
639
  if [ -z "$RESPONSE" ]; then
@@ -614,10 +653,10 @@ echo "$RESPONSE" | grep "name"
614
653
 
615
654
  ```bash
616
655
  # Default: waits forever
617
- curl -s https://slow-api.example.com
656
+ curl -s https://api.icarus.mx/analytics
618
657
 
619
658
  # With timeout: fails after 10 seconds
620
- curl -s --max-time 10 https://slow-api.example.com
659
+ curl -s --max-time 10 https://api.icarus.mx/analytics
621
660
  ```
622
661
 
623
662
  }}}
@@ -677,19 +716,19 @@ curl -s URL | grep "active" > output.txt
677
716
 
678
717
  ```bash
679
718
  # Health check
680
- curl -s -w "%{http_code}" -o /dev/null https://api.example.com/health
719
+ curl -s -w "%{http_code}" -o /dev/null https://api.icarus.mx/health
681
720
 
682
721
  # Count records
683
- curl -s https://api.example.com/users | grep "\"id\":" | wc -l
722
+ curl -s https://api.icarus.mx/students | grep "\"id\":" | wc -l
684
723
 
685
724
  # Extract field
686
- curl -s https://api.example.com/config | grep "version" | sed 's/.*"version": "\(.*\)".*/\1/'
725
+ curl -s https://api.icarus.mx/config | grep "version" | sed 's/.*"version": "\(.*\)".*/\1/'
687
726
 
688
727
  # Monitor errors
689
- curl -s https://logs.example.com/today | grep "ERROR" | wc -l
728
+ curl -s https://logs.icarus.mx/today | grep "ERROR" | wc -l
690
729
 
691
730
  # Test endpoint
692
- curl -s https://api.example.com/users | grep -q "data" && echo "OK" || echo "FAIL"
731
+ curl -s https://api.icarus.mx/students | grep -q "data" && echo "OK" || echo "FAIL"
693
732
  ```
694
733
 
695
734
  }}}
@@ -721,7 +760,7 @@ echo -e "api.service1.com\napi.service2.com\napi.service3.com" \
721
760
 
722
761
  ```bash
723
762
  # Stream large response
724
- curl -s https://api.example.com/large-dataset \
763
+ curl -s https://api.icarus.mx/analytics \
725
764
  | while IFS= read -r line; do
726
765
  echo "$line" | grep "active" >> active-records.txt
727
766
  done
@@ -733,28 +772,104 @@ curl -s https://api.example.com/large-dataset \
733
772
 
734
773
  ### Authenticated API Requests {{{
735
774
 
736
- **JWT token example:**
775
+ **Progressive security: unsafe → safe → production**
776
+
777
+ #### 🚨 Level 0: Hardcoded (NEVER do this)
778
+
779
+ ```bash
780
+ # ❌ DANGER: JWT visible in shell history
781
+ curl -s -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" \
782
+ https://api.icarus.mx/admin/students | grep "data"
783
+
784
+ # Verify the problem: token saved forever
785
+ history | tail -n 2
786
+ # 482 curl -s -H "Authorization: Bearer eyJhbGci...
787
+ ```
788
+
789
+ **Why dangerous:**
790
+ - Stored in `~/.bash_history` forever
791
+ - Visible in `ps aux` while running
792
+ - Accidentally committed to git
793
+ - Leaked in screenshots/demos
794
+
795
+ #### ✅ Level 1: Environment Variable (Basic safety)
737
796
 
738
797
  ```bash
739
- # Store token
740
- TOKEN="your-jwt-token-here"
798
+ # Store JWT in variable (not in command)
799
+ TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U"
741
800
 
742
- # Authenticated request
801
+ # Use variable (history only shows $TOKEN)
743
802
  curl -s -H "Authorization: Bearer $TOKEN" \
744
- https://api.example.com/protected \
745
- | grep "data"
803
+ https://api.icarus.mx/admin/students | grep "data"
804
+
805
+ # Check history - no JWT visible!
806
+ history | tail -n 1
807
+ # 483 curl -s -H "Authorization: Bearer $TOKEN" ...
746
808
  ```
747
809
 
748
- **Environment variable:**
810
+ **Better, but:** Token still in memory during session.
811
+
812
+ #### ✅ Level 2: .env File (Recommended for scripts)
749
813
 
750
814
  ```bash
751
- # In .env or .bashrc
752
- export API_TOKEN="your-token"
815
+ # Create .env file (add to .gitignore!)
816
+ cat > .env <<'EOF'
817
+ ICARUS_JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U
818
+ EOF
819
+
820
+ # Protect .env and ensure it's ignored
821
+ chmod 600 .env
822
+ echo '.env' >> .gitignore
823
+
824
+ # Source environment
825
+ source .env
753
826
 
754
- # In script
755
- curl -s -H "Authorization: Bearer $API_TOKEN" https://api.example.com/protected
827
+ # Use safely
828
+ curl -s -H "Authorization: Bearer $ICARUS_JWT" \
829
+ https://api.icarus.mx/admin/students | grep "data"
756
830
  ```
757
831
 
832
+ **Best practice:** Never commit .env to version control.
833
+
834
+ #### ✅ Level 3: Secure File Read (No environment variables)
835
+
836
+ ```bash
837
+ # Store JWT in protected file
838
+ echo 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U' > ~/.icarus-jwt
839
+ chmod 600 ~/.icarus-jwt # Only you can read
840
+
841
+ # Read directly in subshell (never enters environment)
842
+ curl -s -H "Authorization: Bearer $(cat ~/.icarus-jwt)" \
843
+ https://api.icarus.mx/admin/students | grep "data"
844
+
845
+ # Verify: no JWT in environment
846
+ env | grep -i jwt
847
+ # (empty - JWT never loaded into environment)
848
+ ```
849
+
850
+ **Advantage:** Token never enters shell environment.
851
+
852
+ #### 🔒 Level 4: Production (Keychain/Secret Manager)
853
+
854
+ ```bash
855
+ # macOS Keychain
856
+ security add-generic-password -a "$USER" -s icarus-jwt -w "eyJhbGci..."
857
+ JWT=$(security find-generic-password -a "$USER" -s icarus-jwt -w)
858
+ curl -s -H "Authorization: Bearer $JWT" https://api.icarus.mx/admin/students
859
+
860
+ # Linux pass (password-store)
861
+ pass insert icarus/jwt
862
+ JWT=$(pass show icarus/jwt)
863
+ curl -s -H "Authorization: Bearer $JWT" https://api.icarus.mx/admin/students
864
+
865
+ # GitHub Actions / CI/CD
866
+ # Use encrypted secrets, never hardcode
867
+ curl -s -H "Authorization: Bearer ${{ secrets.ICARUS_JWT }}" \
868
+ https://api.icarus.mx/admin/students
869
+ ```
870
+
871
+ **Production rule:** If you can see your JWT in `history` or `env`, you did it wrong.
872
+
758
873
  }}}
759
874
 
760
875
  ### POST Requests with Data {{{
@@ -788,34 +903,34 @@ curl -s -X POST \
788
903
 
789
904
  1. **Combine with watch for live monitoring:**
790
905
  ```bash
791
- watch -n 5 'curl -s https://api.example.com/metrics | grep "active" | wc -l'
906
+ watch -n 5 'curl -s https://api.icarus.mx/metrics | grep "active" | wc -l'
792
907
  ```
793
908
 
794
909
  2. **Save complex one-liners as shell functions:**
795
910
  ```bash
796
911
  # In .bashrc or .zshrc
797
912
  api_health() {
798
- curl -s -w "%{http_code}" -o /dev/null "https://api.example.com/$1"
913
+ curl -s -w "%{http_code}" -o /dev/null "https://api.icarus.mx/$1"
799
914
  }
800
915
 
801
916
  # Usage
802
- api_health users # Check /users endpoint
917
+ api_health students # Check /students endpoint
803
918
  ```
804
919
 
805
920
  3. **Use aliases for frequent API checks:**
806
921
  ```bash
807
- alias check-api='curl -s https://api.myapp.com/health | grep "ok"'
922
+ alias check-api='curl -s https://api.icarus.mx/health | grep "ok"'
808
923
  ```
809
924
 
810
925
  4. **Pipe to pbcopy (Mac) or xclip (Linux) to copy output:**
811
926
  ```bash
812
- curl -s https://api.example.com/users | grep "email" | pbcopy
927
+ curl -sL https://icarus.mx/creta/README.md | pbcopy
813
928
  ```
814
929
 
815
930
  5. **Chain with git for API version tracking:**
816
931
  ```bash
817
- curl -s https://api.example.com/schema > schema.json
818
- git diff schema.json # See what changed
932
+ curl -s https://api.icarus.mx/config > config.json
933
+ git diff config.json # See what changed
819
934
  ```
820
935
 
821
936
  }}}