@lark-tns/openclaw-guardian-plugin 2026.4.16 → 2026.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import{createRequire as e}from"node:module";import{definePluginEntry as t}from"openclaw/plugin-sdk/plugin-entry";import{basename as n,dirname as r,join as i,relative as a,resolve as o}from"node:path";import{homedir as s,hostname as c}from"node:os";import{lstat as l,mkdir as u,readFile as d,readdir as f,rename as p,stat as m,unlink as h,writeFile as g}from"node:fs/promises";import{createHash as _}from"node:crypto";import{existsSync as v}from"node:fs";var y=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),b=e(import.meta.url);const x=2e4;function S(e){return`[openclaw-guardian-plugin] ${e}`}function C(){let e=new WeakSet;return(t,n)=>{if(n instanceof Error)return{name:n.name,message:n.message,stack:n.stack};if(typeof n==`bigint`)return n.toString();if(typeof n==`object`&&n){if(e.has(n))return`[Circular]`;e.add(n)}return n}}function w(e){let t=JSON.stringify(e,C(),2)??`null`;return t.length<=x?t:`${t.slice(0,x)}\n...<truncated>`}function T(e,t){return t===`online`?`[payload omitted in online]`:w(e)}function E(e,t,n,r){e.logger.info(S(`[${t}] ${T(n,r)}`))}function ee(e){return typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`?String(e):JSON.stringify(e,C(),2)??`null`}function D(e){let t=e?.pluginConfig?.env;return t===`boe`||t===`dev`||t===`pre`?t:`online`}let O=null,k=null;function A(e,t){if(typeof e!=`string`||!e)throw Error(`missing or invalid ${t}`);return e}function j(...e){for(let t of e)if(typeof t==`string`&&t)return t;return null}function M(e){return!e||typeof e!=`object`||Array.isArray(e)?null:e}function N(e){let t=j(e?.pluginConfig?.appId),n=j(e?.pluginConfig?.appSecret),r=t&&n?{appId:t,appSecret:n}:null,i=M(M(M(e?.config)?.channels)?.feishu),a=j(i?.appId,i?.app_id),o=j(i?.appSecret,i?.app_secret),s=a&&o?{appId:a,appSecret:o}:null,c=D(e);return c===`online`||c===`pre`?s??r??null:r??s??null}function P(e){return!!N(e)}function F(e){let t=e?.pluginConfig?.x_tt_env;return typeof t==`string`&&t?t:D(e)===`boe`?`boe_tns_api`:null}function te(e){let t=D(e);return t===`online`?`https://open.feishu.cn`:t===`pre`?`https://open.feishu-pre.cn`:`https://open.feishu-boe.cn`}function ne(e){if(!e||typeof e!=`object`||Array.isArray(e))return null;let t=e;return{code:typeof t.code==`number`?t.code:NaN,msg:typeof t.msg==`string`?t.msg:``,tenant_access_token:typeof t.tenant_access_token==`string`?t.tenant_access_token:void 0,expire:typeof t.expire==`number`?t.expire:void 0}}async function I(e){let t=Date.now();return O&&O.expiresAtMs-t>18e5?O.token:k||(k=(async()=>{let t=N(e);if(!t)throw Error(`missing Feishu appId/appSecret from api.config.channels.feishu or pluginConfig`);let n=A(t.appId,`appId`),r=A(t.appSecret,`appSecret`),i=`${te(e)}/open-apis/auth/v3/tenant_access_token/internal`,a={"content-type":`application/json`},o=F(e);o&&(a[`x-tt-env`]=o),e.logger.debug?.(S(`[auth] requesting tenant_access_token`));let{signal:s,clear:c}=ie(U),l;try{l=await fetch(i,{method:`POST`,headers:a,body:JSON.stringify({app_id:n,app_secret:r}),signal:s})}catch(e){throw c(),e instanceof Error&&e.name===`AbortError`?new z(i,U):new B(i,e)}finally{c()}let u=await l.text();if(!l.ok)throw Error(`[auth] tenant_access_token request failed status=${l.status} body=${u||`<empty>`}`);let d=null;try{d=u?JSON.parse(u):null}catch{d=null}let f=ne(d);if(!f||!Number.isFinite(f.code))throw Error(`[auth] tenant_access_token response parse failed`);if(f.code!==0)throw Error(`[auth] tenant_access_token request failed code=${f.code}${f.msg?` msg=${f.msg}`:``}`);let p=A(f.tenant_access_token,`tenant_access_token`),m=typeof f.expire==`number`&&f.expire>0?f.expire:7200;return O={token:p,expiresAtMs:Date.now()+m*1e3},e.logger.debug?.(S(`[auth] tenant_access_token updated`)),p})().finally(()=>{k=null}),k)}async function L(e){if(D(e)===`dev`)return{};let t={},n=F(e);return n&&(t[`x-tt-env`]=n),t.authorization=`Bearer ${await I(e)}`,t}async function R(e,t={}){let n=await L(e),r=new Headers(t.headers??{});for(let[e,t]of Object.entries(n))r.set(e,t);return{...t,headers:r}}var z=class extends Error{code=`TIMEOUT`;constructor(e,t){super(`Request to ${e} timed out after ${t}ms`),this.name=`RequestTimeoutError`}},B=class extends Error{code=`NETWORK`;constructor(e,t){super(`Network error requesting ${e}: ${t instanceof Error?t.message:String(t)}`),this.name=`NetworkError`}},re=class extends Error{code=`SERVER`;statusCode;constructor(e,t,n){super(`Server error ${t} from ${e}${n?`: ${n}`:``}`),this.name=`ServerError`,this.statusCode=t}};function V(e){return e instanceof z?`TIMEOUT`:e instanceof B?`NETWORK`:e instanceof re?`SERVER`:e instanceof Error&&e.name===`AbortError`?`TIMEOUT`:`UNKNOWN`}const H=3e4,U=3e4;function ie(e){let t=new AbortController,n=setTimeout(()=>t.abort(),e);return typeof n==`object`&&`unref`in n&&n.unref(),{signal:t.signal,clear:()=>clearTimeout(n)}}function ae(e,t){if(!e)return t;let n=new AbortController,r=()=>n.abort();return e.addEventListener(`abort`,r,{once:!0}),t.addEventListener(`abort`,r,{once:!0}),n.signal}const oe={dev:`http://localhost:8001`,online:`https://open.feishu.cn`,boe:`https://open.feishu-boe.cn`,pre:`https://open.feishu-pre.cn`};function W(e){return`${oe[D(e)]}/open-apis/security_plugin/v1/openclaw_plugin`}function se(e){return`${W(e)}/config`}function ce(e){return`${W(e)}/detect`}function le(e){return`${W(e)}/batch_check_skill_detection`}function ue(e){return`${W(e)}/skill_detect`}function de(e={}){let t={};for(let[n,r]of Object.entries(e??{}))t[n]=ee(r);return t}function fe(e,t,n=``){return{hook_name:e,payload:de(t),source:n}}function pe(e){if(!e)return null;try{let t=JSON.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:null}catch{return null}}function me(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.code==`number`&&Number.isFinite(t.code)&&typeof t.msg==`string`}async function he(e,t,n){let r=await n.text();if(e.logger.debug?.(S(`[${t}] response: ${r}`)),!n.ok)throw Error(`${t} request failed: status=${n.status} body=${r||`<empty>`}`);let i=pe(r);if(!me(i))throw Error(`${t} response parse failed: missing or invalid code/msg fields`);if(i.code!==0)throw Error(`${t} request failed: code=${i.code}${i.msg?` msg=${i.msg}`:``}`);return i.data??null}async function G(e,t,n,r,i=H){let a=await R(e,r),{signal:o,clear:s}=ie(i),c=ae(a.signal,o),l,u=Date.now();try{l=await fetch(n,{...a,signal:c});let r=Date.now()-u;e.logger.info(S(`[${t}] http_elapsed=${r}ms status=${l.status} url=${n}`))}catch(r){let a=Date.now()-u;throw e.logger.info(S(`[${t}] http_elapsed=${a}ms error=${r instanceof Error?r.message:String(r)} url=${n}`)),s(),r instanceof Error&&r.name===`AbortError`?new z(n,i):new B(n,r)}finally{s()}return he(e,t,l)}let ge=null;function _e(){return ge||=c(),ge}function ve(){return{hostname:_e()}}function ye(e){if(!e||typeof e!=`object`||Array.isArray(e))return e;let t=e;return Object.prototype.hasOwnProperty.call(t,`hostname`)?e:{...t,...ve()}}async function K(e,t,n){let r=fe(t,ye(n),`miaoda`);return G(e,t,ce(e),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(r)},H)}function q(...e){return e.find(e=>e!=null)}function J(e){return e==null?``:typeof e==`string`?e:String(e)}function be(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:{}}function xe(e){return Array.isArray(e)?e:[]}function Se(e){try{let t=new URL(e);return{domain:t.host,path:t.pathname||`/`}}catch{return{domain:``,path:``}}}function Ce(e){let{domain:t,path:n}=Se(J(e?.url));return{request_id:J(e?.request_id),domain:t,path:n,origin_req:q(e?.jsonBody,e?.rawBody,``)}}function we(e){let{domain:t,path:n}=Se(J(e?.url));return{request_id:J(e?.request_id),domain:t,path:n,is_sse:e?.isSse?`true`:`false`,chunks:xe(e?.chunks),origin_resp:e?.isSse?``:J(q(e?.originResp,``))}}function Te(e,t){return{agent_name:J(t?.agentId),session_id:J(t?.sessionId),session_key:J(t?.sessionKey),channel_id:J(t?.channelId),message_provider:J(t?.messageProvider),trigger:J(t?.trigger),model:J(e?.model),provider:J(e?.provider),run_id:J(e?.runId)}}function Ee(e,t){return{...Te(e,t),prompt:J(e?.prompt),system_prompt:J(e?.systemPrompt),history_messages:xe(e?.historyMessages)}}function De(e,t){return{...Te(e,t),assistant_texts:xe(e?.assistantTexts),last_assistant:J(JSON.stringify(e?.lastAssistant))}}function Oe(e,t){return{agent_name:J(t?.agentId),session_id:J(t?.sessionId),session_key:J(t?.sessionKey),tool_call_id:J(e?.toolCallId),tool_name:J(e?.toolName),tool_args:q(e?.params,{}),run_id:J(e?.runId)}}function ke(e,t){return Oe(e,t)}function Ae(e,t){return{...Oe(e,t),tool_output:q(e?.result,``),tool_error:q(e?.error,``),tool_duration_ms:J(q(e?.durationMs,``))}}function Y(e,t,n,r){let i=t,a=t,o=n;switch(e){case`before_tool_call`:return ke(i,o);case`after_tool_call`:return Ae(i,o);case`before_llm_fetch`:return Ce(r);case`after_llm_fetch`:return we(r);case`llm_input`:return Ee(a,o);case`llm_output`:return De(a,o);default:return be(r)}}function je(e){return i(e??i(s(),`.openclaw`,`workspace`),`.openclaw-guardian`,`skill-detect-state.json`)}const Me=je();function Ne(e){if(!e||typeof e!=`object`||!(`code`in e))return;let{code:t}=e;return typeof t==`string`?t:void 0}function Pe(e,t){return e.is_detected?typeof e.last_detect_ts==`number`?(t??Date.now())-e.last_detect_ts>864e5:!0:!1}function Fe(e){return!e.dir_hash||!e.zip_hash}let Ie=Promise.resolve();function Le(e){let t=Ie.then(e,e);return Ie=t.catch(()=>void 0),t}async function X(e){try{await h(e)}catch{}}async function Re(e,t){return Le(async()=>{let n=t??Me;e.logger.info(S(`[skill-storage] loading state from: ${n}`));try{let t=await d(n,`utf-8`),r=JSON.parse(t);return!r||typeof r!=`object`||Array.isArray(r)?(e.logger.warn(S(`[skill-storage] corrupted state file (invalid format), deleting and starting fresh`)),await X(n),{}):(e.logger.info(S(`[skill-storage] loaded ${Object.keys(r).length} skill(s) from state`)),r)}catch(t){return Ne(t)===`ENOENT`?(e.logger.info(S(`[skill-storage] no existing state file, starting fresh`)),{}):t instanceof SyntaxError?(e.logger.warn(S(`[skill-storage] corrupted state file (invalid JSON), deleting and starting fresh`)),await X(n),{}):(e.logger.warn(S(`[skill-storage] failed to load state: ${t instanceof Error?t.message:String(t)}`)),{})}})}async function ze(e,t,n){return Le(async()=>{let i=n??Me,a=`${i}.tmp`;e.logger.info(S(`[skill-storage] saving state (${Object.keys(t).length} skill(s)) to: ${i}`));try{await u(r(i),{recursive:!0}),await g(a,JSON.stringify(t,null,2),`utf-8`),await p(a,i),e.logger.info(S(`[skill-storage] state saved successfully`))}catch(t){e.logger.error(S(`[skill-storage] failed to save state: ${t instanceof Error?t.message:String(t)}`)),await X(a)}})}function Be(e,t,n){let r={...e},i=n??Date.now();for(let e of t){let t=r[e.dirName];t&&t.dir_hash===e.dirHash&&!Fe(t)?Pe(t,i)?r[e.dirName]={...t,skill_name:e.skillName,is_detected:!1}:r[e.dirName]={...t,skill_name:e.skillName}:r[e.dirName]={skill_name:e.skillName,dir_hash:e.dirHash,zip_hash:``,is_detected:!1,last_detect_ts:null}}let a=new Set(t.map(e=>e.dirName));for(let e of Object.keys(r))a.has(e)||delete r[e];return r}function Ve(e){if(e.tool_name!==`read`)return null;let t=e.tool_args;return!t||typeof t!=`object`||Array.isArray(t)?null:Object.values(t).find(e=>typeof e==`string`&&e.endsWith(`SKILL.md`))??null}async function He(e,t,i){let a=n(r(t));try{let t;i&&(t=je(e.runtime.agent.resolveAgentWorkspaceDir(e.config,i)));let n=(await Re(e,t))[a];return!n||!n.zip_hash?null:{skill_name:n.skill_name,skill_hash:n.zip_hash}}catch{return null}}function Ue(...e){return e.find(e=>typeof e==`string`)??``}function We(e){return typeof e==`string`?e.toUpperCase():`PERMIT`}function Ge(e){if(!(typeof e!=`string`||e.length===0))try{let t=JSON.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}catch{return}}function Ke(e){return{effect:We(e?.effect),denyOutput:Ue(e?.deny_output),rewriteOutput:Ue(e?.rewrite_output)}}function qe(e){let t=We(e.effect);if(t===`DENY`)return e.denyOutput?{action:`deny`,output:e.denyOutput,returnValue:{block:!0,blockReason:e.denyOutput||`Tool call blocked by detect service`}}:{action:`permit`,returnValue:void 0};if(t===`REWRITE`){if(!e.rewriteOutput)return{action:`permit`,returnValue:void 0};let t=Ge(e.rewriteOutput);return t?{action:`rewrite`,returnValue:{params:t}}:{action:`rewrite_invalid`,returnValue:void 0}}return{action:`permit`,returnValue:void 0}}async function Je(e,t,n,r,i){if(!await t.isHookEnabled(n)){e.logger.info(S(`[${n}] detect skipped: hook disabled by runtime config`));return}let a=Date.now(),o=Y(n,r,i);E(e,n,o,D(e));try{let t=Ke(await K(e,n,o));e.logger.info(S(`[${n}] detect effect observed: effect=${t.effect} (report-only hook)`))}catch(t){e.logger.error(S(`[${n}] detect request failed: ${t instanceof Error?t.message:String(t)}`))}finally{let t=Date.now()-a;e.logger.info(S(`[${n}] total_elapsed=${t}ms`))}}async function Ye(e,t,n,r){let i=Date.now();if(!await t.isHookEnabled(`before_tool_call`)){e.logger.info(S(`[before_tool_call] detect skipped: hook disabled by runtime config`));return}let a=Y(`before_tool_call`,n,r),o=Ve(a),s=a;if(o){let t=await He(e,o,r.agentId);t&&(s={...s,...t},e.logger.info(S(`[before_tool_call] skill read detected: skill=${t.skill_name} hash=${t.skill_hash.slice(0,12)}...`)))}E(e,`before_tool_call`,s,D(e));let c;try{let t=qe(Ke(await K(e,`before_tool_call`,s)));e.logger.info(S(`[before_tool_call] detect effect applied: ${JSON.stringify(t.returnValue)}`)),c=t.returnValue}catch(t){e.logger.error(S(`[before_tool_call] detect request failed: ${t instanceof Error?t.message:String(t)}`))}let l=Date.now()-i;return e.logger.info(S(`[before_tool_call] total_elapsed=${l}ms`)),c}function Xe(e,t){e.on(`llm_input`,async(n,r)=>{await Je(e,t,`llm_input`,n,r)}),e.on(`llm_output`,async(n,r)=>{await Je(e,t,`llm_output`,n,r)}),e.on(`after_tool_call`,async(n,r)=>{await Je(e,t,`after_tool_call`,n,r)}),e.on(`before_tool_call`,async(n,r)=>Ye(e,t,n,r))}function Z(e){return typeof e==`object`&&!!e}function Ze(e,t){if(!Z(e))return null;let n=e[t];return Z(n)?n:null}function Qe(e){let t=Ze(Ze(e,`models`),`providers`);return t?Object.entries(t).map(([e,t])=>{if(!Z(t))return null;let n=t.baseUrl??t.baseURL;return typeof n==`string`&&n?{providerId:e,baseUrl:n}:null}).filter(e=>e!==null):[]}function $e(e,t){for(let n of t)if(e.startsWith(n.baseUrl))return n;return null}function et(e){return typeof e==`string`?e:e instanceof URLSearchParams?e.toString():e instanceof Uint8Array?new TextDecoder().decode(e):ArrayBuffer.isView(e)?new TextDecoder().decode(new Uint8Array(e.buffer,e.byteOffset,e.byteLength)):e instanceof ArrayBuffer?new TextDecoder().decode(new Uint8Array(e)):null}function tt(e){let t=et(e);if(!t)return null;try{let e=JSON.parse(t);return Z(e)?e:null}catch{return null}}function nt(e){return Z(e)?Array.isArray(e.messages)||typeof e.prompt==`string`||typeof e.input==`string`:!1}function rt(e){return typeof e==`string`&&e.includes(`/open-apis/security_plugin/v1/openclaw_plugin`)}function it(e){return typeof e==`string`&&e.includes(`text/event-stream`)}function at(e,t){let n=e.split(/\r?\n/).filter(e=>e.startsWith(`data:`)).map(e=>e.slice(5).trim()).filter(e=>e.length>0&&e!==`[DONE]`),r=Math.max(1,Number(t)||1);if(r===1)return n;let i=[];for(let e=0;e<n.length;e+=r)i.push(n.slice(e,e+r).join(`
2
- `));return i}function ot(e,t){return t?`${String(e).split(/\r?\n/).map(e=>`data: ${e}`).join(`
3
- `)}\n\n`:e}function st(e,t,n){let r=new Headers(e.headers);return r.delete(`content-length`),n?r.set(`content-type`,`text/event-stream; charset=utf-8`):r.get(`content-type`)||r.set(`content-type`,`text/plain; charset=utf-8`),new Response(ot(t,n),{status:e.status,statusText:e.statusText,headers:r})}async function ct(e,t,n){let r=await t.clone().text(),i=it(t.headers.get(`content-type`)??``);return{url:e,isSse:i,chunks:i?at(r,n):[],originResp:i?``:r}}function lt(...e){return e.find(e=>typeof e==`string`)??``}function ut(e){return typeof e==`string`?e.toUpperCase():`PERMIT`}function dt(e){return{effect:ut(e?.effect),denyOutput:lt(e?.deny_output),rewriteOutput:lt(e?.rewrite_output)}}function ft(e){let t=ut(e.effect);return t===`DENY`&&e.denyOutput?{action:`deny`,output:e.denyOutput,effect:t}:t===`REWRITE`&&e.rewriteOutput?{action:`rewrite`,output:e.rewriteOutput,effect:t}:{action:`permit`,output:``,effect:t}}function pt(e){let t=ut(e.effect);return t===`DENY`&&e.denyOutput?{action:`deny`,output:e.denyOutput,effect:t}:t===`REWRITE`&&e.rewriteOutput?{action:`rewrite`,output:e.rewriteOutput,effect:t}:{action:`permit`,output:``,effect:t}}function mt(e,t,n){e.logger.info(S(`[${t}] ${T(n,D(e))}`))}function ht(){let e=globalThis.crypto;return e?.randomUUID?e.randomUUID():`${Date.now()}-${Math.random().toString(16).slice(2)}`}function gt(e){let t=String(e);function n(e){if(typeof e!=`string`)return JSON.stringify(e);try{let t=JSON.parse(e);return typeof t==`string`?t:JSON.stringify(t)}catch{return e}}try{let e=JSON.parse(t);if(Array.isArray(e))return e.map(e=>n(e))}catch{}return t.split(/\r?\n/)}function _t(e,t){let n=new Headers(e.headers);n.delete(`content-length`),n.set(`content-type`,`text/event-stream; charset=utf-8`);let r=`${gt(t).map(e=>`data: ${e}\n\n`).join(``)}`;return new Response(r,{status:e.status,statusText:e.statusText,headers:n})}function vt(e){return(e.headers.get(`content-type`)??``).includes(`text/event-stream`)}async function yt(e,t,n,r,i,a){let o=r.body;if(!o)return r;let s=Math.max(1,Number(await i.getSseChunkSize())||1),c=o.getReader(),l=new TextDecoder,u=new TextEncoder,d=``,f=[],p=[];async function m(r){let i=Y(`after_llm_fetch`,null,null,{request_id:n,url:t,isSse:!0,chunks:r,originResp:``});return mt(e,`after_llm_fetch`,i),pt(dt(await K(e,`after_llm_fetch`,i)))}function h(e){f.length!==0&&(e.enqueue(u.encode(f.join(``))),f=[])}let g=new ReadableStream({async start(t){try{for(;;){let{value:i,done:o}=await c.read();if(o)break;for(d+=l.decode(i,{stream:!0});;){let i=d.indexOf(`
1
+ import{createRequire as e}from"node:module";import{definePluginEntry as t}from"openclaw/plugin-sdk/plugin-entry";import{basename as n,dirname as r,join as i,relative as a,resolve as o}from"node:path";import{homedir as s,hostname as c}from"node:os";import{lstat as l,mkdir as u,readFile as d,readdir as f,rename as p,stat as m,unlink as h,writeFile as g}from"node:fs/promises";import{createHash as _}from"node:crypto";import{existsSync as v}from"node:fs";var y=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),b=e(import.meta.url);const ee=2e4;function x(e){return`[openclaw-guardian-plugin] ${e}`}function S(){let e=new WeakSet;return(t,n)=>{if(n instanceof Error)return{name:n.name,message:n.message,stack:n.stack};if(typeof n==`bigint`)return n.toString();if(typeof n==`object`&&n){if(e.has(n))return`[Circular]`;e.add(n)}return n}}function C(e){let t=JSON.stringify(e,S(),2)??`null`;return t.length<=ee?t:`${t.slice(0,ee)}\n...<truncated>`}function w(e,t){return t===`online`?`[payload omitted in online]`:C(e)}function T(e,t,n,r){e.logger.info(x(`[${t}] ${w(n,r)}`))}function te(e){return typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`?String(e):JSON.stringify(e,S(),2)??`null`}function E(e){let t=e?.pluginConfig?.env;return t===`boe`||t===`dev`||t===`pre`?t:`online`}let D=null,O=null;function k(e,t){if(typeof e!=`string`||!e)throw Error(`missing or invalid ${t}`);return e}function A(...e){for(let t of e)if(typeof t==`string`&&t)return t;return null}function j(e){return!e||typeof e!=`object`||Array.isArray(e)?null:e}function M(e){let t=A(e?.pluginConfig?.appId),n=A(e?.pluginConfig?.appSecret),r=t&&n?{appId:t,appSecret:n}:null,i=j(j(j(e?.config)?.channels)?.feishu),a=A(i?.appId,i?.app_id),o=A(i?.appSecret,i?.app_secret),s=a&&o?{appId:a,appSecret:o}:null,c=E(e);return c===`online`||c===`pre`?s??r??null:r??s??null}function N(e){return!!M(e)}function P(e){let t=e?.pluginConfig?.x_tt_env;return typeof t==`string`&&t?t:E(e)===`boe`?`boe_tns_api`:null}function F(e){let t=E(e);return t===`online`?`https://open.feishu.cn`:t===`pre`?`https://open.feishu-pre.cn`:`https://open.feishu-boe.cn`}function ne(e){if(!e||typeof e!=`object`||Array.isArray(e))return null;let t=e;return{code:typeof t.code==`number`?t.code:NaN,msg:typeof t.msg==`string`?t.msg:``,tenant_access_token:typeof t.tenant_access_token==`string`?t.tenant_access_token:void 0,expire:typeof t.expire==`number`?t.expire:void 0}}async function I(e){let t=Date.now();return D&&D.expiresAtMs-t>18e5?D.token:O||(O=(async()=>{let t=M(e);if(!t)throw Error(`missing Feishu appId/appSecret from api.config.channels.feishu or pluginConfig`);let n=k(t.appId,`appId`),r=k(t.appSecret,`appSecret`),i=`${F(e)}/open-apis/auth/v3/tenant_access_token/internal`,a={"content-type":`application/json`},o=P(e);o&&(a[`x-tt-env`]=o),e.logger.debug?.(x(`[auth] requesting tenant_access_token`));let{signal:s,clear:c}=ie(U),l;try{l=await fetch(i,{method:`POST`,headers:a,body:JSON.stringify({app_id:n,app_secret:r}),signal:s})}catch(e){throw c(),e instanceof Error&&e.name===`AbortError`?new z(i,U):new B(i,e)}finally{c()}let u=await l.text();if(!l.ok)throw Error(`[auth] tenant_access_token request failed status=${l.status} body=${u||`<empty>`}`);let d=null;try{d=u?JSON.parse(u):null}catch{d=null}let f=ne(d);if(!f||!Number.isFinite(f.code))throw Error(`[auth] tenant_access_token response parse failed`);if(f.code!==0)throw Error(`[auth] tenant_access_token request failed code=${f.code}${f.msg?` msg=${f.msg}`:``}`);let p=k(f.tenant_access_token,`tenant_access_token`),m=typeof f.expire==`number`&&f.expire>0?f.expire:7200;return D={token:p,expiresAtMs:Date.now()+m*1e3},e.logger.debug?.(x(`[auth] tenant_access_token updated`)),p})().finally(()=>{O=null}),O)}async function L(e){if(E(e)===`dev`)return{};let t={},n=P(e);return n&&(t[`x-tt-env`]=n),t.authorization=`Bearer ${await I(e)}`,t}async function R(e,t={}){let n=await L(e),r=new Headers(t.headers??{});for(let[e,t]of Object.entries(n))r.set(e,t);return{...t,headers:r}}var z=class extends Error{code=`TIMEOUT`;constructor(e,t){super(`Request to ${e} timed out after ${t}ms`),this.name=`RequestTimeoutError`}},B=class extends Error{code=`NETWORK`;constructor(e,t){super(`Network error requesting ${e}: ${t instanceof Error?t.message:String(t)}`),this.name=`NetworkError`}},re=class extends Error{code=`SERVER`;statusCode;constructor(e,t,n){super(`Server error ${t} from ${e}${n?`: ${n}`:``}`),this.name=`ServerError`,this.statusCode=t}};function V(e){return e instanceof z?`TIMEOUT`:e instanceof B?`NETWORK`:e instanceof re?`SERVER`:e instanceof Error&&e.name===`AbortError`?`TIMEOUT`:`UNKNOWN`}const H=5e3,U=5e3;function ie(e){let t=new AbortController,n=setTimeout(()=>t.abort(),e);return typeof n==`object`&&`unref`in n&&n.unref(),{signal:t.signal,clear:()=>clearTimeout(n)}}function ae(e,t){if(!e)return t;let n=new AbortController,r=()=>n.abort();return e.addEventListener(`abort`,r,{once:!0}),t.addEventListener(`abort`,r,{once:!0}),n.signal}const oe={dev:`http://localhost:8001`,online:`https://open.feishu.cn`,boe:`https://open.feishu-boe.cn`,pre:`https://open.feishu-pre.cn`};function W(e){return`${oe[E(e)]}/open-apis/security_plugin/v1/openclaw_plugin`}function se(e){return`${W(e)}/config`}function ce(e){return`${W(e)}/detect`}function le(e){return`${W(e)}/batch_check_skill_detection`}function ue(e){return`${W(e)}/skill_detect`}function de(e={}){let t={};for(let[n,r]of Object.entries(e??{}))t[n]=te(r);return t}function fe(e,t,n=``){return{hook_name:e,payload:de(t),source:n}}function pe(e){if(!e)return null;try{let t=JSON.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:null}catch{return null}}function me(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.code==`number`&&Number.isFinite(t.code)&&typeof t.msg==`string`}async function he(e,t,n){let r=await n.text();if(e.logger.debug?.(x(`[${t}] response: ${r}`)),!n.ok)throw Error(`${t} request failed: status=${n.status} body=${r||`<empty>`}`);let i=pe(r);if(!me(i))throw Error(`${t} response parse failed: missing or invalid code/msg fields`);if(i.code!==0)throw Error(`${t} request failed: code=${i.code}${i.msg?` msg=${i.msg}`:``}`);return i.data??null}async function G(e,t,n,r,i=H){let a=await R(e,r),{signal:o,clear:s}=ie(i),c=ae(a.signal,o),l,u=Date.now();try{l=await fetch(n,{...a,signal:c});let r=Date.now()-u;e.logger.info(x(`[${t}] http_elapsed=${r}ms status=${l.status} url=${n}`))}catch(r){let a=Date.now()-u;throw e.logger.info(x(`[${t}] http_elapsed=${a}ms error=${r instanceof Error?r.message:String(r)} url=${n}`)),s(),r instanceof Error&&r.name===`AbortError`?new z(n,i):new B(n,r)}finally{s()}return he(e,t,l)}let ge=null;function _e(){return ge||=c(),ge}function ve(){return{hostname:_e()}}function ye(e){if(!e||typeof e!=`object`||Array.isArray(e))return e;let t=e;return Object.prototype.hasOwnProperty.call(t,`hostname`)?e:{...t,...ve()}}async function K(e,t,n){let r=fe(t,ye(n),`miaoda`);return G(e,t,ce(e),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(r)},H)}function q(...e){return e.find(e=>e!=null)}function J(e){return e==null?``:typeof e==`string`?e:String(e)}function be(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:{}}function Y(e){return Array.isArray(e)?e:[]}function xe(e){try{let t=new URL(e);return{domain:t.host,path:t.pathname||`/`}}catch{return{domain:``,path:``}}}function Se(e){let{domain:t,path:n}=xe(J(e?.url));return{request_id:J(e?.request_id),domain:t,path:n,origin_req:q(e?.jsonBody,e?.rawBody,``)}}function Ce(e){let{domain:t,path:n}=xe(J(e?.url));return{request_id:J(e?.request_id),domain:t,path:n,is_sse:e?.isSse?`true`:`false`,chunks:Y(e?.chunks),origin_resp:e?.isSse?``:J(q(e?.originResp,``))}}function we(e,t){return{agent_name:J(t?.agentId),session_id:J(t?.sessionId),session_key:J(t?.sessionKey),channel_id:J(t?.channelId),message_provider:J(t?.messageProvider),trigger:J(t?.trigger),model:J(e?.model),provider:J(e?.provider),run_id:J(e?.runId)}}function Te(e,t){return{...we(e,t),prompt:J(e?.prompt),system_prompt:J(e?.systemPrompt),history_messages:Y(e?.historyMessages)}}function Ee(e,t){return{...we(e,t),assistant_texts:Y(e?.assistantTexts),last_assistant:J(JSON.stringify(e?.lastAssistant))}}function De(e,t){return{agent_name:J(t?.agentId),session_id:J(t?.sessionId),session_key:J(t?.sessionKey),tool_call_id:J(e?.toolCallId),tool_name:J(e?.toolName),tool_args:q(e?.params,{}),run_id:J(e?.runId)}}function Oe(e,t){return De(e,t)}function ke(e,t){return{...De(e,t),tool_output:q(e?.result,``),tool_error:q(e?.error,``),tool_duration_ms:J(q(e?.durationMs,``))}}function X(e,t,n,r){let i=t,a=t,o=n;switch(e){case`before_tool_call`:return Oe(i,o);case`after_tool_call`:return ke(i,o);case`before_llm_fetch`:return Se(r);case`after_llm_fetch`:return Ce(r);case`llm_input`:return Te(a,o);case`llm_output`:return Ee(a,o);default:return be(r)}}function Ae(e){return i(e??i(s(),`.openclaw`,`workspace`),`.openclaw-guardian`,`skill-detect-state.json`)}const je=Ae();function Me(e){if(!e||typeof e!=`object`||!(`code`in e))return;let{code:t}=e;return typeof t==`string`?t:void 0}function Ne(e,t){return e.is_detected?typeof e.last_detect_ts==`number`?(t??Date.now())-e.last_detect_ts>864e5:!0:!1}function Pe(e){return!e.skill_hash}let Fe=Promise.resolve();function Ie(e){let t=Fe.then(e,e);return Fe=t.catch(()=>void 0),t}async function Le(e){try{await h(e)}catch{}}async function Re(e,t){return Ie(async()=>{let n=t??je;e.logger.info(x(`[skill-storage] loading state from: ${n}`));try{let t=await d(n,`utf-8`),r=JSON.parse(t);return!r||typeof r!=`object`||Array.isArray(r)?(e.logger.warn(x(`[skill-storage] corrupted state file (invalid format), deleting and starting fresh`)),await Le(n),{}):(e.logger.info(x(`[skill-storage] loaded ${Object.keys(r).length} skill(s) from state`)),r)}catch(t){return Me(t)===`ENOENT`?(e.logger.info(x(`[skill-storage] no existing state file, starting fresh`)),{}):t instanceof SyntaxError?(e.logger.warn(x(`[skill-storage] corrupted state file (invalid JSON), deleting and starting fresh`)),await Le(n),{}):(e.logger.warn(x(`[skill-storage] failed to load state: ${t instanceof Error?t.message:String(t)}`)),{})}})}async function ze(e,t,n){return Ie(async()=>{let i=n??je,a=`${i}.tmp`;e.logger.info(x(`[skill-storage] saving state (${Object.keys(t).length} skill(s)) to: ${i}`));try{await u(r(i),{recursive:!0}),await g(a,JSON.stringify(t,null,2),`utf-8`),await p(a,i),e.logger.info(x(`[skill-storage] state saved successfully`))}catch(t){e.logger.error(x(`[skill-storage] failed to save state: ${t instanceof Error?t.message:String(t)}`)),await Le(a)}})}function Be(e,t,n){let r={...e},i=n??Date.now();for(let e of t){let t=r[e.dirName];t&&t.skill_hash===e.skillHash?Ne(t,i)?r[e.dirName]={...t,skill_name:e.skillName,is_detected:!1}:r[e.dirName]={...t,skill_name:e.skillName}:r[e.dirName]={skill_name:e.skillName,skill_hash:e.skillHash,is_detected:!1,last_detect_ts:null}}let a=new Set(t.map(e=>e.dirName));for(let e of Object.keys(r))a.has(e)||delete r[e];return r}var Ve=y(((e,t)=>{function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,`default`)?e.default:e}let r=new Int32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);function i(e){if(Buffer.isBuffer(e))return e;if(typeof e==`number`)return Buffer.alloc(e);if(typeof e==`string`)return Buffer.from(e);throw Error(`input must be buffer, number, or string, received `+typeof e)}function a(e){let t=i(4);return t.writeInt32BE(e,0),t}function o(e,t){e=i(e),Buffer.isBuffer(t)&&(t=t.readUInt32BE(0));let n=~~t^-1;for(var a=0;a<e.length;a++)n=r[(n^e[a])&255]^n>>>8;return n^-1}function s(){return a(o.apply(null,arguments))}s.signed=function(){return o.apply(null,arguments)},s.unsigned=function(){return o.apply(null,arguments)>>>0},t.exports=n(s)})),He=y((e=>{var t=b(`fs`),n=b(`stream`).Transform,r=b(`stream`).PassThrough,i=b(`zlib`),a=b(`util`),o=b(`events`).EventEmitter,s=b(`events`).errorMonitor,c=Ve();e.ZipFile=l,a.inherits(l,o);function l(){this.outputStream=new r,this.entries=[],this.outputStreamCursor=0,this.ended=!1,this.allDone=!1,this.forceZip64Eocd=!1,this.errored=!1,this.on(s,function(){this.errored=!0})}l.prototype.addFile=function(e,n,r){var i=this;if(n=x(n,!1),r??={},!g(i)){var a=new C(n,!1,r);i.entries.push(a),t.stat(e,function(n,o){if(n)return i.emit(`error`,n);if(!o.isFile())return i.emit(`error`,Error(`not a file: `+e));a.uncompressedSize=o.size,r.mtime??a.setLastModDate(o.mtime),r.mode??a.setFileAttributesMode(o.mode),a.setFileDataPumpFunction(function(){var n=t.createReadStream(e);a.state=C.FILE_DATA_IN_PROGRESS,n.on(`error`,function(e){i.emit(`error`,e)}),f(i,a,n)}),m(i)})}},l.prototype.addReadStream=function(e,t,n){this.addReadStreamLazy(t,n,function(t){t(null,e)})},l.prototype.addReadStreamLazy=function(e,t,n){var r=this;if(typeof t==`function`&&(n=t,t=null),t??={},e=x(e,!1),!g(r)){var i=new C(e,!1,t);r.entries.push(i),i.setFileDataPumpFunction(function(){i.state=C.FILE_DATA_IN_PROGRESS,n(function(e,t){if(e)return r.emit(`error`,e);f(r,i,t)})}),m(r)}},l.prototype.addBuffer=function(e,t,n){var r=this;if(t=x(t,!1),e.length>1073741823)throw Error(`buffer too large: `+e.length+` > 1073741823`);if(n??={},n.size!=null)throw Error(`options.size not allowed`);if(g(r))return;var a=new C(t,!1,n);a.uncompressedSize=e.length,a.crc32=c.unsigned(e),a.crcAndFileSizeKnown=!0,r.entries.push(a),a.compressionLevel===0?o(e):i.deflateRaw(e,{level:a.compressionLevel},function(e,t){o(t)});function o(e){a.compressedSize=e.length,a.setFileDataPumpFunction(function(){d(r,e),d(r,a.getDataDescriptor()),a.state=C.FILE_DATA_DONE,setImmediate(function(){m(r)})}),m(r)}},l.prototype.addEmptyDirectory=function(e,t){var n=this;if(e=x(e,!0),t??={},t.size!=null)throw Error(`options.size not allowed`);if(t.compress!=null)throw Error(`options.compress not allowed`);if(t.compressionLevel!=null)throw Error(`options.compressionLevel not allowed`);if(!g(n)){var r=new C(e,!0,t);n.entries.push(r),r.setFileDataPumpFunction(function(){d(n,r.getDataDescriptor()),r.state=C.FILE_DATA_DONE,m(n)}),m(n)}};var u=H([80,75,5,6]);l.prototype.end=function(e,t){if(typeof e==`function`&&(t=e,e=null),e??={},!this.ended&&(this.ended=!0,!this.errored)){if(this.calculatedTotalSizeCallback=t,this.forceZip64Eocd=!!e.forceZip64Format,e.comment){if(typeof e.comment==`string`?this.comment=re(e.comment):this.comment=e.comment,this.comment.length>65535)throw Error(`comment is too large`);if(U(this.comment,u))throw Error(`comment contains end of central directory record signature`)}else this.comment=S;m(this)}};function d(e,t){e.outputStream.write(t),e.outputStreamCursor+=t.length}function f(e,t,n){var a=new R,o=new L,s=t.compressionLevel===0?new r:new i.DeflateRaw({level:t.compressionLevel}),c=new L;n.pipe(a).pipe(o).pipe(s).pipe(c).pipe(e.outputStream,{end:!1}),c.on(`end`,function(){if(t.crc32=a.crc32,t.uncompressedSize==null)t.uncompressedSize=o.byteCount;else if(t.uncompressedSize!==o.byteCount)return e.emit(`error`,Error(`file data stream has unexpected number of bytes`));t.compressedSize=c.byteCount,e.outputStreamCursor+=t.compressedSize,d(e,t.getDataDescriptor()),t.state=C.FILE_DATA_DONE,m(e)})}function p(e){if(e.compress!=null&&e.compressionLevel!=null&&!!e.compress!=!!e.compressionLevel)throw Error(`conflicting settings for compress and compressionLevel`);return e.compressionLevel==null?e.compress===!1?0:6:e.compressionLevel}function m(e){if(e.allDone||e.errored)return;if(e.ended&&e.calculatedTotalSizeCallback!=null){var t=h(e);t!=null&&(e.calculatedTotalSizeCallback(t),e.calculatedTotalSizeCallback=null)}var n=r();function r(){for(var t=0;t<e.entries.length;t++){var n=e.entries[t];if(n.state<C.FILE_DATA_DONE)return n}return null}if(n!=null){if(n.state<C.READY_TO_PUMP_FILE_DATA||n.state===C.FILE_DATA_IN_PROGRESS)return;n.relativeOffsetOfLocalHeader=e.outputStreamCursor,d(e,n.getLocalFileHeader()),n.doFileDataPump()}else e.ended&&(e.offsetOfStartOfCentralDirectory=e.outputStreamCursor,e.entries.forEach(function(t){d(e,t.getCentralDirectoryRecord())}),d(e,ee(e)),e.outputStream.end(),e.allDone=!0)}function h(e){for(var t=0,n=0,r=0;r<e.entries.length;r++){var i=e.entries[r];if(i.compressionLevel!==0)return-1;if(i.state>=C.READY_TO_PUMP_FILE_DATA){if(i.uncompressedSize==null)return-1}else if(i.uncompressedSize==null)return null;i.relativeOffsetOfLocalHeader=t;var a=i.useZip64Format();t+=w+i.utf8FileName.length,t+=i.uncompressedSize,i.crcAndFileSizeKnown||(a?t+=A:t+=k),n+=j+i.utf8FileName.length+i.fileComment.length,i.forceDosTimestamp||(n+=M),a&&(n+=N)}var o=0;return(e.forceZip64Eocd||e.entries.length>=65535||n>=65535||t>=4294967295)&&(o+=_+v),o+=y+e.comment.length,t+n+o}function g(e){if(e.ended)throw Error(`cannot add entries after calling end()`);return!!e.errored}var _=56,v=20,y=22;function ee(e,t){var n=!1,r=e.entries.length;(e.forceZip64Eocd||e.entries.length>=65535)&&(r=65535,n=!0);var i=e.outputStreamCursor-e.offsetOfStartOfCentralDirectory,a=i;(e.forceZip64Eocd||i>=4294967295)&&(a=4294967295,n=!0);var o=e.offsetOfStartOfCentralDirectory;if((e.forceZip64Eocd||e.offsetOfStartOfCentralDirectory>=4294967295)&&(o=4294967295,n=!0),t)return n?_+v+y:y;var s=V(y+e.comment.length);if(s.writeUInt32LE(101010256,0),s.writeUInt16LE(0,4),s.writeUInt16LE(0,6),s.writeUInt16LE(r,8),s.writeUInt16LE(r,10),s.writeUInt32LE(a,12),s.writeUInt32LE(o,16),s.writeUInt16LE(e.comment.length,20),e.comment.copy(s,22),!n)return s;var c=V(_);c.writeUInt32LE(101075792,0),I(c,_-12,4),c.writeUInt16LE(E,12),c.writeUInt16LE(te,14),c.writeUInt32LE(0,16),c.writeUInt32LE(0,20),I(c,e.entries.length,24),I(c,e.entries.length,32),I(c,i,40),I(c,e.offsetOfStartOfCentralDirectory,48);var l=V(v);return l.writeUInt32LE(117853008,0),l.writeUInt32LE(0,4),I(l,e.outputStreamCursor,8),l.writeUInt32LE(1,16),Buffer.concat([c,l,s])}function x(e,t){if(e===``)throw Error(`empty metadataPath`);if(e=e.replace(/\\/g,`/`),/^[a-zA-Z]:/.test(e)||/^\//.test(e))throw Error(`absolute path: `+e);if(e.split(`/`).indexOf(`..`)!==-1)throw Error(`invalid relative path: `+e);var n=/\/$/.test(e);if(t)n||(e+=`/`);else if(n)throw Error(`file path cannot end with '/': `+e);return e}var S=V(0);function C(e,t,n){if(this.utf8FileName=H(e),this.utf8FileName.length>65535)throw Error(`utf8 file name too long. `+utf8FileName.length+` > 65535`);if(this.isDirectory=t,this.state=C.WAITING_FOR_METADATA,this.setLastModDate(n.mtime==null?new Date:n.mtime),this.forceDosTimestamp=!!n.forceDosTimestamp,n.mode==null?this.setFileAttributesMode(t?16893:33204):this.setFileAttributesMode(n.mode),t?(this.crcAndFileSizeKnown=!0,this.crc32=0,this.uncompressedSize=0,this.compressedSize=0):(this.crcAndFileSizeKnown=!1,this.crc32=null,this.uncompressedSize=null,this.compressedSize=null,n.size!=null&&(this.uncompressedSize=n.size)),t?this.compressionLevel=0:this.compressionLevel=p(n),this.forceZip64Format=!!n.forceZip64Format,n.fileComment){if(typeof n.fileComment==`string`?this.fileComment=H(n.fileComment,`utf-8`):this.fileComment=n.fileComment,this.fileComment.length>65535)throw Error(`fileComment is too large`)}else this.fileComment=S}C.WAITING_FOR_METADATA=0,C.READY_TO_PUMP_FILE_DATA=1,C.FILE_DATA_IN_PROGRESS=2,C.FILE_DATA_DONE=3,C.prototype.setLastModDate=function(e){this.mtime=e;var t=ne(e);this.lastModFileTime=t.time,this.lastModFileDate=t.date},C.prototype.setFileAttributesMode=function(e){if((e&65535)!==e)throw Error(`invalid mode. expected: 0 <= `+e+` <= 65535`);this.externalFileAttributes=e<<16>>>0},C.prototype.setFileDataPumpFunction=function(e){this.doFileDataPump=e,this.state=C.READY_TO_PUMP_FILE_DATA},C.prototype.useZip64Format=function(){return this.forceZip64Format||this.uncompressedSize!=null&&this.uncompressedSize>4294967294||this.compressedSize!=null&&this.compressedSize>4294967294||this.relativeOffsetOfLocalHeader!=null&&this.relativeOffsetOfLocalHeader>4294967294};var w=30,T=20,te=45,E=831,D=2048,O=8;C.prototype.getLocalFileHeader=function(){var e=0,t=0,n=0;this.crcAndFileSizeKnown&&(e=this.crc32,t=this.compressedSize,n=this.uncompressedSize);var r=V(w),i=D;return this.crcAndFileSizeKnown||(i|=O),r.writeUInt32LE(67324752,0),r.writeUInt16LE(T,4),r.writeUInt16LE(i,6),r.writeUInt16LE(this.getCompressionMethod(),8),r.writeUInt16LE(this.lastModFileTime,10),r.writeUInt16LE(this.lastModFileDate,12),r.writeUInt32LE(e,14),r.writeUInt32LE(t,18),r.writeUInt32LE(n,22),r.writeUInt16LE(this.utf8FileName.length,26),r.writeUInt16LE(0,28),Buffer.concat([r,this.utf8FileName])};var k=16,A=24;C.prototype.getDataDescriptor=function(){if(this.crcAndFileSizeKnown)return S;if(this.useZip64Format()){var e=V(A);return e.writeUInt32LE(134695760,0),e.writeUInt32LE(this.crc32,4),I(e,this.compressedSize,8),I(e,this.uncompressedSize,16),e}else{var e=V(k);return e.writeUInt32LE(134695760,0),e.writeUInt32LE(this.crc32,4),e.writeUInt32LE(this.compressedSize,8),e.writeUInt32LE(this.uncompressedSize,12),e}};var j=46,M=9,N=28;C.prototype.getCentralDirectoryRecord=function(){var e=V(j),t=D;this.crcAndFileSizeKnown||(t|=O);var n=S;if(!this.forceDosTimestamp){n=V(M),n.writeUInt16LE(21589,0),n.writeUInt16LE(M-4,2),n.writeUInt8(3,4);var r=Math.floor(this.mtime.getTime()/1e3);r<-2147483648&&(r=-2147483648),r>2147483647&&(r=2147483647),n.writeUInt32LE(r,5)}var i=this.compressedSize,a=this.uncompressedSize,o=this.relativeOffsetOfLocalHeader,s=T,c=S;return this.useZip64Format()&&(i=4294967295,a=4294967295,o=4294967295,s=te,c=V(N),c.writeUInt16LE(1,0),c.writeUInt16LE(N-4,2),I(c,this.uncompressedSize,4),I(c,this.compressedSize,12),I(c,this.relativeOffsetOfLocalHeader,20)),e.writeUInt32LE(33639248,0),e.writeUInt16LE(E,4),e.writeUInt16LE(s,6),e.writeUInt16LE(t,8),e.writeUInt16LE(this.getCompressionMethod(),10),e.writeUInt16LE(this.lastModFileTime,12),e.writeUInt16LE(this.lastModFileDate,14),e.writeUInt32LE(this.crc32,16),e.writeUInt32LE(i,20),e.writeUInt32LE(a,24),e.writeUInt16LE(this.utf8FileName.length,28),e.writeUInt16LE(n.length+c.length,30),e.writeUInt16LE(this.fileComment.length,32),e.writeUInt16LE(0,34),e.writeUInt16LE(0,36),e.writeUInt32LE(this.externalFileAttributes,38),e.writeUInt32LE(o,42),Buffer.concat([e,this.utf8FileName,n,c,this.fileComment])},C.prototype.getCompressionMethod=function(){return this.compressionLevel===0?0:8};var P=new Date(1980,0,1),F=new Date(2107,11,31,23,59,58);function ne(e){e<P?e=P:e>F&&(e=F);var t=0;t|=e.getDate()&31,t|=(e.getMonth()+1&15)<<5,t|=(e.getFullYear()-1980&127)<<9;var n=0;return n|=Math.floor(e.getSeconds()/2),n|=(e.getMinutes()&63)<<5,n|=(e.getHours()&31)<<11,{date:t,time:n}}function I(e,t,n){var r=Math.floor(t/4294967296),i=t%4294967296;e.writeUInt32LE(i,n),e.writeUInt32LE(r,n+4)}a.inherits(L,n);function L(e){n.call(this,e),this.byteCount=0}L.prototype._transform=function(e,t,n){this.byteCount+=e.length,n(null,e)},a.inherits(R,n);function R(e){n.call(this,e),this.crc32=0}R.prototype._transform=function(e,t,n){this.crc32=c.unsigned(e,this.crc32),n(null,e)};var z=`\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■\xA0`;if(z.length!==256)throw Error(`assertion failure`);var B=null;function re(e){if(/^[\x20-\x7e]*$/.test(e))return H(e,`utf-8`);if(B==null){B={};for(var t=0;t<z.length;t++)B[z[t]]=t}for(var n=V(e.length),t=0;t<e.length;t++){var r=B[e[t]];if(r==null)throw Error(`character not encodable in CP437: `+JSON.stringify(e[t]));n[t]=r}return n}function V(e){V=t;try{return V(e)}catch{return V=n,V(e)}function t(e){return Buffer.allocUnsafe(e)}function n(e){return new Buffer(e)}}function H(e,t){H=n;try{return H(e,t)}catch{return H=r,H(e,t)}function n(e,t){return Buffer.from(e,t)}function r(e,t){return new Buffer(e,t)}}function U(e,t){U=n;try{return U(e,t)}catch{return U=r,U(e,t)}function n(e,t){return e.includes(t)}function r(e,t){for(var n=0;n<=e.length-t.length;n++)for(var r=0;;r++){if(r===t.length)return!0;if(e[n+r]!==t[r])break}return!1}}}))();function Z(e){return`v1:${e}`}function Ue(e){if(!e||typeof e!=`object`||Array.isArray(e))return{};let t={};for(let[n,r]of Object.entries(e))t[n]=r===!0;return t}function We(e){return{skills:Object.values(e).map(e=>({skill_name:e.skill_name,skill_hash:Z(e.skill_hash)}))}}async function Ge(e,t){let n=le(e),r=We(t),i=await G(e,`batch_check_detection`,n,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(r)},H);return i&&typeof i==`object`&&!Array.isArray(i)&&`result`in i?Ue(i.result):Ue(i)}const Ke=10*1024*1024;async function qe(e){let t=await f(e),n=[];for(let r of t){let t=i(e,r),a=await l(t);a.isSymbolicLink()||(a.isDirectory()?n.push(...await qe(t)):a.isFile()&&n.push(t))}return n}async function Je(e){let t=await m(e).catch(()=>null);if(!t||!t.isDirectory())throw Error(`zipDirectory: path does not exist or is not a directory: ${e}`);let n=await qe(e);return n.sort((t,n)=>{let r=a(e,t),i=a(e,n);return r<i?-1:+(r>i)}),new Promise((t,r)=>{let i=new He.ZipFile,o=[],s=0,c=!1,l=e=>{c||(c=!0,r(e))};i.outputStream.on(`data`,t=>{if(!c){if(s+=t.length,s>Ke){l(Error(`zipDirectory: zip exceeds ${Ke} bytes limit for ${e} (${s} bytes)`));return}o.push(t)}}),i.outputStream.on(`end`,()=>{c||(c=!0,t(Buffer.concat(o)))}),i.outputStream.on(`error`,l);for(let t of n)i.addFile(t,a(e,t));i.end()})}async function Ye(e,t,n){let r=ue(e),i=`skill_detect:${n.skill_name}`;e.logger.info(x(`[skill-detect] detect: sending skill=${n.skill_name} hash=${n.skill_hash.slice(0,12)}... dir=${t}`));let a=await Je(t);e.logger.info(x(`[skill-detect] zipped ${t} (${a.length} bytes)`));let o=new FormData,s=new Blob([new Uint8Array(a)],{type:`application/zip`});return o.append(`file`,s,n.skill_name),o.append(`skill`,JSON.stringify({skill_name:n.skill_name,skill_hash:Z(n.skill_hash)})),o.append(`payload`,JSON.stringify(ve())),await G(e,i,r,{method:`POST`,body:o},6e5),e.logger.info(x(`[skill-detect] skill ${n.skill_name} detected successfully`)),!0}function Xe(e){if(e.tool_name!==`read`)return null;let t=e.tool_args;return!t||typeof t!=`object`||Array.isArray(t)?null:Object.values(t).find(e=>typeof e==`string`&&e.endsWith(`SKILL.md`))??null}async function Ze(e,t,i){let a=n(r(t));try{let t;i&&(t=Ae(e.runtime.agent.resolveAgentWorkspaceDir(e.config,i)));let n=(await Re(e,t))[a];return!n||!n.skill_hash?null:{skill_name:n.skill_name,skill_hash:Z(n.skill_hash)}}catch{return null}}function Qe(...e){return e.find(e=>typeof e==`string`)??``}function $e(e){return typeof e==`string`?e.toUpperCase():`PERMIT`}function et(e){if(!(typeof e!=`string`||e.length===0))try{let t=JSON.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}catch{return}}function tt(e){return{effect:$e(e?.effect),denyOutput:Qe(e?.deny_output),rewriteOutput:Qe(e?.rewrite_output)}}function nt(e){let t=$e(e.effect);if(t===`DENY`)return e.denyOutput?{action:`deny`,output:e.denyOutput,returnValue:{block:!0,blockReason:e.denyOutput||`Tool call blocked by detect service`}}:{action:`permit`,returnValue:void 0};if(t===`REWRITE`){if(!e.rewriteOutput)return{action:`permit`,returnValue:void 0};let t=et(e.rewriteOutput);return t?{action:`rewrite`,returnValue:{params:t}}:{action:`rewrite_invalid`,returnValue:void 0}}return{action:`permit`,returnValue:void 0}}async function rt(e,t,n,r,i){if(!await t.isHookEnabled(n)){e.logger.info(x(`[${n}] detect skipped: hook disabled by runtime config`));return}let a=Date.now(),o=X(n,r,i);T(e,n,o,E(e));try{let t=tt(await K(e,n,o));e.logger.info(x(`[${n}] detect effect observed: effect=${t.effect} (report-only hook)`))}catch(t){e.logger.error(x(`[${n}] detect request failed: ${t instanceof Error?t.message:String(t)}`))}finally{let t=Date.now()-a;e.logger.info(x(`[${n}] total_elapsed=${t}ms`))}}async function it(e,t,n,r){let i=Date.now();if(!await t.isHookEnabled(`before_tool_call`)){e.logger.info(x(`[before_tool_call] detect skipped: hook disabled by runtime config`));return}let a=X(`before_tool_call`,n,r),o=Xe(a),s=a;if(o){let t=await Ze(e,o,r.agentId);t&&(s={...s,...t},e.logger.info(x(`[before_tool_call] skill read detected: skill=${t.skill_name} hash=${t.skill_hash.slice(0,12)}...`)))}T(e,`before_tool_call`,s,E(e));let c;try{let t=nt(tt(await K(e,`before_tool_call`,s)));e.logger.info(x(`[before_tool_call] detect effect applied: ${JSON.stringify(t.returnValue)}`)),c=t.returnValue}catch(t){e.logger.error(x(`[before_tool_call] detect request failed: ${t instanceof Error?t.message:String(t)}`))}let l=Date.now()-i;return e.logger.info(x(`[before_tool_call] total_elapsed=${l}ms`)),c}function at(e,t){e.on(`llm_input`,async(n,r)=>{await rt(e,t,`llm_input`,n,r)}),e.on(`llm_output`,async(n,r)=>{await rt(e,t,`llm_output`,n,r)}),e.on(`after_tool_call`,async(n,r)=>{await rt(e,t,`after_tool_call`,n,r)}),e.on(`before_tool_call`,async(n,r)=>it(e,t,n,r))}function Q(e){return typeof e==`object`&&!!e}function ot(e,t){if(!Q(e))return null;let n=e[t];return Q(n)?n:null}function st(e){let t=ot(ot(e,`models`),`providers`);return t?Object.entries(t).map(([e,t])=>{if(!Q(t))return null;let n=t.baseUrl??t.baseURL;return typeof n==`string`&&n?{providerId:e,baseUrl:n}:null}).filter(e=>e!==null):[]}function ct(e,t){for(let n of t)if(e.startsWith(n.baseUrl))return n;return null}function lt(e){return typeof e==`string`?e:e instanceof URLSearchParams?e.toString():e instanceof Uint8Array?new TextDecoder().decode(e):ArrayBuffer.isView(e)?new TextDecoder().decode(new Uint8Array(e.buffer,e.byteOffset,e.byteLength)):e instanceof ArrayBuffer?new TextDecoder().decode(new Uint8Array(e)):null}function ut(e){let t=lt(e);if(!t)return null;try{let e=JSON.parse(t);return Q(e)?e:null}catch{return null}}function dt(e){return Q(e)?Array.isArray(e.messages)||typeof e.prompt==`string`||typeof e.input==`string`:!1}function ft(e){return typeof e==`string`&&e.includes(`/open-apis/security_plugin/v1/openclaw_plugin`)}function pt(e){return typeof e==`string`&&e.includes(`text/event-stream`)}function mt(e,t){let n=e.split(/\r?\n/).filter(e=>e.startsWith(`data:`)).map(e=>e.slice(5).trim()).filter(e=>e.length>0&&e!==`[DONE]`),r=Math.max(1,Number(t)||1);if(r===1)return n;let i=[];for(let e=0;e<n.length;e+=r)i.push(n.slice(e,e+r).join(`
2
+ `));return i}function ht(e,t){return t?`${String(e).split(/\r?\n/).map(e=>`data: ${e}`).join(`
3
+ `)}\n\n`:e}function gt(e,t,n){let r=new Headers(e.headers);return r.delete(`content-length`),n?r.set(`content-type`,`text/event-stream; charset=utf-8`):r.get(`content-type`)||r.set(`content-type`,`text/plain; charset=utf-8`),new Response(ht(t,n),{status:e.status,statusText:e.statusText,headers:r})}async function _t(e,t,n){let r=await t.clone().text(),i=pt(t.headers.get(`content-type`)??``);return{url:e,isSse:i,chunks:i?mt(r,n):[],originResp:i?``:r}}function vt(...e){return e.find(e=>typeof e==`string`)??``}function yt(e){return typeof e==`string`?e.toUpperCase():`PERMIT`}function bt(e){return{effect:yt(e?.effect),denyOutput:vt(e?.deny_output),rewriteOutput:vt(e?.rewrite_output)}}function xt(e){let t=yt(e.effect);return t===`DENY`&&e.denyOutput?{action:`deny`,output:e.denyOutput,effect:t}:t===`REWRITE`&&e.rewriteOutput?{action:`rewrite`,output:e.rewriteOutput,effect:t}:{action:`permit`,output:``,effect:t}}function St(e){let t=yt(e.effect);return t===`DENY`&&e.denyOutput?{action:`deny`,output:e.denyOutput,effect:t}:t===`REWRITE`&&e.rewriteOutput?{action:`rewrite`,output:e.rewriteOutput,effect:t}:{action:`permit`,output:``,effect:t}}function Ct(e,t,n){e.logger.info(x(`[${t}] ${w(n,E(e))}`))}function wt(){let e=globalThis.crypto;return e?.randomUUID?e.randomUUID():`${Date.now()}-${Math.random().toString(16).slice(2)}`}function Tt(e){let t=String(e);function n(e){if(typeof e!=`string`)return JSON.stringify(e);try{let t=JSON.parse(e);return typeof t==`string`?t:JSON.stringify(t)}catch{return e}}try{let e=JSON.parse(t);if(Array.isArray(e))return e.map(e=>n(e))}catch{}return t.split(/\r?\n/)}function Et(e,t){let n=new Headers(e.headers);n.delete(`content-length`),n.set(`content-type`,`text/event-stream; charset=utf-8`);let r=`${Tt(t).map(e=>`data: ${e}\n\n`).join(``)}`;return new Response(r,{status:e.status,statusText:e.statusText,headers:n})}function Dt(e){return(e.headers.get(`content-type`)??``).includes(`text/event-stream`)}async function Ot(e,t,n,r,i,a){let o=r.body;if(!o)return r;let s=Math.max(1,Number(await i.getSseChunkSize())||1),c=o.getReader(),l=new TextDecoder,u=new TextEncoder,d=``,f=[],p=[];async function m(r){let i=X(`after_llm_fetch`,null,null,{request_id:n,url:t,isSse:!0,chunks:r,originResp:``});return Ct(e,`after_llm_fetch`,i),St(bt(await K(e,`after_llm_fetch`,i)))}function h(e){f.length!==0&&(e.enqueue(u.encode(f.join(``))),f=[])}let g=new ReadableStream({async start(t){try{for(;;){let{value:i,done:o}=await c.read();if(o)break;for(d+=l.decode(i,{stream:!0});;){let i=d.indexOf(`
4
4
 
5
5
  `),o=2;if(i<0&&(i=d.indexOf(`\r
6
6
  \r
7
- `),o=4),i<0)break;let l=d.slice(0,i);d=d.slice(i+o);let g=`${l}\n\n`;f.push(g);let _=l.split(/\r?\n/);for(let e of _){if(!e.startsWith(`data:`))continue;let t=e.slice(5).trim();!t||t===`[DONE]`||p.push(t)}if(p.length>=s){try{let i=await m(p);if((i.action===`deny`||i.action===`rewrite`)&&i.output){f=[],p=[];let o=await _t(r,i.output).text();t.enqueue(u.encode(o));try{await c.cancel()}catch{}t.close(),e.logger.info(S(`[llm_fetch] total_elapsed=${Date.now()-a}ms request_id=${n}`));return}}catch(t){e.logger.error(S(`[after_llm_fetch] detect failed; passthrough buffered events: ${t instanceof Error?t.message:String(t)}`))}h(t),p=[]}}}if(d&&=(f.push(d),``),p.length>0)try{let i=await m(p);if((i.action===`deny`||i.action===`rewrite`)&&i.output){f=[],p=[];let o=await _t(r,i.output).text();t.enqueue(u.encode(o));try{await c.cancel()}catch{}t.close(),e.logger.info(S(`[llm_fetch] total_elapsed=${Date.now()-a}ms request_id=${n}`));return}}catch(t){e.logger.error(S(`[after_llm_fetch] detect failed; passthrough buffered events: ${t instanceof Error?t.message:String(t)}`))}h(t),t.close(),e.logger.info(S(`[llm_fetch] total_elapsed=${Date.now()-a}ms request_id=${n}`))}catch(e){try{await c.cancel()}catch{}t.error(e)}}}),_=new Headers(r.headers);return _.delete(`content-length`),_.set(`content-type`,`text/event-stream; charset=utf-8`),new Response(g,{status:r.status,statusText:r.statusText,headers:_})}function bt(e,t){let n=globalThis.fetch;if(typeof n!=`function`){e.logger.warn(S(`[before_llm_fetch] global.fetch is unavailable; skipping interceptor`));return}globalThis.__openclawGuardianOriginalFetch||(globalThis.__openclawGuardianOriginalFetch=n,globalThis.fetch=async function(r,i){let a=[r,i],o=r?.toString?.()??``,s=i??{},c=()=>n.call(globalThis,a[0],a[1]);if(a[1]||=s,rt(o))return c();let l,u=null;try{let r=$e(o,Qe(e.config));if(!r)return e.logger.info(S(`[before_llm_fetch] pass-through: no provider baseUrl match for url=${o}`)),c();e.logger.info(S(`[before_llm_fetch] matched provider=${r.providerId} baseUrl=${r.baseUrl} url=${o}`));let i=tt(s.body);if(!nt(i))return e.logger.info(S(`[before_llm_fetch] pass-through: matched provider=${r.providerId} but request body is not a supported LLM payload shape`)),c();let d={request_id:ht(),url:o,rawBody:et(s.body)??``,jsonBody:i},f=String(d.request_id);if(u=Date.now(),await t.isHookEnabled(`before_llm_fetch`)){let t=Y(`before_llm_fetch`,null,null,d);mt(e,`before_llm_fetch`,t);let n=dt(await K(e,`before_llm_fetch`,t)),i=ft(n);(i.action===`deny`||i.action===`rewrite`)&&i.output?(s.body=String(i.output),a[1]=s,e.logger.info(S(`[before_llm_fetch] detect effect applied: ${i.action} (use output as new body) provider=${r.providerId}`))):e.logger.info(S(`[before_llm_fetch] detect effect passthrough: effect=${n.effect} provider=${r.providerId}`))}else e.logger.info(S(`[before_llm_fetch] detect skipped: hook disabled by runtime config`));if(l=await n.apply(this,a),!await t.isHookEnabled(`after_llm_fetch`))return u!==null&&e.logger.info(S(`[llm_fetch] total_elapsed=${Date.now()-u}ms request_id=${f}`)),l;if(vt(l))return await yt(e,o,f,l,t,u??Date.now());let p=await ct(o,l,await t.getSseChunkSize()),m=Y(`after_llm_fetch`,null,null,{...p,request_id:f});mt(e,`after_llm_fetch`,m);let h=dt(await K(e,`after_llm_fetch`,m)),g=pt(h);return(g.action===`deny`||g.action===`rewrite`)&&g.output?(e.logger.info(S(`[after_llm_fetch] detect effect applied: ${g.action} provider=${r.providerId}`)),u!==null&&e.logger.info(S(`[llm_fetch] total_elapsed=${Date.now()-u}ms url=${o}`)),st(l,g.output,p.isSse)):(e.logger.info(S(`[after_llm_fetch] detect effect passthrough: effect=${h.effect} provider=${r.providerId}`)),u!==null&&e.logger.info(S(`[llm_fetch] total_elapsed=${Date.now()-u}ms request_id=${f}`)),l)}catch(t){return e.logger.error(S(`[llm_fetch] detect request failed, allowing original fetch flow: ${t instanceof Error?t.message:String(t)}`)),l?(u!==null&&e.logger.info(S(`[llm_fetch] total_elapsed=${Date.now()-u}ms request_id=<unknown>`)),l):c()}})}var xt=y(((e,t)=>{function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,`default`)?e.default:e}let r=new Int32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);function i(e){if(Buffer.isBuffer(e))return e;if(typeof e==`number`)return Buffer.alloc(e);if(typeof e==`string`)return Buffer.from(e);throw Error(`input must be buffer, number, or string, received `+typeof e)}function a(e){let t=i(4);return t.writeInt32BE(e,0),t}function o(e,t){e=i(e),Buffer.isBuffer(t)&&(t=t.readUInt32BE(0));let n=~~t^-1;for(var a=0;a<e.length;a++)n=r[(n^e[a])&255]^n>>>8;return n^-1}function s(){return a(o.apply(null,arguments))}s.signed=function(){return o.apply(null,arguments)},s.unsigned=function(){return o.apply(null,arguments)>>>0},t.exports=n(s)})),St=y((e=>{var t=b(`fs`),n=b(`stream`).Transform,r=b(`stream`).PassThrough,i=b(`zlib`),a=b(`util`),o=b(`events`).EventEmitter,s=b(`events`).errorMonitor,c=xt();e.ZipFile=l,a.inherits(l,o);function l(){this.outputStream=new r,this.entries=[],this.outputStreamCursor=0,this.ended=!1,this.allDone=!1,this.forceZip64Eocd=!1,this.errored=!1,this.on(s,function(){this.errored=!0})}l.prototype.addFile=function(e,n,r){var i=this;if(n=S(n,!1),r??={},!g(i)){var a=new w(n,!1,r);i.entries.push(a),t.stat(e,function(n,o){if(n)return i.emit(`error`,n);if(!o.isFile())return i.emit(`error`,Error(`not a file: `+e));a.uncompressedSize=o.size,r.mtime??a.setLastModDate(o.mtime),r.mode??a.setFileAttributesMode(o.mode),a.setFileDataPumpFunction(function(){var n=t.createReadStream(e);a.state=w.FILE_DATA_IN_PROGRESS,n.on(`error`,function(e){i.emit(`error`,e)}),f(i,a,n)}),m(i)})}},l.prototype.addReadStream=function(e,t,n){this.addReadStreamLazy(t,n,function(t){t(null,e)})},l.prototype.addReadStreamLazy=function(e,t,n){var r=this;if(typeof t==`function`&&(n=t,t=null),t??={},e=S(e,!1),!g(r)){var i=new w(e,!1,t);r.entries.push(i),i.setFileDataPumpFunction(function(){i.state=w.FILE_DATA_IN_PROGRESS,n(function(e,t){if(e)return r.emit(`error`,e);f(r,i,t)})}),m(r)}},l.prototype.addBuffer=function(e,t,n){var r=this;if(t=S(t,!1),e.length>1073741823)throw Error(`buffer too large: `+e.length+` > 1073741823`);if(n??={},n.size!=null)throw Error(`options.size not allowed`);if(g(r))return;var a=new w(t,!1,n);a.uncompressedSize=e.length,a.crc32=c.unsigned(e),a.crcAndFileSizeKnown=!0,r.entries.push(a),a.compressionLevel===0?o(e):i.deflateRaw(e,{level:a.compressionLevel},function(e,t){o(t)});function o(e){a.compressedSize=e.length,a.setFileDataPumpFunction(function(){d(r,e),d(r,a.getDataDescriptor()),a.state=w.FILE_DATA_DONE,setImmediate(function(){m(r)})}),m(r)}},l.prototype.addEmptyDirectory=function(e,t){var n=this;if(e=S(e,!0),t??={},t.size!=null)throw Error(`options.size not allowed`);if(t.compress!=null)throw Error(`options.compress not allowed`);if(t.compressionLevel!=null)throw Error(`options.compressionLevel not allowed`);if(!g(n)){var r=new w(e,!0,t);n.entries.push(r),r.setFileDataPumpFunction(function(){d(n,r.getDataDescriptor()),r.state=w.FILE_DATA_DONE,m(n)}),m(n)}};var u=H([80,75,5,6]);l.prototype.end=function(e,t){if(typeof e==`function`&&(t=e,e=null),e??={},!this.ended&&(this.ended=!0,!this.errored)){if(this.calculatedTotalSizeCallback=t,this.forceZip64Eocd=!!e.forceZip64Format,e.comment){if(typeof e.comment==`string`?this.comment=re(e.comment):this.comment=e.comment,this.comment.length>65535)throw Error(`comment is too large`);if(U(this.comment,u))throw Error(`comment contains end of central directory record signature`)}else this.comment=C;m(this)}};function d(e,t){e.outputStream.write(t),e.outputStreamCursor+=t.length}function f(e,t,n){var a=new R,o=new L,s=t.compressionLevel===0?new r:new i.DeflateRaw({level:t.compressionLevel}),c=new L;n.pipe(a).pipe(o).pipe(s).pipe(c).pipe(e.outputStream,{end:!1}),c.on(`end`,function(){if(t.crc32=a.crc32,t.uncompressedSize==null)t.uncompressedSize=o.byteCount;else if(t.uncompressedSize!==o.byteCount)return e.emit(`error`,Error(`file data stream has unexpected number of bytes`));t.compressedSize=c.byteCount,e.outputStreamCursor+=t.compressedSize,d(e,t.getDataDescriptor()),t.state=w.FILE_DATA_DONE,m(e)})}function p(e){if(e.compress!=null&&e.compressionLevel!=null&&!!e.compress!=!!e.compressionLevel)throw Error(`conflicting settings for compress and compressionLevel`);return e.compressionLevel==null?e.compress===!1?0:6:e.compressionLevel}function m(e){if(e.allDone||e.errored)return;if(e.ended&&e.calculatedTotalSizeCallback!=null){var t=h(e);t!=null&&(e.calculatedTotalSizeCallback(t),e.calculatedTotalSizeCallback=null)}var n=r();function r(){for(var t=0;t<e.entries.length;t++){var n=e.entries[t];if(n.state<w.FILE_DATA_DONE)return n}return null}if(n!=null){if(n.state<w.READY_TO_PUMP_FILE_DATA||n.state===w.FILE_DATA_IN_PROGRESS)return;n.relativeOffsetOfLocalHeader=e.outputStreamCursor,d(e,n.getLocalFileHeader()),n.doFileDataPump()}else e.ended&&(e.offsetOfStartOfCentralDirectory=e.outputStreamCursor,e.entries.forEach(function(t){d(e,t.getCentralDirectoryRecord())}),d(e,x(e)),e.outputStream.end(),e.allDone=!0)}function h(e){for(var t=0,n=0,r=0;r<e.entries.length;r++){var i=e.entries[r];if(i.compressionLevel!==0)return-1;if(i.state>=w.READY_TO_PUMP_FILE_DATA){if(i.uncompressedSize==null)return-1}else if(i.uncompressedSize==null)return null;i.relativeOffsetOfLocalHeader=t;var a=i.useZip64Format();t+=T+i.utf8FileName.length,t+=i.uncompressedSize,i.crcAndFileSizeKnown||(a?t+=j:t+=A),n+=M+i.utf8FileName.length+i.fileComment.length,i.forceDosTimestamp||(n+=N),a&&(n+=P)}var o=0;return(e.forceZip64Eocd||e.entries.length>=65535||n>=65535||t>=4294967295)&&(o+=_+v),o+=y+e.comment.length,t+n+o}function g(e){if(e.ended)throw Error(`cannot add entries after calling end()`);return!!e.errored}var _=56,v=20,y=22;function x(e,t){var n=!1,r=e.entries.length;(e.forceZip64Eocd||e.entries.length>=65535)&&(r=65535,n=!0);var i=e.outputStreamCursor-e.offsetOfStartOfCentralDirectory,a=i;(e.forceZip64Eocd||i>=4294967295)&&(a=4294967295,n=!0);var o=e.offsetOfStartOfCentralDirectory;if((e.forceZip64Eocd||e.offsetOfStartOfCentralDirectory>=4294967295)&&(o=4294967295,n=!0),t)return n?_+v+y:y;var s=V(y+e.comment.length);if(s.writeUInt32LE(101010256,0),s.writeUInt16LE(0,4),s.writeUInt16LE(0,6),s.writeUInt16LE(r,8),s.writeUInt16LE(r,10),s.writeUInt32LE(a,12),s.writeUInt32LE(o,16),s.writeUInt16LE(e.comment.length,20),e.comment.copy(s,22),!n)return s;var c=V(_);c.writeUInt32LE(101075792,0),I(c,_-12,4),c.writeUInt16LE(D,12),c.writeUInt16LE(ee,14),c.writeUInt32LE(0,16),c.writeUInt32LE(0,20),I(c,e.entries.length,24),I(c,e.entries.length,32),I(c,i,40),I(c,e.offsetOfStartOfCentralDirectory,48);var l=V(v);return l.writeUInt32LE(117853008,0),l.writeUInt32LE(0,4),I(l,e.outputStreamCursor,8),l.writeUInt32LE(1,16),Buffer.concat([c,l,s])}function S(e,t){if(e===``)throw Error(`empty metadataPath`);if(e=e.replace(/\\/g,`/`),/^[a-zA-Z]:/.test(e)||/^\//.test(e))throw Error(`absolute path: `+e);if(e.split(`/`).indexOf(`..`)!==-1)throw Error(`invalid relative path: `+e);var n=/\/$/.test(e);if(t)n||(e+=`/`);else if(n)throw Error(`file path cannot end with '/': `+e);return e}var C=V(0);function w(e,t,n){if(this.utf8FileName=H(e),this.utf8FileName.length>65535)throw Error(`utf8 file name too long. `+utf8FileName.length+` > 65535`);if(this.isDirectory=t,this.state=w.WAITING_FOR_METADATA,this.setLastModDate(n.mtime==null?new Date:n.mtime),this.forceDosTimestamp=!!n.forceDosTimestamp,n.mode==null?this.setFileAttributesMode(t?16893:33204):this.setFileAttributesMode(n.mode),t?(this.crcAndFileSizeKnown=!0,this.crc32=0,this.uncompressedSize=0,this.compressedSize=0):(this.crcAndFileSizeKnown=!1,this.crc32=null,this.uncompressedSize=null,this.compressedSize=null,n.size!=null&&(this.uncompressedSize=n.size)),t?this.compressionLevel=0:this.compressionLevel=p(n),this.forceZip64Format=!!n.forceZip64Format,n.fileComment){if(typeof n.fileComment==`string`?this.fileComment=H(n.fileComment,`utf-8`):this.fileComment=n.fileComment,this.fileComment.length>65535)throw Error(`fileComment is too large`)}else this.fileComment=C}w.WAITING_FOR_METADATA=0,w.READY_TO_PUMP_FILE_DATA=1,w.FILE_DATA_IN_PROGRESS=2,w.FILE_DATA_DONE=3,w.prototype.setLastModDate=function(e){this.mtime=e;var t=ne(e);this.lastModFileTime=t.time,this.lastModFileDate=t.date},w.prototype.setFileAttributesMode=function(e){if((e&65535)!==e)throw Error(`invalid mode. expected: 0 <= `+e+` <= 65535`);this.externalFileAttributes=e<<16>>>0},w.prototype.setFileDataPumpFunction=function(e){this.doFileDataPump=e,this.state=w.READY_TO_PUMP_FILE_DATA},w.prototype.useZip64Format=function(){return this.forceZip64Format||this.uncompressedSize!=null&&this.uncompressedSize>4294967294||this.compressedSize!=null&&this.compressedSize>4294967294||this.relativeOffsetOfLocalHeader!=null&&this.relativeOffsetOfLocalHeader>4294967294};var T=30,E=20,ee=45,D=831,O=2048,k=8;w.prototype.getLocalFileHeader=function(){var e=0,t=0,n=0;this.crcAndFileSizeKnown&&(e=this.crc32,t=this.compressedSize,n=this.uncompressedSize);var r=V(T),i=O;return this.crcAndFileSizeKnown||(i|=k),r.writeUInt32LE(67324752,0),r.writeUInt16LE(E,4),r.writeUInt16LE(i,6),r.writeUInt16LE(this.getCompressionMethod(),8),r.writeUInt16LE(this.lastModFileTime,10),r.writeUInt16LE(this.lastModFileDate,12),r.writeUInt32LE(e,14),r.writeUInt32LE(t,18),r.writeUInt32LE(n,22),r.writeUInt16LE(this.utf8FileName.length,26),r.writeUInt16LE(0,28),Buffer.concat([r,this.utf8FileName])};var A=16,j=24;w.prototype.getDataDescriptor=function(){if(this.crcAndFileSizeKnown)return C;if(this.useZip64Format()){var e=V(j);return e.writeUInt32LE(134695760,0),e.writeUInt32LE(this.crc32,4),I(e,this.compressedSize,8),I(e,this.uncompressedSize,16),e}else{var e=V(A);return e.writeUInt32LE(134695760,0),e.writeUInt32LE(this.crc32,4),e.writeUInt32LE(this.compressedSize,8),e.writeUInt32LE(this.uncompressedSize,12),e}};var M=46,N=9,P=28;w.prototype.getCentralDirectoryRecord=function(){var e=V(M),t=O;this.crcAndFileSizeKnown||(t|=k);var n=C;if(!this.forceDosTimestamp){n=V(N),n.writeUInt16LE(21589,0),n.writeUInt16LE(N-4,2),n.writeUInt8(3,4);var r=Math.floor(this.mtime.getTime()/1e3);r<-2147483648&&(r=-2147483648),r>2147483647&&(r=2147483647),n.writeUInt32LE(r,5)}var i=this.compressedSize,a=this.uncompressedSize,o=this.relativeOffsetOfLocalHeader,s=E,c=C;return this.useZip64Format()&&(i=4294967295,a=4294967295,o=4294967295,s=ee,c=V(P),c.writeUInt16LE(1,0),c.writeUInt16LE(P-4,2),I(c,this.uncompressedSize,4),I(c,this.compressedSize,12),I(c,this.relativeOffsetOfLocalHeader,20)),e.writeUInt32LE(33639248,0),e.writeUInt16LE(D,4),e.writeUInt16LE(s,6),e.writeUInt16LE(t,8),e.writeUInt16LE(this.getCompressionMethod(),10),e.writeUInt16LE(this.lastModFileTime,12),e.writeUInt16LE(this.lastModFileDate,14),e.writeUInt32LE(this.crc32,16),e.writeUInt32LE(i,20),e.writeUInt32LE(a,24),e.writeUInt16LE(this.utf8FileName.length,28),e.writeUInt16LE(n.length+c.length,30),e.writeUInt16LE(this.fileComment.length,32),e.writeUInt16LE(0,34),e.writeUInt16LE(0,36),e.writeUInt32LE(this.externalFileAttributes,38),e.writeUInt32LE(o,42),Buffer.concat([e,this.utf8FileName,n,c,this.fileComment])},w.prototype.getCompressionMethod=function(){return this.compressionLevel===0?0:8};var F=new Date(1980,0,1),te=new Date(2107,11,31,23,59,58);function ne(e){e<F?e=F:e>te&&(e=te);var t=0;t|=e.getDate()&31,t|=(e.getMonth()+1&15)<<5,t|=(e.getFullYear()-1980&127)<<9;var n=0;return n|=Math.floor(e.getSeconds()/2),n|=(e.getMinutes()&63)<<5,n|=(e.getHours()&31)<<11,{date:t,time:n}}function I(e,t,n){var r=Math.floor(t/4294967296),i=t%4294967296;e.writeUInt32LE(i,n),e.writeUInt32LE(r,n+4)}a.inherits(L,n);function L(e){n.call(this,e),this.byteCount=0}L.prototype._transform=function(e,t,n){this.byteCount+=e.length,n(null,e)},a.inherits(R,n);function R(e){n.call(this,e),this.crc32=0}R.prototype._transform=function(e,t,n){this.crc32=c.unsigned(e,this.crc32),n(null,e)};var z=`\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■\xA0`;if(z.length!==256)throw Error(`assertion failure`);var B=null;function re(e){if(/^[\x20-\x7e]*$/.test(e))return H(e,`utf-8`);if(B==null){B={};for(var t=0;t<z.length;t++)B[z[t]]=t}for(var n=V(e.length),t=0;t<e.length;t++){var r=B[e[t]];if(r==null)throw Error(`character not encodable in CP437: `+JSON.stringify(e[t]));n[t]=r}return n}function V(e){V=t;try{return V(e)}catch{return V=n,V(e)}function t(e){return Buffer.allocUnsafe(e)}function n(e){return new Buffer(e)}}function H(e,t){H=n;try{return H(e,t)}catch{return H=r,H(e,t)}function n(e,t){return Buffer.from(e,t)}function r(e,t){return new Buffer(e,t)}}function U(e,t){U=n;try{return U(e,t)}catch{return U=r,U(e,t)}function n(e,t){return e.includes(t)}function r(e,t){for(var n=0;n<=e.length-t.length;n++)for(var r=0;;r++){if(r===t.length)return!0;if(e[n+r]!==t[r])break}return!1}}}))();function Ct(e){if(!e||typeof e!=`object`||Array.isArray(e))return{};let t={};for(let[n,r]of Object.entries(e))t[n]=r===!0;return t}function wt(e){return{skills:Object.values(e).map(e=>({skill_name:e.skill_name,skill_hash:e.zip_hash}))}}async function Tt(e,t){let n=le(e),r=wt(t),i=await G(e,`batch_check_detection`,n,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(r)},H);return i&&typeof i==`object`&&!Array.isArray(i)&&`result`in i?Ct(i.result):Ct(i)}const Et=10*1024*1024;async function Dt(e){let t=await f(e),n=[];for(let r of t){let t=i(e,r),a=await l(t);a.isSymbolicLink()||(a.isDirectory()?n.push(...await Dt(t)):a.isFile()&&n.push(t))}return n}async function Ot(e){let t=await m(e).catch(()=>null);if(!t||!t.isDirectory())throw Error(`zipDirectory: path does not exist or is not a directory: ${e}`);let n=await Dt(e);return n.sort((t,n)=>{let r=a(e,t),i=a(e,n);return r<i?-1:+(r>i)}),new Promise((t,r)=>{let i=new St.ZipFile,o=[],s=0,c=!1,l=e=>{c||(c=!0,r(e))};i.outputStream.on(`data`,t=>{if(!c){if(s+=t.length,s>Et){l(Error(`zipDirectory: zip exceeds ${Et} bytes limit for ${e} (${s} bytes)`));return}o.push(t)}}),i.outputStream.on(`end`,()=>{c||(c=!0,t(Buffer.concat(o)))}),i.outputStream.on(`error`,l);for(let t of n)i.addFile(t,a(e,t));i.end()})}async function kt(e,t,n){let r=ue(e),i=`skill_detect:${n.skill_name}`;e.logger.info(S(`[skill-detect] detect: sending skill=${n.skill_name} hash=${n.skill_hash.slice(0,12)}... dir=${t}`));let a=await Ot(t);e.logger.info(S(`[skill-detect] zipped ${t} (${a.length} bytes)`));let o=new FormData,s=new Blob([new Uint8Array(a)],{type:`application/zip`});return o.append(`file`,s,n.skill_name),o.append(`skill`,JSON.stringify({skill_name:n.skill_name,skill_hash:n.skill_hash})),o.append(`payload`,JSON.stringify(ve())),await G(e,i,r,{method:`POST`,body:o},6e5),e.logger.info(S(`[skill-detect] skill ${n.skill_name} detected successfully`)),!0}function Q(e){return e.replace(/\0/g,``)}function At(e,t){let n=s(),r=new Set,a=e.config??{},c=a?.skills?.load?.extraDirs;if(Array.isArray(c))for(let e of c)typeof e==`string`&&e.trim()&&r.add(o(Q(e.trim())));r.add(i(n,`.openclaw`,`skills`)),r.add(i(n,`.agents`,`skills`));let l=new Set,u=a?.agents?.defaults?.workspace;if(typeof u==`string`&&u.trim()&&l.add(o(Q(u.trim()))),Array.isArray(a?.agents?.list))for(let e of a.agents.list)typeof e?.workspace==`string`&&e.workspace.trim()&&l.add(o(Q(e.workspace.trim())));for(let e of l)r.add(i(e,`skills`)),r.add(i(e,`.agents`,`skills`));let d,f=e.pluginConfig;if(typeof f?.openClawDir==`string`&&f.openClawDir.trim())d=o(Q(f.openClawDir.trim()));else try{let t=e.runtime?.state?.resolveStateDir?.();typeof t==`string`&&t.trim()&&(d=t)}catch{}d&&(r.add(i(d,`skills`)),r.add(i(d,`.agents`,`skills`)));let p=a?.plugins;if(p?.installs&&typeof p.installs==`object`){for(let e of Object.values(p.installs))if(typeof e?.installPath==`string`&&e.installPath.trim()){let t=i(Q(e.installPath.trim()),`skills`);r.add(o(t))}}let m=t??i(n,`.openclaw`,`workspace`);r.add(i(m,`.agents`,`skills`)),r.add(i(m,`skills`));let h=Array.from(r),g=h.filter(e=>v(e));return e.logger.info(S(`[skill-scan] resolved ${h.length} skill path(s), ${g.length} exist`)),g}async function jt(e){let t;try{t=await f(e)}catch{return[]}let n=[];for(let r of t){let t=i(e,r),a=await l(t);a.isSymbolicLink()||(a.isDirectory()?n.push(...await jt(t)):a.isFile()&&n.push(t))}return n}const Mt=10*1024*1024,Nt=10*1024*1024;async function Pt(e){let t=await jt(e);if(t.length===0)return _(`sha256`).update(`empty-skill-dir`).digest(`hex`);let n=t.map(t=>a(e,t)),r=n.map((e,t)=>t);r.sort((e,t)=>n[e]<n[t]?-1:+(n[e]>n[t]));let i=_(`sha256`),o=0;for(let a of r){let r=n[a];i.update(`${r.length}:${r}\n`);let s=await d(t[a]);if(o+=s.length,o>Mt)throw Error(`computeSkillDirHash: skill directory exceeds ${Mt} byte limit: ${e}`);i.update(`${s.length}:`),i.update(s),i.update(`
8
- `)}return i.digest(`hex`)}async function Ft(e){let t=await jt(e),n=t.map(t=>a(e,t)),r=n.map((e,t)=>t);r.sort((e,t)=>n[e]<n[t]?-1:+(n[e]>n[t]));let i=r.map(e=>t[e]),o=r.map(e=>n[e]);return new Promise((t,n)=>{let r=new St.ZipFile,a=_(`sha256`),s=0,c=!1,l=e=>{c||(c=!0,n(e))};r.outputStream.on(`data`,t=>{if(!c){if(s+=t.length,s>Nt){l(Error(`computeZipHash: zip exceeds ${Nt} byte limit for ${e}`));return}a.update(t)}}),r.outputStream.on(`end`,()=>{c||(c=!0,t(a.digest(`hex`)))}),r.outputStream.on(`error`,e=>l(e));for(let e=0;e<i.length;e++)r.addFile(i[e],o[e]);r.end()})}function It(e){let t=/^name:\s*(.+)$/m.exec(e);return t?t[1].trim():null}function Lt(e){let t=/^---\n([\s\S]*?)\n---/.exec(e);return t?t[1]:``}async function Rt(e,t){let n;try{n=await f(t,{withFileTypes:!0,encoding:`utf8`})}catch{return[]}let r=[];for(let a of n){if(!a.isDirectory())continue;let n=i(t,a.name),o=i(n,`SKILL.md`);try{let e=It(Lt(await d(o,`utf-8`)))||a.name,t=await Pt(n);r.push({dirName:a.name,dirPath:n,filePath:o,skillName:e,dirHash:t})}catch(t){t instanceof Error&&t.message.includes(`byte limit`)&&e.logger.warn(S(`[skill-scan] skipping skill '${a.name}': ${t.message}`))}}return r}async function zt(e,t){let n=At(e,t);e.logger.info(S(`[skill-scan] scanning ${n.length} skill location(s)`));let r=new Map;for(let t of n){let n=await Rt(e,t);n.length>0&&e.logger.info(S(`[skill-scan] ${t}: ${n.length} skill(s)`));for(let e of n)r.set(e.skillName,e)}let i=Array.from(r.values());return e.logger.info(S(`[skill-scan] scan complete: ${i.length} unique skill(s) across all locations`)),i}function Bt(e,t,n,r,i){e[t]={...n,skill_name:r.skill_name,zip_hash:r.skill_hash,is_detected:i,last_detect_ts:Date.now()}}async function Vt(e,t){e.logger.info(S(`[skill-scan] starting skill scan`));let n=Date.now(),r=je(t),i=await zt(e,t);if(i.length===0){e.logger.info(S(`[skill-scan] no skills found, skipping detection`));return}let a=Be(await Re(e,r),i);e.logger.info(S(`[skill-scan] merged state: ${Object.keys(a).length} skill(s)`));let o=new Map(i.map(e=>[e.dirName,e])),s=[];for(let[t,n]of Object.entries(a)){let r=o.get(t);if(r)try{if(Fe(n)){e.logger.info(S(`[skill-scan] ${n.skill_name}: zip_hash missing, computing`));let i=await Ft(r.dirPath);a[t]={...n,zip_hash:i,is_detected:!1},s.push({dirName:t,entry:a[t],entity:{skill_name:n.skill_name,skill_hash:i}})}else n.is_detected||(e.logger.info(S(`[skill-scan] ${n.skill_name}: not detected, queuing`)),s.push({dirName:t,entry:n,entity:{skill_name:n.skill_name,skill_hash:n.zip_hash}}))}catch(t){e.logger.error(S(`[skill-scan] failed to compute zip_hash for ${n.skill_name}: ${t instanceof Error?t.message:String(t)}`))}}if(e.logger.info(S(`[skill-scan] ${s.length} skill(s) need detection`)),s.length===0){await ze(e,a,r),e.logger.info(S(`[skill-scan] skill scan complete (nothing to detect) total_elapsed=${Date.now()-n}ms scanned=${i.length}`));return}let c={};for(let{dirName:e}of s)c[e]=a[e];let l={},u=!1;try{l=await Tt(e,c),e.logger.info(S(`[skill-scan] batch_check result: ${JSON.stringify(l)}`))}catch(t){e.logger.error(S(`[skill-scan] batch_check_detection failed: ${t instanceof Error?t.message:String(t)}`)),u=!0}for(let{dirName:t,entry:n,entity:r}of s)l[r.skill_hash]===!0&&(Bt(a,t,n,r,!0),e.logger.info(S(`[skill-scan] ${r.skill_name}: already known by server (batch_check)`)));if(u){e.logger.warn(S(`[skill-scan] skipping individual detect calls: batch_check_detection was unreachable`)),await ze(e,a,r),e.logger.info(S(`[skill-scan] skill scan complete (partial — batch_check failed) total_elapsed=${Date.now()-n}ms scanned=${i.length}`));return}for(let{dirName:t,entry:n,entity:r}of s){if(l[r.skill_hash]===!0)continue;let n=o.get(t);if(n)try{let i=await kt(e,n.dirPath,r);Bt(a,t,a[t],r,i),e.logger.info(S(`[skill-scan] detect result for ${r.skill_name}: is_detected=${i}`))}catch(n){e.logger.error(S(`[skill-scan] detect failed for ${r.skill_name}: ${n instanceof Error?n.message:String(n)}`)),Bt(a,t,a[t],r,!1)}}await ze(e,a,r),e.logger.info(S(`[skill-scan] skill scan complete total_elapsed=${Date.now()-n}ms scanned=${i.length} to_detect=${s.length}`))}async function Ht(e,t,n,r){e.logger.info(S(`[gateway_start] gateway ready on port=${n.port} ctx=${JSON.stringify(r)}`))}function Ut(e,t){let n=null,r=!1,i=!1,a;async function o(){if(i)return;let s=await t.getSkillScanIntervalMs();e.logger.info(S(`[skill-scan-service] next scan in ${s/1e3}s`)),n=setTimeout(async()=>{if(!i){if(!await t.isSkillDetectEnabled()){e.logger.info(S(`[skill-scan-service] periodic scan skipped: skill_detect disabled`)),await o();return}if(r){e.logger.info(S(`[skill-scan-service] periodic scan skipped: previous scan still running`)),await o();return}e.logger.info(S(`[skill-scan-service] periodic scan triggered`)),r=!0,Vt(e,a).catch(t=>{e.logger.error(S(`[skill-scan-service] periodic scan failed: ${t instanceof Error?t.message:String(t)}`))}).finally(()=>{r=!1,o()})}},s),n.unref()}return{id:`openclaw-guardian-skill-scan`,async start(n){a=n.workspaceDir,e.logger.info(S(`[skill-scan-service] starting with workspaceDir=${a??`(default)`}`)),i=!1,await t.isSkillDetectEnabled()&&(e.logger.info(S(`[skill-scan-service] running initial skill scan`)),r=!0,Vt(e,a).catch(t=>{e.logger.error(S(`[skill-scan-service] initial scan failed: ${t instanceof Error?t.message:String(t)}`))}).finally(()=>{r=!1})),await o()},async stop(t){i=!0,n&&=(clearTimeout(n),null),e.logger.info(S(`[skill-scan-service] stopped`))}}}function Wt(e,t){e.on(`gateway_start`,async(n,r)=>{await Ht(e,t,n,r)}),e.registerService(Ut(e,t))}const Gt=[...[`before_tool_call`,`after_tool_call`,`before_llm_fetch`,`after_llm_fetch`,`llm_input`,`llm_output`],`skill_detect`];function Kt(){return Object.fromEntries(Gt.map(e=>[e,!1]))}function qt(e){let t=Kt(),n=e&&typeof e==`object`?e:{};for(let e of Gt)t[e]=!!n[e];return t}function Jt(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):1}function Yt(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):900}function $(e){return{enabled:!1,hook_toggles:Kt(),sse_chunk_size:1,skill_scan_duration_second:900,reason:e}}function Xt(e){let t=e&&typeof e==`object`?e:{},n=t.enabled===void 0?!0:!!t.enabled;return{enabled:n,hook_toggles:n?qt(t.hook_toggles):Kt(),sse_chunk_size:Jt(t.sse_chunk_size),skill_scan_duration_second:Yt(t.skill_scan_duration_second),reason:n?`remote`:`remote_disabled`}}function Zt(e){return Qe(e.config).map(e=>e.baseUrl)}async function Qt(e){let t={source:`miaoda`,base_url_list:Zt(e)};return Xt(await G(e,`runtime_config`,se(e),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)},H))}function $t(e){let t=$(`not_initialized`),n=!1,r=null,i=null;async function a(){let r=null;for(let i=1;i<=3;i+=1)try{let r=await Qt(e);return t=r,n=!0,e.logger.debug?.(S(`[runtime_config] initial config loaded on attempt=${i} enabled_hooks=${JSON.stringify(r.hook_toggles)}`)),t}catch(t){r=t;let n=V(t);if(e.logger.error(S(`[runtime_config] initial config load failed attempt=${i} errorCode=${n}: ${t instanceof Error?t.message:String(t)}`)),n===`SERVER`||n===`PARSE`)break}return t=$(`initial_fetch_failed`),e.logger.warn(S(`[runtime_config] initial config unavailable after 3 attempts; detection disabled by default${r?`: ${r instanceof Error?r.message:String(r)}`:``}`)),t}async function o(){try{let r=await Qt(e);return t=r,n=!0,e.logger.debug?.(S(`[runtime_config] config refreshed enabled_hooks=${JSON.stringify(r.hook_toggles)} sse_chunk_size=${r.sse_chunk_size}`)),t}catch(r){let i=V(r);return n?(e.logger.error(S(`[runtime_config] refresh failed (errorCode=${i}); keeping previous config: ${r instanceof Error?r.message:String(r)}`)),t):(e.logger.error(S(`[runtime_config] refresh failed before first successful load (errorCode=${i}): ${r instanceof Error?r.message:String(r)}`)),t=$(`refresh_failed_${i}`),t)}}function s(){r||(r=setInterval(()=>{e.logger.debug?.(S(`[runtime_config] refresh loop fired`)),o().catch(t=>{e.logger.error(S(`[runtime_config] refresh loop failed: ${t instanceof Error?t.message:String(t)}`))})},6e5),r.unref())}function c(){return i||=a().catch(n=>(e.logger.error(S(`[runtime_config] initialize failed: ${n instanceof Error?n.message:String(n)}`)),t)).finally(()=>{s()}),i}return{async isHookEnabled(e){return await c(),!!(t?.enabled&&t?.hook_toggles?.[e])},async isSkillDetectEnabled(){return await c(),!!(t?.enabled&&t?.hook_toggles?.skill_detect)},async getSseChunkSize(){return await c(),Jt(t?.sse_chunk_size)},async getSkillScanIntervalMs(){return await c(),Yt(t?.skill_scan_duration_second)*1e3}}}var en=t({id:`openclaw-guardian-plugin`,name:`OpenClaw Guardian Plugin`,description:`Reports OpenClaw hook payloads to the trust_layer detect service with remote hook toggles.`,register(e){if(!P(e)){e.logger.debug?.(S(`[plugin] missing Feishu appId/appSecret from api.config.channels.feishu or pluginConfig; skip all hooks and reporting`));return}let t=$t(e);bt(e,t),Xe(e,t),Wt(e,t)}});export{en as default};
7
+ `),o=4),i<0)break;let l=d.slice(0,i);d=d.slice(i+o);let g=`${l}\n\n`;f.push(g);let _=l.split(/\r?\n/);for(let e of _){if(!e.startsWith(`data:`))continue;let t=e.slice(5).trim();!t||t===`[DONE]`||p.push(t)}if(p.length>=s){try{let i=await m(p);if((i.action===`deny`||i.action===`rewrite`)&&i.output){f=[],p=[];let o=await Et(r,i.output).text();t.enqueue(u.encode(o));try{await c.cancel()}catch{}t.close(),e.logger.info(x(`[llm_fetch] total_elapsed=${Date.now()-a}ms request_id=${n}`));return}}catch(t){e.logger.error(x(`[after_llm_fetch] detect failed; passthrough buffered events: ${t instanceof Error?t.message:String(t)}`))}h(t),p=[]}}}if(d&&=(f.push(d),``),p.length>0)try{let i=await m(p);if((i.action===`deny`||i.action===`rewrite`)&&i.output){f=[],p=[];let o=await Et(r,i.output).text();t.enqueue(u.encode(o));try{await c.cancel()}catch{}t.close(),e.logger.info(x(`[llm_fetch] total_elapsed=${Date.now()-a}ms request_id=${n}`));return}}catch(t){e.logger.error(x(`[after_llm_fetch] detect failed; passthrough buffered events: ${t instanceof Error?t.message:String(t)}`))}h(t),t.close(),e.logger.info(x(`[llm_fetch] total_elapsed=${Date.now()-a}ms request_id=${n}`))}catch(e){try{await c.cancel()}catch{}t.error(e)}}}),_=new Headers(r.headers);return _.delete(`content-length`),_.set(`content-type`,`text/event-stream; charset=utf-8`),new Response(g,{status:r.status,statusText:r.statusText,headers:_})}function kt(e,t){let n=globalThis.fetch;if(typeof n!=`function`){e.logger.warn(x(`[before_llm_fetch] global.fetch is unavailable; skipping interceptor`));return}globalThis.__openclawGuardianOriginalFetch||(globalThis.__openclawGuardianOriginalFetch=n,globalThis.fetch=async function(r,i){let a=[r,i],o=r?.toString?.()??``,s=i??{},c=()=>n.call(globalThis,a[0],a[1]);if(a[1]||=s,ft(o))return c();let l,u=null;try{let r=ct(o,st(e.config));if(!r)return e.logger.info(x(`[before_llm_fetch] pass-through: no provider baseUrl match for url=${o}`)),c();e.logger.info(x(`[before_llm_fetch] matched provider=${r.providerId} baseUrl=${r.baseUrl} url=${o}`));let i=ut(s.body);if(!dt(i))return e.logger.info(x(`[before_llm_fetch] pass-through: matched provider=${r.providerId} but request body is not a supported LLM payload shape`)),c();let d={request_id:wt(),url:o,rawBody:lt(s.body)??``,jsonBody:i},f=String(d.request_id);if(u=Date.now(),await t.isHookEnabled(`before_llm_fetch`)){let t=X(`before_llm_fetch`,null,null,d);Ct(e,`before_llm_fetch`,t);let n=bt(await K(e,`before_llm_fetch`,t)),i=xt(n);(i.action===`deny`||i.action===`rewrite`)&&i.output?(s.body=String(i.output),a[1]=s,e.logger.info(x(`[before_llm_fetch] detect effect applied: ${i.action} (use output as new body) provider=${r.providerId}`))):e.logger.info(x(`[before_llm_fetch] detect effect passthrough: effect=${n.effect} provider=${r.providerId}`))}else e.logger.info(x(`[before_llm_fetch] detect skipped: hook disabled by runtime config`));if(l=await n.apply(this,a),!await t.isHookEnabled(`after_llm_fetch`))return u!==null&&e.logger.info(x(`[llm_fetch] total_elapsed=${Date.now()-u}ms request_id=${f}`)),l;if(Dt(l))return await Ot(e,o,f,l,t,u??Date.now());let p=await _t(o,l,await t.getSseChunkSize()),m=X(`after_llm_fetch`,null,null,{...p,request_id:f});Ct(e,`after_llm_fetch`,m);let h=bt(await K(e,`after_llm_fetch`,m)),g=St(h);return(g.action===`deny`||g.action===`rewrite`)&&g.output?(e.logger.info(x(`[after_llm_fetch] detect effect applied: ${g.action} provider=${r.providerId}`)),u!==null&&e.logger.info(x(`[llm_fetch] total_elapsed=${Date.now()-u}ms url=${o}`)),gt(l,g.output,p.isSse)):(e.logger.info(x(`[after_llm_fetch] detect effect passthrough: effect=${h.effect} provider=${r.providerId}`)),u!==null&&e.logger.info(x(`[llm_fetch] total_elapsed=${Date.now()-u}ms request_id=${f}`)),l)}catch(t){return e.logger.error(x(`[llm_fetch] detect request failed, allowing original fetch flow: ${t instanceof Error?t.message:String(t)}`)),l?(u!==null&&e.logger.info(x(`[llm_fetch] total_elapsed=${Date.now()-u}ms request_id=<unknown>`)),l):c()}})}function $(e){return e.replace(/\0/g,``)}function At(e,t){let n=s(),r=new Set,a=e.config??{},c=a?.skills?.load?.extraDirs;if(Array.isArray(c))for(let e of c)typeof e==`string`&&e.trim()&&r.add(o($(e.trim())));r.add(i(n,`.openclaw`,`skills`)),r.add(i(n,`.agents`,`skills`));let l=new Set,u=a?.agents?.defaults?.workspace;if(typeof u==`string`&&u.trim()&&l.add(o($(u.trim()))),Array.isArray(a?.agents?.list))for(let e of a.agents.list)typeof e?.workspace==`string`&&e.workspace.trim()&&l.add(o($(e.workspace.trim())));for(let e of l)r.add(i(e,`skills`)),r.add(i(e,`.agents`,`skills`));let d,f=e.pluginConfig;if(typeof f?.openClawDir==`string`&&f.openClawDir.trim())d=o($(f.openClawDir.trim()));else try{let t=e.runtime?.state?.resolveStateDir?.();typeof t==`string`&&t.trim()&&(d=t)}catch{}d&&(r.add(i(d,`skills`)),r.add(i(d,`.agents`,`skills`)));let p=a?.plugins;if(p?.installs&&typeof p.installs==`object`){for(let e of Object.values(p.installs))if(typeof e?.installPath==`string`&&e.installPath.trim()){let t=i($(e.installPath.trim()),`skills`);r.add(o(t))}}let m=t??i(n,`.openclaw`,`workspace`);r.add(i(m,`.agents`,`skills`)),r.add(i(m,`skills`));let h=Array.from(r),g=h.filter(e=>v(e));return e.logger.info(x(`[skill-scan] resolved ${h.length} skill path(s), ${g.length} exist`)),g}async function jt(e){let t;try{t=await f(e)}catch{return[]}let n=[];for(let r of t){let t=i(e,r),a=await l(t);a.isSymbolicLink()||(a.isDirectory()?n.push(...await jt(t)):a.isFile()&&n.push(t))}return n}const Mt=10*1024*1024;async function Nt(e){let t=await jt(e);if(t.length===0)return _(`sha256`).update(`empty-skill-dir`).digest(`hex`);let r=[],i=0;for(let a of t){let t=await d(a);if(i+=t.length,i>Mt)throw Error(`computeCanonicalHash: skill directory exceeds ${Mt} byte limit: ${e}`);let o=n(a),s=_(`sha256`).update(t).digest(`hex`);r.push(`${o}:${s}`)}return r.sort(),_(`sha256`).update(r.join(`
8
+ `)).digest(`hex`)}function Pt(e){let t=/^name:\s*(.+)$/m.exec(e);return t?t[1].trim():null}function Ft(e){let t=/^---\n([\s\S]*?)\n---/.exec(e);return t?t[1]:``}async function It(e,t){let n;try{n=await f(t,{withFileTypes:!0,encoding:`utf8`})}catch{return[]}let r=[];for(let a of n){if(!a.isDirectory())continue;let n=i(t,a.name),o=i(n,`SKILL.md`);try{let e=Pt(Ft(await d(o,`utf-8`)))||a.name,t=await Nt(n);r.push({dirName:a.name,dirPath:n,filePath:o,skillName:e,skillHash:t})}catch(t){t instanceof Error&&t.message.includes(`byte limit`)&&e.logger.warn(x(`[skill-scan] skipping skill '${a.name}': ${t.message}`))}}return r}async function Lt(e,t){let n=At(e,t);e.logger.info(x(`[skill-scan] scanning ${n.length} skill location(s)`));let r=new Map;for(let t of n){let n=await It(e,t);n.length>0&&e.logger.info(x(`[skill-scan] ${t}: ${n.length} skill(s)`));for(let e of n)r.set(e.skillName,e)}let i=Array.from(r.values());return e.logger.info(x(`[skill-scan] scan complete: ${i.length} unique skill(s) across all locations`)),i}function Rt(e,t,n,r,i){e[t]={...n,skill_name:r.skill_name,skill_hash:r.skill_hash,is_detected:i,last_detect_ts:Date.now()}}async function zt(e,t){e.logger.info(x(`[skill-scan] starting skill scan`));let n=Date.now(),r=Ae(t),i=await Lt(e,t);if(i.length===0){e.logger.info(x(`[skill-scan] no skills found, skipping detection`));return}let a=Be(await Re(e,r),i);e.logger.info(x(`[skill-scan] merged state: ${Object.keys(a).length} skill(s)`));let o=new Map(i.map(e=>[e.dirName,e])),s=[];for(let[t,n]of Object.entries(a))if(o.get(t)){if(Pe(n)){e.logger.warn(x(`[skill-scan] ${n.skill_name}: skill_hash missing, skipping`));continue}n.is_detected||(e.logger.info(x(`[skill-scan] ${n.skill_name}: not detected, queuing`)),s.push({dirName:t,entry:n,entity:{skill_name:n.skill_name,skill_hash:n.skill_hash}}))}if(e.logger.info(x(`[skill-scan] ${s.length} skill(s) need detection`)),s.length===0){await ze(e,a,r),e.logger.info(x(`[skill-scan] skill scan complete (nothing to detect) total_elapsed=${Date.now()-n}ms scanned=${i.length}`));return}let c={};for(let{dirName:e}of s)c[e]=a[e];let l={},u=!1;try{l=await Ge(e,c),e.logger.info(x(`[skill-scan] batch_check result: ${JSON.stringify(l)}`))}catch(t){e.logger.error(x(`[skill-scan] batch_check_detection failed: ${t instanceof Error?t.message:String(t)}`)),u=!0}for(let{dirName:t,entry:n,entity:r}of s)l[Z(r.skill_hash)]===!0&&(Rt(a,t,n,r,!0),e.logger.info(x(`[skill-scan] ${r.skill_name}: already known by server (batch_check)`)));if(u){e.logger.warn(x(`[skill-scan] skipping individual detect calls: batch_check_detection was unreachable`)),await ze(e,a,r),e.logger.info(x(`[skill-scan] skill scan complete (partial — batch_check failed) total_elapsed=${Date.now()-n}ms scanned=${i.length}`));return}for(let{dirName:t,entry:n,entity:r}of s){if(l[r.skill_hash]===!0)continue;let n=o.get(t);if(n)try{let i=await Ye(e,n.dirPath,r);Rt(a,t,a[t],r,i),e.logger.info(x(`[skill-scan] detect result for ${r.skill_name}: is_detected=${i}`))}catch(n){e.logger.error(x(`[skill-scan] detect failed for ${r.skill_name}: ${n instanceof Error?n.message:String(n)}`)),Rt(a,t,a[t],r,!1)}}await ze(e,a,r),e.logger.info(x(`[skill-scan] skill scan complete total_elapsed=${Date.now()-n}ms scanned=${i.length} to_detect=${s.length}`))}async function Bt(e,t,n,r){e.logger.info(x(`[gateway_start] gateway ready on port=${n.port} ctx=${JSON.stringify(r)}`))}function Vt(e,t){let n=null,r=!1,i=!1,a;async function o(){if(i)return;let s=await t.getSkillScanIntervalMs();e.logger.info(x(`[skill-scan-service] next scan in ${s/1e3}s`)),n=setTimeout(async()=>{if(!i){if(!await t.isSkillDetectEnabled()){e.logger.info(x(`[skill-scan-service] periodic scan skipped: skill_detect disabled`)),await o();return}if(r){e.logger.info(x(`[skill-scan-service] periodic scan skipped: previous scan still running`)),await o();return}e.logger.info(x(`[skill-scan-service] periodic scan triggered`)),r=!0,zt(e,a).catch(t=>{e.logger.error(x(`[skill-scan-service] periodic scan failed: ${t instanceof Error?t.message:String(t)}`))}).finally(()=>{r=!1,o()})}},s),n.unref()}return{id:`openclaw-guardian-skill-scan`,async start(n){a=n.workspaceDir,e.logger.info(x(`[skill-scan-service] starting with workspaceDir=${a??`(default)`}`)),i=!1,await t.isSkillDetectEnabled()&&(e.logger.info(x(`[skill-scan-service] running initial skill scan`)),r=!0,zt(e,a).catch(t=>{e.logger.error(x(`[skill-scan-service] initial scan failed: ${t instanceof Error?t.message:String(t)}`))}).finally(()=>{r=!1})),await o()},async stop(t){i=!0,n&&=(clearTimeout(n),null),e.logger.info(x(`[skill-scan-service] stopped`))}}}function Ht(e,t){e.on(`gateway_start`,async(n,r)=>{await Bt(e,t,n,r)}),e.registerService(Vt(e,t))}const Ut=[...[`before_tool_call`,`after_tool_call`,`before_llm_fetch`,`after_llm_fetch`,`llm_input`,`llm_output`],`skill_detect`];function Wt(){return Object.fromEntries(Ut.map(e=>[e,!1]))}function Gt(e){let t=Wt(),n=e&&typeof e==`object`?e:{};for(let e of Ut)t[e]=!!n[e];return t}function Kt(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):1}function qt(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):600}function Jt(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):900}function Yt(e){return{enabled:!1,hook_toggles:Wt(),sse_chunk_size:1,skill_scan_duration_second:900,query_duration_second:600,reason:e}}function Xt(e){let t=e&&typeof e==`object`?e:{},n=t.enabled===void 0?!0:!!t.enabled;return{enabled:n,hook_toggles:n?Gt(t.hook_toggles):Wt(),sse_chunk_size:Kt(t.sse_chunk_size),skill_scan_duration_second:Jt(t.skill_scan_duration_second),query_duration_second:qt(t.query_duration_second),reason:n?`remote`:`remote_disabled`}}function Zt(e){return st(e.config).map(e=>e.baseUrl)}async function Qt(e){let t={source:`miaoda`,base_url_list:Zt(e)};return Xt(await G(e,`runtime_config`,se(e),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)},H))}function $t(e){let t=Yt(`not_initialized`),n=!1,r=null,i=null;async function a(){let r=null;for(let i=1;i<=3;i+=1)try{let r=await Qt(e);return t=r,n=!0,e.logger.debug?.(x(`[runtime_config] initial config loaded on attempt=${i} enabled_hooks=${JSON.stringify(r.hook_toggles)}`)),t}catch(t){r=t;let n=V(t);if(e.logger.error(x(`[runtime_config] initial config load failed attempt=${i} errorCode=${n}: ${t instanceof Error?t.message:String(t)}`)),n===`SERVER`||n===`PARSE`)break}return t=Yt(`initial_fetch_failed`),e.logger.warn(x(`[runtime_config] initial config unavailable after 3 attempts; detection disabled by default${r?`: ${r instanceof Error?r.message:String(r)}`:``}`)),t}async function o(){try{let r=await Qt(e);return t=r,n=!0,e.logger.debug?.(x(`[runtime_config] config refreshed enabled_hooks=${JSON.stringify(r.hook_toggles)} sse_chunk_size=${r.sse_chunk_size}`)),t}catch(r){let i=V(r);return n?(e.logger.error(x(`[runtime_config] refresh failed (errorCode=${i}); keeping previous config: ${r instanceof Error?r.message:String(r)}`)),t):(e.logger.error(x(`[runtime_config] refresh failed before first successful load (errorCode=${i}): ${r instanceof Error?r.message:String(r)}`)),t=Yt(`refresh_failed_${i}`),t)}}function s(){r&&clearTimeout(r);let n=t.query_duration_second*1e3;e.logger.debug?.(x(`[runtime_config] next config refresh in ${t.query_duration_second}s`)),r=setTimeout(()=>{e.logger.debug?.(x(`[runtime_config] refresh loop fired`)),o().catch(t=>{e.logger.error(x(`[runtime_config] refresh loop failed: ${t instanceof Error?t.message:String(t)}`))}).finally(()=>{s()})},n),r.unref()}function c(){return i||=a().catch(n=>(e.logger.error(x(`[runtime_config] initialize failed: ${n instanceof Error?n.message:String(n)}`)),t)).finally(()=>{s()}),i}return{async isHookEnabled(e){return await c(),!!(t?.enabled&&t?.hook_toggles?.[e])},async isSkillDetectEnabled(){return await c(),!!(t?.enabled&&t?.hook_toggles?.skill_detect)},async getSseChunkSize(){return await c(),Kt(t?.sse_chunk_size)},async getSkillScanIntervalMs(){return await c(),Jt(t?.skill_scan_duration_second)*1e3}}}var en=t({id:`openclaw-guardian-plugin`,name:`OpenClaw Guardian Plugin`,description:`Reports OpenClaw hook payloads to the trust_layer detect service with remote hook toggles.`,register(e){if(!N(e)){e.logger.debug?.(x(`[plugin] missing Feishu appId/appSecret from api.config.channels.feishu or pluginConfig; skip all hooks and reporting`));return}let t=$t(e);kt(e,t),at(e,t),Ht(e,t)}});export{en as default};
@@ -2,7 +2,7 @@
2
2
  "id": "openclaw-guardian-plugin",
3
3
  "name": "OpenClaw Guardian Plugin",
4
4
  "description": "Reports OpenClaw hook payloads to security_plugin config and detect endpoints.",
5
- "version": "2026.4.10",
5
+ "version": "2026.5.7",
6
6
  "uiHints": {
7
7
  "appId": {
8
8
  "label": "Feishu App ID",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-tns/openclaw-guardian-plugin",
3
- "version": "2026.4.16",
3
+ "version": "2026.5.7",
4
4
  "type": "module",
5
5
  "description": "OpenClaw plugin that reports hook payloads to the security_plugin detect service with remote hook toggles.",
6
6
  "keywords": ["openclaw", "plugin", "security", "guardian"],