g360-cli 1.4.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 (85) hide show
  1. package/README.md +122 -0
  2. package/package.json +11 -4
  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 +60 -0
  13. package/src/assets/snippets/snippets.json +293 -101
  14. package/src/assets/templates/lit-web/src/core/skill.json +12 -5
  15. package/src/assets/templates/python-cli/build-portable.bat +19 -9
  16. package/src/assets/templates/python-cli/src/core/skill.json +25 -6
  17. package/src/assets/templates/python-customtkinter/README.md +32 -31
  18. package/src/assets/templates/python-customtkinter/assets/images/logo-g360-dark.svg +19 -0
  19. package/src/assets/templates/python-customtkinter/assets/images/logo-g360-light.svg +19 -0
  20. package/src/assets/templates/python-customtkinter/build.bat +50 -0
  21. package/src/assets/templates/python-customtkinter/pyproject.toml +26 -0
  22. package/src/assets/templates/python-customtkinter/run.bat +11 -20
  23. package/src/assets/templates/python-customtkinter/src/core/g360_theme.py +101 -0
  24. package/src/assets/templates/python-customtkinter/src/core/skill.json +23 -10
  25. package/src/assets/templates/python-customtkinter/src/main.py +61 -81
  26. package/src/assets/templates/python-flet/README.md +52 -93
  27. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.png +0 -0
  28. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.svg +9 -0
  29. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.png +0 -0
  30. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.svg +9 -0
  31. package/src/assets/templates/python-flet/assets/images/logo-g360-dark.svg +19 -0
  32. package/src/assets/templates/python-flet/assets/images/logo-g360-light.svg +19 -0
  33. package/src/assets/templates/python-flet/build.bat +36 -0
  34. package/src/assets/templates/python-flet/pyproject.toml +26 -0
  35. package/src/assets/templates/python-flet/run.bat +11 -72
  36. package/src/assets/templates/python-flet/src/core/__init__.py +0 -0
  37. package/src/assets/templates/python-flet/src/core/g360_theme.py +186 -0
  38. package/src/assets/templates/python-flet/src/core/skill.json +28 -8
  39. package/src/assets/templates/python-flet/src/export/__init__.py +0 -0
  40. package/src/assets/templates/python-flet/src/main.py +113 -68
  41. package/src/assets/templates/python-flet/src/test_app.py +41 -37
  42. package/src/assets/templates/python-flet/src/ui/__init__.py +0 -0
  43. package/src/assets/templates/python-flet-migrate/README.md +70 -0
  44. package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-dark.svg +19 -0
  45. package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-light.svg +19 -0
  46. package/src/assets/templates/python-flet-migrate/build.bat +36 -0
  47. package/src/assets/templates/python-flet-migrate/pyproject.toml +26 -0
  48. package/src/assets/templates/python-flet-migrate/run.bat +20 -0
  49. package/src/assets/templates/python-flet-migrate/src/core/__init__.py +0 -0
  50. package/src/assets/templates/python-flet-migrate/src/core/g360_theme.py +186 -0
  51. package/src/assets/templates/python-flet-migrate/src/core/skill.json +34 -0
  52. package/src/assets/templates/python-flet-migrate/src/main.py +71 -42
  53. package/src/assets/templates/solid-web/src/core/skill.json +12 -5
  54. package/src/assets/templates/svelte-web/src/core/skill.json +12 -5
  55. package/src/assets/templates/web-pwa/index.html +2 -7
  56. package/src/assets/templates/web-pwa/public/favicon.svg +4 -0
  57. package/src/assets/templates/web-pwa/public/manifest.json +11 -0
  58. package/src/assets/templates/web-pwa/src/App.jsx +22 -0
  59. package/src/assets/templates/web-pwa/src/components/FooterSignature.jsx +9 -0
  60. package/src/assets/templates/web-pwa/src/components/Header.jsx +12 -0
  61. package/src/assets/templates/web-pwa/src/components/LoadingOverlay.jsx +10 -0
  62. package/src/assets/templates/web-pwa/src/core/skill.json +25 -0
  63. package/src/assets/templates/web-pwa/src/main.jsx +9 -0
  64. package/src/assets/templates/web-pwa/src/styles/main.css +133 -0
  65. package/src/assets/templates/web-pwa/vite.config.js +12 -0
  66. package/src/cli.js +4 -4
  67. package/src/commands/bring.js +81 -6
  68. package/src/commands/list.js +79 -9
  69. package/src/lib/asset-validator.js +145 -0
  70. package/src/lib/auditor.js +48 -0
  71. package/src/lib/global-config.js +260 -0
  72. package/src/lib/i18n.js +238 -0
  73. package/src/lib/logger.js +100 -0
  74. package/src/lib/manifest.js +70 -1
  75. package/src/lib/validator.js +39 -0
  76. package/src/schemas/skills-schema.json +1 -0
  77. package/src/schemas/snippets-schema.json +1 -0
  78. package/dist/g360.exe +0 -0
  79. package/src/assets/templates/python-customtkinter/build-portable.bat +0 -28
  80. package/src/assets/templates/python-customtkinter/requirements.txt +0 -1
  81. package/src/assets/templates/python-flet/build-portable.bat +0 -42
  82. package/src/assets/templates/python-flet/create_shortcut.vbs +0 -35
  83. package/src/assets/templates/python-flet/requirements.txt +0 -3
  84. package/src/assets/templates/web-pwa/app.js +0 -1
  85. package/src/assets/templates/web-pwa/styles.css +0 -28
@@ -0,0 +1,19 @@
1
+ <svg viewBox="0 0 280 70" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <filter id="glow-dark" x="-40%" y="-40%" width="180%" height="180%">
4
+ <feGaussianBlur stdDeviation="3" result="blur" />
5
+ <feFlood flood-color="#22c55e" flood-opacity="0.8" result="glowColor"/>
6
+ <feComposite in="glowColor" in2="blur" operator="in" result="softGlow"/>
7
+ <feMerge>
8
+ <feMergeNode in="softGlow"/>
9
+ <feMergeNode in="SourceGraphic"/>
10
+ </feMerge>
11
+ </filter>
12
+ </defs>
13
+ <circle cx="20" cy="20" r="5" fill="#94a3b8" />
14
+ <circle cx="20" cy="40" r="5" fill="#22c55e" filter="url(#glow-dark)" />
15
+ <circle cx="20" cy="60" r="5" fill="#94a3b8" />
16
+ <path d="M45 20 L 65 40 L 45 60" fill="none" stroke="#22c55e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" filter="url(#glow-dark)"/>
17
+ <text x="85" y="45" font-family="Arial Black, sans-serif" font-weight="bold" font-size="38" fill="#f8fafc">G360</text>
18
+ <text x="85" y="65" font-family="monospace" font-size="12" fill="#94a3b8" letter-spacing="4">BY CCUSI</text>
19
+ </svg>
@@ -0,0 +1,19 @@
1
+ <svg viewBox="0 0 280 70" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <filter id="glow-light" x="-30%" y="-30%" width="160%" height="160%">
4
+ <feGaussianBlur stdDeviation="2.5" result="blur" />
5
+ <feFlood flood-color="#22c55e" flood-opacity="0.6" result="glowColor"/>
6
+ <feComposite in="glowColor" in2="blur" operator="in" result="softGlow"/>
7
+ <feMerge>
8
+ <feMergeNode in="softGlow"/>
9
+ <feMergeNode in="SourceGraphic"/>
10
+ </feMerge>
11
+ </filter>
12
+ </defs>
13
+ <circle cx="20" cy="20" r="5" fill="#475569" />
14
+ <circle cx="20" cy="40" r="5" fill="#22c55e" filter="url(#glow-light)" />
15
+ <circle cx="20" cy="60" r="5" fill="#475569" />
16
+ <path d="M45 20 L 65 40 L 45 60" fill="none" stroke="#22c55e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" filter="url(#glow-light)"/>
17
+ <text x="85" y="45" font-family="Arial Black, sans-serif" font-weight="bold" font-size="38" fill="#1e293b">G360</text>
18
+ <text x="85" y="65" font-family="monospace" font-size="12" fill="#64748b" letter-spacing="4">BY CCUSI</text>
19
+ </svg>
@@ -0,0 +1,50 @@
1
+ @echo off
2
+ chcp 65001 >nul
3
+ cd /d "%~dp0"
4
+
5
+ echo.
6
+ echo ========================================
7
+ echo G360 - Build Windows App
8
+ echo Genera ejecutable standalone
9
+ echo ========================================
10
+ echo.
11
+
12
+ REM Verificar uv
13
+ where uv >nul 2>&1
14
+ if errorlevel 1 (
15
+ echo Instalando uv...
16
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
17
+ )
18
+
19
+ REM Verificar dependencias
20
+ uv sync --extra build
21
+
22
+ REM Build con PyInstaller
23
+ echo [BUILD] Generando ejecutable...
24
+ uv run pyinstaller --onefile --windowed ^
25
+ --name "G360-App" ^
26
+ --add-data "src/core;core" ^
27
+ --icon "assets/images/app.ico" ^
28
+ --distpath "dist" ^
29
+ --workpath "build" ^
30
+ --specpath "build" ^
31
+ --noconfirm ^
32
+ src/main.py
33
+
34
+ if errorlevel 1 (
35
+ echo.
36
+ echo ERROR: Fallo la generacion del ejecutable.
37
+ pause
38
+ exit /b 1
39
+ )
40
+
41
+ REM Limpiar temporales
42
+ if exist "build" rmdir /s /q build
43
+
44
+ echo.
45
+ echo ========================================
46
+ echo BUILD EXITOSO
47
+ echo Ejecutable: dist/G360-App.exe
48
+ echo ========================================
49
+ echo.
50
+ pause
@@ -0,0 +1,26 @@
1
+ [project]
2
+ name = "g360-app"
3
+ version = "1.0.0"
4
+ description = "G360 Desktop Application (CustomTkinter)"
5
+ authors = [
6
+ { name = "ccusi", email = "ccusi@cipsa.com.pe" },
7
+ ]
8
+ requires-python = ">=3.11,<4.0"
9
+ dependencies = [
10
+ "customtkinter>=5.2.0",
11
+ "openpyxl>=3.1.0",
12
+ "pandas>=2.0.0",
13
+ ]
14
+
15
+ [project.optional-dependencies]
16
+ dev = [
17
+ "pytest>=8.0.0",
18
+ "pytest-cov>=5.0.0",
19
+ ]
20
+
21
+ [build-system]
22
+ requires = ["hatchling"]
23
+ build-backend = "hatchling.build"
24
+
25
+ [tool.hatch.build.targets.wheel]
26
+ packages = ["src"]
@@ -1,29 +1,20 @@
1
1
  @echo off
2
2
  chcp 65001 >nul
3
- title G360 - CustomTkinter App
3
+ cd /d "%~dp0"
4
4
 
5
5
  echo.
6
- echo ==============================================
7
- echo G360 CustomTkinter Application
8
- echo ==============================================
6
+ echo ========================================
7
+ echo G360 CustomTkinter App
8
+ echo powered by G360
9
+ echo ========================================
9
10
  echo.
10
11
 
11
- python --version >nul 2>&1
12
- if errorlevel 1 (
13
- echo ERROR: Python no encontrado
14
- pause
15
- exit /b 1
16
- )
12
+ REM uv run detecta/instala Python y dependencias automaticamente
13
+ uv run python src/main.py
17
14
 
18
- echo Verificando customtkinter...
19
- pip show customtkinter >nul 2>&1
20
15
  if errorlevel 1 (
21
- echo Instalando customtkinter...
22
- pip install customtkinter
16
+ echo.
17
+ echo ERROR: La aplicacion fallo.
18
+ echo Verifique que uv este instalado: https://docs.astral.sh/uv/
19
+ pause
23
20
  )
24
-
25
- echo.
26
- echo Ejecutando aplicacion...
27
- python src\main.py
28
-
29
- pause
@@ -0,0 +1,101 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+
5
+ class G360Theme:
6
+ def __init__(self, skill_path=None):
7
+ self._search_paths(skill_path)
8
+ self._load_colors()
9
+ self._load_effects()
10
+
11
+ def _search_paths(self, skill_path):
12
+ if skill_path and Path(skill_path).exists():
13
+ self.config_path = Path(skill_path)
14
+ return
15
+ candidates = [
16
+ Path("skill.json"),
17
+ Path("src/core/skill.json"),
18
+ Path(__file__).resolve().parent.parent.parent / "skill.json",
19
+ Path(__file__).resolve().parent / "skill.json",
20
+ Path(__file__).resolve().parent.parent / "g360" / "skills" / "customtkinter-desktop.json",
21
+ ]
22
+ for c in candidates:
23
+ if c.exists():
24
+ self.config_path = c
25
+ return
26
+ raise FileNotFoundError("skill.json not found. Run: g360 init <name> --skill customtkinter-desktop")
27
+
28
+ def _load_colors(self):
29
+ with open(self.config_path, encoding="utf-8") as f:
30
+ self.config = json.load(f)
31
+ colors = self.config.get("colors", {})
32
+ self.bg = colors.get("bg", "#0b1220")
33
+ self.surface = colors.get("surface", "#1a2332")
34
+ self.accent = colors.get("accent", "#00d084")
35
+ self.text = colors.get("text", "#f0f4f8")
36
+ self.muted = colors.get("muted", "#94a3b8")
37
+ self.success = colors.get("success", "#22c55e")
38
+ self.warning = colors.get("warning", "#f59e0b")
39
+ self.error = colors.get("error", "#ef4444")
40
+ self.brand = self.config.get("brand", "g360")
41
+
42
+ def _load_effects(self):
43
+ effects = self.config.get("effects", {})
44
+ self.glassmorphism = effects.get("glassmorphism", True)
45
+ self.blur = effects.get("blur", "12px")
46
+ self.rounded = int(effects.get("rounded", "12px").replace("px", ""))
47
+
48
+ def apply_ctk(self):
49
+ import customtkinter as ctk
50
+ ctk.set_appearance_mode("dark")
51
+ ctk.set_default_color_theme("green")
52
+
53
+ def build_name(self):
54
+ build_cfg = self.config.get("build", {})
55
+ return build_cfg.get("name", "G360-App")
56
+
57
+ def glass_frame(self, parent, **kwargs):
58
+ import customtkinter as ctk
59
+ kwargs.setdefault("fg_color", self.surface)
60
+ kwargs.setdefault("corner_radius", self.rounded)
61
+ if self.glassmorphism:
62
+ kwargs.setdefault("border_width", 1)
63
+ kwargs.setdefault("border_color", f"{self.accent}40")
64
+ return ctk.CTkFrame(parent, **kwargs)
65
+
66
+ def accent_button(self, parent, text="", command=None, **kwargs):
67
+ import customtkinter as ctk
68
+ return ctk.CTkButton(
69
+ parent,
70
+ text=text,
71
+ command=command,
72
+ fg_color=self.accent,
73
+ text_color=self.bg,
74
+ hover_color="#00b070",
75
+ corner_radius=8,
76
+ **kwargs,
77
+ )
78
+
79
+ def styled_label(self, parent, text="", size=14, color=None, **kwargs):
80
+ import customtkinter as ctk
81
+ return ctk.CTkLabel(
82
+ parent,
83
+ text=text,
84
+ font=("Segoe UI", size),
85
+ text_color=color or self.text,
86
+ **kwargs,
87
+ )
88
+
89
+ @property
90
+ def as_dict(self):
91
+ return {
92
+ "bg": self.bg,
93
+ "surface": self.surface,
94
+ "accent": self.accent,
95
+ "text": self.text,
96
+ "muted": self.muted,
97
+ "success": self.success,
98
+ "warning": self.warning,
99
+ "error": self.error,
100
+ "brand": self.brand,
101
+ }
@@ -1,22 +1,35 @@
1
1
  {
2
- "skill": "moderno",
3
- "device": "pc",
4
- "version": "1.0.0",
2
+ "name": "customtkinter-desktop",
3
+ "description": "G360 CustomTkinter Desktop Application",
4
+ "framework": "customtkinter",
5
+ "version": "1.2.0",
6
+ "python": ">=3.11,<4.0",
5
7
  "colors": {
6
8
  "bg": "#0b1220",
7
9
  "surface": "#1a2332",
8
10
  "accent": "#00d084",
9
11
  "text": "#f0f4f8",
10
- "muted": "#94a3b8"
12
+ "muted": "#94a3b8",
13
+ "success": "#22c55e",
14
+ "warning": "#f59e0b",
15
+ "error": "#ef4444"
11
16
  },
12
17
  "effects": {
13
- "glassmorphism": false,
18
+ "glassmorphism": true,
19
+ "blur": "12px",
14
20
  "rounded": "12px"
15
21
  },
16
22
  "signature": {
17
- "mode": "own",
18
- "text": "G360 Desktop"
23
+ "mode": "powered",
24
+ "text": "powered by G360"
19
25
  },
20
- "framework": "customtkinter",
21
- "portable": true
22
- }
26
+ "build": {
27
+ "tool": "pyinstaller",
28
+ "target": "windows",
29
+ "name": "G360-App"
30
+ },
31
+ "dependencies": {
32
+ "customtkinter": ">=5.2.0",
33
+ "pyinstaller": ">=6.0.0"
34
+ }
35
+ }
@@ -4,114 +4,94 @@ G360 CustomTkinter Desktop Application
4
4
  Modern GUI with G360 theme
5
5
  """
6
6
 
7
- import customtkinter as ctk
7
+ import sys
8
8
  from pathlib import Path
9
- import json
10
-
11
-
12
- VERSION = "1.0.0"
13
- APP_NAME = "G360 Desktop"
14
9
 
10
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
15
11
 
16
- def load_skill():
17
- skill_path = Path(__file__).parent / "core" / "skill.json"
18
- if skill_path.exists():
19
- with open(skill_path) as f:
20
- return json.load(f)
21
- return {
22
- "colors": {
23
- "bg": "#0b1220",
24
- "surface": "#1a2332",
25
- "accent": "#00d084"
26
- }
27
- }
12
+ import customtkinter as ctk
13
+ from core.g360_theme import G360Theme
28
14
 
29
15
 
30
16
  class G360App(ctk.CTk):
31
17
  def __init__(self):
32
18
  super().__init__()
33
19
 
34
- skill = load_skill()
35
- colors = skill.get("colors", {})
36
-
37
- ctk.set_appearance_mode("dark")
38
- ctk.set_default_color_theme("green")
20
+ self.theme = G360Theme()
21
+ self.theme.apply_ctk()
39
22
 
40
- self.title(APP_NAME)
41
- self.geometry("800x600")
42
- self.configure(fg_color=colors.get("bg", "#0b1220"))
23
+ self.title(self.theme.build_name())
24
+ self.geometry("900x700")
25
+ self.configure(fg_color=self.theme.bg)
43
26
 
44
27
  self.grid_columnconfigure(0, weight=1)
45
- self.grid_rowconfigure(0, weight=1)
28
+ self.grid_rowconfigure(1, weight=1)
46
29
 
47
- self.create_header(colors)
48
- self.create_content(colors)
49
- self.create_footer()
30
+ self._build_header()
31
+ self._build_content()
32
+ self._build_footer()
50
33
 
51
- def create_header(self, colors):
52
- self.header = ctk.CTkFrame(self, fg_color=colors.get("surface", "#1a2332"))
53
- self.header.grid(row=0, column=0, sticky="ew", padx=10, pady=10)
34
+ def _build_header(self):
35
+ header = self.theme.glass_frame(self)
36
+ header.grid(row=0, column=0, sticky="ew", padx=10, pady=10)
54
37
 
55
- title = ctk.CTkLabel(
56
- self.header,
57
- text=f"{APP_NAME} v{VERSION}",
58
- font=("Segoe UI", 20, "bold"),
59
- text_color=colors.get("accent", "#00d084")
60
- )
61
- title.pack(side="left", padx=20, pady=10)
38
+ self.theme.styled_label(
39
+ header,
40
+ text=self.theme.build_name(),
41
+ size=20,
42
+ color=self.theme.accent
43
+ ).pack(side="left", padx=20, pady=10)
62
44
 
63
- btn_settings = ctk.CTkButton(
64
- self.header,
45
+ self.theme.accent_button(
46
+ header,
65
47
  text="Settings",
66
- fg_color="transparent",
67
- border_width=1,
68
- border_color=colors.get("accent", "#00d084"),
69
- text_color=colors.get("accent", "#00d084")
70
- )
71
- btn_settings.pack(side="right", padx=20)
48
+ command=self._on_settings
49
+ ).pack(side="right", padx=20, pady=10)
72
50
 
73
- def create_content(self, colors):
74
- self.content = ctk.CTkFrame(self, fg_color="transparent")
75
- self.content.grid(row=1, column=0, sticky="nsew", padx=20, pady=10)
51
+ def _build_content(self):
52
+ content = ctk.CTkFrame(self, fg_color="transparent")
53
+ content.grid(row=1, column=0, sticky="nsew", padx=20, pady=10)
54
+ content.grid_columnconfigure(0, weight=1)
55
+ content.grid_rowconfigure(0, weight=1)
76
56
 
77
- self.content.grid_columnconfigure(0, weight=1)
78
- self.content.grid_rowconfigure(0, weight=1)
79
-
80
- card = ctk.CTkFrame(
81
- self.content,
82
- fg_color=colors.get("surface", "#1a2332"),
83
- corner_radius=12
84
- )
57
+ card = self.theme.glass_frame(content)
85
58
  card.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
86
59
 
87
- label = ctk.CTkLabel(
60
+ self.theme.styled_label(
88
61
  card,
89
62
  text="G360 Application\nReady to build",
90
- font=("Segoe UI", 16),
91
- text_color="#f0f4f8"
92
- )
93
- label.pack(pady=40)
63
+ size=18
64
+ ).pack(pady=40)
94
65
 
95
- btn_primary = ctk.CTkButton(
66
+ self.theme.accent_button(
96
67
  card,
97
68
  text="Start",
98
- fg_color=colors.get("accent", "#00d084"),
99
- text_color="#0b1220",
100
- hover_color="#00b070"
101
- )
102
- btn_primary.pack(pady=20)
69
+ command=self._on_start
70
+ ).pack(pady=20)
103
71
 
104
- def create_footer(self):
105
- self.footer = ctk.CTkFrame(self, fg_color="transparent")
106
- self.footer.grid(row=2, column=0, sticky="ew", padx=10, pady=(0, 10))
72
+ def _build_footer(self):
73
+ footer = ctk.CTkFrame(self, fg_color="transparent")
74
+ footer.grid(row=2, column=0, sticky="ew", padx=10, pady=(0, 10))
75
+
76
+ self.theme.styled_label(
77
+ footer,
78
+ text=f"v{self.theme.config.get('version', '1.0.0')}",
79
+ size=12,
80
+ color=self.theme.muted
81
+ ).pack(side="left", padx=20)
107
82
 
108
- status = ctk.CTkLabel(
109
- self.footer,
110
- text="G360 Desktop App",
111
- text_color="#94a3b8",
112
- font=("Segoe UI", 12)
113
- )
114
- status.pack(side="left", padx=20)
83
+ self.theme.styled_label(
84
+ footer,
85
+ text="powered by G360",
86
+ size=10,
87
+ color=self.theme.muted
88
+ ).pack(side="right", padx=20)
89
+
90
+ def _on_settings(self):
91
+ print("Settings clicked")
92
+
93
+ def _on_start(self):
94
+ print("Start clicked")
115
95
 
116
96
 
117
97
  def main():
@@ -120,4 +100,4 @@ def main():
120
100
 
121
101
 
122
102
  if __name__ == "__main__":
123
- main()
103
+ main()
@@ -5,126 +5,85 @@
5
5
  ```
6
6
  mi-proyecto/
7
7
  ├── src/
8
- │ ├── main.py # Punto de entrada
9
- │ ├── test_app.py # Tests con pytest
10
- └── core/
11
- └── skill.json # Configuración del skill
8
+ │ ├── main.py # Entry point: ft.run(main)
9
+ │ ├── core/
10
+ │ ├── skill.json # Configuracion del skill G360
11
+ └── g360_theme.py # Theme engine (lee colores de skill.json)
12
+ │ ├── ui/
13
+ │ │ └── __init__.py # Componentes Flet (PascalCase)
14
+ │ └── export/
15
+ │ └── __init__.py # Reportes Excel (openpyxl)
12
16
  ├── assets/
13
17
  │ └── images/
14
18
  │ └── app.ico # Icono de la app
15
- ├── portable/
16
- ├── build.bat # Build portable EXE (sin Python)
17
- │ └── run.bat # Run con Python (del sistema o UV)
18
- ├── g360-nc-sustentor-portable/ # Copia para distribución
19
- ├── g360/
20
- │ └── (estructura G360)
21
- ├── requirements.txt
22
- ├── create_shortcut.vbs # Crear acceso directo
19
+ ├── skill.json # Skill G360 aplicado
20
+ ├── pyproject.toml # Dependencias (uv sync)
21
+ ├── run.bat # Ejecutar app
22
+ ├── build.bat # Build EXE standalone
23
23
  └── README.md
24
24
  ```
25
25
 
26
- ## Instalación
26
+ ## Requisitos
27
27
 
28
- ```bash
29
- pip install -r requirements.txt
30
- ```
31
-
32
- ## Desarrollo
33
-
34
- ```bash
35
- python src/main.py
36
- ```
28
+ - **Python**: 3.11+ (instalado automaticamente por uv)
29
+ - **uv**: Gestor de paquetes Python (https://docs.astral.sh/uv/)
30
+ - **Windows**: 10/11 x64
37
31
 
38
- ## Tests
32
+ ## Ejecucion
39
33
 
34
+ ### Con uv (recomendado)
40
35
  ```bash
41
- pytest src/test_app.py -v
42
- pytest src/test_app.py --cov=src --cov-report=html
36
+ run.bat
43
37
  ```
44
38
 
45
- ## Dos Modalidades de Portable
46
-
47
- ### Modalidad 1: Con Python (run.bat)
48
- Para PCs que tienen Python instalado o pueden instalarlo:
49
-
39
+ ### Manual
50
40
  ```bash
51
- run.bat
41
+ uv run python src/main.py
52
42
  ```
53
43
 
54
- Esto:
55
- 1. Detecta si hay Python en el sistema
56
- 2. Si no hay, instala UV (gestor rápido)
57
- 3. UV instala Python 3.10
58
- 4. Crea entorno virtual
59
- 5. Instala dependencias
60
- 6. Crea acceso directo en escritorio
61
- 7. Ejecuta la app
44
+ `uv run` detecta/instala Python y dependencias automaticamente.
62
45
 
63
- ### Modalidad 2: Sin Python (build-portable.bat)
64
- Para PCs que NO tienen Python - genera ejecutable standalone:
46
+ ## Build Windows (EXE standalone)
65
47
 
66
48
  ```bash
67
- cd portable
68
49
  build.bat
69
50
  ```
70
51
 
71
- Esto genera: `dist/G360App-Portable.exe`
72
-
73
- El EXE funciona en cualquier PC con Windows sin necesidad de Python.
52
+ Genera ejecutable en `build/windows/` usando `flet build`.
74
53
 
75
- ## Distribución a Clientes
54
+ ## Theme y Colores
76
55
 
77
- 1. **Genera el portable EXE**:
78
- ```bash
79
- portable\build.bat
80
- ```
56
+ Los colores se definen en `src/core/skill.json` y se cargan via `G360Theme`.
81
57
 
82
- 2. **Copia la estructura**:
83
- - Copia todo el proyecto a una carpeta `g360-nc-sustentor-portable`
84
- - O simplemente entrega el EXE de `dist/`
85
-
86
- 3. **Entrega al cliente**:
87
- - Solo necesita ejecutar `run.bat` (si tiene Python)
88
- - O el `G360App-Portable.exe` (si no tiene Python)
89
-
90
- ## Lineamientos para el Agente Python
91
-
92
- ### Para resolver problemas:
93
- 1. Primero ejecuta los tests: `pytest src/test_app.py -v`
94
- 2. Identifica el test que falla
95
- 3. Reproduce el problema en el código
96
- 4. Implementa la solución
97
- 5. Verifica con tests
98
-
99
- ### Para cálculos y procesamiento:
100
- 1. Usa la clase TestCalculations en test_app.py
101
- 2. Agrega nuevos tests para funciones de cálculo
102
- 3. Ejecuta: `pytest src/test_app.py::TestCalculations -v`
103
-
104
- ### Antes de subir a GitHub:
105
- ```bash
106
- g360 clean . --github
107
- ```
108
- Esto actualiza el .gitignore y prepara el repo para remoto.
109
-
110
- ## Skills Disponibles
111
-
112
- - `flet-desktop` - Estilo G360 moderno para desktop
113
- - `flet-desktop-corporativo` - Estilo corporativo
58
+ ### Paleta G360
59
+ | Token | Color | Uso |
60
+ |---|---|---|
61
+ | `bg` | `#0b1220` | Fondo principal |
62
+ | `surface` | `#1a2332` | Cards, contenedores |
63
+ | `accent` | `#00d084` | Verde G360 primary |
64
+ | `text` | `#f0f4f8` | Texto principal |
65
+ | `muted` | `#94a3b8` | Texto secundario |
66
+ | `success` | `#22c55e` | Exito/positivo |
67
+ | `warning` | `#f59e0b` | Advertencia |
68
+ | `error` | `#ef4444` | Error/peligro |
114
69
 
115
70
  ## Snippets Flet
116
71
 
117
- Usa los snippets de G360 para componentes rápidos:
118
- - `flet-page` - Configuración de página
72
+ - `flet-page` - Configuracion de pagina con tema
119
73
  - `flet-card` - Tarjetas con estilo G360
120
74
  - `flet-button` - Botones G360
75
+ - `flet-kpi-card` - Card de KPI para dashboards
76
+ - `flet-drop-zone` - Zona de carga de archivos
121
77
  - `flet-datatable` - Tablas de datos
122
- - `flet-dialog` - Diálogos modales
123
- - `flet-chart-bar` - Gráficos de barras
124
-
125
- ## Notas del build portable
126
-
127
- - El ejecutable incluye todo el runtime de Python
128
- - Tamaño aproximado: 30-50 MB
129
- - Funciona en Windows 10/11 sin dependencias
130
- - El icono se puede personalizar en `assets/images/app.ico`
78
+ - `flet-dialog` - Dialogos modales
79
+ - `flet-loading-overlay` - Overlay de carga
80
+ - `flet-footer-signature` - Footer con branding G360
81
+
82
+ ## Lineamientos de Arquitectura
83
+
84
+ 1. **src/core/**: NO importa `flet`. Solo logica de negocio
85
+ 2. **src/ui/**: Importa `flet` y `core`. Solo presentacion
86
+ 3. **src/export/**: Importa `openpyxl` y `core`. Solo reportes
87
+ 4. **Threading**: Usar `threading.Thread` para operaciones bloqueantes
88
+ 5. **Estado**: Atributos de clase. Evitar variables globales
89
+ 6. **Colores**: Siempre via `G360Theme`. Nunca hardcodear