fix(ci): resolve deploy step hanging on pkill

- pgrep -f botserver matched the SSH command itself causing deadlock
- replaced with pkill -f '/opt/gbo/bin/botserver' || true
- added SSH keepalive (ServerAliveInterval=10, ServerAliveCountMax=3)
- added Step 7: explicitly start botserver after deploy
- fixed unquoted SSH_ARGS causing argument splitting
- increased verify sleep from 10s to 15s
This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2026-04-03 19:44:38 -03:00
parent a377af5ba3
commit 1bf9e1872b
24 changed files with 2 additions and 3218 deletions

1
.gitignore vendored
View file

@ -53,6 +53,7 @@ node_modules/
/blob-report/ /blob-report/
/playwright/.cache/ /playwright/.cache/
/playwright/.auth/ /playwright/.auth/
.playwright*
config/directory_config.json config/directory_config.json
# CI cache bust: Fri Feb 13 22:33:51 UTC 2026 # CI cache bust: Fri Feb 13 22:33:51 UTC 2026

View file

@ -1,37 +0,0 @@
- generic [ref=e5]:
- generic [ref=e6]:
- generic [ref=e7]: Chat
- generic [ref=e8]:
- button [ref=e9] [cursor=pointer]:
- img [ref=e10]
- button [ref=e11] [cursor=pointer]:
- img [ref=e12]
- button [ref=e14] [cursor=pointer]:
- img [ref=e15]
- generic [ref=e18]:
- generic [ref=e19]:
- main [ref=e20]:
- paragraph [ref=e31]: Olá! Sou o assistente virtual do Santuário Cristo Redentor. Como posso ajudá-lo hoje com informações sobre celebrações, eventos, visitação ou orações?
- contentinfo [ref=e21]:
- generic [ref=e22]:
- button "Agendar Batizado" [ref=e32] [cursor=pointer]
- button "Agendar Casamento" [ref=e33] [cursor=pointer]
- button "Agendar Missa" [ref=e34] [cursor=pointer]
- button "Agendar Peregrinação" [ref=e35] [cursor=pointer]
- button "Pedido de Oração" [ref=e36] [cursor=pointer]
- button "Uso de Imagem" [ref=e37] [cursor=pointer]
- button "Licenciamento" [ref=e38] [cursor=pointer]
- button "Evento/Iluminação" [ref=e39] [cursor=pointer]
- button "Cadastrar Guia" [ref=e40] [cursor=pointer]
- button "Fazer Doação" [ref=e41] [cursor=pointer]
- generic [ref=e23]:
- generic [ref=e24]:
- button "Agent" [ref=e25] [cursor=pointer]
- button "Chat" [ref=e26] [cursor=pointer]
- textbox "Message... (type @ to mention)" [active] [ref=e27]
- button "↑" [ref=e28] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"

View file

@ -1,45 +0,0 @@
- generic [ref=e2]:
- generic [ref=e3]:
- img "General Bots" [ref=e6]
- heading "Welcome Back" [level=1] [ref=e7]
- paragraph [ref=e8]: Sign in to your General Bots account
- generic [ref=e10]:
- generic [ref=e11]:
- generic [ref=e12]:
- generic [ref=e13]: Email Address
- generic [ref=e14]:
- img
- textbox "Email Address" [ref=e15]:
- /placeholder: you@example.com
- generic [ref=e16]:
- generic [ref=e17]: Password
- generic [ref=e18]:
- img
- textbox "Password" [ref=e19]:
- /placeholder: ••••••••
- button [ref=e20] [cursor=pointer]:
- img [ref=e21]
- generic [ref=e24]:
- generic [ref=e27] [cursor=pointer]: Remember me
- link "Forgot password?" [ref=e28] [cursor=pointer]:
- /url: /auth/forgot-password
- button "Sign In" [ref=e29] [cursor=pointer]:
- generic [ref=e30]: Sign In
- generic [ref=e32]: or continue with
- generic [ref=e33]:
- button "Google" [ref=e34] [cursor=pointer]:
- img [ref=e35]
- text: Google
- button "Microsoft" [ref=e40] [cursor=pointer]:
- img [ref=e41]
- text: Microsoft
- button "GitHub" [ref=e46] [cursor=pointer]:
- img [ref=e47]
- text: GitHub
- button "Apple" [ref=e49] [cursor=pointer]:
- img [ref=e50]
- text: Apple
- paragraph [ref=e53]:
- text: Don't have an account?
- link "Create account" [ref=e54] [cursor=pointer]:
- /url: /auth/register

View file

@ -1,25 +0,0 @@
- generic [ref=e5]:
- generic [ref=e6]:
- generic [ref=e7]: Chat
- generic [ref=e8]:
- button [ref=e9] [cursor=pointer]:
- img [ref=e10]
- button [ref=e11] [cursor=pointer]:
- img [ref=e12]
- button [ref=e14] [cursor=pointer]:
- img [ref=e15]
- generic [ref=e18]:
- generic [ref=e19]:
- main [ref=e20]
- contentinfo [ref=e21]:
- generic [ref=e23]:
- generic [ref=e24]:
- button "Agent" [ref=e25] [cursor=pointer]
- button "Chat" [ref=e26] [cursor=pointer]
- textbox "Message... (type @ to mention)" [active] [ref=e27]
- button "↑" [ref=e28] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"

View file

@ -1,111 +0,0 @@
- generic [ref=e2]:
- complementary [ref=e3]:
- generic "Home" [ref=e4] [cursor=pointer]:
- img [ref=e5]
- generic "Search" [ref=e8] [cursor=pointer]:
- img [ref=e9]
- generic "Terminal" [ref=e12] [cursor=pointer]:
- img [ref=e13]
- generic "User" [ref=e15] [cursor=pointer]:
- img [ref=e16]
- generic "Apps" [ref=e19] [cursor=pointer]:
- img [ref=e20]
- generic "Settings" [ref=e25] [cursor=pointer]:
- img [ref=e26]
- generic [ref=e29]:
- generic [ref=e30]:
- generic [ref=e31]:
- generic [ref=e32] [cursor=pointer]:
- img [ref=e34]
- generic [ref=e36]: Vibe
- generic [ref=e37] [cursor=pointer]:
- img [ref=e39]
- generic [ref=e44]: CRM
- generic [ref=e45] [cursor=pointer]:
- img [ref=e47]
- generic [ref=e49]: Campaigns
- generic [ref=e50] [cursor=pointer]:
- img [ref=e52]
- generic [ref=e53]: Lists
- generic [ref=e54] [cursor=pointer]:
- img [ref=e56]
- generic [ref=e58]: Templates
- generic [ref=e59] [cursor=pointer]:
- img [ref=e61]
- generic [ref=e64]: Tasks
- generic [ref=e65] [cursor=pointer]:
- img [ref=e67]
- generic [ref=e69]: Chat
- generic [ref=e70] [cursor=pointer]:
- img [ref=e72]
- generic [ref=e74]: Terminal
- generic [ref=e75] [cursor=pointer]:
- img [ref=e77]
- generic [ref=e79]: Explorer
- generic [ref=e80] [cursor=pointer]:
- img [ref=e82]
- generic [ref=e85]: Editor
- generic [ref=e86] [cursor=pointer]:
- img [ref=e88]
- generic [ref=e93]: Designer
- generic [ref=e94] [cursor=pointer]:
- img [ref=e96]
- generic [ref=e99]: BASIC
- generic [ref=e100] [cursor=pointer]:
- img [ref=e102]
- generic [ref=e105]: Browser
- generic [ref=e106]:
- generic [ref=e107]:
- generic [ref=e108]: Chat
- generic [ref=e109]:
- button [ref=e110] [cursor=pointer]:
- img [ref=e111]
- button [ref=e112] [cursor=pointer]:
- img [ref=e113]
- button [ref=e115] [cursor=pointer]:
- img [ref=e116]
- generic [ref=e119]:
- generic [ref=e120]:
- generic:
- generic: Connecting...
- main [ref=e121]
- contentinfo [ref=e122]:
- generic [ref=e124]:
- generic [ref=e125]:
- button "Agent" [ref=e126] [cursor=pointer]
- button "Chat" [ref=e127] [cursor=pointer]
- textbox "Message... (type @ to mention)" [active] [ref=e128]
- button "↑" [ref=e129] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"
- contentinfo [ref=e130]:
- img [ref=e134] [cursor=pointer]
- generic [ref=e136]:
- combobox [ref=e138] [cursor=pointer]:
- option "🎨 Default"
- option "☀️ Light" [selected]
- option "🍊 Orange"
- option "🌃 Cyberpunk"
- option "🌴 Retrowave"
- option "💭 Vapor Dream"
- option "✨ Y2K"
- option "🔲 3D Bevel"
- option "🕹️ Arcade"
- option "🪩 Disco"
- option "🎸 Grunge"
- option "🎺 Jazz"
- option "🌻 Mellow"
- option "🏠 Mid Century"
- option "📷 Polaroid"
- option "📺 Cartoons"
- option "🏖️ Seaside"
- option "⌨️ Typewriter"
- option "📠 Xerox"
- option "📁 XTree"
- button "Sign In" [ref=e139] [cursor=pointer]
- generic [ref=e140]:
- generic [ref=e141]: 00:00
- generic [ref=e142]: 01/01/2026

View file

@ -1,39 +0,0 @@
- generic [ref=e106]:
- generic [ref=e107]:
- generic [ref=e108]: Chat
- generic [ref=e109]:
- button [ref=e110] [cursor=pointer]:
- img [ref=e111]
- button [ref=e112] [cursor=pointer]:
- img [ref=e113]
- button [ref=e115] [cursor=pointer]:
- img [ref=e116]
- generic [ref=e119]:
- generic [ref=e120]:
- main [ref=e121]:
- paragraph [ref=e145]: Olá! Sou o Assistente Virtual da SEAD — Secretaria de Estado da Administração de Sergipe. Estou aqui para ajudá-lo com contracheques, agendamentos no CEAC, perícias médicas, documentos funcionais, cursos da Escola de Governo e muito mais. Como posso te ajudar hoje?
- generic [ref=e158]: 🔍 Detectar Desvios na Folha
- contentinfo [ref=e122]:
- generic [ref=e123]:
- button "📄 Segunda Via de Contracheque" [ref=e146] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e147] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e148] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e149] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e150] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e151] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e152] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e153] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e154] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [active] [ref=e155] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e156] [cursor=pointer]
- generic [ref=e124]:
- generic [ref=e125]:
- button "Agent" [ref=e126] [cursor=pointer]
- button "Chat" [ref=e127] [cursor=pointer]
- textbox "Message... (type @ to mention)" [ref=e128]
- button "↑" [ref=e129] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"

View file

@ -1,109 +0,0 @@
- generic [ref=e2]:
- complementary [ref=e3]:
- generic "Home" [ref=e4] [cursor=pointer]:
- img [ref=e5]
- generic "Search" [ref=e8] [cursor=pointer]:
- img [ref=e9]
- generic "Terminal" [ref=e12] [cursor=pointer]:
- img [ref=e13]
- generic "User" [ref=e15] [cursor=pointer]:
- img [ref=e16]
- generic "Apps" [ref=e19] [cursor=pointer]:
- img [ref=e20]
- generic "Settings" [ref=e25] [cursor=pointer]:
- img [ref=e26]
- generic [ref=e29]:
- generic [ref=e30]:
- generic [ref=e31]:
- generic [ref=e32] [cursor=pointer]:
- img [ref=e34]
- generic [ref=e36]: Vibe
- generic [ref=e37] [cursor=pointer]:
- img [ref=e39]
- generic [ref=e44]: CRM
- generic [ref=e45] [cursor=pointer]:
- img [ref=e47]
- generic [ref=e49]: Campaigns
- generic [ref=e50] [cursor=pointer]:
- img [ref=e52]
- generic [ref=e53]: Lists
- generic [ref=e54] [cursor=pointer]:
- img [ref=e56]
- generic [ref=e58]: Templates
- generic [ref=e59] [cursor=pointer]:
- img [ref=e61]
- generic [ref=e64]: Tasks
- generic [ref=e65] [cursor=pointer]:
- img [ref=e67]
- generic [ref=e69]: Chat
- generic [ref=e70] [cursor=pointer]:
- img [ref=e72]
- generic [ref=e74]: Terminal
- generic [ref=e75] [cursor=pointer]:
- img [ref=e77]
- generic [ref=e79]: Explorer
- generic [ref=e80] [cursor=pointer]:
- img [ref=e82]
- generic [ref=e85]: Editor
- generic [ref=e86] [cursor=pointer]:
- img [ref=e88]
- generic [ref=e93]: Designer
- generic [ref=e94] [cursor=pointer]:
- img [ref=e96]
- generic [ref=e99]: BASIC
- generic [ref=e100] [cursor=pointer]:
- img [ref=e102]
- generic [ref=e105]: Browser
- generic [ref=e106]:
- generic [ref=e107]:
- generic [ref=e108]: Chat
- generic [ref=e109]:
- button [ref=e110] [cursor=pointer]:
- img [ref=e111]
- button [ref=e112] [cursor=pointer]:
- img [ref=e113]
- button [ref=e115] [cursor=pointer]:
- img [ref=e116]
- generic [ref=e119]:
- generic [ref=e120]:
- main [ref=e121]
- contentinfo [ref=e122]:
- generic [ref=e124]:
- generic [ref=e125]:
- button "Agent" [ref=e126] [cursor=pointer]
- button "Chat" [ref=e127] [cursor=pointer]
- textbox "Message... (type @ to mention)" [active] [ref=e128]
- button "↑" [ref=e129] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"
- contentinfo [ref=e130]:
- img [ref=e134] [cursor=pointer]
- generic [ref=e136]:
- combobox [ref=e138] [cursor=pointer]:
- option "🎨 Default"
- option "☀️ Light" [selected]
- option "🍊 Orange"
- option "🌃 Cyberpunk"
- option "🌴 Retrowave"
- option "💭 Vapor Dream"
- option "✨ Y2K"
- option "🔲 3D Bevel"
- option "🕹️ Arcade"
- option "🪩 Disco"
- option "🎸 Grunge"
- option "🎺 Jazz"
- option "🌻 Mellow"
- option "🏠 Mid Century"
- option "📷 Polaroid"
- option "📺 Cartoons"
- option "🏖️ Seaside"
- option "⌨️ Typewriter"
- option "📠 Xerox"
- option "📁 XTree"
- button "Sign In" [ref=e139] [cursor=pointer]
- generic [ref=e140]:
- generic [ref=e141]: 00:00
- generic [ref=e142]: 01/01/2026

View file

@ -1,50 +0,0 @@
- generic [ref=e106]:
- generic [ref=e107]:
- generic [ref=e108]: Chat
- generic [ref=e109]:
- button [ref=e110] [cursor=pointer]:
- img [ref=e111]
- button [ref=e112] [cursor=pointer]:
- img [ref=e113]
- button [ref=e115] [cursor=pointer]:
- img [ref=e116]
- generic [ref=e119]:
- generic [ref=e120]:
- main [ref=e121]:
- paragraph [ref=e145]: Olá! Sou o Assistente Virtual da SEAD — Secretaria de Estado da Administração de Sergipe. Estou aqui para ajudá-lo com contracheques, agendamentos no CEAC, perícias médicas, documentos funcionais, cursos da Escola de Governo e muito mais. Como posso te ajudar hoje?
- generic [ref=e169]: 🔍 Detectar Desvios na Folha
- contentinfo [ref=e122]:
- generic [ref=e123]:
- button "📄 Segunda Via de Contracheque" [ref=e146] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e147] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e148] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e149] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e150] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e151] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e152] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e153] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e154] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [active] [ref=e155] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e156] [cursor=pointer]
- button "📄 Segunda Via de Contracheque" [ref=e157] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e158] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e159] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e160] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e161] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e162] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e163] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e164] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e165] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [ref=e166] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e167] [cursor=pointer]
- generic [ref=e124]:
- generic [ref=e125]:
- button "Agent" [ref=e126] [cursor=pointer]
- button "Chat" [ref=e127] [cursor=pointer]
- textbox "Message... (type @ to mention)" [ref=e128]
- button "↑" [ref=e129] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"

View file

@ -1,123 +0,0 @@
- generic [ref=e106]:
- generic [ref=e107]:
- generic [ref=e108]: Chat
- generic [ref=e109]:
- button [ref=e110] [cursor=pointer]:
- img [ref=e111]
- button [ref=e112] [cursor=pointer]:
- img [ref=e113]
- button [ref=e115] [cursor=pointer]:
- img [ref=e116]
- generic [ref=e119]:
- generic [ref=e120]:
- main [ref=e121]:
- paragraph [ref=e145]: Olá! Sou o Assistente Virtual da SEAD — Secretaria de Estado da Administração de Sergipe. Estou aqui para ajudá-lo com contracheques, agendamentos no CEAC, perícias médicas, documentos funcionais, cursos da Escola de Governo e muito mais. Como posso te ajudar hoje?
- generic [ref=e169]: 🔍 Detectar Desvios na Folha
- generic [ref=e171]:
- paragraph [ref=e172]:
- text: 🕵️‍♀️
- strong [ref=e173]: Passo a passo para detectar desvios na sua folha de pagamento
- list [ref=e174]:
- listitem [ref=e175]:
- paragraph [ref=e176]:
- strong [ref=e177]: Acesse o Contracheque Online
- list [ref=e178]:
- listitem [ref=e179]: Entre no portal SIPES/SEAD com seu login.
- listitem [ref=e180]: Visualize o contracheque do mês corrente e dos últimos 6 meses.
- listitem [ref=e181]:
- paragraph [ref=e182]:
- strong [ref=e183]: Compare os valores
- list [ref=e184]:
- listitem [ref=e185]:
- text: 📈
- strong [ref=e186]: Remuneração Base
- text: ": deve permanecer constante (exceto progressões ou promoções)."
- listitem [ref=e187]:
- text:
- strong [ref=e188]: Verbas Variáveis
- text: ": identifique adicionais, horas extras ou gratificações que não reconhece."
- listitem [ref=e189]:
- text:
- strong [ref=e190]: Descontos
- text: ": cheque descontos de INSS, IRRF, pensão alimentícia e demais deduções."
- listitem [ref=e191]:
- paragraph [ref=e192]:
- strong [ref=e193]: Solicite documentos complementares (se necessário)
- list [ref=e194]:
- listitem [ref=e195]:
- strong [ref=e196]: Histórico de contracheques
- text: tipo
- code [ref=e197]: CONTRACHEQUE_HISTORICO
- text: .
- listitem [ref=e198]:
- strong [ref=e199]: Informe de rendimentos
- text: ou
- strong [ref=e200]: Ficha financeira
- text: para cruzar com a Receita Federal.
- listitem [ref=e201]:
- paragraph [ref=e202]:
- strong [ref=e203]: Cruzamento de informações
- list [ref=e204]:
- listitem [ref=e205]:
- text: Use o
- strong [ref=e206]: Informe de Rendimentos
- text: para verificar se os valores declarados coincidem com o que consta na folha.
- listitem [ref=e207]:
- text: Compare a
- strong [ref=e208]: Ficha Financeira
- text: com o extrato bancário (se houver depósito direto).
- listitem [ref=e209]:
- paragraph [ref=e210]:
- strong [ref=e211]: Registre um protocolo na SEAD/SEPLAGSE
- list [ref=e212]:
- listitem [ref=e213]:
- text: "Caso encontre alguma divergência, abra um protocolo (ex.:"
- code [ref=e214]: CCH123456
- text: ).
- listitem [ref=e215]: Descreva claramente a diferença encontrada e anexe prints ou documentos.
- listitem [ref=e216]:
- paragraph [ref=e217]:
- strong [ref=e218]: Acompanhamento
- list [ref=e219]:
- listitem [ref=e220]: Acompanhe o status do protocolo pelo portal ou pelo telefone da Ouvidoria.
- listitem [ref=e221]: Se a resposta for insatisfatória, solicite revisão ou escalonamento.
- separator [ref=e222]
- paragraph [ref=e223]:
- text: ⚙️
- strong [ref=e224]: Posso ajudar a solicitar algum desses documentos
- text: (histórico de contracheques, informe de rendimentos, ficha financeira) ou a abrir um protocolo de auditoria. Basta informar os dados solicitados (CPF, matrícula, email, etc.).
- contentinfo [ref=e122]:
- generic [ref=e123]:
- button "📄 Segunda Via de Contracheque" [ref=e225] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e226] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e227] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e228] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e229] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e230] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e231] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e232] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e233] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [ref=e234] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e235] [cursor=pointer]
- button "📄 Segunda Via de Contracheque" [ref=e236] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e237] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e238] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e239] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e240] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e241] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e242] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e243] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e244] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [ref=e245] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e246] [cursor=pointer]
- generic [ref=e124]:
- generic [ref=e125]:
- button "Agent" [ref=e126] [cursor=pointer]
- button "Chat" [ref=e127] [cursor=pointer]
- textbox "Message... (type @ to mention)" [ref=e128]
- button "↑" [ref=e129] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"

View file

@ -1,111 +0,0 @@
- generic [ref=e2]:
- complementary [ref=e3]:
- generic "Home" [ref=e4] [cursor=pointer]:
- img [ref=e5]
- generic "Search" [ref=e8] [cursor=pointer]:
- img [ref=e9]
- generic "Terminal" [ref=e12] [cursor=pointer]:
- img [ref=e13]
- generic "User" [ref=e15] [cursor=pointer]:
- img [ref=e16]
- generic "Apps" [ref=e19] [cursor=pointer]:
- img [ref=e20]
- generic "Settings" [ref=e25] [cursor=pointer]:
- img [ref=e26]
- generic [ref=e29]:
- generic [ref=e30]:
- generic [ref=e31]:
- generic [ref=e32] [cursor=pointer]:
- img [ref=e34]
- generic [ref=e36]: Vibe
- generic [ref=e37] [cursor=pointer]:
- img [ref=e39]
- generic [ref=e44]: CRM
- generic [ref=e45] [cursor=pointer]:
- img [ref=e47]
- generic [ref=e49]: Campaigns
- generic [ref=e50] [cursor=pointer]:
- img [ref=e52]
- generic [ref=e53]: Lists
- generic [ref=e54] [cursor=pointer]:
- img [ref=e56]
- generic [ref=e58]: Templates
- generic [ref=e59] [cursor=pointer]:
- img [ref=e61]
- generic [ref=e64]: Tasks
- generic [ref=e65] [cursor=pointer]:
- img [ref=e67]
- generic [ref=e69]: Chat
- generic [ref=e70] [cursor=pointer]:
- img [ref=e72]
- generic [ref=e74]: Terminal
- generic [ref=e75] [cursor=pointer]:
- img [ref=e77]
- generic [ref=e79]: Explorer
- generic [ref=e80] [cursor=pointer]:
- img [ref=e82]
- generic [ref=e85]: Editor
- generic [ref=e86] [cursor=pointer]:
- img [ref=e88]
- generic [ref=e93]: Designer
- generic [ref=e94] [cursor=pointer]:
- img [ref=e96]
- generic [ref=e99]: BASIC
- generic [ref=e100] [cursor=pointer]:
- img [ref=e102]
- generic [ref=e105]: Browser
- generic [ref=e106]:
- generic [ref=e107]:
- generic [ref=e108]: Chat
- generic [ref=e109]:
- button [ref=e110] [cursor=pointer]:
- img [ref=e111]
- button [ref=e112] [cursor=pointer]:
- img [ref=e113]
- button [ref=e115] [cursor=pointer]:
- img [ref=e116]
- generic [ref=e119]:
- generic [ref=e120]:
- generic:
- generic: Connecting...
- main [ref=e121]
- contentinfo [ref=e122]:
- generic [ref=e124]:
- generic [ref=e125]:
- button "Agent" [ref=e126] [cursor=pointer]
- button "Chat" [ref=e127] [cursor=pointer]
- textbox "Message... (type @ to mention)" [active] [ref=e128]
- button "↑" [ref=e129] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"
- contentinfo [ref=e130]:
- img [ref=e134] [cursor=pointer]
- generic [ref=e136]:
- combobox [ref=e138] [cursor=pointer]:
- option "🎨 Default"
- option "☀️ Light" [selected]
- option "🍊 Orange"
- option "🌃 Cyberpunk"
- option "🌴 Retrowave"
- option "💭 Vapor Dream"
- option "✨ Y2K"
- option "🔲 3D Bevel"
- option "🕹️ Arcade"
- option "🪩 Disco"
- option "🎸 Grunge"
- option "🎺 Jazz"
- option "🌻 Mellow"
- option "🏠 Mid Century"
- option "📷 Polaroid"
- option "📺 Cartoons"
- option "🏖️ Seaside"
- option "⌨️ Typewriter"
- option "📠 Xerox"
- option "📁 XTree"
- button "Sign In" [ref=e139] [cursor=pointer]
- generic [ref=e140]:
- generic [ref=e141]: 00:00
- generic [ref=e142]: 01/01/2026

View file

@ -1,61 +0,0 @@
- generic [ref=e106]:
- generic [ref=e107]:
- generic [ref=e108]: Chat
- generic [ref=e109]:
- button [ref=e110] [cursor=pointer]:
- img [ref=e111]
- button [ref=e112] [cursor=pointer]:
- img [ref=e113]
- button [ref=e115] [cursor=pointer]:
- img [ref=e116]
- generic [ref=e119]:
- generic [ref=e120]:
- main [ref=e121]:
- paragraph [ref=e145]: Olá! Sou o Assistente Virtual da SEAD — Secretaria de Estado da Administração de Sergipe. Estou aqui para ajudá-lo com contracheques, agendamentos no CEAC, perícias médicas, documentos funcionais, cursos da Escola de Governo e muito mais. Como posso te ajudar hoje?
- generic [ref=e180]: 🔍 Detectar Desvios na Folha
- contentinfo [ref=e122]:
- generic [ref=e123]:
- button "📄 Segunda Via de Contracheque" [ref=e146] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e147] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e148] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e149] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e150] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e151] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e152] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e153] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e154] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [active] [ref=e155] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e156] [cursor=pointer]
- button "📄 Segunda Via de Contracheque" [ref=e157] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e158] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e159] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e160] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e161] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e162] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e163] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e164] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e165] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [ref=e166] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e167] [cursor=pointer]
- button "📄 Segunda Via de Contracheque" [ref=e168] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e169] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e170] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e171] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e172] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e173] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e174] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e175] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e176] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [ref=e177] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e178] [cursor=pointer]
- generic [ref=e124]:
- generic [ref=e125]:
- button "Agent" [ref=e126] [cursor=pointer]
- button "Chat" [ref=e127] [cursor=pointer]
- textbox "Message... (type @ to mention)" [ref=e128]
- button "↑" [ref=e129] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"

View file

@ -1,82 +0,0 @@
- generic [ref=e106]:
- generic [ref=e107]:
- generic [ref=e108]: Chat
- generic [ref=e109]:
- button [ref=e110] [cursor=pointer]:
- img [ref=e111]
- button [ref=e112] [cursor=pointer]:
- img [ref=e113]
- button [ref=e115] [cursor=pointer]:
- img [ref=e116]
- generic [ref=e119]:
- generic [ref=e120]:
- main [ref=e121]:
- paragraph [ref=e145]: Olá! Sou o Assistente Virtual da SEAD — Secretaria de Estado da Administração de Sergipe. Estou aqui para ajudá-lo com contracheques, agendamentos no CEAC, perícias médicas, documentos funcionais, cursos da Escola de Governo e muito mais. Como posso te ajudar hoje?
- generic [ref=e180]: 🔍 Detectar Desvios na Folha
- generic [ref=e182]:
- paragraph [ref=e183]:
- text: 🔎
- strong [ref=e184]: Vamos analisar a sua folha de pagamento para identificar possíveis desvios.
- text: Para isso preciso que você me informe os dados cadastrais do servidor (mesmo que já os tenha usado antes). Assim consigo solicitar o histórico de contracheques e comparálos.
- blockquote [ref=e185]:
- paragraph [ref=e186]:
- strong [ref=e187]: Dados necessários
- list [ref=e188]:
- listitem [ref=e189]: CPF (com ou sem formatação)
- listitem [ref=e190]: Matrícula funcional
- listitem [ref=e191]: Nome completo do servidor
- listitem [ref=e192]: "Órgão de lotação (ex.: SEAD, SEED, SES, SSP)"
- listitem [ref=e193]: Email (para envio do documento)
- listitem [ref=e194]: Telefone com DDD
- paragraph [ref=e195]:
- text: ⚠️
- strong [ref=e196]: Confirme
- text: que está de acordo em fornecer essas informações e eu solicito o documento
- code [ref=e197]: CONTRACHEQUE_HISTORICO
- text: . Depois analisaremos juntos as variações encontradas.
- contentinfo [ref=e122]:
- generic [ref=e123]:
- button "📄 Segunda Via de Contracheque" [ref=e198] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e199] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e200] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e201] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e202] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e203] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e204] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e205] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e206] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [ref=e207] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e208] [cursor=pointer]
- button "📄 Segunda Via de Contracheque" [ref=e209] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e210] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e211] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e212] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e213] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e214] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e215] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e216] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e217] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [ref=e218] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e219] [cursor=pointer]
- button "📄 Segunda Via de Contracheque" [ref=e220] [cursor=pointer]
- button "📅 Agendar Atendimento no CEAC" [ref=e221] [cursor=pointer]
- button "🩺 Agendar Perícia Médica" [ref=e222] [cursor=pointer]
- button "📋 Solicitar Documentos Funcionais" [ref=e223] [cursor=pointer]
- button "✏️ Atualizar Dados Cadastrais" [ref=e224] [cursor=pointer]
- button "🎓 Cursos da Escola de Governo" [ref=e225] [cursor=pointer]
- button "💰 Informações sobre Benefícios" [ref=e226] [cursor=pointer]
- button "🔍 Consultar Protocolo" [ref=e227] [cursor=pointer]
- button "📞 Falar com a SEAD" [ref=e228] [cursor=pointer]
- button "🔍 Detectar Desvios na Folha" [ref=e229] [cursor=pointer]
- button "❓ Outras Solicitações" [ref=e230] [cursor=pointer]
- generic [ref=e124]:
- generic [ref=e125]:
- button "Agent" [ref=e126] [cursor=pointer]
- button "Chat" [ref=e127] [cursor=pointer]
- textbox "Message... (type @ to mention)" [ref=e128]
- button "↑" [ref=e129] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"

View file

@ -1,27 +0,0 @@
- generic [ref=e5]:
- generic [ref=e6]:
- generic [ref=e7]: Chat
- generic [ref=e8]:
- button [ref=e9] [cursor=pointer]:
- img [ref=e10]
- button [ref=e11] [cursor=pointer]:
- img [ref=e12]
- button [ref=e14] [cursor=pointer]:
- img [ref=e15]
- generic [ref=e18]:
- generic [ref=e19]:
- generic:
- generic: Connecting...
- main [ref=e20]
- contentinfo [ref=e21]:
- generic [ref=e23]:
- generic [ref=e24]:
- button "Agent" [ref=e25] [cursor=pointer]
- button "Chat" [ref=e26] [cursor=pointer]
- textbox "Message... (type @ to mention)" [active] [ref=e27]
- button "↑" [ref=e28] [cursor=pointer]
- button "Scroll to bottom":
- img
- generic:
- generic:
- button "View"

View file

@ -1,147 +0,0 @@
- generic [ref=e2]:
- complementary [ref=e3]:
- generic "Home" [ref=e4] [cursor=pointer]:
- img [ref=e5]
- generic "Search" [ref=e8] [cursor=pointer]:
- img [ref=e9]
- generic "Terminal" [ref=e12] [cursor=pointer]:
- img [ref=e13]
- generic "User" [ref=e15] [cursor=pointer]:
- img [ref=e16]
- generic "Apps" [ref=e19] [cursor=pointer]:
- img [ref=e20]
- generic "Settings" [ref=e25] [cursor=pointer]:
- img [ref=e26]
- generic [ref=e29]:
- generic [ref=e30]:
- generic [ref=e31]:
- generic [ref=e32] [cursor=pointer]:
- img [ref=e34]
- generic [ref=e36]: Vibe
- generic [ref=e37] [cursor=pointer]:
- img [ref=e39]
- generic [ref=e44]: CRM
- generic [ref=e45] [cursor=pointer]:
- img [ref=e47]
- generic [ref=e49]: Campaigns
- generic [ref=e50] [cursor=pointer]:
- img [ref=e52]
- generic [ref=e53]: Lists
- generic [ref=e54] [cursor=pointer]:
- img [ref=e56]
- generic [ref=e58]: Templates
- generic [ref=e59] [cursor=pointer]:
- img [ref=e61]
- generic [ref=e64]: Tasks
- generic [ref=e65] [cursor=pointer]:
- img [ref=e67]
- generic [ref=e69]: Chat
- generic [ref=e70] [cursor=pointer]:
- img [ref=e72]
- generic [ref=e74]: Terminal
- generic [ref=e75] [cursor=pointer]:
- img [ref=e77]
- generic [ref=e79]: Explorer
- generic [ref=e80] [cursor=pointer]:
- img [ref=e82]
- generic [ref=e85]: Editor
- generic [ref=e86] [cursor=pointer]:
- img [ref=e88]
- generic [ref=e93]: Designer
- generic [ref=e94] [cursor=pointer]:
- img [ref=e96]
- generic [ref=e99]: BASIC
- generic [ref=e100] [cursor=pointer]:
- img [ref=e102]
- generic [ref=e105]: Browser
- generic [ref=e106]:
- generic [ref=e107]:
- generic [ref=e108]: Chat
- generic [ref=e109]:
- button [ref=e110] [cursor=pointer]:
- img [ref=e111]
- button [ref=e112] [cursor=pointer]:
- img [ref=e113]
- button [ref=e115] [cursor=pointer]:
- img [ref=e116]
- generic [ref=e119]:
- generic [ref=e120]:
- complementary [ref=e121]:
- button "Chat" [ref=e122]:
- img [ref=e123]
- button "Tasks" [ref=e125]:
- img [ref=e126]
- button "Terminal" [ref=e129]:
- img [ref=e130]
- button "Explorer" [ref=e132]:
- img [ref=e133]
- button "Editor" [ref=e135]:
- img [ref=e136]
- button "Browser" [ref=e139]:
- img [ref=e140]
- main
- generic [ref=e143]:
- generic [ref=e144]:
- text: // BROWSER
- textbox "No preview active" [ref=e145]
- generic [ref=e147]: Waiting for app preview...
- generic [ref=e149]: // TERMINAL
- generic [ref=e150]:
- generic [ref=e151]: "Agent #1"
- text: EVOLVED
- generic [ref=e152]: Claude Opus 4.5 — 99%
- generic [ref=e153]:
- generic [ref=e154]:
- text: Plan
- button [ref=e155]
- generic [ref=e156]:
- text: YOLO
- button [ref=e157]
- generic [ref=e158]:
- generic [ref=e159]:
- button "◄" [ref=e160]
- text: 0 / 0
- button "►" [ref=e161]
- generic [ref=e162]:
- button "💬" [ref=e163]
- button "✏️" [ref=e164]
- button "</>" [ref=e165]
- contentinfo [ref=e166]:
- generic [ref=e168]: Reference Entity
- generic [ref=e169]:
- generic [ref=e170]:
- button "Agent" [ref=e171]
- button "Chat" [ref=e172]
- textbox "Message... (type @ to mention)" [active] [ref=e173]
- button "↑" [ref=e174]
- button "Scroll to bottom" [ref=e175]:
- img [ref=e176]
- button "View" [ref=e180]
- contentinfo [ref=e181]:
- img [ref=e185] [cursor=pointer]
- generic [ref=e187]:
- combobox [ref=e189] [cursor=pointer]:
- option "🎨 Default"
- option "☀️ Light"
- option "🍊 Orange"
- option "🌃 Cyberpunk"
- option "🌴 Retrowave"
- option "💭 Vapor Dream"
- option "✨ Y2K"
- option "🔲 3D Bevel"
- option "🕹️ Arcade"
- option "🪩 Disco"
- option "🎸 Grunge"
- option "🎺 Jazz"
- option "🌻 Mellow"
- option "🏠 Mid Century"
- option "📷 Polaroid"
- option "📺 Cartoons"
- option "🏖️ Seaside"
- option "⌨️ Typewriter" [selected]
- option "📠 Xerox"
- option "📁 XTree"
- button "Sign In" [ref=e190] [cursor=pointer]
- generic [ref=e191]:
- generic [ref=e192]: 00:00
- generic [ref=e193]: 01/01/2026

View file

@ -1,16 +0,0 @@
{
"found": true,
"tag": "DIV",
"className": "suggestions-container",
"innerHTML": "",
"childCount": 0,
"display": "flex",
"visibility": "visible",
"opacity": "1",
"height": "4px",
"maxHeight": "100px",
"overflow": "auto",
"hasClass": false,
"parent": "FOOTER ",
"styleAttr": null
}

View file

@ -1,64 +0,0 @@
{
"rules": [
{
"sheet": "https://chat.pragmatismo.com.br/suite/css/app.css",
"selector": "*",
"display": "",
"maxHeight": "",
"overflow": "",
"opacity": "",
"visibility": "",
"height": "",
"padding": "0px",
"margin": "0px"
},
{
"sheet": "https://chat.pragmatismo.com.br/suite/css/app.css",
"selector": "*",
"display": "",
"maxHeight": "",
"overflow": "",
"opacity": "",
"visibility": "",
"height": "",
"padding": "",
"margin": ""
},
{
"sheet": "https://chat.pragmatismo.com.br/suite/css/base.css",
"selector": "*",
"display": "",
"maxHeight": "",
"overflow": "",
"opacity": "",
"visibility": "",
"height": "",
"padding": "0px",
"margin": "0px"
},
{
"sheet": "inline",
"selector": "*",
"display": "",
"maxHeight": "",
"overflow": "",
"opacity": "",
"visibility": "",
"height": "",
"padding": "0px",
"margin": "0px"
},
{
"sheet": "https://chat.pragmatismo.com.br/suite/chat/chat.css?v=3",
"selector": ".suggestions-container",
"display": "flex",
"maxHeight": "100px",
"overflow": "",
"opacity": "",
"visibility": "",
"height": "",
"padding": "",
"margin": ""
}
]
}

View file

@ -1,112 +0,0 @@
[
{
"tag": "DIV",
"className": "suggestions-container has-bot-suggestions",
"id": "suggestions",
"text": "Agendar BatizadoAgendar CasamentoAgendar MissaAgendar PeregrinaçãoPedido de OraçãoUso de ImagemLicen",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "FOOTER."
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Agendar Batizado",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Agendar Casamento",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Agendar Missa",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Agendar Peregrinação",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Pedido de Oração",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Uso de Imagem",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Licenciamento",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Evento/Iluminação",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Cadastrar Guia",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
},
{
"tag": "BUTTON",
"className": "suggestion-chip",
"id": "",
"text": "Fazer Doação",
"display": "flex",
"visibility": "visible",
"hidden": false,
"parent": "DIV.suggestions-container has-bot-suggestions"
}
]

View file

@ -1,7 +0,0 @@
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_REGION=us-east-1
S3_BUCKET=prod-gbo-backup
INCUS_PROJECT=PROD-GBO1
CONTAINER_NAME=
KEEP_COUNT=10

1818
backup-to-s3/Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,15 +0,0 @@
[package]
name = "backup-to-s3"
version = "0.1.0"
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["full"] }
rusoto_s3 = "0.48"
rusoto_core = "0.48"
rusoto_credential = "0.48"
dotenv = "0.15"
chrono = "0.4"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing-appender = "0.2"

View file

@ -1,213 +0,0 @@
use chrono::Utc;
use rusoto_core::Region;
use rusoto_credential::StaticProvider;
use rusoto_s3::{S3, S3Client};
use std::env;
use tracing::{error, info, warn};
#[derive(Debug)]
struct Config {
access_key: String,
secret_key: String,
bucket: String,
project: String,
keep_count: usize,
region: Region,
}
impl Config {
fn from_env() -> Result<Self, String> {
dotenv::from_path(".env").ok();
let access_key = env::var("AWS_ACCESS_KEY_ID").map_err(|_| "AWS_ACCESS_KEY_ID not set")?;
let secret_key = env::var("AWS_SECRET_ACCESS_KEY").map_err(|_| "AWS_SECRET_ACCESS_KEY not set")?;
let bucket = env::var("S3_BUCKET").map_err(|_| "S3_BUCKET not set")?;
let project = env::var("INCUS_PROJECT").unwrap_or_else(|_| "PROD-GBO1".to_string());
let keep_count: usize = env::var("KEEP_COUNT").unwrap_or_else(|_| "10".to_string()).parse().unwrap_or(10);
let region_name = env::var("AWS_REGION").unwrap_or_else(|_| "us-east-1".to_string());
let region = region_name.parse().unwrap_or(Region::UsEast1);
Ok(Config {
access_key,
secret_key,
bucket,
project,
keep_count,
region,
})
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt()
.with_env_filter("info")
.init();
let config = Config::from_env()?;
info!("Starting backup to S3 bucket: {}", config.bucket);
let credential_provider = StaticProvider::new_minimal(
config.access_key.clone(),
config.secret_key.clone(),
);
let s3_client = S3Client::new_with(
rusoto_core::HttpClient::new().map_err(|e| format!("HTTP client: {}", e))?,
credential_provider,
config.region.clone(),
);
let timestamp = Utc::now().format("%Y-%m-%d").to_string();
let container_name = env::var("CONTAINER_NAME").unwrap_or_default();
let containers = if container_name.is_empty() {
list_inc_containers(&config.project).await?
} else {
vec![container_name]
};
for container in containers {
info!("Backing up container: {}", container);
match backup_container(&container, &config, &s3_client, &timestamp).await {
Ok(_) => info!("Successfully backed up {}", container),
Err(e) => {
error!("Failed to backup {}: {}", container, e);
continue;
}
}
}
cleanup_old_backups(&config, &s3_client).await?;
info!("Backup completed!");
Ok(())
}
async fn list_inc_containers(project: &str) -> Result<Vec<String>, String> {
let output = tokio::process::Command::new("incus")
.args(["list", "--project", project, "--format", "csv", "-c", "n"])
.output()
.await
.map_err(|e| format!("Failed to list containers: {}", e))?;
if !output.status.success() {
return Err("incus list failed".to_string());
}
let stdout = String::from_utf8_lossy(&output.stdout);
let containers: Vec<String> = stdout.lines()
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect();
Ok(containers)
}
async fn backup_container(
container: &str,
config: &Config,
s3_client: &S3Client,
timestamp: &str,
) -> Result<(), String> {
let temp_dir = std::env::temp_dir();
let backup_file = temp_dir.join(format!("{}.tar.gz", container));
info!("Exporting {} to {:?}", container, backup_file);
let export_output = tokio::process::Command::new("incus")
.args([
"export",
container,
backup_file.to_str().unwrap(),
"--instance-only",
"--project",
&config.project,
])
.output()
.await
.map_err(|e| format!("Failed to export container: {}", e))?;
if !export_output.status.success() {
let stderr = String::from_utf8_lossy(&export_output.stderr);
return Err(format!("incus export failed: {}", stderr));
}
let s3_key = format!("{}/{}.tar.gz", timestamp, container);
info!("Uploading to s3://{}/{}", config.bucket, s3_key);
let file_data = tokio::fs::read(&backup_file)
.await
.map_err(|e| format!("Failed to read backup file: {}", e))?;
let put_request = rusoto_s3::PutObjectRequest {
body: Some(file_data.into()),
bucket: config.bucket.clone(),
key: s3_key,
..Default::default()
};
s3_client.put_object(put_request)
.await
.map_err(|e| format!("Failed to upload to S3: {}", e))?;
tokio::fs::remove_file(&backup_file)
.await
.map_err(|e| warn!("Failed to delete temp file: {}", e)).ok();
info!("Uploaded {}", container);
Ok(())
}
async fn cleanup_old_backups(config: &Config, s3_client: &S3Client) -> Result<(), String> {
info!("Cleaning up old backups, keeping {} most recent", config.keep_count);
let list_output = s3_client
.list_objects_v2(rusoto_s3::ListObjectsV2Request {
bucket: config.bucket.clone(),
delimiter: Some("/".to_string()),
..Default::default()
})
.await
.map_err(|e| format!("Failed to list S3: {}", e))?;
let mut prefixes: Vec<String> = list_output
.common_prefixes
.unwrap_or_default()
.iter()
.map(|p| p.prefix.clone().unwrap_or_default().trim_end_matches('/').to_string())
.filter(|p| !p.is_empty())
.collect();
prefixes.sort_by(|a, b| b.cmp(a));
if prefixes.len() > config.keep_count {
for prefix in prefixes.iter().skip(config.keep_count) {
info!("Deleting old backup: {}", prefix);
let objects = s3_client
.list_objects_v2(rusoto_s3::ListObjectsV2Request {
bucket: config.bucket.clone(),
prefix: Some(format!("{}/", prefix)),
..Default::default()
})
.await
.map_err(|e| format!("Failed to list objects: {}", e))?;
for obj in objects.contents.unwrap_or_default() {
if let Some(key) = obj.key {
s3_client
.delete_object(rusoto_s3::DeleteObjectRequest {
bucket: config.bucket.clone(),
key,
..Default::default()
})
.await
.ok();
}
}
}
}
Ok(())
}

@ -1 +1 @@
Subproject commit f097f000d8d53ca3b5caa089a3082960ffbb833f Subproject commit 8019107ebf1e5dd2d3201b96f95e67ed4009361a

View file

@ -1,5 +0,0 @@
@echo off
:loop
ping google.com
timeout /t 18000 /nobreak >nul
goto loop