@icarusmx/creta 1.4.17 → 1.4.19
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/lib/cli/index.js +13 -0
- package/lib/customizers/TerminalCustomizer.js +275 -0
- package/package.json +1 -1
- package/wea-fome-qlia.sh +92 -0
package/lib/cli/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { showHelp } from '../commands/help.js'
|
|
|
8
8
|
import { CretaCodeSession } from '../session.js'
|
|
9
9
|
import { greetUser } from '../utils/greeting.js'
|
|
10
10
|
import { SandboxManager } from '../sandbox/SandboxManager.js'
|
|
11
|
+
import TerminalCustomizer from '../customizers/TerminalCustomizer.js'
|
|
11
12
|
|
|
12
13
|
async function executeMainMenu() {
|
|
13
14
|
const menu = new MenuBuilder(getMainMenuConfig())
|
|
@@ -40,6 +41,16 @@ async function resetUserState() {
|
|
|
40
41
|
console.log('✅ Estado de usuario reiniciado. La próxima vez que ejecutes creta, se te pedirá tu nombre de nuevo.')
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
async function customizeTerminal() {
|
|
45
|
+
const customizer = new TerminalCustomizer()
|
|
46
|
+
await customizer.customize()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function revertTerminal() {
|
|
50
|
+
const customizer = new TerminalCustomizer()
|
|
51
|
+
await customizer.revert()
|
|
52
|
+
}
|
|
53
|
+
|
|
43
54
|
const COMMANDS = new Map([
|
|
44
55
|
['enunciados', () => executeEnunciados()],
|
|
45
56
|
['sintaxis', () => executeSintaxis()],
|
|
@@ -47,6 +58,8 @@ const COMMANDS = new Map([
|
|
|
47
58
|
['portafolio', () => executePortfolio(0)],
|
|
48
59
|
['code', () => runCodeSession()],
|
|
49
60
|
['reset', () => resetUserState()],
|
|
61
|
+
['icarus-terminal', () => customizeTerminal()],
|
|
62
|
+
['revert-terminal', () => revertTerminal()],
|
|
50
63
|
['help', () => showHelp()],
|
|
51
64
|
['ayuda', () => showHelp()]
|
|
52
65
|
])
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import { UserState } from '../utils/user-state.js';
|
|
6
|
+
|
|
7
|
+
class TerminalCustomizer {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.homeDir = os.homedir();
|
|
10
|
+
this.zshrcPath = path.join(this.homeDir, '.zshrc');
|
|
11
|
+
this.icarusZshPath = path.join(this.homeDir, '.icarus-zsh');
|
|
12
|
+
this.tips = this.initializeTips();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
initializeTips() {
|
|
16
|
+
return {
|
|
17
|
+
'terminal-basico': [
|
|
18
|
+
'💡 Usa "cd -" para volver al directorio anterior',
|
|
19
|
+
'💡 "pwd" muestra tu ubicación actual en el sistema',
|
|
20
|
+
'💡 "ls -la" muestra archivos ocultos y permisos',
|
|
21
|
+
'💡 Usa Tab para autocompletar nombres de archivos'
|
|
22
|
+
],
|
|
23
|
+
'git-basico': [
|
|
24
|
+
'💡 Siempre usa "git status" antes de hacer commit',
|
|
25
|
+
'💡 "git log --oneline" muestra el historial compacto',
|
|
26
|
+
'💡 "git diff" te muestra los cambios antes de commit',
|
|
27
|
+
'💡 Commits frecuentes = mejor historial'
|
|
28
|
+
],
|
|
29
|
+
'piping-redireccion': [
|
|
30
|
+
'💡 El pipe "|" conecta la salida de un comando con otro',
|
|
31
|
+
'💡 ">" sobrescribe archivos, ">>" agrega al final',
|
|
32
|
+
'💡 "grep" es tu mejor amigo para buscar en texto'
|
|
33
|
+
],
|
|
34
|
+
'bash-scripts': [
|
|
35
|
+
'💡 Usa "chmod +x script.sh" para hacer ejecutable tu script',
|
|
36
|
+
'💡 Siempre empieza con "#!/bin/bash" en la primera línea',
|
|
37
|
+
'💡 "$?" te dice el código de salida del último comando'
|
|
38
|
+
],
|
|
39
|
+
'portafolio': [
|
|
40
|
+
'💡 "npm run dev" para ver cambios en tiempo real',
|
|
41
|
+
'💡 Tailwind CSS usa clases utilitarias, no CSS custom',
|
|
42
|
+
'💡 Usa "md:" para breakpoints responsive en Tailwind',
|
|
43
|
+
'💡 SvelteKit recarga automáticamente al guardar cambios'
|
|
44
|
+
],
|
|
45
|
+
'general': [
|
|
46
|
+
'💡 Lee los errores completos, suelen decirte qué hacer',
|
|
47
|
+
'💡 Google es tu amigo, pero StackOverflow más',
|
|
48
|
+
'💡 Commits pequeños y frecuentes > commits gigantes',
|
|
49
|
+
'💡 Comenta tu código como si fueras a olvidarlo mañana'
|
|
50
|
+
]
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
getContextualTip() {
|
|
55
|
+
const userState = UserState.get();
|
|
56
|
+
const recentLessons = userState.lessonsCompleted.slice(-3);
|
|
57
|
+
|
|
58
|
+
// Try to get a tip from recently completed lessons
|
|
59
|
+
for (const lesson of recentLessons.reverse()) {
|
|
60
|
+
const lessonId = typeof lesson === 'object' ? lesson.id : lesson;
|
|
61
|
+
if (this.tips[lessonId] && this.tips[lessonId].length > 0) {
|
|
62
|
+
const tips = this.tips[lessonId];
|
|
63
|
+
return tips[Math.floor(Math.random() * tips.length)];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Fallback to general tips
|
|
68
|
+
const generalTips = this.tips.general;
|
|
69
|
+
return generalTips[Math.floor(Math.random() * generalTips.length)];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async customize() {
|
|
73
|
+
console.log('\n🏛️ Configurando tu terminal Creta...\n');
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
// Backup existing .zshrc if it exists
|
|
77
|
+
if (fs.existsSync(this.zshrcPath)) {
|
|
78
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
79
|
+
const backupPath = `${this.zshrcPath}.backup.${timestamp}`;
|
|
80
|
+
fs.copyFileSync(this.zshrcPath, backupPath);
|
|
81
|
+
console.log(`✅ Backup creado: ${backupPath}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Create ~/.icarus-zsh with custom configuration
|
|
85
|
+
this.createIcarusZsh();
|
|
86
|
+
console.log(`✅ Configuración creada: ${this.icarusZshPath}`);
|
|
87
|
+
|
|
88
|
+
// Add source line to .zshrc if not already present
|
|
89
|
+
this.updateZshrc();
|
|
90
|
+
console.log(`✅ Terminal configurado`);
|
|
91
|
+
|
|
92
|
+
// Apply changes instantly
|
|
93
|
+
this.applyChanges();
|
|
94
|
+
|
|
95
|
+
console.log('\n🎉 ¡Terminal Creta configurado exitosamente!');
|
|
96
|
+
console.log('💡 Reinicia tu terminal o ejecuta: source ~/.zshrc\n');
|
|
97
|
+
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error('❌ Error al configurar el terminal:', error.message);
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
createIcarusZsh() {
|
|
105
|
+
const tip = this.getContextualTip();
|
|
106
|
+
const roadmapHint = this.getRoadmapHint();
|
|
107
|
+
|
|
108
|
+
// Use template literal with escaped $ to prevent Node.js interpolation
|
|
109
|
+
const config = `# ========================================
|
|
110
|
+
# 🏛️ Creta Terminal Configuration
|
|
111
|
+
# ========================================
|
|
112
|
+
|
|
113
|
+
# Custom prompt with color #007acc
|
|
114
|
+
autoload -U colors && colors
|
|
115
|
+
setopt PROMPT_SUBST
|
|
116
|
+
|
|
117
|
+
# Prompt color codes
|
|
118
|
+
CRETA_BLUE='%F{39}'
|
|
119
|
+
RESET='%f'
|
|
120
|
+
GIT_BRANCH_COLOR='%F{245}' # Gray for branch
|
|
121
|
+
|
|
122
|
+
# Git branch detection function
|
|
123
|
+
function git_branch_name() {
|
|
124
|
+
git symbolic-ref --short HEAD 2>/dev/null || echo ""
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function git_prompt_info() {
|
|
128
|
+
local branch=\$(git_branch_name)
|
|
129
|
+
if [[ -n "\$branch" ]]; then
|
|
130
|
+
echo " | \${branch}"
|
|
131
|
+
fi
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# Custom prompt: [🏛️ creta | branch] ~/path $
|
|
135
|
+
PROMPT="\${CRETA_BLUE}[🏛️ creta\${GIT_BRANCH_COLOR}\$(git_prompt_info)\${CRETA_BLUE}]\${RESET} %~ $ "
|
|
136
|
+
|
|
137
|
+
# Welcome message function
|
|
138
|
+
function creta_welcome() {
|
|
139
|
+
print ""
|
|
140
|
+
print -P "\${CRETA_BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\${RESET}"
|
|
141
|
+
print -P "\${CRETA_BLUE} 🏛️ Bienvenido a Creta Terminal\${RESET}"
|
|
142
|
+
print -P "\${CRETA_BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\${RESET}"
|
|
143
|
+
print ""
|
|
144
|
+
|
|
145
|
+
# Show contextual tip
|
|
146
|
+
echo "${tip.replace(/"/g, '\\"')}"
|
|
147
|
+
|
|
148
|
+
# Show roadmap hint if available
|
|
149
|
+
if [[ -f "roadmap.txt" ]]; then
|
|
150
|
+
local next_item=\$(grep -v "^#" roadmap.txt | head -n 1)
|
|
151
|
+
if [[ -n "\$next_item" ]]; then
|
|
152
|
+
echo ""
|
|
153
|
+
echo "📋 Siguiente en roadmap: \$next_item"
|
|
154
|
+
fi
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
print ""
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
# Show welcome message
|
|
161
|
+
creta_welcome
|
|
162
|
+
`;
|
|
163
|
+
|
|
164
|
+
fs.writeFileSync(this.icarusZshPath, config, 'utf8');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
getRoadmapHint() {
|
|
168
|
+
// This is a placeholder - actual parsing happens in the shell script
|
|
169
|
+
// We could potentially read roadmap.txt here if we want to customize the message
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
updateZshrc() {
|
|
174
|
+
const sourceLine = '\n# Source Creta terminal configuration\n[ -f ~/.icarus-zsh ] && source ~/.icarus-zsh\n';
|
|
175
|
+
|
|
176
|
+
// Create .zshrc if it doesn't exist
|
|
177
|
+
if (!fs.existsSync(this.zshrcPath)) {
|
|
178
|
+
fs.writeFileSync(this.zshrcPath, sourceLine, 'utf8');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Check if already sourced
|
|
183
|
+
const currentContent = fs.readFileSync(this.zshrcPath, 'utf8');
|
|
184
|
+
if (currentContent.includes('source ~/.icarus-zsh') || currentContent.includes('. ~/.icarus-zsh')) {
|
|
185
|
+
console.log('⚠️ Creta ya estaba configurado en .zshrc (actualizando)');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Append source line
|
|
190
|
+
fs.appendFileSync(this.zshrcPath, sourceLine, 'utf8');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
applyChanges() {
|
|
194
|
+
try {
|
|
195
|
+
// Note: This won't change the current terminal session's prompt,
|
|
196
|
+
// but it will be applied in new sessions
|
|
197
|
+
execSync('source ~/.zshrc', { shell: '/bin/zsh', stdio: 'inherit' });
|
|
198
|
+
} catch (error) {
|
|
199
|
+
// Source command may fail in some contexts, but config is still written
|
|
200
|
+
// User can manually source or restart terminal
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async revert() {
|
|
205
|
+
console.log('\n🔄 Revirtiendo configuración de Creta Terminal...\n');
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
let changesMade = false;
|
|
209
|
+
|
|
210
|
+
// Remove ~/.icarus-zsh if it exists
|
|
211
|
+
if (fs.existsSync(this.icarusZshPath)) {
|
|
212
|
+
fs.unlinkSync(this.icarusZshPath);
|
|
213
|
+
console.log('✅ Archivo ~/.icarus-zsh eliminado');
|
|
214
|
+
changesMade = true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Remove source line from .zshrc
|
|
218
|
+
if (fs.existsSync(this.zshrcPath)) {
|
|
219
|
+
const currentContent = fs.readFileSync(this.zshrcPath, 'utf8');
|
|
220
|
+
|
|
221
|
+
if (currentContent.includes('source ~/.icarus-zsh') || currentContent.includes('. ~/.icarus-zsh')) {
|
|
222
|
+
// Remove the entire Creta block (comment + source line)
|
|
223
|
+
const cleanedContent = currentContent
|
|
224
|
+
.replace(/\n# Source Creta terminal configuration\n\[ -f ~\/\.icarus-zsh \] && source ~\/\.icarus-zsh\n/g, '')
|
|
225
|
+
.replace(/\n# Source Icarus terminal configuration\n\[ -f ~\/\.icarus-zsh \] && source ~\/\.icarus-zsh\n/g, '');
|
|
226
|
+
|
|
227
|
+
fs.writeFileSync(this.zshrcPath, cleanedContent, 'utf8');
|
|
228
|
+
console.log('✅ Configuración eliminada de ~/.zshrc');
|
|
229
|
+
changesMade = true;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!changesMade) {
|
|
234
|
+
console.log('⚠️ No se encontró configuración de Creta para revertir');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Show available backups
|
|
239
|
+
this.showBackups();
|
|
240
|
+
|
|
241
|
+
console.log('\n🎉 ¡Configuración revertida exitosamente!');
|
|
242
|
+
console.log('💡 Reinicia tu terminal o ejecuta: source ~/.zshrc\n');
|
|
243
|
+
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error('❌ Error al revertir configuración:', error.message);
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
showBackups() {
|
|
251
|
+
try {
|
|
252
|
+
const backupFiles = fs.readdirSync(this.homeDir)
|
|
253
|
+
.filter(file => file.startsWith('.zshrc.backup.'))
|
|
254
|
+
.sort()
|
|
255
|
+
.reverse()
|
|
256
|
+
.slice(0, 5); // Show last 5 backups
|
|
257
|
+
|
|
258
|
+
if (backupFiles.length > 0) {
|
|
259
|
+
console.log('\n📦 Backups disponibles (últimos 5):');
|
|
260
|
+
backupFiles.forEach((file, index) => {
|
|
261
|
+
const filepath = path.join(this.homeDir, file);
|
|
262
|
+
const stats = fs.statSync(filepath);
|
|
263
|
+
const date = stats.mtime.toLocaleString('es-MX');
|
|
264
|
+
console.log(` ${index + 1}. ${file} (${date})`);
|
|
265
|
+
});
|
|
266
|
+
console.log('\n💡 Para restaurar un backup manualmente:');
|
|
267
|
+
console.log(' cp ~/.zshrc.backup.TIMESTAMP ~/.zshrc');
|
|
268
|
+
}
|
|
269
|
+
} catch (error) {
|
|
270
|
+
// Silent fail - backups are optional
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export default TerminalCustomizer;
|
package/package.json
CHANGED
package/wea-fome-qlia.sh
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Summarize a repository's architecture via codex using lightweight bash reconnaissance.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
show_help() {
|
|
6
|
+
cat <<'USAGE'
|
|
7
|
+
Usage: wea-fome-qlia.sh [path-to-repo]
|
|
8
|
+
|
|
9
|
+
Collects structural signals from the repository using basic shell commands
|
|
10
|
+
and streams them into `codex -p` to obtain a five-sentence architecture summary.
|
|
11
|
+
Set the SUMMARIZER_PROMPT environment variable to override the default prompt.
|
|
12
|
+
USAGE
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if [[ ${1:-} == "-h" || ${1:-} == "--help" ]]; then
|
|
16
|
+
show_help
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
if (( $# > 1 )); then
|
|
21
|
+
echo "Only zero or one path argument is supported." >&2
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
REPO_DIR=${1:-.}
|
|
26
|
+
if [[ ! -d "$REPO_DIR" ]]; then
|
|
27
|
+
echo "The path '$REPO_DIR' is not a directory." >&2
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
if [[ -z ${BASH_VERSION:-} ]]; then
|
|
32
|
+
echo "This script requires bash. Run it as './wea-fome-qlia.sh' or 'bash wea-fome-qlia.sh'." >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
if ! command -v codex >/dev/null 2>&1; then
|
|
37
|
+
echo "The 'codex' CLI is required but was not found in PATH." >&2
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
REPO_DIR=$(cd "$REPO_DIR" && pwd)
|
|
42
|
+
TEMP_INPUT=$(mktemp)
|
|
43
|
+
trap 'rm -f "$TEMP_INPUT"' EXIT
|
|
44
|
+
|
|
45
|
+
MAX_DIRS=8
|
|
46
|
+
MAX_ITEMS=12
|
|
47
|
+
PROMPT=${SUMMARIZER_PROMPT:-"You are a senior software architect. Using the repository signals provided, write exactly five sentences that explain the current architecture, main modules, dominant technologies, notable build or tooling traits, and any potential work-in-progress areas."}
|
|
48
|
+
|
|
49
|
+
{
|
|
50
|
+
echo "Repository: $REPO_DIR"
|
|
51
|
+
echo
|
|
52
|
+
echo "Top-level entries (ls):"
|
|
53
|
+
ls -1A "$REPO_DIR" | sed 's/^/ - /'
|
|
54
|
+
|
|
55
|
+
echo
|
|
56
|
+
echo "Directory snapshots:"
|
|
57
|
+
dir_count=0
|
|
58
|
+
while IFS= read -r entry; do
|
|
59
|
+
[[ -z "$entry" ]] && continue
|
|
60
|
+
path="$REPO_DIR/$entry"
|
|
61
|
+
if [[ -d "$path" ]]; then
|
|
62
|
+
((dir_count++))
|
|
63
|
+
echo "* $entry"
|
|
64
|
+
ls -1A "$path" | head -n "$MAX_ITEMS" | sed 's/^/ /'
|
|
65
|
+
if command -v git >/dev/null 2>&1; then
|
|
66
|
+
echo " (files: $(ls -1A "$path" | wc -l | tr -d ' '))"
|
|
67
|
+
fi
|
|
68
|
+
echo
|
|
69
|
+
fi
|
|
70
|
+
if (( dir_count >= MAX_DIRS )); then
|
|
71
|
+
break
|
|
72
|
+
fi
|
|
73
|
+
done <<EOF
|
|
74
|
+
$(ls -1A "$REPO_DIR")
|
|
75
|
+
EOF
|
|
76
|
+
|
|
77
|
+
if command -v git >/dev/null 2>&1 && git -C "$REPO_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
78
|
+
echo "Git status:"
|
|
79
|
+
git -C "$REPO_DIR" status -sb
|
|
80
|
+
|
|
81
|
+
echo
|
|
82
|
+
echo "Recent commits:"
|
|
83
|
+
git -C "$REPO_DIR" log -5 --oneline
|
|
84
|
+
fi
|
|
85
|
+
} > "$TEMP_INPUT"
|
|
86
|
+
|
|
87
|
+
{
|
|
88
|
+
printf '%s\n\n' "$PROMPT"
|
|
89
|
+
echo '--- Repository signals start ---'
|
|
90
|
+
cat "$TEMP_INPUT"
|
|
91
|
+
echo '--- Repository signals end ---'
|
|
92
|
+
} | codex exec -
|