@icarusmx/creta 1.5.10 → 1.5.11

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/bin/creta.js CHANGED
@@ -78,8 +78,9 @@ if (command && isCommandHelpRequest(args)) {
78
78
  process.exit(0)
79
79
  }
80
80
 
81
- // ASCII Logo
82
- console.log(`
81
+ // Show logo for interactive commands (skip for utility commands)
82
+ function showLogo() {
83
+ console.log(`
83
84
  █████████████████████████
84
85
  █ █ █ █ █ █ █
85
86
  █ C █ R █ E █ T █ A █ █ █
@@ -89,16 +90,19 @@ console.log(`
89
90
  Bienvenido al taller de software
90
91
  Salgamos de este laberinto 🏛️
91
92
  `)
93
+ }
92
94
 
93
95
  if (!command) {
94
96
  // Default behavior: show main menu
97
+ showLogo()
95
98
  await startMainMenu()
96
99
  process.exit(0)
97
100
  }
98
101
 
99
102
  if (command.startsWith('portafolio')) {
103
+ showLogo()
100
104
  const level = command === 'portafolio' ? 0 : parseInt(command.split('-')[1]) || 0
101
-
105
+
102
106
  // Check if we're in an existing Creta project
103
107
  if (level > 0 && isInCretaProject()) {
104
108
  await unstuckProject(level)
@@ -106,20 +110,25 @@ if (command.startsWith('portafolio')) {
106
110
  await createPortfolioProject(level)
107
111
  }
108
112
  } else if (command === 'enunciados') {
113
+ showLogo()
109
114
  // Start enunciados selector
110
115
  await startEnunciadosSelector()
111
116
  } else if (command === 'sintaxis') {
117
+ showLogo()
112
118
  // Start sintaxis selector with interactive sandbox lessons
113
119
  await startSintaxisSelector()
114
120
  } else if (command === 'code') {
121
+ showLogo()
115
122
  // Start interactive coding session
116
123
  const session = new CretaCodeSession()
117
124
  await session.start()
118
125
  } else if (command === 'papers') {
126
+ showLogo()
119
127
  // Start papers selector
120
128
  const executor = new PapersExecutor()
121
129
  await executor.execute()
122
130
  } else if (command === 'aws') {
131
+ showLogo()
123
132
  // Show AWS billing detective guide
124
133
  const viewer = new AWSGuideViewer()
125
134
  await viewer.start()
@@ -637,6 +646,7 @@ function showHelp() {
637
646
  console.log("📖 Documentación de comandos:")
638
647
  console.log(" creta ls - Documentación en español del comando ls")
639
648
  console.log(" creta cd - Documentación en español del comando cd")
649
+ console.log(" creta curl - Documentación en español del comando curl")
640
650
  console.log(" creta git status - Documentación en español de git status")
641
651
  console.log(" creta [comando] - Documentación de cualquier comando soportado\n")
642
652
 
@@ -1858,7 +1868,7 @@ async function startVimSetupTutorial() {
1858
1868
  // Helper function to detect command help requests
1859
1869
  function isCommandHelpRequest(args) {
1860
1870
  // List of supported commands for help
1861
- const basicCommands = ['ls', 'cd', 'mkdir', 'touch', 'wc']
1871
+ const basicCommands = ['ls', 'cd', 'mkdir', 'touch', 'wc', 'curl']
1862
1872
  const gitCommands = ['git status', 'git add', 'git commit', 'git push', 'git log']
1863
1873
 
1864
1874
  const commandString = args.join(' ')
@@ -0,0 +1,80 @@
1
+ export const curl = {
2
+ command: 'curl',
3
+ description: 'Realiza peticiones HTTP desde la terminal - tu herramienta para APIs',
4
+ usage: 'curl [opciones] [URL]',
5
+ commonOptions: [
6
+ {
7
+ flag: '-X',
8
+ description: 'Especifica el método HTTP (GET, POST, PUT, DELETE)'
9
+ },
10
+ {
11
+ flag: '-H',
12
+ description: 'Agrega un header a la petición'
13
+ },
14
+ {
15
+ flag: '-d',
16
+ description: 'Envía datos en el body (JSON, form data, etc.)'
17
+ },
18
+ {
19
+ flag: '-i',
20
+ description: 'Incluye los headers de respuesta en el output'
21
+ },
22
+ {
23
+ flag: '-L',
24
+ description: 'Sigue redirects automáticamente'
25
+ },
26
+ {
27
+ flag: '-o',
28
+ description: 'Guarda el output en un archivo'
29
+ },
30
+ {
31
+ flag: '-s',
32
+ description: 'Modo silencioso (no muestra progreso)'
33
+ },
34
+ {
35
+ flag: '-v',
36
+ description: 'Modo verbose (muestra toda la comunicación)'
37
+ }
38
+ ],
39
+ examples: [
40
+ {
41
+ command: 'curl https://api.github.com',
42
+ description: 'GET simple - obtiene datos de una API'
43
+ },
44
+ {
45
+ command: 'curl -i https://api.github.com/users/octocat',
46
+ description: 'GET con headers de respuesta incluidos'
47
+ },
48
+ {
49
+ command: 'curl -X POST https://api.ejemplo.com/users -H "Content-Type: application/json" -d \'{"nombre": "Juan"}\'',
50
+ description: 'POST con JSON - envía datos a una API'
51
+ },
52
+ {
53
+ command: 'curl -X POST https://httpbin.org/post -d "nombre=Juan&edad=25"',
54
+ description: 'POST con form data - formato URL-encoded'
55
+ },
56
+ {
57
+ command: 'curl -H "Authorization: Bearer tu_token_aqui" https://api.ejemplo.com/protected',
58
+ description: 'GET con autenticación - usa un token JWT'
59
+ },
60
+ {
61
+ command: 'curl -L https://github.com',
62
+ description: 'Sigue redirects automáticamente (importante para URLs acortadas)'
63
+ },
64
+ {
65
+ command: 'curl -o archivo.json https://api.ejemplo.com/data',
66
+ description: 'Descarga la respuesta y guárdala en un archivo'
67
+ },
68
+ {
69
+ command: 'curl -v https://api.ejemplo.com',
70
+ description: 'Modo verbose - ve toda la negociación HTTP (útil para debugging)'
71
+ }
72
+ ],
73
+ relatedLesson: 'APIs y HTTP',
74
+ tips: [
75
+ 'Pro tip: usa -i siempre para ver los status codes (200, 404, 500) en la respuesta',
76
+ 'Para APIs modernas siempre agrega el header: -H "Content-Type: application/json"',
77
+ 'curl -L es esencial cuando trabajas con URLs acortadas o redirects',
78
+ 'Combina -s (silencioso) con herramientas como jq para parsear JSON: curl -s url | jq'
79
+ ]
80
+ }
@@ -4,6 +4,7 @@ export { cd } from './cd.js'
4
4
  export { mkdir } from './mkdir.js'
5
5
  export { touch } from './touch.js'
6
6
  export { wc } from './wc.js'
7
+ export { curl } from './curl.js'
7
8
 
8
9
  // Git commands
9
10
  export { gitStatus } from './git-status.js'
@@ -20,6 +21,7 @@ export const commandMap = {
20
21
  'mkdir': 'mkdir',
21
22
  'touch': 'touch',
22
23
  'wc': 'wc',
24
+ 'curl': 'curl',
23
25
 
24
26
  // Git
25
27
  'git status': 'gitStatus',
@@ -0,0 +1,221 @@
1
+ export const CURL_PIPES = {
2
+ id: 'curl-pipes',
3
+
4
+ intro: {
5
+ definition: 'curl + pipes: Procesando APIs en tiempo real',
6
+ explanation: 'Aprende a combinar curl con pipes para extraer insights de APIs sin guardar archivos intermedios.',
7
+ detail: 'En el mundo real, usarás curl diariamente para consultar APIs, monitorear servicios, y extraer datos. Combinado con pipes (grep, wc, sed), puedes procesar respuestas JSON instantáneamente.'
8
+ },
9
+
10
+ steps: [
11
+ // --- Introducción a curl ---
12
+ {
13
+ type: 'command-intro',
14
+ command: 'curl',
15
+ description: 'curl: Cliente HTTP para la terminal',
16
+ explanation: 'curl descarga datos de URLs sin abrir el navegador. Es la herramienta #1 para trabajar con APIs REST, probar endpoints, y automatizar descargas.',
17
+ example: 'curl https://api.github.com\ncurl -s https://jsonplaceholder.typicode.com/users/1',
18
+ instruction: 'Úsalo para traer datos desde cualquier URL. El flag -s (silent) oculta el progreso.'
19
+ },
20
+
21
+ {
22
+ type: 'text',
23
+ content: '\nVamos a usar JSONPlaceholder, una API REST falsa para practicar.\n\nAPI endpoints disponibles:\n • https://jsonplaceholder.typicode.com/users (lista de 10 usuarios)\n • https://jsonplaceholder.typicode.com/posts (100 posts)\n • https://jsonplaceholder.typicode.com/comments (500 comentarios)\n'
24
+ },
25
+
26
+ { type: 'pause' },
27
+
28
+ // --- Práctica 1: curl básico ---
29
+ {
30
+ type: 'text',
31
+ content: '📝 Práctica 1: Fetch básico con curl\n\nVamos a traer datos de un usuario. El flag -s (silent) oculta la barra de progreso para ver solo el JSON.'
32
+ },
33
+
34
+ {
35
+ type: 'interactive-command',
36
+ prompt: 'Ejecuta: curl -s https://jsonplaceholder.typicode.com/users/1',
37
+ expectedCommand: 'curl -s https://jsonplaceholder.typicode.com/users/1',
38
+ explanation: '¡Perfecto! Viste un objeto JSON con datos del usuario #1.\n\nNota: El JSON se mostró sin formato (una línea larga). En producción usarías jq para formatearlo, pero con pipes podemos extraer lo que necesitamos.'
39
+ },
40
+
41
+ { type: 'pause' },
42
+
43
+ // --- curl + grep ---
44
+ {
45
+ type: 'text',
46
+ content: '🔍 Combinando curl con grep\n\nNo siempre necesitas TODO el JSON. A veces solo quieres buscar un campo específico.\n\nPuedes enviar la salida de curl directamente a grep sin guardar archivos.'
47
+ },
48
+
49
+ {
50
+ type: 'code',
51
+ title: 'curl + grep en acción',
52
+ code: `# Buscar el email en la respuesta JSON
53
+ curl -s https://jsonplaceholder.typicode.com/users/1 | grep "email"
54
+
55
+ # Buscar todos los nombres de usuario
56
+ curl -s https://jsonplaceholder.typicode.com/users | grep "name"
57
+
58
+ # Buscar posts que mencionan "dolor"
59
+ curl -s https://jsonplaceholder.typicode.com/posts | grep "dolor"`,
60
+ after: ['', 'El pipe | conecta stdout de curl al stdin de grep.', 'grep filtra solo las líneas que contienen el patrón.']
61
+ },
62
+
63
+ { type: 'pause' },
64
+
65
+ // --- Práctica 2: curl + grep ---
66
+ {
67
+ type: 'text',
68
+ content: '📝 Práctica 2: Filtrar respuestas con grep\n\nVamos a buscar el campo "email" en un usuario.'
69
+ },
70
+
71
+ {
72
+ type: 'interactive-command',
73
+ prompt: 'Ejecuta: curl -s https://jsonplaceholder.typicode.com/users/1 | grep "email"',
74
+ expectedCommand: 'curl -s https://jsonplaceholder.typicode.com/users/1 | grep "email"',
75
+ explanation: '¡Exacto! grep filtró la respuesta y solo mostró la línea que contiene "email".\n\nViste algo como: "email": "Sincere@april.biz"\n\nEsto es útil cuando solo necesitas un campo específico y no quieres parsear todo el JSON.'
76
+ },
77
+
78
+ { type: 'pause' },
79
+
80
+ // --- curl + wc ---
81
+ {
82
+ type: 'text',
83
+ content: '🔢 Contando datos con wc\n\nwc (word count) puede contar líneas, palabras, o caracteres.\n\nCombinado con curl, puedes contar registros en APIs sin procesar el JSON completo.'
84
+ },
85
+
86
+ {
87
+ type: 'code',
88
+ title: 'curl + wc para análisis rápido',
89
+ code: `# Contar líneas en la respuesta (aprox. registros)
90
+ curl -s https://jsonplaceholder.typicode.com/users | wc -l
91
+
92
+ # Contar palabras en la respuesta
93
+ curl -s https://jsonplaceholder.typicode.com/posts/1 | wc -w
94
+
95
+ # Contar caracteres (tamaño de la respuesta)
96
+ curl -s https://jsonplaceholder.typicode.com/posts | wc -c`,
97
+ after: ['', 'wc -l cuenta líneas, wc -w palabras, wc -c caracteres.', 'Útil para monitorear tamaños de respuesta o estimar registros.']
98
+ },
99
+
100
+ { type: 'pause' },
101
+
102
+ // --- Práctica 3: curl + wc ---
103
+ {
104
+ type: 'text',
105
+ content: '📝 Práctica 3: Contar líneas en respuesta\n\nVamos a contar cuántas líneas tiene la respuesta de /users.'
106
+ },
107
+
108
+ {
109
+ type: 'interactive-command',
110
+ prompt: 'Ejecuta: curl -s https://jsonplaceholder.typicode.com/users | wc -l',
111
+ expectedCommand: 'curl -s https://jsonplaceholder.typicode.com/users | wc -l',
112
+ explanation: '¡Correcto! Viste un número (probablemente alrededor de 500-700 líneas).\n\nEsto te da una idea rápida del tamaño de la respuesta sin tener que leer todo el JSON.'
113
+ },
114
+
115
+ { type: 'pause' },
116
+
117
+ // --- Múltiples pipes ---
118
+ {
119
+ type: 'text',
120
+ content: '⛓️ Encadenando múltiples pipes\n\nEl verdadero poder viene cuando combinas curl + grep + wc.\n\nPuedes hacer análisis complejos en una sola línea.'
121
+ },
122
+
123
+ {
124
+ type: 'code',
125
+ title: 'Triple combo: curl + grep + wc',
126
+ code: `# ¿Cuántos usuarios tienen email con "biz"?
127
+ curl -s https://jsonplaceholder.typicode.com/users | grep "biz" | wc -l
128
+
129
+ # ¿Cuántas veces aparece "id" en la respuesta?
130
+ curl -s https://jsonplaceholder.typicode.com/posts | grep "id" | wc -l
131
+
132
+ # Buscar posts con "sunt" y contar cuántos
133
+ curl -s https://jsonplaceholder.typicode.com/posts | grep "sunt" | wc -l`,
134
+ after: ['', 'Cada pipe pasa su output al siguiente comando.', 'curl → grep (filtra) → wc (cuenta)', 'Puedes encadenar cuantos pipes necesites.']
135
+ },
136
+
137
+ { type: 'pause' },
138
+
139
+ // --- Práctica 4: múltiples pipes ---
140
+ {
141
+ type: 'text',
142
+ content: '📝 Práctica 4: curl + grep + wc\n\nVamos a contar cuántos emails aparecen en /users (buscando líneas con "email").'
143
+ },
144
+
145
+ {
146
+ type: 'interactive-command',
147
+ prompt: 'Ejecuta: curl -s https://jsonplaceholder.typicode.com/users | grep "email" | wc -l',
148
+ expectedCommand: 'curl -s https://jsonplaceholder.typicode.com/users | grep "email" | wc -l',
149
+ explanation: '¡Excelente! Viste el número de líneas que contienen "email".\n\nEn este caso probablemente 10 (uno por usuario).\n\nEsta técnica es SUPER útil en el mundo real:\n • Monitorear APIs (¿cuántos errores en logs?)\n • Contar registros sin parsear JSON\n • Análisis rápido de respuestas HTTP'
150
+ },
151
+
152
+ { type: 'pause' },
153
+
154
+ // --- Escenarios del mundo real ---
155
+ {
156
+ type: 'text',
157
+ content: '🌍 Escenarios del mundo real\n\nAquí hay ejemplos que usarás en tu día a día como developer:'
158
+ },
159
+
160
+ {
161
+ type: 'code',
162
+ title: 'Casos de uso profesionales',
163
+ code: `# 1. Monitoreo de API: ¿está respondiendo?
164
+ curl -s https://api.miapp.com/health | grep "ok"
165
+
166
+ # 2. Análisis de logs: ¿cuántos errores en las últimas 24h?
167
+ curl -s https://logs.miapp.com/today | grep "ERROR" | wc -l
168
+
169
+ # 3. Testing: ¿la API devuelve el status code correcto?
170
+ curl -s -w "%{http_code}" https://api.miapp.com/users | grep "200"
171
+
172
+ # 4. Data pipeline: descargar, filtrar, y guardar
173
+ curl -s https://api.datos.com/export | grep "activo" > usuarios-activos.txt
174
+
175
+ # 5. Comparación: ¿cuántos posts vs comments?
176
+ curl -s https://jsonplaceholder.typicode.com/posts | wc -l
177
+ curl -s https://jsonplaceholder.typicode.com/comments | wc -l`,
178
+ after: ['', 'Estos patrones son DIARIOS en DevOps, backend, y testing.', 'curl + pipes reemplaza scripts complejos con one-liners simples.']
179
+ },
180
+
181
+ { type: 'pause' },
182
+
183
+ // --- Tips pro ---
184
+ {
185
+ type: 'text',
186
+ content: '💡 Pro Tips\n\n1. Siempre usa -s (silent) para evitar info de progreso en pipes\n2. Usa -i para ver headers HTTP (status codes, content-type)\n3. Combina con head/tail para limitar resultados\n4. grep -i hace búsquedas case-insensitive\n5. En producción, usa jq para parsear JSON correctamente\n\nEjemplo avanzado:\n curl -s https://api.github.com/users/github | grep -i "login"\n'
187
+ },
188
+
189
+ { type: 'pause' },
190
+
191
+ // --- Ejercicio final ---
192
+ {
193
+ type: 'text',
194
+ content: '🎯 Ejercicio final: Análisis completo\n\nVamos a hacer un análisis real: ¿cuántos posts mencionan "qui" en su contenido?'
195
+ },
196
+
197
+ {
198
+ type: 'interactive-command',
199
+ prompt: 'Ejecuta: curl -s https://jsonplaceholder.typicode.com/posts | grep "qui" | wc -l',
200
+ expectedCommand: 'curl -s https://jsonplaceholder.typicode.com/posts | grep "qui" | wc -l',
201
+ explanation: '¡PERFECTO! Acabas de:\n 1. Descargar 100 posts desde una API REST\n 2. Filtrar solo los que contienen "qui"\n 3. Contar cuántos matches encontraste\n\nTodo en una sola línea, sin archivos intermedios.\n\nEsta es la esencia del trabajo con APIs en terminal: rápido, eficiente, y scripteable.'
202
+ },
203
+
204
+ { type: 'pause' },
205
+
206
+ // --- Conclusión ---
207
+ {
208
+ type: 'text',
209
+ content: '🎓 Conclusión\n\nAprendiste a:\n ✅ Usar curl para fetch de APIs\n ✅ Combinar curl + grep para filtrar respuestas\n ✅ Usar curl + wc para análisis rápido\n ✅ Encadenar múltiples pipes (curl + grep + wc)\n ✅ Aplicar estos patrones a escenarios reales\n\nEstas técnicas son FUNDAMENTALES para:\n • DevOps (monitoreo, health checks)\n • Backend development (testing APIs)\n • Data engineering (ETL pipelines)\n • Automation (scripts de CI/CD)\n\nLa próxima vez que necesites consultar una API, ya no abrirás Postman.\nUsarás curl + pipes directo en tu terminal. 🚀'
210
+ },
211
+
212
+ { type: 'pause' },
213
+
214
+ // --- Maze completion ---
215
+ {
216
+ type: 'maze-completion',
217
+ message: '¡Has completado: APIs con curl! 🔥',
218
+ unlocked: 'Dominas curl + pipes para procesar APIs en tiempo real'
219
+ }
220
+ ]
221
+ }
package/lib/data/menus.js CHANGED
@@ -26,6 +26,12 @@ export const SINTAXIS_LESSONS = [
26
26
  title: '4. Escribe scripts',
27
27
  description: '',
28
28
  unlockAfter: 'piping-redireccion'
29
+ },
30
+ {
31
+ id: 'curl-pipes',
32
+ title: '5. APIs con curl',
33
+ description: '',
34
+ unlockAfter: 'bash-scripts'
29
35
  }
30
36
  ]
31
37
 
@@ -5,6 +5,7 @@ import { TERMINAL_BASICO } from '../data/lessons/sintaxis/terminal-basico.js'
5
5
  import { GIT_BASICO } from '../data/lessons/sintaxis/git-basico.js'
6
6
  import { BASH_SCRIPTS } from '../data/lessons/sintaxis/bash-scripts.js'
7
7
  import { PIPING_REDIRECCION } from '../data/lessons/sintaxis/piping-redireccion.js'
8
+ import { CURL_PIPES } from '../data/lessons/sintaxis/curl-pipes.js'
8
9
  import { clearConsole } from '../utils/output.js'
9
10
  import { createPromptInterface } from '../utils/input.js'
10
11
  import { UserState } from '../utils/user-state.js'
@@ -14,7 +15,8 @@ const LESSONS_BY_ID = new Map([
14
15
  ['terminal-basico', TERMINAL_BASICO],
15
16
  ['git-basico', GIT_BASICO],
16
17
  ['bash-scripts', BASH_SCRIPTS],
17
- ['piping-redireccion', PIPING_REDIRECCION]
18
+ ['piping-redireccion', PIPING_REDIRECCION],
19
+ ['curl-pipes', CURL_PIPES]
18
20
  ])
19
21
 
20
22
  function waitForEnter(message = '\nPresiona Enter para continuar...') {
@@ -0,0 +1,844 @@
1
+ # curl + Pipes - Processing APIs in Real Time
2
+
3
+ <!-- vim: set foldmethod=marker foldlevel=0: -->
4
+
5
+ ## 📖 LazyVim Reading Guide {{{
6
+
7
+ **Start with:** `zM` (close all folds) → Navigate with `za` (toggle fold under cursor)
8
+
9
+ This document uses fold markers `{{{` and `}}}` for organized reading.
10
+
11
+ }}}
12
+
13
+ ## 🚨 Problem: Need Quick API Insights Without Postman {{{
14
+
15
+ You're debugging an API and need to:
16
+ - Check if an endpoint is responding
17
+ - Count how many records are returned
18
+ - Filter JSON for specific fields
19
+ - Monitor for errors in real time
20
+
21
+ **Current workflow:**
22
+ 1. Open Postman or browser
23
+ 2. Make request
24
+ 3. Copy response
25
+ 4. Open text editor
26
+ 5. Manually search/count
27
+
28
+ **Time wasted:** 2-5 minutes per query
29
+
30
+ There's a **better way** → `curl + pipes`
31
+
32
+ }}}
33
+
34
+ ## ✅ Solution: curl + grep/wc/sed for Instant Insights {{{
35
+
36
+ Combine curl with pipe commands to process API responses **instantly** in your terminal.
37
+
38
+ **Core pattern:**
39
+ ```bash
40
+ curl [API] | [filter] | [process] | [output]
41
+ ```
42
+
43
+ **Real example:**
44
+ ```bash
45
+ # Count active users in one line
46
+ curl -s https://api.example.com/users | grep "active" | wc -l
47
+ ```
48
+
49
+ **Benefits:**
50
+ - ⚡ **Instant feedback** - no UI switching
51
+ - 🔁 **Scriptable** - automate repetitive checks
52
+ - 🎯 **Precise** - extract exactly what you need
53
+ - 📊 **Pipeline-ready** - chain multiple operations
54
+
55
+ }}}
56
+
57
+ ## 🎯 Essential Curl Flags {{{
58
+
59
+ ### -s (Silent) {{{
60
+
61
+ **Problem:** Default curl shows progress bar, pollutes pipe output
62
+
63
+ ```bash
64
+ # Without -s (messy)
65
+ curl https://api.github.com/users/github | grep "login"
66
+ # % Total % Received... (progress bar appears)
67
+
68
+ # With -s (clean)
69
+ curl -s https://api.github.com/users/github | grep "login"
70
+ # "login": "github" (just the data)
71
+ ```
72
+
73
+ **Rule:** Always use `-s` when piping curl output.
74
+
75
+ }}}
76
+
77
+ ### -i (Include Headers) {{{
78
+
79
+ **Use case:** See HTTP status codes and headers
80
+
81
+ ```bash
82
+ curl -si https://api.github.com/users/github | head -n 1
83
+ # HTTP/2 200 (status code visible)
84
+
85
+ curl -si https://api.github.com/users/fake123 | head -n 1
86
+ # HTTP/2 404 (error detected)
87
+ ```
88
+
89
+ **Pro tip:** Use `head -n 1` to extract just the status line.
90
+
91
+ }}}
92
+
93
+ ### -L (Follow Redirects) {{{
94
+
95
+ **Problem:** Short URLs redirect, curl doesn't follow by default
96
+
97
+ ```bash
98
+ # Without -L (stops at redirect)
99
+ curl -s https://bit.ly/example
100
+ # <redirect HTML>
101
+
102
+ # With -L (follows to final destination)
103
+ curl -sL https://bit.ly/example
104
+ # <actual content>
105
+ ```
106
+
107
+ **Use:** Essential for shortened URLs, CDN redirects, HTTPS upgrades.
108
+
109
+ }}}
110
+
111
+ ### -H (Add Headers) {{{
112
+
113
+ **Use case:** Authentication, content type specification
114
+
115
+ ```bash
116
+ # Add authorization header
117
+ curl -s -H "Authorization: Bearer $TOKEN" https://api.example.com/protected
118
+
119
+ # Specify JSON content type
120
+ curl -s -H "Content-Type: application/json" https://api.example.com/data
121
+
122
+ # Multiple headers
123
+ curl -s \
124
+ -H "Authorization: Bearer $TOKEN" \
125
+ -H "Accept: application/json" \
126
+ https://api.example.com/users
127
+ ```
128
+
129
+ }}}
130
+
131
+ ### -w (Custom Output Format) {{{
132
+
133
+ **Use case:** Extract specific HTTP metadata
134
+
135
+ ```bash
136
+ # Get only HTTP status code
137
+ curl -s -w "%{http_code}" -o /dev/null https://api.github.com/users/github
138
+ # 200
139
+
140
+ # Get response time
141
+ curl -s -w "%{time_total}s" -o /dev/null https://api.github.com
142
+ # 0.452s
143
+
144
+ # Get status + time
145
+ curl -s -w "Status: %{http_code} | Time: %{time_total}s\n" -o /dev/null https://api.github.com
146
+ # Status: 200 | Time: 0.234s
147
+ ```
148
+
149
+ **Flags:**
150
+ - `-w "%{format}"`: Write custom output format
151
+ - `-o /dev/null`: Discard response body (only show -w output)
152
+
153
+ }}}
154
+
155
+ }}}
156
+
157
+ ## 🔗 Pipe Combinations {{{
158
+
159
+ ### curl + grep: Filter JSON Fields {{{
160
+
161
+ **Use case:** Extract specific fields from JSON response
162
+
163
+ ```bash
164
+ # Find email in user object
165
+ curl -s https://jsonplaceholder.typicode.com/users/1 | grep "email"
166
+ # "email": "Sincere@april.biz",
167
+
168
+ # Find all names in user list
169
+ curl -s https://jsonplaceholder.typicode.com/users | grep "name"
170
+ # "name": "Leanne Graham",
171
+ # "name": "Ervin Howell",
172
+ # ...
173
+
174
+ # Case-insensitive search
175
+ curl -s https://api.github.com/users/github | grep -i "LOGIN"
176
+ # "login": "github",
177
+ ```
178
+
179
+ **Pro tip:** Use `grep -i` for case-insensitive matching.
180
+
181
+ }}}
182
+
183
+ ### curl + wc: Count Records/Lines {{{
184
+
185
+ **Use case:** Quick statistics on API responses
186
+
187
+ ```bash
188
+ # Count lines in response (approx. size)
189
+ curl -s https://jsonplaceholder.typicode.com/users | wc -l
190
+ # 542
191
+
192
+ # Count words (tokens)
193
+ curl -s https://jsonplaceholder.typicode.com/users | wc -w
194
+ # 1849
195
+
196
+ # Count bytes (response size)
197
+ curl -s https://jsonplaceholder.typicode.com/users | wc -c
198
+ # 5645
199
+ ```
200
+
201
+ **Interpretation:**
202
+ - `wc -l`: Lines (rough measure of JSON structure)
203
+ - `wc -w`: Words (data density)
204
+ - `wc -c`: Bytes (actual response size)
205
+
206
+ }}}
207
+
208
+ ### curl + grep + wc: Count Matches {{{
209
+
210
+ **Use case:** Answer questions like "How many users have X?"
211
+
212
+ ```bash
213
+ # How many users?
214
+ curl -s https://jsonplaceholder.typicode.com/users | grep "\"id\":" | wc -l
215
+ # 10
216
+
217
+ # How many posts mention "dolor"?
218
+ curl -s https://jsonplaceholder.typicode.com/posts | grep "dolor" | wc -l
219
+ # 23
220
+
221
+ # How many email addresses end in ".biz"?
222
+ curl -s https://jsonplaceholder.typicode.com/users | grep ".biz" | wc -l
223
+ # 2
224
+ ```
225
+
226
+ **Pattern:** `curl → filter → count`
227
+
228
+ }}}
229
+
230
+ ### curl + head/tail: Limit Output {{{
231
+
232
+ **Use case:** See first/last N lines of response
233
+
234
+ ```bash
235
+ # First 10 lines
236
+ curl -s https://jsonplaceholder.typicode.com/posts | head -n 10
237
+
238
+ # Last 5 lines
239
+ curl -s https://jsonplaceholder.typicode.com/posts | tail -n 5
240
+
241
+ # Lines 20-30 (skip first 19, show next 10)
242
+ curl -s https://jsonplaceholder.typicode.com/posts | tail -n +20 | head -n 10
243
+ ```
244
+
245
+ **Use cases:**
246
+ - Preview large responses
247
+ - Sample data without downloading everything
248
+ - Extract specific ranges
249
+
250
+ }}}
251
+
252
+ ### curl + sed: Transform Output {{{
253
+
254
+ **Use case:** Clean up or reformat JSON fields
255
+
256
+ ```bash
257
+ # Extract email addresses (remove JSON quotes)
258
+ curl -s https://jsonplaceholder.typicode.com/users | grep "email" | sed 's/.*"email": "\(.*\)".*/\1/'
259
+
260
+ # Remove all commas from JSON
261
+ curl -s https://jsonplaceholder.typicode.com/users/1 | sed 's/,//g'
262
+
263
+ # Replace text in response
264
+ curl -s https://jsonplaceholder.typicode.com/posts/1 | sed 's/sunt/REDACTED/g'
265
+ ```
266
+
267
+ **Advanced:** Combine with pipes for complex transformations.
268
+
269
+ }}}
270
+
271
+ ### curl + sort + uniq: Deduplicate {{{
272
+
273
+ **Use case:** Find unique values in API responses
274
+
275
+ ```bash
276
+ # Get unique user IDs from posts
277
+ curl -s https://jsonplaceholder.typicode.com/posts | grep "userId" | sort | uniq
278
+
279
+ # Count occurrences of each user
280
+ curl -s https://jsonplaceholder.typicode.com/posts | grep "userId" | sort | uniq -c
281
+ ```
282
+
283
+ **Pattern:** `curl → extract → sort → unique`
284
+
285
+ }}}
286
+
287
+ }}}
288
+
289
+ ## 🌍 Real-World Scenarios {{{
290
+
291
+ ### Scenario 1: Health Check Monitoring {{{
292
+
293
+ **Problem:** Need to check if API is responding with 200 OK
294
+
295
+ ```bash
296
+ # Check status code
297
+ curl -s -w "%{http_code}" -o /dev/null https://api.myapp.com/health
298
+
299
+ # One-liner health check
300
+ if [ $(curl -s -w "%{http_code}" -o /dev/null https://api.myapp.com/health) -eq 200 ]; then
301
+ echo "✅ API is healthy"
302
+ else
303
+ echo "❌ API is down"
304
+ fi
305
+ ```
306
+
307
+ **Use case:** Cron jobs, deployment scripts, CI/CD health checks.
308
+
309
+ }}}
310
+
311
+ ### Scenario 2: Error Log Analysis {{{
312
+
313
+ **Problem:** Count how many errors occurred in last hour
314
+
315
+ ```bash
316
+ # Count ERROR lines in logs API
317
+ curl -s https://logs.myapp.com/last-hour | grep "ERROR" | wc -l
318
+
319
+ # Find critical errors only
320
+ curl -s https://logs.myapp.com/last-hour | grep "CRITICAL" | wc -l
321
+
322
+ # Group by error type
323
+ curl -s https://logs.myapp.com/last-hour | grep "ERROR" | cut -d':' -f2 | sort | uniq -c
324
+ ```
325
+
326
+ **Use case:** Incident response, debugging production issues.
327
+
328
+ }}}
329
+
330
+ ### Scenario 3: API Testing in CI/CD {{{
331
+
332
+ **Problem:** Verify API returns expected data after deployment
333
+
334
+ ```bash
335
+ # Test: Does response contain expected field?
336
+ curl -s https://api.myapp.com/config | grep -q "version" && echo "✅ Pass" || echo "❌ Fail"
337
+
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"
342
+ else
343
+ echo "❌ No users returned"
344
+ fi
345
+ ```
346
+
347
+ **Use case:** Smoke tests after deployment, integration testing.
348
+
349
+ }}}
350
+
351
+ ### Scenario 4: Data Pipeline Extraction {{{
352
+
353
+ **Problem:** Download API data, filter active records, save to file
354
+
355
+ ```bash
356
+ # Extract active users to file
357
+ curl -s https://api.myapp.com/users | grep "\"status\": \"active\"" > active-users.json
358
+
359
+ # Extract and count
360
+ curl -s https://api.myapp.com/orders | grep "\"status\": \"pending\"" | wc -l > pending-orders.txt
361
+
362
+ # Multi-step pipeline
363
+ curl -s https://api.github.com/users/github/repos \
364
+ | grep "\"name\":" \
365
+ | sed 's/.*"name": "\(.*\)".*/\1/' \
366
+ | sort \
367
+ > repo-names.txt
368
+ ```
369
+
370
+ **Use case:** ETL jobs, data exports, scheduled reports.
371
+
372
+ }}}
373
+
374
+ ### Scenario 5: Rate Limit Checking {{{
375
+
376
+ **Problem:** Check how many API calls you have left
377
+
378
+ ```bash
379
+ # GitHub rate limit (headers contain rate info)
380
+ curl -si https://api.github.com/users/github | grep -i "x-ratelimit"
381
+ # x-ratelimit-limit: 60
382
+ # x-ratelimit-remaining: 59
383
+
384
+ # Extract just the remaining count
385
+ curl -si https://api.github.com/users/github \
386
+ | grep -i "x-ratelimit-remaining" \
387
+ | awk '{print $2}'
388
+ # 59
389
+ ```
390
+
391
+ **Use case:** API quota monitoring, avoiding rate limit errors.
392
+
393
+ }}}
394
+
395
+ ### Scenario 6: Comparing API Versions {{{
396
+
397
+ **Problem:** Did the API response change between versions?
398
+
399
+ ```bash
400
+ # Get response from v1
401
+ curl -s https://api.myapp.com/v1/users > v1-response.json
402
+
403
+ # Get response from v2
404
+ curl -s https://api.myapp.com/v2/users > v2-response.json
405
+
406
+ # Compare
407
+ diff v1-response.json v2-response.json
408
+
409
+ # Or count differences
410
+ diff v1-response.json v2-response.json | wc -l
411
+ ```
412
+
413
+ **Use case:** API migration validation, regression testing.
414
+
415
+ }}}
416
+
417
+ }}}
418
+
419
+ ## 🧪 Practice Exercises {{{
420
+
421
+ ### Exercise 1: Basic Filtering {{{
422
+
423
+ **Goal:** Extract the "title" field from a post
424
+
425
+ ```bash
426
+ # API endpoint
427
+ https://jsonplaceholder.typicode.com/posts/1
428
+
429
+ # Your command:
430
+ curl -s https://jsonplaceholder.typicode.com/posts/1 | grep "title"
431
+
432
+ # Expected output:
433
+ # "title": "sunt aut facere repellat provident...",
434
+ ```
435
+
436
+ }}}
437
+
438
+ ### Exercise 2: Counting Records {{{
439
+
440
+ **Goal:** How many comments exist in total?
441
+
442
+ ```bash
443
+ # API endpoint
444
+ https://jsonplaceholder.typicode.com/comments
445
+
446
+ # Your command:
447
+ curl -s https://jsonplaceholder.typicode.com/comments | grep "\"id\":" | wc -l
448
+
449
+ # Expected output:
450
+ # 500
451
+ ```
452
+
453
+ }}}
454
+
455
+ ### Exercise 3: Multi-Pipe Chain {{{
456
+
457
+ **Goal:** Count how many posts contain the word "qui"
458
+
459
+ ```bash
460
+ # API endpoint
461
+ https://jsonplaceholder.typicode.com/posts
462
+
463
+ # Your command:
464
+ curl -s https://jsonplaceholder.typicode.com/posts | grep "qui" | wc -l
465
+
466
+ # Expected output:
467
+ # ~30-40 (number of lines containing "qui")
468
+ ```
469
+
470
+ }}}
471
+
472
+ ### Exercise 4: Status Code Check {{{
473
+
474
+ **Goal:** Verify GitHub API returns 200 for valid user
475
+
476
+ ```bash
477
+ # API endpoint
478
+ https://api.github.com/users/github
479
+
480
+ # Your command:
481
+ curl -s -w "%{http_code}" -o /dev/null https://api.github.com/users/github
482
+
483
+ # Expected output:
484
+ # 200
485
+ ```
486
+
487
+ }}}
488
+
489
+ ### Exercise 5: Extract and Transform {{{
490
+
491
+ **Goal:** Get all email addresses from users, one per line (clean format)
492
+
493
+ ```bash
494
+ # API endpoint
495
+ https://jsonplaceholder.typicode.com/users
496
+
497
+ # Your command:
498
+ curl -s https://jsonplaceholder.typicode.com/users \
499
+ | grep "email" \
500
+ | sed 's/.*"email": "\(.*\)".*/\1/' \
501
+ | sed 's/,$//'
502
+
503
+ # Expected output:
504
+ # Sincere@april.biz
505
+ # Shanna@melissa.tv
506
+ # Nathan@yesenia.net
507
+ # (etc...)
508
+ ```
509
+
510
+ }}}
511
+
512
+ }}}
513
+
514
+ ## 🛡️ Best Practices {{{
515
+
516
+ ### Always Use -s Flag {{{
517
+
518
+ **Why:** Default progress bar pollutes pipe output
519
+
520
+ ```bash
521
+ # ❌ Bad: progress bar interferes with grep
522
+ curl https://api.example.com | grep "name"
523
+
524
+ # ✅ Good: clean output
525
+ curl -s https://api.example.com | grep "name"
526
+ ```
527
+
528
+ }}}
529
+
530
+ ### Check Status Codes Before Processing {{{
531
+
532
+ **Why:** Don't process error responses
533
+
534
+ ```bash
535
+ # ❌ Bad: processes error HTML as JSON
536
+ curl -s https://api.example.com/fake | grep "name"
537
+
538
+ # ✅ Good: check status first
539
+ RESPONSE=$(curl -s -w "\n%{http_code}" https://api.example.com/users)
540
+ STATUS=$(echo "$RESPONSE" | tail -n 1)
541
+ BODY=$(echo "$RESPONSE" | head -n -1)
542
+
543
+ if [ $STATUS -eq 200 ]; then
544
+ echo "$BODY" | grep "name"
545
+ else
546
+ echo "Error: API returned $STATUS"
547
+ fi
548
+ ```
549
+
550
+ }}}
551
+
552
+ ### Use jq for Complex JSON Parsing {{{
553
+
554
+ **When to use pipes:** Simple filtering, counting, text search
555
+ **When to use jq:** Proper JSON parsing, nested fields, arrays
556
+
557
+ ```bash
558
+ # Pipes: Quick field search
559
+ curl -s https://api.example.com/users | grep "email"
560
+
561
+ # jq: Proper JSON parsing
562
+ curl -s https://api.example.com/users | jq '.[].email'
563
+
564
+ # jq: Complex queries
565
+ curl -s https://api.example.com/users | jq '.[] | select(.id > 5) | .name'
566
+ ```
567
+
568
+ **Rule of thumb:** If you need more than 2-3 greps/seds, switch to jq.
569
+
570
+ }}}
571
+
572
+ ### Save Responses for Testing {{{
573
+
574
+ **Why:** Don't hammer APIs during development
575
+
576
+ ```bash
577
+ # ❌ 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"
581
+
582
+ # ✅ 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"
587
+ ```
588
+
589
+ }}}
590
+
591
+ ### Handle Errors Gracefully {{{
592
+
593
+ **Check for empty responses:**
594
+
595
+ ```bash
596
+ # Store response
597
+ RESPONSE=$(curl -s https://api.example.com/users)
598
+
599
+ # Check if empty
600
+ if [ -z "$RESPONSE" ]; then
601
+ echo "Error: Empty response"
602
+ exit 1
603
+ fi
604
+
605
+ # Process
606
+ echo "$RESPONSE" | grep "name"
607
+ ```
608
+
609
+ }}}
610
+
611
+ ### Timeout Long Requests {{{
612
+
613
+ **Prevent hanging scripts:**
614
+
615
+ ```bash
616
+ # Default: waits forever
617
+ curl -s https://slow-api.example.com
618
+
619
+ # With timeout: fails after 10 seconds
620
+ curl -s --max-time 10 https://slow-api.example.com
621
+ ```
622
+
623
+ }}}
624
+
625
+ }}}
626
+
627
+ ## 📚 Quick Reference {{{
628
+
629
+ ### Essential curl Flags {{{
630
+
631
+ ```bash
632
+ -s # Silent (no progress bar)
633
+ -i # Include headers in output
634
+ -I # Headers only (no body)
635
+ -L # Follow redirects
636
+ -w "%{http_code}" # Print HTTP status code
637
+ -o /dev/null # Discard response body
638
+ -H "Key: Value" # Add custom header
639
+ --max-time 10 # Timeout after 10 seconds
640
+ -X POST # HTTP method (POST, PUT, DELETE, etc.)
641
+ -d "key=value" # Send data (POST body)
642
+ ```
643
+
644
+ }}}
645
+
646
+ ### Common Pipe Patterns {{{
647
+
648
+ ```bash
649
+ # Filter
650
+ curl -s URL | grep "pattern"
651
+
652
+ # Count
653
+ curl -s URL | wc -l
654
+
655
+ # Count matches
656
+ curl -s URL | grep "pattern" | wc -l
657
+
658
+ # First N lines
659
+ curl -s URL | head -n 10
660
+
661
+ # Last N lines
662
+ curl -s URL | tail -n 10
663
+
664
+ # Transform
665
+ curl -s URL | sed 's/old/new/g'
666
+
667
+ # Deduplicate
668
+ curl -s URL | grep "field" | sort | uniq
669
+
670
+ # Save filtered results
671
+ curl -s URL | grep "active" > output.txt
672
+ ```
673
+
674
+ }}}
675
+
676
+ ### One-Liner Templates {{{
677
+
678
+ ```bash
679
+ # Health check
680
+ curl -s -w "%{http_code}" -o /dev/null https://api.example.com/health
681
+
682
+ # Count records
683
+ curl -s https://api.example.com/users | grep "\"id\":" | wc -l
684
+
685
+ # Extract field
686
+ curl -s https://api.example.com/config | grep "version" | sed 's/.*"version": "\(.*\)".*/\1/'
687
+
688
+ # Monitor errors
689
+ curl -s https://logs.example.com/today | grep "ERROR" | wc -l
690
+
691
+ # Test endpoint
692
+ curl -s https://api.example.com/users | grep -q "data" && echo "OK" || echo "FAIL"
693
+ ```
694
+
695
+ }}}
696
+
697
+ }}}
698
+
699
+ ## 🎓 Advanced Topics {{{
700
+
701
+ ### Parallel Requests with xargs {{{
702
+
703
+ **Use case:** Check multiple endpoints simultaneously
704
+
705
+ ```bash
706
+ # Check health of multiple services
707
+ echo -e "api.service1.com\napi.service2.com\napi.service3.com" \
708
+ | xargs -I {} -P 3 curl -s -w "{} → %{http_code}\n" -o /dev/null https://{}
709
+ ```
710
+
711
+ **Explanation:**
712
+ - `-I {}`: Replace `{}` with each line
713
+ - `-P 3`: Run 3 parallel processes
714
+ - `-w "... %{http_code}"`: Print status code
715
+
716
+ }}}
717
+
718
+ ### JSON Stream Processing {{{
719
+
720
+ **Use case:** Process large API responses line-by-line
721
+
722
+ ```bash
723
+ # Stream large response
724
+ curl -s https://api.example.com/large-dataset \
725
+ | while IFS= read -r line; do
726
+ echo "$line" | grep "active" >> active-records.txt
727
+ done
728
+ ```
729
+
730
+ **Use when:** API returns huge responses, need to filter during download.
731
+
732
+ }}}
733
+
734
+ ### Authenticated API Requests {{{
735
+
736
+ **JWT token example:**
737
+
738
+ ```bash
739
+ # Store token
740
+ TOKEN="your-jwt-token-here"
741
+
742
+ # Authenticated request
743
+ curl -s -H "Authorization: Bearer $TOKEN" \
744
+ https://api.example.com/protected \
745
+ | grep "data"
746
+ ```
747
+
748
+ **Environment variable:**
749
+
750
+ ```bash
751
+ # In .env or .bashrc
752
+ export API_TOKEN="your-token"
753
+
754
+ # In script
755
+ curl -s -H "Authorization: Bearer $API_TOKEN" https://api.example.com/protected
756
+ ```
757
+
758
+ }}}
759
+
760
+ ### POST Requests with Data {{{
761
+
762
+ **Send JSON data:**
763
+
764
+ ```bash
765
+ # POST JSON
766
+ curl -s -X POST \
767
+ -H "Content-Type: application/json" \
768
+ -d '{"name": "John", "email": "john@example.com"}' \
769
+ https://jsonplaceholder.typicode.com/users \
770
+ | grep "id"
771
+ ```
772
+
773
+ **POST form data:**
774
+
775
+ ```bash
776
+ curl -s -X POST \
777
+ -d "name=John" \
778
+ -d "email=john@example.com" \
779
+ https://httpbin.org/post \
780
+ | grep "form"
781
+ ```
782
+
783
+ }}}
784
+
785
+ }}}
786
+
787
+ ## 💡 Pro Tips {{{
788
+
789
+ 1. **Combine with watch for live monitoring:**
790
+ ```bash
791
+ watch -n 5 'curl -s https://api.example.com/metrics | grep "active" | wc -l'
792
+ ```
793
+
794
+ 2. **Save complex one-liners as shell functions:**
795
+ ```bash
796
+ # In .bashrc or .zshrc
797
+ api_health() {
798
+ curl -s -w "%{http_code}" -o /dev/null "https://api.example.com/$1"
799
+ }
800
+
801
+ # Usage
802
+ api_health users # Check /users endpoint
803
+ ```
804
+
805
+ 3. **Use aliases for frequent API checks:**
806
+ ```bash
807
+ alias check-api='curl -s https://api.myapp.com/health | grep "ok"'
808
+ ```
809
+
810
+ 4. **Pipe to pbcopy (Mac) or xclip (Linux) to copy output:**
811
+ ```bash
812
+ curl -s https://api.example.com/users | grep "email" | pbcopy
813
+ ```
814
+
815
+ 5. **Chain with git for API version tracking:**
816
+ ```bash
817
+ curl -s https://api.example.com/schema > schema.json
818
+ git diff schema.json # See what changed
819
+ ```
820
+
821
+ }}}
822
+
823
+ ## 🚀 Next Steps {{{
824
+
825
+ **Master these progressively:**
826
+
827
+ 1. ✅ **Level 1:** `curl + grep` (filtering)
828
+ 2. ✅ **Level 2:** `curl + grep + wc` (counting)
829
+ 3. ✅ **Level 3:** `curl + sed` (transforming)
830
+ 4. 🎯 **Level 4:** `curl + jq` (proper JSON parsing)
831
+ 5. 🎯 **Level 5:** Write shell scripts with error handling
832
+ 6. 🎯 **Level 6:** Automate with cron jobs
833
+
834
+ **Related skills:**
835
+ - Learn `jq` for advanced JSON manipulation
836
+ - Study bash scripting for automation
837
+ - Explore `watch` for continuous monitoring
838
+ - Master `awk` for columnar data processing
839
+
840
+ }}}
841
+
842
+ ---
843
+
844
+ **Remember:** curl + pipes turns your terminal into a powerful API client. No GUI needed! 🚀
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icarusmx/creta",
3
- "version": "1.5.10",
3
+ "version": "1.5.11",
4
4
  "description": "Salgamos de este laberinto.",
5
5
  "type": "module",
6
6
  "bin": {