@omnizap-system/omnizap 2.6.1 → 2.6.2
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/.env.example +54 -9
- package/.github/workflows/ci.yml +3 -3
- package/.github/workflows/security-runner-hardening.yml +1 -1
- package/.github/workflows/security-zap-full-scan.yml +1 -0
- package/app/config/index.js +2 -0
- package/app/configParts/adminIdentity.js +5 -5
- package/app/configParts/baileysConfig.js +226 -55
- package/app/configParts/groupUtils.js +5 -0
- package/app/configParts/messagePersistenceService.js +143 -3
- package/app/configParts/sessionConfig.js +157 -0
- package/app/connection/baileysCompatibility.test.js +1 -1
- package/app/connection/groupOwnerWriteStateResolver.js +109 -0
- package/app/connection/socketController.js +625 -124
- package/app/connection/socketController.multiSession.test.js +108 -0
- package/app/controllers/messageController.js +1 -1
- package/app/controllers/messagePipeline/commandMiddleware.js +12 -10
- package/app/controllers/messagePipeline/conversationMiddleware.js +2 -1
- package/app/controllers/messagePipeline/messagePipelineMiddlewares.test.js +104 -0
- package/app/controllers/messagePipeline/preProcessingMiddlewares.js +80 -2
- package/app/controllers/messageProcessingPipeline.js +88 -9
- package/app/controllers/messageProcessingPipeline.test.js +200 -0
- package/app/modules/adminModule/AGENT.md +1 -1
- package/app/modules/adminModule/commandConfig.json +3318 -1347
- package/app/modules/adminModule/groupCommandHandlers.js +856 -14
- package/app/modules/adminModule/groupCommandHandlers.test.js +375 -9
- package/app/modules/adminModule/groupWarningRepository.js +152 -0
- package/app/modules/aiModule/AGENT.md +47 -30
- package/app/modules/aiModule/aiConfigRuntime.js +1 -0
- package/app/modules/aiModule/catCommand.js +132 -25
- package/app/modules/aiModule/commandConfig.json +114 -28
- package/app/modules/analyticsModule/messageAnalysisEventRepository.js +54 -6
- package/app/modules/gameModule/AGENT.md +1 -1
- package/app/modules/gameModule/commandConfig.json +29 -0
- package/app/modules/menuModule/AGENT.md +1 -1
- package/app/modules/menuModule/commandConfig.json +45 -10
- package/app/modules/menuModule/menuCatalogService.js +190 -0
- package/app/modules/menuModule/menuCommandUsageRepository.js +109 -0
- package/app/modules/menuModule/menuDynamicService.js +511 -0
- package/app/modules/menuModule/menuDynamicService.test.js +141 -0
- package/app/modules/menuModule/menus.js +36 -5
- package/app/modules/playModule/AGENT.md +10 -5
- package/app/modules/playModule/commandConfig.json +74 -16
- package/app/modules/playModule/playCommandConstants.js +13 -7
- package/app/modules/playModule/playCommandCore.js +4 -6
- package/app/modules/playModule/{playCommandYtDlpClient.js → playCommandMediaClient.js} +684 -332
- package/app/modules/playModule/playConfigRuntime.js +5 -6
- package/app/modules/playModule/playModuleCriticalFlows.test.js +44 -59
- package/app/modules/quoteModule/AGENT.md +1 -1
- package/app/modules/quoteModule/commandConfig.json +29 -0
- package/app/modules/rpgPokemonModule/AGENT.md +1 -1
- package/app/modules/rpgPokemonModule/commandConfig.json +29 -0
- package/app/modules/statsModule/AGENT.md +1 -1
- package/app/modules/statsModule/commandConfig.json +58 -0
- package/app/modules/stickerModule/AGENT.md +1 -1
- package/app/modules/stickerModule/commandConfig.json +145 -0
- package/app/modules/stickerPackModule/AGENT.md +1 -1
- package/app/modules/stickerPackModule/autoPackCollectorService.js +5 -1
- package/app/modules/stickerPackModule/commandConfig.json +29 -0
- package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +1 -1
- package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +78 -57
- package/app/modules/stickerPackModule/stickerPackService.js +13 -6
- package/app/modules/systemMetricsModule/AGENT.md +1 -1
- package/app/modules/systemMetricsModule/commandConfig.json +29 -0
- package/app/modules/tiktokModule/AGENT.md +1 -1
- package/app/modules/tiktokModule/commandConfig.json +29 -0
- package/app/modules/userModule/AGENT.md +1 -1
- package/app/modules/userModule/commandConfig.json +29 -0
- package/app/modules/waifuPicsModule/AGENT.md +57 -27
- package/app/modules/waifuPicsModule/commandConfig.json +87 -0
- package/app/observability/metrics.js +136 -0
- package/app/services/ai/commandConfigEnrichmentService.js +229 -47
- package/app/services/ai/geminiService.js +131 -7
- package/app/services/ai/geminiService.test.js +59 -2
- package/app/services/ai/moduleAiHelpCoreService.js +33 -4
- package/app/services/group/groupMetadataService.js +24 -1
- package/app/services/infra/dbWriteQueue.js +51 -21
- package/app/services/messaging/newsBroadcastService.js +843 -27
- package/app/services/multiSession/assignmentBalancerService.js +457 -0
- package/app/services/multiSession/groupOwnershipRepository.js +381 -0
- package/app/services/multiSession/groupOwnershipService.js +890 -0
- package/app/services/multiSession/groupOwnershipService.test.js +309 -0
- package/app/services/multiSession/sessionRegistryService.js +293 -0
- package/app/store/aiPromptStore.js +36 -19
- package/app/store/groupConfigStore.js +41 -5
- package/app/store/premiumUserStore.js +21 -7
- package/app/utils/antiLink/antiLinkModule.js +352 -16
- package/app/workers/aiHelperContinuousLearningWorker.js +512 -0
- package/database/index.js +6 -0
- package/database/migrations/20260307_d0_hardening_down.sql +1 -1
- package/database/migrations/20260314_d7_canonical_sender_down.sql +1 -1
- package/database/migrations/20260406_d30_security_analytics_down.sql +1 -1
- package/database/migrations/20260411_d35_group_community_metadata_down.sql +59 -0
- package/database/migrations/20260411_d35_group_community_metadata_up.sql +62 -0
- package/database/migrations/20260412_d36_system_config_tables_down.sql +32 -0
- package/database/migrations/20260412_d36_system_config_tables_up.sql +66 -0
- package/database/migrations/20260413_d37_group_user_warnings_down.sql +11 -0
- package/database/migrations/20260413_d37_group_user_warnings_up.sql +24 -0
- package/database/migrations/20260414_d38_multi_session_foundation_down.sql +72 -0
- package/database/migrations/20260414_d38_multi_session_foundation_up.sql +125 -0
- package/database/migrations/20260414_d39_multi_session_cutover_down.sql +103 -0
- package/database/migrations/20260414_d39_multi_session_cutover_up.sql +83 -0
- package/database/schema.sql +102 -1
- package/docker-compose.yml +4 -1
- package/docs/compliance/acceptable-use-policy-2026-03-07.md +1 -1
- package/docs/compliance/privacy-policy-2026-03-07.md +2 -2
- package/docs/security/dsar-lgpd-runbook-2026-03-07.md +1 -1
- package/docs/security/network-hardening-runbook-2026-03-07.md +53 -0
- package/docs/security/omnizap-static-security-headers.conf +25 -0
- package/ecosystem.prod.config.cjs +31 -11
- package/index.js +52 -18
- package/observability/alert-rules.yml +20 -0
- package/observability/grafana/dashboards/omnizap-system-admin.json +229 -0
- package/observability/mysql-setup.sql +4 -4
- package/observability/system-admin-observability.md +26 -0
- package/package.json +12 -5
- package/public/comandos/commands-catalog.json +2253 -78
- package/public/js/apps/commandsReactApp.js +267 -87
- package/public/js/apps/createPackApp.js +3 -3
- package/public/js/apps/stickersApp.js +255 -103
- package/public/js/apps/termsReactApp.js +57 -8
- package/public/js/apps/userPasswordResetReactApp.js +406 -0
- package/public/js/apps/userReactApp.js +96 -47
- package/public/js/apps/userSystemAdmReactApp.js +1506 -0
- package/public/pages/politica-de-privacidade.html +1 -1
- package/public/pages/stickers.html +5 -5
- package/public/pages/termos-de-uso-texto-integral.html +1 -1
- package/public/pages/termos-de-uso.html +1 -1
- package/public/pages/user-password-reset.html +3 -4
- package/public/pages/user-systemadm.html +8 -462
- package/public/pages/user.html +1 -1
- package/scripts/clear-whatsapp-session.sh +123 -0
- package/scripts/core-ai-mode.mjs +163 -0
- package/scripts/deploy.sh +10 -0
- package/scripts/enrich-command-config-ux-openai.mjs +492 -0
- package/scripts/generate-commands-catalog.mjs +155 -0
- package/scripts/new-whatsapp-session.sh +317 -0
- package/scripts/security-web-surface-check.mjs +218 -0
- package/server/controllers/admin/adminPanelHandlers.js +253 -3
- package/server/controllers/admin/systemAdminController.js +267 -0
- package/server/controllers/sticker/stickerCatalogController.js +9 -23
- package/server/controllers/system/contactController.js +9 -17
- package/server/controllers/system/stickerCatalogSystemContext.js +27 -6
- package/server/controllers/system/systemController.js +254 -1
- package/server/controllers/userController.js +6 -0
- package/server/email/emailTemplateService.js +3 -2
- package/server/http/httpServer.js +8 -4
- package/server/middleware/securityHeaders.js +20 -1
- package/server/routes/admin/systemAdminRouter.js +6 -0
- package/server/routes/indexRouter.js +30 -6
- package/server/routes/observability/grafanaProxyRouter.js +254 -0
- package/server/routes/static/staticPageRouter.js +27 -1
- package/server/utils/publicContact.js +31 -0
- package/utils/whatsapp/contactEnv.js +39 -0
- package/vite.config.mjs +2 -1
- package/app/modules/playModule/local/installYtDlp.js +0 -25
- package/app/modules/playModule/local/ytDlpInstaller.js +0 -28
|
@@ -30,11 +30,76 @@ const CommandDetailsPage = ({ command, onClose, devMode }) => {
|
|
|
30
30
|
if (!command) return null;
|
|
31
31
|
const [copyStatus, setCopyStatus] = useState({});
|
|
32
32
|
|
|
33
|
+
const toList = (value) => {
|
|
34
|
+
if (!Array.isArray(value)) return [];
|
|
35
|
+
return value.map((item) => String(item || '').trim()).filter(Boolean);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const metodosDeUso = toList(command.metodos_de_uso);
|
|
39
|
+
const resumoUsuario = String(command.resumo_usuario || command.descricao || `Use /${command.name} para executar esta ação.`).trim();
|
|
40
|
+
const resumoOrigem = String(command.resumo_usuario_origem || '').trim();
|
|
41
|
+
const resumoPendente = Boolean(command.resumo_usuario_revisao_pendente);
|
|
42
|
+
|
|
43
|
+
const quandoUsar = toList(command.quando_usar);
|
|
44
|
+
const respostaEsperada = toList(command.resposta_esperada);
|
|
45
|
+
const errosComuns = toList(command.erros_comuns_usuario);
|
|
46
|
+
const passosErro = toList(command.passos_se_der_erro);
|
|
47
|
+
|
|
48
|
+
const fallbackUso = metodosDeUso[0] || `/${command.name}`;
|
|
49
|
+
const exemplosReais = (Array.isArray(command.exemplos_reais) ? command.exemplos_reais : [])
|
|
50
|
+
.map((example, index) => {
|
|
51
|
+
if (typeof example === 'string') {
|
|
52
|
+
const comando = String(example || '').trim();
|
|
53
|
+
if (!comando) return null;
|
|
54
|
+
return {
|
|
55
|
+
situacao: `Exemplo real ${index + 1} para usar o comando.`,
|
|
56
|
+
comando,
|
|
57
|
+
resposta_esperada: respostaEsperada[0] || 'O bot confirma a execução com uma resposta clara.',
|
|
58
|
+
variacao: '',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!example || typeof example !== 'object' || Array.isArray(example)) return null;
|
|
63
|
+
|
|
64
|
+
const situacao = String(example.situacao || example.cenario || example.contexto || '').trim();
|
|
65
|
+
const comando = String(example.comando || example.command || example.uso || '').trim();
|
|
66
|
+
const resposta = String(example.resposta_esperada || example.expected_response || example.resposta || '').trim();
|
|
67
|
+
const variacao = String(example.variacao || example.outcome_variation || '').trim();
|
|
68
|
+
|
|
69
|
+
if (!comando) return null;
|
|
70
|
+
return {
|
|
71
|
+
situacao: situacao || `Exemplo real ${index + 1} para usar o comando.`,
|
|
72
|
+
comando,
|
|
73
|
+
resposta_esperada: resposta || respostaEsperada[0] || 'O bot responde confirmando o resultado.',
|
|
74
|
+
variacao,
|
|
75
|
+
};
|
|
76
|
+
})
|
|
77
|
+
.filter(Boolean);
|
|
78
|
+
|
|
79
|
+
if (!exemplosReais.length) {
|
|
80
|
+
exemplosReais.push({
|
|
81
|
+
situacao: `Você quer usar /${command.name} no dia a dia.`,
|
|
82
|
+
comando: fallbackUso,
|
|
83
|
+
resposta_esperada: respostaEsperada[0] || 'O bot responde confirmando o resultado.',
|
|
84
|
+
variacao: respostaEsperada[1] || '',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const quandoUsarComFallback = quandoUsar.length ? quandoUsar : [`Quando você precisa executar ${command.descricao || `a ação do comando /${command.name}`}.`, command.requirements?.group ? 'Use dentro de grupos.' : 'Pode ser usado em grupo ou no privado.', command.premium ? 'Disponível para usuários Premium.' : ''].filter(Boolean);
|
|
89
|
+
|
|
90
|
+
const respostaEsperadaComFallback = respostaEsperada.length ? respostaEsperada : ['Sucesso: o bot confirma a execução.', 'Formato incorreto: o bot mostra como usar corretamente.', 'Permissão: o bot informa quando faltar acesso.'];
|
|
91
|
+
|
|
92
|
+
const errosComunsComFallback = errosComuns.length ? errosComuns : ['Digitar o comando fora do formato esperado.', command.requirements?.group ? 'Tentar usar fora de grupo.' : '', command.requirements?.admin ? 'Tentar usar sem ser admin.' : '', command.premium ? 'Tentar usar sem plano Premium ativo.' : ''].filter(Boolean);
|
|
93
|
+
|
|
94
|
+
const passosErroComFallback = passosErro.length ? passosErro : ['Copie um exemplo desta página e teste sem alterar.', 'Confira se você está no local correto (grupo ou privado).', 'Se continuar com erro, fale com o admin no privado.'];
|
|
95
|
+
|
|
33
96
|
const handleCopy = (text, id) => {
|
|
34
|
-
|
|
35
|
-
|
|
97
|
+
const copyText = String(text || '').trim();
|
|
98
|
+
if (!copyText) return;
|
|
99
|
+
navigator.clipboard?.writeText(copyText).catch(() => {});
|
|
100
|
+
setCopyStatus((prev) => ({ ...prev, [id]: true }));
|
|
36
101
|
setTimeout(() => {
|
|
37
|
-
setCopyStatus({ ...
|
|
102
|
+
setCopyStatus((prev) => ({ ...prev, [id]: false }));
|
|
38
103
|
}, 2000);
|
|
39
104
|
};
|
|
40
105
|
|
|
@@ -102,107 +167,222 @@ const CommandDetailsPage = ({ command, onClose, devMode }) => {
|
|
|
102
167
|
|
|
103
168
|
<section className="space-y-6">
|
|
104
169
|
<div className="flex items-center gap-4">
|
|
105
|
-
<h3 className="text-[10px] font-black uppercase tracking-[0.4em] text-white/20">
|
|
170
|
+
<h3 className="text-[10px] font-black uppercase tracking-[0.4em] text-white/20">Resumo rápido</h3>
|
|
106
171
|
<div className="flex-1 h-px bg-white/5"></div>
|
|
107
172
|
</div>
|
|
108
|
-
<div className="
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
173
|
+
<div className="relative p-6 sm:p-8 rounded-[1.5rem] sm:rounded-[2rem] bg-white/[0.03] border border-white/10 space-y-4 overflow-hidden">
|
|
174
|
+
<div className="absolute -top-10 -right-10 w-28 h-28 rounded-full bg-primary/10 blur-3xl"></div>
|
|
175
|
+
<div className="relative flex flex-wrap items-center gap-2">${resumoPendente && html` <span className="badge badge-info badge-sm h-7 px-3 font-bold uppercase tracking-wider">Resumo por IA · Revisão pendente</span> `} ${!resumoPendente && resumoOrigem === 'manual' && html` <span className="badge badge-success badge-sm h-7 px-3 font-bold uppercase tracking-wider">Resumo revisado</span> `}</div>
|
|
176
|
+
<p className="relative text-base sm:text-lg text-white/80 leading-relaxed">${resumoUsuario}</p>
|
|
177
|
+
</div>
|
|
178
|
+
</section>
|
|
179
|
+
|
|
180
|
+
<section className="space-y-6">
|
|
181
|
+
<div className="flex items-center gap-4">
|
|
182
|
+
<h3 className="text-[10px] font-black uppercase tracking-[0.4em] text-white/20">Quando usar</h3>
|
|
183
|
+
<div className="flex-1 h-px bg-white/5"></div>
|
|
184
|
+
</div>
|
|
185
|
+
<div className="grid gap-3">
|
|
186
|
+
${quandoUsarComFallback.map(
|
|
187
|
+
(item, idx) => html`
|
|
188
|
+
<div key=${`when-${idx}`} className="p-4 rounded-2xl bg-white/[0.02] border border-white/5 flex items-start gap-3">
|
|
189
|
+
<span className="mt-0.5 text-primary">•</span>
|
|
190
|
+
<p className="text-sm sm:text-base text-white/75 leading-relaxed">${item}</p>
|
|
117
191
|
</div>
|
|
118
192
|
`,
|
|
119
193
|
)}
|
|
120
194
|
</div>
|
|
121
195
|
</section>
|
|
122
196
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
<div className="flex
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
197
|
+
<section className="space-y-6">
|
|
198
|
+
<div className="flex items-center gap-4">
|
|
199
|
+
<h3 className="text-[10px] font-black uppercase tracking-[0.4em] text-white/20">Exemplos reais</h3>
|
|
200
|
+
<div className="flex-1 h-px bg-white/5"></div>
|
|
201
|
+
</div>
|
|
202
|
+
<div className="grid gap-5">
|
|
203
|
+
${exemplosReais.map(
|
|
204
|
+
(example, idx) => html`
|
|
205
|
+
<article key=${`example-${idx}`} className="p-5 sm:p-6 rounded-[1.5rem] bg-white/[0.03] border border-white/10 space-y-5">
|
|
206
|
+
<div className="space-y-1">
|
|
207
|
+
<p className="text-[9px] font-black uppercase tracking-[0.2em] text-primary/70">Situação real</p>
|
|
208
|
+
<p className="text-sm sm:text-base text-white/80 leading-relaxed">${example.situacao}</p>
|
|
209
|
+
</div>
|
|
210
|
+
|
|
211
|
+
<div className="space-y-2">
|
|
212
|
+
<p className="text-[9px] font-black uppercase tracking-[0.2em] text-white/40">Comando pronto</p>
|
|
213
|
+
<div className="relative flex flex-col sm:flex-row items-stretch sm:items-center gap-0 sm:gap-4 p-1 rounded-2xl bg-[#0b1124] border border-white/10">
|
|
214
|
+
<code className="flex-1 px-5 py-4 sm:px-6 sm:py-4 font-mono text-sm text-primary/80 break-all leading-relaxed">${example.comando}</code>
|
|
215
|
+
<button onClick=${() => handleCopy(example.comando, `example-cmd-${idx}`)} className=${`px-8 py-3.5 rounded-2xl sm:rounded-r-[1.2rem] sm:rounded-l-none font-black text-[10px] uppercase tracking-widest transition-all ${copyStatus[`example-cmd-${idx}`] ? 'bg-success text-white' : 'bg-white/5 hover:bg-primary hover:text-primary-content'}`}>${copyStatus[`example-cmd-${idx}`] ? 'Copiado!' : 'Copiar'}</button>
|
|
140
216
|
</div>
|
|
141
|
-
<p className="text-xs sm:text-sm text-white/50 font-medium leading-relaxed">${arg.description}</p>
|
|
142
217
|
</div>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
218
|
+
|
|
219
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
220
|
+
<div className="p-4 rounded-xl bg-white/[0.02] border border-white/5">
|
|
221
|
+
<p className="text-[9px] font-black uppercase tracking-[0.2em] text-white/40 mb-2">Resposta esperada</p>
|
|
222
|
+
<p className="text-sm text-white/75 leading-relaxed">${example.resposta_esperada}</p>
|
|
223
|
+
</div>
|
|
224
|
+
<div className="p-4 rounded-xl bg-white/[0.02] border border-white/5">
|
|
225
|
+
<p className="text-[9px] font-black uppercase tracking-[0.2em] text-white/40 mb-2">Variação possível</p>
|
|
226
|
+
<p className="text-sm text-white/75 leading-relaxed">${example.variacao || 'Se faltar parâmetro ou permissão, o bot explica o próximo passo para corrigir.'}</p>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
</article>
|
|
230
|
+
`,
|
|
231
|
+
)}
|
|
232
|
+
</div>
|
|
233
|
+
</section>
|
|
234
|
+
|
|
235
|
+
<section className="space-y-6">
|
|
236
|
+
<div className="flex items-center gap-4">
|
|
237
|
+
<h3 className="text-[10px] font-black uppercase tracking-[0.4em] text-white/20">O que esperar de resposta</h3>
|
|
238
|
+
<div className="flex-1 h-px bg-white/5"></div>
|
|
239
|
+
</div>
|
|
240
|
+
<div className="grid gap-3">
|
|
241
|
+
${respostaEsperadaComFallback.map(
|
|
242
|
+
(item, idx) => html`
|
|
243
|
+
<div key=${`expected-${idx}`} className="p-4 rounded-2xl bg-white/[0.02] border border-white/5 flex items-start gap-3">
|
|
244
|
+
<span className="mt-0.5 text-emerald-400">✓</span>
|
|
245
|
+
<p className="text-sm sm:text-base text-white/75 leading-relaxed">${item}</p>
|
|
246
|
+
</div>
|
|
247
|
+
`,
|
|
248
|
+
)}
|
|
249
|
+
</div>
|
|
250
|
+
</section>
|
|
251
|
+
|
|
252
|
+
<section className="space-y-6">
|
|
253
|
+
<div className="flex items-center gap-4">
|
|
254
|
+
<h3 className="text-[10px] font-black uppercase tracking-[0.4em] text-white/20">Se der erro</h3>
|
|
255
|
+
<div className="flex-1 h-px bg-white/5"></div>
|
|
256
|
+
</div>
|
|
257
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-5">
|
|
258
|
+
<div className="p-5 rounded-[1.3rem] bg-white/[0.03] border border-white/10 space-y-4">
|
|
259
|
+
<p className="text-[10px] font-black uppercase tracking-[0.2em] text-amber-300">Erros comuns</p>
|
|
260
|
+
<div className="space-y-2">
|
|
261
|
+
${errosComunsComFallback.map(
|
|
262
|
+
(item, idx) => html`
|
|
263
|
+
<div key=${`common-error-${idx}`} className="text-sm text-white/75 leading-relaxed flex items-start gap-2">
|
|
264
|
+
<span className="text-amber-300">•</span>
|
|
265
|
+
<span>${item}</span>
|
|
266
|
+
</div>
|
|
267
|
+
`,
|
|
268
|
+
)}
|
|
165
269
|
</div>
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
270
|
+
</div>
|
|
271
|
+
|
|
272
|
+
<div className="p-5 rounded-[1.3rem] bg-white/[0.03] border border-white/10 space-y-4">
|
|
273
|
+
<p className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">O que fazer agora</p>
|
|
274
|
+
<div className="space-y-2">
|
|
275
|
+
${passosErroComFallback.map(
|
|
276
|
+
(item, idx) => html`
|
|
277
|
+
<div key=${`error-step-${idx}`} className="text-sm text-white/75 leading-relaxed flex items-start gap-2">
|
|
278
|
+
<span className="text-primary font-black">${idx + 1}.</span>
|
|
279
|
+
<span>${item}</span>
|
|
280
|
+
</div>
|
|
281
|
+
`,
|
|
282
|
+
)}
|
|
169
283
|
</div>
|
|
170
284
|
</div>
|
|
171
|
-
</
|
|
172
|
-
|
|
173
|
-
${command.technical?.collected_data?.length > 0 &&
|
|
174
|
-
html`
|
|
175
|
-
<section className="p-6 sm:p-8 rounded-[1.5rem] sm:rounded-[2.5rem] bg-white/[0.02] border border-white/5 space-y-6 relative overflow-hidden group">
|
|
176
|
-
<div className="absolute -right-8 -bottom-8 w-32 h-32 bg-emerald-500/5 blur-2xl rounded-full group-hover:bg-emerald-500/10 transition-colors"></div>
|
|
177
|
-
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-white/30 relative z-10">Privacidade e Dados</h3>
|
|
178
|
-
<div className="flex flex-wrap gap-2 relative z-10">${command.technical.collected_data.map((data) => html` <span key=${data} className="text-[10px] font-bold bg-white/5 px-4 py-2 rounded-xl border border-white/10 text-white/60">${data}</span> `)}</div>
|
|
179
|
-
<p className="text-[9px] text-white/20 font-medium leading-relaxed italic relative z-10">* Estes dados são processados apenas para execução do comando.</p>
|
|
180
|
-
</section>
|
|
181
|
-
`}
|
|
182
|
-
</div>
|
|
285
|
+
</div>
|
|
286
|
+
</section>
|
|
183
287
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
<
|
|
189
|
-
<div className="flex-1 h-px bg-warning/10"></div>
|
|
288
|
+
<details className="group rounded-[1.5rem] border border-white/10 bg-white/[0.02] open:bg-white/[0.03] transition-colors">
|
|
289
|
+
<summary className="list-none cursor-pointer px-6 py-5 flex items-center justify-between gap-4">
|
|
290
|
+
<div>
|
|
291
|
+
<p className="text-[10px] font-black uppercase tracking-[0.3em] text-white/40">Área técnica</p>
|
|
292
|
+
<p className="text-xs text-white/50 mt-1">Especificações avançadas e metadados do comando.</p>
|
|
190
293
|
</div>
|
|
191
|
-
<
|
|
192
|
-
<
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
294
|
+
<span className="w-8 h-8 rounded-xl bg-white/5 border border-white/10 flex items-center justify-center group-open:rotate-180 transition-transform">
|
|
295
|
+
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-white/60" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M19 9l-7 7-7-7" /></svg>
|
|
296
|
+
</span>
|
|
297
|
+
</summary>
|
|
298
|
+
|
|
299
|
+
<div className="px-6 pb-6 space-y-6">
|
|
300
|
+
${metodosDeUso.length > 0 &&
|
|
301
|
+
html`
|
|
302
|
+
<section className="space-y-3">
|
|
303
|
+
<p className="text-[10px] font-black uppercase tracking-[0.2em] text-white/40">Como usar agora</p>
|
|
304
|
+
<div className="grid gap-3">
|
|
305
|
+
${metodosDeUso.map(
|
|
306
|
+
(usage, idx) => html`
|
|
307
|
+
<div key=${idx} className="relative flex flex-col sm:flex-row items-stretch sm:items-center gap-0 sm:gap-4 p-1 rounded-2xl bg-[#0b1124] border border-white/10">
|
|
308
|
+
<code className="flex-1 px-5 py-4 sm:px-6 sm:py-4 font-mono text-sm text-primary/80 break-all leading-relaxed">${usage}</code>
|
|
309
|
+
<button onClick=${() => handleCopy(usage, `usage-${idx}`)} className=${`px-8 py-3.5 rounded-2xl sm:rounded-r-[1.2rem] sm:rounded-l-none font-black text-[10px] uppercase tracking-widest transition-all ${copyStatus[`usage-${idx}`] ? 'bg-success text-white' : 'bg-white/5 hover:bg-primary hover:text-primary-content'}`}>${copyStatus[`usage-${idx}`] ? 'Copiado!' : 'Copiar'}</button>
|
|
310
|
+
</div>
|
|
311
|
+
`,
|
|
312
|
+
)}
|
|
313
|
+
</div>
|
|
314
|
+
</section>
|
|
315
|
+
`}
|
|
316
|
+
${command.arguments?.length > 0 &&
|
|
317
|
+
html`
|
|
318
|
+
<section className="space-y-3">
|
|
319
|
+
<p className="text-[10px] font-black uppercase tracking-[0.2em] text-white/40">Argumentos</p>
|
|
320
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
|
321
|
+
${command.arguments.map(
|
|
322
|
+
(arg) => html`
|
|
323
|
+
<div key=${arg.name} className="p-4 rounded-2xl bg-white/[0.02] border border-white/10">
|
|
324
|
+
<div className="flex items-start justify-between gap-2 mb-2">
|
|
325
|
+
<h4 className="text-sm font-black text-white">${arg.name}</h4>
|
|
326
|
+
<span className=${`text-[8px] font-black uppercase px-2 py-1 rounded-full border ${arg.required ? 'bg-error/10 text-error border-error/20' : 'bg-white/5 text-white/40 border-white/10'}`}>${arg.required ? 'Obrigatório' : 'Opcional'}</span>
|
|
327
|
+
</div>
|
|
328
|
+
<p className="text-[10px] font-mono text-white/40 uppercase tracking-wider mb-2">Tipo: ${arg.type}</p>
|
|
329
|
+
<p className="text-sm text-white/65 leading-relaxed">${arg.description}</p>
|
|
330
|
+
</div>
|
|
331
|
+
`,
|
|
332
|
+
)}
|
|
333
|
+
</div>
|
|
334
|
+
</section>
|
|
335
|
+
`}
|
|
336
|
+
|
|
337
|
+
<section className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
338
|
+
<div className="p-5 rounded-2xl bg-white/[0.02] border border-white/10 space-y-4">
|
|
339
|
+
<p className="text-[10px] font-black uppercase tracking-[0.2em] text-white/40">Specs técnicas</p>
|
|
340
|
+
<div className="grid grid-cols-2 gap-y-4">
|
|
341
|
+
<div>
|
|
342
|
+
<p className="text-[9px] font-bold uppercase text-white/20 mb-1 tracking-widest">Versão</p>
|
|
343
|
+
<p className="text-sm font-black text-white">${command.technical?.version || '1.0.0'}</p>
|
|
344
|
+
</div>
|
|
345
|
+
<div>
|
|
346
|
+
<p className="text-[9px] font-bold uppercase text-white/20 mb-1 tracking-widest">Estabilidade</p>
|
|
347
|
+
<p className="text-sm font-black text-emerald-400">${command.technical?.stability || 'stable'}</p>
|
|
348
|
+
</div>
|
|
349
|
+
<div>
|
|
350
|
+
<p className="text-[9px] font-bold uppercase text-white/20 mb-1 tracking-widest">Risco</p>
|
|
351
|
+
<p className="text-sm font-black ${command.technical?.risk_level !== 'low' ? 'text-rose-500' : 'text-emerald-400'}">${command.technical?.risk_level?.toUpperCase() || 'LOW'}</p>
|
|
352
|
+
</div>
|
|
353
|
+
<div>
|
|
354
|
+
<p className="text-[9px] font-bold uppercase text-white/20 mb-1 tracking-widest">ID Sistema</p>
|
|
355
|
+
<p className="text-[10px] font-mono font-bold text-white/40 break-all">${command.id}</p>
|
|
356
|
+
</div>
|
|
197
357
|
</div>
|
|
198
|
-
<pre className="p-6 sm:p-8 font-mono text-[9px] sm:text-[11px] text-warning/70 overflow-x-auto max-h-[400px] scrollbar-thin scrollbar-thumb-warning/20">
|
|
199
|
-
${JSON.stringify(command, null, 2)}
|
|
200
|
-
</pre
|
|
201
|
-
>
|
|
202
358
|
</div>
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
359
|
+
|
|
360
|
+
<div className="p-5 rounded-2xl bg-white/[0.02] border border-white/10 space-y-4">
|
|
361
|
+
<p className="text-[10px] font-black uppercase tracking-[0.2em] text-white/40">Privacidade e dados</p>
|
|
362
|
+
${(command.technical?.collected_data || []).length > 0
|
|
363
|
+
? html`
|
|
364
|
+
<div className="flex flex-wrap gap-2">${command.technical.collected_data.map((data) => html` <span key=${data} className="text-[10px] font-bold bg-white/5 px-3 py-1.5 rounded-lg border border-white/10 text-white/60">${data}</span> `)}</div>
|
|
365
|
+
<p className="text-[10px] text-white/40 leading-relaxed">Dados processados apenas para executar a funcionalidade solicitada.</p>
|
|
366
|
+
`
|
|
367
|
+
: html`<p className="text-sm text-white/60 leading-relaxed">Este comando não expõe dados técnicos adicionais de coleta.</p>`}
|
|
368
|
+
</div>
|
|
369
|
+
</section>
|
|
370
|
+
|
|
371
|
+
${devMode &&
|
|
372
|
+
html`
|
|
373
|
+
<section className="space-y-3">
|
|
374
|
+
<p className="text-[10px] font-black uppercase tracking-[0.2em] text-warning/50">Developer Metadata</p>
|
|
375
|
+
<div className="relative bg-[#020617] border border-warning/10 rounded-2xl overflow-hidden">
|
|
376
|
+
<div className="bg-warning/5 px-4 py-3 border-b border-warning/10 flex items-center justify-between gap-4">
|
|
377
|
+
<span className="text-[9px] font-black uppercase tracking-widest text-warning/60 font-mono">command_schema.json</span>
|
|
378
|
+
<button onClick=${() => handleCopy(JSON.stringify(command, null, 2), 'raw-json')} className=${`text-[9px] font-black uppercase tracking-widest transition-colors ${copyStatus['raw-json'] ? 'text-success' : 'text-warning/40 hover:text-warning'}`}>${copyStatus['raw-json'] ? 'Copiado!' : 'Copiar JSON'}</button>
|
|
379
|
+
</div>
|
|
380
|
+
<pre className="p-4 sm:p-6 font-mono text-[9px] sm:text-[11px] text-warning/70 overflow-x-auto max-h-[380px] scrollbar-thin scrollbar-thumb-warning/20">${JSON.stringify(command, null, 2)}</pre>
|
|
381
|
+
</div>
|
|
382
|
+
</section>
|
|
383
|
+
`}
|
|
384
|
+
</div>
|
|
385
|
+
</details>
|
|
206
386
|
|
|
207
387
|
<div className="pt-8 sm:pt-12 pb-20 text-center">
|
|
208
388
|
<button onClick=${onClose} className="group relative inline-flex items-center justify-center w-full sm:w-auto">
|
|
@@ -411,7 +411,7 @@ function CreatePackApp() {
|
|
|
411
411
|
const [name, setName] = useState('');
|
|
412
412
|
const [description, setDescription] = useState('');
|
|
413
413
|
const [publisher, setPublisher] = useState('');
|
|
414
|
-
const [visibility, setVisibility] = useState('
|
|
414
|
+
const [visibility, setVisibility] = useState('private');
|
|
415
415
|
const [tags, setTags] = useState([]);
|
|
416
416
|
const [tagInput, setTagInput] = useState('');
|
|
417
417
|
const [suggestedTags, setSuggestedTags] = useState(DEFAULT_SUGGESTED_TAGS);
|
|
@@ -1322,7 +1322,7 @@ function CreatePackApp() {
|
|
|
1322
1322
|
setName('');
|
|
1323
1323
|
setDescription('');
|
|
1324
1324
|
setPublisher('');
|
|
1325
|
-
setVisibility('
|
|
1325
|
+
setVisibility('private');
|
|
1326
1326
|
setTags([]);
|
|
1327
1327
|
setTagInput('');
|
|
1328
1328
|
setFiles([]);
|
|
@@ -1480,7 +1480,7 @@ function CreatePackApp() {
|
|
|
1480
1480
|
</label>
|
|
1481
1481
|
<label className="block">
|
|
1482
1482
|
<span className="mb-2 inline-block text-xs font-semibold text-slate-300">Visibilidade</span>
|
|
1483
|
-
<select value=${visibility} onChange=${(e) => setVisibility(String(e.target.value || '
|
|
1483
|
+
<select value=${visibility} onChange=${(e) => setVisibility(String(e.target.value || 'private'))} className="h-11 w-full rounded-2xl border border-line/70 bg-panelSoft/80 px-4 text-sm outline-none focus:border-accent/60 md:h-12">
|
|
1484
1484
|
<option value="public">Público</option>
|
|
1485
1485
|
<option value="unlisted">Não listado</option>
|
|
1486
1486
|
<option value="private">Privado</option>
|