g360-cli 1.3.0 → 1.5.0

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 (86) hide show
  1. package/README.md +209 -5
  2. package/package.json +15 -8
  3. package/src/assets/brand/brand.json +43 -0
  4. package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.png +0 -0
  5. package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.svg +9 -0
  6. package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.png +0 -0
  7. package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.svg +9 -0
  8. package/src/assets/brand/g360/logotypes/logo-g360-dark.svg +19 -0
  9. package/src/assets/brand/g360/logotypes/logo-g360-light.svg +19 -0
  10. package/src/assets/brand/g360/logotypes/logo_g360_dark_b64.txt +1 -0
  11. package/src/assets/brand/g360/logotypes/logo_g360_light_b64.txt +1 -0
  12. package/src/assets/config/g360-skills.json +112 -0
  13. package/src/assets/config/project-types.json +16 -0
  14. package/src/assets/config/skills.json +12 -0
  15. package/src/assets/snippets/snippets.json +293 -24
  16. package/src/assets/templates/lit-web/src/core/skill.json +12 -5
  17. package/src/assets/templates/python-cli/build-portable.bat +43 -0
  18. package/src/assets/templates/python-cli/src/core/skill.json +25 -6
  19. package/src/assets/templates/python-cli/src/main.py +107 -3
  20. package/src/assets/templates/python-customtkinter/README.md +48 -0
  21. package/src/assets/templates/python-customtkinter/assets/images/logo-g360-dark.svg +19 -0
  22. package/src/assets/templates/python-customtkinter/assets/images/logo-g360-light.svg +19 -0
  23. package/src/assets/templates/python-customtkinter/build.bat +50 -0
  24. package/src/assets/templates/python-customtkinter/pyproject.toml +26 -0
  25. package/src/assets/templates/python-customtkinter/run.bat +20 -0
  26. package/src/assets/templates/python-customtkinter/src/core/g360_theme.py +101 -0
  27. package/src/assets/templates/python-customtkinter/src/core/skill.json +35 -0
  28. package/src/assets/templates/python-customtkinter/src/main.py +103 -0
  29. package/src/assets/templates/python-flet/README.md +89 -0
  30. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.png +0 -0
  31. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.svg +9 -0
  32. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.png +0 -0
  33. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.svg +9 -0
  34. package/src/assets/templates/python-flet/assets/images/logo-g360-dark.svg +19 -0
  35. package/src/assets/templates/python-flet/assets/images/logo-g360-light.svg +19 -0
  36. package/src/assets/templates/python-flet/build.bat +36 -0
  37. package/src/assets/templates/python-flet/pyproject.toml +26 -0
  38. package/src/assets/templates/python-flet/run.bat +20 -0
  39. package/src/assets/templates/python-flet/src/core/__init__.py +0 -0
  40. package/src/assets/templates/python-flet/src/core/g360_theme.py +186 -0
  41. package/src/assets/templates/python-flet/src/core/skill.json +41 -0
  42. package/src/assets/templates/python-flet/src/export/__init__.py +0 -0
  43. package/src/assets/templates/python-flet/src/main.py +146 -0
  44. package/src/assets/templates/python-flet/src/test_app.py +107 -0
  45. package/src/assets/templates/python-flet/src/ui/__init__.py +0 -0
  46. package/src/assets/templates/python-flet-migrate/README.md +70 -0
  47. package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-dark.svg +19 -0
  48. package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-light.svg +19 -0
  49. package/src/assets/templates/python-flet-migrate/build.bat +36 -0
  50. package/src/assets/templates/python-flet-migrate/pyproject.toml +26 -0
  51. package/src/assets/templates/python-flet-migrate/run.bat +20 -0
  52. package/src/assets/templates/python-flet-migrate/src/core/__init__.py +0 -0
  53. package/src/assets/templates/python-flet-migrate/src/core/g360_theme.py +186 -0
  54. package/src/assets/templates/python-flet-migrate/src/core/skill.json +34 -0
  55. package/src/assets/templates/python-flet-migrate/src/main.py +97 -0
  56. package/src/assets/templates/python-flet-migrate/src/migrate_tkinter.py +56 -0
  57. package/src/assets/templates/solid-web/src/core/skill.json +12 -5
  58. package/src/assets/templates/svelte-web/src/core/skill.json +12 -5
  59. package/src/assets/templates/web-pwa/index.html +2 -7
  60. package/src/assets/templates/web-pwa/public/favicon.svg +4 -0
  61. package/src/assets/templates/web-pwa/public/manifest.json +11 -0
  62. package/src/assets/templates/web-pwa/src/App.jsx +22 -0
  63. package/src/assets/templates/web-pwa/src/components/FooterSignature.jsx +9 -0
  64. package/src/assets/templates/web-pwa/src/components/Header.jsx +12 -0
  65. package/src/assets/templates/web-pwa/src/components/LoadingOverlay.jsx +10 -0
  66. package/src/assets/templates/web-pwa/src/core/skill.json +25 -0
  67. package/src/assets/templates/web-pwa/src/main.jsx +9 -0
  68. package/src/assets/templates/web-pwa/src/styles/main.css +133 -0
  69. package/src/assets/templates/web-pwa/vite.config.js +12 -0
  70. package/src/cli.js +8 -4
  71. package/src/commands/bring.js +81 -6
  72. package/src/commands/clean.js +51 -4
  73. package/src/commands/init.js +60 -8
  74. package/src/commands/list.js +79 -9
  75. package/src/commands/signature.js +12 -8
  76. package/src/lib/asset-validator.js +145 -0
  77. package/src/lib/auditor.js +48 -0
  78. package/src/lib/global-config.js +260 -0
  79. package/src/lib/i18n.js +238 -0
  80. package/src/lib/logger.js +100 -0
  81. package/src/lib/manifest.js +70 -1
  82. package/src/lib/validator.js +39 -0
  83. package/src/schemas/skills-schema.json +1 -0
  84. package/src/schemas/snippets-schema.json +1 -0
  85. package/src/assets/templates/web-pwa/app.js +0 -1
  86. package/src/assets/templates/web-pwa/styles.css +0 -28
@@ -0,0 +1,238 @@
1
+ /**
2
+ * @file i18n.js
3
+ * @description Sistema de internacionalización para G360-CLI
4
+ */
5
+
6
+ /**
7
+ * Traducciones disponibles
8
+ * @type {Object.<string, Object.<string, string>>}
9
+ */
10
+ const translations = {
11
+ es: {
12
+ // Comandos
13
+ 'command.init.title': '🚀 Inicialización de Proyecto G360',
14
+ 'command.init.project': 'Proyecto',
15
+ 'command.init.template': 'Plantilla',
16
+ 'command.init.skill': 'Skill',
17
+ 'command.init.target': 'Destino',
18
+ 'command.init.success': '✅ Proyecto creado exitosamente',
19
+ 'command.init.portable': '📦 Versión portable habilitada',
20
+ 'command.init.next_steps': 'Próximos pasos',
21
+
22
+ 'command.list.title': '📋 Assets G360',
23
+ 'command.list.templates': '📁 Plantillas',
24
+ 'command.list.components': '🧩 Componentes',
25
+ 'command.list.skills': '⚡ Skills',
26
+ 'command.list.snippets': '📝 Snippets',
27
+ 'command.list.no_templates': 'No se encontraron plantillas',
28
+ 'command.list.no_components': 'No se encontraron componentes',
29
+ 'command.list.no_skills': 'No se encontraron skills',
30
+ 'command.list.no_snippets': 'No se encontraron snippets',
31
+
32
+ 'command.set-skill.title': '🎨 Selector de Skill G360',
33
+ 'command.set-skill.success': '✅ Skill configurado correctamente',
34
+ 'command.set-skill.not_found': '❌ Skill no encontrado',
35
+ 'command.set-skill.already_exists': '⚠️ El proyecto ya tiene un skill configurado',
36
+ 'command.set-skill.use_force': 'Usa --force para sobrescribir',
37
+
38
+ 'command.audit.title': '🔍 Auditoría de Proyecto G360',
39
+ 'command.audit.results': '📊 Resultados de Auditoría',
40
+ 'command.audit.passed': 'Pasaron',
41
+ 'command.audit.failed': 'Fallaron',
42
+ 'command.audit.warnings': 'Advertencias',
43
+ 'command.audit.issues': 'Issues Encontrados',
44
+ 'command.audit.compliant': '✅ El proyecto es compliant con G360',
45
+ 'command.audit.issues_found': '⚠️ Algunos issues necesitan atención',
46
+
47
+ 'command.health.title': '🏥 Verificación de Salud G360',
48
+ 'command.health.status': 'Estado del Sistema',
49
+ 'command.health.healthy': '✅ El sistema está saludable',
50
+ 'command.health.failed': '❌ Algunos checks fallaron',
51
+
52
+ 'command.clean.title': '🧹 Limpieza de Proyecto G360',
53
+ 'command.clean.preview': '📋 DRY RUN - No se eliminarán archivos',
54
+ 'command.clean.success': '✅ Limpieza completada',
55
+
56
+ // Errores
57
+ 'error.templates_not_found': '❌ Plantillas no encontradas. Ejecuta: g360 update',
58
+ 'error.template_not_found': '❌ Plantilla no encontrada',
59
+ 'error.directory_exists': '❌ El directorio ya existe. Usa --force para sobrescribir',
60
+ 'error.path_not_found': '❌ Ruta no encontrada',
61
+ 'error.config_not_found': '❌ No se pudo cargar la configuración de skills',
62
+
63
+ // General
64
+ 'general.available': 'Disponibles',
65
+ 'general.device': 'Dispositivo',
66
+ 'general.description': 'Descripción',
67
+ 'general.language': 'Lenguaje',
68
+ 'general.loading': 'Cargando...',
69
+ 'general.done': 'Completado',
70
+ 'general.cancelled': 'Cancelado',
71
+ 'general.error': 'Error',
72
+ 'general.warning': 'Advertencia',
73
+ 'general.info': 'Información',
74
+ 'general.success': 'Éxito'
75
+ },
76
+
77
+ en: {
78
+ // Commands
79
+ 'command.init.title': '🚀 G360 Project Initialization',
80
+ 'command.init.project': 'Project',
81
+ 'command.init.template': 'Template',
82
+ 'command.init.skill': 'Skill',
83
+ 'command.init.target': 'Target',
84
+ 'command.init.success': '✅ Project created successfully',
85
+ 'command.init.portable': '📦 Portable version enabled',
86
+ 'command.init.next_steps': 'Next steps',
87
+
88
+ 'command.list.title': '📋 G360 Assets',
89
+ 'command.list.templates': '📁 Templates',
90
+ 'command.list.components': '🧩 Components',
91
+ 'command.list.skills': '⚡ Skills',
92
+ 'command.list.snippets': '📝 Snippets',
93
+ 'command.list.no_templates': 'No templates found',
94
+ 'command.list.no_components': 'No components found',
95
+ 'command.list.no_skills': 'No skills found',
96
+ 'command.list.no_snippets': 'No snippets found',
97
+
98
+ 'command.set-skill.title': '🎨 G360 Skill Selector',
99
+ 'command.set-skill.success': '✅ Skill configured successfully',
100
+ 'command.set-skill.not_found': '❌ Skill not found',
101
+ 'command.set-skill.already_exists': '⚠️ Project already has a skill configured',
102
+ 'command.set-skill.use_force': 'Use --force to overwrite',
103
+
104
+ 'command.audit.title': '🔍 G360 Project Audit',
105
+ 'command.audit.results': '📊 Audit Results',
106
+ 'command.audit.passed': 'Passed',
107
+ 'command.audit.failed': 'Failed',
108
+ 'command.audit.warnings': 'Warnings',
109
+ 'command.audit.issues': 'Issues Found',
110
+ 'command.audit.compliant': '✅ Project is G360 compliant',
111
+ 'command.audit.issues_found': '⚠️ Some issues need attention',
112
+
113
+ 'command.health.title': '🏥 G360 Health Check',
114
+ 'command.health.status': 'System Status',
115
+ 'command.health.healthy': '✅ System is healthy',
116
+ 'command.health.failed': '❌ Some checks failed',
117
+
118
+ 'command.clean.title': '🧹 G360 Project Clean',
119
+ 'command.clean.preview': '📋 DRY RUN - No files will be removed',
120
+ 'command.clean.success': '✅ Cleanup completed',
121
+
122
+ // Errors
123
+ 'error.templates_not_found': '❌ Templates not found. Run: g360 update',
124
+ 'error.template_not_found': '❌ Template not found',
125
+ 'error.directory_exists': '❌ Directory already exists. Use --force to overwrite',
126
+ 'error.path_not_found': '❌ Path not found',
127
+ 'error.config_not_found': '❌ Could not load skills configuration',
128
+
129
+ // General
130
+ 'general.available': 'Available',
131
+ 'general.device': 'Device',
132
+ 'general.description': 'Description',
133
+ 'general.language': 'Language',
134
+ 'general.loading': 'Loading...',
135
+ 'general.done': 'Done',
136
+ 'general.cancelled': 'Cancelled',
137
+ 'general.error': 'Error',
138
+ 'general.warning': 'Warning',
139
+ 'general.info': 'Info',
140
+ 'general.success': 'Success'
141
+ }
142
+ };
143
+
144
+ /**
145
+ * Idioma actual
146
+ * @type {string}
147
+ */
148
+ let currentLanguage = 'es';
149
+
150
+ /**
151
+ * Módulo de internacionalización para G360-CLI
152
+ * @namespace i18n
153
+ */
154
+ export const i18n = {
155
+ /**
156
+ * Establece el idioma actual
157
+ * @param {string} language - Código de idioma ('es' | 'en')
158
+ * @returns {void}
159
+ * @example
160
+ * i18n.setLanguage('en');
161
+ */
162
+ setLanguage(language) {
163
+ if (translations[language]) {
164
+ currentLanguage = language;
165
+ } else {
166
+ console.warn(`Language '${language}' not supported, using 'es'`);
167
+ }
168
+ },
169
+
170
+ /**
171
+ * Obtiene el idioma actual
172
+ * @returns {string} Código de idioma actual
173
+ * @example
174
+ * const lang = i18n.getLanguage();
175
+ */
176
+ getLanguage() {
177
+ return currentLanguage;
178
+ },
179
+
180
+ /**
181
+ * Traduce una clave de texto
182
+ * @param {string} key - Clave de traducción
183
+ * @param {Object} [params] - Parámetros para interpolación
184
+ * @returns {string} Texto traducido
185
+ * @example
186
+ * const text = i18n.t('command.init.success');
187
+ * const text = i18n.t('command.init.project', { name: 'my-project' });
188
+ */
189
+ t(key, params = {}) {
190
+ const lang = translations[currentLanguage] || translations.es;
191
+ let text = lang[key] || translations.es[key] || key;
192
+
193
+ // Interpolación de parámetros
194
+ Object.keys(params).forEach(param => {
195
+ text = text.replace(`{${param}}`, params[param]);
196
+ });
197
+
198
+ return text;
199
+ },
200
+
201
+ /**
202
+ * Verifica si una clave de traducción existe
203
+ * @param {string} key - Clave de traducción
204
+ * @returns {boolean} true si existe, false en caso contrario
205
+ * @example
206
+ * if (i18n.has('command.init.success')) {
207
+ * console.log(i18n.t('command.init.success'));
208
+ * }
209
+ */
210
+ has(key) {
211
+ const lang = translations[currentLanguage] || translations.es;
212
+ return key in lang;
213
+ },
214
+
215
+ /**
216
+ * Obtiene todos los idiomas disponibles
217
+ * @returns {string[]} Lista de códigos de idioma
218
+ * @example
219
+ * const languages = i18n.getAvailableLanguages();
220
+ * console.log('Available languages:', languages);
221
+ */
222
+ getAvailableLanguages() {
223
+ return Object.keys(translations);
224
+ },
225
+
226
+ /**
227
+ * Obtiene las traducciones para un idioma específico
228
+ * @param {string} language - Código de idioma
229
+ * @returns {Object|null} Objeto de traducciones o null si no existe
230
+ * @example
231
+ * const esTranslations = i18n.getTranslations('es');
232
+ */
233
+ getTranslations(language) {
234
+ return translations[language] || null;
235
+ }
236
+ };
237
+
238
+ export default i18n;
@@ -0,0 +1,100 @@
1
+ import winston from 'winston';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+
7
+ /**
8
+ * Niveles de log disponibles
9
+ * @enum {string}
10
+ */
11
+ const LogLevel = {
12
+ ERROR: 'error',
13
+ WARN: 'warn',
14
+ INFO: 'info',
15
+ DEBUG: 'debug'
16
+ };
17
+
18
+ /**
19
+ * Formato personalizado para logs
20
+ * @param {Object} info - Información del log
21
+ * @returns {string} Log formateado
22
+ */
23
+ const customFormat = winston.format.combine(
24
+ winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
25
+ winston.format.errors({ stack: true }),
26
+ winston.format.printf(({ level, message, timestamp, ...metadata }) => {
27
+ let msg = `${timestamp} [${level.toUpperCase()}]: ${message}`;
28
+
29
+ if (Object.keys(metadata).length > 0) {
30
+ msg += ` ${JSON.stringify(metadata)}`;
31
+ }
32
+
33
+ return msg;
34
+ })
35
+ );
36
+
37
+ /**
38
+ * Logger configurado para G360-CLI
39
+ * @type {winston.Logger}
40
+ */
41
+ export const logger = winston.createLogger({
42
+ level: process.env.LOG_LEVEL || 'info',
43
+ format: customFormat,
44
+ transports: [
45
+ // Console transport para desarrollo
46
+ new winston.transports.Console({
47
+ format: winston.format.combine(
48
+ winston.format.colorize(),
49
+ customFormat
50
+ )
51
+ }),
52
+
53
+ // File transport para logs persistentes
54
+ new winston.transports.File({
55
+ filename: path.join(__dirname, '../../logs/g360-cli.log'),
56
+ level: 'info',
57
+ maxsize: 5242880, // 5MB
58
+ maxFiles: 3
59
+ }),
60
+
61
+ // Error file transport
62
+ new winston.transports.File({
63
+ filename: path.join(__dirname, '../../logs/error.log'),
64
+ level: 'error',
65
+ maxsize: 5242880, // 5MB
66
+ maxFiles: 3
67
+ })
68
+ ]
69
+ });
70
+
71
+ /**
72
+ * Crea un logger hijo con contexto específico
73
+ * @param {string} context - Contexto del logger
74
+ * @returns {winston.Logger} Logger hijo con contexto
75
+ */
76
+ export function createChildLogger(context) {
77
+ return logger.child({ context });
78
+ }
79
+
80
+ /**
81
+ * Logger para comandos CLI
82
+ */
83
+ export const commandLogger = createChildLogger('command');
84
+
85
+ /**
86
+ * Logger para operaciones de archivos
87
+ */
88
+ export const fileLogger = createChildLogger('file');
89
+
90
+ /**
91
+ * Logger para validaciones
92
+ */
93
+ export const validationLogger = createChildLogger('validation');
94
+
95
+ /**
96
+ * Logger para auditoría
97
+ */
98
+ export const auditLogger = createChildLogger('audit');
99
+
100
+ export default logger;
@@ -1,7 +1,42 @@
1
1
  import fs from 'fs-extra';
2
2
  import path from 'path';
3
3
 
4
+ /**
5
+ * @typedef {Object} ProjectManifest
6
+ * @property {string} name - Nombre del proyecto
7
+ * @property {string} template - Plantilla utilizada
8
+ * @property {string} version - Versión del proyecto
9
+ * @property {string} createdAt - Fecha de creación en formato ISO
10
+ * @property {Asset[]} assets - Lista de assets del proyecto
11
+ */
12
+
13
+ /**
14
+ * @typedef {Object} Asset
15
+ * @property {string} name - Nombre del asset
16
+ * @property {string} type - Tipo del asset
17
+ * @property {string} addedAt - Fecha de adición en formato ISO
18
+ */
19
+
20
+ /**
21
+ * Módulo para gestión de manifiestos de proyectos G360
22
+ * @namespace manifest
23
+ */
4
24
  export const manifest = {
25
+ /**
26
+ * Inicializa un nuevo manifiesto de proyecto
27
+ * @param {string} projectDir - Directorio del proyecto
28
+ * @param {Object} data - Datos del proyecto
29
+ * @param {string} data.name - Nombre del proyecto
30
+ * @param {string} data.template - Plantilla utilizada
31
+ * @param {string} data.version - Versión del proyecto
32
+ * @returns {Promise<ProjectManifest>} Manifiesto creado
33
+ * @example
34
+ * const manifest = await manifest.init('/my/project', {
35
+ * name: 'my-project',
36
+ * template: 'web-pwa',
37
+ * version: '1.0.0'
38
+ * });
39
+ */
5
40
  async init(projectDir, data) {
6
41
  const manifestPath = path.join(projectDir, 'g360-manifest.json');
7
42
  const manifest = {
@@ -15,14 +50,41 @@ export const manifest = {
15
50
  return manifest;
16
51
  },
17
52
 
53
+ /**
54
+ * Carga el manifiesto de un proyecto existente
55
+ * @param {string} projectDir - Directorio del proyecto
56
+ * @returns {Promise<ProjectManifest|null>} Manifiesto del proyecto o null si no existe
57
+ * @example
58
+ * const manifest = await manifest.load('/my/project');
59
+ * if (manifest) {
60
+ * console.log('Proyecto:', manifest.name);
61
+ * }
62
+ */
18
63
  async load(projectDir) {
19
64
  const manifestPath = path.join(projectDir, 'g360-manifest.json');
20
65
  if (fs.existsSync(manifestPath)) {
21
- return fs.readJson(manifestPath);
66
+ try {
67
+ return await fs.readJson(manifestPath);
68
+ } catch (error) {
69
+ return null;
70
+ }
22
71
  }
23
72
  return null;
24
73
  },
25
74
 
75
+ /**
76
+ * Agrega un asset al manifiesto del proyecto
77
+ * @param {string} projectDir - Directorio del proyecto
78
+ * @param {Object} asset - Asset a agregar
79
+ * @param {string} asset.name - Nombre del asset
80
+ * @param {string} asset.type - Tipo del asset
81
+ * @returns {Promise<void>}
82
+ * @example
83
+ * await manifest.addAsset('/my/project', {
84
+ * name: 'components',
85
+ * type: 'directory'
86
+ * });
87
+ */
26
88
  async addAsset(projectDir, asset) {
27
89
  const data = await this.load(projectDir);
28
90
  if (data) {
@@ -34,6 +96,13 @@ export const manifest = {
34
96
  }
35
97
  },
36
98
 
99
+ /**
100
+ * Elimina el manifiesto del proyecto
101
+ * @param {string} projectDir - Directorio del proyecto
102
+ * @returns {Promise<void>}
103
+ * @example
104
+ * await manifest.remove('/my/project');
105
+ */
37
106
  async remove(projectDir) {
38
107
  const manifestPath = path.join(projectDir, 'g360-manifest.json');
39
108
  if (fs.existsSync(manifestPath)) {
@@ -1,10 +1,37 @@
1
1
  import fs from 'fs-extra';
2
2
 
3
+ /**
4
+ * @typedef {Object} ValidationResult
5
+ * @property {boolean} valid - Indica si la validación fue exitosa
6
+ * @property {string[]} errors - Lista de errores encontrados
7
+ * @property {string[]} warnings - Lista de advertencias encontradas
8
+ */
9
+
10
+ /**
11
+ * Módulo de validación para proyectos G360
12
+ * @namespace validator
13
+ */
3
14
  export const validator = {
15
+ /**
16
+ * Valida si un nombre de proyecto es válido
17
+ * @param {string} name - Nombre del proyecto a validar
18
+ * @returns {boolean} true si el nombre es válido, false en caso contrario
19
+ * @example
20
+ * validator.isValidProjectName('my-project') // true
21
+ * validator.isValidProjectName('My-Project') // false
22
+ */
4
23
  isValidProjectName(name) {
5
24
  return /^[a-z0-9][a-z0-9-]*$/.test(name);
6
25
  },
7
26
 
27
+ /**
28
+ * Valida si una ruta existe en el sistema de archivos
29
+ * @param {string} path - Ruta a validar
30
+ * @returns {boolean} true si la ruta existe, false en caso contrario
31
+ * @example
32
+ * validator.isValidPath('/existing/path') // true
33
+ * validator.isValidPath('/non/existing') // false
34
+ */
8
35
  isValidPath(path) {
9
36
  try {
10
37
  return fs.existsSync(path);
@@ -13,6 +40,18 @@ export const validator = {
13
40
  }
14
41
  },
15
42
 
43
+ /**
44
+ * Valida si un directorio es un proyecto G360 válido
45
+ * @param {string} projectDir - Ruta del directorio del proyecto
46
+ * @returns {ValidationResult} Objeto con resultado de la validación
47
+ * @example
48
+ * const result = validator.validateProject('/my/project');
49
+ * if (result.valid) {
50
+ * console.log('Proyecto válido');
51
+ * } else {
52
+ * console.error('Errores:', result.errors);
53
+ * }
54
+ */
16
55
  validateProject(projectDir) {
17
56
  const errors = [];
18
57
  const warnings = [];
@@ -0,0 +1 @@
1
+ {"$schema":"http://json-schema.org/draft-07/schema#","properties":{"skills":{"items":{"properties":{"colors":{"properties":{"accent":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"},"bg":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"},"muted":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"},"surface":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"},"text":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"}},"required":["bg","surface","accent","text","muted"],"type":"object"},"description":{"minLength":1,"type":"string"},"device":{"enum":["pc","movil","both"],"type":"string"},"name":{"pattern":"^[a-z0-9-]+$","type":"string"},"signature":{"properties":{"mode":{"enum":["powered","own","optional","custom"],"type":"string"},"text":{"minLength":1,"type":"string"}},"required":["mode","text"],"type":"object"}},"required":["name","description","device","colors","signature"],"type":"object"},"type":"array"}},"required":["skills"],"title":"G360 Skills Configuration","type":"object"}
@@ -0,0 +1 @@
1
+ {"$schema":"http://json-schema.org/draft-07/schema#","properties":{"snippets":{"items":{"properties":{"code":{"minLength":1,"type":"string"},"description":{"minLength":1,"type":"string"},"language":{"minLength":1,"type":"string"},"name":{"pattern":"^[a-z0-9-]+$","type":"string"}},"required":["name","description","code"],"type":"object"},"type":"array"}},"required":["snippets"],"title":"G360 Snippets Configuration","type":"object"}
@@ -1 +0,0 @@
1
- console.log('G360 Project initialized');
@@ -1,28 +0,0 @@
1
- :root {
2
- --g360-primary: #3B82F6;
3
- --g360-secondary: #10B981;
4
- --g360-accent: #8B5CF6;
5
- --g360-bg: #ffffff;
6
- --g360-text: #1f2937;
7
- }
8
-
9
- * { box-sizing: border-box; margin: 0; padding: 0; }
10
-
11
- body {
12
- font-family: system-ui, sans-serif;
13
- background: var(--g360-bg);
14
- color: var(--g360-text);
15
- line-height: 1.6;
16
- }
17
-
18
- .g360-header {
19
- background: var(--g360-primary);
20
- color: white;
21
- padding: 1rem 2rem;
22
- }
23
-
24
- .g360-footer {
25
- text-align: center;
26
- padding: 1rem;
27
- color: #6b7280;
28
- }