| 7701 | 2. If the condition is not met, return: {"ok": false, "reason": "Reason for why it is not met"}`]),thinkingConfig:{type:"disabled"},tools:$.options.tools,signal:X,options:{async getToolPermissionContext(){return $.getAppState().toolPermissionContext},model:q.model??PH(),toolChoice:void 0,isNonInteractiveSession:!0,hasAppendSystemPrompt:!1,agents:[],querySource:"hook_prompt",mcpTools:[],agentId:$.agentId,outputFormat:{type:"json_schema",schema:{type:"object",properties:{ok:{type:"boolean"},reason:{type:"string"}},required:["ok"],additionalProperties:!1}}}});P();let D=L3(W.message.content);$.setResponseLength((T)=>T+D.length);let f=D.trim();N(`Hooks: Model response: ${f}`);let G=m5(f);if(!G)return N(`Hooks: error parsing response as JSON: ${f}`),{hook:q,outcome:"non_blocking_error",message:V4({type:"hook_non_blocking_error",hookName:K,toolUseID:w,hookEvent:_,stderr:"JSON validation failed",stdout:f,exitCode:1})};let Z=Uq8().safeParse(G);if(!Z.success)return N(`Hooks: model response does not conform to expected schema: ${Z.error.message}`),{hook:q,outcome:"non_blocking_error",message:V4({type:"hook_non_blocking_error",hookName:K,toolUseID:w,hookEvent:_,stderr:`Schema validation failed: ${Z.error.message}`,stdout:f,exitCode:1})};if(!Z.data.ok)return N(`Hooks: Prompt hook condition was not met: ${Z.data.reason}`),{hook:q,outcome:"blocking",blockingError:{blockingError:`Prompt hook condition was not met: ${Z.data.reason}`,command:q.prompt},preventContinuation:!0,stopReason:Z.data.reason};return N("Hooks: Prompt hook condition was met"),{hook:q,outcome:"success",message:V4({type:"hook_success",hookName:K,toolUseID:w,hookEvent:_,content:""})}}catch(W){if(P(),X.aborted)return{hook:q,outcome:"cancelled"};throw W}}catch(j){let H=d6(j);return N(`Hooks: Prompt hook error: ${H}`),{hook:q,outcome:"non_blocking_error",message:V4({type:"hook_non_blocking_error",hookName:K,toolUseID:w,hookEvent:_,stderr:`Error executing prompt hook: ${H}`,stdout:"",exitCode:1})}}}var OgK=y(()=>{ew();lP();nS6();_8();y8();vO();i1();aq();LQ8()});import{randomUUID as wgK}from"crypto";async function jgK(q,K,_,z,Y,$,A,O,w){let j=A||`hook-${wgK()}`,H=$.agentId?c0($.agentId):Y$(),J=Date.now();try{let M=yQ8(q.prompt,z);N(`Hooks: Processing agent hook with prompt: ${M}`);let P=[U8({content:M})];N(`Hooks: Starting agent query with ${P.length} messages`);let W=q.timeout?q.timeout*1000:60000,D=P3(),{signal:f,cleanup:G}=Ty(Y,{timeoutMs:W}),Z=()=>D.abort();f.addEventListener("abort",Z);let T=D.signal;try{let v=$gK(),E=[...$.options.tools.filter((F)=>!g_(F,MD)).filter((F)=>!mV6.has(F.name)),v],S=iK([`You are verifying a stop condition in Claude Code. Your task is to verify that the agent completed the given plan. The conversation transcript is available at: ${H} |
| 7709 | - ok: false with reason if the condition is not met`]),R=q.model??PH(),x=50,I=pO(`hook-agent-${wgK()}`),B={...$,agentId:I,abortController:D,options:{...$.options,tools:E,mainLoopModel:R,isNonInteractiveSession:!0,thinkingConfig:{type:"disabled"}},setInProgressToolUseIDs:()=>{},getAppState(){let F=$.getAppState(),U=F.toolPermissionContext.alwaysAllowRules.session??[];return{...F,toolPermissionContext:{...F.toolPermissionContext,mode:"dontAsk",alwaysAllowRules:{...F.toolPermissionContext.alwaysAllowRules,session:[...U,`Read(/${H})`]}}}}};EQ8($.setAppState,I);let p=null,C=0,g=!1;for await(let F of Db({messages:P,systemPrompt:S,userContext:{},systemContext:{},canUseTool:uX,toolUseContext:B,querySource:"hook_agent"})){if(fh6(F,()=>{},(U)=>$.setResponseLength((c)=>c+U.length),$.setStreamMode??(()=>{}),()=>{}),F.type==="stream_event"||F.type==="stream_request_start")continue;if(F.type==="assistant"){if(C++,C>=50){g=!0,N(`Hooks: Agent turn ${C} hit max turns, aborting`),D.abort();break}}if(F.type==="attachment"&&F.attachment.type==="structured_output"){let U=Uq8().safeParse(F.attachment.data);if(U.success){p=U.data,N(`Hooks: Got structured output: ${g6(p)}`),D.abort();break}}}if(f.removeEventListener("abort",Z),G(),pN6($.setAppState,I),!p){if(g)return N("Hooks: Agent hook did not complete within 50 turns"),d("tengu_agent_stop_hook_max_turns",{durationMs:Date.now()-J,turnCount:C,agentName:w}),{hook:q,outcome:"cancelled"};return N("Hooks: Agent hook did not return structured output"),d("tengu_agent_stop_hook_error",{durationMs:Date.now()-J,turnCount:C,errorType:1,agentName:w}),{hook:q,outcome:"cancelled"}}if(!p.ok)return N(`Hooks: Agent hook condition was not met: ${p.reason}`),{hook:q,outcome:"blocking",blockingError:{blockingError:`Agent hook condition was not met: ${p.reason}`,command:q.prompt}};return N("Hooks: Agent hook condition was met"),d("tengu_agent_stop_hook_success",{durationMs:Date.now()-J,turnCount:C,agentName:w}),{hook:q,outcome:"success",message:V4({type:"hook_success",hookName:K,toolUseID:j,hookEvent:_,content:""})}}catch(v){if(f.removeEventListener("abort",Z),G(),T.aborted)return{hook:q,outcome:"cancelled"};throw v}}catch(M){let X=d6(M);return N(`Hooks: Agent hook error: ${X}`),d("tengu_agent_stop_hook_error",{durationMs:Date.now()-J,errorType:2,agentName:w}),{hook:q,outcome:"non_blocking_error",message:V4({type:"hook_non_blocking_error",hookName:K,toolUseID:j,hookEvent:_,stderr:`Error executing agent hook: ${X}`,stdout:"",exitCode:1})}}}var HgK=y(()=>{Tj6();k8();Bq();GU();BD();M0();B2();lP();nS6();_8();y8();i1();aq();Fj();_K();l8();LQ8();zo()});import{lookup as xhY}from"dns";import{isIP as XgK}from"net";function JgK(q){let K=XgK(q);if(K===4)return PgK(q);if(K===6)return IhY(q);return!1}function PgK(q){let K=q.split(".").map(Number),[_,z]=K;if(K.length!==4||_===void 0||z===void 0||K.some((Y)=>Number.isNaN(Y)))return!1;if(_===127)return!1;if(_===0)return!0;if(_===10)return!0;if(_===169&&z===254)return!0;if(_===172&&z>=16&&z<=31)return!0;if(_===100&&z>=64&&z<=127)return!0;if(_===192&&z===168)return!0;return!1}function IhY(q){let K=q.toLowerCase();if(K==="::1")return!1;if(K==="::")return!0;let _=mhY(K);if(_!==null)return PgK(_);if(K.startsWith("fc")||K.startsWith("fd"))return!0;let z=K.split(":")[0];if(z&&z.length===4&&z>="fe80"&&z<="febf")return!0;return!1}function uhY(q){let K=[];if(q.includes(".")){let j=q.lastIndexOf(":"),H=q.slice(j+1);q=q.slice(0,j);let J=H.split(".").map(Number);if(J.length!==4||J.some((M)=>!Number.isInteger(M)||M<0||M>255))return null;K=[J[0]<<8|J[1],J[2]<<8|J[3]]}let _=q.indexOf("::"),z,Y;if(_===-1)z=q.split(":"),Y=[];else{let j=q.slice(0,_),H=q.slice(_+2);z=j===""?[]:j.split(":"),Y=H===""?[]:H.split(":")}let A=8-K.length-z.length-Y.length;if(A<0)return null;let w=[...z,...Array(A).fill("0"),...Y].map((j)=>parseInt(j,16));if(w.some((j)=>Number.isNaN(j)||j<0||j>65535))return null;return w.push(...K),w.length===8?w:null}function mhY(q){let K=uhY(q);if(!K)return null;if(K[0]===0&&K[1]===0&&K[2]===0&&K[3]===0&&K[4]===0&&K[5]===65535){let _=K[6],z=K[7];return`${_>>8}.${_&255}.${z>>8}.${z&255}`}return null}function WgK(q,K,_){let z="all"in K&&K.all===!0,Y=XgK(q);if(Y!==0){if(JgK(q)){_(MgK(q,q),"");return}let $=Y===6?6:4;if(z)_(null,[{address:q,family:$}]);else _(null,q,$);return}xhY(q,{all:!0},($,A)=>{if($){_($,"");return}for(let{address:j}of A)if(JgK(j)){_(MgK(q,j),"");return}let O=A[0];if(!O){_(Object.assign(Error(`ENOTFOUND ${q}`),{code:"ENOTFOUND",hostname:q}),"");return}let w=O.family===6?6:4;if(z)_(null,A.map((j)=>({address:j.address,family:j.family===6?6:4})));else _(null,O.address,w)})}function MgK(q,K){let _=Error(`HTTP hook blocked: ${q} resolves to ${K} (private/link-local address). Loopback (127.0.0.1, ::1) is allowed for local dev.`);return Object.assign(_,{code:"ERR_HTTP_HOOK_BLOCKED_ADDRESS",hostname:q,address:K})}var DgK=()=>{};async function BhY(){let{SandboxManager:q}=await Promise.resolve().then(() => (K$(),g54));if(!q.isSandboxingEnabled())return;await q.waitForNetworkInitialization();let K=q.getProxyPort();if(!K)return;return{host:"127.0.0.1",port:K,protocol:"http"}}function ghY(){let q=N7();return{allowedUrls:q.allowedHttpHookUrls,allowedEnvVars:q.httpHookAllowedEnvVars}}function FhY(q,K){let z=K.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${z}$`).test(q)}function UhY(q){return q.replace(/[\r\n\x00]/g,"")}function QhY(q,K){let _=q.replace(/\$\{([A-Z_][A-Z0-9_]*)\}|\$([A-Z_][A-Z0-9_]*)/g,(z,Y,$)=>{let A=Y??$;if(!K.has(A))return N(`Hooks: env var $${A} not in allowedEnvVars, skipping interpolation`,{level:"warn"}),"";return process.env[A]??""});return UhY(_)}async function $_7(q,K,_,z){let Y=ghY();if(Y.allowedUrls!==void 0){if(!Y.allowedUrls.some((j)=>FhY(q.url,j))){let j=`HTTP hook blocked: ${q.url} does not match any pattern in allowedHttpHookUrls`;return N(j,{level:"warn"}),{ok:!1,body:"",error:j}}}let $=q.timeout?q.timeout*1000:phY,{signal:A,cleanup:O}=Ty(z,{timeoutMs:$});try{let w={"Content-Type":"application/json"};if(q.headers){let X=q.allowedEnvVars??[],P=Y.allowedEnvVars!==void 0?X.filter((D)=>Y.allowedEnvVars.includes(D)):X,W=new Set(P);for(let[D,f]of Object.entries(q.headers))w[D]=QhY(f,W)}let j=await BhY(),H=!j&&dh()!==void 0&&!b66(q.url);if(j)N(`Hooks: HTTP hook POST to ${q.url} (via sandbox proxy :${j.port})`);else if(H)N(`Hooks: HTTP hook POST to ${q.url} (via env-var proxy)`);else N(`Hooks: HTTP hook POST to ${q.url}`);let J=await $1.post(q.url,_,{headers:w,signal:A,responseType:"text",validateStatus:()=>!0,maxRedirects:0,proxy:j??!1,lookup:j||H?void 0:WgK});O();let M=J.data??"";return N(`Hooks: HTTP hook response status ${J.status}, body length ${M.length}`),{ok:J.status>=200&&J.status<300,statusCode:J.status,body:M}}catch(w){if(O(),A.aborted)return{ok:!1,body:"",aborted:!0};let j=d6(w);return N(`Hooks: HTTP hook error: ${j}`,{level:"error"}),{ok:!1,body:"",error:j}}}var phY=600000;var fgK=y(()=>{CK();nS6();_8();y8();qv();U1();DgK()});var FL8={};T8(FL8,{shouldSkipHookDueToTrust:()=>Qq8,hasWorktreeCreateHook:()=>NJ6,hasInstructionsLoadedHook:()=>Wr6,hasBlockingResult:()=>eT6,getUserPromptSubmitHookBlockingMessage:()=>w_7,getTeammateIdleHookMessage:()=>T87,getTaskCreatedHookMessage:()=>Y67,getTaskCompletedHookMessage:()=>p88,getStopHookMessage:()=>G87,getSessionEndHookTimeoutMs:()=>H78,getPreToolHookBlockingMessage:()=>z87,getMatchingHooks:()=>O_7,executeWorktreeRemoveHook:()=>SQ8,executeWorktreeCreateHook:()=>dq8,executeUserPromptSubmitHooks:()=>j_7,executeTeammateIdleHooks:()=>k87,executeTaskCreatedHooks:()=>$67,executeTaskCompletedHooks:()=>B88,executeSubagentStartHooks:()=>gr1,executeStopHooks:()=>v87,executeStopFailureHooks:()=>kp8,executeStatusLineCommand:()=>H_7,executeSetupHooks:()=>Mo1,executeSessionStartHooks:()=>Jo1,executeSessionEndHooks:()=>J78,executePreToolHooks:()=>Y87,executePreCompactHooks:()=>qh6,executePostToolUseFailureHooks:()=>A87,executePostToolHooks:()=>$87,executePostCompactHooks:()=>Ip8,executePermissionRequestHooks:()=>hH6,executePermissionDeniedHooks:()=>j87,executeNotificationHooks:()=>bU,executeInstructionsLoadedHooks:()=>Dr6,executeFileSuggestionCommand:()=>hq7,executeFileChangedHooks:()=>$o1,executeElicitationResultHooks:()=>jg1,executeElicitationHooks:()=>wg1,executeCwdChangedHooks:()=>Yo1,executeConfigChangeHooks:()=>qv6,createBaseHookInput:()=>C$});import{basename as dhY}from"path";import{spawn as ZgK}from"child_process";import{randomUUID as vy}from"crypto";function H78(){let q=process.env.CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS,K=q?parseInt(q,10):NaN;return Number.isFinite(K)&&K>0?K:chY}function GgK({processId:q,hookId:K,shellCommand:_,asyncResponse:z,hookEvent:Y,hookName:$,command:A,asyncRewake:O,pluginId:w}){if(O)return _.result.then(async(j)=>{await new Promise((M)=>setImmediate(M));let H=await _.taskOutput.getStdout(),J=_.taskOutput.getStderr();if(_.cleanup(),i0({hookId:K,hookName:$,hookEvent:Y,output:H+J,stdout:H,stderr:J,exitCode:j.code,outcome:j.code===0?"success":"error"}),j.code===2)IO({value:KT(`Stop hook blocking error from command "${$}": ${J||H}`),mode:"task-notification"})}),!0;if(!_.background(q))return!1;return AfK({processId:q,hookId:K,asyncResponse:z,hookEvent:Y,hookName:$,command:A,shellCommand:_,pluginId:w}),!0}function Qq8(){if(!!i7())return!1;return!l$()}function C$(q,K,_){let z=K??N8(),Y=_?.agentType??qB();return{session_id:z,transcript_path:JT(z),cwd:Z8(),permission_mode:q,agent_id:_?.agentId,agent_type:Y}}function vgK(q){let K=r8(q),_=lS6().safeParse(K);if(_.success)return N("Successfully parsed and validated hook JSON output"),{json:_.data};return{validationError:`Hook JSON output validation failed: |