rivale 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +121 -0
  3. package/dist/cli.js +519 -0
  4. package/package.json +53 -0
package/dist/cli.js ADDED
@@ -0,0 +1,519 @@
1
+ #!/usr/bin/env node
2
+ import jp from"node:readline";function F(r="id"){let e=crypto.randomUUID?crypto.randomUUID():Math.random().toString(36).slice(2);return`${r}_${e}`}var Tr=/<[^>]*?invoke\s+name="([^"]+)"[^>]*?>([\s\S]*?)<\/[^>]*?invoke[^>]*?>/gi,Mo=/<[^>]*?parameter\s+name="([^"]+)"([^>]*?)>([\s\S]*?)<\/[^>]*?parameter[^>]*?>/gi;function gi(r){return typeof r=="string"&&/invoke\s+name="/i.test(r)&&/parameter\s+name="/i.test(r)}function ke(r,e){if(!gi(r))return{toolCalls:[],cleanedContent:r};let t=[],o;for(Tr.lastIndex=0;(o=Tr.exec(r))!==null;){let n=o[1],a=o[2]||"",s=bi(n,e);if(!s)continue;let i={};Mo.lastIndex=0;let c;for(;(c=Mo.exec(a))!==null;){let l=c[1],u=c[2]||"";i[l]=yi(c[3],u)}t.push({id:F("toolcall"),name:s,arguments:i})}return{toolCalls:t,cleanedContent:vi(r)}}function yi(r,e){let t=String(r??"").trim();if(/string\s*=\s*"true"/i.test(e))return t;try{return JSON.parse(t)}catch{return t}}function bi(r,e){if(!e?.tools)return r||null;if(e.tools.has(r))return r;let t=Po(r);for(let o of e.tools.keys())if(Po(o)===t)return o;return null}function Po(r){return String(r||"").toLowerCase().replace(/[^a-z0-9]/g,"")}function vi(r){return String(r).replace(Tr,"").replace(/<\/?[^>]*?tool_?calls[^>]*?>/gi,"").replace(/[||]+\s*DSML\s*[||]+/gi,"").replace(/\n{3,}/g,`
3
+
4
+ `).trim()}var Er=class extends Error{constructor(e="Operation timed out"){super(e),this.name="TimeoutError"}},$e=class extends Error{constructor(e="Operacao cancelada"){super(e),this.name="AbortError"}};async function Ue(r,e,t,o){if(o?.aborted)throw new $e("Operacao cancelada pelo usuario");let n=new AbortController,a,s,i=new Promise((c,l)=>{e&&e>0&&(a=setTimeout(()=>{l(new Er(t||`Operation exceeded ${e}ms`)),n.abort()},e)),o&&(s=()=>{l(new $e("Operacao cancelada pelo usuario")),n.abort()},o.addEventListener("abort",s,{once:!0}))});try{return await Promise.race([r(n.signal),i])}finally{clearTimeout(a),o&&s&&o.removeEventListener("abort",s)}}function wi(r){if(r?.aborted)throw new $e("Operacao cancelada pelo usuario")}var ct=class{constructor({config:e,llmManager:t,toolRegistry:o,toolRunner:n,eventBus:a,logger:s}={}){this.config=e,this.llmManager=t,this.toolRegistry=o,this.toolRunner=n,this.eventBus=a,this.logger=s}async run({messages:e,state:t,conversationId:o,userMessage:n="",stream:a=!1,onToken:s,approvalHandler:i,signal:c,humanPrompt:l}){let u=!!(this.config.coordinator?.enabled&&this.config.multiAgent?.enabled),m=u?this.config.coordinator.allowedTools:null;this.toolRegistry.resetActivations?.();let f=!!(u&&this.config.coordinator?.enforceDelegation&&Ti(n)),g=!1;for(let y=0;y<this.config.agent.maxToolIterations;y+=1){let b=this.checkBudget(t);if(b.exceeded){await this.eventBus?.emit("agent:budget_exceeded",{runId:t.runId,reason:b.reason,costUsd:t.costUsd,totalTokens:t.inputTokens+t.outputTokens});let A=`
5
+
6
+ \u26A0\uFE0F Run interrompida: ${b.reason}. (Ajuste AGENT_MAX_USD_PER_RUN / AGENT_MAX_TOKENS_PER_RUN ou 0 p/ ilimitado.)`,M=[...e].reverse().find(P=>P.role==="assistant"&&P.content);return{content:M?.content?`${M.content}${A}`:A.trim(),messages:e,stopReason:"budget"}}t.addStep({type:"llm",iteration:y}),wi(c);let E=this.toolRegistry.toLLMTools({allowedNames:m}),k=await this.callLLM({messages:e,tools:E,state:t,iteration:y,stream:a&&(!f||g),onToken:s,signal:c});if(t.recordLLM(k),k.toolCalls=_i(k.toolCalls||[],this.toolRegistry),!k.toolCalls.length){let A=ke(k.content,this.toolRegistry);k.content=A.cleanedContent,A.toolCalls.length&&(k.toolCalls=A.toolCalls)}if(!k.toolCalls?.length&&f&&!g){let A=Si(n);await this.eventBus?.emit("coordinator:auto_delegate",{toolCall:A,reason:"technical_work_without_delegation"}),e.push({role:"system",content:["Resposta direta bloqueada pelo Coordinator Mode.","Esta e uma tarefa tecnica de codigo/refatoracao/criacao/teste.","O Supervisor deve delegar para subagente e nao escrever codigo ou tentar executar sozinho."].join(`
7
+ `)}),e.push({role:"assistant",content:"Delegando a tarefa tecnica para um subagente especializado.",toolCalls:[A]});let M=await this.executeToolCalls([A],{state:t,conversationId:o,approvalHandler:i,stream:a,onToken:s,messages:e,allowedToolNames:m,signal:c,humanPrompt:l});g=g||M.some(No);for(let P of M)t.recordTool(P),e.push(Io(P));continue}let R={role:"assistant",content:k.content||"",toolCalls:k.toolCalls||[],reasoningContent:k.reasoningContent};if(e.push(R),!k.toolCalls?.length)return{content:k.content||"",messages:e};let h=await this.executeToolCalls(k.toolCalls,{state:t,conversationId:o,approvalHandler:i,stream:a,onToken:s,messages:e,allowedToolNames:m,signal:c,humanPrompt:l});g=g||h.some(No);for(let A of h)t.recordTool(A),e.push(Io(A))}e.push({role:"system",content:"O limite de iteracoes de ferramentas foi atingido. Gere a melhor resposta final possivel com os dados disponiveis."});let w=await this.callLLM({messages:e,tools:[],state:t,iteration:"final",stream:a,onToken:s,signal:c,metadata:{final:!0}});return t.recordLLM(w),{content:ke(w.content||"",this.toolRegistry).cleanedContent,messages:e}}checkBudget(e){let t=Number(this.config.agent?.maxUsdPerRun)||0,o=Number(this.config.agent?.maxTokensPerRun)||0;if(t>0&&e.costUsd>=t)return{exceeded:!0,reason:`teto de custo atingido ($${e.costUsd.toFixed(4)} / $${t.toFixed(2)})`};let n=e.inputTokens+e.outputTokens;return o>0&&n>=o?{exceeded:!0,reason:`teto de tokens atingido (${n} / ${o})`}:{exceeded:!1}}async callLLM({messages:e,tools:t,state:o,iteration:n,stream:a,onToken:s,metadata:i={},signal:c}){let l={messages:e,tools:t,signal:c,metadata:{runId:o.runId,iteration:n,...i}};if(a){let u=await this.llmManager.stream({...l,onToken:s});if(Ei(u))return u;this.logger?.warn("empty streamed response, retrying without streaming",{runId:o.runId,iteration:n}),o.recordStreamFallback();let m=await this.llmManager.generate({...l,metadata:{...l.metadata,streamFallback:!0}});return m.content&&await s?.(m.content),m}return this.llmManager.generate(l)}isConcurrencySafeCall(e){let t=this.toolRegistry?.get?.(e.name);if(!t)return!1;let o=t.isConcurrencySafe;if(typeof o=="function")try{return!!o.call(t,e.arguments||{})}catch{return!1}return o===!0}planToolBatches(e,{maxRead:t,maxWrite:o}){let n=[];for(let a of e){let s=this.isConcurrencySafeCall(a),i=s?t:o,c=n[n.length-1];c&&c.safe===s&&c.items.length<i?c.items.push(a):n.push({safe:s,items:[a]})}return n}async executeToolCalls(e,t){let o=Math.max(1,this.config.agent.maxParallelToolCalls),n=Math.max(o,Number(this.config.agent?.maxParallelReads)||1),a=[],s=Array.isArray(t.allowedToolNames)&&t.allowedToolNames.length>0?new Set(t.allowedToolNames):null,i=c=>s&&!s.has(c.name)?{toolCallId:c.id,name:c.name,ok:!1,durationMs:0,error:{name:"CoordinatorToolPermissionError",message:`Supervisor nao pode usar ${c.name}. Delegue para um subagente apropriado.`}}:this.toolRunner.execute(c,{agentState:t.state,conversationId:t.conversationId,approvalHandler:t.approvalHandler,stream:t.stream,onToken:t.onToken,messages:t.messages,signal:t.signal,humanPrompt:t.humanPrompt});for(let c of this.planToolBatches(e,{maxRead:n,maxWrite:o}))(await Promise.allSettled(c.items.map(i))).forEach((u,m)=>{if(u.status==="fulfilled")a.push(u.value);else{let f=c.items[m];a.push({toolCallId:f.id,name:f.name,ok:!1,durationMs:0,error:{name:"ToolExecutionError",message:String(u.reason?.message||u.reason)}})}});return a}};function Io(r){return{role:"tool",toolCallId:r.toolCallId,name:r.name,content:JSON.stringify(r.ok?r.result:{error:r.error})}}function No(r){return r?.ok&&["invoke_subagent","invoke_parallel_subagents","start_swarm_debate"].includes(r.name)}function Si(r){let e=xi(r);return{id:`auto_delegate_${Date.now()}`,name:"invoke_subagent",arguments:{agent:e,task:["Execute a tarefa tecnica solicitada pelo usuario. Nao apenas explique.","Use ferramentas para ler, criar, editar ou validar arquivos conforme necessario.","Se houver caminho absoluto fora do TOOL_FILE_ROOT, explique a limitacao e use o caminho permitido quando possivel.","",`Pedido original do usuario:
8
+ ${r}`].join(`
9
+ `),context:"Delegacao automatica criada pelo Coordinator Mode porque o Supervisor nao deve implementar codigo diretamente.",expectedOutput:"Relatorio curto com arquivos criados/alterados, validacoes executadas e qualquer erro/limitacao."}}}function xi(r){let e=qo(r);return/(seguranca|security|vulnerab|permiss|auth|token|cript|crypto)/.test(e)?"security":/(test|teste|validar|verificar|playwright|browser|e2e)/.test(e)?"tester":/(review|revis|auditar|avaliar)/.test(e)?"reviewer":/(pesquis|documenta|docs|buscar|web|fonte)/.test(e)?"researcher":"coder"}function Ti(r){let e=qo(r);return/(\bcrie\b|\bcriar\b|\bcria\b|\bimplement|\brefator|refatur|\baltere\b|\baltera\b|\bedite\b|\bedita\b|\bcorrij|\bconsert|\bsalve\b|\bsalva\b|\bescreva\b|\bescreve\b|\badicion|\bremova\b|\bremove\b|\bdelete\b|\bapague\b|\bapaga\b|\bgere\b|\bgera\b|\bgerar\b|\bconstr|\bdesenvolv|\bteste\b|\btesta\b|\btestar\b|\bimplemente\b|\bimplementar\b|\brode\b|\brodar\b|\bexecut|\bdebug|\bscraper\b)/.test(e)}function qo(r){return String(r||"").normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase()}function Ei(r){return!!r?.content?.trim()||!!r?.toolCalls?.length}function _i(r,e){return r.map(t=>{if(!t?.name||e.get(t.name))return t;let o=String(t.name).match(/^([a-zA-Z0-9_-]+)(\{.*\})$/);if(!o)return t;let[,n,a]=o;return e.get(n)?{...t,name:n,arguments:{...ki(a,{}),...t.arguments||{}}}:t})}function ki(r,e){try{return JSON.parse(r)}catch{return e}}var lt=class{constructor({conversationId:e="default"}={}){this.runId=F("run"),this.conversationId=e,this.startedAt=performance.now(),this.llmCalls=0,this.toolCalls=0,this.streamFallbacks=0,this.inputTokens=0,this.outputTokens=0,this.cachedTokens=0,this.costUsd=0,this.toolResults=[],this.steps=[]}recordLLM(e){this.llmCalls+=1,this.inputTokens+=e.usage?.prompt_tokens||e.usage?.inputTokens||0,this.outputTokens+=e.usage?.completion_tokens||e.usage?.outputTokens||0,this.cachedTokens+=e.usage?.cachedTokens||0,this.costUsd+=e.costUsd||0}recordTool(e){this.toolCalls+=1,this.toolResults.push(e)}recordStreamFallback(){this.streamFallbacks+=1}addStep(e){this.steps.push({...e,at:new Date().toISOString()})}metrics(){return{runId:this.runId,conversationId:this.conversationId,durationMs:Math.round(performance.now()-this.startedAt),llmCalls:this.llmCalls,toolCalls:this.toolCalls,streamFallbacks:this.streamFallbacks,inputTokens:this.inputTokens,outputTokens:this.outputTokens,cachedTokens:this.cachedTokens,totalTokens:this.inputTokens+this.outputTokens,costUsd:this.costUsd}}};var jo=["pending","in_progress","completed","blocked","cancelled"],$i=["pending","in_progress","completed"];function Do({storage:r,eventBus:e}){return{name:"todo_write",description:"Atualiza a checklist visivel da sessao. Use para tarefas com 2+ passos e marque exatamente um item como in_progress quando estiver trabalhando.",risk:"internal",requiresApproval:!1,shouldDefer:!0,inputSchema:{type:"object",required:["todos"],additionalProperties:!1,properties:{todos:{type:"array",minItems:0,maxItems:20,items:{type:"object",required:["content","status"],additionalProperties:!1,properties:{id:{type:"string"},content:{type:"string",minLength:1,maxLength:400},status:{type:"string",enum:$i},owner:{type:"string",maxLength:80}}}}}},async execute(t,o={}){let n=o.conversationId||"default",a=new Date().toISOString(),s=Fe(r,n);r.run("DELETE FROM todos WHERE conversation_id = ?",[n]),t.todos.forEach((c,l)=>{r.run(`INSERT INTO todos
10
+ (id, conversation_id, content, status, owner, position, metadata_json, created_at, updated_at)
11
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[c.id||F("todo"),n,c.content,c.status,c.owner||null,l,"{}",a,a])});let i=Fe(r,n);return await e?.emit("todo:updated",{conversationId:n,previous:s,todos:i}),{previousCount:s.length,todos:i}}}}function Uo({storage:r,eventBus:e}){return{name:"task_create",description:"Cria uma tarefa persistente da sessao com status pending. Use para trabalhos longos, delegados ou rastreaveis.",risk:"internal",requiresApproval:!1,shouldDefer:!0,inputSchema:{type:"object",required:["subject"],additionalProperties:!1,properties:{subject:{type:"string",minLength:1,maxLength:120},description:{type:"string",maxLength:2e3},activeForm:{type:"string",maxLength:120},owner:{type:"string",maxLength:80},metadata:{type:"object"}}},async execute(t,o={}){let n=Ai(r,{conversationId:o.conversationId||"default",subject:t.subject,description:t.description||"",activeForm:t.activeForm||"",status:"pending",owner:t.owner||"",metadata:t.metadata||{}});return await e?.emit("task:created",n),{task:n}}}}function Fo({storage:r,eventBus:e}){return{name:"task_update",description:"Atualiza status/dados de uma tarefa persistente. Status: pending, in_progress, completed, blocked, cancelled.",risk:"internal",requiresApproval:!1,shouldDefer:!0,inputSchema:{type:"object",required:["taskId"],additionalProperties:!1,properties:{taskId:{type:"string",minLength:1},subject:{type:"string",maxLength:120},description:{type:"string",maxLength:2e3},activeForm:{type:"string",maxLength:120},status:{type:"string",enum:jo},owner:{type:"string",maxLength:80},metadata:{type:"object"}}},async execute(t){let o=_r(r,t.taskId);if(!o)throw new Error(`Task not found: ${t.taskId}`);let n={...o,subject:t.subject??o.subject,description:t.description??o.description,activeForm:t.activeForm??o.activeForm,status:t.status??o.status,owner:t.owner??o.owner,metadata:t.metadata?{...o.metadata,...t.metadata}:o.metadata};r.run(`UPDATE tasks
12
+ SET subject = ?, description = ?, active_form = ?, status = ?, owner = ?, metadata_json = ?, updated_at = ?
13
+ WHERE id = ?`,[n.subject,n.description,n.activeForm||null,n.status,n.owner||null,JSON.stringify(n.metadata||{}),new Date().toISOString(),n.id]);let a=_r(r,t.taskId);return await e?.emit("task:updated",{previous:o,task:a}),{task:a}}}}function Bo({storage:r}){return{name:"task_list",description:"Lista tarefas persistentes da conversa atual.",risk:"read",isReadOnly:!0,requiresApproval:!1,shouldDefer:!0,inputSchema:{type:"object",additionalProperties:!1,properties:{status:{type:"string",enum:jo},limit:{type:"integer",minimum:1,maximum:100}}},async execute(e,t={}){return{tasks:Ri(r,{conversationId:t.conversationId||"default",status:e.status,limit:e.limit||50}),todos:Fe(r,t.conversationId||"default")}}}}async function zo(r,e,t,o=[]){if(!r||!Array.isArray(o)||o.length===0)return null;let n=t||"default";if(Fe(r,n).length>0)return null;let s=new Date().toISOString();o.slice(0,20).forEach((c,l)=>{r.run(`INSERT INTO todos
14
+ (id, conversation_id, content, status, owner, position, metadata_json, created_at, updated_at)
15
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[F("todo"),n,String(c).slice(0,400),"pending","supervisor",l,"{}",s,s])});let i=Fe(r,n);return await e?.emit("todo:updated",{conversationId:n,previous:[],todos:i}),i}function Ai(r,{conversationId:e,subject:t,description:o,activeForm:n,status:a,owner:s,metadata:i}){let c=F("task"),l=new Date().toISOString();return r.run(`INSERT INTO tasks
16
+ (id, conversation_id, subject, description, active_form, status, owner, metadata_json, created_at, updated_at)
17
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[c,e,t,o,n||null,a,s||null,JSON.stringify(i||{}),l,l]),_r(r,c)}function _r(r,e){let t=r.query("SELECT * FROM tasks WHERE id = ? LIMIT 1",[e])[0];return t?Ho(t):null}function Ri(r,{conversationId:e,status:t,limit:o}){let n=[e],a="SELECT * FROM tasks WHERE conversation_id = ?";return t&&(a+=" AND status = ?",n.push(t)),a+=" ORDER BY updated_at DESC LIMIT ?",n.push(o),r.query(a,n).map(Ho)}function Fe(r,e){return r.query("SELECT * FROM todos WHERE conversation_id = ? ORDER BY position ASC",[e]).map(Ci)}function Ho(r){return{id:r.id,conversationId:r.conversation_id,subject:r.subject,description:r.description,activeForm:r.active_form,status:r.status,owner:r.owner,metadata:Go(r.metadata_json,{}),createdAt:r.created_at,updatedAt:r.updated_at}}function Ci(r){return{id:r.id,conversationId:r.conversation_id,content:r.content,status:r.status,owner:r.owner,position:r.position,metadata:Go(r.metadata_json,{}),createdAt:r.created_at,updatedAt:r.updated_at}}function Go(r,e){try{return JSON.parse(r)}catch{return e}}var ut=class{constructor({config:e,llmManager:t,toolRegistry:o,toolRunner:n,memoryManager:a,contextManager:s,planner:i,storage:c,checkpointManager:l,hookManager:u,eventBus:m,logger:f}={}){this.config=e,this.llmManager=t,this.memoryManager=a,this.contextManager=s,this.planner=i,this.storage=c,this.checkpointManager=l,this.hookManager=u,this.eventBus=m,this.logger=f,this.loop=new ct({config:e,llmManager:t,toolRegistry:o,toolRunner:n,eventBus:m,logger:f})}async run(e,{conversationId:t="default",stream:o=!1,onToken:n,approvalHandler:a,signal:s,humanPrompt:i}={}){let c=new lt({conversationId:t});this.checkpointManager?.startRun(t,c.runId),await this.eventBus?.emit("agent:start",{runId:c.runId,conversationId:t,message:e});try{let l=/^(1|true|yes|on)$/i.test(String(process.env.RIVALE_SKIP_PROMPT_HOOKS||"")),u=l?null:await this.hookManager?.runUserPromptSubmit?.({prompt:e,conversationId:t})?.catch(h=>(this.logger?.warn?.("UserPromptSubmit hook falhou",{error:h.message}),null));if(u?.blocked){let h=u.reason||"Pedido bloqueado por um hook UserPromptSubmit.";await this.eventBus?.emit("agent:prompt_blocked",{runId:c.runId,conversationId:t,hook:u.blockedBy,reason:h});let A={content:`\u26D4 ${h}`,plan:null,metrics:c.metrics(),blocked:!0};return await this.eventBus?.emit("agent:response",A),A}let m=u?.updatedInput?.prompt;typeof m=="string"&&m.trim()&&(e=m),this.memoryManager.addConversationMessage(t,{role:"user",content:e}),await this.memoryManager.maybeSaveFromUserMessage(e,{conversationId:t,runId:c.runId});let f=await this.planner.createPlan({message:e});f?.steps?.length&&await zo(this.storage,this.eventBus,t,f.steps).catch(h=>{this.logger?.warn("failed to seed todos from plan",{error:h.message})});let w=[...(await this.contextManager.buildContext({conversationId:t,userMessage:e,plan:f})).messages],y=(u?.additionalContext||[]).map(h=>String(h).trim()).filter(Boolean);y.length&&w.push({role:"system",content:`Contexto adicional (hook UserPromptSubmit):
18
+ ${y.join(`
19
+
20
+ `)}`});let b=h=>this.loop.run({messages:h,state:c,conversationId:t,userMessage:e,stream:o,onToken:n,approvalHandler:a,signal:s,humanPrompt:i}),E=await b(w),k=0;for(;!l&&E.stopReason!=="budget"&&k<2;){let h=await this.hookManager?.runStop?.({content:E.content,conversationId:t})?.catch(A=>(this.logger?.warn?.("Stop hook falhou",{error:A.message}),null));if(!h?.blocked)break;k+=1,await this.eventBus?.emit("agent:stop_continue",{runId:c.runId,reason:h.reason,attempt:k}),E=await b([...E.messages,{role:"user",content:`[verifica\xE7\xE3o autom\xE1tica] ${h.reason||"A tarefa ainda n\xE3o est\xE1 comprovadamente conclu\xEDda. Verifique (rode testes/build) e finalize."}`}])}this.memoryManager.addConversationMessage(t,{role:"assistant",content:E.content});let R={content:E.content,plan:f,metrics:c.metrics()};return await this.eventBus?.emit("agent:response",R),await this.maybeAutoCompact(t).catch(h=>{this.logger?.warn?.("auto-compact failed",{error:h.message})}),R}catch(l){throw await this.eventBus?.emit("agent:error",{runId:c.runId,conversationId:t,error:l.message}),this.logger?.error("agent run failed",{runId:c.runId,error:l.message}),l}}async maybeAutoCompact(e){let t=this.config?.memory||{};if(!t.autoCompact||!t.autoCompactTokenThreshold)return;let o=this.memoryManager.estimateShortTermTokens?.(e)||0;if(o<t.autoCompactTokenThreshold)return;await this.eventBus?.emit("memory:autocompact:start",{conversationId:e,tokens:o});let n=await this.memoryManager.compactConversation(e,{llmManager:this.llmManager});return await this.eventBus?.emit("memory:autocompact:done",{conversationId:e,...n}),n}};import{randomBytes as Wo,createCipheriv as Li,createDecipheriv as Oi}from"node:crypto";import{readFileSync as Vo,writeFileSync as Ko,existsSync as $r,mkdirSync as Mi,chmodSync as Xo}from"node:fs";import kr from"node:path";import Pi from"node:os";function dt(){let r=process.env.RIVALE_SECRETS_DIR||kr.join(Pi.homedir(),".rivale");return{DIR:r,KEY_FILE:kr.join(r,"secret.key"),STORE_FILE:kr.join(r,"secrets.json")}}function Yo(){let{DIR:r}=dt();$r(r)||Mi(r,{recursive:!0})}function Jo(){Yo();let{KEY_FILE:r}=dt();if($r(r)){let t=Vo(r,"utf8").trim(),o=Buffer.from(t,"base64");if(o.length===32)return o}let e=Wo(32);Ko(r,e.toString("base64"),"utf8");try{Xo(r,384)}catch{}return e}function Be(){let{STORE_FILE:r}=dt();try{if($r(r))return JSON.parse(Vo(r,"utf8"))}catch{}return{}}function Qo(r){Yo();let{STORE_FILE:e}=dt();Ko(e,`${JSON.stringify(r,null,2)}
21
+ `,"utf8");try{Xo(e,384)}catch{}}function Ii(r){let e=Jo(),t=Wo(12),o=Li("aes-256-gcm",e,t),n=Buffer.concat([o.update(String(r),"utf8"),o.final()]),a=o.getAuthTag();return Buffer.concat([t,a,n]).toString("base64")}function Ni(r){let e=Jo(),t=Buffer.from(r,"base64"),o=t.subarray(0,12),n=t.subarray(12,28),a=t.subarray(28),s=Oi("aes-256-gcm",e,o);return s.setAuthTag(n),Buffer.concat([s.update(a),s.final()]).toString("utf8")}function ze(r,e){let t=Be();t[r]=Ii(e),Qo(t)}function mt(r){let e=Be();if(!e[r])return null;try{return Ni(e[r])}catch{return null}}function Zo(r){let e=Be();return r in e?(delete e[r],Qo(e),!0):!1}function en(){return Object.keys(Be()).sort()}function tn(){let r=Be();for(let e of Object.keys(r)){if(process.env[e]!==void 0)continue;let t=mt(e);t!=null&&(process.env[e]=t)}}import{createInterface as Di}from"node:readline/promises";var H={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",gray:"\x1B[90m"};function on({color:r=ji()}={}){let e=(n,a)=>r?`${n}${a}${H.reset}`:String(a);return{color:r,bold:n=>e(H.bold,n),dim:n=>e(H.dim,n),red:n=>e(H.red,n),green:n=>e(H.green,n),yellow:n=>e(H.yellow,n),blue:n=>e(H.blue,n),magenta:n=>e(H.magenta,n),cyan:n=>e(H.cyan,n),gray:n=>e(H.gray,n),userPrompt:()=>`${e(H.cyan,"Voce")} ${e(H.gray,">")} `,agentPrompt:()=>`${e(H.green,"Agent")} ${e(H.gray,">")} `,status:(n,a="")=>`${e(H.blue,`[${n}]`)}${a?` ${a}`:""}`,ok:n=>`${e(H.green,"[ok]")} ${n}`,warn:n=>`${e(H.yellow,"[aviso]")} ${n}`,error:n=>`${e(H.red,"[erro]")} ${n}`,section:n=>e(H.bold,n),divider:()=>e(H.gray,"-".repeat(64)),box:t};function t(n,a=[]){let s=Math.min(88,Math.max(32,n.length+4,...a.map(u=>rn(u)+4))),i=`+${"-".repeat(s-2)}+`,c=`| ${n.padEnd(s-4)} |`,l=a.map(u=>{let m=rn(u),f=Math.max(0,s-m-4);return`| ${u}${" ".repeat(f)} |`});return[o(i),o(c),o(i),...l,o(i)].join(`
22
+ `)}function o(n){return e(H.gray,n)}}function qi(r){return String(r).replace(/\x1b\[[0-9;]*m/g,"")}function rn(r){return qi(r).length}function ji(){return process.env.NO_COLOR?!1:process.env.FORCE_COLOR?!0:!!process.stdout.isTTY}function sn({ask:r,input:e=process.stdin,output:t=process.stdout,theme:o=on()}={}){let n=Promise.resolve(),a={approveAll:!1,approvedTools:new Set};return async function(i){return a.approveAll?{approved:!0,scope:"session",reason:"approved_all_for_session"}:a.approvedTools.has(i.toolName)?{approved:!0,scope:"tool",reason:"approved_tool_for_session"}:(n=n.catch(()=>{}).then(async()=>{let c=await Ui({request:i,ask:r,input:e,output:t,theme:o});return c.scope==="all"&&(a.approveAll=!0),c.scope==="tool"&&a.approvedTools.add(i.toolName),c}),n)}}async function Ui({request:r,ask:e,input:t,output:o,theme:n}){if(!e&&!t.isTTY)return{approved:!1,reason:"non_interactive_terminal"};let a=Fi(r,n);if(e){let i=await e(a);return nn(i)}let s=Di({input:t,output:o});try{let i=await s.question(a);return nn(i)}finally{s.close()}}function Fi(r,e){let t=[`${e.bold("Ferramenta")} ${r.toolName}`,`${e.bold("Risco")} ${Bi(r.risk,e)}`,`${e.bold("Motivo")} ${r.reason}`,`${e.bold("Args")} ${zi(r.arguments)}`];return["",e.box("Aprovacao Necessaria",t),`${e.yellow("Executar?")} ${e.dim("[s] uma vez [t] sempre esta ferramenta [a] sempre tudo [n] nao")} `].join(`
23
+ `)}function nn(r){let e=String(r||"").trim().toLowerCase(),t=["s","sim","y","yes"].includes(e),o=["t","tool","ferramenta","sempre ferramenta"].includes(e),n=["a","all","always","sempre","sempre tudo"].includes(e),a=t||o||n;return{approved:a,scope:n?"all":o?"tool":t?"once":"none",reason:a?n?"approved_all_for_session":o?"approved_tool_for_session":"approved_once_by_user":"denied_by_user"}}function Bi(r,e){return r==="dangerous"?e.red(r):r==="browser"||r==="network"?e.yellow(r):e.cyan(r||"unknown")}function zi(r={}){let e=Object.entries(r).map(([t,o])=>typeof o=="string"?`${t}=${an(o,120)}`:`${t}=${an(JSON.stringify(o),120)}`);return e.length?e.join(", "):"{}"}function an(r,e){let t=String(r??"");return t.length<=e?t:`${t.slice(0,e-3)}...`}import{render as Ki,Box as v,Text as d,Static as Xi,useApp as Yi,useInput as hn}from"ink";import gn from"ink-text-input";import{basename as Ji,dirname as Qi,join as He}from"node:path";import{homedir as Or}from"node:os";import{existsSync as Ge,mkdirSync as yn,readFileSync as bn,readdirSync as Zi,writeFileSync as vn}from"node:fs";import{spawn as Ar}from"node:child_process";import{createElement as ec,useState as B,useEffect as We,useRef as K,useCallback as J}from"react";import tc from"htm";import{readdirSync as Hi,readFileSync as Gi}from"node:fs";import be from"node:path";import Wi from"node:os";function pt(r){let e=String(r||"");if(!e.startsWith("---"))return{frontmatter:{},content:e};let t=e.indexOf(`
24
+ ---`,3);if(t===-1)return{frontmatter:{},content:e};let o=e.slice(3,t).trim(),n=e.slice(t+4).replace(/^\r?\n/,""),a={};for(let s of o.split(/\r?\n/)){let i=s.match(/^([A-Za-z0-9_-]+)\s*:\s*(.*)$/);i&&(a[i[1]]=ln(i[2]))}return{frontmatter:a,content:n}}function cn(r){if(Array.isArray(r))return r.map(t=>String(t).trim()).filter(Boolean);let e=String(r||"").trim().replace(/^\[/,"").replace(/\]$/,"");return e?e.split(/[,\s]+/).map(t=>ln(t).trim()).filter(Boolean):[]}function ln(r){let e=String(r??"").trim();return e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function Vi(r,e){let{frontmatter:t,content:o}=pt(r),n=be.basename(e,be.extname(e)).trim().toLowerCase(),a=o.trim();if(!n||!/^[a-z0-9_-]+$/.test(n))throw new Error(`nome de comando invalido: "${n}"`);if(!a)throw new Error("corpo vazio (o template do prompt e o corpo do markdown)");return{name:n,description:String(t.description||`comando customizado /${n}`).trim(),argumentHint:String(t["argument-hint"]||t.argumentHint||"").trim(),template:a,source:"file",filePath:e}}function un(r,e){let t=[];try{t=Hi(r,{withFileTypes:!0})}catch{return[]}let o=[];for(let n of t){if(!n.isFile()||!n.name.toLowerCase().endsWith(".md"))continue;let a=be.join(r,n.name);try{o.push(Vi(Gi(a,"utf8"),a))}catch(s){e?.warn?.(`[commands] ignorando ${a}: ${s.message}`)}}return o}function dn({fileRoot:r=".",logger:e}={}){let t=be.join(Wi.homedir(),".rivale","commands"),o=be.resolve(r,".rivale","commands"),n=new Map;for(let a of un(t,e))n.set(a.name,a);if(be.resolve(o)!==be.resolve(t))for(let a of un(o,e))n.set(a.name,a);return[...n.values()]}function mn(r,e=""){let t=String(e||"").trim(),o=t?t.split(/\s+/):[],n=/\$ARGUMENTS\b|\$[1-9]\b/.test(r),a=r.replace(/\$ARGUMENTS\b/g,t);return a=a.replace(/\$([1-9])\b/g,(s,i)=>o[Number(i)-1]||""),!n&&t&&(a=`${a}
25
+
26
+ ${t}`),a.trim()}var x=tc.bind(ec),rc=["\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557","\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D","\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 ","\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D ","\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557","\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"],wn={"ctrl+l":"clear","ctrl+d":"exit","ctrl+s":"stashDraft","shift+tab":"cycleApproval"},Mr=["clear","exit","stashDraft","cycleApproval"],oc=JSON.stringify({_actions:Mr,bindings:wn},null,2),nc=["groq","openai","anthropic","gemini","openrouter","deepseek"],ft=["never","dangerous","write","network","always"],ac=["auto","always","never"],sc=["silent","info","debug"],Sn=[["/help","lista de comandos e atalhos"],["/clear","limpa a tela"],["/stream","liga/desliga streaming"],["/tools","lista as ferramentas dispon\xEDveis"],["/agents","lista os subagentes"],["/permissions","mostra as regras de permiss\xE3o ativas"],["/config","abre a tela de configura\xE7\xE3o"],["/mcp","gerencia os servers MCP \xB7 /mcp edit abre o json"],["/compact","resume a conversa pra economizar contexto"],["/plan","liga/desliga o modo plan (s\xF3 leitura, n\xE3o altera nada)"],["/keybindings","edita os atalhos (~/.rivale/keybindings.json)"],["/rollback","desfaz as altera\xE7\xF5es do \xFAltimo run"],["/resume","retoma uma conversa [<id>]"],["/exit","sair"]];async function xn(r,{conversationId:e="chat",stream:t=!0,mcp:o=[]}={}){await r.hookManager?.runSessionStart({conversationId:e,mode:"chat"}).catch(()=>{}),await Ki(x`<${ic} runtime=${r} conversationId=${e} stream=${t} mcp=${o} />`,{exitOnCtrlC:!1}).waitUntilExit(),await r.hookManager?.runSessionEnd({conversationId:e,mode:"chat"}).catch(()=>{}),await r.lspManager?.stop().catch(()=>{}),await r.mcpManager?.disconnectAll?.().catch(()=>{}),r.storage.close()}function ic({runtime:r,conversationId:e,stream:t,mcp:o=[]}){let{exit:n}=Yi(),[a,s]=B(()=>[Rr(r,t,o)]),[i,c]=B(""),[l,u]=B(!1),[m,f]=B(""),[g,w]=B("pensando"),[y,b]=B("idle"),[E,k]=B(null),[R,h]=B(t),[A,M]=B(0),[P,Y]=B(0),[ce,hr]=B(0),[pe,Ne]=B(0),[N,L]=B(!1),[G,W]=B(0),[re,ee]=B(null),[,ei]=B(0),[ge,ti]=B([]),[go,gr]=B(0),[yo,bo]=B(null),[ri,oe]=B(null),[oi,ni]=B(0),[ai,vo]=B(!1),[,si]=B(0),ii=K(1),Ee=K(null),qe=K(""),_e=K(null),wo=K(0),So=K(0),yr=K([]),ne=K(-1),xo=K(!1),To=K(new Set),nt=K({}),at=K(""),ci=K($c()),U=J(p=>{s(S=>[...S,{id:ii.current++,...p}])},[]);We(()=>{let p=r.eventBus;if(!p)return;let S=[p.on("planner:created",({plan:T})=>{T?.required&&U({kind:"activity",dim:!0,text:`plano \xB7 ${T.steps?.length||0} passos`})}),p.on("context:built",({estimatedTokens:T,memories:$})=>U({kind:"activity",dim:!0,text:`contexto \xB7 ~${T} tokens \xB7 ${$} mem\xF3rias`})),p.on("tool:start",({name:T,arguments:$})=>{let C=Tc(T,$);w(fn(T)),U({kind:"tool",text:`${fn(T)}${C?` ${C}`:""}`})}),p.on("tool:end",({durationMs:T})=>U({kind:"toolend",ok:!0,text:`ok \xB7 ${Cr(T)}`})),p.on("tool:error",({error:T})=>U({kind:"toolend",ok:!1,text:`erro \xB7 ${le(T?.message||"erro",120)}`})),p.on("subagent:start",({agentName:T,task:$})=>{w(`${T} trabalhando`),U({kind:"subagent",text:`delegando \u2192 ${T}`,sub:le($,90)})}),p.on("subagent:end",({durationMs:T,toolResults:$})=>U({kind:"toolend",ok:!0,text:`conclu\xEDdo \xB7 ${Cr(T)} \xB7 ${$?.length||0} ferramentas`})),p.on("subagent:error",({error:T})=>U({kind:"toolend",ok:!1,text:`falhou \xB7 ${le(T,120)}`})),p.on("llm:start",({metadata:T})=>{T?.compact?w("compactando contexto"):T?.subagent?w(`${T.subagentName||"subagente"} pensando`):T?.planner?w("planejando"):w("pensando")}),p.on("memory:autocompact:start",()=>w("compactando contexto")),p.on("memory:autocompact:done",({compacted:T,before:$,summaryTokens:C})=>{T&&U({kind:"activity",dim:!0,text:`contexto compactado automaticamente \xB7 ${$} msgs \u2192 ~${C} tokens`})})];return()=>S.forEach(T=>T&&T())},[r,U]),We(()=>{if(!l)return;wo.current=Date.now(),Y(0);let p=setInterval(()=>Y(Math.floor((Date.now()-wo.current)/1e3)),1e3);return()=>clearInterval(p)},[l]);let Eo=J(()=>{_e.current||(_e.current=setTimeout(()=>{_e.current=null,f(qe.current)},40))},[]),_o=J(p=>xo.current?Promise.resolve({approved:!0,scope:"all"}):To.current.has(p.toolName)?Promise.resolve({approved:!0,scope:"tool"}):new Promise(S=>{k({kind:"approval",request:p,resolve:S}),b("approval")}),[]),ko=J(p=>new Promise(S=>{k({kind:"askHuman",question:p,resolve:S}),b("askHuman"),c("")}),[]),li=J(()=>{let p=yr.current;p.length&&(ne.current=ne.current<0?p.length-1:Math.max(0,ne.current-1),c(p[ne.current]))},[]),ui=J(()=>{let p=yr.current;ne.current<0||(ne.current+=1,ne.current>=p.length?(ne.current=-1,c("")):c(p[ne.current]))},[]),st=K(null);if(st.current===null)try{st.current=hc(r.config.tools.fileRoot)}catch{st.current=[]}let je=K(null);if(je.current===null)try{je.current=dn({fileRoot:r.config.tools.fileRoot})}catch{je.current=[]}let q=r.config,ye=[{key:"provider",label:"Provider",env:"LLM_PROVIDER",type:"enum",opts:nc,get:()=>q.llm.provider,set:p=>q.llm.provider=p},{key:"model",label:"Modelo",env:"LLM_MODEL",type:"text",get:()=>q.llm.model,set:p=>q.llm.model=p},{key:"apikey",label:()=>`API key \xB7 ${q.llm.provider}`,env:()=>`${q.llm.provider.toUpperCase()}_API_KEY`,type:"secret",get:()=>q.llm.apiKeys?.[q.llm.provider]||"",set:p=>{q.llm.apiKeys||(q.llm.apiKeys={}),q.llm.apiKeys[q.llm.provider]=p,process.env[`${q.llm.provider.toUpperCase()}_API_KEY`]=p}},{key:"approval",label:"Modo de aprova\xE7\xE3o",env:"TOOL_APPROVAL_MODE",type:"enum",opts:ft,get:()=>q.tools.approvalMode,set:p=>q.tools.approvalMode=p},{key:"stream",label:"Streaming",type:"bool",app:"stream"},{key:"temp",label:"Temperatura",env:"LLM_TEMPERATURE",type:"number",get:()=>q.llm.temperature,set:p=>q.llm.temperature=p},{key:"maxTokens",label:"Max tokens (resposta)",env:"LLM_MAX_TOKENS",type:"number",get:()=>q.llm.maxTokens,set:p=>q.llm.maxTokens=p},{key:"iters",label:"M\xE1x. itera\xE7\xF5es de tools",env:"AGENT_MAX_TOOL_ITERATIONS",type:"number",get:()=>q.agent.maxToolIterations,set:p=>q.agent.maxToolIterations=p},{key:"coord",label:"Coordinator Mode",env:"COORDINATOR_MODE_ENABLED",type:"bool",get:()=>q.coordinator.enabled,set:p=>q.coordinator.enabled=p},{key:"multi",label:"Multi-agente",env:"MULTI_AGENT_ENABLED",type:"bool",get:()=>q.multiAgent.enabled,set:p=>q.multiAgent.enabled=p},{key:"planner",label:"Planner",env:"PLANNER_MODE",type:"enum",opts:ac,get:()=>q.planner.mode,set:p=>q.planner.mode=p},{key:"log",label:"Log level",env:"LOG_LEVEL",type:"enum",opts:sc,get:()=>q.app.logLevel,set:p=>q.app.logLevel=p}];function $o(p){return p.app==="stream"?R:p.get()}function it(p,S){ei($=>$+1),ee(null);let T=typeof p.env=="function"?p.env():p.env;T&&(nt.current[T]=Rc(S),W(Object.keys(nt.current).length))}function br(p,S){if(p.app==="stream"){h(T=>!T);return}if(p.type==="bool"){let T=!p.get();p.set(T),it(p,T)}else if(p.type==="enum"){let T=p.get(),$=Math.max(0,p.opts.indexOf(T)),C=p.opts[($+S+p.opts.length)%p.opts.length];p.set(C),it(p,C)}}function di(p){let S=ye[pe],T=String(p).trim();if(S.type==="number"){let $=Number(T);Number.isFinite($)&&(S.set($),it(S,$))}else S.set(T),it(S,T);L(!1),c("")}function mi(){let p=Object.entries(nt.current);if(!p.length){ee({tone:"dim",text:"nada alterado para salvar"});return}try{let S=p.filter(([V])=>/_API_KEY$/i.test(V)),T=p.filter(([V])=>!/_API_KEY$/i.test(V));for(let[V,xr]of S)ze(V,xr);let $=T.length?Lc(T):null,C=[];S.length&&C.push(`${S.length} no cofre \u{1F512}`),T.length&&C.push(`${T.length} em ${$}`),ee({tone:"ok",text:`salvo \xB7 ${C.join(" \xB7 ")}`}),nt.current={},W(0)}catch(S){ee({tone:"error",text:`falha ao salvar: ${S.message}`})}}let Ao=J(()=>{Ne(0),L(!1),ee(null),c(""),b("config")},[]),vr=J(()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),s([Rr(r,R,o)]),ni(p=>p+1)},[r,R,o]),De=J(()=>{let p=r.mcpManager?.status?.(process.env.MCP_CONFIG_PATH)||[];return ti(p),p},[r]),Ro=J(()=>{gr(0),oe(null),De(),b("mcp")},[De]),Co=J(async()=>{if(!l){u(!0),w("compactando");try{let p=await r.memoryManager.compactConversation(e,{llmManager:r.llmManager});p.compacted?(U({kind:"compact",text:`compactado \xB7 ${p.before} mensagens \u2192 resumo (~${p.summaryTokens} tokens) \xB7 mem\xF3ria preservada`}),U({kind:"activity",dim:!0,text:le(p.summary,220)})):U({kind:"warn",text:p.reason||"nada para compactar"})}catch(p){U({kind:"error",text:`falha ao compactar: ${p.message}`})}finally{u(!1)}}},[l,r,e,U]);async function pi(p){if(!p||yo)return;let S=r.mcpManager,T=r.config.coordinator?.allowedTools;bo(p.name),oe(null);try{if(p.connected){let $=S.serverTools?.get(p.name)||[];if(await S.disconnect(p.name),Array.isArray(T))for(let C of $){let V=T.indexOf(C);V>=0&&T.splice(V,1)}oe({tone:"dim",text:`${p.name} desconectado`})}else{let $=await S.connectByName(p.name,process.env.MCP_CONFIG_PATH);if(Array.isArray(T))for(let C of $)T.includes(C)||T.push(C);oe({tone:"ok",text:`${p.name} conectado \xB7 ${$.length} tools`})}}catch($){oe({tone:"error",text:`${p.name}: ${$.message}`})}finally{bo(null),De()}}function fi(){let p={};for(let S of ge)S.declared&&(p[S.name]=S.connected);if(!Object.keys(p).length){oe({tone:"dim",text:"nada declarado para salvar"});return}try{let S=r.mcpManager.saveEnabledState(process.env.MCP_CONFIG_PATH,p);oe({tone:"ok",text:`estado salvo em ${S}`}),De()}catch(S){oe({tone:"error",text:`falha ao salvar: ${S.message}`})}}let wr=J(async p=>{U({kind:"user",text:p}),u(!0),f(""),qe.current="";let S=new AbortController;Ee.current=S;try{let T=await r.agent.run(p,{conversationId:e,stream:R,approvalHandler:_o,humanPrompt:ko,signal:S.signal,onToken:V=>{qe.current+=V,Eo()}});_e.current&&(clearTimeout(_e.current),_e.current=null);let $=(T.content||qe.current||"").trim();U({kind:"agent",text:$||"(sem texto retornado)"});let C=T.metrics;C&&(M(V=>V+(C.costUsd||0)),C.totalTokens&&hr(C.totalTokens),U({kind:"summary",metrics:C}))}catch(T){T?.name==="AbortError"?U({kind:"warn",text:"Run cancelada."}):U({kind:"error",text:T.message})}finally{u(!1),f(""),qe.current="",Ee.current=null}},[r,e,R,_o,ko,Eo,U]),Lo=J(p=>{let S=p.trim();if(c(""),y==="askHuman"&&E){U({kind:"human",text:S}),E.resolve(S),k(null),b("idle");return}if(!l&&S){if(yr.current.push(S),ne.current=-1,S.startsWith("/")){xc(S,{runtime:r,conversationId:e,push:U,setLog:s,exit:n,streamingEnabled:R,setStreamingEnabled:h,openConfig:Ao,openMcp:Ro,compactNow:Co,clearScreen:vr,mcp:o,commands:je.current,runMessage:wr});return}wr(S)}},[y,E,l,r,e,R,wr,U,n,Ao,Ro,Co,vr,o]);hn((p,S)=>{if(S.ctrl&&p==="c"){if(l&&Ee.current){Ee.current.abort();return}let $=Date.now();$-So.current<2e3&&(n(),process.exit(0)),So.current=$,U({kind:"activity",dim:!0,text:"pressione Ctrl-C novamente para sair"});return}if(!l&&y==="idle"){let $=ci.current[_c(p,S)];if($==="clear"){vr();return}if($==="exit"){i||(n(),process.exit(0));return}if($==="stashDraft"){i?(at.current=i,c(""),vo(!0)):at.current&&(c(at.current),at.current="",vo(!1));return}if($==="cycleApproval"){let C=r.config.tools.approvalMode,V=ft[(Math.max(0,ft.indexOf(C))+1)%ft.length];r.config.tools.approvalMode=V,si(xr=>xr+1);return}}if(y==="config"){let $=ye[pe];if(N){S.escape&&(L(!1),c(""));return}if(S.escape){b("idle"),c("");return}if(S.upArrow||S.ctrl&&p==="p"){Ne(C=>(C-1+ye.length)%ye.length);return}if(S.downArrow||S.ctrl&&p==="n"){Ne(C=>(C+1)%ye.length);return}if(S.leftArrow){br($,-1);return}if(S.rightArrow){br($,1);return}if(S.return){if($.type==="number"||$.type==="text"||$.type==="secret"){let C=$o($);c(C==null?"":String(C)),L(!0)}else br($,1);return}String(p||"").toLowerCase()==="s"&&mi();return}if(y==="mcp"){if(S.escape){b("idle");return}if(!ge.length)return;if(S.upArrow||S.ctrl&&p==="p"){gr(C=>(C-1+ge.length)%ge.length);return}if(S.downArrow||S.ctrl&&p==="n"){gr(C=>(C+1)%ge.length);return}let $=String(p||"").toLowerCase();if(S.return||$==="c"){pi(ge[go]);return}if($==="r"){De(),oe({tone:"dim",text:"lista recarregada do mcp.json"});return}if($==="s"){fi();return}if($==="e"){let C=r.mcpManager.resolveConfigFile?.(process.env.MCP_CONFIG_PATH)||".rivale/mcp.json",V=Lr(C,`${JSON.stringify({mcpServers:{}},null,2)}
27
+ `);oe({tone:V?"ok":"error",text:V?`abrindo ${C} no editor`:`edite manualmente: ${C}`});return}return}if(y==="approval"&&E){let $=String(p||"").toLowerCase();$==="s"||$==="y"||S.return?T(!0,"once"):$==="t"?(To.current.add(E.request?.toolName),T(!0,"tool")):$==="a"?(xo.current=!0,T(!0,"all")):($==="n"||S.escape)&&T(!1,"none");return}if(S.escape&&l&&Ee.current){Ee.current.abort();return}function T($,C){U({kind:"activity",text:$?`\u2713 ${C==="all"?"sempre":C==="tool"?"sempre esta":"aprovado"} \xB7 ${E.request?.toolName}`:`\u2717 negado \xB7 ${E.request?.toolName}`}),E.resolve({approved:$,scope:C}),k(null),b("idle")}});let Sr=!l&&y==="idle",hi=[...Sn,...(je.current||[]).map(p=>[`/${p.name}`,p.argumentHint?`${p.description} \xB7 ${p.argumentHint}`:p.description])],Oo=Sr&&i.startsWith("/")?hi.filter(([p])=>p.startsWith(i.split(/\s+/)[0])):[];return x`
28
+ <${v} flexDirection="column">
29
+ <${Xi} key=${oi} items=${a}>${p=>x`<${mc} key=${p.id} item=${p} />`}<//>
30
+
31
+ ${m?x`<${cc} text=${m} />`:null}
32
+
33
+ ${l&&y==="idle"&&!m?x`<${lc} label=${g} elapsed=${P} />`:null}
34
+
35
+ ${y==="approval"&&E?x`<${dc} request=${E.request} />`:null}
36
+
37
+ ${y==="config"?x`<${pc}
38
+ fields=${ye}
39
+ values=${ye.map($o)}
40
+ idx=${pe}
41
+ editing=${N}
42
+ input=${i}
43
+ setInput=${c}
44
+ onCommit=${di}
45
+ dirty=${G}
46
+ msg=${re}
47
+ />`:null}
48
+
49
+ ${y==="mcp"?x`<${bc} servers=${ge} idx=${go} busy=${yo} msg=${ri} />`:null}
50
+
51
+ ${y==="askHuman"&&E?x`
52
+ <${v} flexDirection="column" marginTop=${1}>
53
+ <${d} color="yellow">❓ ${E.question}</${d}>
54
+ <${v}><${d} color="cyan">resposta ${"\u203A "}</${d}><${gn} value=${i} onChange=${c} onSubmit=${Lo} /></${v}>
55
+ </${v}>
56
+ `:null}
57
+
58
+ ${Sr?x`
59
+ <${v} marginTop=${1}>
60
+ <${yc}
61
+ value=${i}
62
+ onChange=${c}
63
+ onSubmit=${Lo}
64
+ onHistoryPrev=${li}
65
+ onHistoryNext=${ui}
66
+ prompt="você › "
67
+ placeholder="digite ou /help · @ menciona arquivo · \\+Enter nova linha"
68
+ focus=${Sr}
69
+ files=${st.current}
70
+ />
71
+ </${v}>
72
+ `:null}
73
+
74
+ ${Oo.length?x`
75
+ <${v} flexDirection="column">
76
+ ${Oo.map(([p,S])=>x`<${d} key=${p} dimColor> ${p.padEnd(10)} ${S}</${d}>`)}
77
+ </${v}>
78
+ `:null}
79
+
80
+ <${uc}
81
+ provider=${r.config.llm.provider}
82
+ model=${r.config.llm.model}
83
+ approval=${r.config.tools.approvalMode}
84
+ plan=${r.config.tools.planMode}
85
+ streaming=${R}
86
+ cost=${A}
87
+ tokens=${ce}
88
+ stash=${ai}
89
+ busy=${l}
90
+ elapsed=${P}
91
+ />
92
+ </${v}>
93
+ `}function cc({text:r}){let e=process.stdout?.rows||24,t=process.stdout?.columns||80,o=Math.max(4,Math.min(16,e-10)),n=r.split(`
94
+ `),a=Math.max(20,t),s=[],i=0,c=!1;for(let l=n.length-1;l>=0;l-=1){let u=n[l],m=Math.max(1,Math.ceil((u.length||1)/a));if(i+m>o&&s.length>0){c=!0;break}s.unshift(u),i+=m}return x`
95
+ <${v} flexDirection="column" marginTop=${1}>
96
+ <${v}>
97
+ <${d} color="green" bold>⏺ </${d}>
98
+ ${c?x`<${d} dimColor>⋮ escrevendo (mostrando o final)…</${d}>`:null}
99
+ </${v}>
100
+ <${d}>${s.join(`
101
+ `)}</${d}>
102
+ </${v}>
103
+ `}function lc({label:r,elapsed:e}){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],[o,n]=B(0);return We(()=>{let a=setInterval(()=>n(s=>(s+1)%t.length),80);return()=>clearInterval(a)},[]),x`
104
+ <${v} marginTop=${1}>
105
+ <${d} color="cyan">${t[o]} </${d}>
106
+ <${d} dimColor>${r}… </${d}>
107
+ <${d} dimColor>(${e}s · esc para interromper)</${d}>
108
+ </${v}>
109
+ `}function uc({provider:r,model:e,streaming:t,cost:o,tokens:n,busy:a,elapsed:s,approval:i,stash:c,plan:l}){let u=a?x`<${d} color="yellow">●</${d}>`:x`<${d} color="green">●</${d}>`,m=[`${r}\xB7${e}`,i?`aprov:${i}`:null,t?"stream":"no-stream",n?`${n} tok`:null,o>0?`$${o.toFixed(4)}`:null,c?"\u270E rascunho":null,a?`\u23F1 ${s}s`:null].filter(Boolean),f=l?x`<${d} color="magenta" bold> PLAN</${d}>`:null;return x`
110
+ <${v} marginTop=${1}>
111
+ ${u}
112
+ <${d} dimColor> ${Ji(process.cwd())} ${m.join(" ")}</${d}>
113
+ ${f}
114
+ </${v}>
115
+ `}function dc({request:r}){let e=r?.risk||"unknown",t=e==="dangerous"?"red":e==="browser"||e==="network"?"yellow":"cyan",o=Ec(r?.arguments);return x`
116
+ <${v} flexDirection="column" marginTop=${1} borderStyle="round" borderColor="yellow" paddingX=${1}>
117
+ <${d} color="yellow" bold>⚠ Aprovação necessária</${d}>
118
+ <${d}><${d} dimColor>ferramenta </${d}>${r?.toolName} <${d} dimColor>· risco </${d}><${d} color=${t}>${e}</${d}></${d}>
119
+ ${r?.reason?x`<${d} dimColor>${le(r.reason,120)}</${d}>`:null}
120
+ ${o?x`<${d} dimColor>args · ${o}</${d}>`:null}
121
+ <${d}><${d} color="green">[s]</${d}> sim <${d} color="cyan">[t]</${d}> sempre esta <${d} color="cyan">[a]</${d}> sempre tudo <${d} color="red">[n]</${d}> não</${d}>
122
+ </${v}>
123
+ `}function mc({item:r}){switch(r.kind){case"welcome":return x`<${vc} ...${r.data} />`;case"user":return x`<${v} marginTop=${1}><${d} color="cyan" bold>você ${"\u203A "}</${d}><${d}>${r.text}</${d}></${v}>`;case"human":return x`<${v}><${d} color="cyan">resposta ${"\u203A "}</${d}><${d}>${r.text}</${d}></${v}>`;case"agent":return x`
124
+ <${v} marginTop=${1} flexDirection="column">
125
+ <${d} color="green" bold>⏺ </${d}>
126
+ <${wc} text=${r.text} />
127
+ </${v}>
128
+ `;case"tool":return x`<${d}> <${d} dimColor>●</${d}> ${r.text}</${d}>`;case"subagent":return x`<${v} flexDirection="column"><${d}> <${d} dimColor>●</${d}> ${r.text}</${d}>${r.sub?x`<${d} dimColor> ${r.sub}</${d}>`:null}</${v}>`;case"toolend":return x`<${d} dimColor> └ <${d} color=${r.ok?"green":"red"}>${r.text}</${d}></${d}>`;case"activity":return x`<${d} dimColor=${!!r.dim}> ${r.text}</${d}>`;case"summary":{let e=r.metrics,t=[Cr(e.durationMs),`${e.llmCalls} LLM`,`${e.toolCalls} tools`,`${e.totalTokens} tokens`];return e.cachedTokens&&t.push(`${e.cachedTokens} cache`),typeof e.costUsd=="number"&&t.push(`$${e.costUsd.toFixed(4)}`),x`<${v} marginTop=${1}><${d} color="green">✓ </${d}><${d} dimColor>${t.join(" \xB7 ")}</${d}></${v}>`}case"compact":return x`<${v} marginTop=${1}><${d} color="green">✓ </${d}><${d} bold>${r.text}</${d}></${v}>`;case"warn":return x`<${v} marginTop=${1}><${d} color="yellow">${r.text}</${d}></${v}>`;case"error":return x`<${v} marginTop=${1} borderStyle="round" borderColor="red" paddingX=${1}><${d} color="red">${r.text}</${d}></${v}>`;default:return x`<${d}>${r.text||""}</${d}>`}}function pc({fields:r,values:e,idx:t,editing:o,input:n,setInput:a,onCommit:s,dirty:i,msg:c=null}){let l=c?.tone==="error"?"red":c?.tone==="ok"?"green":"gray";return x`
129
+ <${v} flexDirection="column" marginTop=${1} borderStyle="round" borderColor="cyan" paddingX=${1}>
130
+ <${d} color="cyan" bold>⚙ Configuração <${d} dimColor>(vale já nesta sessão)</${d}></${d}>
131
+ ${r.map((u,m)=>{let f=m===t,g=e[m],w=typeof u.label=="function"?u.label():u.label,y=u.type==="bool"?g?"on":"off":u.type==="secret"?g?Cc(g):"\u2014 (n\xE3o definida)":g==null||g===""?"\u2014":String(g);return x`
132
+ <${v} key=${u.key}>
133
+ <${d} color=${f?"cyan":void 0}>${f?"\u203A ":" "}${Tn(w)}</${d}>
134
+ ${o&&f?x`<${gn} value=${n} onChange=${a} onSubmit=${s} mask=${u.type==="secret"?"\u2022":void 0} />`:x`<${d} bold color=${f?"white":"gray"}>${u.type==="enum"&&f?`\u2039 ${y} \u203A`:y}</${d}>`}
135
+ </${v}>
136
+ `})}
137
+ <${v} marginTop=${1}>
138
+ <${d} dimColor>↑↓ mover · ←→ alterar · enter editar/aplicar · s salvar (API key → cofre 🔒) · esc fechar</${d}>
139
+ </${v}>
140
+ ${i?x`<${d} color="yellow">● ${i} alteração(ões) não salva(s) — pressione s</${d}>`:null}
141
+ ${c?x`<${d} color=${l}>${c.tone==="error"?"\u2717 ":c.tone==="ok"?"\u2713 ":""}${c.text}</${d}>`:null}
142
+ </${v}>
143
+ `}function Tn(r){return r.length>=24?`${r} `:r+" ".repeat(24-r.length)}var fc=new Set(["node_modules","dist","build","coverage","out","data"]);function hc(r,e=800){let t=[],o=(n,a,s)=>{if(s>6||t.length>=e)return;let i;try{i=Zi(n,{withFileTypes:!0})}catch{return}i.sort((c,l)=>c.name.localeCompare(l.name));for(let c of i){if(t.length>=e)return;let l=a?`${a}/${c.name}`:c.name;if(c.isDirectory()){if(fc.has(c.name)||c.name.startsWith("."))continue;t.push(`${l}/`),o(He(n,c.name),l,s+1)}else c.isFile()&&t.push(l)}};return o(r,"",0),t}function gc(r,e,t=8){let o=String(e||"").toLowerCase();if(!o)return r.filter(a=>!a.slice(0,-1).includes("/")).slice(0,t);let n=[];for(let a of r){let s=a.toLowerCase(),i=a.replace(/\/$/,""),c=i.slice(i.lastIndexOf("/")+1).toLowerCase(),l=-1;c.startsWith(o)?l=0:c.includes(o)?l=1:s.includes(o)&&(l=2),l>=0&&n.push({p:a,score:l,len:a.length})}return n.sort((a,s)=>a.score-s.score||a.len-s.len||a.p.localeCompare(s.p)),n.slice(0,t).map(a=>a.p)}function yc({value:r="",onChange:e,onSubmit:t,onHistoryPrev:o,onHistoryNext:n,prompt:a="",placeholder:s="",focus:i=!0,files:c=[]}){let[l,u]=B(r.length),[m,f]=B(0),g=K(" ");We(()=>{u(N=>N>r.length?r.length:N)},[r]);let y=r.slice(0,l).match(/(^|\s)@([^\s@]*)$/),b=y?y[2]:null,E=y?l-y[2].length-1:-1,k=b!==null?gc(c,b):[],R=i&&k.length>0&&g.current!==(b===null?" ":b);We(()=>{f(0)},[b]);let h=N=>{if(E<0||!N)return;let L=r.slice(0,E),G=r.slice(l),W=`@${N}${N.endsWith("/")?"":" "}`;e?.(L+W+G),u((L+W).length),g.current=" "},A=N=>{let L=String(N).replace(/\r\n?/g,`
144
+ `);e?.(r.slice(0,l)+L+r.slice(l)),u(l+L.length)},M=N=>{let L=r.slice(0,l).lastIndexOf(`
145
+ `)+1,G=l-L;if(N<0){let W=L-1;if(W<0)return;let re=r.lastIndexOf(`
146
+ `,W-1)+1;u(re+Math.min(G,W-re))}else{let W=r.indexOf(`
147
+ `,l);if(W<0)return;let re=W+1,ee=r.indexOf(`
148
+ `,re);ee<0&&(ee=r.length),u(re+Math.min(G,ee-re))}};hn((N,L)=>{if(R){if(L.upArrow||L.ctrl&&N==="p")return f(G=>(G-1+k.length)%k.length);if(L.downArrow||L.ctrl&&N==="n")return f(G=>(G+1)%k.length);if(L.return||L.tab)return h(k[Math.min(m,k.length-1)]);if(L.escape){g.current=b;return}}if(L.return){if(L.meta)return A(`
149
+ `);if(r[l-1]==="\\"){e?.(r.slice(0,l-1)+`
150
+ `+r.slice(l));return}return t?.(r)}if(L.leftArrow)return u(G=>Math.max(0,G-1));if(L.rightArrow)return u(G=>Math.min(r.length,G+1));if(L.upArrow||L.ctrl&&N==="p")return r.slice(0,l).includes(`
151
+ `)?M(-1):o?.();if(L.downArrow||L.ctrl&&N==="n")return r.slice(l).includes(`
152
+ `)?M(1):n?.();if(L.backspace||L.delete){l>0&&(e?.(r.slice(0,l-1)+r.slice(l)),u(l-1));return}N&&!L.ctrl&&!L.meta&&!L.tab&&A(N)},{isActive:i});let P=" ".repeat(a.length),Y=R?x`
153
+ <${v} flexDirection="column" marginLeft=${a.length}>
154
+ ${k.map((N,L)=>{let G=N.endsWith("/"),W=L===m;return x`
155
+ <${v} key=${N}>
156
+ <${d} color=${W?"cyan":"gray"}>${W?"\u203A ":" "}</${d}>
157
+ <${d} color=${G?"yellow":"blue"}>${G?"\u25B8 ":"\xB7 "}</${d}>
158
+ <${d} color=${W?"white":void 0} dimColor=${!W}>${N}</${d}>
159
+ </${v}>
160
+ `})}
161
+ <${v}><${d} dimColor> ↑↓ navegar · Tab/Enter inserir · Esc fechar</${d}></${v}>
162
+ </${v}>
163
+ `:null;if(!r.length)return x`
164
+ <${v} flexDirection="column">
165
+ <${v}>
166
+ <${d} color="cyan" bold>${a}</${d}>
167
+ ${i?x`<${d} inverse> </${d}>`:null}
168
+ <${d} dimColor>${s}</${d}>
169
+ </${v}>
170
+ ${Y}
171
+ </${v}>
172
+ `;let ce=r.slice(0,l),hr=(ce.match(/\n/g)||[]).length,pe=l-(ce.lastIndexOf(`
173
+ `)+1),Ne=r.split(`
174
+ `);return x`
175
+ <${v} flexDirection="column">
176
+ ${Ne.map((N,L)=>{let G=L===0?x`<${d} color="cyan" bold>${a}</${d}>`:x`<${d}>${P}</${d}>`;if(!i||L!==hr)return x`<${v} key=${L}>${G}<${d}>${N||" "}</${d}></${v}>`;let W=N.slice(0,pe),re=N.slice(pe,pe+1)||" ",ee=N.slice(pe+1);return x`
177
+ <${v} key=${L}>
178
+ ${G}<${d}>${W}</${d}><${d} inverse>${re}</${d}><${d}>${ee}</${d}>
179
+ </${v}>
180
+ `})}
181
+ ${Y}
182
+ </${v}>
183
+ `}function bc({servers:r=[],idx:e=0,busy:t=null,msg:o=null}){let n=o?.tone==="error"?"red":o?.tone==="ok"?"green":"gray",a=r.filter(s=>s.declared&&s.connected===!!s.disabled).length;return x`
184
+ <${v} flexDirection="column" marginTop=${1} borderStyle="round" borderColor="magenta" paddingX=${1}>
185
+ <${d} color="magenta" bold>◆ Gestão de MCP <${d} dimColor>(.rivale/mcp.json)</${d}></${d}>
186
+ ${r.length===0?x`<${d} dimColor>nenhum server declarado — crie .rivale/mcp.json com "mcpServers": { ... }</${d}>`:r.map((s,i)=>{let c=i===e,l=t===s.name,u=l?"\u25CC":s.connected?"\u25CF":"\u25CB",m=l?"yellow":s.connected?"green":"gray",f=l?s.connected?"desconectando\u2026":"conectando\u2026":s.connected?`conectado \xB7 ${s.tools} tools`:s.disabled?"desativado (enabled:false)":"desconectado";return x`
187
+ <${v} key=${s.name}>
188
+ <${d} color=${c?"cyan":void 0}>${c?"\u203A ":" "}</${d}>
189
+ <${d} color=${m}>${u} </${d}>
190
+ <${d} color=${c?"white":void 0} bold=${c}>${Tn(s.name)}</${d}>
191
+ <${d} dimColor>${f}</${d}>
192
+ </${v}>
193
+ `})}
194
+ <${v} marginTop=${1}>
195
+ <${d} dimColor>↑↓ mover · enter/c conectar·desconectar · s salvar · e editar json · r recarregar · esc fechar</${d}>
196
+ </${v}>
197
+ ${a?x`<${d} color="yellow">● ${a} mudança(s) não salva(s) no mcp.json — pressione s</${d}>`:null}
198
+ ${o?x`<${d} color=${n}>${o.tone==="error"?"\u2717 ":o.tone==="ok"?"\u2713 ":""}${o.text}</${d}>`:null}
199
+ </${v}>
200
+ `}function vc({provider:r,model:e,tools:t,streaming:o,cwd:n,mcp:a=[]}){let s=a.filter(c=>c.ok),i=a.filter(c=>!c.ok);return x`
201
+ <${v} flexDirection="column">
202
+ <${v} flexDirection="column">
203
+ ${rc.map((c,l)=>x`<${d} key=${l} color="cyan" bold>${c}</${d}>`)}
204
+ </${v}>
205
+ <${v} flexDirection="column" borderStyle="round" borderColor="cyan" paddingX=${1}>
206
+ <${d} dimColor>Autonomous Agent</${d}>
207
+ <${d}>
208
+ <${d} color="green">●</${d}> ${r} <${d} dimColor>·</${d}> ${e} <${d} dimColor>·</${d}> ${t} ferramentas${s.length?x`<${d} color="magenta"> · ${s.length} MCP</${d}>`:null}
209
+ </${d}>
210
+ ${i.map(c=>x`<${d} key=${c.name} color="yellow">MCP ${c.name} falhou · ${le(c.error,60)}</${d}>`)}
211
+ <${d} dimColor>${n}</${d}>
212
+ <${d} dimColor>streaming ${o?"on":"off"} · /help · /mcp · ↑↓ histórico · esc interrompe · Ctrl-C×2 sai</${d}>
213
+ </${v}>
214
+ </${v}>
215
+ `}function wc({text:r}){let e=String(r||"").split(`
216
+ `),t=[],o=0;for(;o<e.length;){if(e[o].match(/^\s*```(\w*)/)){let a=[];for(o+=1;o<e.length&&!/^\s*```/.test(e[o]);)a.push(e[o]),o+=1;o+=1,t.push({type:"code",text:a.join(`
217
+ `)});continue}t.push({type:"line",text:e[o]}),o+=1}return x`
218
+ <${v} flexDirection="column">
219
+ ${t.map((n,a)=>n.type==="code"?x`
220
+ <${v} key=${a} borderStyle="round" borderColor="gray" paddingX=${1} flexDirection="column">
221
+ ${n.text.split(`
222
+ `).map((s,i)=>x`<${d} key=${i} color="cyan">${s||" "}</${d}>`)}
223
+ </${v}>
224
+ `:x`<${Sc} key=${a} text=${n.text} />`)}
225
+ </${v}>
226
+ `}function Sc({text:r}){if(!r.trim())return x`<${d}> </${d}>`;let e=r.match(/^(#{1,6})\s+(.*)/);if(e)return x`<${d} bold color="white">${e[2]}</${d}>`;let t=r.match(/^(\s*)[-*]\s+(.*)/);return t?x`<${d}>${t[1]}<${d} color="cyan">• </${d}>${pn(t[2])}</${d}>`:x`<${d}>${pn(r)}</${d}>`}function pn(r){let e=[],t=/(\*\*[^*]+\*\*|`[^`]+`|\*[^*]+\*)/g,o=0,n;for(;n=t.exec(r);){n.index>o&&e.push({text:r.slice(o,n.index)});let s=n[0];s.startsWith("**")?e.push({text:s.slice(2,-2),bold:!0}):s.startsWith("`")?e.push({text:s.slice(1,-1),code:!0}):e.push({text:s.slice(1,-1),italic:!0}),o=t.lastIndex}return o<r.length&&e.push({text:r.slice(o)}),(e.length?e:[{text:r}]).map((s,i)=>x`<${d} key=${i} bold=${!!s.bold} italic=${!!s.italic} color=${s.code?"yellow":void 0}>${s.text}</${d}>`)}function Rr(r,e,t=[]){return{id:0,kind:"welcome",data:{provider:r.config.llm.provider,model:r.config.llm.model,tools:r.toolRegistry.list().length,streaming:e,cwd:process.cwd(),mcp:t}}}function xc(r,e){let[t,...o]=r.slice(1).split(/\s+/),n=o.join(" "),{runtime:a,conversationId:s,push:i,setLog:c,exit:l,streamingEnabled:u,setStreamingEnabled:m,openConfig:f,openMcp:g,compactNow:w,clearScreen:y,mcp:b=[],commands:E=[],runMessage:k}=e,R=E.find(h=>h.name===t);if(R){let h=mn(R.template,n);if(!h){i({kind:"warn",text:`/${t}: template vazio ap\xF3s expandir.`});return}i({kind:"activity",dim:!0,text:`/${t}${n?` ${n}`:""} \u2192 executando comando customizado`}),k?.(h);return}switch(t){case"exit":case"quit":l(),process.exit(0);break;case"config":case"settings":f?.();break;case"mcp":if(/^(edit|json|config|abrir)$/i.test(n)){let h=a.mcpManager.resolveConfigFile?.(process.env.MCP_CONFIG_PATH)||".rivale/mcp.json",A=Lr(h,`${JSON.stringify({mcpServers:{}},null,2)}
227
+ `);i({kind:"activity",text:A?`abrindo ${h} no editor`:`edite manualmente: ${h}`})}else g?.();break;case"compact":w?.();break;case"plan":{let h=n?["on","true","1"].includes(n.toLowerCase()):!a.config.tools.planMode;a.config.tools.planMode=h,i({kind:"activity",text:`modo plan ${h?"ligado \u2014 s\xF3 leitura/pesquisa, nada \xE9 alterado":"desligado \u2014 execu\xE7\xE3o normal"}`});break}case"keybindings":case"keys":{let h=He(Or(),".rivale","keybindings.json"),A=Lr(h,`${oc}
228
+ `);i({kind:"activity",text:A?`abrindo ${h} \xB7 a\xE7\xF5es: ${Mr.join(", ")} \xB7 reinicie pra aplicar`:`edite manualmente: ${h}`});break}case"clear":y?y():c([Rr(a,u,b)]);break;case"help":i({kind:"activity",text:["comandos: "+Sn.map(([h])=>h).join(" "),E.length?"customizados: "+E.map(h=>`/${h.name}`).join(" "):null,"atalhos: \\+Enter nova linha \xB7 \u2191\u2193 (ou Ctrl+P/N) hist\xF3rico \xB7 Shift+Tab modo de aprova\xE7\xE3o"," Ctrl+L limpa tela \xB7 Ctrl+S guarda rascunho \xB7 esc interrompe \xB7 Ctrl+D sai (vazio) \xB7 Ctrl+C cancela (2\xD7 sai)"].filter(Boolean).join(`
229
+ `)});break;case"stream":{let h=n?["on","true","1"].includes(n.toLowerCase()):!u;m(h),i({kind:"activity",text:`streaming ${h?"on":"off"}`});break}case"tools":{let h=a.toolRegistry.list().map(A=>A.name);i({kind:"activity",text:`${h.length} ferramentas: ${h.slice(0,30).join(", ")}${h.length>30?"\u2026":""}`});break}case"agents":{let h=a.subAgentRegistry.list().map(A=>A.name);i({kind:"activity",text:`subagentes: ${h.join(", ")}`});break}case"permissions":case"perms":{let h=a.permissionEngine;if(!h||h.isEmpty){i({kind:"activity",text:"sem regras de permiss\xE3o \u2014 vale o TOOL_APPROVAL_MODE. Crie .rivale/permissions.json (veja permissions.example.json)."});break}let A=M=>M.map(P=>P.pattern?`${P.tool}:${P.pattern}`:P.tool).join(", ")||"\u2014";i({kind:"activity",text:[`deny (${h.deny.length}): ${A(h.deny)}`,`ask (${h.ask.length}): ${A(h.ask)}`,`allow (${h.allow.length}): ${A(h.allow)}`].join(`
230
+ `)});break}case"rollback":case"undo":a.checkpointManager?.rollback(s).then(h=>{h.restored?.length?i({kind:"activity",text:`rollback: ${h.restored.length} arquivo(s) restaurado(s)`}):i({kind:"warn",text:h.message||"Nada para reverter."})}).catch(h=>i({kind:"error",text:h.message}));break;case"resume":{if(n){let h=a.memoryManager.hydrateConversation(n);i({kind:"activity",text:`retomando "${n}" \u2014 ${h} mensagens carregadas`})}else{let h=a.memoryManager.listConversations(20);i({kind:"activity",text:h.length?`conversas: ${h.map(A=>`${A.conversationId}(${A.messages})`).join(", ")}`:"nenhuma conversa persistida"})}break}default:i({kind:"warn",text:`comando desconhecido: /${t}`})}}function fn(r){return{invoke_subagent:"delegando",invoke_parallel_subagents:"delegando (paralelo)",start_swarm_debate:"debate de agentes",web_search:"pesquisando na web",http_request:"requisi\xE7\xE3o http",playwright_browser:"navegando",seo_analyzer:"analisando seo",file_list:"listando",file_read:"lendo",file_mkdir:"criando pasta",file_write:"escrevendo",file_copy:"copiando",file_edit:"editando",file_delete:"removendo",grep_search:"buscando",glob_search:"localizando",semantic_code_search:"busca sem\xE2ntica",sqlite:"consultando db",lsp_code:"analisando (lsp)",ast_search:"buscando (ast)",memory_search:"buscando mem\xF3ria",memory_save:"salvando mem\xF3ria",run_command:"executando comando",connect_mcp_server:"conectando mcp",ask_human:"aguardando sua resposta"}[r]||`executando ${r}`}function Tc(r,e){if(!e||typeof e!="object")return"";let t=e.path||e.file||e.url||e.command||e.query||e.pattern||e.name||e.agentName||"";return t?le(String(t),68):""}function Ec(r={}){if(!r||typeof r!="object")return"";let e=Object.entries(r).map(([t,o])=>{let n=typeof o=="string"?o:JSON.stringify(o);return`${t}=${le(String(n),60)}`});return le(e.join(", "),160)}function Cr(r){let e=Number(r)||0;return e<1e3?`${e}ms`:`${(e/1e3).toFixed(1)}s`}function le(r,e){let t=String(r||"").replace(/\s+/g," ").trim();return t.length<=e?t:`${t.slice(0,e-1)}\u2026`}function _c(r,e){let t=[];e.ctrl&&t.push("ctrl"),e.shift&&t.push("shift"),e.meta&&t.push("alt");let o="";return e.tab?o="tab":e.return?o="enter":e.escape?o="esc":e.upArrow?o="up":e.downArrow?o="down":e.leftArrow?o="left":e.rightArrow?o="right":r&&(o=String(r).toLowerCase()),o?[...t,o].join("+"):""}function kc(r){let e=String(r).toLowerCase().split("+").map(a=>a.trim()).filter(Boolean),t=new Set,o="";for(let a of e)a==="ctrl"||a==="control"?t.add("ctrl"):a==="shift"?t.add("shift"):a==="alt"||a==="meta"||a==="option"?t.add("alt"):o=a;return[...["ctrl","shift","alt"].filter(a=>t.has(a)),o].filter(Boolean).join("+")}function $c(){let r={...wn};try{let e=He(Or(),".rivale","keybindings.json");if(Ge(e)){let t=JSON.parse(bn(e,"utf8"));if(t?.bindings&&typeof t.bindings=="object")for(let[o,n]of Object.entries(t.bindings))Mr.includes(n)&&(r[kc(o)]=n)}}catch{}return r}function Lr(r,e=""){try{let t=Qi(r);t&&!Ge(t)&&yn(t,{recursive:!0}),Ge(r)||vn(r,e,"utf8")}catch{}return Ac(r)}function Ac(r){try{return process.platform==="win32"?Ar("cmd",["/c","start","",r],{stdio:"ignore",detached:!0}).unref():process.platform==="darwin"?Ar("open",[r],{stdio:"ignore",detached:!0}).unref():Ar("xdg-open",[r],{stdio:"ignore",detached:!0}).unref(),!0}catch{return!1}}function Rc(r){return typeof r=="boolean"?r?"true":"false":String(r)}function Cc(r){let e=String(r);return e.length<=6?"\u2022\u2022\u2022\u2022":`${e.slice(0,3)}\u2022\u2022\u2022\u2022${e.slice(-3)}`}function Lc(r){let e=He(Or(),".rivale"),t=He(e,".env");Ge(e)||yn(e,{recursive:!0});let o=Ge(t)?bn(t,"utf8"):"",n=o.length?o.split(/\r?\n/).filter(a=>a!==""):[];for(let[a,s]of r){let i=`${a}=${s}`,c=n.findIndex(l=>l.trimStart().startsWith(`${a}=`));c>=0?n[c]=i:n.push(i)}return vn(t,`${n.join(`
231
+ `)}
232
+ `,"utf8"),t}import Ke from"node:path";import jc from"node:os";var _={app:{env:"development",name:"rivale"},llm:{provider:"groq",modelByProvider:{groq:"llama-3.3-70b-versatile",openai:"gpt-4.1",anthropic:"claude-3-5-sonnet-latest",gemini:"gemini-1.5-pro",openrouter:"openai/gpt-4.1",deepseek:"deepseek-chat"},maxTokens:8192,contextWindow:64e3,strongProvider:null,strongModel:null,visionProvider:null,visionModel:null},agent:{maxToolIterations:25,maxParallelToolCalls:4,maxParallelReads:6,maxTokens:8192,temperature:.1,maxUsdPerRun:0,maxTokensPerRun:0},coordinator:{enabled:!0,enforceDelegation:!0,allowedTools:["invoke_subagent","invoke_parallel_subagents","start_swarm_debate","subagent_list_runs","subagent_read_run","subagent_cancel_run","todo_write","task_create","task_update","task_list","skill_use","tool_search","memory_search","memory_save","file_list","file_read","grep_search","glob_search","lsp_code","semantic_code_search","web_search","http_request","seo_analyzer","keyword_research","ad_copy_generator","campaign_planner","utm_builder","ads_budget_calculator","landing_page_audit","ask_human"]},multiAgent:{enabled:!0,maxSubagents:5,concurrency:3,maxSubagentToolIterations:15,maxTokens:16e3,temperature:.2},planner:{mode:"auto",maxSteps:8},autoDream:{enabled:!0,idleTimeoutMs:6e4},memory:{shortTermLimit:20,shortTermSummaryThreshold:30,shortTermTokenBudget:4e3,autoCompact:!0,autoCompactTokenThreshold:5e3,searchLimit:6,embeddingsEnabled:!0},lsp:{enabled:!1,command:"",args:[],timeoutMs:8e3,fallbackEnabled:!0},hooks:{enabled:!0,configPath:".rivale/hooks.json",inlineJson:"",timeoutMs:1e4},skills:{enabled:!0,paths:[".rivale/skills"],maxContentChars:12e3},embeddings:{provider:"local",model:"local-hash-v1",dimensions:256},tools:{enabled:["web_search","http_request","playwright_browser","file_list","file_read","file_mkdir","file_write","file_edit","file_delete","file_copy","grep_search","glob_search","lsp_code","semantic_code_search","sqlite","memory_search","memory_save","invoke_subagent","invoke_parallel_subagents","start_swarm_debate","skill_use","todo_write","task_create","task_update","task_list","subagent_list_runs","subagent_read_run","subagent_cancel_run","start_background_task","read_task_logs","kill_background_task","list_background_tasks","run_command","ask_human","index_codebase","ast_search","mcp_connect","tool_search","seo_analyzer","keyword_research","ad_copy_generator","campaign_planner","utm_builder","ads_budget_calculator","landing_page_audit"],timeoutMs:3e4,retryAttempts:1,rateLimitPerMinute:120,httpMaxBytes:1048576,playwrightNavigationTimeoutMs:15e3,playwrightActionTimeoutMs:5e3,approvalMode:"dangerous",planMode:!1,blockPrivateEgress:!0,allowDangerousCommands:!1,commandDenylist:[],commandAllowlist:[]}};import{readFileSync as Oc,existsSync as Mc}from"node:fs";import Ve from"node:path";import Pc from"node:os";import{fileURLToPath as Ic}from"node:url";var En=!1,Nc=Ve.resolve(Ve.dirname(Ic(import.meta.url)),"..","..");function _n(){if(En)return;En=!0;let r=[Ve.resolve(process.cwd(),".env"),Ve.join(Pc.homedir(),".rivale",".env"),Ve.join(Nc,".env")];for(let e of r)qc(e);try{tn()}catch{}}function qc(r){if(!Mc(r))return;let e;try{e=Oc(r,"utf8")}catch{return}for(let t of e.split(/\r?\n/)){let o=t.trim();if(!o||o.startsWith("#"))continue;let n=o.indexOf("=");if(n===-1)continue;let a=o.slice(0,n).trim();if(!a||process.env[a]!==void 0)continue;let s=o.slice(n+1).trim();(s.startsWith('"')&&s.endsWith('"')||s.startsWith("'")&&s.endsWith("'"))&&(s=s.slice(1,-1)),process.env[a]=s}}var Dc=new Set(["1","true","yes","on"]);function O(r,e=void 0){let t=process.env[r];return t===void 0||t===""?e:t}function D(r,e){let t=Number(O(r,e));return Number.isFinite(t)?t:e}function X(r,e=!1){let t=O(r);return t===void 0?e:Dc.has(String(t).toLowerCase())}function fe(r,e=[]){let t=O(r);return t?t.split(",").map(o=>o.trim()).filter(Boolean):e}function Ae(r){return r&&(Ke.isAbsolute(r)?r:Ke.resolve(process.cwd(),r))}function Pr(){_n();let r=O("LLM_PROVIDER",_.llm.provider).toLowerCase(),e=O("LLM_MODEL",_.llm.modelByProvider[r]||"local-model"),t=Ae(O("TOOL_FILE_ROOT",".")),o=String(t).replace(/[/\\:]+/g,"-").replace(/[^a-zA-Z0-9_.-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").toLowerCase()||"default",n=Ke.join(jc.homedir(),".rivale","projects",o,"data"),a=Ae(O("DATA_DIR",n));return{app:{env:O("APP_ENV",_.app.env),name:_.app.name,logLevel:O("LOG_LEVEL","info")},llm:{provider:r,model:e,temperature:D("LLM_TEMPERATURE",_.llm.temperature),maxTokens:D("LLM_MAX_TOKENS",_.llm.maxTokens),contextWindow:D("LLM_CONTEXT_WINDOW",_.llm.contextWindow),strongProvider:O("STRONG_LLM_PROVIDER",_.llm.strongProvider)?.toLowerCase()||null,strongModel:O("STRONG_LLM_MODEL",_.llm.strongModel)||null,visionProvider:O("VISION_LLM_PROVIDER",_.llm.visionProvider)?.toLowerCase()||null,visionModel:O("VISION_LLM_MODEL",_.llm.visionModel)||null,apiKeys:{groq:O("GROQ_API_KEY"),openai:O("OPENAI_API_KEY"),anthropic:O("ANTHROPIC_API_KEY"),gemini:O("GEMINI_API_KEY"),openrouter:O("OPENROUTER_API_KEY"),deepseek:O("DEEPSEEK_API_KEY")},baseUrls:{groq:O("GROQ_BASE_URL","https://api.groq.com/openai/v1"),openai:O("OPENAI_BASE_URL","https://api.openai.com/v1"),anthropic:O("ANTHROPIC_BASE_URL","https://api.anthropic.com/v1"),gemini:O("GEMINI_BASE_URL","https://generativelanguage.googleapis.com/v1beta"),openrouter:O("OPENROUTER_BASE_URL","https://openrouter.ai/api/v1"),deepseek:O("DEEPSEEK_BASE_URL","https://api.deepseek.com")}},agent:{maxToolIterations:D("AGENT_MAX_TOOL_ITERATIONS",_.agent.maxToolIterations),maxParallelToolCalls:D("AGENT_MAX_PARALLEL_TOOL_CALLS",_.agent.maxParallelToolCalls),maxParallelReads:D("AGENT_MAX_PARALLEL_READS",_.agent.maxParallelReads),maxUsdPerRun:D("AGENT_MAX_USD_PER_RUN",_.agent.maxUsdPerRun),maxTokensPerRun:D("AGENT_MAX_TOKENS_PER_RUN",_.agent.maxTokensPerRun)},coordinator:{enabled:X("COORDINATOR_MODE_ENABLED",_.coordinator.enabled),enforceDelegation:X("COORDINATOR_ENFORCE_DELEGATION",_.coordinator.enforceDelegation),allowedTools:fe("COORDINATOR_ALLOWED_TOOLS",_.coordinator.allowedTools)},multiAgent:{enabled:X("MULTI_AGENT_ENABLED",_.multiAgent.enabled),maxSubagentToolIterations:D("MULTI_AGENT_MAX_SUBAGENT_TOOL_ITERATIONS",_.multiAgent.maxSubagentToolIterations),maxTokens:D("MULTI_AGENT_MAX_TOKENS",_.multiAgent.maxTokens),temperature:D("MULTI_AGENT_TEMPERATURE",_.multiAgent.temperature)},planner:{mode:O("PLANNER_MODE",_.planner.mode).toLowerCase(),maxSteps:D("PLANNER_MAX_STEPS",_.planner.maxSteps)},memory:{shortTermLimit:D("SHORT_TERM_LIMIT",_.memory.shortTermLimit),shortTermSummaryThreshold:D("SHORT_TERM_SUMMARY_THRESHOLD",_.memory.shortTermSummaryThreshold),shortTermTokenBudget:D("SHORT_TERM_TOKEN_BUDGET",_.memory.shortTermTokenBudget),autoCompact:X("MEMORY_AUTO_COMPACT",_.memory.autoCompact),autoCompactTokenThreshold:D("MEMORY_AUTO_COMPACT_TOKEN_THRESHOLD",_.memory.autoCompactTokenThreshold),searchLimit:D("MEMORY_SEARCH_LIMIT",_.memory.searchLimit),embeddingsEnabled:X("MEMORY_EMBEDDINGS_ENABLED",_.memory.embeddingsEnabled)},lsp:{enabled:X("LSP_ENABLED",_.lsp.enabled),command:O("LSP_SERVER_COMMAND",_.lsp.command),args:fe("LSP_SERVER_ARGS",_.lsp.args),timeoutMs:D("LSP_TIMEOUT_MS",_.lsp.timeoutMs),fallbackEnabled:X("LSP_FALLBACK_ENABLED",_.lsp.fallbackEnabled)},hooks:{enabled:X("HOOKS_ENABLED",_.hooks.enabled),configPath:O("HOOKS_CONFIG_PATH",_.hooks.configPath),inlineJson:O("HOOKS_INLINE_JSON",_.hooks.inlineJson),timeoutMs:D("HOOK_TIMEOUT_MS",_.hooks.timeoutMs)},skills:{enabled:X("SKILLS_ENABLED",_.skills.enabled),paths:fe("SKILLS_PATHS",_.skills.paths).map(Ae),maxContentChars:D("SKILLS_MAX_CONTENT_CHARS",_.skills.maxContentChars)},embeddings:{provider:O("EMBEDDING_PROVIDER",_.embeddings.provider).toLowerCase(),model:O("EMBEDDING_MODEL",_.embeddings.model),dimensions:D("EMBEDDING_DIMENSIONS",_.embeddings.dimensions),apiKeys:{openai:O("OPENAI_API_KEY")},baseUrls:{openai:O("OPENAI_BASE_URL","https://api.openai.com/v1")}},storage:{dataDir:a,databasePath:Ae(O("DATABASE_PATH",Ke.join(a,"agent.sqlite")))},tools:{enabled:fe("TOOLS_ENABLED",_.tools.enabled),timeoutMs:D("TOOL_TIMEOUT_MS",_.tools.timeoutMs),retryAttempts:D("TOOL_RETRY_ATTEMPTS",_.tools.retryAttempts),rateLimitPerMinute:D("TOOL_RATE_LIMIT_PER_MINUTE",_.tools.rateLimitPerMinute),approvalMode:O("TOOL_APPROVAL_MODE",_.tools.approvalMode).toLowerCase(),approvalRequiredTools:fe("TOOL_APPROVAL_REQUIRED",[]),planMode:X("TOOL_PLAN_MODE",_.tools.planMode),blockPrivateEgress:X("TOOL_BLOCK_PRIVATE_EGRESS",_.tools.blockPrivateEgress),allowDangerousCommands:X("TOOL_ALLOW_DANGEROUS_COMMANDS",_.tools.allowDangerousCommands),commandDenylist:fe("TOOL_COMMAND_DENYLIST",_.tools.commandDenylist),commandAllowlist:fe("TOOL_COMMAND_ALLOWLIST",_.tools.commandAllowlist),fileRoot:Ae(O("TOOL_FILE_ROOT",".")),fileWriteEnabled:X("TOOL_FILE_WRITE_ENABLED",!0),httpAllowedMethods:fe("TOOL_HTTP_ALLOWED_METHODS",["GET","POST"]).map(s=>s.toUpperCase()),httpMaxBytes:D("TOOL_HTTP_MAX_BYTES",_.tools.httpMaxBytes),sqlitePath:Ae(O("TOOL_SQLITE_PATH",Ke.join(a,"tool.sqlite"))),sqliteAllowWrite:X("TOOL_SQLITE_ALLOW_WRITE",!1),playwrightHeadless:X("PLAYWRIGHT_HEADLESS",!0),playwrightNavigationTimeoutMs:D("PLAYWRIGHT_NAVIGATION_TIMEOUT_MS",_.tools.playwrightNavigationTimeoutMs),playwrightActionTimeoutMs:D("PLAYWRIGHT_ACTION_TIMEOUT_MS",_.tools.playwrightActionTimeoutMs),webSearch:{provider:O("WEB_SEARCH_PROVIDER","duckduckgo").toLowerCase(),endpoint:O("WEB_SEARCH_ENDPOINT"),braveApiKey:O("BRAVE_SEARCH_API_KEY"),tavilyApiKey:O("TAVILY_API_KEY")}}}}import{readdir as Bc,readFile as zc,stat as Hc}from"node:fs/promises";import kn from"node:path";var ht=class{constructor({tokenEstimator:e}={}){this.tokenEstimator=e}compressMessages(e,t){let o=e.filter(u=>u.role==="system"),n=e.filter(u=>u.role!=="system"),a=[],s=0;o.forEach((u,m)=>{let f=this.tokenEstimator.estimateMessage(u);(m===0||s+f<=t)&&(a.push(u),s+=f)});let i=Math.max(0,t-s),c=[],l=0;for(let u of[...n].reverse()){let m=this.tokenEstimator.estimateMessage(u);if(l+m>i)break;c.unshift(u),l+=m}return[...a,...c]}};var gt=class{estimateText(e){return e?Math.ceil(String(e).length/4):0}estimateMessage(e){let t=typeof e.content=="string"?e.content:JSON.stringify(e.content||""),o=this.estimateText(t)+6;return e.toolCalls?.length&&(o+=this.estimateText(JSON.stringify(e.toolCalls))),o}estimateMessages(e=[]){return e.reduce((t,o)=>t+this.estimateMessage(o),0)}};import Uc from"fs/promises";import Fc from"path";async function yt(r){let e=["RULES.md",".clinerules",".cursorrules","ia_rules.md"];for(let t of e)try{let o=Fc.join(r,t),n=await Uc.readFile(o,"utf-8");if(n.trim())return`
233
+ === REGRAS DE PROJETO IDENTIFICADAS (${t}) ===
234
+ ${n.trim()}
235
+ ======================================================
236
+ `}catch{}return""}var Gc=/[\w./\\-]+\.(?:js|mjs|cjs|jsx|ts|tsx|py|go|rs|java|json|md|css|scss|html|vue|svelte)\b/gi,Wc=new Set(["node_modules",".git","dist","build","coverage",".rivale"]),Re=class{constructor({config:e,memoryManager:t,subAgentRegistry:o,skillManager:n,toolRegistry:a,eventBus:s,logger:i}={}){this.config=e,this.memoryManager=t,this.subAgentRegistry=o,this.skillManager=n,this.toolRegistry=a,this.eventBus=s,this.logger=i,this.tokenEstimator=new gt,this.compressor=new ht({tokenEstimator:this.tokenEstimator})}async buildContext({conversationId:e,userMessage:t,plan:o}){let n=await this.skillManager?.describeForPrompt?.().catch(()=>""),a=Kc(this.config,this.subAgentRegistry,n),s=await yt(this.config.tools.fileRoot),i=this.memoryManager.getConversationSummary(e),c=this.memoryManager.getRecentMessages(e,this.config.memory.shortTermLimit),l=await this.memoryManager.searchMemory({query:t,limit:this.config.memory.searchLimit}),u=[{role:"system",content:a+(s?`
237
+
238
+ ${s}`:"")}];i&&u.push({role:"system",content:`Resumo recente da conversa:
239
+ ${i}`}),l.length>0&&u.push({role:"system",content:`Memorias relevantes recuperadas:
240
+ ${l.map(R=>`- (${R.id}) ${R.content}`).join(`
241
+ `)}`}),o?.steps?.length&&u.push({role:"system",content:`Plano de trabalho atual:
242
+ ${o.steps.map((R,h)=>`${h+1}. ${R}`).join(`
243
+ `)}`});let m=await this.gatherFileContext(t).catch(()=>[]);m.length&&u.push({role:"system",content:`Arquivos referenciados na mensagem (contexto automatico):
244
+
245
+ `+m.map(R=>`--- ${R.path} ---
246
+ ${R.content}`).join(`
247
+
248
+ `)}),u.push(...c.map(Vc));let f=this.config.llm.contextWindow,g=this.config.llm.maxTokens||0,w=this.estimateToolTokens(),b=Math.max(1024,f-g-w-512),E=this.compressor.compressMessages(u,b),k=this.tokenEstimator.estimateMessages(E);return this.logger?.debug("context built",{messages:E.length,estimatedTokens:k,budget:b,toolTokens:w}),await this.eventBus?.emit("context:built",{messages:E.length,memories:l.length,estimatedTokens:k}),{messages:E,memories:l,estimatedTokens:k}}};function Vc(r){let{createdAt:e,...t}=r;return t}Re.prototype.gatherFileContext=async function(e,{maxFiles:t=3,maxChars:o=2500}={}){let n=this.config?.tools?.fileRoot;if(!n||!e)return[];let a=[...String(e).matchAll(Gc)].map(m=>m[0].replace(/\\/g,"/").split("/").pop().toLowerCase()).filter(Boolean),s=new Set(a);if(s.size===0)return[];let i=[],c=new Set,l=0,u=async m=>{if(i.length>=t||l>4e3)return;let f;try{f=await Bc(m,{withFileTypes:!0})}catch{return}for(let g of f){if(i.length>=t)return;let w=kn.join(m,g.name);if(g.isDirectory()){if(Wc.has(g.name)||g.name.startsWith("."))continue;await u(w)}else if(g.isFile()){if(l+=1,!s.has(g.name.toLowerCase())||c.has(g.name.toLowerCase()))continue;try{if((await Hc(w)).size>200*1024)continue;let b=await zc(w,"utf8");c.add(g.name.toLowerCase()),i.push({path:kn.relative(n,w)||w,content:b.length>o?`${b.slice(0,o)}
249
+ ... (truncado)`:b})}catch{}}}};return await u(n),i};Re.prototype.estimateToolTokens=function(){try{let e=this.toolRegistry?.toLLMTools?.()||[];return e.length?this.tokenEstimator.estimateText(JSON.stringify(e)):0}catch{return 0}};function Kc(r,e,t=""){let o=new Date().toLocaleString("pt-BR",{timeZone:"America/Sao_Paulo"}),n=e?.describe?.()||"";return[`A data e hora atuais sao: ${o}.`,"Voce e o Supervisor Agent, o GERENTE e ORQUESTRADOR do sistema multi-agent.","Seu trabalho e receber o pedido do usuario, fazer o planejamento e DELEGAR obrigatoriamente as tarefas tecnicas para seus subagentes.",r.multiAgent?.enabled?`Subagentes disponiveis para delegacao via invoke_subagent:
250
+ ${n}`:"Delegacao multi-agent esta desativada por configuracao.",t?`Skills disponiveis via skill_use:
251
+ ${t}`:"Nenhuma skill externa encontrada; skills builtin ainda podem estar disponiveis via skill_use.",r.coordinator?.enabled?`Coordinator Mode ativo. Ferramentas do Supervisor limitadas a: ${(r.coordinator.allowedTools||[]).join(", ")}.`:"Coordinator Mode desativado.","REGRA DE OURO: VOCE NUNCA DEVE ESCREVER CODIGO DIRETAMENTE OU CRIAR/EDITAR ARQUIVOS NO CHAT. Toda e qualquer tarefa de programacao, refatoracao, criacao de arquivos ou testes DEVE OBRIGATORIAMENTE ser delegada usando invoke_subagent ou invoke_parallel_subagents.","Antes de delegar tarefas especializadas, use skill_use quando uma skill relevante existir. Inclua no prompt do subagente o nome da skill e as instrucoes importantes carregadas.","Aja apenas como a ponte inteligente: planeje a execucao, delegue as etapas, acompanhe os relatorios recebidos e entregue a conclusao consolidada ao usuario.","SE UMA FERRAMENTA OU SUBAGENTE FALHAR COM UM ERRO, LEIA A MENSAGEM DE ERRO, CORRIJA OS PAR\xC2METROS E TENTE NOVAMENTE. VOC\xCA EST\xC1 ESTRITAMENTE PROIBIDO DE DESISTIR DA FERRAMENTA E 'TENTAR FAZER SOZINHO' JOGANDO O RESULTADO OU C\xD3DIGO NO CHAT.","IMPORTANTE: Ao analisar ou revisar o que seus subagentes fizeram, se voce precisar mostrar blocos de codigo curtos, NUNCA use placeholders. MAS, arquivos inteiros NUNCA devem ser exibidos no chat. O Subagente Lucas DEVE salvar no disco.","IMPORTANTE: Lembre os subagentes que a formata\xE7\xE3o e as quebras de linha sejam rigorosamente preservadas usando '\\n' na string JSON.","Use ferramentas como file_list, glob_search, grep_search, lsp_code ou file_read apenas para analisar o contexto inicial da tarefa antes de delegar, se achar necessario.","Use lsp_code para navegar codigo como uma IDE: simbolos, definicoes, referencias, hover e diagnosticos. Para busca textual simples, use grep_search/glob_search.","Hooks de automacao podem rodar antes/depois de ferramentas; se uma ferramenta for bloqueada por hook, explique o motivo ao usuario e ajuste o plano.","Use todo_write e task_create/task_update/task_list para manter progresso visivel em tarefas com multiplas etapas.","Para marketing, growth, SEO ou ads, delegue para o subagente marketer e use o fluxo: keyword_research, seo_analyzer/landing_page_audit, ad_copy_generator, campaign_planner, utm_builder e ads_budget_calculator.","Nao abra o navegador para tarefas comuns, delegue as pesquisas ou testes visuais.",`Diretorio permitido para ferramentas de arquivo: ${r.tools.fileRoot}.`,"Ao usar ferramentas de arquivo, use caminhos relativos a esse diretorio quando possivel. Nao use caminhos Linux inventados como /home/user.","Para criar um projeto/pasta, use file_mkdir para a pasta e depois file_write para arquivos dentro dela. Nunca use file_write com conteudo vazio para representar uma pasta.","Para alterar arquivo existente, prefira file_edit depois de ler o arquivo completo com file_read. Use file_write para criar arquivos novos ou sobrescrever conscientemente.","Para listar conteudo de pastas, use file_list. Para apagar arquivos ou pastas, use file_delete. Antes de deletar uma pasta inteira, liste com file_list e peca confirmacao humana pela ferramenta.","Ao chamar ferramentas, USE EXCLUSIVAMENTE o recurso nativo de tool_calls da API JSON. NUNCA escreva tags XML, pseudo-codigo ou JSON no texto da sua resposta para tentar chamar uma ferramenta (ex: <function> ou similares sao PROIBIDOS).","Nao invente resultados de ferramentas. Se precisar de dados externos, chame uma ferramenta apropriada.","Salve memorias apenas quando forem fatos duraveis, preferencias do usuario ou decisoes importantes.","Para tarefas complexas, siga o plano e avance passo a passo.","COMPORTAMENTO ESPERADO:","- Adapte o tamanho da sua resposta ao tamanho do prompt do usuario. Respostas curtas merecem respostas curtas.","- Se algo estiver ambiguo ou faltar contexto essencial, use a ferramenta ask_human imediatamente em vez de assumir.","- Seja proativo: ao finalizar, antecipe o proximo passo util ou sugira o proximo comando.","Responda de forma objetiva, em portugues por padrao, a menos que o usuario peca outro idioma."].join(`
252
+ `)}var bt=class{constructor({logger:e}={}){this.logger=e,this.listeners=new Map}on(e,t){let o=this.listeners.get(e)||new Set;return o.add(t),this.listeners.set(e,o),()=>o.delete(t)}once(e,t){let o=this.on(e,async n=>{o(),await t(n)});return o}async emit(e,t={}){this.logger?.debug("event emitted",{event:e,payload:t});let o=[...this.listeners.get(e)||[],...this.listeners.get("*")||[]];for(let n of o)try{await n(t,e)}catch(a){this.logger?.error("event listener failed",{event:e,error:a.message})}}};import{exec as Xc}from"node:child_process";import $n from"node:fs";import Ir from"node:path";import{promisify as Yc}from"node:util";var Jc=Yc(Xc),qr=class extends Error{constructor(e,t={}){super(e),this.name="HookBlockedError",this.details=t}},vt=class{constructor({config:e,eventBus:t,logger:o}={}){this.config=e,this.eventBus=t,this.logger=o,this.root=Ir.resolve(e?.tools?.fileRoot||"."),this.hooks=new Map,this.lastRuns=[],this.load()}load(){if(this.hooks.clear(),!this.config?.hooks?.enabled)return;let e=[],t=this.parseInlineConfig(),o=this.readFileConfig();e.push(...An(t)),e.push(...An(o));for(let n of e){if(n.enabled===!1||!n.event||!n.command)continue;let a=this.hooks.get(n.event)||[];a.push({name:n.name||`${n.event}:${a.length+1}`,matcher:n.matcher||"*",command:n.command,timeoutMs:tl(n.timeoutMs||this.config.hooks.timeoutMs),continueOnError:n.continueOnError!==!1}),this.hooks.set(n.event,a)}this.logger?.info("hooks loaded",{count:e.length,enabledCount:this.listHooks().length})}listHooks(){return[...this.hooks.entries()].flatMap(([e,t])=>t.map(o=>({event:e,name:o.name,matcher:o.matcher,timeoutMs:o.timeoutMs,command:o.command})))}recentRuns(e=20){return this.lastRuns.slice(0,e)}async runPreToolUse({tool:e,toolCall:t}){let o=await this.run("PreToolUse",{tool:e,toolCallId:t.id,input:t.arguments||{},cwd:this.root});if(o.blocked)throw new qr(o.reason||`Hook blocked tool ${e.name}`,{toolName:e.name,hook:o.blockedBy});return o}async runPostToolUse({tool:e,toolCall:t,result:o,durationMs:n}){return this.run("PostToolUse",{tool:e,toolCallId:t.id,input:t.arguments||{},result:o,durationMs:n,cwd:this.root})}async runPostToolUseFailure({toolCall:e,error:t,durationMs:o}){return this.run("PostToolUseFailure",{tool:{name:e.name},toolCallId:e.id,input:e.arguments||{},error:{name:t.name,message:t.message,details:t.details},durationMs:o,cwd:this.root})}async runUserPromptSubmit({prompt:e,conversationId:t}={}){return this.run("UserPromptSubmit",{prompt:e,conversationId:t,cwd:this.root})}async runStop({content:e,conversationId:t}={}){return this.run("Stop",{content:e,conversationId:t,cwd:this.root})}async runSessionStart(e={}){return this.run("SessionStart",{...e,cwd:this.root})}async runSessionEnd(e={}){return this.run("SessionEnd",{...e,cwd:this.root})}async run(e,t={}){if(!this.config?.hooks?.enabled)return Nr();let o=(this.hooks.get(e)||[]).filter(a=>Qc(a,t.tool?.name));if(o.length===0)return Nr();let n=Nr();for(let a of o){let s=await this.executeHook(e,a,t);if(n.runs.push(s),s.output?.updatedInput&&typeof s.output.updatedInput=="object"&&(n.updatedInput={...n.updatedInput||{},...s.output.updatedInput}),s.output?.additionalContext&&n.additionalContext.push(String(s.output.additionalContext)),s.output?.continue===!1||s.output?.decision==="block"){n.blocked=!0,n.blockedBy=a.name,n.reason=s.output.stopReason||s.output.reason||`Hook ${a.name} bloqueou a acao.`;break}if(!s.ok&&!a.continueOnError){n.blocked=!0,n.blockedBy=a.name,n.reason=s.error||`Hook ${a.name} falhou.`;break}}return n}async executeHook(e,t,o){let n=performance.now(),a=el(t.command,{event:e,hook:t,payload:o,cwd:this.root}),s={event:e,hook:t.name,matcher:t.matcher,command:a,ok:!1,durationMs:0,output:null,stdout:"",stderr:"",error:null,createdAt:new Date().toISOString()};await this.eventBus?.emit("hook:start",{event:e,hook:t.name,toolName:o.tool?.name,command:a});try{let i=JSON.stringify({event:e,hook:t.name,tool:o.tool,toolCallId:o.toolCallId,input:o.input,result:o.result,error:o.error,durationMs:o.durationMs,prompt:o.prompt,content:o.content,conversationId:o.conversationId,cwd:this.root}),{stdout:c,stderr:l}=await Jc(a,{cwd:this.root,timeout:t.timeoutMs,maxBuffer:1024*1024,env:{...process.env,RIVALE_HOOK_EVENT:e,RIVALE_HOOK_NAME:t.name,RIVALE_HOOK_PAYLOAD:i}});s.ok=!0,s.stdout=String(c||"").trimEnd(),s.stderr=String(l||"").trimEnd(),s.output=Rn(s.stdout)}catch(i){s.ok=!1,s.stdout=String(i.stdout||"").trimEnd(),s.stderr=String(i.stderr||"").trimEnd(),s.error=i.killed?`Hook atingiu timeout de ${t.timeoutMs}ms.`:i.message,s.output=Rn(s.stdout)}return s.durationMs=Math.round(performance.now()-n),this.rememberRun(s),await this.eventBus?.emit(s.ok?"hook:end":"hook:error",{event:e,hook:t.name,toolName:o.tool?.name,durationMs:s.durationMs,ok:s.ok,error:s.error}),s}parseInlineConfig(){let e=this.config?.hooks?.inlineJson;if(!e)return null;try{return JSON.parse(e)}catch(t){return this.logger?.warn("invalid HOOKS_INLINE_JSON",{error:t.message}),null}}readFileConfig(){let e=this.config?.hooks?.configPath;if(!e)return null;let t=Ir.isAbsolute(e)?e:Ir.resolve(process.cwd(),e);if(!$n.existsSync(t))return null;try{return JSON.parse($n.readFileSync(t,"utf8"))}catch(o){return this.logger?.warn("invalid hooks config file",{path:t,error:o.message}),null}}rememberRun(e){this.lastRuns.unshift({event:e.event,hook:e.hook,ok:e.ok,durationMs:e.durationMs,error:e.error,createdAt:e.createdAt}),this.lastRuns=this.lastRuns.slice(0,50)}};function Nr(){return{runs:[],updatedInput:null,additionalContext:[],blocked:!1,blockedBy:null,reason:null}}function An(r){if(!r)return[];if(Array.isArray(r))return r;let e=r.hooks||r;if(Array.isArray(e))return e;let t=[];for(let[o,n]of Object.entries(e))if(Array.isArray(n))for(let a of n)t.push({...a,event:a.event||o});return t}function Qc(r,e=""){let t=String(r.matcher||"*").trim();if(!t||t==="*")return!0;for(let o of t.split(",").map(n=>n.trim()).filter(Boolean)){if(o===e||o.includes("*")&&new RegExp(`^${rl(o).replaceAll("\\*",".*")}$`).test(e))return!0;if(o.startsWith("/")&&o.endsWith("/"))try{if(new RegExp(o.slice(1,-1)).test(e))return!0}catch{}}return!1}function Rn(r){let e=String(r||"").trim();if(!e.startsWith("{"))return{};try{return JSON.parse(e)}catch{return{}}}var Zc=new Set(["event","cwd","hook.name"]);function el(r,e){return String(r||"").replace(/\{\{\s*([^}]+?)\s*\}\}/g,(t,o)=>{let n=String(o||"").trim();return n==="event"?e.event:n==="cwd"?e.cwd:n==="hook.name"?e.hook.name:(Zc.has(n),"")})}function tl(r){let e=Number(r);return Number.isFinite(e)?Math.min(Math.max(e,100),12e4):1e4}function rl(r){return String(r).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Cn=[{name:"researcher",title:"Ana (Pesquisadora)",description:"Pesquisa, compara fontes e resume informacoes externas ou documentacao.",tools:["web_search","http_request","memory_search","grep_search","glob_search","semantic_code_search","lsp_code","ast_search","skill_use","invoke_subagent","ask_human"],systemPrompt:["Voce e a Ana, a Research Agent.","Seu trabalho e pesquisar, comparar fontes e entregar um resumo util ao Supervisor.","Nao escreva arquivos. Nao execute acoes destrutivas.","Quando usar fontes externas, cite URLs retornadas pelas ferramentas.","Entregue conclusoes, riscos e proximos passos objetivos.","Use invoke_subagent para pedir ajuda a colegas (ex: Lucas) se precisar. Use ask_human se precisar de uma decisao do usuario."].join(`
253
+ `)},{name:"coder",title:"Lucas (Programador)",preferStrong:!0,description:"Cria e altera arquivos de codigo dentro do diretorio permitido.",tools:["file_list","file_read","file_mkdir","file_write","file_edit","file_copy","memory_search","grep_search","glob_search","semantic_code_search","lsp_code","ast_search","index_codebase","run_command","skill_use","todo_write","task_create","task_update","task_list","invoke_subagent","ask_human"],systemPrompt:["Voce e o Lucas, o Coder Agent.","Seu trabalho e implementar codigo limpo, modular e coerente com o projeto.","PADRAO DE IDIOMA NO CODIGO (OBRIGATORIO): nomes de funcoes, variaveis, classes, metodos, arquivos, chaves de objeto/JSON e identificadores devem SEMPRE seguir o padrao em INGLES (ex: getUser, isActive, calculateTotal, userList), mesmo que a conversa e o usuario estejam em portugues. NUNCA nomeie identificadores em portugues por conta propria (ex: pegarUsuario, estaAtivo, listaDeUsuarios) \u2014 isso quebra a convencao. So use portugues em identificadores se o usuario pedir EXPLICITAMENTE.","Comentarios, textos de log, mensagens de UI e strings voltadas ao usuario final PODEM ficar em portugues (ou no idioma do projeto). O padrao ingles vale para os NOMES no codigo, nao para o conteudo textual.","Se o projeto existente ja usa um padrao (ingles ou portugues), siga o padrao do projeto para manter consistencia.","Antes de refatoracoes ou tarefas especializadas, use skill_use se houver skill relevante.","Use lsp_code, glob_search, grep_search e ast_search para encontrar arquivos/funcoes, e file_read para entender arquivos existentes.","Use file_edit para alterar arquivos existentes com seguranca. Use file_write para criar arquivos novos ou sobrescrever apenas depois de ler o arquivo.","T\xC9CNICA DE REFATORA\xC7\xC3O DE GRANDES ARQUIVOS: Se o usuario pedir para CRIAR UMA C\xD3PIA de um arquivo grande e refator\xE1-lo, NUNCA tente escrever o novo arquivo inteiro de uma vez com file_write (voce batera no limite de tokens). Em vez disso, use a ferramenta 'file_copy' para duplicar o arquivo primeiro, e depois use 'file_edit' no novo arquivo para fazer as alteracoes progressivamente.","Nunca use caminhos fora do diretorio permitido.","Entregue uma lista dos arquivos criados/alterados e observacoes de implementacao.","IMPORTANTE: NUNCA use placeholders como '// ...' ou '// codigo existente' por preguica. O codigo gerado DEVE ser 100% completo, caso contrario voce quebrara a aplicacao.","SE UMA FERRAMENTA COMO file_write OU file_edit FALHAR (ex: erro de permissao, caminho fora da raiz), VOCE DEVE LER O ERRO, CORRIGIR O CAMINHO E TENTAR NOVAMENTE. NUNCA 'desista' e jogue o codigo final no chat como resposta textual. VOCE \xC9 OBRIGADO A SALVAR O ARQUIVO NO DISCO.","CICLO DE VERIFICACAO (OBRIGATORIO): depois de escrever ou alterar codigo, EXECUTE a verificacao relevante com run_command \u2014 rode os testes (ex: 'bun test'/'npm test'), o build ou o proprio arquivo. LEIA a saida. Se houver erro ou teste falhando, corrija o codigo e rode de novo. Repita esse ciclo ate ficar verde ou ate esgotar as iteracoes.","DEFINICAO DE PRONTO: so relate sucesso ao Supervisor DEPOIS de ter verificado que roda/passa. Se nao conseguiu deixar verde, relate honestamente o que falta, o ultimo erro e o proximo passo \u2014 nao finja que terminou.","Trabalhe em passos pequenos e verificaveis (escreve -> testa -> corrige) em vez de um unico despejo gigante. Voce tem varias iteracoes de ferramentas para isso; use-as.","Se nao houver testes ainda e a tarefa pedir, crie um teste minimo que exercite o que voce implementou e rode-o.","Use invoke_subagent para pedir ajuda a colegas (ex: Camila) se precisar. Use ask_human antes de acoes muito destrutivas ou ambiguas."].join(`
254
+ `)},{name:"reviewer",title:"Camila (Revisora)",preferStrong:!0,description:"Revisa codigo, aponta bugs, inconsistencias, regressao e melhorias.",tools:["file_list","file_read","memory_search","grep_search","glob_search","lsp_code","ast_search","skill_use","invoke_subagent","ask_human"],systemPrompt:["Voce e a Camila, a Review Agent.","Seu trabalho e revisar codigo com foco em bugs, riscos, regressao e manutenibilidade.","Sinalize como problema qualquer identificador (funcao, variavel, classe, arquivo) nomeado em portugues quando o padrao do projeto e ingles (ex: 'pegarUsuario' deveria ser 'getUser'), a menos que o usuario tenha pedido portugues explicitamente. Nomes no codigo devem seguir a convencao em ingles; comentarios/strings ao usuario podem ficar em portugues.","Use lsp_code, grep_search e ast_search para navegar eficientemente no projeto.","Priorize achados concretos com arquivo/caminho quando possivel.","Nao altere arquivos. Entregue findings ordenados por severidade.","Use invoke_subagent para delegar correcoes ao Lucas. Use ask_human se precisar esclarecer regras com o usuario."].join(`
255
+ `)},{name:"security",title:"Marcos (Seguran\xE7a)",preferStrong:!0,description:"Analisa seguranca, permissoes, vazamento de dados e superficies de ataque.",tools:["file_list","file_read","http_request","memory_search","grep_search","glob_search","lsp_code","ast_search","skill_use","ask_human"],systemPrompt:["Voce e o Marcos, o Security Agent.","Seu trabalho e avaliar riscos de seguranca, validacao, permissoes e dados sensiveis.","Nao execute acoes destrutivas. Nao escreva arquivos.","Entregue vulnerabilidades, impacto, explorabilidade e mitigacoes praticas.","Use ask_human em caso de perigo critico ou falta de contexto de negocio."].join(`
256
+ `)},{name:"tester",title:"Julia (Testadora)",preferStrong:!0,description:"Valida comportamento, fluxos, paginas e resultados observaveis.",tools:["file_list","file_read","http_request","playwright_browser","memory_search","grep_search","glob_search","lsp_code","run_command","skill_use","task_create","task_update","task_list","ask_human"],systemPrompt:["Voce e a Julia, a Test Agent.","Seu trabalho e validar resultados observaveis e propor testes objetivos.","Use navegador apenas quando precisar inspecionar uma pagina real.","Nao altere arquivos. Entregue passos executados, resultado e falhas encontradas.","Use ask_human para perguntar ao usuario como testar algo manualmente se n\xE3o for possivel automatizar."].join(`
257
+ `)},{name:"memory",title:"Roberto (Bibliotec\xE1rio)",description:"Busca e salva fatos duraveis, preferencias e decisoes importantes.",tools:["memory_search","memory_save","skill_use","ask_human"],systemPrompt:["Voce e o Roberto, o Memory Agent.","Seu trabalho e recuperar e persistir memorias uteis para o Supervisor.","Salve apenas fatos duraveis, preferencias explicitas ou decisoes importantes.","Entregue o que encontrou, o que salvou e por que isso importa.","Use ask_human para esclarecer uma memoria confusa ou pedir contexto adicional."].join(`
258
+ `)},{name:"dreamer",title:"Sonhador (Background)",description:"Analisa o projeto silenciosamente e consolida memorias no banco de dados.",tools:["file_read","file_list","grep_search","ast_search","memory_save"],systemPrompt:["Voce e o AutoDream, o Agente Sonhador rodando em background.","Seu objetivo e explorar o repositorio silenciosamente, extrair insights de arquitetura, padroes e consolidar regras usando a ferramenta memory_save.","Voce nao deve interagir com o usuario, nem criar ou alterar nenhum codigo. Apenas explore e aprenda.","Revise arquivos chave ou recentes e crie memorias concisas."].join(`
259
+ `)},{name:"marketer",title:"Don (Marketing e Growth)",description:"Especialista em Marketing, SEO, Ads e Growth. Ajuda a analisar concorrentes, sugerir copys e tracionar o negocio.",tools:["seo_analyzer","keyword_research","ad_copy_generator","campaign_planner","utm_builder","ads_budget_calculator","landing_page_audit","playwright_browser","web_search","http_request","file_read","file_write","skill_use","memory_search","ask_human"],systemPrompt:["Voce e Don, o Especialista de Marketing, Ads e Growth.","Seu objetivo e ajudar a empresa a crescer.","Use keyword_research para mapear demanda, ad_copy_generator para copys, campaign_planner para estrategia, utm_builder para tracking, ads_budget_calculator para CPA/ROAS e landing_page_audit para CRO.","Voce pode analisar Landing Pages de concorrentes usando seo_analyzer ou playwright_browser, e extrair dores, copys e funis.","Crie textos persuasivos (frameworks AIDA, PAS, etc), analise metricas e sugira estrategias de tr\xE1fego (SEO, Facebook Ads, Google Ads).","Seja proativo e sempre oriente suas respostas para aumento de conversao e reducao de CPA (Custo por Aquisicao).","Use as skills disponiveis via skill_use se houverem playbooks de marketing da empresa."].join(`
260
+ `)},{name:"creator",title:"Ravi (Criador de Conteudo)",description:"Especialista em YouTube e video. Cria roteiros, ganchos, titulos, thumbnails e pacote de SEO para o canal.",tools:["youtube_script_generator","youtube_title_ideas","youtube_seo_pack","keyword_research","web_search","http_request","file_write","skill_use","memory_search","ask_human"],systemPrompt:["Voce e Ravi, o Content Creator Agent focado em YouTube.","Seu objetivo e transformar uma ideia em video pronto pra gravar: roteiro, gancho, titulo, thumbnail e SEO.","Use youtube_script_generator para montar o roteiro (gancho, blocos, falas, acao de tela, CTA), youtube_title_ideas para titulos/thumbnails e youtube_seo_pack para descricao, tags e capitulos.","Use keyword_research ou web_search quando precisar validar demanda ou entender o que ja existe sobre o tema.","Pense em retencao: gancho nos primeiros 5s, ritmo com cortes, uma unica CTA clara.","IMPORTANTE (etica): para temas de bug, falha ou seguranca de plataformas de terceiros, oriente demonstrar apenas em ambiente proprio ou escopo autorizado (bug bounty). Nunca incentive expor dados reais ou mostrar exploracao funcional; foque no comportamento visual e na correcao. Respeite o safetyNotice retornado pela tool.","Se o usuario quiser salvar o roteiro, use file_write para gravar um .md dentro do diretorio permitido.","Use ask_human quando faltar contexto (nicho, publico, formato) que muda o roteiro."].join(`
261
+ `)}];var wt=class{constructor({profiles:e=Cn}={}){this.agents=new Map;for(let t of e)this.register(t)}register(e){if(!e?.name||!e?.systemPrompt)throw new Error("Invalid subagent profile");return this.agents.set(e.name,e),this}get(e){return this.agents.get(e)||null}list(){return[...this.agents.values()]}describe(){return this.list().map(e=>`- ${e.name}: ${e.description}`).join(`
262
+ `)}};import{readdirSync as ol,readFileSync as nl}from"node:fs";import ve from"node:path";import al from"node:os";var sl=["file_read","file_list","grep_search","glob_search","semantic_code_search","lsp_code","ast_search","web_search","memory_search","ask_human"];function il(r,e){let{frontmatter:t,content:o}=pt(r),n=ve.basename(e,ve.extname(e)),a=String(t.name||n).trim(),s=o.trim();if(!a||!/^[a-zA-Z0-9_-]+$/.test(a))throw new Error(`nome de agente invalido: "${a}"`);if(!s)throw new Error("corpo vazio (o system prompt do agente e o corpo do markdown)");let i=cn(t.tools),c=String(t.model||"").toLowerCase(),l=/^(true|strong|forte)$/.test(String(t.preferStrong||"").toLowerCase())||c==="strong"||c==="forte";return{name:a,title:String(t.title||a).trim(),description:String(t.description||a).trim(),tools:i.length?i:[...sl],preferStrong:l,systemPrompt:s,source:"file",filePath:e}}function Ln(r,e){let t=[];try{t=ol(r,{withFileTypes:!0})}catch{return[]}let o=[];for(let n of t){if(!n.isFile()||!n.name.toLowerCase().endsWith(".md"))continue;let a=ve.join(r,n.name);try{o.push(il(nl(a,"utf8"),a))}catch(s){e?.warn?.(`[agents] ignorando ${a}: ${s.message}`)}}return o}function cl({fileRoot:r=".",logger:e}={}){let t=ve.join(al.homedir(),".rivale","agents"),o=ve.resolve(r,".rivale","agents"),n=new Map;for(let a of Ln(t,e))n.set(a.name,a);if(ve.resolve(o)!==ve.resolve(t))for(let a of Ln(o,e))n.set(a.name,a);return[...n.values()]}function On(r,{fileRoot:e=".",logger:t}={}){let o=cl({fileRoot:e,logger:t}),n=[];for(let a of o)try{r.register(a),n.push(a.name)}catch(s){t?.warn?.(`[agents] falha ao registrar "${a.name}": ${s.message}`)}return n.length&&t?.info?.(`[agents] customizados carregados: ${n.join(", ")}`),n}import{mkdir as dl,writeFile as ml}from"node:fs/promises";import Dn from"node:path";import{appendFile as ll,mkdir as ul}from"node:fs/promises";import Mn from"node:path";var St=class{constructor(e){this.storagePath=Mn.join(e.storage?.dataDir||e.storageDir||".ia_data","sidechains")}async record(e,t){try{await ul(this.storagePath,{recursive:!0});let o=Mn.join(this.storagePath,`${e}.jsonl`),n=t.map(a=>JSON.stringify({timestamp:new Date().toISOString(),...a})+`
263
+ `);await ll(o,n.join(""),"utf8")}catch(o){console.warn(`[SidechainStorage] Failed to record sidechain for ${e}: ${o.message}`)}}};var xt=class{constructor({config:e,llmManager:t,toolRegistry:o,toolRunner:n,subAgentRegistry:a,storage:s,eventBus:i,logger:c}={}){this.config=e,this.llmManager=t,this.toolRegistry=o,this.toolRunner=n,this.subAgentRegistry=a,this.storage=s,this.eventBus=i,this.logger=c,this.sidechainStorage=new St(e),this.activeRuns=new Map,this.parallelWriteLock=Promise.resolve()}async invoke({agentName:e,task:t,context:o="",expectedOutput:n="",parentMessages:a=[]},s={}){let i=this.subAgentRegistry.get(e);if(!i)throw new Error(`Unknown subagent: ${e}`);if(hl(`${t}
264
+ ${n}`)&&!i.tools.includes("file_write"))throw new Error(`O subagente "${e}" nao pode criar/editar arquivos (nao tem file_write). Para criar ou alterar arquivos/codigo, delegue para o 'coder'.`);let c=F(`subagent_${e}`),l=performance.now(),u=Dn.join(this.config.storage.dataDir,"subagents",`${c}.json`),m={runId:c,agentName:e,title:i.title,task:t,outputPath:u,cancelled:!1,startedAt:new Date().toISOString()};this.activeRuns.set(c,m),await jr(this.storage,{id:c,agentName:e,title:i.title,task:t,status:"running",outputPath:u});let f=await yt(this.config.tools.fileRoot),g=pl({profile:i,task:t,context:o,expectedOutput:n,config:this.config,rules:f,parentMessages:a}),w=this.getAllowedTools(i),y=[],b=this.resolveModelOverride(i);await this.eventBus?.emit("subagent:start",{runId:c,agentName:e,title:i.title,task:t,outputPath:u});try{for(let h=0;h<this.config.multiAgent.maxSubagentToolIterations;h+=1){qn(m);let A={messages:g,tools:w,temperature:this.config.multiAgent.temperature,maxTokens:this.config.multiAgent.maxTokens,...b,signal:s.signal,metadata:{subagent:!0,subagentName:i.title,runId:c,iteration:h}},M=s.stream&&s.onToken&&!s.parallel?await this.llmManager.stream({...A,onToken:s.onToken}):await this.llmManager.generate(A);if(M.toolCalls=fl(M.toolCalls||[],this.toolRegistry),!M.toolCalls.length){let P=ke(M.content,this.toolRegistry);M.content=P.cleanedContent,P.toolCalls.length&&(M.toolCalls=P.toolCalls)}if(g.push({role:"assistant",content:M.content||"",toolCalls:M.toolCalls||[],reasoningContent:M.reasoningContent}),!M.toolCalls?.length)return this.finish({runId:c,profile:i,task:t,content:M.content||"",toolResults:y,startedAt:l,messages:g,outputPath:u});for(let P of M.toolCalls){if(qn(m),!i.tools.includes(P.name)){let ce={toolCallId:P.id,name:P.name,ok:!1,error:{name:"SubAgentPermissionError",message:`Subagent ${e} is not allowed to use tool ${P.name}`}};y.push(ce),g.push(Pn(ce));continue}let Y=await this.executeSubagentTool(P,{...s,subagent:e,subagentRunId:c},!!s.parallel);y.push(Y),g.push(Pn(Y))}}g.push({role:"system",content:"Voce atingiu o limite de iteracoes de ferramentas. Gere um relatorio final conciso com os dados disponiveis."});let E={messages:g,tools:[],temperature:this.config.multiAgent.temperature,maxTokens:this.config.multiAgent.maxTokens,...b,signal:s.signal,metadata:{subagent:!0,subagentName:i.title,runId:c,final:!0}},k=s.stream&&s.onToken&&!s.parallel?await this.llmManager.stream({...E,onToken:s.onToken}):await this.llmManager.generate(E),R=ke(k.content||"",this.toolRegistry).cleanedContent;return this.finish({runId:c,profile:i,task:t,content:R,toolResults:y,startedAt:l,messages:g,outputPath:u})}catch(E){let k=m.cancelled?"cancelled":"failed",R={runId:c,agent:i.name,title:i.title,task:t,status:k,outputPath:u,error:E.message,toolResults:Nn(y)};throw await jr(this.storage,{id:c,agentName:e,title:i.title,task:t,status:k,outputPath:u,error:E.message,result:R}),await In(u,R),await this.eventBus?.emit("subagent:error",{runId:c,agentName:e,error:E.message}),E}finally{this.activeRuns.delete(c)}}async executeSubagentTool(e,t,o){let n=()=>this.toolRunner.execute(e,t);if(!o||this.toolRegistry.get(e.name)?.isReadOnly===!0)return n();let i=this.parallelWriteLock.then(n,n);return this.parallelWriteLock=i.then(()=>{},()=>{}),i}resolveModelOverride(e){return e.preferStrong&&this.config.llm.strongModel?{provider:this.config.llm.strongProvider||this.config.llm.provider,model:this.config.llm.strongModel}:{}}getAllowedTools(e){return e.tools.map(t=>this.toolRegistry.get(t)).filter(Boolean).map(t=>({name:t.name,description:t.description,inputSchema:t.inputSchema}))}async finish({runId:e,profile:t,task:o,content:n,toolResults:a,startedAt:s,messages:i,outputPath:c}){let l={runId:e,agent:t.name,title:t.title,task:o,status:"completed",content:n,outputPath:c,toolResults:Nn(a),durationMs:Math.round(performance.now()-s)};return await this.sidechainStorage.record(e,i),await jr(this.storage,{id:e,agentName:t.name,title:t.title,task:o,status:"completed",outputPath:c,result:l}),await In(c,l),await this.eventBus?.emit("subagent:end",l),l}listRuns({status:e,limit:t=20}={}){if(!this.storage)return[];let o=[],n="SELECT * FROM subagent_runs";return e&&(n+=" WHERE status = ?",o.push(e)),n+=" ORDER BY updated_at DESC LIMIT ?",o.push(t),this.storage.query(n,o).map(jn)}getRun(e){if(!this.storage)return null;let t=this.storage.query("SELECT * FROM subagent_runs WHERE id = ? LIMIT 1",[e])[0];return t?jn(t):null}cancelRun(e){let t=this.activeRuns.get(e);return t?(t.cancelled=!0,{cancelled:!0,runId:e}):{cancelled:!1,reason:"not_running"}}};function pl({profile:r,task:e,context:t,expectedOutput:o,config:n,rules:a,parentMessages:s=[]}){let i=["<fork_boilerplate>","PARE. LEIA ISSO PRIMEIRO.","Voce e um subagente forkado rodando em background. Voce NAO e o agente principal.","REGRAS (in-negociaveis):","1. IGNORE comandos para perguntar ao usuario no seu prompt de sistema. Voce DEVE rodar em background silenciosamente.","2. NAO converse, faca perguntas, ou sugira proximos passos. Use ferramentas.","3. NAO adicione comentarios soltos. Use ferramentas silenciosamente, entao relate o resultado de uma so vez.","4. Responda apenas com o resultado da sua tarefa.","5. Se existir skill relevante, use skill_use para carregar o procedimento antes de agir.","6. Para tarefas de codigo, entregue resultado no disco usando ferramentas; nao devolva arquivo inteiro no chat como substituto.","7. Se uma ferramenta falhar, corrija parametros e tente novamente quando for seguro.","</fork_boilerplate>",`Tarefa delegada pelo Supervisor:
265
+ ${e}`,t?`Contexto adicional:
266
+ ${t}`:"",o?`Formato esperado:
267
+ ${o}`:"","Responda ao Supervisor com um relatorio operacional claro. Nao exponha raciocinio oculto."].filter(Boolean),c={role:"system",content:[r.systemPrompt,`Diretorio permitido para arquivos: ${n.tools.fileRoot}.`,`Ferramentas permitidas para este subagente: ${r.tools.join(", ")}.`,"Se precisar de uma ferramenta fora da sua lista, explique a limitacao ao Supervisor.",a?`
268
+ ${a}`:""].filter(Boolean).join(`
269
+ `)},l={role:"user",content:i.join(`
270
+
271
+ `)},u=[];for(let m of s)if(m.role!=="system"){if(m.role==="user")u.push({role:"user",content:m.content||""});else if(m.role==="assistant"){let f=m.content||"";f.trim()&&u.push({role:"assistant",content:f})}}return u.unshift(c),u.push(l),u}function Pn(r){return{role:"tool",toolCallId:r.toolCallId,name:r.name,content:JSON.stringify(r.ok?r.result:{error:r.error})}}function fl(r,e){return r.map(t=>{if(!t?.name||e.get(t.name))return t;let o=String(t.name).match(/^([a-zA-Z0-9_-]+)(\{.*\})$/);if(!o)return t;let[,n,a]=o;return e.get(n)?{...t,name:n,arguments:{...Un(a,{}),...t.arguments||{}}}:t})}async function jr(r,{id:e,agentName:t,title:o,task:n,status:a,outputPath:s,result:i={},error:c=null}){if(!r)return;let l=new Date().toISOString();if(r.query("SELECT id FROM subagent_runs WHERE id = ?",[e])[0]){r.run(`UPDATE subagent_runs
272
+ SET status = ?, output_path = ?, result_json = ?, error = ?, updated_at = ?,
273
+ completed_at = CASE WHEN ? IN ('completed', 'failed', 'cancelled') THEN ? ELSE completed_at END
274
+ WHERE id = ?`,[a,s,JSON.stringify(i||{}),c,l,a,l,e]);return}r.run(`INSERT INTO subagent_runs
275
+ (id, agent_name, title, task, status, output_path, result_json, error, started_at, updated_at, completed_at)
276
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[e,t,o,n,a,s,JSON.stringify(i||{}),c,l,l,["completed","failed","cancelled"].includes(a)?l:null])}async function In(r,e){r&&(await dl(Dn.dirname(r),{recursive:!0}),await ml(r,JSON.stringify(e,null,2),"utf8"))}function Nn(r){return r.map(e=>({name:e.name,ok:e.ok,durationMs:e.durationMs,error:e.error?.message}))}function hl(r){let e=String(r||"").toLowerCase(),t=/\b(cri[ae]|escrev|salv|ger[ae]|edit|implement|adicion[ae]|refator)/.test(e),o=/(arquivo|\bfile\b|file_write|filewrite|\.(js|mjs|cjs|ts|tsx|jsx|json|py|go|rs|java|css|scss|html|md|vue|svelte))\b/.test(e);return t&&o}function qn(r){if(r.cancelled)throw new Error(`Subagent ${r.runId} was cancelled`)}function jn(r){return{id:r.id,agentName:r.agent_name,title:r.title,task:r.task,status:r.status,outputPath:r.output_path,result:Un(r.result_json,{}),error:r.error,startedAt:r.started_at,updatedAt:r.updated_at,completedAt:r.completed_at}}function Un(r,e){try{return JSON.parse(r)}catch{return{_malformed_json:!0,_raw:r}}}import Gr from"node:path";import Ce from"node:path";import zn from"node:fs";import{existsSync as Tt,readFileSync as gl}from"node:fs";import te from"node:path";import{fileURLToPath as yl}from"node:url";var Xe=null;try{Xe=te.resolve(te.dirname(yl(import.meta.url)),"..")}catch{Xe=null}var Dr=new Map;function bl(r){if(Dr.has(r))return Dr.get(r);let e=!1;try{let t=te.join(r,"package.json");Tt(t)&&JSON.parse(gl(t,"utf8"))?.name==="rivale"&&Tt(te.join(r,"dist","cli.js"))&&!Tt(te.join(r,"src"))&&(e=!0)}catch{e=!1}return Dr.set(r,e),e}function vl(r,e){if(!r)return!1;let t=te.relative(r,e);return t===""||!t.startsWith("..")&&!te.isAbsolute(t)}function wl(r){let e;try{e=te.resolve(r)}catch{return!1}if(Xe&&!Tt(te.join(Xe,"src"))&&vl(Xe,e))return!0;let t=te.dirname(e);for(let o=0;o<10;o+=1){if(bl(t))return!0;let n=te.dirname(t);if(n===t)break;t=n}return!1}var Sl="Acesso bloqueado: este \xE9 o pacote distribu\xEDdo do Rivale (c\xF3digo propriet\xE1rio e minificado). O Rivale n\xE3o l\xEA, edita, busca nem faz engenharia reversa do pr\xF3prio artefato publicado.";function Ur(r){if(wl(r)){let e=new Error(Sl);throw e.name="SelfProtectionError",e}}function I(r,e){let t=Ce.resolve(r),o=Ce.resolve(t,e);Fn(t,o,e);let n=Bn(t)||t,a=xl(o),s=Bn(a)||a;return Fn(n,s,e),Ur(o),Ur(s),o}function Hn(r,e){return Et(Ce.resolve(r))===Et(Ce.resolve(e))}function Fn(r,e,t){let o=Et(r),n=Et(e);if(n!==o&&!n.startsWith(`${o}${Ce.sep}`))throw new Error(`Path escapes allowed root. Allowed root: ${r}. Requested: ${t}. Resolved: ${e}`)}function xl(r){let e=r;for(;!zn.existsSync(e);){let t=Ce.dirname(e);if(t===e)break;e=t}return e}function Bn(r){try{return zn.realpathSync.native(r)}catch{return null}}function Et(r){return process.platform==="win32"?r.toLowerCase():r}import{spawn as _l}from"node:child_process";import{readFile as kl}from"node:fs/promises";import zr from"node:path";import Fr from"node:path";import{fileURLToPath as Tl,pathToFileURL as El}from"node:url";function _t(r){return El(Fr.resolve(r)).href}function Br(r){return r?r.startsWith("file://")?Tl(r):r:""}function Gn(r){let e=Fr.extname(r).toLowerCase();return Fr.basename(r).toLowerCase()==="package.json"?"json":e===".js"||e===".mjs"||e===".cjs"?"javascript":e===".jsx"?"javascriptreact":e===".ts"||e===".mts"||e===".cts"?"typescript":e===".tsx"?"typescriptreact":e===".json"?"json":e===".css"?"css":e===".html"||e===".htm"?"html":e===".md"?"markdown":e===".py"?"python":e===".go"?"go":e===".rs"?"rust":"plaintext"}var kt=class{constructor({command:e,args:t=[],root:o,timeoutMs:n=8e3,logger:a}={}){this.command=e,this.args=t,this.root=zr.resolve(o||"."),this.timeoutMs=n,this.logger=a,this.process=null,this.nextId=1,this.pending=new Map,this.opened=new Set,this.diagnostics=new Map,this.buffer=Buffer.alloc(0),this.initialized=!1}async start(){if(!this.initialized){if(!this.command)throw new Error("LSP command is not configured.");this.process=_l(this.command,this.args,{cwd:this.root,stdio:["pipe","pipe","pipe"]}),this.process.stdout.on("data",e=>this.onData(e)),this.process.stderr.on("data",e=>{let t=String(e||"").trim();t&&this.logger?.debug("lsp stderr",{text:t})}),this.process.on("exit",(e,t)=>{this.initialized=!1;let o=new Error(`LSP server exited with code ${e??"null"} signal ${t??"null"}`);for(let n of this.pending.values())clearTimeout(n.timer),n.reject(o);this.pending.clear()}),await this.request("initialize",{processId:process.pid,rootPath:this.root,rootUri:_t(this.root),capabilities:{textDocument:{synchronization:{didSave:!0,dynamicRegistration:!1},definition:{dynamicRegistration:!1},references:{dynamicRegistration:!1},hover:{dynamicRegistration:!1},documentSymbol:{dynamicRegistration:!1},callHierarchy:{dynamicRegistration:!1}},workspace:{symbol:{dynamicRegistration:!1},workspaceFolders:!0}},workspaceFolders:[{name:zr.basename(this.root),uri:_t(this.root)}]}),this.notify("initialized",{}),this.initialized=!0}}async stop(){if(this.process)try{await this.request("shutdown",null,1500).catch(()=>null),this.notify("exit",{})}finally{this.process.kill(),this.process=null,this.initialized=!1,this.opened.clear()}}async ensureDocumentOpen(e){await this.start();let t=zr.resolve(e),o=_t(t);if(this.opened.has(o))return o;let n=await kl(t,"utf8");return this.notify("textDocument/didOpen",{textDocument:{uri:o,languageId:Gn(t),version:1,text:n}}),this.opened.add(o),o}async documentSymbols(e){let t=await this.ensureDocumentOpen(e);return this.request("textDocument/documentSymbol",{textDocument:{uri:t}})}async workspaceSymbols(e){return await this.start(),this.request("workspace/symbol",{query:e||""})}async definition({filePath:e,line:t,character:o}){let n=await this.ensureDocumentOpen(e);return this.request("textDocument/definition",{textDocument:{uri:n},position:Hr(t,o)})}async references({filePath:e,line:t,character:o,includeDeclaration:n=!0}){let a=await this.ensureDocumentOpen(e);return this.request("textDocument/references",{textDocument:{uri:a},position:Hr(t,o),context:{includeDeclaration:n}})}async hover({filePath:e,line:t,character:o}){let n=await this.ensureDocumentOpen(e);return this.request("textDocument/hover",{textDocument:{uri:n},position:Hr(t,o)})}async getDiagnostics(e){let t=await this.ensureDocumentOpen(e);return await new Promise(o=>setTimeout(o,250)),this.diagnostics.get(t)||[]}request(e,t,o=this.timeoutMs){if(!this.process?.stdin?.writable)throw new Error("LSP server is not running.");let n=this.nextId++,s=JSON.stringify({jsonrpc:"2.0",id:n,method:e,params:t});return new Promise((i,c)=>{let l=setTimeout(()=>{this.pending.delete(n),c(new Error(`LSP request timed out: ${e}`))},o);this.pending.set(n,{resolve:i,reject:c,timer:l,method:e}),this.write(s)})}notify(e,t){this.process?.stdin?.writable&&this.write(JSON.stringify({jsonrpc:"2.0",method:e,params:t}))}write(e){let t=Buffer.byteLength(e,"utf8");this.process.stdin.write(`Content-Length: ${t}\r
277
+ \r
278
+ ${e}`)}onData(e){for(this.buffer=Buffer.concat([this.buffer,e]);;){let t=this.buffer.indexOf(`\r
279
+ \r
280
+ `);if(t===-1)return;let n=this.buffer.slice(0,t).toString("utf8").match(/Content-Length:\s*(\d+)/i);if(!n){this.buffer=this.buffer.slice(t+4);continue}let a=Number(n[1]),s=t+4,i=s+a;if(this.buffer.length<i)return;let c=this.buffer.slice(s,i).toString("utf8");this.buffer=this.buffer.slice(i),this.handleMessage(c)}}handleMessage(e){let t;try{t=JSON.parse(e)}catch(n){this.logger?.warn("invalid lsp message",{error:n.message});return}if(t.method==="textDocument/publishDiagnostics"){this.diagnostics.set(t.params?.uri,t.params?.diagnostics||[]);return}if(t.id===void 0)return;let o=this.pending.get(t.id);if(o){if(clearTimeout(o.timer),this.pending.delete(t.id),t.error){o.reject(new Error(t.error.message||`${o.method} failed`));return}o.resolve(t.result)}}};function Hr(r,e){return{line:Math.max(0,Number(r||1)-1),character:Math.max(0,Number(e||1)-1)}}import{readdir as $l,readFile as $t,stat as Al}from"node:fs/promises";import ue from"node:path";var Rl=new Set([".js",".jsx",".mjs",".cjs",".ts",".tsx",".mts",".cts"]),Wn=new Set([".git",".next",".turbo",".vercel","coverage","dist","build","node_modules","out"]),Vn=2500,Cl=1024*1024,At=class{constructor({root:e,logger:t}={}){this.root=ue.resolve(e||"."),this.logger=t,this.cache=null,this.cacheCreatedAt=0,this.cacheTtlMs=15e3}async documentSymbols(e){let t=ue.resolve(e),o=await $t(t,"utf8");return Kn({content:o,filePath:t,root:this.root})}async workspaceSymbols(e="",{maxResults:t=50}={}){let o=await this.getIndex(),n=String(e||"").toLowerCase();return o.symbols.filter(a=>!n||a.name.toLowerCase().includes(n)).slice(0,t)}async definition({filePath:e,line:t,character:o,query:n,maxResults:a=20}){let s=n||await this.identifierAt(e,t,o);return s?(await this.getIndex()).symbols.filter(c=>c.name===s).slice(0,a):[]}async references({filePath:e,line:t,character:o,query:n,maxResults:a=80}){let s=n||await this.identifierAt(e,t,o);if(!s)return[];let i=await this.getFiles(),c=new RegExp(`\\b${Ol(s)}\\b`,"g"),l=[];for(let u of i){let m="";try{m=await $t(u,"utf8")}catch{continue}let f=m.split(/\r?\n/);for(let g=0;g<f.length;g+=1){c.lastIndex=0;let w=c.exec(f[g]);if(w&&(l.push({filePath:u,relativePath:ue.relative(this.root,u)||ue.basename(u),line:g+1,character:w.index+1,preview:f[g].trim()}),l.length>=a))return l}}return l}async hover({filePath:e,line:t,character:o,query:n}){let a=n||await this.identifierAt(e,t,o);if(!a)return{text:"Nenhum identificador encontrado nessa posicao.",symbol:null};let s=await this.definition({filePath:e,line:t,character:o,query:a,maxResults:3});return s.length===0?{text:`Identificador: ${a}. Nenhuma definicao encontrada pelo fallback estatico.`,symbol:a}:{text:s.map(i=>`${i.kind} ${i.name} em ${i.relativePath}:${i.line}
281
+ ${i.preview}`).join(`
282
+
283
+ `),symbol:a,definitions:s}}async identifierAt(e,t,o){if(!e||!t||!o)return"";let s=(await $t(ue.resolve(e),"utf8")).split(/\r?\n/)[Math.max(0,Number(t)-1)]||"";return Ll(s,Math.max(0,Number(o)-1))}async getIndex(){let e=Date.now();if(this.cache&&e-this.cacheCreatedAt<this.cacheTtlMs)return this.cache;let t=await this.getFiles(),o=[];for(let n of t)try{let a=await $t(n,"utf8");o.push(...Kn({content:a,filePath:n,root:this.root}))}catch(a){this.logger?.debug("static code index skipped file",{file:n,error:a.message})}return this.cache={files:t,symbols:o},this.cacheCreatedAt=e,this.cache}async getFiles(){let e=[];return await Xn(this.root,e),e}};async function Xn(r,e){if(e.length>=Vn)return;let t=[];try{t=await $l(r,{withFileTypes:!0})}catch{return}for(let o of t){if(e.length>=Vn)return;if(o.name.startsWith(".")&&o.name!==".env"&&o.isDirectory()&&Wn.has(o.name))continue;let n=ue.join(r,o.name);if(o.isDirectory()){if(Wn.has(o.name))continue;await Xn(n,e);continue}if(o.isFile()&&Rl.has(ue.extname(o.name).toLowerCase()))try{if((await Al(n)).size>Cl)continue;e.push(n)}catch{}}}function Kn({content:r,filePath:e,root:t}){let o=String(r||"").split(/\r?\n/),n=[],a=[{kind:"class",regex:/^\s*(?:export\s+)?(?:default\s+)?class\s+([A-Za-z_$][\w$]*)/},{kind:"function",regex:/^\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/},{kind:"function",regex:/^\s*(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:async\s*)?(?:function\b|\([^)]*\)\s*=>|[A-Za-z_$][\w$]*\s*=>)/},{kind:"method",regex:/^\s*(?:async\s+)?([A-Za-z_$][\w$]*)\s*\([^)]*\)\s*\{/}];for(let s=0;s<o.length;s+=1){let i=o[s];for(let c of a){let l=i.match(c.regex);if(l?.[1]&&!["if","for","while","switch","catch","function"].includes(l[1])){n.push({name:l[1],kind:c.kind,filePath:e,relativePath:ue.relative(t,e)||ue.basename(e),line:s+1,character:Math.max(1,i.indexOf(l[1])+1),preview:i.trim()});break}}}return n}function Ll(r,e){let t=String(r||"");if(!t)return"";let o=Math.min(e,t.length-1);for(;o>0&&/[\w$]/.test(t[o-1]);)o-=1;let n=Math.max(e,0);for(;n<t.length&&/[\w$]/.test(t[n]);)n+=1;let a=t.slice(o,n);return/^[A-Za-z_$][\w$]*$/.test(a)?a:""}function Ol(r){return String(r).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Ct=class{constructor({config:e,logger:t}={}){this.config=e,this.logger=t,this.root=Gr.resolve(e?.tools?.fileRoot||"."),this.staticIndex=new At({root:this.root,logger:t}),this.client=null,this.lastError=null}status(){return{configured:this.isConfigured(),enabled:!!this.config?.lsp?.enabled,command:this.config?.lsp?.command||null,args:this.config?.lsp?.args||[],fallbackEnabled:!!this.config?.lsp?.fallbackEnabled,root:this.root,initialized:!!this.client?.initialized,lastError:this.lastError?.message||null}}async stop(){await this.client?.stop(),this.client=null}async run(e){let t=e.operation;if(t==="status")return this.status();let o=this.normalizeInput(e),n=this.isConfigured()&&Ml(t,o),a=this.isConfigured()&&!n;if(n)try{let s=await this.runWithLsp(t,o);return this.lastError=null,{provider:"lsp",operation:t,result:s}}catch(s){if(this.lastError=s,this.logger?.warn("lsp operation failed; falling back",{operation:t,error:s.message}),!this.config.lsp.fallbackEnabled)throw s}return{provider:"static-fallback",operation:t,warning:a?"Operacao por query usa fallback estatico; LSP real precisa de line e character.":this.isConfigured()?`Servidor LSP falhou: ${this.lastError?.message||"erro desconhecido"}`:"Servidor LSP nao configurado; usando fallback estatico para JS/TS.",result:await this.runFallback(t,o)}}isConfigured(){return!!(this.config?.lsp?.enabled&&this.config?.lsp?.command)}getClient(){return this.client||(this.client=new kt({command:this.config.lsp.command,args:this.config.lsp.args,root:this.root,timeoutMs:this.config.lsp.timeoutMs,logger:this.logger})),this.client}normalizeInput(e){let t={...e};return t.filePath&&(t.filePath=I(this.root,t.filePath)),t.maxResults=Math.min(Math.max(Number(t.maxResults||50),1),200),t}async runWithLsp(e,t){let o=this.getClient();if(e==="documentSymbols")return Pl(await o.documentSymbols(Rt(t)));if(e==="workspaceSymbols")return Il(await o.workspaceSymbols(t.query||""),this.root,t.maxResults);if(e==="definition")return Yn(await o.definition(Le(t)),this.root,t.maxResults);if(e==="references")return Yn(await o.references(Le(t)),this.root,t.maxResults);if(e==="hover")return Nl(await o.hover(Le(t)));if(e==="diagnostics")return ql(await o.getDiagnostics(Rt(t)));throw new Error(`Unsupported LSP operation: ${e}`)}async runFallback(e,t){if(e==="documentSymbols")return this.staticIndex.documentSymbols(Rt(t));if(e==="workspaceSymbols")return this.staticIndex.workspaceSymbols(t.query||"",{maxResults:t.maxResults});if(e==="definition")return this.staticIndex.definition(Le(t));if(e==="references")return this.staticIndex.references(Le(t));if(e==="hover")return this.staticIndex.hover(Le(t));if(e==="diagnostics")return{diagnostics:[],note:"Diagnosticos precisam de um servidor LSP real configurado."};throw new Error(`Unsupported code intelligence operation: ${e}`)}};function Rt(r){if(!r.filePath)throw new Error("filePath e obrigatorio para esta operacao.");return r.filePath}function Le(r){if(Rt(r),!r.query&&(!r.line||!r.character))throw new Error("Informe line e character, ou query para fallback estatico.");return r}function Ml(r,e){return["definition","references","hover"].includes(r)?!!(e.filePath&&e.line&&e.character):!0}function Pl(r){let e=[];for(let t of Array.isArray(r)?r:[])Qn(t,e);return e}function Qn(r,e,t=""){let n=(r.selectionRange||r.range||{}).start||{},a=t?`${t}.${r.name}`:r.name;e.push({name:a,kind:Zn(r.kind),line:Number(n.line||0)+1,character:Number(n.character||0)+1,detail:r.detail||""});for(let s of r.children||[])Qn(s,e,a)}function Il(r,e,t){return(Array.isArray(r)?r:[]).slice(0,t).map(o=>{let n=o.location||{},a=Br(n.uri),s=n.range?.start||{};return{name:o.name,kind:Zn(o.kind),filePath:a,relativePath:Gr.relative(e,a)||a,line:Number(s.line||0)+1,character:Number(s.character||0)+1,containerName:o.containerName||""}})}function Yn(r,e,t){return(Array.isArray(r)?r:r?[r]:[]).slice(0,t).map(n=>{let a=n.uri||n.targetUri,i=(n.range||n.targetSelectionRange||n.targetRange||{}).start||{},c=Br(a);return{filePath:c,relativePath:Gr.relative(e,c)||c,line:Number(i.line||0)+1,character:Number(i.character||0)+1}})}function Nl(r){if(!r)return{text:""};let e=r.contents;return typeof e=="string"?{text:e}:Array.isArray(e)?{text:e.map(Jn).filter(Boolean).join(`
284
+ `)}:e?.kind&&e?.value?{text:e.value,kind:e.kind}:{text:Jn(e)}}function Jn(r){return r?typeof r=="string"?r:typeof r.value=="string"?r.value:"":""}function ql(r){return{diagnostics:(Array.isArray(r)?r:[]).map(e=>({severity:jl(e.severity),message:e.message,source:e.source||"",code:e.code||"",line:Number(e.range?.start?.line||0)+1,character:Number(e.range?.start?.character||0)+1}))}}function Zn(r){return{1:"file",2:"module",3:"namespace",4:"package",5:"class",6:"method",7:"property",8:"field",9:"constructor",10:"enum",11:"interface",12:"function",13:"variable",14:"constant"}[r]||String(r||"unknown")}function jl(r){return r===1?"error":r===2?"warning":r===3?"info":r===4?"hint":"unknown"}async function Ye(r,{attempts:e=1,delayMs:t=400,shouldRetry:o=Dl}={}){let n;for(let a=0;a<=e;a+=1)try{return await r(a)}catch(s){if(n=s,a>=e||!o(s))break;let i=t*2**a;if(s.retryAfter){let c=parseFloat(s.retryAfter);isNaN(c)||(i=Math.max(i,c*1e3+200))}s.retryAfterMs&&Number.isFinite(s.retryAfterMs)&&(i=Math.max(i,s.retryAfterMs+200)),await Ul(i)}throw n}function Dl(r){return!(!r||r.name==="AbortError"||r.name==="ValidationError"||r.status&&r.status<500&&r.status!==429)}function Ul(r){return new Promise(e=>setTimeout(e,r))}function ea(r=[]){return r.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.inputSchema||{type:"object",properties:{}}}}))}function ta(r=[]){return r.map(e=>{if(e.role==="assistant"&&e.toolCalls?.length)return{role:"assistant",content:e.content||null,...e.reasoningContent?{reasoning_content:e.reasoningContent}:{},tool_calls:e.toolCalls.map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.arguments||{})}}))};if(e.role==="tool")return{role:"tool",tool_call_id:e.toolCallId||e.tool_call_id,content:Q(e.content)};if(e.images?.length){let o=[{type:"text",text:Q(e.content)}];for(let n of e.images)o.push({type:"image_url",image_url:{url:`data:${n.mimeType||"image/png"};base64,${n.data}`}});return{role:e.role,content:o}}let t={role:e.role,content:Q(e.content)};return e.role==="assistant"&&e.reasoningContent&&(t.reasoning_content=e.reasoningContent),t})}function ra(r,{provider:e="",model:t=""}={}){return!/deepseek/i.test(e)||!(/reasoner|thinking|v4/i.test(t)||r.some(n=>n.role==="assistant"&&n.reasoning_content))?r:r.map(n=>n.role==="assistant"&&Array.isArray(n.tool_calls)&&n.tool_calls.length>0&&!n.reasoning_content?{...n,reasoning_content:"(sem raciocinio explicito)"}:n)}function oa(r){let e=r.choices?.[0]?.message||{};return{content:e.content||"",reasoningContent:e.reasoning_content||void 0,toolCalls:(e.tool_calls||[]).map(t=>({id:t.id||F("toolcall"),name:t.function?.name,arguments:Lt(t.function?.arguments,{})})),usage:we(r.usage),raw:r}}function we(r={}){let e=r.prompt_tokens??r.input_tokens??r.promptTokenCount??0,t=r.completion_tokens??r.output_tokens??r.candidatesTokenCount??0,o=r.prompt_tokens_details?.cached_tokens??r.cache_read_input_tokens??r.cachedContentTokenCount??0;return{inputTokens:e,outputTokens:t,cachedTokens:o,totalTokens:r.total_tokens??r.totalTokenCount??e+t}}function Q(r){return r==null?"":typeof r=="string"?r:JSON.stringify(r)}function Lt(r,e=null){if(r==null||r==="")return e;if(typeof r=="object")return r;try{return JSON.parse(r)}catch{return{_malformed_json:!0,_raw:r}}}var ae=class{constructor({name:e,apiKey:t,baseUrl:o,model:n,defaultHeaders:a={}}={}){this.name=e,this.apiKey=t,this.baseUrl=o?.replace(/\/$/,""),this.model=n,this.defaultHeaders=a}async generate({messages:e,tools:t=[],temperature:o,maxTokens:n,signal:a}){this.assertConfigured();let s=this.buildBody({messages:e,tools:t,temperature:o,maxTokens:n}),i=await fetch(`${this.baseUrl}/chat/completions`,{method:"POST",signal:a,headers:{"content-type":"application/json",authorization:`Bearer ${this.apiKey}`,...this.defaultHeaders},body:JSON.stringify(s)}),c=await i.json().catch(()=>({}));if(!i.ok){let l=new Error(c.error?.message||`${this.name} request failed`);throw l.status=i.status,l.provider=this.name,l.body=c,l.retryAfter=i.headers.get("retry-after")||c.error?.retry_after||null,l}return oa(c)}async stream({messages:e,tools:t=[],temperature:o,maxTokens:n,signal:a,onToken:s}){this.assertConfigured();let i={...this.buildBody({messages:e,tools:t,temperature:o,maxTokens:n}),stream:!0,stream_options:{include_usage:!0}},c=await fetch(`${this.baseUrl}/chat/completions`,{method:"POST",signal:a,headers:{"content-type":"application/json",authorization:`Bearer ${this.apiKey}`,...this.defaultHeaders},body:JSON.stringify(i)});if(!c.ok){let l=await c.json().catch(()=>({})),u=new Error(l.error?.message||`${this.name} stream request failed`);throw u.status=c.status,u.provider=this.name,u.body=l,u.retryAfter=c.headers.get("retry-after")||l.error?.retry_after||null,u}if(!c.body)throw new Error(`${this.name} stream response did not include a body`);return Fl(c.body,s)}buildBody({messages:e,tools:t=[],temperature:o,maxTokens:n}){let a=/^(o1|o3|o2|gpt-5)/.test(this.model),s={model:this.model,messages:ra(ta(e),{provider:this.name,model:this.model}),temperature:o};return n!=null&&(a?s.max_completion_tokens=n:s.max_tokens=n),t.length>0&&(s.tools=ea(t),s.tool_choice="auto"),s}assertConfigured(){if(!this.apiKey)throw new Error(`Missing API key for provider ${this.name}`);if(!this.baseUrl)throw new Error(`Missing base URL for provider ${this.name}`)}};async function Fl(r,e){let t=new TextDecoder,o=r.getReader(),n="",a="",s="",i={},c=new Map;for(;;){let{value:f,done:g}=await o.read();if(g)break;n+=t.decode(f,{stream:!0});let w=n.split(/\r?\n/);n=w.pop()||"";for(let y of w)await na(y,{toolCalls:c,onToken:e,appendContent:l,appendReasoning:u,setUsage:m})}return n.trim()&&await na(n,{toolCalls:c,onToken:e,appendContent:l,appendReasoning:u,setUsage:m}),{content:a,reasoningContent:s||void 0,toolCalls:[...c.values()].filter(f=>f.name).map(f=>({id:f.id,name:f.name,arguments:Lt(f.argumentsText,{})})),usage:we(i),raw:null};function l(f){a+=f}function u(f){s+=f}function m(f){i=f}}async function na(r,{toolCalls:e,onToken:t,appendContent:o,appendReasoning:n,setUsage:a}){let s=r.trim();if(!s||!s.startsWith("data:"))return;let i=s.slice(5).trim();if(i==="[DONE]")return;let c=Lt(i,null);if(!c)return;c.usage&&a(c.usage);let l=c.choices?.[0]?.delta||{};l.reasoning_content&&n(l.reasoning_content),l.content&&(o(l.content),await t?.(l.content));for(let u of l.tool_calls||[]){let m=u.index??e.size,f=e.get(m)||{id:u.id||F("toolcall"),name:"",argumentsText:""};u.id&&(f.id=u.id),u.function?.name&&(f.name+=u.function.name),u.function?.arguments&&(f.argumentsText+=u.function.arguments),e.set(m,f)}}var Ot=class extends ae{constructor(e={}){super({...e,name:"groq"})}};var Mt=class extends ae{constructor(e={}){super({...e,name:"openai"})}};var Pt=class{constructor({apiKey:e,baseUrl:t,model:o}={}){this.name="anthropic",this.apiKey=e,this.baseUrl=t?.replace(/\/$/,""),this.model=o}async generate({messages:e,tools:t=[],temperature:o,maxTokens:n,signal:a}){this.assertConfigured();let{system:s,anthropicMessages:i}=zl(e),c={model:this.model,max_tokens:n,temperature:o,messages:Hl(i)};s&&(c.system=[{type:"text",text:s,cache_control:{type:"ephemeral"}}]),t.length>0&&(c.tools=Bl(t));let l=await fetch(`${this.baseUrl}/messages`,{method:"POST",signal:a,headers:{"content-type":"application/json","x-api-key":this.apiKey,"anthropic-version":"2023-06-01"},body:JSON.stringify(c)}),u=await l.json().catch(()=>({}));if(!l.ok){let g=new Error(u.error?.message||"Anthropic request failed");throw g.status=l.status,g.provider=this.name,g.body=u,g}let m=[],f=[];for(let g of u.content||[])g.type==="text"&&m.push(g.text),g.type==="tool_use"&&f.push({id:g.id||F("toolcall"),name:g.name,arguments:g.input||{}});return{content:m.join(`
285
+ `),toolCalls:f,usage:we(u.usage),raw:u}}assertConfigured(){if(!this.apiKey)throw new Error("Missing API key for provider anthropic");if(!this.baseUrl)throw new Error("Missing base URL for provider anthropic")}};function Bl(r){return r.map((e,t)=>{let o={name:e.name,description:e.description,input_schema:e.inputSchema||{type:"object",properties:{}}};return t===r.length-1&&(o.cache_control={type:"ephemeral"}),o})}function zl(r){let e=[],t=[];for(let o of r){if(o.role==="system"){e.push(Q(o.content));continue}if(o.role==="tool"){t.push({role:"user",content:[{type:"tool_result",tool_use_id:o.toolCallId||o.tool_call_id,content:Q(o.content)}]});continue}if(o.role==="assistant"&&o.toolCalls?.length){let n=[];o.content&&n.push({type:"text",text:Q(o.content)});for(let a of o.toolCalls)n.push({type:"tool_use",id:a.id,name:a.name,input:a.arguments||{}});t.push({role:"assistant",content:n});continue}t.push({role:o.role==="assistant"?"assistant":"user",content:Q(o.content)})}return{system:e.join(`
286
+
287
+ `),anthropicMessages:t}}function Hl(r){let e=[];for(let t of r){let o=e[e.length-1];if(!o||o.role!==t.role){e.push(t);continue}o.content=[...aa(o.content),...aa(t.content)]}return e}function aa(r){return Array.isArray(r)?r:[{type:"text",text:Q(r)}]}var It=class{constructor({apiKey:e,baseUrl:t,model:o}={}){this.name="gemini",this.apiKey=e,this.baseUrl=t?.replace(/\/$/,""),this.model=o}async generate({messages:e,tools:t=[],temperature:o,maxTokens:n,signal:a}){this.assertConfigured();let{system:s,contents:i}=Vl(e),c={contents:Kl(i),generationConfig:{temperature:o,maxOutputTokens:n}};s&&(c.systemInstruction={parts:[{text:s}]}),t.length>0&&(c.tools=[{functionDeclarations:t.map(Gl)}]);let l=`${this.baseUrl}/models/${encodeURIComponent(this.model)}:generateContent?key=${encodeURIComponent(this.apiKey)}`,u=await fetch(l,{method:"POST",signal:a,headers:{"content-type":"application/json"},body:JSON.stringify(c)}),m=await u.json().catch(()=>({}));if(!u.ok){let y=new Error(m.error?.message||"Gemini request failed");throw y.status=u.status,y.provider=this.name,y.body=m,y}let f=m.candidates?.[0]?.content?.parts||[],g=[],w=[];for(let y of f)y.text&&g.push(y.text),y.functionCall&&w.push({id:y.functionCall.id||F("toolcall"),name:y.functionCall.name,arguments:y.functionCall.args||{},thoughtSignature:y.thoughtSignature||y.thought_signature||null});return{content:g.join(`
288
+ `),toolCalls:w,usage:we(m.usageMetadata),raw:m}}assertConfigured(){if(!this.apiKey)throw new Error("Missing API key for provider gemini");if(!this.baseUrl)throw new Error("Missing base URL for provider gemini")}};function Gl(r){return{name:r.name,description:r.description,parameters:Wr(r.inputSchema||{type:"object",properties:{}})}}function Wr(r){if(!r||typeof r!="object")return{type:"object",properties:{}};let e=Wl(r.type,r),t={};if(e&&(t.type=e),r.description&&(t.description=String(r.description)),Array.isArray(r.enum)&&(t.enum=r.enum.map(String)),Array.isArray(r.required)&&r.required.length>0&&(t.required=r.required.map(String)),e==="object"){let o=r.properties||{};t.properties={};for(let[n,a]of Object.entries(o))t.properties[n]=Wr(a);Object.keys(t.properties).length===0&&delete t.properties}return e==="array"&&(t.items=Wr(r.items||{type:"string"})),r.minimum!==void 0&&typeof r.minimum=="number"&&(t.minimum=r.minimum),r.maximum!==void 0&&typeof r.maximum=="number"&&(t.maximum=r.maximum),r.minItems!==void 0&&e==="array"&&(t.minItems=r.minItems),r.maxItems!==void 0&&e==="array"&&(t.maxItems=r.maxItems),t}function Wl(r,e){let t=Array.isArray(r)?r.find(o=>o!=="null"):r;return t||(e.properties||e.required||e.additionalProperties?"object":e.items?"array":"string")}function Vl(r){let e=[],t=[];for(let o of r){if(o.role==="system"){e.push(Q(o.content));continue}if(o.role==="assistant"&&o.toolCalls?.length){t.push({role:"model",parts:[{text:`Chamadas de ferramenta solicitadas: ${o.toolCalls.map(a=>a.name).join(", ")}. Os resultados aparecem nas proximas mensagens.`}]});continue}if(o.role==="tool"){t.push({role:"user",parts:[{text:`Resultado da ferramenta ${o.name||"tool_result"}:
289
+ ${Q(o.content)}`}]});continue}let n=[{text:Q(o.content)}];if(o.images?.length)for(let a of o.images)n.push({inlineData:{mimeType:a.mimeType||"image/png",data:a.data}});t.push({role:o.role==="assistant"?"model":"user",parts:n})}return{system:e.join(`
290
+
291
+ `),contents:t}}function Kl(r){let e=[];for(let t of r){let o=e[e.length-1];o?.role===t.role?o.parts.push(...t.parts):e.push(t)}return e}var Nt=class extends ae{constructor(e={}){super({...e,name:"openrouter",defaultHeaders:{"HTTP-Referer":"http://localhost","X-Title":"Rivale Autonomous Agent"}})}buildBody(e){let t=super.buildBody(e);return this.supportsAnthropicCache()&&(t.messages=Xl(t.messages)),t}supportsAnthropicCache(){return/claude|anthropic/i.test(this.model||"")}};function Xl(r){let e=!1;return r.map(t=>e||t.role!=="system"||typeof t.content!="string"?t:(e=!0,{...t,content:[{type:"text",text:t.content,cache_control:{type:"ephemeral"}}]}))}var qt=class extends ae{constructor(e={}){super({...e,name:"deepseek"})}};var se={"gpt-4o-mini":{input:.15,output:.6},"gpt-4o":{input:2.5,output:10},"gpt-4.1":{input:2,output:8},"gpt-4.1-mini":{input:.4,output:1.6},"gpt-5.4-mini":{input:.15,output:.6},"claude-3-5-sonnet":{input:3,output:15},"claude-3-5-haiku":{input:.25,output:1.25},"claude-3-opus":{input:15,output:75},"gemini-1.5-flash":{input:.075,output:.3},"gemini-1.5-pro":{input:1.25,output:5},"llama-3.3-70b-versatile":{input:.59,output:.79},"llama3-70b-8192":{input:.59,output:.79},"llama3-8b-8192":{input:.05,output:.08},"mixtral-8x7b-32768":{input:.24,output:.24},"deepseek-chat":{input:.27,output:1.1},"deepseek-reasoner":{input:.55,output:2.19},"deepseek-v4-flash":{input:.27,output:1.1},"deepseek-v4-pro":{input:.55,output:2.19}},Yl={"openai/gpt-4.1":"gpt-4.1","openai/gpt-4.1-mini":"gpt-4.1-mini","openai/gpt-4o":"gpt-4o","openai/gpt-4o-mini":"gpt-4o-mini","claude-3-5-sonnet-latest":"claude-3-5-sonnet","claude-3-5-sonnet-20241022":"claude-3-5-sonnet","claude-3-5-haiku-latest":"claude-3-5-haiku","claude-3-5-haiku-20241022":"claude-3-5-haiku"};function Jl(r){if(!r)return null;if(se[r])return se[r];let e=Yl[r];if(e&&se[e])return se[e];let t=String(r).toLowerCase();return t.includes("deepseek")?se[/reason|pro/.test(t)?"deepseek-reasoner":"deepseek-chat"]:t.includes("claude")?se[t.includes("haiku")?"claude-3-5-haiku":"claude-3-5-sonnet"]:t.includes("gemini")?se[t.includes("flash")?"gemini-1.5-flash":"gemini-1.5-pro"]:t.includes("gpt-4o-mini")||t.includes("mini")?se["gpt-4o-mini"]:t.includes("gpt")?se["gpt-4.1"]:t.includes("llama")?se["llama-3.3-70b-versatile"]:null}function Vr(r,e,t){let o=Jl(r);if(!o)return 0;let n=e/1e6*o.input,a=t/1e6*o.output;return n+a}var jt=class{constructor({config:e,eventBus:t,logger:o}={}){this.config=e,this.eventBus=t,this.logger=o,this.providerCache=new Map,this.provider=this.getProvider(this.config.llm.provider,this.config.llm.model)}resolve({provider:e,model:t}={}){let o=(e||this.config.llm.provider).toLowerCase(),n=t||this.config.llm.model;return e&&!this.config.llm.apiKeys?.[o]&&(this.logger?.warn("modelo forte pedido sem credencial; usando o principal",{requested:o,fallback:this.config.llm.provider}),o=this.config.llm.provider,n=this.config.llm.model),{impl:this.getProvider(o,n),providerName:o,modelName:n}}getProvider(e,t){let o=`${e}:${t}`,n=this.providerCache.get(o);if(n)return n;let a=this.createProviderFor(e,t);return this.providerCache.set(o,a),a}async generate({messages:e,tools:t=[],temperature:o,maxTokens:n,metadata:a={},provider:s,model:i,signal:c}){let l=performance.now(),{impl:u,providerName:m,modelName:f}=this.resolve({provider:s,model:i});await this.eventBus?.emit("llm:start",{provider:m,model:f,metadata:a});try{let g=await Ye(()=>Ue(k=>this.callProviderWithToolRepair(u,"generate",{messages:e,tools:t,temperature:o??this.config.llm.temperature,maxTokens:n??this.config.llm.maxTokens,signal:k}),12e4,"LLM call timed out",c),{attempts:3}),w=Math.round(performance.now()-l),{inputTokens:y,outputTokens:b}=sa(g.usage),E=Vr(f,y,b);return await this.eventBus?.emit("llm:end",{provider:m,model:f,metadata:a,durationMs:w,costUsd:E,usage:g.usage}),{...g,provider:m,model:f,durationMs:w,costUsd:E}}catch(g){throw await this.eventBus?.emit("llm:error",{provider:m,model:f,error:g.message}),g}}async stream({messages:e,tools:t=[],temperature:o,maxTokens:n,metadata:a={},onToken:s,provider:i,model:c,signal:l}){let u=performance.now(),{impl:m,providerName:f,modelName:g}=this.resolve({provider:i,model:c});await this.eventBus?.emit("llm:start",{provider:f,model:g,stream:!0,metadata:a});try{let w=await Ye(()=>Ue(async R=>{if(typeof m.stream=="function")return this.callProviderWithToolRepair(m,"stream",{messages:e,tools:t,temperature:o??this.config.llm.temperature,maxTokens:n??this.config.llm.maxTokens,signal:R,onToken:s});let h=await this.callProviderWithToolRepair(m,"generate",{messages:e,tools:t,temperature:o??this.config.llm.temperature,maxTokens:n??this.config.llm.maxTokens,signal:R});return h.content&&await s?.(h.content),h},12e4,"LLM stream timed out",l),{attempts:3}),y=Math.round(performance.now()-u),{inputTokens:b,outputTokens:E}=sa(w.usage),k=Vr(g,b,E);return await this.eventBus?.emit("llm:end",{provider:f,model:g,stream:!0,metadata:a,durationMs:y,costUsd:k,usage:w.usage}),{...w,provider:f,model:g,durationMs:y,costUsd:k}}catch(w){throw await this.eventBus?.emit("llm:error",{provider:f,model:g,stream:!0,error:w.message}),w}}async callProviderWithToolRepair(e,t,{messages:o,tools:n,...a}){try{return await e[t]({messages:o,tools:n,...a})}catch(s){if(!Ql(s)||!n?.length)throw s;return this.logger?.warn("tool call validation failed, retrying with stricter tool instructions",{error:s.message}),e[t]({...a,tools:n,messages:[...o,{role:"system",content:Zl(n,s)}]})}}createProviderFor(e,t){let o={apiKey:this.config.llm.apiKeys[e],baseUrl:this.config.llm.baseUrls[e],model:t};switch(e){case"groq":return new Ot(o);case"openai":return new Mt(o);case"anthropic":return new Pt(o);case"gemini":return new It(o);case"openrouter":return new Nt(o);case"deepseek":return new qt(o);default:throw new Error(`Unsupported LLM provider: ${e}`)}}};function sa(r){return{inputTokens:r?.inputTokens??r?.prompt_tokens??0,outputTokens:r?.outputTokens??r?.completion_tokens??0}}function Ql(r){let e=String(r?.message||"");return r?.status===400&&/tool call validation failed|not in request\.tools|attempted to call tool/i.test(e)}function Zl(r,e){let t=r.map(o=>o.name).join(", ");return["A chamada anterior falhou por nome de ferramenta invalido.",`Erro do provedor: ${e.message}`,`Ferramentas validas: ${t}.`,"Use exatamente um desses nomes no campo de nome da ferramenta.","Coloque parametros somente no objeto JSON de argumentos.","Nunca escreva argumentos junto ao nome da ferramenta.",'Exemplo correto: ferramenta file_mkdir com argumentos {"path":"nodejs-login"}.','Exemplo incorreto: file_mkdir{"path":"nodejs-login"}.'].join(`
292
+ `)}var Dt=class{constructor({config:e,logger:t}={}){this.config=e,this.logger=t}get enabled(){return!!this.config.memory.embeddingsEnabled}get semantic(){return this.enabled&&this.config.embeddings.provider==="openai"&&!!this.config.embeddings.apiKeys?.openai}async embed(e){return this.enabled?this.config.embeddings.provider==="openai"?this.embedWithOpenAI(e):{provider:"local",model:this.config.embeddings.model,dimensions:this.config.embeddings.dimensions,vector:ia(e,this.config.embeddings.dimensions)}:null}async embedWithOpenAI(e){let t=this.config.embeddings.apiKeys.openai;if(!t)return this.logger?.warn("OpenAI embedding key missing, falling back to local embeddings"),{provider:"local",model:"local-hash-v1",dimensions:this.config.embeddings.dimensions,vector:ia(e,this.config.embeddings.dimensions)};let o=this.config.embeddings.baseUrls.openai.replace(/\/$/,""),n=await fetch(`${o}/embeddings`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${t}`},body:JSON.stringify({model:this.config.embeddings.model,input:e})}),a=await n.json().catch(()=>({}));if(!n.ok){let i=new Error(a.error?.message||"OpenAI embedding request failed");throw i.status=n.status,i}let s=a.data?.[0]?.embedding;if(!Array.isArray(s))throw new Error("OpenAI embedding response did not include a vector");return{provider:"openai",model:this.config.embeddings.model,dimensions:s.length,vector:la(s)}}};function ia(r,e){let t=new Array(e).fill(0),o=eu(r);for(let n of o){let a=ca(n)%e,s=ca(`${n}:sign`)%2===0?1:-1;t[a]+=s*(1+Math.log(1+n.length))}return la(t)}function eu(r){return String(r||"").toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z0-9_]+/g)||[]}function ca(r){let e=2166136261;for(let t=0;t<r.length;t+=1)e^=r.charCodeAt(t),e=Math.imul(e,16777619);return e>>>0}function la(r){let e=Math.sqrt(r.reduce((t,o)=>t+o*o,0));return e?r.map(t=>Number((t/e).toFixed(8))):r}var Ut=class{constructor({storage:e,eventBus:t,logger:o,embeddingManager:n,searchLimit:a=6}={}){this.storage=e,this.eventBus=t,this.logger=o,this.embeddingManager=n,this.searchLimit=a}async saveMemory({content:e,tags:t=[],importance:o=1,metadata:n={}}){let a=this.storage.saveMemory({content:e,tags:t,importance:o,metadata:n});return await this.saveEmbedding(a),await this.eventBus?.emit("memory:saved",{memory:a}),this.logger?.info("memory saved",{id:a.id,tags:a.tags,importance:a.importance}),a}async searchMemory({query:e,limit:t=this.searchLimit}){let o=this.storage.searchMemories({query:e,limit:t}),n=this.embeddingManager?.semantic?await this.searchByEmbedding({query:e,limit:t}):[];return tu({lexical:o,semantic:n,limit:t})}async deleteMemory(e){return this.storage.deleteMemory(e),await this.eventBus?.emit("memory:deleted",{id:e}),{id:e,deleted:!0}}async summarizeMemory({query:e,limit:t=this.searchLimit}={}){return(await this.searchMemory({query:e,limit:t})).map(n=>`- ${n.content}`).join(`
293
+ `)}async saveEmbedding(e){if(this.embeddingManager?.semantic)try{let t=await this.embeddingManager.embed(e.content);if(!t?.vector?.length)return;this.storage.saveMemoryEmbedding({memoryId:e.id,provider:t.provider,model:t.model,dimensions:t.dimensions,vector:t.vector})}catch(t){this.logger?.warn("memory embedding failed",{id:e.id,error:t.message})}}async searchByEmbedding({query:e,limit:t}){if(!this.embeddingManager?.enabled||!e)return[];try{let o=await this.embeddingManager.embed(e);return o?.vector?.length?this.storage.searchMemoriesByVector({vector:o.vector,limit:t}):[]}catch(o){return this.logger?.warn("memory vector search failed",{error:o.message}),[]}}};function tu({lexical:r,semantic:e,limit:t}){let o=new Map;for(let n of e)o.set(n.id,{...n,searchScore:n.vectorScore||0,searchType:"semantic"});for(let n of r){let a=o.get(n.id);o.set(n.id,{...a||n,...n,searchScore:(a?.searchScore||0)+.25+n.importance/10,searchType:a?"hybrid":"lexical"})}return[...o.values()].sort((n,a)=>(a.searchScore||0)-(n.searchScore||0)).slice(0,t)}var Ft=class{constructor({limit:e=20,summaryThreshold:t=30,tokenBudget:o=0,minKeep:n=4}={}){this.limit=e,this.summaryThreshold=t,this.tokenBudget=o,this.minKeep=n,this.conversations=new Map}addMessage(e,t){let o=this.getState(e);o.messages.push({...t,createdAt:new Date().toISOString()}),this.fold(o)}fold(e){if(e.messages.length>this.limit){let t=e.messages.splice(0,e.messages.length-this.limit);e.summary=Xr(e.summary,Kr(t))}if(this.tokenBudget>0)for(;e.messages.length>this.minKeep&&ua(e.messages)>this.tokenBudget;){let[t]=e.messages.splice(0,1);e.summary=Xr(e.summary,Kr([t]))}}estimateTokens(e){let t=this.getState(e);return ua(t.messages)+da(t.summary)}getRecent(e,t=this.limit){return this.getState(e).messages.slice(-t)}getSummary(e){return this.getState(e).summary}summarize(e){let t=this.getState(e),o=t.messages.slice(-this.limit),n=t.messages.slice(0,Math.max(0,t.messages.length-this.limit));return n.length>0&&(t.summary=Xr(t.summary,Kr(n)),t.messages=o),t.summary}setCompacted(e,{summary:t,keep:o=[]}={}){let n=this.getState(e);return n.summary=t||"",n.messages=Array.isArray(o)?[...o]:[],n}getState(e){let t=e||"default";return this.conversations.has(t)||this.conversations.set(t,{messages:[],summary:""}),this.conversations.get(t)}};function da(r){return Math.ceil(String(r||"").length/4)}function ua(r){let e=0;for(let t of r){let o=typeof t.content=="string"?t.content:JSON.stringify(t.content||"");e+=da(o)+4}return e}function Kr(r){return r.filter(e=>e.role!=="tool").map(e=>{let t=typeof e.content=="string"?e.content:JSON.stringify(e.content);return`${e.role}: ${t.slice(0,240)}`}).join(`
294
+ `)}function Xr(r,e){let t=[r,e].filter(Boolean).join(`
295
+ `);return t.length<=4e3?t:t.slice(-4e3)}var ru=[/lembre(?:-se)? que\s+(.+)/i,/guarde que\s+(.+)/i,/minha preferencia e\s+(.+)/i,/remember that\s+(.+)/i,/my preference is\s+(.+)/i],Bt=class{constructor({config:e,storage:t,eventBus:o,logger:n}={}){this.storage=t,this.logger=n,this.embeddingManager=new Dt({config:e,logger:n}),this.shortTerm=new Ft({limit:e.memory.shortTermLimit,summaryThreshold:e.memory.shortTermSummaryThreshold,tokenBudget:e.memory.shortTermTokenBudget||0}),this.longTerm=new Ut({storage:t,eventBus:o,logger:n,embeddingManager:this.embeddingManager,searchLimit:e.memory.searchLimit})}addConversationMessage(e,t){this.shortTerm.addMessage(e,t);try{this.storage?.saveConversationMessage?.({conversationId:e,role:t.role,content:t.content})}catch(o){this.logger?.warn?.("failed to persist conversation message",{error:o.message})}}hydrateConversation(e,t=40){let n=(this.storage?.getConversationMessages?.(e,200)||[]).slice(-t);for(let a of n)this.shortTerm.addMessage(e,{role:a.role,content:a.content});return n.length}listConversations(e=20){return this.storage?.listConversations?.(e)||[]}getRecentMessages(e,t){return this.shortTerm.getRecent(e,t)}getConversationSummary(e){return this.shortTerm.getSummary(e)}estimateShortTermTokens(e){return this.shortTerm.estimateTokens(e)}async saveMemory(e){return this.longTerm.saveMemory(e)}async searchMemory(e){return this.longTerm.searchMemory(e)}async deleteMemory(e){return this.longTerm.deleteMemory(e)}async summarizeMemory(e){return this.longTerm.summarizeMemory(e)}async compactConversation(e,{llmManager:t,keepRecent:o=3}={}){let n=this.shortTerm.getState(e),a=n.messages||[],s=n.summary||"";if(a.length<=o&&!s)return{compacted:!1,reason:"conversa curta demais para compactar"};if(!t)return{compacted:!1,reason:"llmManager indisponivel"};let i=ou(s,a),c=[{role:"system",content:["Voce condensa o historico de uma conversa entre um usuario e um agente de codigo.","Produza um resumo DENSO e factual em portugues, preservando:","- objetivo atual e o que ja foi decidido;","- arquivos criados/alterados e mudancas importantes;","- estado da tarefa (o que falta, pendencias, bloqueios);","- preferencias e restricoes que o usuario declarou.","Nao invente. Sem preambulo. Use topicos curtos. Maximo ~400 palavras."].join(`
296
+ `)},{role:"user",content:`Resuma a conversa a seguir:
297
+
298
+ ${i}`}],l=await t.generate({messages:c,tools:[],metadata:{compact:!0,conversationId:e}}),u=String(l?.content||"").trim();if(!u)return{compacted:!1,reason:"o modelo nao retornou resumo"};let m=a.slice(-o);return this.shortTerm.setCompacted(e,{summary:u,keep:m}),{compacted:!0,before:a.length,after:m.length,summary:u,summaryTokens:Math.ceil(u.length/4)}}async maybeSaveFromUserMessage(e,t={}){let o=nu(e);return o?this.saveMemory({content:o,tags:["user_fact","auto"],importance:3,metadata:t}):null}};function ou(r,e){let t=[];r&&t.push(`[resumo anterior]
299
+ ${r}`);for(let o of e){if(o.role==="tool")continue;let n=typeof o.content=="string"?o.content:JSON.stringify(o.content);n?.trim()&&t.push(`${o.role}: ${n.slice(0,2e3)}`)}return t.join(`
300
+
301
+ `)}function nu(r){let e=au(String(r||""));for(let t of ru){let o=e.match(t);if(o?.[1])return o[1].trim()}return null}function au(r){return r.normalize("NFD").replace(/[\u0300-\u036f]/g,"")}var zt=class{constructor({config:e,llmManager:t,eventBus:o,logger:n}={}){this.config=e,this.llmManager=t,this.eventBus=o,this.logger=n}async createPlan({message:e}){if(!su(e))return{required:!1,source:"none",steps:[]};let o=await this.createLLMPlan(e).catch(n=>(this.logger?.warn("llm planner failed, using heuristic planner",{error:n.message}),null))||{required:!0,source:"heuristic",steps:iu(e,this.config.planner.maxSteps)};return await this.eventBus?.emit("planner:created",{plan:o}),this.logger?.info("plan created",{source:o.source,steps:o.steps.length}),o}async createLLMPlan(e){if(!["auto","llm"].includes(this.config.planner.mode)||!this.llmManager)return null;let t=await this.llmManager.generate({messages:[{role:"system",content:["Voce cria planos curtos para um agente autonomo.","Responda apenas JSON valido, sem markdown.",'Formato: {"steps":["passo 1","passo 2"]}.',`Use no maximo ${this.config.planner.maxSteps} passos.`].join(`
302
+ `)},{role:"user",content:`Objetivo do usuario:
303
+ ${e}`}],tools:[],temperature:.1,maxTokens:700,metadata:{planner:!0}}),o=cu(t.content),n=lu(o.steps,this.config.planner.maxSteps);return n.length===0?null:{required:!0,source:"llm",steps:n}}};function su(r){let e=String(r||"").toLowerCase();return e.length>180?!0:["crie","construa","implemente","automatize","scraper","sistema","projeto","arquitetura","refatore","analise"].some(t=>e.includes(t))}function iu(r,e=8){let t=String(r||"").toLowerCase(),o=["Analisar o objetivo e restricoes do usuario"];return(t.includes("pesquis")||t.includes("documenta")||t.includes("scraper"))&&o.push("Pesquisar ou consultar fontes relevantes quando necessario"),(t.includes("crie")||t.includes("construa")||t.includes("implemente"))&&(o.push("Definir estrutura tecnica e componentes principais"),o.push("Implementar a solucao de forma incremental")),(t.includes("arquivo")||t.includes("codigo")||t.includes("projeto"))&&o.push("Ler ou modificar arquivos usando ferramentas seguras"),o.push("Validar o resultado com verificacoes objetivas"),o.push("Entregar resposta final com resumo e proximos passos uteis"),[...new Set(o)].slice(0,e)}function cu(r){let t=String(r||"").trim().replace(/^```(?:json)?/i,"").replace(/```$/,"").trim(),o=t.indexOf("{"),n=t.lastIndexOf("}");return o===-1||n===-1?{}:JSON.parse(t.slice(o,n+1))}function lu(r,e){return Array.isArray(r)?r.map(t=>String(t||"").trim()).filter(Boolean).slice(0,e):[]}import{readdir as uu,readFile as du}from"node:fs/promises";import Je from"node:path";var mu=[{name:"refactor-js",description:"Refatoracao segura de codigo JavaScript/Node.js preservando comportamento.",whenToUse:"Use antes de alterar codigo JS/Node existente, especialmente refatoracoes, separacao de funcoes e limpeza estrutural.",source:"builtin",content:["# Refatoracao JS/Node","","- Leia os arquivos relevantes antes de editar.","- Preserve comportamento publico, nomes exportados e contratos existentes.","- Prefira `file_edit` para mudancas localizadas e `file_write` para arquivos novos.","- Se precisar criar uma copia, use `file_copy` ou escreva explicitamente o novo arquivo.","- Depois de editar, rode uma verificacao leve quando houver comando disponivel.","- Relate arquivos alterados, motivo da mudanca e como validar."].join(`
304
+ `)},{name:"code-review",description:"Revisao tecnica focada em bugs, regressao, manutencao e testes.",whenToUse:"Use para revisar mudancas ou pedir segunda opiniao antes/depois de editar codigo.",source:"builtin",content:["# Revisao De Codigo","","- Priorize bugs reais e riscos de regressao.","- Cite arquivo e linha quando possivel.","- Separe achados de sugestoes cosmeticas.","- Verifique se existem testes ou validacoes ausentes.","- Nao aprove trabalho sem evidencias."].join(`
305
+ `)},{name:"secure-command",description:"Analise de seguranca para comandos shell, PowerShell e operacoes destrutivas.",whenToUse:"Use antes de executar comandos de escrita, remocao, rede ou scripts gerados dinamicamente.",source:"builtin",content:["# Seguranca De Comandos","","- Comandos de leitura devem ser preferidos para diagnostico.","- Evite `Remove-Item -Recurse -Force`, `git reset --hard`, `git clean -f`, `curl | sh`, `Invoke-Expression` e `EncodedCommand`.","- Para alterar arquivos, prefira ferramentas estruturadas (`file_edit`, `file_write`) em vez de shell.","- Quando houver risco de perda de dados, peca confirmacao humana."].join(`
306
+ `)}],Ht=class{constructor({config:e,logger:t}={}){this.config=e,this.logger=t,this.cache=null,this.cacheCreatedAt=0,this.cacheTtlMs=1e4}async listSkills({refresh:e=!1}={}){if(!this.config?.skills?.enabled)return[];let t=Date.now();if(!e&&this.cache&&t-this.cacheCreatedAt<this.cacheTtlMs)return this.cache;let o=[];for(let a of this.config.skills.paths||[])o.push(...await this.loadSkillsFromPath(a));let n=yu([...mu,...o]).map(a=>({...a,content:vu(a.content,this.config.skills.maxContentChars)})).sort((a,s)=>a.name.localeCompare(s.name));return this.cache=n,this.cacheCreatedAt=t,n}async searchSkills(e,{limit:t=8}={}){let o=Se(e),n=await this.listSkills();return o?n.map(a=>({skill:a,score:gu(a,o)})).filter(a=>a.score>0).sort((a,s)=>s.score-a.score).slice(0,t).map(a=>a.skill):n.slice(0,t)}async getSkill(e){let t=Se(e);return(await this.listSkills()).find(n=>Se(n.name)===t)||null}async describeForPrompt({limit:e=12}={}){let t=await this.listSkills();return t.length===0?"":t.slice(0,e).map(o=>`- ${o.name}: ${o.description}${o.whenToUse?` (${o.whenToUse})`:""}`).join(`
307
+ `)}async loadSkillsFromPath(e){let t=Je.isAbsolute(e)?e:Je.resolve(process.cwd(),e),o=[];try{o=await uu(t,{withFileTypes:!0})}catch{return[]}let n=[];for(let a of o){if(!a.isFile()||!a.name.toLowerCase().endsWith(".md"))continue;let s=Je.join(t,a.name);try{let i=await du(s,"utf8");n.push(pu(i,s))}catch(i){this.logger?.warn("failed to load skill",{filePath:s,error:i.message})}}return n}};function pu(r,e){let{frontmatter:t,content:o}=fu(r),n=Je.basename(e,Je.extname(e)),a=String(t.name||n).trim();return{name:a,description:String(t.description||hu(o)||a).trim(),whenToUse:String(t.when_to_use||t.whenToUse||"").trim(),source:"file",filePath:e,content:o.trim()}}function fu(r){let e=String(r||"");if(!e.startsWith("---"))return{frontmatter:{},content:e};let t=e.indexOf(`
308
+ ---`,3);if(t===-1)return{frontmatter:{},content:e};let o=e.slice(3,t).trim(),n=e.slice(t+4).replace(/^\r?\n/,""),a={};for(let s of o.split(/\r?\n/)){let i=s.match(/^([A-Za-z0-9_-]+)\s*:\s*(.*)$/);i&&(a[i[1]]=bu(i[2]))}return{frontmatter:a,content:n}}function hu(r){let e=String(r||"").split(/\r?\n/).find(t=>t.startsWith("#"));return e?e.replace(/^#+\s*/,"").trim():""}function gu(r,e){let t=Se([r.name,r.description,r.whenToUse,r.content].join(" ")),o=0;for(let n of e.split(/\s+/).filter(Boolean))Se(r.name).includes(n)&&(o+=6),Se(r.description).includes(n)&&(o+=3),t.includes(n)&&(o+=1);return o}function yu(r){let e=new Map;for(let t of r)e.set(Se(t.name),t);return[...e.values()]}function bu(r){return String(r||"").trim().replace(/^["']|["']$/g,"")}function Se(r){return String(r||"").normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase().trim()}function vu(r,e=12e3){let t=String(r||"");return t.length<=e?t:`${t.slice(0,e-3)}...`}import wu from"better-sqlite3";import{mkdirSync as Su}from"node:fs";import xu from"node:path";var ma=[{id:"001_initial_schema",up(r){r.exec(`
309
+ CREATE TABLE IF NOT EXISTS migrations (
310
+ id TEXT PRIMARY KEY,
311
+ applied_at TEXT NOT NULL
312
+ );
313
+
314
+ CREATE TABLE IF NOT EXISTS memories (
315
+ id TEXT PRIMARY KEY,
316
+ content TEXT NOT NULL,
317
+ tags TEXT,
318
+ importance INTEGER NOT NULL DEFAULT 1,
319
+ metadata_json TEXT NOT NULL DEFAULT '{}',
320
+ created_at TEXT NOT NULL,
321
+ updated_at TEXT NOT NULL
322
+ );
323
+
324
+ CREATE TABLE IF NOT EXISTS events (
325
+ id TEXT PRIMARY KEY,
326
+ type TEXT NOT NULL,
327
+ payload_json TEXT NOT NULL DEFAULT '{}',
328
+ created_at TEXT NOT NULL
329
+ );
330
+ `)}},{id:"002_memory_fts",up(r){try{r.exec(`
331
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts
332
+ USING fts5(id UNINDEXED, content, tags);
333
+ `)}catch{}}},{id:"003_memory_embeddings",up(r){r.exec(`
334
+ CREATE TABLE IF NOT EXISTS memory_embeddings (
335
+ memory_id TEXT PRIMARY KEY,
336
+ provider TEXT NOT NULL,
337
+ model TEXT NOT NULL,
338
+ dimensions INTEGER NOT NULL,
339
+ vector_json TEXT NOT NULL,
340
+ created_at TEXT NOT NULL,
341
+ updated_at TEXT NOT NULL,
342
+ FOREIGN KEY(memory_id) REFERENCES memories(id) ON DELETE CASCADE
343
+ );
344
+ `)}},{id:"004_tasks_and_subagents",up(r){r.exec(`
345
+ CREATE TABLE IF NOT EXISTS tasks (
346
+ id TEXT PRIMARY KEY,
347
+ conversation_id TEXT NOT NULL,
348
+ subject TEXT NOT NULL,
349
+ description TEXT NOT NULL DEFAULT '',
350
+ active_form TEXT,
351
+ status TEXT NOT NULL DEFAULT 'pending',
352
+ owner TEXT,
353
+ metadata_json TEXT NOT NULL DEFAULT '{}',
354
+ created_at TEXT NOT NULL,
355
+ updated_at TEXT NOT NULL
356
+ );
357
+
358
+ CREATE INDEX IF NOT EXISTS idx_tasks_conversation_status
359
+ ON tasks(conversation_id, status, updated_at);
360
+
361
+ CREATE TABLE IF NOT EXISTS todos (
362
+ id TEXT PRIMARY KEY,
363
+ conversation_id TEXT NOT NULL,
364
+ content TEXT NOT NULL,
365
+ status TEXT NOT NULL DEFAULT 'pending',
366
+ owner TEXT,
367
+ position INTEGER NOT NULL DEFAULT 0,
368
+ metadata_json TEXT NOT NULL DEFAULT '{}',
369
+ created_at TEXT NOT NULL,
370
+ updated_at TEXT NOT NULL
371
+ );
372
+
373
+ CREATE INDEX IF NOT EXISTS idx_todos_conversation_status
374
+ ON todos(conversation_id, status, position);
375
+
376
+ CREATE TABLE IF NOT EXISTS subagent_runs (
377
+ id TEXT PRIMARY KEY,
378
+ agent_name TEXT NOT NULL,
379
+ title TEXT,
380
+ task TEXT NOT NULL,
381
+ status TEXT NOT NULL,
382
+ output_path TEXT,
383
+ result_json TEXT NOT NULL DEFAULT '{}',
384
+ error TEXT,
385
+ started_at TEXT NOT NULL,
386
+ updated_at TEXT NOT NULL,
387
+ completed_at TEXT
388
+ );
389
+
390
+ CREATE INDEX IF NOT EXISTS idx_subagent_runs_status_updated
391
+ ON subagent_runs(status, updated_at);
392
+ `)}},{id:"005_code_index_and_conversations",up(r){r.exec(`
393
+ CREATE TABLE IF NOT EXISTS code_chunks (
394
+ id TEXT PRIMARY KEY,
395
+ path TEXT NOT NULL,
396
+ start_line INTEGER NOT NULL,
397
+ end_line INTEGER NOT NULL,
398
+ content TEXT NOT NULL,
399
+ provider TEXT,
400
+ model TEXT,
401
+ vector_json TEXT NOT NULL,
402
+ created_at TEXT NOT NULL
403
+ );
404
+
405
+ CREATE INDEX IF NOT EXISTS idx_code_chunks_path ON code_chunks(path);
406
+
407
+ CREATE TABLE IF NOT EXISTS conversation_messages (
408
+ id TEXT PRIMARY KEY,
409
+ conversation_id TEXT NOT NULL,
410
+ role TEXT NOT NULL,
411
+ content TEXT NOT NULL DEFAULT '',
412
+ created_at TEXT NOT NULL
413
+ );
414
+
415
+ CREATE INDEX IF NOT EXISTS idx_conv_messages
416
+ ON conversation_messages(conversation_id, created_at);
417
+ `)}}];var Gt=class{constructor({databasePath:e,logger:t}={}){this.databasePath=e,this.logger=t,Su(xu.dirname(e),{recursive:!0}),this.db=new wu(e),this.db.pragma("journal_mode = WAL"),this.db.pragma("foreign_keys = ON"),this.applyMigrations()}applyMigrations(){this.db.exec(`
418
+ CREATE TABLE IF NOT EXISTS migrations (
419
+ id TEXT PRIMARY KEY,
420
+ applied_at TEXT NOT NULL
421
+ );
422
+ `);for(let e of ma)this.db.prepare("SELECT id FROM migrations WHERE id = ?").get(e.id)||(e.up(this.db),this.db.prepare("INSERT INTO migrations (id, applied_at) VALUES (?, ?)").run(e.id,new Date().toISOString()),this.logger?.info("storage migration applied",{id:e.id}))}saveMemory({id:e=F("mem"),content:t,tags:o=[],importance:n=1,metadata:a={}}){let s=new Date().toISOString(),i=o.join(",");return this.db.prepare(`INSERT INTO memories (id, content, tags, importance, metadata_json, created_at, updated_at)
423
+ VALUES (?, ?, ?, ?, ?, ?, ?)
424
+ ON CONFLICT(id) DO UPDATE SET
425
+ content = excluded.content,
426
+ tags = excluded.tags,
427
+ importance = excluded.importance,
428
+ metadata_json = excluded.metadata_json,
429
+ updated_at = excluded.updated_at`).run(e,t,i,n,JSON.stringify(a),s,s),this.upsertMemoryFts({id:e,content:t,tags:i}),this.getMemory(e)}saveMemoryEmbedding({memoryId:e,provider:t,model:o,dimensions:n,vector:a}){let s=new Date().toISOString();this.db.prepare(`INSERT INTO memory_embeddings
430
+ (memory_id, provider, model, dimensions, vector_json, created_at, updated_at)
431
+ VALUES (?, ?, ?, ?, ?, ?, ?)
432
+ ON CONFLICT(memory_id) DO UPDATE SET
433
+ provider = excluded.provider,
434
+ model = excluded.model,
435
+ dimensions = excluded.dimensions,
436
+ vector_json = excluded.vector_json,
437
+ updated_at = excluded.updated_at`).run(e,t,o,n,JSON.stringify(a),s,s)}upsertMemoryFts({id:e,content:t,tags:o}){try{this.db.prepare("DELETE FROM memories_fts WHERE id = ?").run(e),this.db.prepare("INSERT INTO memories_fts (id, content, tags) VALUES (?, ?, ?)").run(e,t,o)}catch{}}getMemory(e){let t=this.db.prepare("SELECT * FROM memories WHERE id = ?").get(e);return t?Qe(t):null}searchMemories({query:e,limit:t=5}){let o=String(e||"").trim();if(!o)return this.db.prepare("SELECT * FROM memories ORDER BY importance DESC, updated_at DESC LIMIT ?").all(t).map(Qe);try{return this.db.prepare(`SELECT m.*
438
+ FROM memories_fts f
439
+ JOIN memories m ON m.id = f.id
440
+ WHERE memories_fts MATCH ?
441
+ ORDER BY bm25(memories_fts), m.importance DESC
442
+ LIMIT ?`).all(Tu(o),t).map(Qe)}catch{let n=`%${o}%`;return this.db.prepare(`SELECT * FROM memories
443
+ WHERE content LIKE ? OR tags LIKE ?
444
+ ORDER BY importance DESC, updated_at DESC
445
+ LIMIT ?`).all(n,n,t).map(Qe)}}searchMemoriesByVector({vector:e,limit:t=5}){return this.db.prepare(`SELECT m.*, e.vector_json
446
+ FROM memory_embeddings e
447
+ JOIN memories m ON m.id = e.memory_id`).all().map(n=>({...Qe(n),vectorScore:pa(e,Yr(n.vector_json,[]))})).filter(n=>Number.isFinite(n.vectorScore)).sort((n,a)=>a.vectorScore-n.vectorScore).slice(0,t)}clearCodeChunks(e){e?this.db.prepare("DELETE FROM code_chunks WHERE path LIKE ?").run(`${e}%`):this.db.prepare("DELETE FROM code_chunks").run()}saveCodeChunk({id:e,path:t,startLine:o,endLine:n,content:a,provider:s,model:i,vector:c}){this.db.prepare(`INSERT OR REPLACE INTO code_chunks
448
+ (id, path, start_line, end_line, content, provider, model, vector_json, created_at)
449
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(e,t,o,n,a,s||null,i||null,JSON.stringify(c),new Date().toISOString())}countCodeChunks(){return this.db.prepare("SELECT COUNT(*) AS n FROM code_chunks").get().n}searchCodeByVector({vector:e,limit:t=8}){return this.db.prepare("SELECT id, path, start_line, end_line, content, vector_json FROM code_chunks").all().map(n=>({id:n.id,path:n.path,startLine:n.start_line,endLine:n.end_line,content:n.content,score:pa(e,Yr(n.vector_json,[]))})).filter(n=>Number.isFinite(n.score)).sort((n,a)=>a.score-n.score).slice(0,t)}saveConversationMessage({id:e=F("msg"),conversationId:t,role:o,content:n}){this.db.prepare("INSERT INTO conversation_messages (id, conversation_id, role, content, created_at) VALUES (?, ?, ?, ?, ?)").run(e,t,o,typeof n=="string"?n:JSON.stringify(n??""),new Date().toISOString())}listConversations(e=20){return this.db.prepare(`SELECT conversation_id AS conversationId, COUNT(*) AS messages, MAX(created_at) AS lastAt
450
+ FROM conversation_messages GROUP BY conversation_id ORDER BY lastAt DESC LIMIT ?`).all(e)}getConversationMessages(e,t=200){return this.db.prepare("SELECT role, content, created_at AS createdAt FROM conversation_messages WHERE conversation_id = ? ORDER BY created_at ASC LIMIT ?").all(e,t)}deleteConversation(e){return this.db.prepare("DELETE FROM conversation_messages WHERE conversation_id = ?").run(e)}deleteMemory(e){this.db.prepare("DELETE FROM memories WHERE id = ?").run(e),this.db.prepare("DELETE FROM memory_embeddings WHERE memory_id = ?").run(e);try{this.db.prepare("DELETE FROM memories_fts WHERE id = ?").run(e)}catch{}}logEvent({id:e=F("evt"),type:t,payload:o={}}){this.db.prepare("INSERT INTO events (id, type, payload_json, created_at) VALUES (?, ?, ?, ?)").run(e,t,JSON.stringify(o),new Date().toISOString())}query(e,t=[]){return this.db.prepare(e).all(...t)}run(e,t=[]){return this.db.prepare(e).run(...t)}close(){this.db.close()}};function pa(r,e){if(!Array.isArray(r)||!Array.isArray(e)||r.length===0||r.length!==e.length)return 0;let t=0,o=0,n=0;for(let a=0;a<r.length;a+=1){let s=Number(r[a])||0,i=Number(e[a])||0;t+=s*i,o+=s*s,n+=i*i}return o===0||n===0?0:t/(Math.sqrt(o)*Math.sqrt(n))}function Qe(r){return{id:r.id,content:r.content,tags:r.tags?r.tags.split(",").filter(Boolean):[],importance:r.importance,metadata:Yr(r.metadata_json,{}),createdAt:r.created_at,updatedAt:r.updated_at}}function Yr(r,e){try{return JSON.parse(r)}catch{return e}}function Tu(r){return r.split(/\s+/).map(e=>`"${e.replaceAll('"','""')}"`).join(" OR ")}var Wt=class{constructor({config:e,logger:t}={}){this.config=e,this.logger=t,this.adapter=new Gt({databasePath:e.storage.databasePath,logger:t})}saveMemory(e){return this.adapter.saveMemory(e)}saveMemoryEmbedding(e){return this.adapter.saveMemoryEmbedding(e)}searchMemories(e){return this.adapter.searchMemories(e)}searchMemoriesByVector(e){return this.adapter.searchMemoriesByVector(e)}deleteMemory(e){return this.adapter.deleteMemory(e)}clearCodeChunks(e){return this.adapter.clearCodeChunks(e)}saveCodeChunk(e){return this.adapter.saveCodeChunk(e)}countCodeChunks(){return this.adapter.countCodeChunks()}searchCodeByVector(e){return this.adapter.searchCodeByVector(e)}saveConversationMessage(e){return this.adapter.saveConversationMessage(e)}listConversations(e){return this.adapter.listConversations(e)}getConversationMessages(e,t){return this.adapter.getConversationMessages(e,t)}deleteConversation(e){return this.adapter.deleteConversation?.(e)}logEvent(e){return this.adapter.logEvent(e)}query(e,t){return this.adapter.query(e,t)}run(e,t){return this.adapter.run(e,t)}close(){return this.adapter.close()}};var Vt=class{constructor({enabled:e=[]}={}){this.enabled=new Set(e),this.tools=new Map,this.activated=new Set}activate(e=[]){let t=[];for(let o of e)this.tools.has(o)&&!this.activated.has(o)&&(this.activated.add(o),t.push(o));return t}resetActivations(){this.activated.clear()}register(e){if(!e?.name||typeof e.execute!="function")throw new Error("Invalid tool registration");return this.tools.set(e.name,e),this}unregister(e){let t=this.tools.delete(e);return this.enabled.delete(e),this.activated.delete(e),t}get(e){let t=this.tools.get(e);return!t||this.enabled.size>0&&!this.enabled.has(e)?null:t}list(){return[...this.tools.values()].filter(e=>this.enabled.size===0||this.enabled.has(e.name))}toLLMTools({allowedNames:e,includeDeferred:t=!1}={}){let o=Array.isArray(e)&&e.length>0?new Set(e):null;return this.list().filter(n=>!o||o.has(n.name)).filter(n=>t||!n.shouldDefer||this.activated.has(n.name)).map(n=>({name:n.name,description:n.description,inputSchema:n.inputSchema}))}describeTool(e){return{name:e.name,description:e.description,risk:e.risk||(typeof e.getRisk=="function"?Eu(e.getRisk,e,"internal"):"internal"),readOnly:fa(e.isReadOnly,e),concurrencySafe:fa(e.isConcurrencySafe,e),shouldDefer:!!e.shouldDefer,searchHint:e.searchHint||""}}};function fa(r,e){if(typeof r=="function")try{return!!r.call(e,{})}catch{return!1}return!!r}function Eu(r,e,t){try{return r.call(e,{})??t}catch{return t}}import{rm as _u,stat as ku}from"node:fs/promises";function ha({config:r}){return{name:"file_delete",description:`Deleta arquivo ou pasta dentro do diretorio permitido: ${r.tools.fileRoot}. Operacao destrutiva. Use file_list antes quando houver duvida.`,risk:"dangerous",requiresApproval:!0,approvalReason:"Pode apagar arquivos ou pastas no workspace permitido.",inputSchema:{type:"object",required:["path"],additionalProperties:!1,properties:{path:{type:"string",minLength:1,maxLength:1e3},recursive:{type:"boolean"}}},async execute(e){let t=I(r.tools.fileRoot,"."),o=I(r.tools.fileRoot,e.path);if(Hn(t,o))throw new Error(`Refusing to delete the allowed root itself: ${t}`);let n=await ku(o);if(n.isDirectory()&&!e.recursive)throw new Error("Target is a directory. Pass recursive=true to delete directories.");return await _u(o,{recursive:!!e.recursive,force:!1}),{path:o,deleted:!0,type:n.isDirectory()?"directory":"file",recursive:!!e.recursive}}}}import{readdir as $u,stat as ga}from"node:fs/promises";import Jr from"node:path";function ya({config:r}){return{name:"file_list",description:`Lista arquivos e pastas dentro do diretorio permitido: ${r.tools.fileRoot}. Use antes de deletar ou modificar pastas.`,risk:"read",isReadOnly:!0,isConcurrencySafe:!0,searchHint:"list files and directories",inputSchema:{type:"object",required:["path"],additionalProperties:!1,properties:{path:{type:"string",minLength:1,maxLength:1e3},recursive:{type:"boolean"},maxDepth:{type:"integer",minimum:0,maximum:6},maxEntries:{type:"integer",minimum:1,maximum:500}}},async execute(e){let t=I(r.tools.fileRoot,e.path),o=await ga(t),n=e.maxEntries||100,a=e.recursive?e.maxDepth??2:0,s=[];return o.isFile()?{path:t,type:"file",entries:[{path:t,name:Jr.basename(t),type:"file",bytes:o.size}]}:(await ba(t,{root:t,depth:0,maxDepth:a,maxEntries:n,entries:s}),{path:t,type:"directory",entries:s,count:s.length,truncated:s.length>=n})}}}async function ba(r,e){if(e.entries.length>=e.maxEntries)return;let t=await $u(r,{withFileTypes:!0});for(let o of t){if(e.entries.length>=e.maxEntries)return;let n=Jr.join(r,o.name),a=Jr.relative(e.root,n),s=await ga(n),i=o.isDirectory()?"directory":o.isFile()?"file":"other";e.entries.push({path:a||".",name:o.name,type:i,bytes:o.isFile()?s.size:void 0}),o.isDirectory()&&e.depth<e.maxDepth&&await ba(n,{...e,depth:e.depth+1})}}import{readFile as Au,stat as Ru}from"node:fs/promises";function va({config:r}){return{name:"file_read",description:"L\xEA um arquivo dentro do diret\xF3rio permitido do agente. Suporta pagina\xE7\xE3o via startLine e endLine para arquivos gigantes. ATEN\xC7\xC3O: Nunca leia um arquivo grande inteiro para procurar por palavras-chave ou fun\xE7\xF5es! Sempre use a ferramenta 'grep_search' primeiro para descobrir as linhas exatas, e s\xF3 ent\xE3o use o 'file_read' com startLine e endLine para ler o contexto ao redor daquela linha.",inputSchema:{type:"object",required:["path"],additionalProperties:!1,properties:{path:{type:"string",minLength:1,maxLength:1e3},startLine:{type:"integer",minimum:1,description:"Linha inicial para leitura (1-indexado). Opcional."},endLine:{type:"integer",minimum:1,description:"Linha final para leitura (inclusive). Opcional."},maxBytes:{type:"integer",minimum:1,maximum:1048576,description:"M\xE1ximo de bytes a ler. Padr\xE3o 200KB."}}},risk:"read",isReadOnly:!0,isConcurrencySafe:!0,searchHint:"read local file with line ranges",maxResultSizeChars:1/0,async execute(e,t={}){let o=I(r.tools.fileRoot,e.path),n=await Ru(o),a=e.maxBytes||2e5;if(!n.isFile())throw new Error("Path is not a file");let s=t.readFileState?.get(o);if(s&&s.timestamp===n.mtimeMs&&s.size===n.size&&s.startLine===e.startLine&&s.endLine===e.endLine&&s.readAt&&Date.now()-new Date(s.readAt).getTime()<12e4)return{path:o,bytes:n.size,alreadyRead:!0,note:"Este arquivo ja foi lido nesta sessao e nao mudou. O conteudo esta acima no historico \u2014 use-o em vez de reler."};let i=await Au(o,"utf8"),c=i,l=!!(e.startLine||e.endLine);if(e.startLine||e.endLine){let u=i.split(/\r?\n/),m=Math.max(1,e.startLine||1)-1,f=e.endLine?Math.min(u.length,e.endLine):u.length;c=u.slice(m,f).join(`
451
+ `)}if(Buffer.byteLength(c,"utf8")>a)throw new Error(`O trecho solicitado possui ${Buffer.byteLength(c,"utf8")} bytes, excedendo o limite de ${a}. Use startLine e endLine para ler um trecho menor do arquivo.`);return t.readFileState?.set(o,{content:i,timestamp:n.mtimeMs,size:n.size,isPartialView:l,startLine:e.startLine,endLine:e.endLine,readAt:new Date().toISOString()}),{path:o,bytes:n.size,linesReturned:c.split(/\r?\n/).length,partial:l,content:c}}}}import{mkdir as Cu,stat as Lu}from"node:fs/promises";function wa({config:r}){return{name:"file_mkdir",description:`Cria diretorios dentro do root permitido: ${r.tools.fileRoot}. Use antes de criar projetos/pastas.`,risk:"dangerous",requiresApproval:!0,approvalReason:"Pode criar diretorios no workspace permitido.",inputSchema:{type:"object",required:["path"],additionalProperties:!1,properties:{path:{type:"string",minLength:1,maxLength:1e3}}},async execute(e){let t=I(r.tools.fileRoot,e.path),o=await Lu(t).catch(()=>null);if(o?.isFile())throw new Error(`Cannot create directory because a file already exists at: ${t}`);return await Cu(t,{recursive:!0}),{path:t,created:!o}}}}import{appendFile as Iu,mkdir as Nu,readFile as qu,stat as Qr,writeFile as ju}from"node:fs/promises";import Yt from"node:path";var j=class{constructor(e={}){this.name=e.name||this.constructor.name,this.description=e.description||"",this.inputSchema=e.inputSchema||{type:"object",properties:{}},this.requiresApproval=e.requiresApproval??!1,this.isConcurrencySafe=e.isConcurrencySafe??!1,this.isReadOnly=e.isReadOnly??!1,this.shouldDefer=e.shouldDefer??!1,this.risk=e.risk||(this.isReadOnly?"read":"internal"),this.maxResultSizeChars=e.maxResultSizeChars,this.searchHint=e.searchHint||"",this.approvalReason=e.approvalReason,this.timeoutMs=e.timeoutMs,this.retryAttempts=e.retryAttempts}async execute(e,t){throw new Error(`execute() not implemented for tool: ${this.name}`)}validate(e){return e}getRisk(){return this.risk}getApprovalReason(){return this.approvalReason||"Ferramenta sensivel configurada para exigir aprovacao humana."}getActivityDescription(e){return`${this.name} ${JSON.stringify(e||{})}`}};function Kt({filePath:r="file",before:e="",after:t="",contextLines:o=3}={}){if(e===t)return"";let n=Sa(e),a=Sa(t),s=Ou(n,a),i=Mu(s,o);return[`--- ${r}`,`+++ ${r}`,...i.flatMap(Pu)].join(`
452
+ `)}function Xt(r){let e=String(r||"").split(/\r?\n/),t=0,o=0;for(let n of e)n.startsWith("+++")||n.startsWith("---")||(n.startsWith("+")&&(t+=1),n.startsWith("-")&&(o+=1));return{additions:t,deletions:o,changes:t+o}}function Sa(r){let e=String(r??"");return e?e.replace(/\r\n/g,`
453
+ `).split(`
454
+ `):[]}function Ou(r,e){let t=Array.from({length:r.length+1},()=>Array(e.length+1).fill(0));for(let c=r.length-1;c>=0;c-=1)for(let l=e.length-1;l>=0;l-=1)t[c][l]=r[c]===e[l]?t[c+1][l+1]+1:Math.max(t[c+1][l],t[c][l+1]);let o=[],n=0,a=0,s=1,i=1;for(;n<r.length||a<e.length;){if(n<r.length&&a<e.length&&r[n]===e[a]){o.push({type:"context",text:r[n],oldLine:s,newLine:i}),n+=1,a+=1,s+=1,i+=1;continue}if(a<e.length&&(n===r.length||t[n][a+1]>=t[n+1][a])){o.push({type:"add",text:e[a],oldLine:s,newLine:i}),a+=1,i+=1;continue}o.push({type:"delete",text:r[n],oldLine:s,newLine:i}),n+=1,s+=1}return o}function Mu(r,e){let t=r.map((n,a)=>n.type==="context"?-1:a).filter(n=>n>=0);if(t.length===0)return[];let o=[];for(let n of t){let a=Math.max(0,n-e),s=Math.min(r.length-1,n+e),i=o[o.length-1];i&&a<=i.end+1?i.end=Math.max(i.end,s):o.push({start:a,end:s})}return o.map(({start:n,end:a})=>r.slice(n,a+1))}function Pu(r){let e=xa(r,"oldLine"),t=xa(r,"newLine"),o=r.filter(a=>a.type!=="add").length||1,n=r.filter(a=>a.type!=="delete").length||1;return[`@@ -${e},${o} +${t},${n} @@`,...r.map(a=>a.type==="add"?`+${a.text}`:a.type==="delete"?`-${a.text}`:` ${a.text}`)]}function xa(r,e){return r.find(o=>Number.isInteger(o[e])&&o[e]>0)?.[e]||1}function Ta({config:r,lspManager:e}){class t extends j{constructor(){super({name:"file_write",description:`Escreve ou acrescenta conteudo em arquivos dentro do diretorio permitido: ${r.tools.fileRoot}. IMPORTANTE: Sempre preserve a formata\xE7\xE3o e as quebras de linha originais do c\xF3digo usando '\\n' na string JSON do 'content'. NUNCA escreva todo o c\xF3digo em uma \xFAnica linha! Para criar pastas, use file_mkdir. Para projetos, escreva arquivos como pasta/package.json, pasta/server.js.`,requiresApproval:!0,inputSchema:{type:"object",required:["path","content"],additionalProperties:!1,properties:{path:{type:"string",minLength:1,maxLength:1e3},content:{type:"string",maxLength:1e6},append:{type:"boolean"}}},risk:"write",maxResultSizeChars:3e4,searchHint:"create or overwrite local files"}),this.risk="dangerous",this.approvalReason="Pode modificar arquivos no workspace permitido."}getRisk(n={}){return n.append?"write":"dangerous"}getApprovalReason(n={}){return n.append?"Pode acrescentar conteudo em arquivo no workspace permitido.":"Pode criar ou sobrescrever arquivos no workspace permitido."}async execute(n,a={}){if(!r.tools.fileWriteEnabled)throw new Error("File write tool is disabled by configuration");let s=I(r.tools.fileRoot,n.path);if(Uu(n.path,n.content))throw new Error(`file_write expected a file path, but this looks like a directory: ${n.path}. Use file_mkdir, then write files inside it.`);let i=await Qr(s).catch(()=>null);if(i?.isDirectory())throw new Error(`file_write cannot write content to a directory. Use a file path inside it: ${s}`);let c=Yt.dirname(s);if((await Qr(c).catch(()=>null))?.isFile())throw new Error(`Cannot create file because parent path is already a file: ${c}. Delete or rename that file first.`);let u=null;i?.isFile()&&(u=await qu(s,"utf8"),n.append||Du({filePath:s,currentContent:u,currentMtime:i.mtimeMs,readFileState:a.readFileState}));let m=[];if(e?.isConfigured()&&i?.isFile())try{m=(await e.run({operation:"diagnostics",filePath:s})).result?.diagnostics||[]}catch{}await Nu(c,{recursive:!0}),n.append?await Iu(s,n.content,"utf8"):await ju(s,n.content,"utf8");let f=n.append&&u!==null?u+n.content:n.content,g=await Qr(s);a.readFileState?.set(s,{content:f,timestamp:g.mtimeMs,size:g.size,isPartialView:!1,readAt:new Date().toISOString()});let w=u===null?"":Kt({filePath:Yt.relative(r.tools.fileRoot,s)||s,before:u,after:f}),y={path:s,bytes:Buffer.byteLength(n.content,"utf8"),append:!!n.append,mode:u===null?"create":n.append?"append":"overwrite",diff:w?Fu(w,2e4):void 0,changes:w?Xt(w):void 0};if(e?.isConfigured())try{await new Promise(h=>setTimeout(h,800));let R=((await e.run({operation:"diagnostics",filePath:s})).result?.diagnostics||[]).filter(h=>!m.some(A=>A.message===h.message&&A.line===h.line)).filter(h=>h.severity==="error"||h.severity==="warning");R.length>0&&(y.diagnosticsWarning=`[ALERTA DE SEGURANCA LSP] Sua alteracao introduziu ${R.length} novo(s) erro(s)/aviso(s) na tipagem/sintaxe do arquivo! Por favor, conserte-os imediatamente:
455
+ `+R.map(h=>` - [${h.severity.toUpperCase()}] Linha ${h.line}: ${h.message}`).join(`
456
+ `))}catch{}return y}}return new t}function Du({filePath:r,currentContent:e,currentMtime:t,readFileState:o}){let n=o?.get(r);if(!n||n.isPartialView)throw new Error(`Arquivo existente ainda nao foi lido por completo nesta sessao: ${r}. Use file_read sem startLine/endLine antes de sobrescrever.`);if(t>n.timestamp&&e!==n.content)throw new Error(`Arquivo mudou desde a ultima leitura: ${r}. Use file_read novamente antes de sobrescrever para evitar perder alteracoes do usuario.`)}function Uu(r,e){let t=String(r||"");if(/[\\/]$/.test(t))return!0;if(String(e||"").length>0)return!1;let o=Yt.basename(t);return!o||o==="."||o===".."?!0:o.startsWith(".")?!1:!Yt.extname(o)}function Fu(r,e){let t=String(r||"");return t.length<=e?t:`${t.slice(0,e-3)}...`}import{mkdir as Bu,readFile as zu,stat as Ea,writeFile as Hu}from"node:fs/promises";import _a from"node:path";function ka({config:r,lspManager:e}){class t extends j{constructor(){super({name:"file_edit",description:[`Edita um arquivo dentro do diretorio permitido: ${r.tools.fileRoot}.`,"Substitui oldString por newString. Antes de editar arquivo existente, use file_read sem startLine/endLine.","Aceita tambem 'edits': uma lista de {oldString,newString,replaceAll} aplicadas em sequencia (multi-edit).","Se o match exato falhar, tenta um match por indentacao (fuzzy) \u2014 voce nao precisa acertar espacos/tabs exatos.","Se oldString aparecer varias vezes, forneca mais contexto ou use replaceAll=true."].join(" "),requiresApproval:!0,risk:"write",maxResultSizeChars:3e4,searchHint:"edit local file replace text multi-edit fuzzy",inputSchema:{type:"object",required:["path"],additionalProperties:!1,properties:{path:{type:"string",minLength:1,maxLength:1e3},oldString:{type:"string",description:"Texto a substituir. Use string vazia apenas para criar arquivo novo."},newString:{type:"string",maxLength:1e6,description:"Novo texto."},replaceAll:{type:"boolean",description:"Substitui todas as ocorrencias. Padrao false."},edits:{type:"array",maxItems:50,description:"Multiplas edicoes aplicadas em sequencia no mesmo arquivo.",items:{type:"object",required:["oldString","newString"],additionalProperties:!1,properties:{oldString:{type:"string"},newString:{type:"string",maxLength:1e6},replaceAll:{type:"boolean"}}}}}}})}validate(n){let{old_string:a,new_string:s,replace_all:i,...c}=n,l={...c};return(n.oldString!==void 0||a!==void 0)&&(l.oldString=n.oldString??a),(n.newString!==void 0||s!==void 0)&&(l.newString=n.newString??s),(n.replaceAll!==void 0||i!==void 0)&&(l.replaceAll=!!(n.replaceAll??i)),Array.isArray(n.edits)&&(l.edits=n.edits.map(u=>({oldString:u.oldString??u.old_string,newString:u.newString??u.new_string,replaceAll:!!(u.replaceAll??u.replace_all)}))),l}getApprovalReason(){return"Pode alterar trechos especificos de arquivos no workspace permitido."}async execute(n,a={}){if(!r.tools.fileWriteEnabled)throw new Error("File edit tool is disabled by configuration");let s=Gu(n);if(s.length===0)throw new Error("Nada para editar: forneca oldString/newString ou uma lista 'edits'.");let i=I(r.tools.fileRoot,n.path),c=await Ea(i).catch(()=>null);if(c?.isDirectory())throw new Error(`file_edit nao pode editar diretorio: ${i}`);let l="",u=!1;if(c?.isFile())u=!0,l=await zu(i,"utf8"),Xu({filePath:i,currentContent:l,currentMtime:c.mtimeMs,readFileState:a.readFileState});else if(!(s.length===1&&s[0].oldString===""))throw new Error(`Arquivo nao existe: ${i}. Use oldString vazio apenas para criar arquivo novo.`);let m=[];if(e?.isConfigured())try{m=(await e.run({operation:"diagnostics",filePath:i})).result?.diagnostics||[]}catch{}let f=l,g=[];s.forEach((R,h)=>{if(R.oldString===R.newString)throw new Error(`Edicao ${h+1}: oldString e newString sao identicos.`);let{after:A,strategy:M}=Wu(f,R.oldString,R.newString,R.replaceAll,h+1);f=A,g.push(M)});let w=f;await Bu(_a.dirname(i),{recursive:!0}),await Hu(i,w,"utf8");let y=await Ea(i);a.readFileState?.set(i,{content:w,timestamp:y.mtimeMs,size:y.size,isPartialView:!1,readAt:new Date().toISOString()});let b=_a.relative(r.tools.fileRoot,i)||i,E=Kt({filePath:b,before:l,after:w}),k={path:i,mode:u?"edit":"create",editsApplied:s.length,matchStrategies:g,diff:$a(E,2e4),changes:Xt(E)};if(g.includes("fuzzy")&&(k.note="Uma ou mais edicoes casaram por indentacao (fuzzy), nao por match exato."),e?.isConfigured())try{await new Promise(P=>setTimeout(P,800));let M=((await e.run({operation:"diagnostics",filePath:i})).result?.diagnostics||[]).filter(P=>!m.some(Y=>Y.message===P.message&&Y.line===P.line)).filter(P=>P.severity==="error"||P.severity==="warning");M.length>0&&(k.diagnosticsWarning=`[ALERTA DE SEGURANCA LSP] Sua alteracao introduziu ${M.length} novo(s) erro(s)/aviso(s)! Conserte imediatamente:
457
+ `+M.map(P=>` - [${P.severity.toUpperCase()}] Linha ${P.line}: ${P.message}`).join(`
458
+ `))}catch{}return k}}return new t}function Gu(r){return Array.isArray(r.edits)&&r.edits.length>0?r.edits.map(e=>({oldString:e.oldString??"",newString:e.newString??"",replaceAll:!!e.replaceAll})):r.oldString!==void 0&&r.newString!==void 0?[{oldString:r.oldString,newString:r.newString,replaceAll:!!r.replaceAll}]:[]}function Wu(r,e,t,o,n){if(e===""){if(r.trim()!=="")throw new Error(`Edicao ${n}: oldString vazio so pode criar/preencher arquivo vazio.`);return{after:t,strategy:"create"}}let a=Ku(r,e);if(a===1||a>1&&o)return{after:o?r.split(e).join(t):r.replace(e,t),strategy:"exact"};if(a>1&&!o)throw new Error(`Edicao ${n}: oldString apareceu ${a} vezes. Forneca mais contexto ou use replaceAll=true.`);let s=Vu(r,e);if(s.length===1||s.length>1&&o){let i=o?s:[s[0]],c=r;for(let l=i.length-1;l>=0;l-=1)c=c.slice(0,i[l].startChar)+t+c.slice(i[l].endChar);return{after:c,strategy:"fuzzy"}}throw s.length>1&&!o?new Error(`Edicao ${n}: match por indentacao encontrou ${s.length} ocorrencias. Use replaceAll=true ou mais contexto.`):new Error(`Edicao ${n}: texto nao encontrado (nem exato nem por indentacao). oldString: ${$a(e,400)}`)}function Vu(r,e){let t=r.split(`
459
+ `),o=e.replace(/\n$/,"").split(`
460
+ `).map(i=>i.trim());if(o.length===0)return[];let n=[],a=0;for(let i of t)n.push(a),a+=i.length+1;let s=[];for(let i=0;i+o.length<=t.length;i+=1){let c=!0;for(let l=0;l<o.length;l+=1)if(t[i+l].trim()!==o[l]){c=!1;break}if(c){let l=i+o.length-1;s.push({startChar:n[i],endChar:n[l]+t[l].length})}}return s}function Ku(r,e){if(!e)return 0;let t=0,o=0;for(;o=r.indexOf(e,o),o!==-1;)t+=1,o+=e.length;return t}function Xu({filePath:r,currentContent:e,currentMtime:t,readFileState:o}){let n=o?.get(r);if(!n||n.isPartialView)throw new Error(`Arquivo precisa ser lido por completo antes de editar: ${r}. Use file_read sem startLine/endLine.`);if(t>n.timestamp&&e!==n.content)throw new Error(`Arquivo mudou desde a ultima leitura: ${r}. Use file_read novamente antes de editar.`)}function $a(r,e){let t=String(r||"");return t.length<=e?t:`${t.slice(0,e-3)}...`}import{copyFile as Yu,stat as Aa}from"node:fs/promises";function Ra({config:r}){class e extends j{constructor(){super({name:"file_copy",description:`Copia um arquivo de um caminho para outro dentro do diretorio permitido: ${r.tools.fileRoot}. Muito util para duplicar arquivos sem precisar ler o conteudo e gastar tokens.`,requiresApproval:!0,inputSchema:{type:"object",required:["sourcePath","destinationPath"],additionalProperties:!1,properties:{sourcePath:{type:"string",minLength:1,maxLength:1e3},destinationPath:{type:"string",minLength:1,maxLength:1e3}}},risk:"write",maxResultSizeChars:5e3,searchHint:"copy, duplicate, move files"}),this.risk="dangerous",this.approvalReason="Pode criar e sobrescrever arquivos no workspace permitido durante a copia."}async execute(o,n={}){if(!r.tools.fileWriteEnabled)throw new Error("File write/copy tool is disabled by configuration");let a=I(r.tools.fileRoot,o.sourcePath),s=I(r.tools.fileRoot,o.destinationPath),i=await Aa(a).catch(()=>null);if(!i)throw new Error(`Source file does not exist: ${o.sourcePath}`);if(i.isDirectory())throw new Error(`Cannot copy a directory with this tool: ${o.sourcePath}. Use run_command with cp -r.`);if((await Aa(s).catch(()=>null))?.isDirectory())throw new Error(`Destination is a directory: ${o.destinationPath}. You must provide the full file path including the filename.`);return await Yu(a,s),{success:!0,source:a,destination:s,bytesCopied:i.size}}}return new e}import{isIP as La}from"node:net";import{lookup as Ju}from"node:dns/promises";var Qu=new Set(["localhost","localhost.localdomain","ip6-localhost","ip6-loopback"]);function Ca(r){let e=La(r);return e===4?Oa(r):e===6?Zu(r):!1}function Oa(r){let e=r.split(".").map(n=>Number.parseInt(n,10));if(e.length!==4||e.some(n=>Number.isNaN(n)||n<0||n>255))return!0;let[t,o]=e;return t===0||t===10||t===127||t===169&&o===254||t===172&&o>=16&&o<=31||t===192&&o===168||t===100&&o>=64&&o<=127||t>=224}function Zu(r){let e=r.toLowerCase().split("%")[0];if(e==="::1"||e==="::")return!0;let t=e.match(/::ffff:(\d+\.\d+\.\d+\.\d+)$/);if(t)return Oa(t[1]);let o=e.slice(0,4);return!!(o.startsWith("fc")||o.startsWith("fd")||o.startsWith("fe8")||o.startsWith("fe9")||o.startsWith("fea")||o.startsWith("feb"))}async function Oe(r,{resolveDns:e=!0}={}){let t;try{t=new URL(r)}catch{throw new Error(`URL invalida: ${r}`)}if(!["http:","https:"].includes(t.protocol))throw new Error(`Protocolo nao permitido: ${t.protocol} (use http/https)`);let o=t.hostname.replace(/^\[|\]$/g,"").toLowerCase();if(Qu.has(o))throw new Error(`Host bloqueado (loopback): ${o}`);if(La(o)){if(Ca(o))throw new Error(`IP interno/privado bloqueado: ${o}`);return t}if(!e)return t;let n;try{n=await Ju(o,{all:!0})}catch(a){throw new Error(`Falha ao resolver host ${o}: ${a.message}`)}for(let{address:a}of n)if(Ca(a))throw new Error(`Host ${o} resolve para IP interno/privado (${a}) \u2014 bloqueado`);return t}async function Jt(r,e={},{maxRedirects:t=5}={}){let o=(await Oe(r)).toString(),n=0;for(;;){let a=await fetch(o,{...e,redirect:"manual"});if(!(a.status>=300&&a.status<400&&a.headers.has("location")))return a;if(n>=t)throw new Error(`Excesso de redirects (max ${t})`);n+=1;let i=new URL(a.headers.get("location"),o).toString();o=(await Oe(i)).toString()}}function Ma({config:r}){return{name:"http_request",description:"Executa uma requisicao HTTP controlada e retorna status, headers e corpo textual limitado.",risk:"network",requiresApproval:!0,approvalReason:"Pode enviar requisicoes para servicos externos.",inputSchema:{type:"object",required:["url"],additionalProperties:!1,properties:{url:{type:"string",format:"uri",minLength:1,maxLength:2e3},method:{type:"string",enum:["GET","POST","PUT","PATCH","DELETE","HEAD"]},headers:{type:"object",additionalProperties:{type:"string"}},body:{type:"string",maxLength:1e6}}},async execute(e,{signal:t}={}){let o=(e.method||"GET").toUpperCase();if(!r.tools.httpAllowedMethods.includes(o))throw new Error(`HTTP method ${o} is not allowed`);let n=await Jt(e.url,{method:o,headers:ed(e.headers||{}),body:o==="GET"||o==="HEAD"?void 0:e.body,signal:t}),a=await td(n,r.tools.httpMaxBytes);return{url:n.url,status:n.status,ok:n.ok,headers:Object.fromEntries(n.headers.entries()),body:a}}}}function ed(r){let e=new Set(["authorization","cookie","set-cookie"]),t={};for(let[o,n]of Object.entries(r||{}))e.has(o.toLowerCase())||(t[o]=String(n));return t}async function td(r,e){if(!r.body)return"";let t=r.body.getReader(),o=[],n=0;for(;;){let{value:i,done:c}=await t.read();if(c)break;if(n+=i.byteLength,n>e)throw new Error(`HTTP response too large. Max allowed: ${e} bytes`);o.push(i)}let a=new Uint8Array(n),s=0;for(let i of o)a.set(i,s),s+=i.byteLength;return new TextDecoder().decode(a)}function Pa({memoryManager:r}){return{name:"memory_save",description:"Salva uma memoria persistente quando houver um fato duravel, preferencia ou decisao importante.",inputSchema:{type:"object",required:["content"],additionalProperties:!1,properties:{content:{type:"string",minLength:1,maxLength:4e3},tags:{type:"array",maxItems:10,items:{type:"string",maxLength:60}},importance:{type:"integer",minimum:1,maximum:5}}},async execute(e){return{saved:!0,memory:await r.saveMemory({content:e.content,tags:e.tags||["agent"],importance:e.importance||2,metadata:{source:"tool"}})}}}}function Ia({memoryManager:r}){return{name:"memory_search",description:"Busca memorias persistentes relevantes do agente.",inputSchema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",minLength:1,maxLength:500},limit:{type:"integer",minimum:1,maximum:20}}},async execute(e){let t=await r.searchMemory({query:e.query,limit:e.limit||6});return{query:e.query,memories:t}}}}import{mkdir as rd}from"node:fs/promises";import Na from"node:path";function qa({config:r}){return{name:"playwright_browser",description:"Abre uma pagina com Playwright, executa acoes simples e extrai texto, HTML, titulo ou screenshot.",risk:"browser",requiresApproval:!0,approvalReason:"Pode abrir paginas externas e interagir com sites.",timeoutMs:Math.max(r.tools.playwrightNavigationTimeoutMs+r.tools.playwrightActionTimeoutMs*2,2e4),inputSchema:{type:"object",required:["url"],additionalProperties:!1,properties:{url:{type:"string",format:"uri",minLength:1,maxLength:2e3},actions:{type:"array",maxItems:12,items:{type:"object",required:["type"],additionalProperties:!1,properties:{type:{type:"string",enum:["click","fill","press","wait","select","evaluate"]},selector:{type:"string",maxLength:1e3},value:{type:"string",maxLength:4e3},ms:{type:"integer",minimum:0,maximum:1e4},script:{type:"string",maxLength:4e3}}}},extract:{type:"string",enum:["text","html","title","screenshot"]}}},async execute(e){await Oe(e.url);let t=await import("playwright").catch(()=>null);if(!t)throw new Error("Playwright is not installed. Run `bun install` to install optional dependencies.");let o=await t.chromium.launch({headless:r.tools.playwrightHeadless});try{let n=await o.newPage();n.setDefaultTimeout(r.tools.playwrightActionTimeoutMs),n.setDefaultNavigationTimeout(r.tools.playwrightNavigationTimeoutMs),await n.goto(e.url,{waitUntil:"domcontentloaded",timeout:r.tools.playwrightNavigationTimeoutMs});for(let c of e.actions||[])await od(n,c,r.tools.playwrightActionTimeoutMs);let a=e.extract||"text",s=await n.title();if(a==="title")return{url:n.url(),title:s};if(a==="html"){let c=await n.content();return{url:n.url(),title:s,html:c.slice(0,5e4),truncated:c.length>5e4}}if(a==="screenshot"){let c=Na.join(r.storage.dataDir,"screenshots");await rd(c,{recursive:!0});let l=Na.join(c,`${F("shot")}.png`);return await n.screenshot({path:l,fullPage:!0}),{url:n.url(),title:s,screenshotPath:l}}let i=await n.locator("body").innerText({timeout:5e3}).catch(()=>"");return{url:n.url(),title:s,text:i.slice(0,3e4),truncated:i.length>3e4}}finally{await o.close()}}}}async function od(r,e,t){if(e.type==="wait"){await r.waitForTimeout(e.ms||1e3);return}if(e.type==="evaluate"){if(!nd())throw new Error("Playwright evaluate action is disabled. Set PLAYWRIGHT_ALLOW_EVALUATE=true to enable it.");await r.evaluate(e.script||"");return}if(!e.selector)throw new Error(`Selector is required for action ${e.type}`);let o={timeout:t};e.type==="click"&&await r.click(e.selector,o),e.type==="fill"&&await r.fill(e.selector,e.value||"",o),e.type==="press"&&await r.press(e.selector,e.value||"Enter",o),e.type==="select"&&await r.selectOption(e.selector,e.value||"",o)}function nd(){return["1","true","yes","on"].includes(String(process.env.PLAYWRIGHT_ALLOW_EVALUATE||"").toLowerCase())}import ad from"better-sqlite3";import{mkdirSync as sd}from"node:fs";import id from"node:path";function ja({config:r}){let e;return{name:"sqlite",description:"Executa queries SQLite parametrizadas no banco de ferramentas configurado.",risk:"database",requiresApproval(t){let o=String(t.sql||"").trim().split(/\s+/,1)[0].toUpperCase();return r.tools.sqliteAllowWrite&&!["SELECT","PRAGMA","WITH"].includes(o)},approvalReason:"Pode alterar dados no banco SQLite de ferramentas.",inputSchema:{type:"object",required:["sql"],additionalProperties:!1,properties:{sql:{type:"string",minLength:1,maxLength:1e4},params:{type:"array",maxItems:50},maxRows:{type:"integer",minimum:1,maximum:500}}},async execute(t){e||=cd(r.tools.sqlitePath);let o=t.sql.trim(),n=t.params||[],a=o.split(/\s+/,1)[0].toUpperCase();if(ld(o))throw new Error("Only one SQL statement is allowed");if(!r.tools.sqliteAllowWrite&&!["SELECT","PRAGMA","WITH"].includes(a))throw new Error("SQLite write operations are disabled by configuration");if(["SELECT","PRAGMA","WITH"].includes(a)){let i=e.prepare(o).all(...n);return{kind:a,rows:i.slice(0,t.maxRows||100),rowCount:i.length,truncated:i.length>(t.maxRows||100)}}let s=e.prepare(o).run(...n);return{kind:a,changes:s.changes,lastInsertRowid:s.lastInsertRowid?.toString?.()||s.lastInsertRowid}}}}function cd(r){sd(id.dirname(r),{recursive:!0});let e=new ad(r);return e.pragma("journal_mode = WAL"),e}function ld(r){return r.replace(/;\s*$/,"").includes(";")}function Da({config:r}){return{name:"web_search",description:"Pesquisa na web usando o provedor configurado e retorna resultados resumidos.",risk:"network",isReadOnly:!0,isConcurrencySafe:!0,searchHint:"search the web",inputSchema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",minLength:1,maxLength:500},limit:{type:"integer",minimum:1,maximum:10}}},async execute(e,{signal:t}={}){let o=r.tools.webSearch.provider,n=e.limit||5;return o==="brave"?ud(r,e.query,n,t):o==="tavily"?dd(r,e.query,n,t):o==="searxng"?md(r,e.query,n,t):pd(e.query,n,t)}}}async function ud(r,e,t,o){if(!r.tools.webSearch.braveApiKey)throw new Error("BRAVE_SEARCH_API_KEY is required for Brave search");let n=new URL("https://api.search.brave.com/res/v1/web/search");n.searchParams.set("q",e),n.searchParams.set("count",String(t));let a=await Qt(n,{signal:o,headers:{accept:"application/json","x-subscription-token":r.tools.webSearch.braveApiKey}});return{provider:"brave",query:e,results:(a.web?.results||[]).slice(0,t).map(s=>({title:s.title,url:s.url,snippet:s.description}))}}async function dd(r,e,t,o){if(!r.tools.webSearch.tavilyApiKey)throw new Error("TAVILY_API_KEY is required for Tavily search");let n=await Qt("https://api.tavily.com/search",{method:"POST",signal:o,headers:{"content-type":"application/json"},body:JSON.stringify({api_key:r.tools.webSearch.tavilyApiKey,query:e,max_results:t})});return{provider:"tavily",query:e,results:(n.results||[]).slice(0,t).map(a=>({title:a.title,url:a.url,snippet:a.content}))}}async function md(r,e,t,o){if(!r.tools.webSearch.endpoint)throw new Error("WEB_SEARCH_ENDPOINT is required for SearXNG search");let n=new URL(r.tools.webSearch.endpoint);n.searchParams.set("q",e),n.searchParams.set("format","json");let a=await Qt(n,{signal:o});return{provider:"searxng",query:e,results:(a.results||[]).slice(0,t).map(s=>({title:s.title,url:s.url,snippet:s.content}))}}async function pd(r,e,t){let o=new URL("https://api.duckduckgo.com/");o.searchParams.set("q",r),o.searchParams.set("format","json"),o.searchParams.set("no_redirect","1"),o.searchParams.set("no_html","1");let n=await Qt(o,{signal:t}),a=Ua(n.RelatedTopics||[]);return{provider:"duckduckgo",query:r,abstract:n.AbstractText||"",results:a.slice(0,e)}}function Ua(r){let e=[];for(let t of r)t.Topics?e.push(...Ua(t.Topics)):(t.FirstURL||t.Text)&&e.push({title:t.Text?.split(" - ")[0]||t.FirstURL,url:t.FirstURL,snippet:t.Text});return e}async function Qt(r,e={}){let t=await fetch(r,e),o=await t.json().catch(()=>({}));if(!t.ok){let n=new Error(o.error?.message||`Search request failed with ${t.status}`);throw n.status=t.status,n}return o}import{readdir as hd,readFile as gd,stat as Ba}from"node:fs/promises";import{extname as yd,join as bd,relative as vd}from"node:path";import fd from"node:path";function Zr(r){let e=xe(r||"**/*"),t="^";for(let o=0;o<e.length;o+=1){let n=e[o],a=e[o+1];if(n==="*"&&a==="*"){e[o+2]==="/"?(t+="(?:.*\\/)?",o+=2):(t+=".*",o+=1);continue}if(n==="*"){t+="[^/]*";continue}if(n==="?"){t+="[^/]";continue}if(n==="{"){let s=e.indexOf("}",o+1);if(s!==-1){let i=e.slice(o+1,s).split(",").map(Fa).join("|");t+=`(?:${i})`,o=s;continue}}t+=Fa(n)}return t+="$",new RegExp(t,process.platform==="win32"?"i":"")}function eo(r,e){return Zr(e).test(xe(r))}function xe(r){return String(r||"").split(fd.sep).join("/")}function Fa(r){return String(r).replace(/[|\\{}()[\]^$+*?.]/g,"\\$&")}var wd=new Set(["node_modules",".git","dist","build",".next","coverage"]),Sd=new Set([".png",".jpg",".jpeg",".gif",".webp",".ico",".pdf",".mp4",".mov",".zip",".gz",".sqlite",".db",".exe",".dll"]);function za({config:r}){return{name:"grep_search",description:[`Pesquisa conteudo de arquivos no diretorio permitido (${r.tools.fileRoot}).`,"Suporta regex, glob, outputMode=content|files_with_matches|count, context, headLimit e offset.","Use antes de file_read para encontrar linhas exatas sem gastar contexto."].join(" "),risk:"read",isReadOnly:!0,isConcurrencySafe:!0,searchHint:"search file contents with regex",maxResultSizeChars:3e4,inputSchema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",minLength:1,description:"Termo ou regex de busca."},isRegex:{type:"boolean",description:"Se true, trata query como regex."},directory:{type:"string",description:"Subdiretorio relativo ao TOOL_FILE_ROOT."},glob:{type:"string",description:"Filtro de arquivos, ex: **/*.js ou *.{js,json}."},outputMode:{type:"string",enum:["content","files_with_matches","count"],description:"Padrao: content."},context:{type:"integer",minimum:0,maximum:20},before:{type:"integer",minimum:0,maximum:20},after:{type:"integer",minimum:0,maximum:20},caseInsensitive:{type:"boolean"},headLimit:{type:"integer",minimum:0,maximum:1e3},offset:{type:"integer",minimum:0}}},validate(e){let{pattern:t,output_mode:o,head_limit:n,case_insensitive:a,...s}=e;return Ed({...s,query:e.query??t,outputMode:e.outputMode??o,headLimit:e.headLimit??n,caseInsensitive:e.caseInsensitive??a})},async execute(e){let t=e.directory?I(r.tools.fileRoot,e.directory):r.tools.fileRoot,n=(await Ba(t)).isFile()?[t]:await Ha(t),a=xd(e),s=e.outputMode||"content",i=e.context??e.before??0,c=e.context??e.after??0,l=e.offset||0,u=e.headLimit??250,m=[],f=new Map;for(let y of n){if(Sd.has(yd(y).toLowerCase()))continue;let b=xe(vd(r.tools.fileRoot,y)||y);if(e.glob&&!eo(b,e.glob)&&!eo(y,e.glob))continue;let E=await Ba(y).catch(()=>null);if(!E?.isFile()||E.size>2e7)continue;let k;try{k=await gd(y,"utf8")}catch{continue}let R=k.split(/\r?\n/),h=!1;for(let A=0;A<R.length;A+=1)if(a.lastIndex=0,!!a.test(R[A])&&(h=!0,f.set(b,(f.get(b)||0)+1),s==="content")){let M=Math.max(0,A-i),P=Math.min(R.length-1,A+c);m.push({file:b,line:A+1,snippet:R[A].trim(),context:R.slice(M,P+1).map((Y,ce)=>({line:M+ce+1,text:Y}))})}h&&s==="files_with_matches"&&m.push({file:b})}let g=s==="count"?[...f.entries()].map(([y,b])=>({file:y,count:b})):m,w=u===0?g.slice(l):g.slice(l,l+u);return{status:"OK",query:e.query,mode:s,total:g.length,returned:w.length,offset:l,headLimit:u===0?null:u,truncated:u!==0&&l+u<g.length,results:w}}}}async function Ha(r){let e=[],t=await hd(r,{withFileTypes:!0}).catch(()=>[]);for(let o of t){if(wd.has(o.name))continue;let n=bd(r,o.name);o.isDirectory()?e.push(...await Ha(n)):o.isFile()&&e.push(n)}return e}function xd(r){try{return r.isRegex?new RegExp(r.query,r.caseInsensitive?"gi":"g"):new RegExp(Td(r.query),r.caseInsensitive?"gi":"g")}catch(e){throw new Error(`Regex invalido: ${e.message}`)}}function Td(r){return String(r).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ed(r){return Object.fromEntries(Object.entries(r).filter(([,e])=>e!==void 0))}import{readdir as _d,stat as kd}from"node:fs/promises";import{join as $d,relative as Ad}from"node:path";var Rd=new Set(["node_modules",".git","dist","build",".next","coverage"]);function Ga({config:r}){return{name:"glob_search",description:[`Encontra arquivos por padrao glob dentro do diretorio permitido (${r.tools.fileRoot}).`,"Use para localizar arquivos rapidamente por nome ou extensao, ex: **/*.js, src/**/login*."].join(" "),risk:"read",isReadOnly:!0,isConcurrencySafe:!0,searchHint:"find files by glob pattern",maxResultSizeChars:3e4,inputSchema:{type:"object",required:["pattern"],additionalProperties:!1,properties:{pattern:{type:"string",minLength:1,description:"Padrao glob. Ex: **/*.js"},directory:{type:"string",description:"Subdiretorio relativo ao TOOL_FILE_ROOT."},maxResults:{type:"integer",minimum:1,maximum:1e3},offset:{type:"integer",minimum:0}}},async execute(e){let t=e.directory?I(r.tools.fileRoot,e.directory):r.tools.fileRoot,n=(await kd(t)).isFile()?[t]:await Wa(t),a=Zr(e.pattern),s=e.offset||0,i=e.maxResults||100,c=[];for(let u of n){let m=xe(Ad(r.tools.fileRoot,u)||u);(a.test(m)||a.test(xe(u)))&&c.push(m)}let l=c.slice(s,s+i);return{pattern:e.pattern,total:c.length,returned:l.length,offset:s,maxResults:i,truncated:s+i<c.length,files:l}}}}async function Wa(r){let e=[],t=await _d(r,{withFileTypes:!0}).catch(()=>[]);for(let o of t){if(Rd.has(o.name))continue;let n=$d(r,o.name);o.isDirectory()?e.push(...await Wa(n)):o.isFile()&&e.push(n)}return e}var Va=["status","documentSymbols","workspaceSymbols","definition","references","hover","diagnostics"];function Ka({lspManager:r}){class e extends j{constructor(){super({name:"lsp_code",description:["Navega codigo com inteligencia de IDE/LSP.","Operacoes: status, documentSymbols, workspaceSymbols, definition, references, hover, diagnostics.","Quando nao houver servidor LSP configurado, usa fallback estatico para JS/TS."].join(" "),risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,maxResultSizeChars:6e4,searchHint:"code intelligence definitions references symbols hover diagnostics",inputSchema:{type:"object",required:["operation"],additionalProperties:!1,properties:{operation:{type:"string",enum:Va,description:"Operacao de inteligencia de codigo."},filePath:{type:"string",description:"Caminho relativo ao TOOL_FILE_ROOT. Obrigatorio para operacoes de arquivo."},query:{type:"string",description:"Busca de simbolo. Usado em workspaceSymbols ou como fallback para definition/references/hover."},line:{type:"integer",minimum:1,description:"Linha 1-based, igual ao editor."},character:{type:"integer",minimum:1,description:"Coluna 1-based, igual ao editor."},includeDeclaration:{type:"boolean",description:"Inclui a propria declaracao em references. Padrao true."},maxResults:{type:"integer",minimum:1,maximum:200,description:"Limite de resultados. Padrao 50."}}}})}validate(o){let n=o.operation;if(!Va.includes(n))throw new Error(`Operacao LSP invalida: ${n}`);if(["documentSymbols","diagnostics"].includes(n)&&!o.filePath)throw new Error(`filePath e obrigatorio para ${n}.`);if(["definition","references","hover"].includes(n)){if(!o.filePath)throw new Error(`filePath e obrigatorio para ${n}.`);if(!o.query&&(!o.line||!o.character))throw new Error(`${n} precisa de line e character, ou query para fallback estatico.`)}return{...o,includeDeclaration:o.includeDeclaration??!0,maxResults:o.maxResults||50}}getActivityDescription(o={}){return`analisando codigo: ${o.operation}${o.filePath?` ${o.filePath}`:""}`}async execute(o){if(!r)throw new Error("LSP Manager is not configured or not available in this environment.");return r.run(o)}}return new e}import{spawn as Hd}from"node:child_process";var Cd=new Set(["cat","cd","dir","echo","find","findstr","git","grep","head","ls","pwd","rg","select-string","stat","tail","tree","type","where","where.exe","which","whoami","get-childitem","get-content","get-item","get-location","get-process","get-service","test-path","resolve-path"]),Ld=new Set(["branch","diff","grep","log","ls-files","rev-parse","show","status"]),Od=new Set(["bun","cargo","chmod","chown","cp","go","make","mkdir","mv","npm","pnpm","python","python3","node","rmdir","touch","yarn"]),Md=[{pattern:/\brm\s+-[^\n;|&]*[rR][^\n;|&]*f|\brm\s+-[^\n;|&]*f[^\n;|&]*[rR]/,warning:"Pode apagar arquivos recursivamente e sem confirmacao."},{pattern:/\bgit\s+reset\s+--hard\b/i,warning:"Pode descartar alteracoes locais nao commitadas."},{pattern:/\bgit\s+clean\b(?![^\n;|&]*(?:-n|--dry-run))[^\n;|&]*-.*f/i,warning:"Pode apagar arquivos nao rastreados pelo Git."},{pattern:/\bgit\s+push\b[^\n;|&]*(--force|--force-with-lease|-f)\b/i,warning:"Pode sobrescrever historico remoto."},{pattern:/\bgit\s+(checkout|restore)\s+(--\s+)?\./i,warning:"Pode descartar alteracoes no workspace."},{pattern:/\b(drop|truncate)\s+(table|database|schema)\b/i,warning:"Pode destruir objetos de banco de dados."},{pattern:/\bdelete\s+from\s+\w+\s*(;|$)/i,warning:"Pode deletar todas as linhas de uma tabela."},{pattern:/\bterraform\s+destroy\b/i,warning:"Pode destruir infraestrutura."},{pattern:/\bkubectl\s+delete\b/i,warning:"Pode deletar recursos Kubernetes."},{pattern:/\bformat\s+[a-z]:/i,warning:"Pode formatar uma unidade."},{pattern:/\bdel\s+\/[fsq]/i,warning:"Pode apagar arquivos no Windows sem confirmacao."},{pattern:/\bRemove-Item\b[^\n;|&]*(-Recurse|-Force)/i,warning:"Pode apagar arquivos no PowerShell."}],Pd=/\$\(|\$\{|<\(|>\(|`/,Id=new Set(["-delete","-exec","-execdir","-ok","-okdir","-fprint","-fprintf","-fls"]),Nd=[/>\s*\S+/,/>>\s*\S+/,/\|\s*tee\b/i,/\bsed\b[^\n;|&]*\s-i\b/i,/\bSet-Content\b/i,/\bAdd-Content\b/i,/\bNew-Item\b/i,/\bCopy-Item\b/i,/\bMove-Item\b/i];function ie(r){let e=String(r||"").trim();if(!e)return{risk:"read",readOnly:!0,warning:null,reason:"Comando vazio."};let t=Md.find(({pattern:n})=>n.test(e));if(t)return{risk:"dangerous",readOnly:!1,warning:t.warning,reason:t.warning};if(Pd.test(e))return{risk:"write",readOnly:!1,warning:"Comando usa substituicao de comando ($(), crase ou ${}); requer aprovacao.",reason:"Substituicao de comando presente \u2014 classificacao segura como escrita."};if(Nd.some(n=>n.test(e)))return{risk:"write",readOnly:!1,warning:"Comando escreve em arquivo ou altera estado.",reason:"Comando contem redirecionamento/escrita."};let o=Me(e);if(o.length===0)return{risk:"write",readOnly:!1,warning:"Nao foi possivel classificar o comando.",reason:"Classificacao inconclusiva."};for(let n of o){let a=qd(n);if(a){if(a==="git"){let s=to(n)[1]||"";if(!Ld.has(s.toLowerCase()))return{risk:"write",readOnly:!1,warning:`git ${s||""}`.trim()+" pode alterar estado.",reason:"Subcomando git nao e somente leitura."};continue}if(a==="find"){if(to(n).map(i=>i.toLowerCase()).some(i=>Id.has(i)))return{risk:"dangerous",readOnly:!1,warning:"find com -delete/-exec pode apagar ou executar comandos.",reason:"find usa flag destrutiva/executora."};continue}if(Od.has(a))return{risk:"write",readOnly:!1,warning:`${a} pode alterar arquivos, instalar dependencias ou executar codigo.`,reason:`Comando ${a} requer aprovacao.`};if(!Cd.has(a))return{risk:"write",readOnly:!1,warning:`Comando ${a} nao esta na allowlist de leitura.`,reason:"Comando fora da allowlist read-only."}}}return{risk:"read",readOnly:!0,warning:null,reason:"Comando classificado como somente leitura."}}function Me(r){return String(r||"").split(/&&|\|\||[;\n|&]/).map(e=>e.trim()).filter(Boolean).filter(e=>!/^[<>]/.test(e))}function qd(r){let e=to(r).find(t=>!/^[A-Za-z_][A-Za-z0-9_]*=/.test(t));return jd(e||"")}function to(r){return String(r||"").trim().split(/\s+/).filter(Boolean)}function jd(r){return String(r||"").replace(/^['"]|['"]$/g,"").replace(/\.(exe|cmd|bat|ps1)$/i,"").toLowerCase()}var Dd=new Set(["curl","wget","nc","ncat","netcat","telnet","ftp","tftp","invoke-webrequest","iwr","invoke-restmethod","irm","start-bitstransfer"]),Ud=[{pattern:/node_modules[\\/]+rivale(?![\w-])/i,reason:"acesso ao pacote instalado do Rivale (codigo proprietario) nao e permitido."},{pattern:/(^|[\s"'`=(/\\])rivale[\\/]+dist([\\/]|\b)/i,reason:"acesso ao bundle distribuido do Rivale (dist/cli.js) nao e permitido."}],Fd=[{pattern:/(^|[\s;|&(])sudo(\s|$)/i,reason:"sudo (escalada de privilegio) nao e permitido."},{pattern:/(^|[\s;|&(])su(\s|$)/i,reason:"su (troca de usuario) nao e permitido."},{pattern:/\|\s*(sh|bash|zsh|ksh|dash|fish|pwsh|powershell|python[0-9.]*|perl|ruby|node)\b/i,reason:"pipe para um interpretador (executar conteudo baixado) nao e permitido."},{pattern:/\b(iex|invoke-expression)\b/i,reason:"Invoke-Expression (execucao dinamica) nao e permitido."},{pattern:/\beval\s/i,reason:"eval (execucao dinamica) nao e permitido."},{pattern:/file:\/\//i,reason:"esquema file:// (leitura de arquivo local via rede) nao e permitido."}];function Ya(r){let e=String(r||"").trim().split(/\s+/).find(t=>!/^[A-Za-z_][A-Za-z0-9_]*=/.test(t));return String(e||"").replace(/^['"]|['"]$/g,"").replace(/\.(exe|cmd|bat|ps1)$/i,"").toLowerCase()}function Xa(r){return String(r).replace(/[)>\]}'";,]+$/,"")}function Bd(r){let e=[],t=/\bhttps?:\/\/[^\s'"`|;&]+/gi,o;for(;o=t.exec(r);)e.push(Xa(o[0]));let n=/(?<![\w.])(localhost|127(?:\.\d{1,3}){3}|10(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2}|169\.254(?:\.\d{1,3}){2}|0\.0\.0\.0)(?::\d+)?/gi;for(;o=n.exec(r);)e.push(`http://${Xa(o[0])}`);return[...new Set(e)]}function zd(r,{allowDangerous:e,denylist:t,allowlist:o}){let n=String(r||"");for(let{pattern:a,reason:s}of Ud)if(a.test(n))return{blocked:!0,reason:s};if(!e){for(let{pattern:a,reason:s}of Fd)if(a.test(n))return{blocked:!0,reason:s}}for(let a of t)try{if(new RegExp(a,"i").test(n))return{blocked:!0,reason:`Comando na denylist: /${a}/`}}catch{}if(Array.isArray(o)&&o.length)for(let a of Me(n)){let s=Ya(a);if(s&&!o.includes(s))return{blocked:!0,reason:`Comando "${s}" fora da allowlist configurada.`}}return null}async function Zt(r,e={}){let t=e.tools||{},o={allowDangerous:t.allowDangerousCommands===!0,denylist:Array.isArray(t.commandDenylist)?t.commandDenylist:[],allowlist:Array.isArray(t.commandAllowlist)?t.commandAllowlist:[]},n=zd(r,o);if(n)return n;if(t.blockPrivateEgress===!1)return{blocked:!1};let a=String(r||"");if(!Me(a).some(i=>Dd.has(Ya(i))))return{blocked:!1};for(let i of Bd(a))try{await Oe(i)}catch(c){return{blocked:!0,reason:`egress de rede bloqueado (SSRF): ${c.message}`}}return{blocked:!1}}var ro=class{constructor(){this.tasks=new Map,this.nextId=1}start(e,t,o){let n=`task_${this.nextId++}`,a=Hd(e,t,{cwd:o,shell:!0}),s={id:n,child:a,command:`${e} ${t.join(" ")}`.trim(),status:"running",stdout:"",stderr:"",exitCode:null,error:null};return a.stdout.on("data",i=>{s.stdout+=i.toString(),s.stdout.length>1e5&&(s.stdout=s.stdout.slice(-1e5))}),a.stderr.on("data",i=>{s.stderr+=i.toString(),s.stderr.length>1e5&&(s.stderr=s.stderr.slice(-1e5))}),a.on("error",i=>{s.status="error",s.error=i.message}),a.on("close",i=>{s.status==="running"&&(s.status="stopped"),s.exitCode=i}),this.tasks.set(n,s),s}get(e){return this.tasks.get(e)}list(){return Array.from(this.tasks.values()).map(e=>({id:e.id,command:e.command,status:e.status,exitCode:e.exitCode}))}kill(e){let t=this.tasks.get(e);if(!t)throw new Error(`Task ${e} not found`);return t.status==="running"&&(t.child.kill("SIGTERM"),t.status="killed"),t}},tr=new ro;function Ja({config:r}){return{name:"start_background_task",description:"Inicia um processo em segundo plano (como servidores, testes ou bash longo) e retorna o taskId. Permite execucao assincrona de bash.",risk:"write",requiresApproval(e){return ie(er(e)).risk!=="read"},getRisk(e={}){return ie(er(e)).risk},getApprovalReason(e={}){let t=ie(er(e));return t.warning||t.reason||"Processo em segundo plano requer aprovacao."},inputSchema:{type:"object",required:["command"],properties:{command:{type:"string"},args:{type:"array",items:{type:"string"}},directory:{type:"string",description:"Diretorio relativo ao TOOL_FILE_ROOT. Padrao: raiz."}}},async execute(e){let t=await Zt(er(e),r);if(t.blocked)throw new Error(`Comando bloqueado por seguranca: ${t.reason}`);let o=e.directory?I(r.tools.fileRoot,e.directory):r.tools.fileRoot,n=tr.start(e.command,e.args||[],o);return{taskId:n.id,command:n.command,cwd:o,status:n.status}}}}function Qa(){return{name:"read_task_logs",description:"Le os logs (stdout e stderr) de um processo em segundo plano rodando no sistema.",risk:"read",isReadOnly:!0,inputSchema:{type:"object",required:["taskId"],properties:{taskId:{type:"string"}}},async execute(r){let e=tr.get(r.taskId);if(!e)throw new Error(`Task ${r.taskId} not found`);return{taskId:e.id,status:e.status,exitCode:e.exitCode,stdout:e.stdout.slice(-1e4),stderr:e.stderr.slice(-1e4)}}}}function Za(){return{name:"kill_background_task",description:"Encerra (mata) um processo em segundo plano.",risk:"write",inputSchema:{type:"object",required:["taskId"],properties:{taskId:{type:"string"}}},async execute(r){let e=tr.kill(r.taskId);return{taskId:e.id,status:e.status}}}}function es(){return{name:"list_background_tasks",description:"Lista todos os processos em segundo plano ativos ou parados.",risk:"read",isReadOnly:!0,inputSchema:{type:"object",properties:{}},async execute(){return{tasks:tr.list()}}}}function er(r={}){return[r.command,...r.args||[]].filter(Boolean).join(" ")}import{exec as Gd}from"node:child_process";import{promisify as Wd}from"node:util";var Vd=Wd(Gd),Kd=15e3,ts=12e4,rs=3e4;function as({config:r}){return{name:"run_command",description:["Executa um comando de terminal no diretorio permitido.","Classifica risco automaticamente: read, write ou dangerous.","Use para comandos curtos como bun test, git status, npm run build. Para servidores longos, use start_background_task."].join(" "),inputSchema:{type:"object",required:["command"],additionalProperties:!1,properties:{command:{type:"string",minLength:1,maxLength:4e3,description:"Comando a executar"},directory:{type:"string",description:"Diretorio relativo ao TOOL_FILE_ROOT. Padrao: raiz."},timeoutMs:{type:"integer",minimum:1e3,maximum:ts,description:"Timeout em ms. Padrao 15000."}}},risk:"write",requiresApproval(e){return ie(e.command).risk!=="read"},getRisk(e={}){return ie(e.command).risk},getApprovalReason(e={}){let t=ie(e.command);return t.warning||t.reason||"Comando de terminal requer aprovacao."},isReadOnly(e={}){return ie(e.command).readOnly},getActivityDescription(e={}){return`executando ${e.command||"comando"}`},async execute(e){let t=await Zt(e.command,r);if(t.blocked)return{status:"error",blocked:!0,command:e.command,message:`Comando bloqueado por politica de seguranca: ${t.reason}`};let o=e.directory?I(r.tools.fileRoot,e.directory):r.tools.fileRoot,n=Math.min(e.timeoutMs||Kd,ts),a=ie(e.command);try{let{stdout:s,stderr:i}=await Vd(e.command,{cwd:o,timeout:n,maxBuffer:5242880});return os({status:"success",command:e.command,cwd:o,classification:a,stdout:s,stderr:i,timeoutMs:n})}catch(s){let i=s.killed&&s.signal==="SIGTERM";return os({status:"error",command:e.command,cwd:o,classification:a,exitCode:s.code,message:i?`O comando atingiu o tempo limite de ${n}ms e foi interrompido.`:s.message,stdout:s.stdout||"",stderr:s.stderr||"",timeoutMs:n,timedOut:i})}}}}function os({stdout:r="",stderr:e="",...t}){let o=String(r).trimEnd(),n=String(e).trimEnd(),a=o.length+n.length;if(a<=rs)return{...t,stdout:o,stderr:n,truncated:!1};let s=Math.floor(rs/2);return{...t,stdout:ns(o,s),stderr:ns(n,s),outputBytes:a,truncated:!0,note:"Saida muito grande; retornando inicio e fim do stdout/stderr."}}function ns(r,e){let t=String(r||"");if(t.length<=e)return t;let o=Math.floor(e/2),n=e-o-32;return`${t.slice(0,o)}
461
+ ...[truncated ${t.length-e} chars]...
462
+ ${t.slice(-n)}`}import{createInterface as Xd}from"node:readline/promises";function ss(){return{name:"ask_human",description:"Faz uma pergunta ao usuario no terminal e aguarda a resposta. Use para esclarecer dependencias, ambiguidades, pedir chaves de API ou tomar decisoes criticas de arquitetura.",risk:"read",isConcurrencySafe:!1,timeoutMs:36e5,inputSchema:{type:"object",required:["question"],properties:{question:{type:"string",description:"A pergunta ou pedido de aprovacao para o usuario."}}},async execute(r,e={}){if(typeof e.humanPrompt=="function"){let o=await e.humanPrompt(r.question);return{status:"success",userAnswer:String(o||"").trim()}}console.log(`
463
+ \x1B[1m\x1B[33m========================================\x1B[0m`),console.log("\x1B[1m\x1B[33m\u26A0\uFE0F AGENTE PEDE AJUDA: \x1B[0m"),console.log(`\x1B[33m${r.question}\x1B[0m`),console.log(`\x1B[1m\x1B[33m========================================\x1B[0m
464
+ `);let t=Xd({input:process.stdin,output:process.stdout});try{return{status:"success",userAnswer:(await t.question("\x1B[1m\x1B[36m> Sua resposta:\x1B[0m ")).trim()}}finally{t.close()}}}}import{readdir as Yd,readFile as Jd}from"node:fs/promises";import{join as is,extname as Qd}from"node:path";async function cs(r){let e=[],t=await Yd(r,{withFileTypes:!0});for(let o of t){if(o.name==="node_modules"||o.name===".git"||o.name==="dist")continue;let n=is(r,o.name);o.isDirectory()?e.push(...await cs(n)):e.push(n)}return e}function ls({storage:r,config:e}){return{name:"index_codebase",description:"Varre os arquivos do reposit\xF3rio (JS/TS) construindo uma \xE1rvore sint\xE1tica abstrata (AST) simplificada em banco de dados. Extrai declara\xE7\xF5es de fun\xE7\xF5es e classes.",inputSchema:{type:"object",properties:{directory:{type:"string",description:"Diret\xF3rio base a ser varrido. Padr\xE3o: src do agente."}}},async execute(t){let o=t.directory||is(e.tools.fileRoot,"src");r.run(`
465
+ CREATE TABLE IF NOT EXISTS ast_nodes (
466
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
467
+ node_type TEXT,
468
+ name TEXT,
469
+ file_path TEXT,
470
+ line_number INTEGER,
471
+ snippet TEXT
472
+ )
473
+ `),r.run("DELETE FROM ast_nodes");let n=await cs(o).catch(()=>[]),a=0,s=[{type:"class",regex:/class\s+([A-Za-z0-9_]+)/},{type:"function",regex:/function\s+([A-Za-z0-9_]+)/},{type:"const_func",regex:/(?:const|let|var)\s+([A-Za-z0-9_]+)\s*=\s*(?:async\s*)?(?:\([^)]*\)|[A-Za-z0-9_]+)\s*=>/}];for(let i of n)if([".js",".ts",".jsx",".tsx"].includes(Qd(i)))try{let l=(await Jd(i,"utf8")).split(`
474
+ `);for(let u=0;u<l.length;u++){let m=l[u];for(let{type:f,regex:g}of s){let w=m.match(g);if(w){let y=w[1],b=l.slice(u,u+5).join(`
475
+ `);r.run("INSERT INTO ast_nodes (node_type, name, file_path, line_number, snippet) VALUES (?, ?, ?, ?, ?)",[f,y,i,u+1,b]),a++}}}}catch{}return{status:"indexed",totalNodes:a,rootDirectory:o}}}}function us({storage:r}){return{name:"ast_search",description:"Busca na estrutura AST indexada do c\xF3digo por nomes de fun\xE7\xF5es ou classes.",inputSchema:{type:"object",required:["query"],properties:{query:{type:"string",description:"Nome exato ou parcial da fun\xE7\xE3o/classe."}}},async execute(e){try{return{results:r.query("SELECT * FROM ast_nodes WHERE name LIKE ? LIMIT 20",[`%${e.query}%`])}}catch(t){throw t.message.includes("no such table")?new Error("Tabela ast_nodes n\xE3o existe. Execute a ferramenta index_codebase primeiro."):t}}}}import{execFile as Zd}from"node:child_process";import{promisify as em}from"node:util";var tm=em(Zd),oo=6e4;async function Z(r,e){try{let{stdout:t,stderr:o}=await tm("git",r,{cwd:e,maxBuffer:20971520,windowsHide:!0}),n=String(t||"").trimEnd();return o&&!n&&(n=String(o).trimEnd()),n.length>oo&&(n=`${n.slice(0,oo)}
476
+ \u2026 (saida truncada em ${oo} caracteres)`),n||"(sem saida)"}catch(t){let o=String(t.stderr||t.stdout||t.message||"").trim();throw/not a git repository/i.test(o)?new Error("Este diretorio nao e um repositorio git. Use git_commit com operation:init para criar um."):/'git' is not recognized|ENOENT/i.test(o)?new Error("git nao encontrado no PATH. Instale o Git para usar estas ferramentas."):new Error(o||"Falha ao executar git.")}}function ds({config:r}){let e=r.tools.fileRoot;return{name:"git",description:"Inspeciona o repositorio git (somente leitura): status, diff (working/staged), log, show, branch e branch atual. Use para entender o estado do repo antes de commitar.",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,searchHint:"git status diff log branch history",inputSchema:{type:"object",required:["operation"],additionalProperties:!1,properties:{operation:{type:"string",enum:["status","diff","log","show","branch","current_branch"],description:"status | diff | log | show | branch | current_branch"},staged:{type:"boolean",description:"diff: mostra o que esta staged (--staged) em vez do working tree"},path:{type:"string",maxLength:1e3,description:"diff/log: limita a um arquivo/pasta"},ref:{type:"string",maxLength:200,description:"show: commit/ref a exibir (ex: HEAD, abc123)"},limit:{type:"integer",minimum:1,maximum:100,description:"log: numero de commits (padrao 15)"}}},async execute(t){let o=t.operation,n=t.path?(I(e,t.path),t.path):null;switch(o){case"status":return{output:await Z(["status","--short","--branch"],e)};case"diff":{let a=["--no-pager","diff"];return t.staged&&a.push("--staged"),n&&a.push("--",n),{output:await Z(a,e)}}case"log":{let s=["--no-pager","log",`-n${t.limit||15}`,"--oneline","--decorate","--graph"];return n&&s.push("--",n),{output:await Z(s,e)}}case"show":return{output:await Z(["--no-pager","show","--stat",t.ref||"HEAD"],e)};case"branch":return{output:await Z(["branch","--all","-vv"],e)};case"current_branch":return{output:await Z(["rev-parse","--abbrev-ref","HEAD"],e)};default:throw new Error(`Operacao git desconhecida: ${o}`)}}}}function ms({config:r}){let e=r.tools.fileRoot;return{name:"git_commit",description:"Modifica o repositorio git: init (criar repo), add (stage de arquivos), commit (com mensagem) e branch (criar/trocar). NAO faz push nem operacoes destrutivas (reset --hard, clean). Exige aprovacao.",risk:"write",requiresApproval:!0,approvalReason:"Vai alterar o estado do repositorio git (stage/commit/branch/init).",searchHint:"git commit add stage branch init",inputSchema:{type:"object",required:["operation"],additionalProperties:!1,properties:{operation:{type:"string",enum:["init","add","commit","commit_all","branch"],description:"init | add | commit | commit_all (add -A + commit) | branch"},message:{type:"string",maxLength:2e3,description:"commit/commit_all: mensagem do commit"},paths:{type:"array",items:{type:"string",maxLength:1e3},maxItems:200,description:"add: arquivos/pastas a stagear (relativos ao root)"},branch:{type:"string",maxLength:200,description:"branch: nome do branch a criar/trocar"}}},async execute(t){let o=t.operation;switch(o){case"init":return{output:await Z(["init"],e)};case"add":{let n=Array.isArray(t.paths)&&t.paths.length?t.paths:["-A"];for(let a of n)a!=="-A"&&I(e,a);return{output:await Z(["add",...n],e)}}case"commit":{if(!t.message)throw new Error("commit exige 'message'.");return{output:await Z(["commit","-m",t.message],e)}}case"commit_all":{if(!t.message)throw new Error("commit_all exige 'message'.");return await Z(["add","-A"],e),{output:await Z(["commit","-m",t.message],e)}}case"branch":{if(!t.branch)throw new Error("branch exige 'branch' (nome).");return{output:await Z(["checkout","-B",t.branch],e)}}default:throw new Error(`Operacao git_commit desconhecida: ${o}`)}}}}function ps({toolRegistry:r}){return{name:"tool_search",description:"Pesquisa e CARREGA ferramentas disponiveis por palavra-chave. Ferramentas especialistas (marketing, youtube, lsp, etc.) nao vem carregadas por padrao para economizar tokens \u2014 use esta ferramenta para descobri-las e ativa-las antes de chama-las.",risk:"read",isReadOnly:!0,requiresApproval:!1,inputSchema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",minLength:1,maxLength:200},limit:{type:"integer",minimum:1,maximum:20}}},async execute(e){let t=String(e.query||"").toLowerCase().split(/\s+/).filter(Boolean),o=e.limit||8,n=r.list().filter(s=>s.name!=="tool_search").map(s=>{let i=r.describeTool(s),c=[i.name,i.description,i.searchHint,i.risk,i.readOnly?"read only readonly":"",i.concurrencySafe?"parallel concurrent":""].join(" ").toLowerCase(),l=t.reduce((u,m)=>u+(c.includes(m)?1:0),0);return{...i,score:l}}).filter(s=>s.score>0).sort((s,i)=>i.score-s.score||s.name.localeCompare(i.name)).slice(0,o).map(({score:s,...i})=>i),a=r.activate?.(n.map(s=>s.name))||[];return{query:e.query,total:n.length,matches:n,activated:a,note:a.length?`Ferramentas carregadas e agora disponiveis para chamar: ${a.join(", ")}.`:"Nenhuma ferramenta nova para carregar."}}}}function fs({skillManager:r}){class e extends j{constructor(){super({name:"skill_use",description:["Lista, busca ou carrega skills de engenharia em markdown.","Use antes de delegar ou executar tarefas especializadas como refatoracao, review, seguranca e testes.","Modos: list, search, read."].join(" "),risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,maxResultSizeChars:5e4,searchHint:"skills markdown procedures playbooks",inputSchema:{type:"object",required:["mode"],additionalProperties:!1,properties:{mode:{type:"string",enum:["list","search","read"],description:"list para listar, search para buscar, read para carregar uma skill."},query:{type:"string",description:"Texto de busca para mode=search."},skill:{type:"string",description:"Nome exato da skill para mode=read."},limit:{type:"integer",minimum:1,maximum:20,description:"Limite de resultados. Padrao 8."}}}})}validate(o){if(o.mode==="search"&&!o.query)throw new Error("query e obrigatorio para skill_use mode=search.");if(o.mode==="read"&&!o.skill)throw new Error("skill e obrigatorio para skill_use mode=read.");return{...o,limit:o.limit||8}}async execute(o){if(o.mode==="list"){let a=await r.listSkills();return{skills:a.slice(0,o.limit).map(no),total:a.length}}if(o.mode==="search"){let a=await r.searchSkills(o.query,{limit:o.limit});return{query:o.query,skills:a.map(no)}}let n=await r.getSkill(o.skill);if(!n)throw new Error(`Skill nao encontrada: ${o.skill}`);return{skill:no(n),content:n.content}}}return new e}function no(r){return{name:r.name,description:r.description,whenToUse:r.whenToUse||"",source:r.source,filePath:r.filePath}}function hs(){class r extends j{constructor(){super({name:"seo_analyzer",description:"Analisa uma URL publica e retorna dados de SEO (Title, Meta Description, Headings, e densidade de palavras-chave). Use para analisar concorrentes ou otimizar landing pages.",risk:"network",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,requiresApproval:!0,approvalReason:"Faz uma requisicao HTTP para a URL informada.",inputSchema:{type:"object",required:["url"],additionalProperties:!1,properties:{url:{type:"string",format:"uri",minLength:1,maxLength:2e3,description:"URL publica da pagina a ser analisada."}}}})}async execute({url:t}){try{let o=await Jt(t,{headers:{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) SEO-Analyzer/1.0"}});if(!o.ok)throw new Error(`HTTP Error: ${o.status}`);let n=await o.text(),a=n.match(/<title[^>]*>([^<]+)<\/title>/i),s=a?a[1].trim():"N/A",i=n.match(/<meta[^>]*name=["']description["'][^>]*content=["']([^"']+)["'][^>]*>/i)||n.match(/<meta[^>]*content=["']([^"']+)["'][^>]*name=["']description["'][^>]*>/i),c=i?i[1].trim():"N/A",l=[...n.matchAll(/<h1[^>]*>([\s\S]*?)<\/h1>/gi)].map(b=>b[1].replace(/<[^>]+>/g,"").trim()).filter(Boolean),u=[...n.matchAll(/<h2[^>]*>([\s\S]*?)<\/h2>/gi)].map(b=>b[1].replace(/<[^>]+>/g,"").trim()).filter(Boolean),m=n.match(/<body[^>]*>([\s\S]*?)<\/body>/i),f=m?m[1]:n;f=f.replace(/<script[^>]*>[\s\S]*?<\/script>/gi," ").replace(/<style[^>]*>[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/g," ").toLowerCase();let g=f.split(/\s+/).filter(b=>b.length>3&&/^[a-z]+$/.test(b)),w={};for(let b of g)w[b]=(w[b]||0)+1;let y=Object.entries(w).sort((b,E)=>E[1]-b[1]).slice(0,10).map(([b,E])=>`${b}: ${E}`);return{url:t,seoInfo:{title:s,titleLength:s.length,description:c,descriptionLength:c.length,h1:l,h2:u.slice(0,10),topKeywords:y},recommendations:[s.length>60?"Title muito longo (ideal: ate 60 caracteres)":"Title tem bom tamanho",c.length>160?"Meta Description muito longa (ideal: ate 160 caracteres)":"Meta Description tem bom tamanho",l.length===0?"Pagina nao possui H1!":l.length>1?"Pagina possui multiplos H1. Ideal e apenas 1.":"H1 configurado corretamente"]}}catch(o){throw new Error(`Falha ao analisar SEO: ${o.message}`)}}}return new r}var ys=["google_search","meta_ads","tiktok_ads","linkedin_ads","youtube_ads","seo","email"],bs=["pt-BR","en-US","es-ES"];function vs(){class r extends j{constructor(){super({name:"keyword_research",description:"Gera ideias de keywords, clusters, intencao de busca e angulos de conteudo/ads a partir de um tema, produto ou mercado.",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"marketing keyword research seo search intent clusters",maxResultSizeChars:4e4,inputSchema:{type:"object",required:["seed"],additionalProperties:!1,properties:{seed:{type:"string",minLength:1,maxLength:200,description:"Tema, produto, servico ou palavra-chave base."},audience:{type:"string",maxLength:300,description:"Publico-alvo."},market:{type:"string",maxLength:120,description:"Nicho/mercado."},language:{type:"string",enum:bs,description:"Idioma. Padrao pt-BR."},includeAdsAngles:{type:"boolean",description:"Inclui angulos para anuncios. Padrao true."}}}})}validate(t){return{...t,language:t.language||"pt-BR",includeAdsAngles:t.includeAdsAngles??!0}}async execute(t){let o=ym(t.seed),n=t.audience||"publico comprador",a=t.market||o,s=rm(t.language),i=[Ze("problema",o,s.problem,"informational","topo"),Ze("solucao",o,s.solution,"commercial","meio"),Ze("comparacao",o,s.comparison,"commercial","meio/fundo"),Ze("compra",o,s.purchase,"transactional","fundo"),Ze("localizacao",o,s.local,"transactional","fundo")];return{seed:o,market:a,audience:n,clusters:i,contentIdeas:i.flatMap(c=>c.keywords.slice(0,2).map(l=>({keyword:l,title:nm(l,t.language),funnelStage:c.funnelStage,intent:c.intent}))),adsAngles:t.includeAdsAngles?om(o,n,t.language):[]}}}return new r}function ws(){class r extends j{constructor(){super({name:"ad_copy_generator",description:"Gera variacoes de copys para anuncios em Google, Meta, TikTok, LinkedIn, YouTube ou email usando frameworks como AIDA, PAS e oferta direta.",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"ads copy marketing aida pas headlines descriptions cta",maxResultSizeChars:5e4,inputSchema:{type:"object",required:["product","audience"],additionalProperties:!1,properties:{product:{type:"string",minLength:1,maxLength:240},audience:{type:"string",minLength:1,maxLength:300},channel:{type:"string",enum:ys,description:"Canal do anuncio. Padrao meta_ads."},offer:{type:"string",maxLength:240,description:"Oferta, desconto, bonus ou promessa."},painPoints:{type:"array",items:{type:"string"},maxItems:8},benefits:{type:"array",items:{type:"string"},maxItems:8},tone:{type:"string",enum:["direto","premium","urgente","educativo","emocional"],description:"Tom da copy."},language:{type:"string",enum:bs},variations:{type:"integer",minimum:1,maximum:12}}}})}validate(t){return{...t,channel:t.channel||"meta_ads",tone:t.tone||"direto",language:t.language||"pt-BR",variations:t.variations||6,painPoints:t.painPoints||[],benefits:t.benefits||[]}}async execute(t){let o=["AIDA","PAS","Oferta Direta","Prova","Antes/Depois","Curiosidade"],n=[];for(let a=0;a<t.variations;a+=1){let s=o[a%o.length];n.push(am({...t,framework:s,index:a}))}return{product:t.product,channel:t.channel,tone:t.tone,copies:n,complianceNotes:["Evite promessas absolutas ou garantias impossiveis de comprovar.","Valide politicas da plataforma antes de subir campanha.","Teste pelo menos 3 angulos: dor, beneficio e prova."]}}}return new r}function Ss(){class r extends j{constructor(){super({name:"campaign_planner",description:"Cria estrutura de campanha de marketing/ads com funil, canais, publicos, criativos, metricas e plano de testes.",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"marketing campaign planner funnel ads growth media plan",maxResultSizeChars:5e4,inputSchema:{type:"object",required:["objective","product","audience"],additionalProperties:!1,properties:{objective:{type:"string",minLength:1,maxLength:240,description:"Objetivo: leads, vendas, awareness, trial, app installs etc."},product:{type:"string",minLength:1,maxLength:240},audience:{type:"string",minLength:1,maxLength:400},channels:{type:"array",items:{type:"string",enum:ys},maxItems:7},budget:{type:"number",minimum:0},currency:{type:"string",maxLength:8},durationDays:{type:"integer",minimum:1,maximum:365},offer:{type:"string",maxLength:240}}}})}validate(t){return{...t,channels:t.channels?.length?t.channels:["google_search","meta_ads","seo"],currency:t.currency||"BRL",durationDays:t.durationDays||30,budget:t.budget||0}}async execute(t){let o=t.budget>0?t.budget/t.durationDays:0,n=mm(t.channels);return{objective:t.objective,product:t.product,audience:t.audience,durationDays:t.durationDays,budget:t.budget,dailyBudget:de(o),currency:t.currency,funnel:lm(t),channelPlan:t.channels.map(a=>um(a,t,o,n[a]||0)),testingRoadmap:["Semana 1: validar angulos de dor, beneficio e prova social.","Semana 2: pausar criativos com CTR baixo e duplicar vencedores.","Semana 3: testar landing page alternativa ou novo CTA.","Semana 4: escalar campanhas com CPA dentro da meta."],kpis:["CTR","CPC","CVR","CPA","ROAS","lead_quality","payback"]}}}return new r}function xs(){class r extends j{constructor(){super({name:"utm_builder",description:"Cria URLs com parametros UTM padronizados para campanhas de marketing.",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"utm campaign tracking url builder",inputSchema:{type:"object",required:["url","source","medium","campaign"],additionalProperties:!1,properties:{url:{type:"string",minLength:1,maxLength:2e3},source:{type:"string",minLength:1,maxLength:120},medium:{type:"string",minLength:1,maxLength:120},campaign:{type:"string",minLength:1,maxLength:160},term:{type:"string",maxLength:160},content:{type:"string",maxLength:160}}}})}async execute(t){let o=new URL(t.url);return o.searchParams.set("utm_source",et(t.source)),o.searchParams.set("utm_medium",et(t.medium)),o.searchParams.set("utm_campaign",et(t.campaign)),t.term&&o.searchParams.set("utm_term",et(t.term)),t.content&&o.searchParams.set("utm_content",et(t.content)),{url:o.toString(),parameters:Object.fromEntries(o.searchParams.entries()),namingConvention:"lowercase, sem acentos, espacos convertidos em hifen"}}}return new r}function Ts(){class r extends j{constructor(){super({name:"ads_budget_calculator",description:"Calcula cenarios de budget, clicks, conversoes, CPA, ROAS e break-even para campanhas pagas.",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"ads budget calculator cpa roas cpc conversion rate",inputSchema:{type:"object",required:["budget","avgCpc","conversionRate"],additionalProperties:!1,properties:{budget:{type:"number",minimum:0},avgCpc:{type:"number",minimum:.01},conversionRate:{type:"number",minimum:.01,description:"Taxa de conversao em porcentagem. Ex: 2.5"},averageOrderValue:{type:"number",minimum:0,description:"Ticket medio/receita por conversao."},grossMargin:{type:"number",minimum:0,maximum:100,description:"Margem bruta em porcentagem."},targetCpa:{type:"number",minimum:0},currency:{type:"string",maxLength:8}}}})}validate(t){return{...t,averageOrderValue:t.averageOrderValue||0,grossMargin:t.grossMargin??100,targetCpa:t.targetCpa||0,currency:t.currency||"BRL"}}async execute(t){let o=t.budget/t.avgCpc,n=o*(t.conversionRate/100),a=n>0?t.budget/n:1/0,s=n*t.averageOrderValue,i=s*(t.grossMargin/100),c=t.budget>0?s/t.budget:0,l=t.averageOrderValue*(t.grossMargin/100);return{currency:t.currency,baseScenario:{budget:de(t.budget),avgCpc:de(t.avgCpc),clicks:Math.floor(o),conversionRate:`${t.conversionRate}%`,conversions:tt(n),cpa:de(a),revenue:de(s),grossProfit:de(i),roas:tt(c),breakEvenCpa:de(l),targetStatus:t.targetCpa?a<=t.targetCpa?"within_target":"above_target":"no_target"},sensitivity:[-20,0,20].map(u=>{let m=t.conversionRate*(1+u/100),f=o*(m/100);return{cvrChange:`${u}%`,conversionRate:`${tt(m)}%`,conversions:tt(f),cpa:de(f>0?t.budget/f:1/0)}}),recommendations:pm({cpa:a,breakEvenCpa:l,targetCpa:t.targetCpa})}}}return new r}function Es(){class r extends j{constructor(){super({name:"landing_page_audit",description:"Audita texto ou HTML de landing page para clareza de oferta, CTA, prova, objecoes, SEO basico e conversao.",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"landing page audit conversion cta copy seo cro",maxResultSizeChars:4e4,inputSchema:{type:"object",required:["content"],additionalProperties:!1,properties:{content:{type:"string",minLength:1,maxLength:2e5,description:"HTML ou texto da landing page."},targetKeyword:{type:"string",maxLength:160},audience:{type:"string",maxLength:300}}}})}async execute(t){let o=fm(t.content),n=o.toLowerCase(),a=hm(o),s=[Pe("Oferta clara",rr(n,["ganhe","aumente","reduza","economize","crie","automatize","solucao","resultado"])),Pe("CTA presente",a.length>0),Pe("Prova social",rr(n,["cliente","depoimento","case","resultado","garantia","avaliacao","estrelas"])),Pe("Urgencia/escassez",rr(n,["hoje","agora","limitado","ultimas","prazo","bonus"])),Pe("Objecoes respondidas",rr(n,["seguro","sem risco","garantia","suporte","cancelar","duvida","faq"])),Pe("Keyword alvo",t.targetKeyword?n.includes(t.targetKeyword.toLowerCase()):!0)];return{score:Math.round(s.filter(c=>c.pass).length/s.length*100),wordCount:o.split(/\s+/).filter(Boolean).length,ctas:a,checks:s,issues:s.filter(c=>!c.pass).map(c=>c.name),recommendations:gm(s,t),extractedPreview:o.slice(0,1e3)}}}return new r}function rm(r){return r==="en-US"?{problem:["problem","pain","why","how to fix","mistakes"],solution:["software","tool","service","strategy","template"],comparison:["best","alternative","vs","review","comparison"],purchase:["price","hire","buy","agency","consultant"],local:["near me","for small business","for startups","online"]}:r==="es-ES"?{problem:["problema","dolor","por que","como resolver","errores"],solution:["software","herramienta","servicio","estrategia","plantilla"],comparison:["mejor","alternativa","vs","resena","comparacion"],purchase:["precio","contratar","comprar","agencia","consultor"],local:["cerca de mi","para pequenas empresas","para startups","online"]}:{problem:["problema","dor","por que","como resolver","erros"],solution:["software","ferramenta","servico","estrategia","modelo"],comparison:["melhor","alternativa","vs","review","comparativo"],purchase:["preco","contratar","comprar","agencia","consultor"],local:["perto de mim","para pequenas empresas","para startups","online"]}}function Ze(r,e,t,o,n){return{name:r,intent:o,funnelStage:n,keywords:t.map(a=>`${a} ${e}`)}}function om(r,e,t){return(t==="en-US"?["pain relief","speed","proof","price","authority"]:["dor","velocidade","prova","preco","autoridade"]).map(n=>({angle:n,hook:`${bm(n)} para ${e}: ${r} sem complicar o processo.`,cta:t==="en-US"?"Learn more":"Saiba mais"}))}function nm(r,e){return e==="en-US"?`How to choose ${r} without wasting budget`:e==="es-ES"?`Como elegir ${r} sin desperdiciar presupuesto`:`Como escolher ${r} sem desperdi\xE7ar budget`}function am(r){let e=r.painPoints[r.index%Math.max(1,r.painPoints.length)]||"perder tempo e dinheiro",t=r.benefits[r.index%Math.max(1,r.benefits.length)]||"crescer com mais previsibilidade",o=r.offer||"comece agora",n=cm(r.channel,r.language),a=sm(r.framework,r.product,t,e);return{framework:r.framework,channel:r.channel,headline:gs(a,r.channel==="google_search"?30:90),primaryText:im(r.framework,r.product,r.audience,e,t,o),description:gs(`${t}. ${o}.`,r.channel==="google_search"?90:140),cta:n}}function sm(r,e,t,o){return r==="PAS"?`Chega de ${o}`:r==="Prova"?`${e} com resultado real`:r==="Antes/Depois"?`De ${o} para ${t}`:r==="Curiosidade"?`O jeito simples de ${t}`:r==="Oferta Direta"?`${e} para ${t}`:`${t} com ${e}`}function im(r,e,t,o,n,a){return r==="PAS"?`Se ${t} ainda sofre com ${o}, ${e} ajuda a transformar isso em ${n}. ${a}.`:r==="AIDA"?`${t}: veja como ${e} pode gerar ${n} sem complicar sua rotina. ${a}.`:r==="Prova"?`${e} foi pensado para quem precisa de ${n}. Teste um caminho mais direto. ${a}.`:`${e} ajuda ${t} a sair de ${o} e chegar em ${n}. ${a}.`}function cm(r,e){return e==="en-US"?r==="email"?"Reply now":"Learn more":e==="es-ES"?"Saber mas":r==="google_search"?"Ver oferta":r==="email"?"Responder agora":"Saiba mais"}function lm(r){return[{stage:"topo",goal:"Gerar demanda e educar",assets:["conteudo curto","video","post SEO"],message:`Problema que ${r.audience} quer resolver`},{stage:"meio",goal:"Capturar interesse",assets:["lead magnet","comparativo","case"],message:`Por que ${r.product} e uma opcao forte`},{stage:"fundo",goal:"Converter",assets:["landing page","remarketing","prova social"],message:r.offer||"Oferta clara com CTA direto"}]}function um(r,e,t,o){let n={channel:r,budgetShare:tt(o),dailyBudget:de(t*o),objective:e.objective};return r==="google_search"?{...n,structure:["brand","non-brand high-intent","competitors"],primaryKpi:"CPA"}:r==="meta_ads"?{...n,structure:["broad","lookalike","remarketing"],primaryKpi:"CTR + CPA"}:r==="seo"?{...n,structure:["clusters","landing pages","internal links"],primaryKpi:"organic leads"}:{...n,structure:["awareness","consideration","retargeting"],primaryKpi:"qualified conversions"}}function dm(r){return r==="google_search"?.35:r==="meta_ads"?.3:r==="seo"?.15:r==="linkedin_ads"?.25:.2}function mm(r){let e=r.map(o=>[o,dm(o)]),t=e.reduce((o,[,n])=>o+n,0);if(!t){let o=r.length?1/r.length:0;return Object.fromEntries(r.map(n=>[n,o]))}return Object.fromEntries(e.map(([o,n])=>[o,n/t]))}function pm({cpa:r,breakEvenCpa:e,targetCpa:t}){let o=[];return t&&r>t&&o.push("CPA acima da meta: reduza CPC, melhore CVR ou estreite segmentacao."),e&&r>e&&o.push("CPA acima do break-even: campanha tende a perder margem."),o.length||o.push("Cenario inicial saudavel; teste criativos antes de escalar budget."),o.push("Acompanhe CPA por canal e por criativo, nao apenas media geral."),o}function fm(r){return String(r||"").replace(/<script[^>]*>[\s\S]*?<\/script>/gi," ").replace(/<style[^>]*>[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/g," ").replace(/\s+/g," ").trim()}function hm(r){let e=["saiba mais","comece","comprar","contratar","fale conosco","agendar","teste gratis","ver oferta","inscrever","baixar"],t=r.toLowerCase();return e.filter(o=>t.includes(o))}function Pe(r,e){return{name:r,pass:!!e}}function gm(r,e){let t=new Set(r.filter(n=>!n.pass).map(n=>n.name)),o=[];return t.has("Oferta clara")&&o.push("Reescreva o hero com promessa clara: resultado, publico e mecanismo."),t.has("CTA presente")&&o.push("Adicione CTA acima da dobra e repita apos prova/beneficios."),t.has("Prova social")&&o.push("Inclua depoimentos, numeros, logos, prints ou cases."),t.has("Objecoes respondidas")&&o.push("Adicione FAQ com risco, suporte, prazo, garantia e processo."),e.targetKeyword&&t.has("Keyword alvo")&&o.push(`Inclua a keyword alvo "${e.targetKeyword}" no H1, intro e meta.`),o.length||o.push("Pagina tem boa base; proximo passo e testar headline e CTA em A/B."),o}function rr(r,e){return e.some(t=>r.includes(t))}function ym(r){return String(r||"").trim().replace(/\s+/g," ")}function et(r){return String(r||"").normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function bm(r){let e=String(r||"");return e&&e[0].toUpperCase()+e.slice(1)}function gs(r,e){let t=String(r||"");return t.length<=e?t:t.slice(0,e-1).trimEnd()}function tt(r){return Number.isFinite(r)?Math.round(r*100)/100:null}function de(r){return Number.isFinite(r)?Math.round(r*100)/100:null}var ao=["pt-BR","en-US","es-ES"],vm=["tela_e_voz","tutorial","analise","review","storytelling","listicle","short"],wm=["direto","didatico","descontraido","tecnico","provocativo"],Sm=["leve","medio","pesado"],xm={curiosidade:"\u{1F440}",dor:"\u{1F624}",numero:"\u{1F4C8}",contraste:"\u2694\uFE0F",autoridade:"\u{1F3AF}",erro:"\u26A0\uFE0F",resultado:"\u{1F525}",transformacao:"\u{1F680}",segredo:"\u{1F92B}",choque:"\u{1F480}"},Tm=["bug","falha","vulnerabilidade","exploit","hack","invas","burlar","brecha","seguranca","sql","xss","payload","bypass","senha","credencial"];function ks(){class r extends j{constructor(){super({name:"youtube_script_generator",description:"Gera um roteiro estruturado para video de YouTube (gancho, intro, blocos com falas e sugestoes de tela/b-roll, CTA e outro) a partir de um tema, formato e duracao. Ideal para canais de marketing, tecnologia, analise de sistemas e tutoriais.",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"youtube roteiro script video gancho hook cta tutorial analise",maxResultSizeChars:6e4,inputSchema:{type:"object",required:["topic"],additionalProperties:!1,properties:{topic:{type:"string",minLength:1,maxLength:240,description:"Tema central do video."},audience:{type:"string",maxLength:300,description:"Publico-alvo. Ex: devs iniciantes, empreendedores."},format:{type:"string",enum:vm,description:"Formato do video. Padrao tela_e_voz."},durationMinutes:{type:"number",minimum:.5,maximum:60,description:"Duracao alvo em minutos. Padrao 6."},tone:{type:"string",enum:wm,description:"Tom da narracao. Padrao didatico."},keyPoints:{type:"array",items:{type:"string",maxLength:200},maxItems:10,description:"Pontos que voce quer cobrir. Se vazio, o roteiro sugere blocos automaticamente."},cta:{type:"string",maxLength:200,description:"Chamada para acao no final. Ex: inscreva-se, link na descricao."},language:{type:"string",enum:ao,description:"Idioma. Padrao pt-BR."}}}})}validate(t){return{...t,format:t.format||"tela_e_voz",tone:t.tone||"didatico",durationMinutes:t.durationMinutes||6,audience:t.audience||"quem quer aprender sobre o tema",keyPoints:t.keyPoints||[],language:t.language||"pt-BR"}}async execute(t){let o=Lm(t.topic,t.keyPoints),n=Em(t),a=Math.round(t.durationMinutes*140),s=Math.max(40,Math.round(a/Math.max(1,n.length)));return{topic:t.topic,format:t.format,tone:t.tone,audience:t.audience,durationMinutes:t.durationMinutes,estimatedWordCount:a,hook:km(t),intro:$m(t),blocks:n.map((i,c)=>({order:c+1,title:i.title,talkingPoints:i.points,suggestedNarration:i.narration,screenAction:i.screen,approxWords:s})),cta:Am(t),outro:Rm(t),editingNotes:["Corte pausas longas e '\xE9\xE9\xE9'/'hum' \u2014 deixa o ritmo mais firme.","Adicione um corte (jump cut) ou zoom a cada 8-15s pra manter retencao.","Legenda queimada ajuda muito quem assiste sem som.","Primeiros 5s definem retencao: entregue o gancho antes de qualquer vinheta."],safetyNotice:o?Cm(t.language):null}}}return new r}function $s(){class r extends j{constructor(){super({name:"youtube_title_ideas",description:"Gera ideias de titulos e frases de thumbnail para um video, com angulos diferentes (curiosidade, dor, numero, contraste, autoridade, transformacao, segredo, choque) e um score heuristico de CTR. O nivel de 'punch' controla o quanto o titulo fica agressivo/clickbait (caixa alta, emoji, valores).",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"youtube titulos thumbnail ctr headline ideas clickbait punch",maxResultSizeChars:4e4,inputSchema:{type:"object",required:["topic"],additionalProperties:!1,properties:{topic:{type:"string",minLength:1,maxLength:240},audience:{type:"string",maxLength:300},keyword:{type:"string",maxLength:120,description:"Palavra-chave para reforcar no titulo."},count:{type:"integer",minimum:3,maximum:20,description:"Quantidade de titulos. Padrao 8."},punch:{type:"string",enum:Sm,description:"Intensidade do clickbait: leve (limpo), medio (uma parte em CAIXA ALTA), pesado (caixa alta + emoji + valores). Padrao medio."},language:{type:"string",enum:ao}}}})}validate(t){return{...t,count:t.count||8,punch:t.punch||"medio",language:t.language||"pt-BR"}}async execute(t){let o=["curiosidade","dor","numero","contraste","autoridade","erro","resultado","transformacao","segredo","choque"],n=[];for(let a=0;a<t.count;a+=1){let s=o[a%o.length],i=Om(s,t,a),c=Mm(i,s,t.punch,a);n.push({angle:s,title:Bm(c,80),length:c.length,thumbnailText:Pm(s,t),ctrScore:Im(c,s,t.keyword,t.punch)})}return n.sort((a,s)=>s.ctrScore-a.ctrScore),{topic:t.topic,keyword:t.keyword||null,punch:t.punch,ideas:n,tips:["Titulo bom tem <= 60 caracteres pra nao cortar no mobile (emoji conta como 2).","Thumbnail e titulo devem se completar, nao repetir a mesma frase.","Numero, promessa concreta e curiosidade sao os que mais puxam clique.","Punch pesado sobe o CTR mas so segura audiencia se o video entregar a promessa."]}}}return new r}function As(){class r extends j{constructor(){super({name:"youtube_seo_pack",description:"Monta um pacote de SEO para o video: descricao otimizada, tags, hashtags e estrutura de capitulos/timestamps a partir dos blocos do roteiro.",risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"youtube seo descricao tags hashtags capitulos timestamps",maxResultSizeChars:4e4,inputSchema:{type:"object",required:["topic"],additionalProperties:!1,properties:{topic:{type:"string",minLength:1,maxLength:240},audience:{type:"string",maxLength:300},keywords:{type:"array",items:{type:"string",maxLength:80},maxItems:15},chapters:{type:"array",items:{type:"string",maxLength:120},maxItems:20,description:"Titulos dos blocos/capitulos, na ordem do video."},links:{type:"array",items:{type:"string",maxLength:300},maxItems:10,description:"Links pra descricao (site, redes, produto)."},language:{type:"string",enum:ao}}}})}validate(t){return{...t,keywords:t.keywords||[],chapters:t.chapters||[],links:t.links||[],language:t.language||"pt-BR"}}async execute(t){let o=t.keywords.length?t.keywords:Nm(t.topic),n=qm(t,o),a=Dm(t.chapters);return{topic:t.topic,description:n,tags:jm(t.topic,o),hashtags:o.slice(0,5).map(s=>`#${Fm(s).replace(/-/g,"")}`),chapters:a,notes:["Cole os timestamps no inicio da descricao pra ativar os capitulos do YouTube (o primeiro precisa ser 00:00).","As 2 primeiras linhas da descricao sao as que aparecem na busca: coloque a promessa + keyword ali."]}}}return new r}function Em(r){return r.keyPoints.length?r.keyPoints.map(t=>({title:rt(t),points:[t],narration:`Aqui a ideia e explicar: ${t}. Mostra na tela enquanto fala pra fixar.`,screen:"Mostre na tela o que voce esta explicando (site, codigo, painel, exemplo)."})):_m(r.format).map(t=>({title:t.title.replace("{topic}",r.topic),points:t.points.map(o=>o.replace("{topic}",r.topic)),narration:t.narration.replace("{topic}",r.topic),screen:t.screen}))}function _m(r){return r==="tutorial"?[{title:"O que vamos construir",points:["Resultado final primeiro","Pre-requisitos"],narration:"Mostra o resultado de {topic} logo de cara pra prender atencao.",screen:"Mostre o resultado pronto funcionando."},{title:"Passo a passo",points:["Passo 1","Passo 2","Passo 3"],narration:"Vai fazendo {topic} ao vivo, um passo por vez, sem pular etapa.",screen:"Grave a tela executando cada passo."},{title:"Erros comuns",points:["Onde a maioria trava","Como resolver"],narration:"Mostre os erros que costumam acontecer em {topic} e como sair deles.",screen:"Reproduza o erro e a correcao."}]:r==="analise"||r==="review"?[{title:"O que e {topic} e por que importa",points:["Contexto","Pra quem serve"],narration:"Explica rapido o que e {topic} e por que vale a pena olhar.",screen:"Mostre a plataforma/produto na tela."},{title:"Pontos fortes",points:["O que funciona bem"],narration:"Aponte o que {topic} faz bem, com exemplo na tela.",screen:"Navegue mostrando os acertos."},{title:"Pontos fracos e o problema que ninguem repara",points:["Fluxo","Validacao","UX"],narration:"Mostre o detalhe do fluxo/validacao que a maioria ignora em {topic}.",screen:"Mostre o comportamento visual, sem explorar nada."},{title:"Como eu resolveria",points:["Sugestao pratica"],narration:"Diga como voce corrigiria/melhoraria isso.",screen:"Mostre um mockup ou explique a solucao."}]:r==="short"||r==="listicle"?[{title:"Promessa",points:["1 frase de valor"],narration:"Entregue a promessa de {topic} nos primeiros 2 segundos.",screen:"Texto grande na tela."},{title:"Conteudo direto",points:["Ponto 1","Ponto 2","Ponto 3"],narration:"Vai direto ao ponto sobre {topic}, sem enrolar.",screen:"Corte rapido entre cada ponto."},{title:"Fecho + gancho",points:["CTA curto"],narration:"Feche com um gancho pra proximo video.",screen:"Texto de CTA."}]:[{title:"O que vou mostrar",points:["Promessa clara do video"],narration:"Diga em 1 frase o que a pessoa vai ver sobre {topic}.",screen:"Abra a tela do que vai mostrar."},{title:"Por que isso importa",points:["Contexto e relevancia"],narration:"Explique por que {topic} importa pra quem esta assistindo.",screen:"Mostre um exemplo real."},{title:"Onde esta o problema / a oportunidade",points:["O ponto central"],narration:"Aponte na tela onde esta o problema ou a oportunidade em {topic}.",screen:"Zoom no detalhe que importa."},{title:"Como eu encontrei / como funciona",points:["Seu processo"],narration:"Mostre como voce chegou nisso, passo a passo.",screen:"Grave o passo a passo."},{title:"O que poderia melhorar",points:["Sua opiniao/solucao"],narration:"Feche com sua visao: o que da pra melhorar em {topic}.",screen:"Resumo na tela."}]}function km(r){let e=[`Presta atencao nesse detalhe de ${r.topic} que quase ninguem repara.`,`Em ${r.topic}, tem um erro que parece bobo mas quebra tudo \u2014 vou te mostrar.`,`Se voce mexe com ${r.topic}, esse video vai te economizar um temp\xE3o.`];return{line:e[0],alternatives:e.slice(1),tip:"Fale o gancho antes de qualquer vinheta ou 'fala galera'. Os 5 primeiros segundos seguram a retencao."}}function $m(r){return{line:`Fala! Hoje eu vou ${r.format==="tutorial"?"te mostrar na pratica":"analisar"} ${r.topic}${r.audience?`, pensando em ${r.audience}`:""}.`,tip:"Intro curta: no maximo 10-15s. Prometa o que a pessoa leva no fim do video."}}function Am(r){return{line:r.cta||"Se isso te ajudou, deixa o like e se inscreve \u2014 tem mais video assim vindo.",tip:"Peca 1 acao so (like OU inscricao OU comentario). Pedir tudo junto dilui."}}function Rm(r){return{line:`Se quiser que eu aprofunde em algum ponto de ${r.topic}, escreve nos comentarios. Ate o proximo.`,tip:"Termine com gancho pro proximo video ou card pra um relacionado \u2014 segura o watch time da sessao."}}function Cm(r){return r==="en-US"?"Sensitive topic detected (bug/security/third-party platform). Only demonstrate on systems you own or that are in an authorized bug bounty scope. Do not expose real data or show a working exploit; show the visual behavior and how it could be fixed.":"Tema sensivel detectado (bug/seguranca/plataforma de terceiros). So demonstre em sistema seu ou dentro de escopo autorizado (ex: bug bounty). Nao exponha dados reais nem mostre exploracao funcional \u2014 mostre o comportamento visual e como poderia ser corrigido."}function Lm(r,e){let t=[r,...e||[]].join(" ").toLowerCase();return Tm.some(o=>t.includes(o))}function Om(r,e,t){let o=e.topic,n=e.keyword?`${e.keyword}: `:"";return{curiosidade:`${n}O detalhe de ${o} que quase ninguem percebe`,dor:`${n}Parei de errar em ${o} depois que entendi isso`,numero:`${n}${3+t%5} coisas sobre ${o} que mudam tudo`,contraste:`${n}${o}: o que te ensinam vs o que funciona`,autoridade:`${n}Como eu analiso ${o} na pratica`,erro:`${n}O erro em ${o} que todo mundo comete`,resultado:`${n}Consegui isso em ${o} sem complicar`,transformacao:`${n}De zero a dominar ${o} em 7 dias`,segredo:`${n}O que ninguem te conta sobre ${o}`,choque:`${n}Isso sobre ${o} vai te assustar`}[r]||`${n}${rt(o)}`}function Mm(r,e,t,o){if(t==="leve")return r;if(t==="medio")return _s(r);let n=xm[e]||"\u{1F525}",a=_s(r),s=o%2===0?" (S\xC9RIO)":"";return`${a}${s} ${n}`}function _s(r){let e=r.match(/^(.*?)(\s(?:que|de|em|sobre|vs|depois|a\s)\b.*)$/i);if(e&&e[1].length>=6)return`${e[1].toUpperCase()}${e[2]}`;let t=Math.max(8,Math.floor(r.length*.5));return`${r.slice(0,t).toUpperCase()}${r.slice(t)}`}function Pm(r,e){return{curiosidade:"NINGUEM PERCEBE",dor:"PAREI DE ERRAR",numero:"ISSO MUDA TUDO",contraste:"TEORIA x REAL",autoridade:"NA PRATICA",erro:"ERRO COMUM",resultado:"FUNCIONOU",transformacao:"DIA 1 x DIA 7",segredo:"NINGUEM CONTA",choque:"OLHA ISSO"}[r]||rt(e.topic).slice(0,22)}function Im(r,e,t,o="medio"){let n=50,a=[...r].length;return a<=60?n+=15:a<=70?n+=5:n-=10,/\d/.test(r)&&(n+=10),["curiosidade","dor","erro","resultado","choque","transformacao"].includes(e)&&(n+=8),t&&r.toLowerCase().includes(t.toLowerCase())&&(n+=7),/[A-ZÁÉÍÓÚÂÊÔÃÕÇ]{4,}/.test(r)&&(n+=5),new RegExp("\\p{Extended_Pictographic}","u").test(r)&&(n+=4),o==="pesado"?n+=4:o==="leve"&&(n-=3),Math.max(0,Math.min(100,n))}function Nm(r){let e=Rs(r).toLowerCase();return[e,`como fazer ${e}`,`${e} passo a passo`,`${e} na pratica`,`${e} para iniciantes`]}function qm(r,e){let t=`${rt(r.topic)}: neste video eu mostro na pratica${r.audience?`, pensando em ${r.audience}`:""}.`,o=`Assista ate o fim pra pegar todos os detalhes sobre ${r.topic}.`,n=r.links.length?`
477
+
478
+ Links:
479
+ ${r.links.map(s=>`- ${s}`).join(`
480
+ `)}`:"",a=`
481
+
482
+ Topicos: ${e.join(", ")}.`;return`${t}
483
+ ${o}${n}${a}`}function jm(r,e){return[...new Set([Rs(r).toLowerCase(),...e.map(o=>o.toLowerCase())])].filter(Boolean).slice(0,15)}function Dm(r){return r.length?r.map((e,t)=>({time:Um(t===0?0:t*60),title:rt(e)})):[{time:"00:00",title:"Introducao"}]}function Um(r){let e=Math.floor(r/60),t=r%60;return`${String(e).padStart(2,"0")}:${String(t).padStart(2,"0")}`}function Rs(r){return String(r||"").trim().replace(/\s+/g," ")}function Fm(r){return String(r||"").normalize("NFD").replace(/[̀-ͯ]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function rt(r){let e=String(r||"").trim();return e&&e[0].toUpperCase()+e.slice(1)}function Bm(r,e){let t=String(r||"");return t.length<=e?t:t.slice(0,e-1).trimEnd()}function Cs({config:r,memoryManager:e,storage:t,eventBus:o,logger:n,lspManager:a,skillManager:s}={}){let i=new Vt({enabled:r.tools.enabled}).register(Da({config:r,logger:n})).register(Ma({config:r,logger:n})).register(qa({config:r,logger:n})).register(ya({config:r,logger:n})).register(va({config:r,logger:n})).register(wa({config:r,logger:n})).register(Ta({config:r,logger:n,lspManager:a})).register(ka({config:r,logger:n,lspManager:a})).register(ha({config:r,logger:n})).register(Ra({config:r,logger:n})).register(za({config:r,logger:n})).register(Ga({config:r})).register(Ka({lspManager:a})).register(ja({config:r,storage:t,logger:n})).register(Ia({memoryManager:e,logger:n})).register(Pa({memoryManager:e,logger:n})).register(Ja({config:r})).register(Qa()).register(Za()).register(es()).register(as({config:r,logger:n})).register(ss()).register(ls({storage:t,config:r})).register(us({storage:t})).register(ds({config:r})).register(ms({config:r})).register(fs({skillManager:s})).register(Do({storage:t,eventBus:o})).register(Uo({storage:t,eventBus:o})).register(Fo({storage:t,eventBus:o})).register(Bo({storage:t})).register(hs()).register(vs()).register(ws()).register(Ss()).register(xs()).register(Ts()).register(Es()).register(ks()).register($s()).register(As());return i.register(ps({toolRegistry:i})),i}function Ls({subAgentRegistry:r,subAgentRunner:e}){return{name:"invoke_subagent",description:["Delega uma tarefa especializada para um subagente e retorna um relatorio ao Supervisor.","Use obrigatoriamente para tarefas de codigo, refatoracao, criacao/edicao de arquivos, testes, revisao, seguranca ou pesquisa tecnica.","Escreva o prompt como uma instrucao auto-contida: inclua objetivo, arquivos/caminhos conhecidos, contexto, restricoes e formato esperado.","Nunca delegue entendimento com frases vagas como 'com base nisso, faca'. O Supervisor deve sintetizar e passar instrucoes concretas.","NAO escreva o codigo pronto dentro de 'task' e peca para o subagente 'salvar'. Descreva O QUE deve ser feito (requisitos, API, arquivos, comportamento) e deixe o coder GERAR o codigo. Codigo grande colado no task e proibido.","Para criar/editar arquivos ou escrever codigo, use SEMPRE o agente 'coder'. O 'researcher' NAO escreve arquivos.","O resultado do subagente e interno; depois voce resume ao usuario.",`Subagentes disponiveis: ${r.list().map(t=>t.name).join(", ")}.`].join(" "),risk:"internal",requiresApproval:!1,timeoutMs:0,inputSchema:{type:"object",required:["agent","task"],additionalProperties:!1,properties:{agent:{type:"string",enum:r.list().map(t=>t.name)},task:{type:"string",minLength:1,maxLength:24e3},context:{type:"string",maxLength:16e3},expectedOutput:{type:"string",maxLength:4e3}}},async execute(t,o={}){let n=await e.invoke({agentName:t.agent,task:t.task,context:t.context||"",expectedOutput:t.expectedOutput||"",parentMessages:o.messages||[]},o);return{agent:n.agent,title:n.title,durationMs:n.durationMs,content:n.content,toolResults:n.toolResults}}}}function Os({subAgentRegistry:r,subAgentRunner:e}){return{name:"invoke_parallel_subagents",description:["Delega multiplas tarefas para diferentes subagentes rodarem em paralelo e retorna um array de relatorios.","Use para pesquisas independentes, revisoes separadas ou partes que nao editam os mesmos arquivos.","Cada tarefa deve ser auto-contida: objetivo, contexto, restricoes, arquivos relevantes e formato esperado.","Nao use para tarefas que editam os mesmos arquivos em paralelo; implemente uma por vez quando houver conflito de escrita.",`Subagentes disponiveis: ${r.list().map(t=>t.name).join(", ")}.`].join(" "),risk:"internal",requiresApproval:!1,timeoutMs:0,inputSchema:{type:"object",required:["tasks"],additionalProperties:!1,properties:{tasks:{type:"array",minItems:1,maxItems:5,items:{type:"object",required:["agent","task"],properties:{agent:{type:"string",enum:r.list().map(t=>t.name)},task:{type:"string",minLength:1,maxLength:24e3},context:{type:"string",maxLength:16e3},expectedOutput:{type:"string",maxLength:4e3}}}}}},async execute(t,o={}){let n=Math.max(1,o.config?.multiAgent?.concurrency||3);return(await zm(t.tasks,n,s=>e.invoke({agentName:s.agent,task:s.task,context:s.context||"",expectedOutput:s.expectedOutput||""},{...o,parallel:!0}))).map((s,i)=>{if(s.status==="fulfilled"){let c=s.value;return{agent:c.agent,title:c.title,durationMs:c.durationMs,content:c.content,toolResults:c.toolResults}}return{agent:t.tasks[i].agent,ok:!1,error:String(s.reason?.message||s.reason)}})}}}async function zm(r,e,t){let o=new Array(r.length),n=0;async function a(){for(;n<r.length;){let s=n;n+=1;try{o[s]={status:"fulfilled",value:await t(r[s])}}catch(i){o[s]={status:"rejected",reason:i}}}}return await Promise.all(Array.from({length:Math.min(e,r.length)},()=>a())),o}var Hm="<<<CONSENSUS_REACHED>>>";function Gm(r){return/(^|\n)\s*<<<CONSENSUS_REACHED>>>\s*($|\n)/.test(String(r||""))}function Wm(r){let e=String(r||"");return e.length<=8e3?e:`...(historico anterior truncado)...
484
+ ${e.slice(-8e3)}`}function Ms({subAgentRegistry:r,subAgentRunner:e}){return{name:"start_swarm_debate",description:["Inicia uma din\xE2mica de Swarm (Bate-Papo Colaborativo) entre m\xFAltiplos subagentes.","\xDAtil para resolver problemas complexos onde um agente cria (ex: coder) e outro critica (ex: reviewer).","Os agentes ir\xE3o debater em turnos at\xE9 chegarem num consenso ou atingirem o n\xFAmero m\xE1ximo de rodadas."].join(" "),risk:"internal",requiresApproval:!1,timeoutMs:0,inputSchema:{type:"object",required:["agents","topic"],additionalProperties:!1,properties:{agents:{type:"array",minItems:2,maxItems:4,items:{type:"string",enum:r.list().map(t=>t.name)},description:"Lista ordenada de agentes que ir\xE3o participar do debate (ex: ['coder', 'reviewer'])"},topic:{type:"string",maxLength:8e3,description:"O problema a ser resolvido pelo swarm."},maxRounds:{type:"integer",minimum:1,maximum:5,default:3,description:"N\xFAmero m\xE1ximo de rodadas de debate."}}},async execute(t,o={}){let{agents:n,topic:a,maxRounds:s=3}=t,i=`T\xF3pico Inicial do Supervisor:
485
+ ${a}
486
+
487
+ `,c=[];for(let l=1;l<=s;l++){i+=`--- RODADA ${l} ---
488
+ `;for(let u of n){o.stream&&o.onToken&&o.onToken(`
489
+
490
+ \x1B[1m\x1B[36m[SWARM: ${u.toUpperCase()} falando...]\x1B[0m
491
+ `);let m=await e.invoke({agentName:u,task:`Este \xE9 um Swarm Debate. Voc\xEA est\xE1 colaborando com outros agentes.
492
+
493
+ Hist\xF3rico do Debate at\xE9 agora:
494
+ ${Wm(i)}
495
+
496
+ Sua tarefa:
497
+ Contribua com o seu conhecimento espec\xEDfico (seja codificando, criticando ou pesquisando). Fa\xE7a as altera\xE7\xF5es necess\xE1rias.
498
+ Se \u2014 e somente se \u2014 voc\xEA julgar que o problema est\xE1 totalmente resolvido e sem pend\xEAncias, termine sua resposta com o marcador exato numa linha pr\xF3pria: ${Hm}`},o);if(i+=`[Resposta de ${u}]:
499
+ ${m.content}
500
+
501
+ `,m.toolResults&&c.push(...m.toolResults),Gm(m.content))return i+=`
502
+ [SISTEMA]: Consenso atingido na rodada ${l} por ${u}. Encerrando swarm.
503
+ `,{status:"consensus_reached",rounds:l,history:i,toolResults:c}}}return i+=`
504
+ [SISTEMA]: N\xFAmero m\xE1ximo de rodadas atingido sem consenso expl\xEDcito.
505
+ `,{status:"max_rounds_reached",rounds:s,history:i,toolResults:c}}}}import{readFile as Vm}from"node:fs/promises";function Ps({subAgentRunner:r}){return{name:"subagent_list_runs",description:"Lista execucoes recentes de subagentes, incluindo status, arquivo de saida e erro.",risk:"read",isReadOnly:!0,requiresApproval:!1,shouldDefer:!0,inputSchema:{type:"object",additionalProperties:!1,properties:{status:{type:"string",enum:["running","completed","failed","cancelled"]},limit:{type:"integer",minimum:1,maximum:100}}},async execute(e){return{runs:r.listRuns({status:e.status,limit:e.limit||20})}}}}function Is({subAgentRunner:r}){return{name:"subagent_read_run",description:"Le o resultado persistido de uma execucao de subagente por runId.",risk:"read",isReadOnly:!0,requiresApproval:!1,shouldDefer:!0,inputSchema:{type:"object",required:["runId"],additionalProperties:!1,properties:{runId:{type:"string",minLength:1},includeRawOutput:{type:"boolean"}}},async execute(e){let t=r.getRun(e.runId);if(!t)throw new Error(`Subagent run not found: ${e.runId}`);if(!e.includeRawOutput||!t.outputPath)return{run:t};let o=await Vm(t.outputPath,"utf8").catch(n=>{throw new Error(`Nao foi possivel ler outputPath ${t.outputPath}: ${n.message}`)});return{run:t,rawOutput:o.length>5e4?`${o.slice(0,5e4)}
506
+ ...[truncated]`:o}}}}function Ns({subAgentRunner:r}){return{name:"subagent_cancel_run",description:"Solicita cancelamento cooperativo de uma execucao ativa de subagente.",risk:"write",requiresApproval:!1,shouldDefer:!0,inputSchema:{type:"object",required:["runId"],additionalProperties:!1,properties:{runId:{type:"string",minLength:1}}},async execute(e){return r.cancelRun(e.runId)}}}function qs({mcpManager:r}){return{name:"connect_mcp_server",description:"Conecta a um servidor MCP (Model Context Protocol) e injeta dinamicamente as ferramentas dele neste agente. Suporta stdio (informe 'command') ou remoto por URL (informe 'url' com type 'http' ou 'sse'). Exige aprovacao humana.",risk:"dangerous",requiresApproval:!0,approvalReason:"Vai iniciar um processo local ou conectar a um servidor MCP externo e registrar as ferramentas dele no agente.",inputSchema:{type:"object",required:["serverName"],additionalProperties:!1,properties:{serverName:{type:"string",minLength:1,maxLength:64,description:"Nome identificador do servidor"},command:{type:"string",minLength:1,maxLength:200,description:"stdio: comando execut\xE1vel (ex: npx, python)"},args:{type:"array",items:{type:"string",maxLength:500},maxItems:32,description:"stdio: argumentos do comando"},env:{type:"object",additionalProperties:{type:"string"},description:"stdio: vari\xE1veis de ambiente (as chaves de API do agente N\xC3O s\xE3o repassadas)"},url:{type:"string",minLength:1,maxLength:2e3,description:"remoto: URL do endpoint MCP (http streamable ou sse)"},type:{type:"string",enum:["http","streamable-http","sse"],description:"remoto: transporte. Padr\xE3o http (com fallback pra sse)"},headers:{type:"object",additionalProperties:{type:"string"},description:"remoto: headers HTTP (ex: Authorization: Bearer ...)"}}},async execute(e){let{serverName:t,command:o,args:n=[],env:a={},url:s,type:i,headers:c}=e;if(!o&&!s)throw new Error("Informe 'command' (stdio) ou 'url' (remoto) para conectar o servidor MCP.");let l;if(s)l={url:s,...i?{type:i}:{},...c?{headers:c}:{}};else{let m=String(process.env.MCP_ALLOWED_COMMANDS||"").split(",").map(f=>f.trim()).filter(Boolean);if(m.length&&!m.includes(o))throw new Error(`Comando MCP "${o}" nao esta na allowlist (MCP_ALLOWED_COMMANDS: ${m.join(", ")}).`);l={command:o,args:n,env:a}}let u=await r.connect(t,l);return{status:"connected",server:t,transport:s?i||"http":"stdio",toolsAdded:u}}}}import{Client as Km}from"@modelcontextprotocol/sdk/client/index.js";import{StdioClientTransport as Xm}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as Ym}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{SSEClientTransport as js}from"@modelcontextprotocol/sdk/client/sse.js";import{readFileSync as Ds,existsSync as so,writeFileSync as Jm}from"node:fs";import me from"node:path";import Us from"node:os";import{fileURLToPath as Qm}from"node:url";var Fs=me.resolve(me.dirname(Qm(import.meta.url)),"..","..",".."),Zm=["PATH","HOME","USERPROFILE","TEMP","TMP","TMPDIR","LANG","LC_ALL","SystemRoot","windir","APPDATA","LOCALAPPDATA"];function ep(r={}){let e={};for(let t of Zm)process.env[t]!==void 0&&(e[t]=process.env[t]);return{...e,...r}}function tp(r,e){let t=o=>String(o||"").replace(/[^a-zA-Z0-9_.-]/g,"_");return`mcp__${t(r)}__${t(e)}`}var nr=class{constructor({toolRegistry:e,logger:t}){this.toolRegistry=e,this.logger=t,this.clients=new Map,this.serverTools=new Map}async connect(e,t,o=[],n={}){if(this.clients.has(e))throw new Error(`MCP server ${e} already connected.`);let a=t&&typeof t=="object"?t:{command:t,args:o,env:n},{client:s,kind:i}=await this.openClient(e,a);this.clients.set(e,s);let c=await this.registerServerTools(e,s);return this.logger?.info(`[MCP] Server ${e} conectado via ${i}. Tools: ${c.join(", ")||"(nenhuma)"}`),c}async openClient(e,t){let o=()=>new Km({name:"ia_multi_agent",version:"1.0.0"},{capabilities:{}});if(t?.url){let a=new URL(t.url),s=t.headers&&typeof t.headers=="object"?t.headers:null,i=s?{requestInit:{headers:s}}:void 0,c=s?{requestInit:{headers:s},eventSourceInit:{fetch:(u,m)=>fetch(u,{...m,headers:{...m?.headers||{},...s}})}}:void 0,l=String(t.type||"").toLowerCase();if(l==="sse"){this.logger?.info(`[MCP] Conectando ${e} via SSE (${a.href})...`);let u=o();return await u.connect(new js(a,c)),{client:u,kind:"sse"}}try{this.logger?.info(`[MCP] Conectando ${e} via HTTP streamable (${a.href})...`);let u=o();return await u.connect(new Ym(a,i)),{client:u,kind:"http"}}catch(u){if(["http","streamable-http","streamablehttp"].includes(l))throw u;this.logger?.warn(`[MCP] HTTP streamable falhou p/ ${e} (${u.message}); tentando SSE...`);let f=o();return await f.connect(new js(a,c)),{client:f,kind:"sse"}}}if(!t?.command)throw new Error(`Defini\xE7\xE3o MCP inv\xE1lida para "${e}": informe "command" (stdio) ou "url" (http/sse).`);this.logger?.info(`[MCP] Conectando ${e} via stdio (${t.command})...`);let n=o();return await n.connect(new Xm({command:t.command,args:t.args||[],env:ep(t.env||{}),stderr:"ignore"})),{client:n,kind:"stdio"}}async registerServerTools(e,t){let o=await t.listTools(),n=[];for(let a of o.tools){let s=tp(e,a.name),i=a.name;class c extends j{constructor(){super({name:s,description:`[MCP: ${e}] ${a.description||"N/A"}`,inputSchema:a.inputSchema,risk:"network",requiresApproval:!0,approvalReason:`Executa a ferramenta "${i}" no servidor MCP externo "${e}".`}),this.isMcp=!0}async execute(u){let m=await t.callTool({name:i,arguments:u});if(m.isError)throw new Error(m.content.map(f=>f.text).join(`
507
+ `));return m.content.map(f=>f.text).join(`
508
+ `)}}this.toolRegistry.register(new c),this.toolRegistry.enabled?.size&&this.toolRegistry.enabled.add(s),n.push(s)}return this.serverTools.set(e,n),n}async disconnect(e){let t=this.clients.get(e),o=this.serverTools.get(e)||[];if(!t&&!o.length)return!1;try{await t?.close?.()}catch(n){this.logger?.warn(`[MCP] Error closing server ${e}: ${n.message}`)}for(let n of o)this.toolRegistry.unregister?.(n);return this.serverTools.delete(e),this.clients.delete(e),!0}isConnected(e){return this.clients.has(e)}readDeclaredServers(e){return or(e)}async connectByName(e,t){let n=or(t)[e];if(!n||!n.command&&!n.url)throw new Error(`Server MCP "${e}" nao declarado em mcp.json`);return this.connect(e,n)}resolveConfigFile(e){let t=[e,me.resolve(process.cwd(),".rivale","mcp.json"),me.join(Us.homedir(),".rivale","mcp.json"),me.join(Fs,".rivale","mcp.json")].filter(Boolean);for(let o of t)if(so(o))return o;return me.resolve(process.cwd(),".rivale","mcp.json")}saveEnabledState(e,t){let o=this.resolveConfigFile(e),n={};try{so(o)&&(n=JSON.parse(Ds(o,"utf8")))}catch{n={}}let a=n.servers&&!n.mcpServers?"servers":"mcpServers";(!n[a]||typeof n[a]!="object")&&(n[a]={});let s=n[a];for(let[i,c]of Object.entries(t))s[i]&&typeof s[i]=="object"&&(s[i].enabled=c);return Jm(o,`${JSON.stringify(n,null,2)}
509
+ `,"utf8"),o}status(e){let t=or(e);return[...new Set([...Object.keys(t),...this.clients.keys()])].sort().map(n=>({name:n,declared:!!t[n],disabled:t[n]?.enabled===!1,connected:this.clients.has(n),tools:(this.serverTools.get(n)||[]).length,command:t[n]?.command||t[n]?.url||""}))}async disconnectAll(){let e=[...this.clients.keys()];for(let t of e)await this.disconnect(t)}async connectFromConfig(e){let t=or(e),o=[];for(let[n,a]of Object.entries(t))if(a?.enabled!==!1&&!(!a?.command&&!a?.url))try{let s=await this.connect(n,a);o.push({name:n,ok:!0,tools:s})}catch(s){this.logger?.warn(`[MCP] auto-connect falhou para "${n}": ${s.message}`),o.push({name:n,ok:!1,error:s.message})}return o}};function or(r){let e=[r,me.resolve(process.cwd(),".rivale","mcp.json"),me.join(Us.homedir(),".rivale","mcp.json"),me.join(Fs,".rivale","mcp.json")].filter(Boolean);for(let t of e)try{if(!so(t))continue;let o=JSON.parse(Ds(t,"utf8")),n=o?.mcpServers||o?.servers;if(n&&typeof n=="object")return n}catch{}return{}}var ar=class{constructor({limit:e=60,windowMs:t=6e4}={}){this.limit=e,this.windowMs=t,this.events=new Map}check(e){let t=Date.now(),n=(this.events.get(e)||[]).filter(a=>t-a<this.windowMs);if(n.length>=this.limit){let a=this.windowMs-(t-n[0]),s=new Error(`Rate limit exceeded for ${e}`);throw s.name="RateLimitError",s.retryAfterMs=a,s}n.push(t),this.events.set(e,n)}};var io=class extends Error{constructor(e,t={}){super(e),this.name="ValidationError",this.details=t}};function lo(r,e,t="$"){return he(r||{},e,t),e}function he(r,e,t){if(!r||r===!0)return;if(r===!1)throw z(t,"Value is not allowed by schema");if(e===void 0||e===null&&r.nullable)return;rp(r,e,t),op(r,e,t),np(r,e,t);let o=up(r,e);o==="object"&&ap(r,e,t),o==="array"&&sp(r,e,t),o==="string"&&ip(r,e,t),(o==="number"||o==="integer")&&cp(r,e,t)}function rp(r,e,t){if(r.allOf)for(let o of r.allOf)he(o,e,t);if(r.anyOf){let o=Bs(r.anyOf,e,t);if(o.length===r.anyOf.length)throw z(t,"Value does not match any allowed schema",{errors:o})}if(r.oneOf){let o=Bs(r.oneOf,e,t),n=r.oneOf.length-o.length;if(n!==1)throw z(t,"Value must match exactly one schema",{matches:n,errors:o})}if(r.not){try{he(r.not,e,t)}catch{return}throw z(t,"Value matches a forbidden schema")}}function Bs(r,e,t){let o=[];for(let n of r)try{he(n,e,t)}catch(a){o.push(a.message)}return o}function op(r,e,t){if("const"in r&&!zs(e,r.const))throw z(t,"Value does not match const",{expected:r.const,received:e});if(r.enum&&!r.enum.some(o=>zs(o,e)))throw z(t,`Invalid value. Expected one of: ${r.enum.join(", ")}`,{allowed:r.enum,received:e})}function np(r,e,t){if(r.type&&!uo(e,r.type))throw z(t,`Invalid type. Expected ${mp(r.type)}.`,{expected:r.type,received:Array.isArray(e)?"array":e===null?"null":typeof e})}function ap(r,e,t){if(!co(e))return;let o=r.required||[];for(let s of o)if(e[s]===void 0||e[s]===null)throw z(`${t}.${s}`,"Missing required field");if(r.minProperties!==void 0&&Object.keys(e).length<r.minProperties)throw z(t,`Object has fewer than ${r.minProperties} properties`);if(r.maxProperties!==void 0&&Object.keys(e).length>r.maxProperties)throw z(t,`Object has more than ${r.maxProperties} properties`);let n=r.properties||{},a=dp(r.patternProperties||{});for(let[s,i]of Object.entries(e)){if(n[s]){he(n[s],i,`${t}.${s}`);continue}let c=a.find(({regex:l})=>l.test(s));if(c){he(c.schema,i,`${t}.${s}`);continue}if(r.additionalProperties===!1)throw z(`${t}.${s}`,"Unexpected field");co(r.additionalProperties)&&he(r.additionalProperties,i,`${t}.${s}`)}}function sp(r,e,t){if(Array.isArray(e)){if(r.minItems!==void 0&&e.length<r.minItems)throw z(t,`Array has fewer than ${r.minItems} items`);if(r.maxItems!==void 0&&e.length>r.maxItems)throw z(t,`Array has more than ${r.maxItems} items`);if(r.uniqueItems&&new Set(e.map(o=>JSON.stringify(o))).size!==e.length)throw z(t,"Array items must be unique");r.items&&e.forEach((o,n)=>he(r.items,o,`${t}[${n}]`))}}function ip(r,e,t){if(typeof e=="string"){if(r.minLength!==void 0&&e.length<r.minLength)throw z(t,`String shorter than ${r.minLength}`);if(r.maxLength!==void 0&&e.length>r.maxLength)throw z(t,`String longer than ${r.maxLength}`);if(r.pattern&&!new RegExp(r.pattern).test(e))throw z(t,`String does not match pattern ${r.pattern}`);r.format&&lp(r.format,e,t)}}function cp(r,e,t){if(!(typeof e!="number"||!Number.isFinite(e))){if(r.type==="integer"&&!Number.isInteger(e))throw z(t,"Expected integer");if(r.minimum!==void 0&&e<r.minimum)throw z(t,`Number below minimum ${r.minimum}`);if(r.maximum!==void 0&&e>r.maximum)throw z(t,`Number above maximum ${r.maximum}`);if(r.exclusiveMinimum!==void 0&&e<=r.exclusiveMinimum)throw z(t,`Number must be greater than ${r.exclusiveMinimum}`);if(r.exclusiveMaximum!==void 0&&e>=r.exclusiveMaximum)throw z(t,`Number must be less than ${r.exclusiveMaximum}`);if(r.multipleOf!==void 0&&e%r.multipleOf!==0)throw z(t,`Number must be multiple of ${r.multipleOf}`)}}function lp(r,e,t){if(r==="uri"||r==="url")try{new URL(e);return}catch{throw z(t,"Invalid URL format")}if(r==="email"&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e))throw z(t,"Invalid email format");if(r==="date-time"&&Number.isNaN(Date.parse(e)))throw z(t,"Invalid date-time format")}function up(r,e){return Array.isArray(r.type)?r.type.find(t=>uo(e,t)):r.type?r.type:r.properties||r.required?"object":r.items||Array.isArray(e)?"array":e===null?"null":typeof e}function uo(r,e){return Array.isArray(e)?e.some(t=>uo(r,t)):e==="array"?Array.isArray(r):e==="integer"?Number.isInteger(r):e==="number"?typeof r=="number"&&Number.isFinite(r):e==="object"?co(r):e==="null"?r===null:typeof r===e}function co(r){return r!==null&&typeof r=="object"&&!Array.isArray(r)}function dp(r){return Object.entries(r).map(([e,t])=>({regex:new RegExp(e),schema:t}))}function zs(r,e){return JSON.stringify(r)===JSON.stringify(e)}function mp(r){return Array.isArray(r)?r.join(" | "):r}function z(r,e,t={}){return new io(`${e} at ${r}`,{path:r,...t})}var pp=new Set(["file_write","file_edit","file_delete"]),ot=class extends Error{constructor(e,t={}){super(e),this.name="ToolApprovalError",this.details=t}},mo=class extends Error{constructor(e,t={}){super(e),this.name="ToolPlanModeError",this.details=t}},sr=class{constructor({registry:e,config:t,eventBus:o,logger:n,hookManager:a,checkpointManager:s,permissionEngine:i}={}){this.registry=e,this.config=t,this.eventBus=o,this.logger=n,this.hookManager=a,this.checkpointManager=s,this.permissionEngine=i,this.readFileState=new Map,this.rateLimiter=new ar({limit:t.tools.rateLimitPerMinute,windowMs:6e4})}async execute(e,t={}){let o=this.registry.get(e.name);if(!o)return this.failure(e,new Error(`Unknown or disabled tool: ${e.name}`));let n=performance.now();await this.eventBus?.emit("tool:start",{id:e.id,name:o.name,arguments:e.arguments});try{this.rateLimiter.check(o.name);let a=e.arguments||{};if(a&&a._malformed_json)if(o.name==="file_write"){let m=yp(a._raw);if(m)a=m,e.arguments=a;else throw new Error("Invalid JSON syntax in tool arguments. You likely failed to escape quotes or newlines. Do not pass massive code blocks without proper escaping. Write the file in smaller chunks or use file_edit.")}else throw new Error("Invalid JSON syntax in tool arguments.");typeof o.validate=="function"&&(a=o.validate(a)||a,e.arguments=a),lo(o.inputSchema,a);let s=await this.hookManager?.runPreToolUse({tool:o,toolCall:e});if(s?.updatedInput&&(a={...a,...s.updatedInput},e.arguments=a,lo(o.inputSchema,a)),this.enforcePlanMode(o,a),await this.ensureApproved(o,e,t),this.checkpointManager&&pp.has(o.name)&&a?.path)try{let m=I(this.config.tools.fileRoot,a.path);await this.checkpointManager.snapshot(t.conversationId,m)}catch{}let i=await Ye(()=>Ue(m=>o.execute(e.arguments||{},{...t,signal:m,config:this.config,eventBus:this.eventBus,logger:this.logger,readFileState:this.readFileState}),o.timeoutMs??this.config.tools.timeoutMs,`Tool ${o.name} timed out`,t.signal),{attempts:fp(o,this.config.tools.retryAttempts)}),c=Math.round(performance.now()-n),l={toolCallId:e.id,name:o.name,ok:!0,durationMs:c,result:hp(i,o.maxResultSizeChars)},u=await this.hookManager?.runPostToolUse({tool:o,toolCall:e,result:l.result,durationMs:c});return u?.runs?.length&&(u.additionalContext?.length&&(l.result=gp(l.result,u.additionalContext)),l.hooks={runs:u.runs.map(m=>({hook:m.hook,ok:m.ok,durationMs:m.durationMs,error:m.error})),additionalContext:u.additionalContext}),await this.eventBus?.emit("tool:end",l),this.logger?.info("tool executed",{name:o.name,durationMs:c}),l}catch(a){let s=Math.round(performance.now()-n);return await this.hookManager?.runPostToolUseFailure({toolCall:e,error:a,durationMs:s}).catch(i=>{this.logger?.warn("post failure hook failed",{tool:e.name,error:i.message})}),this.failure(e,a,s)}}async failure(e,t,o=0){let n={toolCallId:e.id,name:e.name,ok:!1,durationMs:o,error:{name:t.name,message:t.message,details:t.details}};return await this.eventBus?.emit("tool:error",n),this.logger?.warn("tool failed",{name:e.name,error:t.message}),n}enforcePlanMode(e,t){if(!this.config.tools?.planMode)return;let o=typeof e.getRisk=="function"?e.getRisk(t):e.risk;if(o==="write"||o==="dangerous")throw new mo(`Modo plan ativo: "${e.name}" (risco ${o}) altera estado e esta bloqueado. So leitura e pesquisa sao permitidas \u2014 desligue o plan mode para executar.`,{toolName:e.name,risk:o})}async ensureApproved(e,t,o){let n=t.arguments||{},a=this.permissionEngine?.isEmpty?null:this.permissionEngine?.evaluate(e.name,n);if(a==="deny")throw await this.eventBus?.emit("tool:approval:denied",{toolName:e.name,arguments:n,byRule:!0}),new ot(`Ferramenta "${e.name}" bloqueada por regra de permissao (deny) em .rivale/permissions.json.`,{toolName:e.name,byRule:!0});if(a!=="allow"){if(!(a==="ask"||this.requiresApproval(e,n)))return}else return;let s={toolName:e.name,toolDescription:e.description,arguments:t.arguments||{},reason:typeof e.getApprovalReason=="function"?e.getApprovalReason(t.arguments||{}):e.approvalReason||"Ferramenta sensivel configurada para exigir aprovacao humana.",risk:typeof e.getRisk=="function"?e.getRisk(t.arguments||{}):e.risk||"dangerous"};if(await this.eventBus?.emit("tool:approval:required",s),typeof o.approvalHandler!="function")throw new ot(`Approval required for tool ${e.name}, but no approval handler was provided.`,{toolName:e.name});let i=await o.approvalHandler(s);if(!(typeof i=="boolean"?i:!!i?.approved))throw await this.eventBus?.emit("tool:approval:denied",{...s,decision:i}),new ot(`Tool ${e.name} was denied by human approval.`,{toolName:e.name,decision:i});await this.eventBus?.emit("tool:approval:approved",{...s,decision:i})}requiresApproval(e,t){let o=this.config.tools.approvalMode;if(o==="never"||o==="off")return!1;if(o==="always"||this.config.tools.approvalRequiredTools.includes(e.name))return!0;if(typeof e.requiresApproval=="function")return!!e.requiresApproval(t);if(typeof e.requiresApproval=="boolean"&&e.requiresApproval)return!0;let n=typeof e.getRisk=="function"?e.getRisk(t):e.risk;return o==="dangerous"?n==="dangerous":o==="write"?n==="write"||n==="dangerous":o==="network"?n==="network"||n==="browser":!1}};function fp(r,e){return r.retryAttempts!=null?r.retryAttempts:r.isReadOnly===!0?e:0}function hp(r,e=12e3){let t=typeof r=="string"?r:JSON.stringify(r??null);if(e===1/0)return r;let o=Number.isFinite(e)?e:12e3;return t.length<=o?r:{truncated:!0,preview:t.slice(0,o)}}function gp(r,e){return e?.length?r&&typeof r=="object"&&!Array.isArray(r)?{...r,hookContext:e}:{value:r,hookContext:e}:r}function yp(r){if(typeof r!="string")return null;try{let e=r.match(/['"]?path['"]?\s*:\s*['"]([^'"]+)['"]/i),t=r.match(/['"]?(?:content|code|codigo|text|body)['"]?\s*:\s*['"`]([\s\S]*)/i);if(e&&t){let o=t[1];if(!r.trim().endsWith("}"))throw new Error("TOKEN LIMIT REACHED: Your output was truncated because the file is too large. You CANNOT write this entire file at once. You must use 'file_edit' to edit the file in smaller chunks, or write the file in parts.");return o=o.replace(/["'`]?\s*\}\s*`*$/,""),{path:e[1],content:o.replace(/\\n/g,`
510
+ `).replace(/\\"/g,'"').replace(/\\\\/g,"\\")}}}catch(e){if(e.message.includes("TOKEN LIMIT REACHED"))throw e}return null}import{readFileSync as bp,existsSync as vp}from"node:fs";import Ie from"node:path";import wp from"node:os";var Sp=new Set(["run_command","start_background_task"]),xp=["path","to","dest","destination","target","file"];function ir(r){let e=String(r).replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${e}$`,"i")}function po(r){let e=String(r||"").trim(),t=e.indexOf(":");return t===-1?{tool:e,pattern:null}:{tool:e.slice(0,t).trim(),pattern:e.slice(t+1).trim()}}function Tp(r,e){try{let t=Ie.resolve(r||"."),o=Ie.resolve(t,String(e));return Ie.relative(t,o).split(Ie.sep).join("/")||"."}catch{return String(e)}}function Ep(r){let e=String(r||"").trim().replace(/\s+/g," ");if(!e)return"";let t=e.indexOf(" "),o=t===-1?e:e.slice(0,t),n=t===-1?"":e.slice(t);return o.replace(/^[\\"']+/,"").replace(/["']+$/,"").replace(/^.*[/\\]/,"")+n}function _p(r,e,t="."){if(!e||typeof e!="object")return"";if(e.command!=null)return String(e.command);for(let o of xp)if(e[o]!=null)return Tp(t,e[o]);return e.url!=null?String(e.url):e.query!=null?String(e.query):Object.values(e).filter(o=>typeof o=="string").join(" ")}var cr=class{constructor({rules:e,fileRoot:t}={}){this.fileRoot=t||".",this.deny=(e?.deny||[]).map(po),this.ask=(e?.ask||[]).map(po),this.allow=(e?.allow||[]).map(po)}get isEmpty(){return this.deny.length===0&&this.ask.length===0&&this.allow.length===0}matchesTool(e,t,o){return e.some(n=>ir(n.tool).test(t)?n.pattern==null?!0:ir(n.pattern).test(o):!1)}matchesCmd(e,t,o){return e.some(n=>t.some(a=>ir(n.tool).test(a))?n.pattern==null?!0:ir(n.pattern).test(o.trim()):!1)}evaluateCommand(e,t){let o=e==="start_background_task"?[t?.command,...Array.isArray(t?.args)?t.args:[]].filter(Boolean).join(" "):String(t?.command||"");if(!o.trim())return null;let n=Me(o),a=(n.length?n:[o]).map(Ep).filter(Boolean),s=e==="run_command"?["run_command"]:[e,"run_command"];for(let c of a)if(this.matchesCmd(this.deny,s,c))return"deny";for(let c of a)if(this.matchesCmd(this.ask,s,c))return"ask";return!a.some(c=>/[<>]/.test(c))&&this.allow.length&&a.every(c=>this.matchesCmd(this.allow,[e],c))?"allow":null}evaluate(e,t){if(Sp.has(e))return this.evaluateCommand(e,t);let o=_p(e,t,this.fileRoot);return this.matchesTool(this.deny,e,o)?"deny":this.matchesTool(this.ask,e,o)?"ask":this.matchesTool(this.allow,e,o)?"allow":null}};function Hs({fileRoot:r=".",logger:e}={}){let t=Ie.join(wp.homedir(),".rivale","permissions.json"),o=Ie.resolve(r,".rivale","permissions.json"),n=o===t?[t]:[t,o],a={allow:[],deny:[],ask:[]};for(let s of n)try{if(!vp(s))continue;let i=JSON.parse(bp(s,"utf8")),c=i.permissions||i;for(let l of["allow","deny","ask"])Array.isArray(c[l])&&a[l].push(...c[l])}catch(i){e?.warn?.(`[permissions] ignorando ${s}: ${i.message}`)}return a}import{mkdir as kp,readFile as ur,writeFile as lr,rm as $p}from"node:fs/promises";import Te from"node:path";var dr=class{constructor({config:e,logger:t}={}){this.baseDir=Te.join(e.storage.dataDir,"checkpoints"),this.logger=t,this.currentRun=new Map,this.snapshotted=new Map}startRun(e,t){this.currentRun.set(e||"default",t),this.snapshotted.has(t)||this.snapshotted.set(t,new Set)}async snapshot(e,t){let o=this.currentRun.get(e||"default");if(!o||!t)return;let n=this.snapshotted.get(o)||new Set;if(!n.has(t)){n.add(t),this.snapshotted.set(o,n);try{let a=Te.join(this.baseDir,fo(o));await kp(a,{recursive:!0});let s=null,i=!1;try{s=await ur(t,"utf8"),i=!0}catch{i=!1}let c=Te.join(a,"manifest.json"),l=await Gs(c,{runId:o,conversationId:e||"default",entries:[]}),u=l.entries.length,m=null;i&&(m=Te.join(a,`${u}.bak`),await lr(m,s,"utf8")),l.entries.push({path:t,existed:i,backupFile:m}),await lr(c,JSON.stringify(l,null,2),"utf8"),await lr(this.pointerPath(e),o,"utf8")}catch(a){this.logger?.warn("checkpoint snapshot failed",{path:t,error:a.message})}}}async rollback(e){let t=e||"default",o=this.currentRun.get(t);if(o&&(this.snapshotted.get(o)?.size||0)>0||(o=await Ap(this.pointerPath(t))),!o)return{restored:[],message:"Nenhum checkpoint para reverter."};let a=Te.join(this.baseDir,fo(o)),s=await Gs(Te.join(a,"manifest.json"),null);if(!s?.entries?.length)return{restored:[],message:"Checkpoint vazio ou nao encontrado."};let i=[];for(let c of s.entries)try{if(c.existed&&c.backupFile){let l=await ur(c.backupFile,"utf8");await lr(c.path,l,"utf8"),i.push({path:c.path,action:"restored"})}else await $p(c.path,{force:!0}),i.push({path:c.path,action:"deleted"})}catch(l){i.push({path:c.path,action:"error",error:l.message})}return this.snapshotted.delete(o),{restored:i,runId:o}}pointerPath(e){return Te.join(this.baseDir,`latest_${fo(e||"default")}.txt`)}};function fo(r){return String(r||"").replace(/[^a-zA-Z0-9_-]/g,"_")}async function Gs(r,e){try{return JSON.parse(await ur(r,"utf8"))}catch{return e}}async function Ap(r){try{return(await ur(r,"utf8")).trim()}catch{return null}}import{readdir as Rp,readFile as Cp,stat as Lp}from"node:fs/promises";import ho from"node:path";var Op=new Set([".js",".mjs",".cjs",".jsx",".ts",".tsx",".vue",".svelte",".py",".go",".rs",".java",".rb",".php",".c",".cpp",".h",".css",".scss",".html",".json",".md"]),Mp=new Set(["node_modules",".git","data","dist","build","coverage",".rivale",".next","out"]),Pp=200*1024,Ws=40,Ip=8,mr=class{constructor({config:e,storage:t,embeddingManager:o,logger:n}={}){this.config=e,this.storage=t,this.embeddingManager=o,this.logger=n}get semanticQuality(){return this.embeddingManager?.semantic?"high":"low"}async ensureIndexed(e){return this.storage.countCodeChunks()>0?{alreadyIndexed:!0,chunks:this.storage.countCodeChunks()}:this.index(e)}async index({maxFiles:e=500,maxChunks:t=1200}={}){let o=this.config.tools.fileRoot,n=await Np(o,e);this.storage.clearCodeChunks();let a=0;for(let s of n){if(a>=t)break;let i;try{i=await Cp(s,"utf8")}catch{continue}let c=ho.relative(o,s)||s,l=qp(i);for(let u of l){if(a>=t)break;try{let m=await this.embeddingManager.embed(`${c}
511
+ ${u.text}`);if(!m?.vector?.length)continue;this.storage.saveCodeChunk({id:F("chunk"),path:c,startLine:u.startLine,endLine:u.endLine,content:u.text,provider:m.provider,model:m.model,vector:m.vector}),a+=1}catch(m){this.logger?.warn("code chunk embedding failed",{path:c,error:m.message})}}}return{files:n.length,chunks:a,quality:this.semanticQuality}}async search({query:e,limit:t=8}){let o=await this.embeddingManager.embed(e);return o?.vector?.length?this.storage.searchCodeByVector({vector:o.vector,limit:t}):[]}};async function Np(r,e){let t=[];async function o(n){if(t.length>=e)return;let a;try{a=await Rp(n,{withFileTypes:!0})}catch{return}for(let s of a){if(t.length>=e)return;let i=ho.join(n,s.name);if(s.isDirectory()){if(Mp.has(s.name)||s.name.startsWith("."))continue;await o(i)}else if(s.isFile()&&Op.has(ho.extname(s.name).toLowerCase()))try{(await Lp(i)).size<=Pp&&t.push(i)}catch{}}}return await o(r),t}function qp(r){let e=String(r||"").split(`
512
+ `),t=[];for(let o=0;o<e.length;o+=Ws-Ip){let n=Math.min(o+Ws,e.length),a=e.slice(o,n).join(`
513
+ `).trim();if(a&&t.push({startLine:o+1,endLine:n,text:a}),n>=e.length)break}return t}function Vs({codeIndexer:r}){class e extends j{constructor(){super({name:"semantic_code_search",description:["Busca semantica no codigo do workspace: descreva o que procura em linguagem natural","(ex: 'onde a autenticacao valida a senha') e recebe os trechos mais relevantes por significado.","Complementa grep_search (exato) quando voce nao sabe o nome exato do simbolo.","Indexa automaticamente na primeira vez; use action='reindex' apos mudancas grandes."].join(" "),risk:"read",isReadOnly:!0,isConcurrencySafe:!0,shouldDefer:!0,searchHint:"semantic code search embeddings meaning find relevant snippets",maxResultSizeChars:4e4,inputSchema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",minLength:1,maxLength:400,description:"O que voce procura, em linguagem natural."},action:{type:"string",enum:["search","reindex"],description:"Padrao search. reindex reconstroi o indice."},limit:{type:"integer",minimum:1,maximum:20,description:"Quantidade de trechos. Padrao 8."}}}})}validate(o){return{...o,action:o.action||"search",limit:o.limit||8}}async execute(o){let n=null;o.action==="reindex"?n=await r.index():n=await r.ensureIndexed();let a=await r.search({query:o.query,limit:o.limit});return{query:o.query,indexed:n,quality:r.semanticQuality,note:r.semanticQuality==="low"?"Embeddings em modo 'local' (fraco). Para busca semantica de verdade, use EMBEDDING_PROVIDER=openai.":void 0,matches:a.map(s=>({location:`${s.path}:${s.startLine}-${s.endLine}`,score:Math.round((s.score||0)*1e3)/1e3,preview:s.content.slice(0,600)}))}}}return new e}var pr={debug:10,info:20,warn:30,error:40,silent:100},fr=class r{constructor({level:e="info",name:t="agent"}={}){this.level=pr[e]??pr.info,this.name=t}child(e={}){let t=new r({level:"debug",name:this.name});return t.level=this.level,t.bindings={...this.bindings||{},...e},t}debug(e,t={}){this.write("debug",e,t)}info(e,t={}){this.write("info",e,t)}warn(e,t={}){this.write("warn",e,t)}error(e,t={}){this.write("error",e,t)}write(e,t,o={}){if((pr[e]??pr.info)<this.level)return;let n={time:new Date().toISOString(),level:e,logger:this.name,message:t,...this.bindings||{},...Ks(o)},a=JSON.stringify(n);console.error(a)}};function Ks(r){if(!r||typeof r!="object")return r;let e=["apiKey","apikey","authorization","password","secret","token"],t=Array.isArray(r)?[]:{};for(let[o,n]of Object.entries(r))e.some(a=>o.toLowerCase().includes(a))?t[o]="[redacted]":n&&typeof n=="object"?t[o]=Ks(n):t[o]=n;return t}function Xs(r={}){let e=r.config||Pr(),t=r.logger||new fr({level:e.app.logLevel,name:e.app.name}),o=r.eventBus||new bt({logger:t}),n=r.storage||new Wt({config:e,logger:t}),a=r.lspManager||new Ct({config:e,logger:t}),s=r.hookManager||new vt({config:e,eventBus:o,logger:t}),i=r.skillManager||new Ht({config:e,logger:t});o.on("*",async(A,M)=>{(M?.startsWith("llm:")||M?.startsWith("tool:")||M?.startsWith("agent:"))&&n.logEvent({type:M,payload:A})});let c=r.memoryManager||new Bt({config:e,storage:n,eventBus:o,lspManager:a,logger:t}),l=r.llmManager||new jt({config:e,eventBus:o,logger:t,hookManager:s}),u=r.toolRegistry||Cs({config:e,memoryManager:c,storage:n,eventBus:o,lspManager:a,skillManager:i,logger:t}),m=r.mcpManager||new nr({toolRegistry:u,logger:t});u.register(qs({mcpManager:m}));let f=r.codeIndexer||new mr({config:e,storage:n,embeddingManager:c.embeddingManager,logger:t});u.register(Vs({codeIndexer:f}));let g=r.checkpointManager||new dr({config:e,logger:t}),w=r.permissionEngine||new cr({rules:Hs({fileRoot:e.tools.fileRoot,logger:t}),fileRoot:e.tools.fileRoot}),y=r.toolRunner||new sr({registry:u,config:e,eventBus:o,logger:t,hookManager:s,checkpointManager:g,permissionEngine:w}),b=r.subAgentRegistry||new wt;r.subAgentRegistry||On(b,{fileRoot:e.tools.fileRoot,logger:t});let E=r.subAgentRunner||new xt({config:e,llmManager:l,toolRegistry:u,toolRunner:y,subAgentRegistry:b,storage:n,eventBus:o,logger:t});e.multiAgent.enabled&&!u.tools.has("invoke_subagent")&&(u.register(Ls({subAgentRegistry:b,subAgentRunner:E})),u.register(Os({subAgentRegistry:b,subAgentRunner:E})),u.register(Ms({subAgentRegistry:b,subAgentRunner:E})),u.register(Ps({subAgentRunner:E})),u.register(Is({subAgentRunner:E})),u.register(Ns({subAgentRunner:E})));let k=r.contextManager||new Re({config:e,memoryManager:c,subAgentRegistry:b,skillManager:i,toolRegistry:u,eventBus:o,logger:t}),R=r.planner||new zt({config:e,llmManager:l,eventBus:o,logger:t});return{agent:new ut({config:e,llmManager:l,toolRegistry:u,toolRunner:y,memoryManager:c,contextManager:k,planner:R,storage:n,checkpointManager:g,hookManager:s,eventBus:o,logger:t}),config:e,logger:t,eventBus:o,storage:n,lspManager:a,hookManager:s,skillManager:i,memoryManager:c,llmManager:l,toolRegistry:u,toolRunner:y,permissionEngine:w,mcpManager:m,checkpointManager:g,codeIndexer:f,subAgentRegistry:b,subAgentRunner:E,contextManager:k,planner:R}}async function Zs(r=process.argv.slice(2)){let e=r;if(e[0]==="keys"){await Fp(e.slice(1));return}let t=e.includes("--debug"),o=e.length===0||e.includes("--chat"),n=e.includes("--stream")||o&&!e.includes("--no-stream");if(o){let l=Js({debug:t,chatMode:!0}),u=Xs({config:l}),m=await Ys(u,{quiet:!0});await xn(u,{conversationId:process.env.CONVERSATION_ID||"chat",stream:n,mcp:m}),process.exit(0)}let a=e.filter(l=>!l.startsWith("--")).join(" ").trim();a||(console.log("Uso:"),console.log(" rivale"),console.log(" node src/index.js --chat"),console.log(' node src/index.js --stream "sua mensagem"'),console.log(' node src/index.js "sua mensagem"'),process.exit(0));let s=Xs({config:Js({debug:t,chatMode:!1})}),{agent:i,storage:c}=s;await Ys(s);try{await s.hookManager?.runSessionStart({conversationId:process.env.CONVERSATION_ID||"cli",mode:"cli"}),console.log(`
514
+ Resposta:
515
+ `);let l=await i.run(a,{conversationId:process.env.CONVERSATION_ID||"cli",stream:n,approvalHandler:sn(),onToken:n?u=>process.stdout.write(u):void 0});!n||l.blocked?console.log(l.content):process.stdout.write(`
516
+ `),console.log(`
517
+ Metricas:`),console.log(JSON.stringify(l.metrics,null,2))}catch(l){console.error(`
518
+ Erro: ${l.message}`),process.exitCode=1}finally{await s.hookManager?.runSessionEnd({conversationId:process.env.CONVERSATION_ID||"cli",mode:"cli"}).catch(()=>null),await s.lspManager?.stop().catch(()=>null),await s.mcpManager?.disconnectAll?.().catch(()=>null),c.close()}}async function Ys(r,{quiet:e=!1}={}){try{let t=await r.mcpManager.connectFromConfig(process.env.MCP_CONFIG_PATH),o=t.filter(a=>a.ok),n=r.config.coordinator?.allowedTools;if(Array.isArray(n))for(let a of o)for(let s of a.tools||[])n.includes(s)||n.push(s);if(!e){o.length&&console.log(`MCP: ${o.map(a=>`${a.name} (${a.tools?.length||0} tools)`).join(", ")}`);for(let a of t.filter(s=>!s.ok))console.error(`MCP: falha em "${a.name}" \u2014 ${a.error}`)}return t}catch(t){return e||console.error(`MCP: erro ao auto-conectar \u2014 ${t.message}`),[]}}function Js({debug:r=!1,chatMode:e=!1}={}){let t=Pr();return t.app.logLevel=r?"debug":"silent",e&&(t.agent.maxParallelToolCalls=1),t}var Dp=["GROQ_API_KEY","OPENAI_API_KEY","GEMINI_API_KEY","DEEPSEEK_API_KEY","ANTHROPIC_API_KEY","BRAVE_API_KEY","OPENROUTER_API_KEY"];function Up(r){return new Promise(e=>{let t=jp.createInterface({input:process.stdin,output:process.stdout});process.stdout.write(`${r}: `),process.stdin.isTTY&&(t._writeToOutput=()=>{}),t.question("",o=>{t.close(),process.stdout.write(`
519
+ `),e(String(o).trim())})})}function Qs(r){return r?r.length<=8?"****":`${r.slice(0,4)}\u2026${r.slice(-4)}`:""}async function Fp(r){let[e,t,o]=r;switch(e){case"list":{let n=en();if(!n.length){console.log("Cofre vazio. Use: rivale keys set NOME");return}console.log("Chaves no cofre (~/.rivale/secrets.json):");for(let a of n)console.log(` ${a} = ${Qs(mt(a))}`);return}case"set":{if(!t){console.log("Uso: rivale keys set NOME [valor] (sem valor = digita escondido)");return}let n=o||await Up(`Valor de ${t}`);if(!n){console.error("Valor vazio; nada salvo."),process.exitCode=1;return}ze(t,n),console.log(`\u2713 ${t} salvo no cofre (${Qs(n)}).`);return}case"get":{if(!t){console.log("Uso: rivale keys get NOME");return}let n=mt(t);if(n==null){console.error(`"${t}" n\xE3o est\xE1 no cofre.`),process.exitCode=1;return}console.log(n);return}case"rm":case"delete":{if(!t){console.log("Uso: rivale keys rm NOME");return}console.log(Zo(t)?`\u2713 ${t} removido do cofre.`:`"${t}" n\xE3o estava no cofre.`);return}case"import-env":{let n=[];for(let a of Dp){let s=process.env[a];s&&(ze(a,s),n.push(a))}if(!n.length){console.log("Nenhuma chave conhecida encontrada no ambiente para migrar.");return}console.log(`\u2713 Migradas pro cofre: ${n.join(", ")}`),console.log("Agora REMOVA essas linhas do seu .env (elas ficar\xE3o s\xF3 no cofre criptografado).");return}default:console.log("Uso: rivale keys <list | set NOME [valor] | get NOME | rm NOME | import-env>")}}process.env.TOOL_FILE_ROOT||(process.env.TOOL_FILE_ROOT=process.cwd());Zs(process.argv.slice(2)).catch(r=>{console.error(r),process.exitCode=1});