@icarusmx/creta 0.7.3 → 0.8.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 (2) hide show
  1. package/bin/creta.js +339 -16
  2. package/package.json +1 -1
package/bin/creta.js CHANGED
@@ -49,12 +49,13 @@ const ENUNCIADOS = [
49
49
  const args = process.argv.slice(2)
50
50
  const command = args[0]
51
51
 
52
- console.log("¡Bienvenida de vuelta! 🏛️")
53
- console.log("Retomemos desde donde nos quedamos: hagamos tu portafolio.\n")
52
+ // Welcome message
53
+ console.log("🏛️ Bienvenido a Creta")
54
+ console.log("La escuela de software de icarus.mx\n")
54
55
 
55
56
  if (!command) {
56
- // Default behavior: show enunciados selector
57
- await startEnunciadosSelector()
57
+ // Default behavior: show main menu
58
+ await startMainMenu()
58
59
  process.exit(0)
59
60
  }
60
61
 
@@ -578,6 +579,157 @@ function showHelp() {
578
579
  console.log(" construir comprensión real, no solo sintaxis.")
579
580
  }
580
581
 
582
+ async function startMainMenu() {
583
+ // Always try interactive mode first, fall back only if it fails
584
+ try {
585
+ return await startMainMenuInteractive()
586
+ } catch (error) {
587
+ // If interactive mode fails, fall back to numbered selection
588
+ console.log('\nModo interactivo no disponible, usando selección numérica...\n')
589
+ return await startMainMenuFallback()
590
+ }
591
+ }
592
+
593
+ async function startMainMenuInteractive() {
594
+ // Check if setRawMode is available before trying to use it
595
+ if (typeof process.stdin.setRawMode !== 'function') {
596
+ throw new Error('setRawMode not available')
597
+ }
598
+
599
+ console.log("Te ofrecemos las siguientes opciones")
600
+ console.log("Usa ↑/↓ para navegar, Enter para seleccionar, 'q' para salir\n")
601
+
602
+ const options = [
603
+ { id: 1, title: "🧠 Aprender conceptos", description: "Explora los enunciados fundamentales" },
604
+ { id: 2, title: "🚀 Construir proyectos", description: "Crea tu portafolio personal" }
605
+ ]
606
+
607
+ let selectedIndex = 0
608
+
609
+ // Enable raw mode to capture arrow keys
610
+ try {
611
+ process.stdin.setRawMode(true)
612
+ process.stdin.resume()
613
+ process.stdin.setEncoding('utf8')
614
+ } catch (error) {
615
+ throw new Error('Failed to enable raw mode: ' + error.message)
616
+ }
617
+
618
+ const renderOptions = () => {
619
+ // Clear previous output and move cursor to top
620
+ process.stdout.write('\x1b[2J')
621
+ process.stdout.write('\x1b[H')
622
+
623
+ console.log("🏛️ Bienvenido a Creta")
624
+ console.log("La escuela de software de icarus.mx\n")
625
+ console.log("Te ofrecemos las siguientes opciones")
626
+ console.log("Usa ↑/↓ para navegar, Enter para seleccionar, 'q' para salir\n")
627
+
628
+ options.forEach((option, index) => {
629
+ const isSelected = index === selectedIndex
630
+ const prefix = isSelected ? '▶ ' : ' '
631
+ const highlight = isSelected ? '\x1b[36m' : '\x1b[37m' // cyan for selected, white for normal
632
+ const reset = '\x1b[0m'
633
+
634
+ console.log(`${highlight}${prefix}${option.title}${reset}`)
635
+ if (isSelected) {
636
+ console.log(`${highlight} ${option.description}${reset}`)
637
+ }
638
+ console.log("")
639
+ })
640
+ }
641
+
642
+ return new Promise((resolve) => {
643
+ renderOptions()
644
+
645
+ const onKeyPress = (key) => {
646
+ if (key === 'q' || key === '\x03') { // q or Ctrl+C
647
+ process.stdin.setRawMode(false)
648
+ process.stdin.removeListener('data', onKeyPress)
649
+ console.log("\n¡Hasta la vista! 👋")
650
+ resolve()
651
+ return
652
+ }
653
+
654
+ if (key === '\r' || key === '\n') { // Enter
655
+ process.stdin.setRawMode(false)
656
+ process.stdin.removeListener('data', onKeyPress)
657
+
658
+ const selectedOption = options[selectedIndex]
659
+
660
+ // Clear screen
661
+ process.stdout.write('\x1b[2J')
662
+ process.stdout.write('\x1b[H')
663
+
664
+ if (selectedOption.id === 1) {
665
+ startEnunciadosSelector().then(resolve)
666
+ } else if (selectedOption.id === 2) {
667
+ startProyectosSelector().then(resolve)
668
+ }
669
+ return
670
+ }
671
+
672
+ // Handle arrow keys (escape sequences)
673
+ if (key === '\u001b[A') { // Up arrow
674
+ selectedIndex = selectedIndex > 0 ? selectedIndex - 1 : options.length - 1
675
+ renderOptions()
676
+ } else if (key === '\u001b[B') { // Down arrow
677
+ selectedIndex = selectedIndex < options.length - 1 ? selectedIndex + 1 : 0
678
+ renderOptions()
679
+ }
680
+ }
681
+
682
+ process.stdin.on('data', onKeyPress)
683
+ })
684
+ }
685
+
686
+ async function startMainMenuFallback() {
687
+ const rl = createInterface({
688
+ input: process.stdin,
689
+ output: process.stdout
690
+ })
691
+
692
+ const askQuestion = (question) => {
693
+ return new Promise((resolve) => {
694
+ rl.question(question, resolve)
695
+ })
696
+ }
697
+
698
+ try {
699
+ console.log("Te ofrecemos las siguientes opciones")
700
+ console.log("")
701
+ console.log("1. 🧠 Aprender conceptos - Explora los enunciados fundamentales")
702
+ console.log("2. 🚀 Construir proyectos - Crea tu portafolio personal")
703
+ console.log("")
704
+
705
+ const respuesta = await askQuestion("Elige una opción (1-2) o 'q' para salir: ")
706
+
707
+ if (respuesta.toLowerCase() === 'q') {
708
+ console.log("¡Hasta la vista! 👋")
709
+ rl.close()
710
+ return
711
+ }
712
+
713
+ const opcionSeleccionada = parseInt(respuesta)
714
+
715
+ if (opcionSeleccionada === 1) {
716
+ rl.close()
717
+ await startEnunciadosSelector()
718
+ } else if (opcionSeleccionada === 2) {
719
+ rl.close()
720
+ await startProyectosSelector()
721
+ } else {
722
+ console.log("❌ Opción no válida. Elige 1 o 2.")
723
+ rl.close()
724
+ }
725
+
726
+ } catch (error) {
727
+ console.error('Error:', error.message)
728
+ rl.close()
729
+ process.exit(1)
730
+ }
731
+ }
732
+
581
733
  async function startEnunciadosSelector() {
582
734
  // Always try interactive mode first, fall back only if it fails
583
735
  try {
@@ -590,27 +742,34 @@ async function startEnunciadosSelector() {
590
742
  }
591
743
 
592
744
  async function startEnunciadosSelectorInteractive() {
593
- console.log("\n🧠 Los 6 Enunciados Fundamentales de Programación Orientada a Objetos")
594
- console.log("=" .repeat(70))
595
- console.log("¿Cuál de estos enunciados te genera más 'ruido' (curiosidad/confusión)?")
745
+ // Check if setRawMode is available before trying to use it
746
+ if (typeof process.stdin.setRawMode !== 'function') {
747
+ throw new Error('setRawMode not available')
748
+ }
749
+
750
+ console.log("\n🧠 Conceptos Fundamentales")
751
+ console.log("¿Cuáles de estos enunciados quieres explorar?")
596
752
  console.log("Usa ↑/↓ para navegar, Enter para seleccionar, 'q' para salir\n")
597
753
 
598
754
  let selectedIndex = 0
599
755
  let running = true
600
756
 
601
757
  // Enable raw mode to capture arrow keys
602
- process.stdin.setRawMode(true)
603
- process.stdin.resume()
604
- process.stdin.setEncoding('utf8')
758
+ try {
759
+ process.stdin.setRawMode(true)
760
+ process.stdin.resume()
761
+ process.stdin.setEncoding('utf8')
762
+ } catch (error) {
763
+ throw new Error('Failed to enable raw mode: ' + error.message)
764
+ }
605
765
 
606
766
  const renderOptions = () => {
607
767
  // Clear previous output and move cursor to top
608
768
  process.stdout.write('\x1b[2J')
609
769
  process.stdout.write('\x1b[H')
610
770
 
611
- console.log("🧠 Los 6 Enunciados Fundamentales de Programación Orientada a Objetos")
612
- console.log("=" .repeat(70))
613
- console.log("¿Cuál de estos enunciados te genera más 'ruido' (curiosidad/confusión)?")
771
+ console.log("🧠 Conceptos Fundamentales")
772
+ console.log("¿Cuáles de estos enunciados quieres explorar?")
614
773
  console.log("Usa ↑/↓ para navegar, Enter para seleccionar, 'q' para salir\n")
615
774
 
616
775
  ENUNCIADOS.forEach((enunciado, index) => {
@@ -710,9 +869,8 @@ async function startEnunciadosSelectorFallback() {
710
869
  }
711
870
 
712
871
  try {
713
- console.log("\n🧠 Los 6 Enunciados Fundamentales de Programación Orientada a Objetos")
714
- console.log("=" .repeat(70))
715
- console.log("¿Cuál de estos enunciados te genera más 'ruido' (curiosidad/confusión)?")
872
+ console.log("\n🧠 Conceptos Fundamentales")
873
+ console.log("¿Cuáles de estos enunciados quieres explorar?")
716
874
  console.log("")
717
875
 
718
876
  ENUNCIADOS.forEach((enunciado, index) => {
@@ -758,3 +916,168 @@ async function startEnunciadosSelectorFallback() {
758
916
  process.exit(1)
759
917
  }
760
918
  }
919
+
920
+
921
+ async function startProyectosSelector() {
922
+ // Always try interactive mode first, fall back only if it fails
923
+ try {
924
+ return await startProyectosSelectorInteractive()
925
+ } catch (error) {
926
+ // If interactive mode fails, fall back to numbered selection
927
+ console.log('\nModo interactivo no disponible, usando selección numérica...\n')
928
+ return await startProyectosSelectorFallback()
929
+ }
930
+ }
931
+
932
+ async function startProyectosSelectorInteractive() {
933
+ // Check if setRawMode is available before trying to use it
934
+ if (typeof process.stdin.setRawMode !== 'function') {
935
+ throw new Error('setRawMode not available')
936
+ }
937
+
938
+ console.log("\n🚀 Proyectos Disponibles")
939
+ console.log("¿Qué proyecto quieres crear?")
940
+ console.log("Usa ↑/↓ para navegar, Enter para seleccionar, 'q' para salir\n")
941
+
942
+ const projects = [
943
+ { id: 1, title: "🎨 Portafolio Personal", description: "Reto completo", level: 0 },
944
+ { id: 2, title: "🔓 Portafolio Nivel 1", description: "Solo navbar", level: 1 },
945
+ { id: 3, title: "🔓 Portafolio Nivel 2", description: "Navbar + hero", level: 2 },
946
+ { id: 4, title: "🔓 Portafolio Nivel 3", description: "Solución completa", level: 3 }
947
+ ]
948
+
949
+ let selectedIndex = 0
950
+
951
+ // Enable raw mode to capture arrow keys
952
+ try {
953
+ process.stdin.setRawMode(true)
954
+ process.stdin.resume()
955
+ process.stdin.setEncoding('utf8')
956
+ } catch (error) {
957
+ throw new Error('Failed to enable raw mode: ' + error.message)
958
+ }
959
+
960
+ const renderOptions = () => {
961
+ // Clear previous output and move cursor to top
962
+ process.stdout.write('\x1b[2J')
963
+ process.stdout.write('\x1b[H')
964
+
965
+ console.log("🚀 Proyectos Disponibles")
966
+ console.log("¿Qué proyecto quieres crear?")
967
+ console.log("Usa ↑/↓ para navegar, Enter para seleccionar, 'q' para salir\n")
968
+
969
+ projects.forEach((project, index) => {
970
+ const isSelected = index === selectedIndex
971
+ const prefix = isSelected ? '▶ ' : ' '
972
+ const highlight = isSelected ? '\x1b[36m' : '\x1b[37m' // cyan for selected, white for normal
973
+ const reset = '\x1b[0m'
974
+
975
+ console.log(`${highlight}${prefix}${project.title}${reset}`)
976
+ if (isSelected) {
977
+ console.log(`${highlight} ${project.description}${reset}`)
978
+ }
979
+ console.log("")
980
+ })
981
+ }
982
+
983
+ return new Promise((resolve) => {
984
+ renderOptions()
985
+
986
+ const onKeyPress = (key) => {
987
+ if (key === 'q' || key === '\x03') { // q or Ctrl+C
988
+ process.stdin.setRawMode(false)
989
+ process.stdin.removeListener('data', onKeyPress)
990
+ console.log("\n¡Hasta la vista! 👋")
991
+ resolve()
992
+ return
993
+ }
994
+
995
+ if (key === '\r' || key === '\n') { // Enter
996
+ process.stdin.setRawMode(false)
997
+ process.stdin.removeListener('data', onKeyPress)
998
+
999
+ const selectedProject = projects[selectedIndex]
1000
+ const level = selectedProject.level
1001
+
1002
+ // Clear screen
1003
+ process.stdout.write('\x1b[2J')
1004
+ process.stdout.write('\x1b[H')
1005
+
1006
+ // Check if we're in an existing Creta project
1007
+ if (level > 0 && isInCretaProject()) {
1008
+ unstuckProject(level).then(resolve)
1009
+ } else {
1010
+ createPortfolioProject(level).then(resolve)
1011
+ }
1012
+ return
1013
+ }
1014
+
1015
+ // Handle arrow keys (escape sequences)
1016
+ if (key === '\u001b[A') { // Up arrow
1017
+ selectedIndex = selectedIndex > 0 ? selectedIndex - 1 : projects.length - 1
1018
+ renderOptions()
1019
+ } else if (key === '\u001b[B') { // Down arrow
1020
+ selectedIndex = selectedIndex < projects.length - 1 ? selectedIndex + 1 : 0
1021
+ renderOptions()
1022
+ }
1023
+ }
1024
+
1025
+ process.stdin.on('data', onKeyPress)
1026
+ })
1027
+ }
1028
+
1029
+ async function startProyectosSelectorFallback() {
1030
+ const rl = createInterface({
1031
+ input: process.stdin,
1032
+ output: process.stdout
1033
+ })
1034
+
1035
+ const askQuestion = (question) => {
1036
+ return new Promise((resolve) => {
1037
+ rl.question(question, resolve)
1038
+ })
1039
+ }
1040
+
1041
+ try {
1042
+ console.log("\n🚀 Proyectos Disponibles")
1043
+ console.log("¿Qué proyecto quieres crear?")
1044
+ console.log("")
1045
+ console.log("1. 🎨 Portafolio Personal - Reto completo")
1046
+ console.log("2. 🔓 Portafolio Nivel 1 - Solo navbar")
1047
+ console.log("3. 🔓 Portafolio Nivel 2 - Navbar + hero")
1048
+ console.log("4. 🔓 Portafolio Nivel 3 - Solución completa")
1049
+ console.log("")
1050
+
1051
+ const respuesta = await askQuestion("Elige una opción (1-4) o 'q' para salir: ")
1052
+
1053
+ if (respuesta.toLowerCase() === 'q') {
1054
+ console.log("¡Hasta la vista! 👋")
1055
+ rl.close()
1056
+ return
1057
+ }
1058
+
1059
+ const opcionSeleccionada = parseInt(respuesta)
1060
+
1061
+ if (opcionSeleccionada >= 1 && opcionSeleccionada <= 4) {
1062
+ rl.close()
1063
+
1064
+ // Map selection to portfolio level
1065
+ const level = opcionSeleccionada === 1 ? 0 : opcionSeleccionada - 1
1066
+
1067
+ // Check if we're in an existing Creta project
1068
+ if (level > 0 && isInCretaProject()) {
1069
+ await unstuckProject(level)
1070
+ } else {
1071
+ await createPortfolioProject(level)
1072
+ }
1073
+ } else {
1074
+ console.log("❌ Opción no válida. Elige un número entre 1 y 4.")
1075
+ rl.close()
1076
+ }
1077
+
1078
+ } catch (error) {
1079
+ console.error('Error:', error.message)
1080
+ rl.close()
1081
+ process.exit(1)
1082
+ }
1083
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icarusmx/creta",
3
- "version": "0.7.3",
3
+ "version": "0.8.1",
4
4
  "description": "Salgamos de este laberinto.",
5
5
  "type": "module",
6
6
  "bin": {