g360-cli 1.4.0 → 1.6.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.
- package/README.md +122 -0
- package/package.json +11 -4
- package/src/assets/brand/brand.json +43 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.png +0 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.svg +9 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.png +0 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.svg +9 -0
- package/src/assets/brand/g360/logotypes/logo-g360-dark.svg +19 -0
- package/src/assets/brand/g360/logotypes/logo-g360-light.svg +19 -0
- package/src/assets/brand/g360/logotypes/logo_g360_dark_b64.txt +1 -0
- package/src/assets/brand/g360/logotypes/logo_g360_light_b64.txt +1 -0
- package/src/assets/config/g360-skills.json +60 -0
- package/src/assets/signature/g360_flet/__init__.py +5 -0
- package/src/assets/signature/g360_flet/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/assets/signature/g360_flet/__pycache__/__init__.cpython-314.pyc +0 -0
- package/src/assets/signature/g360_flet/__pycache__/g360_signature.cpython-312.pyc +0 -0
- package/src/assets/signature/g360_flet/__pycache__/g360_signature.cpython-314.pyc +0 -0
- package/src/assets/signature/g360_flet/g360_signature.py +224 -0
- package/src/assets/signature/index.js +130 -0
- package/src/assets/snippets/snippets.json +293 -101
- package/src/assets/templates/lit-web/src/core/skill.json +12 -5
- package/src/assets/templates/python-cli/build-portable.bat +19 -9
- package/src/assets/templates/python-cli/src/core/skill.json +25 -6
- package/src/assets/templates/python-customtkinter/README.md +32 -31
- package/src/assets/templates/python-customtkinter/assets/images/logo-g360-dark.svg +19 -0
- package/src/assets/templates/python-customtkinter/assets/images/logo-g360-light.svg +19 -0
- package/src/assets/templates/python-customtkinter/build.bat +50 -0
- package/src/assets/templates/python-customtkinter/pyproject.toml +26 -0
- package/src/assets/templates/python-customtkinter/run.bat +11 -20
- package/src/assets/templates/python-customtkinter/src/core/g360_theme.py +101 -0
- package/src/assets/templates/python-customtkinter/src/core/skill.json +23 -10
- package/src/assets/templates/python-customtkinter/src/main.py +61 -81
- package/src/assets/templates/python-flet/README.md +52 -93
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.png +0 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.svg +9 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.png +0 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.svg +9 -0
- package/src/assets/templates/python-flet/assets/images/logo-g360-dark.svg +19 -0
- package/src/assets/templates/python-flet/assets/images/logo-g360-light.svg +19 -0
- package/src/assets/templates/python-flet/build.bat +36 -0
- package/src/assets/templates/python-flet/pyproject.toml +26 -0
- package/src/assets/templates/python-flet/run.bat +11 -72
- package/src/assets/templates/python-flet/src/core/__init__.py +0 -0
- package/src/assets/templates/python-flet/src/core/g360_theme.py +193 -0
- package/src/assets/templates/python-flet/src/core/skill.json +28 -8
- package/src/assets/templates/python-flet/src/export/__init__.py +0 -0
- package/src/assets/templates/python-flet/src/main.py +113 -68
- package/src/assets/templates/python-flet/src/test_app.py +41 -37
- package/src/assets/templates/python-flet/src/ui/__init__.py +0 -0
- package/src/assets/templates/python-flet-migrate/README.md +70 -0
- package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-dark.svg +19 -0
- package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-light.svg +19 -0
- package/src/assets/templates/python-flet-migrate/build.bat +36 -0
- package/src/assets/templates/python-flet-migrate/pyproject.toml +26 -0
- package/src/assets/templates/python-flet-migrate/run.bat +20 -0
- package/src/assets/templates/python-flet-migrate/src/core/__init__.py +0 -0
- package/src/assets/templates/python-flet-migrate/src/core/g360_theme.py +186 -0
- package/src/assets/templates/python-flet-migrate/src/core/skill.json +34 -0
- package/src/assets/templates/python-flet-migrate/src/main.py +71 -42
- package/src/assets/templates/solid-web/src/core/skill.json +12 -5
- package/src/assets/templates/svelte-web/src/core/skill.json +12 -5
- package/src/assets/templates/web-pwa/index.html +5 -7
- package/src/assets/templates/web-pwa/public/favicon.svg +4 -0
- package/src/assets/templates/web-pwa/public/manifest.json +11 -0
- package/src/assets/templates/web-pwa/src/App.jsx +22 -0
- package/src/assets/templates/web-pwa/src/components/FooterSignature.jsx +9 -0
- package/src/assets/templates/web-pwa/src/components/Header.jsx +12 -0
- package/src/assets/templates/web-pwa/src/components/LoadingOverlay.jsx +10 -0
- package/src/assets/templates/web-pwa/src/core/skill.json +25 -0
- package/src/assets/templates/web-pwa/src/main.jsx +9 -0
- package/src/assets/templates/web-pwa/src/styles/main.css +133 -0
- package/src/assets/templates/web-pwa/vite.config.js +12 -0
- package/src/cli.js +10 -5
- package/src/commands/bring.js +81 -6
- package/src/commands/list.js +79 -9
- package/src/commands/signature.js +252 -55
- package/src/lib/asset-validator.js +145 -0
- package/src/lib/auditor.js +48 -0
- package/src/lib/global-config.js +260 -0
- package/src/lib/i18n.js +238 -0
- package/src/lib/logger.js +100 -0
- package/src/lib/manifest.js +70 -1
- package/src/lib/validator.js +39 -0
- package/src/schemas/skills-schema.json +1 -0
- package/src/schemas/snippets-schema.json +1 -0
- package/dist/g360.exe +0 -0
- package/src/assets/templates/python-customtkinter/build-portable.bat +0 -28
- package/src/assets/templates/python-customtkinter/requirements.txt +0 -1
- package/src/assets/templates/python-flet/build-portable.bat +0 -42
- package/src/assets/templates/python-flet/create_shortcut.vbs +0 -35
- package/src/assets/templates/python-flet/requirements.txt +0 -3
- package/src/assets/templates/web-pwa/app.js +0 -1
- package/src/assets/templates/web-pwa/styles.css +0 -28
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"""
|
|
2
|
+
g360-signature para Flet
|
|
3
|
+
Widget reutilizable del isotipo G360 (3 puntos + chevron) para apps Flet.
|
|
4
|
+
Soporta tema automatico (claro/oscuro) igual que la version web.
|
|
5
|
+
|
|
6
|
+
Uso:
|
|
7
|
+
from g360_flet.g360_signature import G360Signature
|
|
8
|
+
|
|
9
|
+
page.add(G360Signature(mode="own"))
|
|
10
|
+
page.add(G360Signature(mode="powered", version="3.1"))
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import flet as ft
|
|
14
|
+
|
|
15
|
+
# Colores G360
|
|
16
|
+
G360_GREEN = "#00d084"
|
|
17
|
+
G360_GRAY_DARK = "#94a3b8" # dark mode
|
|
18
|
+
G360_GRAY_LIGHT = "#64748b" # light mode
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class G360Signature(ft.Row):
|
|
22
|
+
"""
|
|
23
|
+
Componente de branding G360 para Flet.
|
|
24
|
+
|
|
25
|
+
Detecta automaticamente el tema de la pagina (light/dark)
|
|
26
|
+
y ajusta los colores igual que el Web Component original.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
mode: str = "own",
|
|
32
|
+
version: str | None = None,
|
|
33
|
+
opacity: float = 0.4,
|
|
34
|
+
grayscale: bool = False,
|
|
35
|
+
spacing: int = 4,
|
|
36
|
+
on_hover=None,
|
|
37
|
+
**kwargs,
|
|
38
|
+
):
|
|
39
|
+
super().__init__(**kwargs)
|
|
40
|
+
|
|
41
|
+
self._base_opacity = opacity
|
|
42
|
+
self._grayscale = grayscale
|
|
43
|
+
self.spacing = spacing
|
|
44
|
+
self.vertical_alignment = ft.CrossAxisAlignment.CENTER
|
|
45
|
+
|
|
46
|
+
self._mode = "own"
|
|
47
|
+
self._version = None
|
|
48
|
+
|
|
49
|
+
self.mode = mode
|
|
50
|
+
self.version = version
|
|
51
|
+
|
|
52
|
+
if on_hover is None:
|
|
53
|
+
self.on_hover = self._default_on_hover
|
|
54
|
+
else:
|
|
55
|
+
self.on_hover = on_hover
|
|
56
|
+
|
|
57
|
+
self.opacity = opacity
|
|
58
|
+
|
|
59
|
+
def _default_on_hover(self, e: ft.HoverEvent):
|
|
60
|
+
self.opacity = 1.0 if e.data == "true" else self._base_opacity
|
|
61
|
+
self.update()
|
|
62
|
+
|
|
63
|
+
def _is_dark(self) -> bool:
|
|
64
|
+
"""Detecta si el tema actual es oscuro."""
|
|
65
|
+
if not self._is_mounted():
|
|
66
|
+
return False
|
|
67
|
+
mode = self.page.theme_mode
|
|
68
|
+
if mode == ft.ThemeMode.DARK:
|
|
69
|
+
return True
|
|
70
|
+
if mode == ft.ThemeMode.LIGHT:
|
|
71
|
+
return False
|
|
72
|
+
# SYSTEM: detectar por color de fondo
|
|
73
|
+
bg = self.page.bgcolor
|
|
74
|
+
if bg and isinstance(bg, str):
|
|
75
|
+
bg_lower = bg.lower()
|
|
76
|
+
if bg_lower.startswith("#"):
|
|
77
|
+
r = int(bg_lower[1:3], 16)
|
|
78
|
+
g = int(bg_lower[3:5], 16)
|
|
79
|
+
b = int(bg_lower[5:7], 16)
|
|
80
|
+
lum = (0.299 * r + 0.587 * g + 0.114 * b) / 255
|
|
81
|
+
return lum < 0.5
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
def _get_colors(self):
|
|
85
|
+
"""Retorna colores segun el tema actual."""
|
|
86
|
+
if self._grayscale:
|
|
87
|
+
return G360_GRAY_DARK, G360_GRAY_DARK
|
|
88
|
+
if self._is_dark():
|
|
89
|
+
return G360_GREEN, G360_GRAY_DARK
|
|
90
|
+
return G360_GREEN, G360_GRAY_LIGHT
|
|
91
|
+
|
|
92
|
+
def _build(self):
|
|
93
|
+
green, gray = self._get_colors()
|
|
94
|
+
|
|
95
|
+
# 3 puntos verticales
|
|
96
|
+
dots = ft.Column(
|
|
97
|
+
controls=[
|
|
98
|
+
ft.Container(width=4, height=4, border_radius=2, bgcolor=gray),
|
|
99
|
+
ft.Container(width=4, height=4, border_radius=2, bgcolor=green),
|
|
100
|
+
ft.Container(width=4, height=4, border_radius=2, bgcolor=gray),
|
|
101
|
+
],
|
|
102
|
+
spacing=2,
|
|
103
|
+
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Chevron ">"
|
|
107
|
+
chevron = ft.Text(
|
|
108
|
+
">",
|
|
109
|
+
size=14,
|
|
110
|
+
color=green,
|
|
111
|
+
font_family="Consolas",
|
|
112
|
+
selectable=False,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
isotype = ft.Row(
|
|
116
|
+
controls=[dots, chevron],
|
|
117
|
+
spacing=1,
|
|
118
|
+
vertical_alignment=ft.CrossAxisAlignment.CENTER,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Texto principal
|
|
122
|
+
if self.mode == "own":
|
|
123
|
+
text_controls = [
|
|
124
|
+
ft.Text("G360", size=12, color=green, weight=ft.FontWeight.BOLD,
|
|
125
|
+
font_family="Consolas", selectable=False),
|
|
126
|
+
ft.Text(" by ccusi", size=12, color=gray,
|
|
127
|
+
font_family="Consolas", selectable=False),
|
|
128
|
+
]
|
|
129
|
+
else:
|
|
130
|
+
text_controls = [
|
|
131
|
+
ft.Text("powered by ", size=12, color=gray,
|
|
132
|
+
font_family="Consolas", selectable=False),
|
|
133
|
+
ft.Text("G360", size=12, color=green, weight=ft.FontWeight.BOLD,
|
|
134
|
+
font_family="Consolas", selectable=False),
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
if self.version:
|
|
138
|
+
text_controls.append(
|
|
139
|
+
ft.Text(f" v{self.version}", size=12, color=gray, opacity=0.7,
|
|
140
|
+
font_family="Consolas", selectable=False)
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
text_row = ft.Row(
|
|
144
|
+
controls=text_controls,
|
|
145
|
+
spacing=0,
|
|
146
|
+
vertical_alignment=ft.CrossAxisAlignment.CENTER,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
self.controls = [isotype, text_row]
|
|
150
|
+
|
|
151
|
+
# -- Propiedades --
|
|
152
|
+
|
|
153
|
+
def _is_mounted(self) -> bool:
|
|
154
|
+
"""Verifica si el widget ya esta montado en la pagina."""
|
|
155
|
+
try:
|
|
156
|
+
return self.page is not None
|
|
157
|
+
except RuntimeError:
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def mode(self) -> str:
|
|
162
|
+
return self._mode
|
|
163
|
+
|
|
164
|
+
@mode.setter
|
|
165
|
+
def mode(self, value: str):
|
|
166
|
+
if value not in ("own", "powered"):
|
|
167
|
+
raise ValueError(f"mode debe ser 'own' o 'powered', recibido: '{value}'")
|
|
168
|
+
self._mode = value
|
|
169
|
+
if self._is_mounted():
|
|
170
|
+
self._build()
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def version(self) -> str | None:
|
|
174
|
+
return self._version
|
|
175
|
+
|
|
176
|
+
@version.setter
|
|
177
|
+
def version(self, value: str | None):
|
|
178
|
+
self._version = value
|
|
179
|
+
if self._is_mounted():
|
|
180
|
+
self._build()
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
def grayscale(self) -> bool:
|
|
184
|
+
return self._grayscale
|
|
185
|
+
|
|
186
|
+
@grayscale.setter
|
|
187
|
+
def grayscale(self, value: bool):
|
|
188
|
+
self._grayscale = value
|
|
189
|
+
if self._is_mounted():
|
|
190
|
+
self._build()
|
|
191
|
+
|
|
192
|
+
def did_mount(self):
|
|
193
|
+
"""Se ejecuta cuando el widget se monta en la pagina."""
|
|
194
|
+
self._build()
|
|
195
|
+
self.update()
|
|
196
|
+
|
|
197
|
+
def update(self):
|
|
198
|
+
"""Actualiza colores segun tema y refresca."""
|
|
199
|
+
if self._is_mounted():
|
|
200
|
+
self._build()
|
|
201
|
+
super().update()
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# ============================================================
|
|
205
|
+
# Funciones de conveniencia
|
|
206
|
+
# ============================================================
|
|
207
|
+
|
|
208
|
+
def g360_own(version: str | None = None, **kwargs) -> G360Signature:
|
|
209
|
+
"""Isotipo modo propio: G360 by ccusi"""
|
|
210
|
+
return G360Signature(mode="own", version=version, **kwargs)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def g360_powered(version: str | None = None, **kwargs) -> G360Signature:
|
|
214
|
+
"""Isotipo modo powered: powered by G360"""
|
|
215
|
+
return G360Signature(mode="powered", version=version, **kwargs)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def g360_footer(version: str | None = None, **kwargs) -> ft.Container:
|
|
219
|
+
"""Footer completo con el isotipo G360."""
|
|
220
|
+
return ft.Container(
|
|
221
|
+
content=G360Signature(mode="powered", version=version, opacity=0.6, **kwargs),
|
|
222
|
+
padding=ft.padding.Padding(0, 0, 0, 16),
|
|
223
|
+
alignment=ft.alignment.Alignment(0, 1),
|
|
224
|
+
)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* g360-signature v1.1.0
|
|
3
|
+
* Web component para branding G360 - Sin Shadow DOM
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const G360_SIGNATURE_CSS = `
|
|
7
|
+
.g360-signature {
|
|
8
|
+
display: inline-flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
gap: 4px;
|
|
11
|
+
height: 18px;
|
|
12
|
+
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
|
13
|
+
font-size: 12px;
|
|
14
|
+
line-height: 1;
|
|
15
|
+
opacity: 0.4;
|
|
16
|
+
transition: opacity 0.3s ease;
|
|
17
|
+
cursor: default;
|
|
18
|
+
--g360-green: #00d084;
|
|
19
|
+
--g360-gray: #64748b;
|
|
20
|
+
}
|
|
21
|
+
.g360-signature:hover {
|
|
22
|
+
opacity: 1;
|
|
23
|
+
}
|
|
24
|
+
.g360-signature .g360-iw {
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
gap: 1px;
|
|
28
|
+
height: 100%;
|
|
29
|
+
}
|
|
30
|
+
.g360-signature .g360-iso {
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
gap: 2px;
|
|
35
|
+
height: 100%;
|
|
36
|
+
}
|
|
37
|
+
.g360-signature .g360-d {
|
|
38
|
+
width: 4px;
|
|
39
|
+
height: 4px;
|
|
40
|
+
border-radius: 50%;
|
|
41
|
+
}
|
|
42
|
+
.g360-signature .g360-dt { background: var(--g360-gray); }
|
|
43
|
+
.g360-signature .g360-dm { background: var(--g360-green); }
|
|
44
|
+
.g360-signature .g360-db { background: var(--g360-gray); }
|
|
45
|
+
.g360-signature .g360-ch {
|
|
46
|
+
color: var(--g360-green);
|
|
47
|
+
width: 20px;
|
|
48
|
+
height: 20px;
|
|
49
|
+
}
|
|
50
|
+
.g360-signature .g360-t {
|
|
51
|
+
color: var(--g360-gray);
|
|
52
|
+
letter-spacing: 0.5px;
|
|
53
|
+
}
|
|
54
|
+
.g360-signature .g360-v {
|
|
55
|
+
color: var(--g360-gray);
|
|
56
|
+
opacity: 0.7;
|
|
57
|
+
}
|
|
58
|
+
.g360-signature .g360-s {
|
|
59
|
+
color: var(--g360-gray);
|
|
60
|
+
opacity: 0.5;
|
|
61
|
+
}
|
|
62
|
+
@media (prefers-color-scheme: dark) {
|
|
63
|
+
.g360-signature { --g360-gray: #94a3b8; }
|
|
64
|
+
}
|
|
65
|
+
`;
|
|
66
|
+
|
|
67
|
+
class G360Signature extends HTMLElement {
|
|
68
|
+
static get observedAttributes() {
|
|
69
|
+
return ['mode', 'version'];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
constructor() {
|
|
73
|
+
super();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
connectedCallback() {
|
|
77
|
+
this._injectStyles();
|
|
78
|
+
this.render();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
attributeChangedCallback() {
|
|
82
|
+
this.render();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
_injectStyles() {
|
|
86
|
+
if (document.getElementById('g360-signature-css')) return;
|
|
87
|
+
const style = document.createElement('style');
|
|
88
|
+
style.id = 'g360-signature-css';
|
|
89
|
+
style.textContent = G360_SIGNATURE_CSS;
|
|
90
|
+
document.head.appendChild(style);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get mode() {
|
|
94
|
+
return this.getAttribute('mode') || 'own';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
get version() {
|
|
98
|
+
return this.getAttribute('version') || '';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
render() {
|
|
102
|
+
const isOwn = this.mode === 'own';
|
|
103
|
+
const mainText = isOwn ? 'G360 by ccusi' : 'powered by G360';
|
|
104
|
+
|
|
105
|
+
const versionHtml = this.version
|
|
106
|
+
? `<span class="g360-s">></span><span class="g360-v">${this.version}</span>`
|
|
107
|
+
: '';
|
|
108
|
+
|
|
109
|
+
this.innerHTML = `
|
|
110
|
+
<span class="g360-signature">
|
|
111
|
+
<span class="g360-iw">
|
|
112
|
+
<span class="g360-iso">
|
|
113
|
+
<span class="g360-d g360-dt"></span>
|
|
114
|
+
<span class="g360-d g360-dm"></span>
|
|
115
|
+
<span class="g360-d g360-db"></span>
|
|
116
|
+
</span>
|
|
117
|
+
<svg class="g360-ch" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
118
|
+
<polyline points="6 4 14 10 6 16"></polyline>
|
|
119
|
+
</svg>
|
|
120
|
+
</span>
|
|
121
|
+
<span class="g360-t">${mainText}</span>
|
|
122
|
+
${versionHtml}
|
|
123
|
+
</span>
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!customElements.get('g360-signature')) {
|
|
129
|
+
customElements.define('g360-signature', G360Signature);
|
|
130
|
+
}
|