@icarusmx/creta 1.5.15 → 1.5.16
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 +5 -1
- package/lib/readers/exercise-reader.js +89 -1
- package/package.json +1 -1
package/bin/creta.js
CHANGED
|
@@ -10,7 +10,7 @@ import { PullRequestTutorial } from '../lib/pr-tutorial.js'
|
|
|
10
10
|
import { VimSetupTutorial } from '../lib/vim-setup-tutorial.js'
|
|
11
11
|
import { AWSGuideViewer } from '../lib/aws-guide-viewer.js'
|
|
12
12
|
import { CommandHelpExecutor } from '../lib/executors/CommandHelpExecutor.js'
|
|
13
|
-
import { readExercise, listExercises } from '../lib/readers/exercise-reader.js'
|
|
13
|
+
import { readExercise, listExercises, syncBiblioteca } from '../lib/readers/exercise-reader.js'
|
|
14
14
|
import { PapersExecutor } from '../lib/papers/PapersExecutor.js'
|
|
15
15
|
import { ExercisesExecutor } from '../lib/executors/ExercisesExecutor.js'
|
|
16
16
|
import { executeSintaxis } from '../lib/executors/sintaxis-executor.js'
|
|
@@ -193,6 +193,9 @@ if (command.startsWith('portafolio')) {
|
|
|
193
193
|
} else if (command === 'exercises' || command === 'ejercicios') {
|
|
194
194
|
// List all exercises
|
|
195
195
|
await listExercises()
|
|
196
|
+
} else if (command === 'biblioteca') {
|
|
197
|
+
// Sync exercises to ~/.creta/biblioteca
|
|
198
|
+
await syncBiblioteca()
|
|
196
199
|
} else if (command === 'help' || command === 'ayuda') {
|
|
197
200
|
// Show available commands
|
|
198
201
|
showHelp()
|
|
@@ -708,6 +711,7 @@ function showHelp() {
|
|
|
708
711
|
console.log(" creta code - Sesión interactiva de programación con IA\n")
|
|
709
712
|
|
|
710
713
|
console.log("🔧 Utilidades:")
|
|
714
|
+
console.log(" creta biblioteca - Sincroniza ejercicios a ~/.creta/biblioteca/")
|
|
711
715
|
console.log(" creta reset - Reinicia tu progreso (elimina ~/.creta/user.json)")
|
|
712
716
|
console.log(" creta privacy - Explica qué datos guarda Creta y dónde\n")
|
|
713
717
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { readFileSync, readdirSync } from 'fs'
|
|
1
|
+
import { readFileSync, readdirSync, existsSync, mkdirSync, copyFileSync, statSync } from 'fs'
|
|
2
2
|
import { join, dirname } from 'path'
|
|
3
3
|
import { fileURLToPath } from 'url'
|
|
4
|
+
import { homedir } from 'os'
|
|
4
5
|
import chalk from 'chalk'
|
|
5
6
|
|
|
6
7
|
const __filename = fileURLToPath(import.meta.url)
|
|
@@ -9,6 +10,78 @@ const __dirname = dirname(__filename)
|
|
|
9
10
|
export class ExerciseReader {
|
|
10
11
|
constructor() {
|
|
11
12
|
this.exercisesDir = join(__dirname, '../exercises')
|
|
13
|
+
this.bibliotecaDir = join(homedir(), '.creta', 'biblioteca')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Ensure biblioteca directory exists and sync exercises
|
|
18
|
+
*/
|
|
19
|
+
syncBiblioteca(silent = false) {
|
|
20
|
+
try {
|
|
21
|
+
// Create directory if needed
|
|
22
|
+
if (!existsSync(this.bibliotecaDir)) {
|
|
23
|
+
mkdirSync(this.bibliotecaDir, { recursive: true })
|
|
24
|
+
if (!silent) {
|
|
25
|
+
console.log(chalk.cyan('\n📚 Creando biblioteca en ~/.creta/biblioteca...'))
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Get all exercise files
|
|
30
|
+
const exercises = this.getAvailableExercises()
|
|
31
|
+
let copied = 0
|
|
32
|
+
let updated = 0
|
|
33
|
+
let skipped = 0
|
|
34
|
+
|
|
35
|
+
exercises.forEach(exercise => {
|
|
36
|
+
const sourcePath = join(this.exercisesDir, exercise.filename)
|
|
37
|
+
const destPath = join(this.bibliotecaDir, exercise.filename)
|
|
38
|
+
|
|
39
|
+
// Check if destination exists and is up to date
|
|
40
|
+
if (existsSync(destPath)) {
|
|
41
|
+
const sourceStats = statSync(sourcePath)
|
|
42
|
+
const destStats = statSync(destPath)
|
|
43
|
+
|
|
44
|
+
if (sourceStats.mtime > destStats.mtime) {
|
|
45
|
+
copyFileSync(sourcePath, destPath)
|
|
46
|
+
updated++
|
|
47
|
+
} else {
|
|
48
|
+
skipped++
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
copyFileSync(sourcePath, destPath)
|
|
52
|
+
copied++
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
if (!silent) {
|
|
57
|
+
console.log(chalk.green('\n✅ Biblioteca sincronizada'))
|
|
58
|
+
if (copied > 0) console.log(chalk.gray(` ${copied} ejercicio${copied !== 1 ? 's' : ''} copiado${copied !== 1 ? 's' : ''}`))
|
|
59
|
+
if (updated > 0) console.log(chalk.gray(` ${updated} ejercicio${updated !== 1 ? 's' : ''} actualizado${updated !== 1 ? 's' : ''}`))
|
|
60
|
+
if (skipped > 0) console.log(chalk.gray(` ${skipped} ejercicio${skipped !== 1 ? 's' : ''} sin cambios`))
|
|
61
|
+
console.log(chalk.cyan(`\n💡 Abre ejercicios con: nvim ~/.creta/biblioteca/<archivo>.md`))
|
|
62
|
+
console.log(chalk.gray(` Ejemplo: nvim ~/.creta/biblioteca/14-gh-fundamentals.md\n`))
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return { copied, updated, skipped, total: exercises.length }
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (!silent) {
|
|
68
|
+
console.error(chalk.red('\n❌ Error sincronizando biblioteca:'), error.message)
|
|
69
|
+
}
|
|
70
|
+
return { copied: 0, updated: 0, skipped: 0, total: 0, error }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Check if biblioteca needs initialization (show tip on first read)
|
|
76
|
+
*/
|
|
77
|
+
checkBiblioteca() {
|
|
78
|
+
if (!existsSync(this.bibliotecaDir)) {
|
|
79
|
+
return {
|
|
80
|
+
exists: false,
|
|
81
|
+
message: chalk.dim(`\n💡 Tip: Ejecuta ${chalk.cyan('creta biblioteca')} para copiar ejercicios a ~/.creta/biblioteca/\n Así podrás abrirlos en nvim con fold markers.`)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { exists: true, message: null }
|
|
12
85
|
}
|
|
13
86
|
|
|
14
87
|
/**
|
|
@@ -94,6 +167,13 @@ export class ExerciseReader {
|
|
|
94
167
|
const content = readFileSync(filepath, 'utf-8')
|
|
95
168
|
|
|
96
169
|
this.displayExercise(exercise, content)
|
|
170
|
+
|
|
171
|
+
// Show biblioteca tip on first read
|
|
172
|
+
const bibliotecaStatus = this.checkBiblioteca()
|
|
173
|
+
if (!bibliotecaStatus.exists && bibliotecaStatus.message) {
|
|
174
|
+
console.log(bibliotecaStatus.message)
|
|
175
|
+
}
|
|
176
|
+
|
|
97
177
|
return true
|
|
98
178
|
} catch (error) {
|
|
99
179
|
console.error(chalk.red('❌ Error leyendo ejercicio:'), error.message)
|
|
@@ -195,3 +275,11 @@ export async function listExercises() {
|
|
|
195
275
|
const reader = new ExerciseReader()
|
|
196
276
|
reader.list()
|
|
197
277
|
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Sync biblioteca CLI entry point
|
|
281
|
+
*/
|
|
282
|
+
export async function syncBiblioteca() {
|
|
283
|
+
const reader = new ExerciseReader()
|
|
284
|
+
reader.syncBiblioteca()
|
|
285
|
+
}
|