@atbash/atbash-openclaw 0.1.19-dev.1 → 0.1.19-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ If you're not using OpenClaw and want to use ATBASH from your own code, install
7
7
  ## Install
8
8
 
9
9
  ```bash
10
- openclaw plugins install @atbash/atbash-openclaw@0.1.17-dev.6
10
+ openclaw plugins install @atbash/atbash-openclaw@0.1.19-dev.1
11
11
  ```
12
12
 
13
13
  **The judge endpoint and chain ids are compiled into the build**, so the version selects the environment. A `-dev.N` version targets the development environment. `openclaw plugins list` shows which you have. No configuration repoints a build afterwards — the wrong one loads cleanly, fires its hook, and then fails every judge call because the agent does not exist on the chain that build targets. Organization names are not unique across environments, so a resolving org name is not proof the build is right.
@@ -132,6 +132,7 @@ plugin loads unconfigured and audits nothing.
132
132
  | `memoryFilePath` | string | `<memoryWorkspaceDir>/MEMORY.md` | Explicit path to the agent's MEMORY.md. Overrides the `memoryWorkspaceDir`-relative default. Supports `~/`. |
133
133
  | `memorySyncTTLMs` | integer | `30000` | How long (ms) to trust the locally cached memory chain pointer before re-fetching from the chain. Lower values increase freshness at the cost of more chain queries. |
134
134
  | `memoryRollbackMinScore` | integer (1–10) | `1` | Block memory reads when a rolled-back version's safety score is below this threshold. Default `1` means warn only, never block. Raise to e.g. `3` to refuse reading poisoned rollbacks. |
135
+ | `judgeTimeoutMs` | integer | — | Max milliseconds to wait for a judge or memory-guard response before treating it as a timeout. When triggered, the plugin applies the same fail-closed/open logic as any other error (`enforceDecision` controls the outcome). Unset means the plugin waits as long as the host allows. Set to e.g. `12000` when the host has a hard hook deadline and you want the plugin to fail gracefully instead of being killed mid-await. |
135
136
 
136
137
  ## Updating
137
138
 
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";var y=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var I=(t,e)=>{for(var n in e)y(t,n,{get:e[n],enumerable:!0})},v=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of P(e))!$.call(t,r)&&r!==n&&y(t,r,{get:()=>e[r],enumerable:!(o=N(e,r))||o.enumerable});return t};var D=t=>v(y({},"__esModule",{value:!0}),t);var Z={};I(Z,{default:()=>L});module.exports=D(Z);var R=require("os"),m=require("@atbash/sdk");var h="atbash-openclaw",j=["openclaw","atbash-plugin"];function E(t){return t.config?.plugins?.entries?.[h]?.config??{}}function x(t){let e=t.config?.plugins,n=e?.entries??{},o=Array.isArray(e?.allow)?e.allow:[],r=j.filter(a=>n[a]!==void 0||o.includes(a));if(r.length===0)return;let s=n[h]?.config!==void 0;t.logger?.warn?.(`[atbash] found config under former plugin id${r.length>1?"s":""} ${r.map(a=>`"${a}"`).join(", ")} \u2014 this plugin's id is "${h}" and those entries are ignored`+(s?". Remove them to avoid confusion.":`. No "${h}" config found, so the plugin is running on defaults \u2014 move your settings under "${h}".`),{formerIds:r,configured:s})}var F={"0xdac17f958d2ee523a2206206994597c13d831ec7":"USDT","0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48":"USDC","0x6b175474e89094c44da98b954eedeac495271d0f":"DAI","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2":"WETH","0x2260fac5e5542a773aa44fbcfedf7c193bc2c599":"WBTC","0x1f9840a85d5af5bf1d1762f925bdaddc4201f984":"UNI","0x514910771af9ca656af840dff83e8264ecf986ca":"LINK","0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9":"AAVE","0xb0df6379ba1692841965a0745ac1bd3046d79ba3":"ATBASH","0xe9c094187219d9a29382c1a36fc43619c9257777":"ATBASH","0xf8b071428558c657a7a9aa1c43e152e75dd77777":"ATBASH"},A=/\b(0x[a-fA-F0-9]{40})\b/,M=/(0x[a-fA-F0-9]{40})/,C=/\b(transfer|send|swap|approve|erc20)\b/i;function O(t){if(!t)return"ETH";let e=t.toLowerCase(),n=M.exec(e);return n?F[n[1].toLowerCase()]??"other":e==="c60"||e==="eth"?"ETH":e==="atbash"?"ATBASH":e==="usdt"||e==="tether"?"USDT":e==="usdc"?"USDC":"other"}function w(t,...e){for(let n of e){let o=t[n];if(typeof o=="string"&&o.trim())return o.trim()}}function H(t,e){let n=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0,o=n?w(n,"command","cmd","shell_command"):void 0,r=C.test(t),s=o?C.test(o):!1,a=o?A.test(o):!1;if(!r&&!s&&!a)return;let c=b=>o?new RegExp(`--${b}[= ]+(\\S+)`).exec(o)?.[1]:void 0,u=(n?w(n,"token","token_address","asset","currency"):void 0)??c("token");if(!u&&o){let b=A.exec(o);b&&(u=b[1])}let g=(n?w(n,"to","recipient","destination"):void 0)??c("to")??c("recipient"),f=(n?w(n,"amount","value","qty"):void 0)??c("amount"),d=O(u??""),i=o??t;return{operation:/\bswap\b/i.test(i)?"swap":/\b(approve|erc20)\b/i.test(i)?"approve":"transfer",asset:d,amount:f,recipient_status:g?"external":"unspecified",note:"canonicalized pre-judge; raw 0x addresses omitted (redacted upstream)"}}function _(t,e){let n=t??{},o=n.toolName??e.tool?.name??e.toolName??e.name??"unknown",r=n.params??e.params??n.args??e.args??n.arguments??e.arguments,s=JSON.stringify({tool_name:o});return{toolName:o,args:r,context:s,resolved:H(o,r)}}var W=["memory.md","dreams.md","claude.md","agents.md","/.openclaw/","/.claude/projects/","/memory/"];function S(t){let e=t.replace(/\\/g,"/").toLowerCase();return W.some(n=>e.includes(n))}var B=/^\*\*\* (Update|Add|Delete) File:\s*(.+?)\s*$/mg;function U(t,e){let n=t.split(`
2
- `),o=!1,r=[];for(let s of n){let a=/^\*\*\* (?:Update|Add|Delete) File:\s*(.+?)\s*$/.exec(s);if(a){o=a[1]===e;continue}o&&(s.startsWith("*** ")||s.startsWith("@@")||s.startsWith("+")&&r.push(s.slice(1)))}return r.join(`
3
- `)}function z(t){if(!t||typeof t!="object")return null;let e=t;if((e.toolName??e.tool_name??"").toString().toLowerCase()!=="apply_patch")return null;let o=e.params??e.args??e.arguments??{},r=o.input;if(typeof r!="string"||r.length===0)return null;let s=r.replace(/\r\n/g,`
4
- `),a=new RegExp(B.source,"mg"),c,u,g;for(;(g=a.exec(s))!==null;){let[,i,l]=g;if(i!=="Delete"&&S(l)){c=i,u=l;break}}if(!c||!u)return null;let f=U(s,u);return{...e,toolName:c==="Add"?"write":"edit",params:{...o,file_path:u,content:f,new_string:f}}}function p(t){let e=t.trim();return e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}var K=/[|;&`$]|<\(|\)/;function G(t){return K.test(t)}function V(t){if(G(t))return null;let e=t.trim(),n=/^grep\b(?:\s+-\S+)*\s+\S+\s+(.+)$/.exec(e);if(n)return p(n[1]);let o=/^sed\b(?!\s+-i\b)(?:\s+-\S+)*\s+\S+\s+(.+)$/.exec(e);if(o)return p(o[1]);let r=/^(?:cat|less|more|head|tail)\b(?:\s+-\S+(?:\s+\S+)?)*\s+(.+)$/.exec(e);return r?p(r[1]):null}function q(t){if(/[|;&`$]|<\(|\)/.test(t))return null;let e=t.trim(),n=/^(?:echo|printf)\s+(.+?)\s*>>?\s*(\S+)\s*$/.exec(e);if(n)return{content:p(n[1]),path:p(n[2])};let o=/^tee\b(?:\s+-\S+)*\s+(\S+)\s*$/.exec(e);if(o)return{content:"",path:p(o[1])};let r=/^sed\s+-i(?:\s+-\S+)*\s+(\S+)\s+(\S+)\s*$/.exec(e);if(r)return{content:p(r[1]),path:p(r[2])};let s=/^awk\s+-i\s+inplace\b.*\s+(\S+)\s*$/.exec(e);if(s)return{content:"",path:p(s[1])};let a=/^(?:cp|mv)\b(?:\s+-\S+)*\s+\S+\s+(\S+)\s*$/.exec(e);return a?{content:"",path:p(a[1])}:null}var J=new Set(["exec","bash","shell","run_command","run_bash"]);function Y(t){if(!t||typeof t!="object")return null;let e=t,n=(e.toolName??e.tool_name??"").toString().toLowerCase();if(!J.has(n))return null;let r=e.params??e.args??e.arguments??{},s=r.command??r.cmd??r.script,a=typeof s=="string"?s:null;if(!a||a.length===0)return null;let c=q(a);if(c&&S(c.path))return{...e,toolName:"write",params:{...r,file_path:c.path,content:c.content}};let u=V(a);return u&&S(u)?{...e,toolName:"read",params:{...r,path:u}}:null}function k(t){return z(t)??Y(t)??t}function T(t){return t.replace(/^~(?=\/|$)/,(0,R.homedir)())}function X(t){return t.memoryWorkspaceDir?T(t.memoryWorkspaceDir):process.cwd()}function Q(t){if(t.judgeEndpoint)return t.judgeEndpointPolicy==="self-hosted"?{policy:"self-hosted",endpoint:t.judgeEndpoint,verifyPubKey:t.judgeVerifyPubKey??""}:{policy:"default",endpoint:t.judgeEndpoint}}function L(t){let e=t,n=E(e);if(x(e),n.enabled===!1){e.logger?.info?.("[atbash] plugin disabled via config");return}(0,m.setupTelemetry)({enabled:!0,source:"plugin:openclaw"}),process.once("beforeExit",()=>(0,m.shutdownTelemetry)()),process.once("SIGINT",()=>(0,m.shutdownTelemetry)().finally(()=>process.exit(0))),process.once("SIGTERM",()=>(0,m.shutdownTelemetry)().finally(()=>process.exit(0)));let o;try{o=m.Atbash.fromConfig({judge:Q(n),keyPath:n.chromiaSecretPath,orgName:n.orgName,failClosed:n.enforceDecision!==!1,logger:e.logger})}catch(a){let c=a instanceof Error?a.message:String(a);throw e.logger?.warn?.("[atbash] init failed",{error:c}),a}let r=n.enforceDecision!==!1;e.logger?.info?.("[atbash] plugin loaded",{enforceDecision:r});let s=(0,m.createMemoryGuardManager)({auth:o.auth,workspaceDir:X(n),memoryFilePath:n.memoryFilePath?T(n.memoryFilePath):void 0,ttlMs:n.memorySyncTTLMs,rollbackMinScore:n.memoryRollbackMinScore,memoryPathPatterns:n.memoryPathPatterns,judgeEndpoint:n.judgeEndpoint,judgeVerifyPubKey:n.judgeVerifyPubKey,orgName:n.orgName,enforce:r,debug:!!n.debug,hostLogger:e.logger});if(s.runBootProbe().catch(a=>{e.logger?.warn?.("[atbash] boot probe failed",{error:a instanceof Error?a.message:String(a)})}),!e.on){e.logger?.warn?.("[atbash] on() API not available");return}e.on("before_tool_call",async(a,c)=>{let u=k(a),g;try{g=await s.handleBeforeToolCall(u,c)}catch(i){let l=i instanceof Error?i.message:String(i);return e.logger?.warn?.("[atbash] memory guard error",{error:l}),i instanceof m.MemoryIntegrityError||r?{block:!0,blockReason:`Memory guard error: ${l}`,allow:!1,reason:`Memory guard error: ${l}`}:{allow:!0}}if(g)return g;let f;try{f=await o.auditToolCall(_(a,c))}catch(i){let l=i instanceof Error?i.message:String(i);return e.logger?.warn?.("[atbash] unexpected error",{error:l}),r?{block:!0,blockReason:`Atbash unavailable: ${l}`,allow:!1,reason:`Atbash unavailable: ${l}`}:{allow:!0}}let d=f.reason??"";switch(f.verdict){case"BLOCK":return e.logger?.warn?.("[atbash] BLOCK",{reason:d}),r?{block:!0,blockReason:d,allow:!1,reason:d}:{allow:!0};case"HOLD":{let i=["Action held for operator review. The agent will not be jailed \u2014 please approve or reject this request from the Atbash dashboard, then ask the agent to try again.",`Reason: ${d}`];f.toolCallId&&i.push(`Tool Call ID: ${f.toolCallId}`);let l=i.join(`
5
- `);return e.logger?.warn?.("[atbash] HOLD",{reason:d,toolCallId:f.toolCallId}),r?{block:!0,blockReason:l,allow:!1,reason:l}:{allow:!0}}case"ERROR":return e.logger?.warn?.("[atbash] ERROR",{reason:d}),r?{block:!0,blockReason:d,allow:!1,reason:d}:{allow:!0};case"ALLOW":if(f.allow===!0)return e.logger?.info?.("[atbash] ALLOW",{reason:d}),{allow:!0};break}{let i=String(f.verdict);if(e.logger?.warn?.("[atbash] unusable decision",{verdict:i,allow:f.allow,reason:d}),!r)return{allow:!0};let l=`Blocked (unusable Atbash decision ${i}): ${d}`;return{block:!0,blockReason:l,allow:!1,reason:l}}})}
1
+ "use strict";var y=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var v=(t,e)=>{for(var n in e)y(t,n,{get:e[n],enumerable:!0})},D=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of N(e))!I.call(t,o)&&o!==n&&y(t,o,{get:()=>e[o],enumerable:!(r=L(e,o))||r.enumerable});return t};var j=t=>D(y({},"__esModule",{value:!0}),t);var ee={};v(ee,{default:()=>$});module.exports=j(ee);var R=require("os"),m=require("@atbash/sdk");var b="atbash-openclaw",M=["openclaw","atbash-plugin"];function E(t){return t.config?.plugins?.entries?.[b]?.config??{}}function x(t){let e=t.config?.plugins,n=e?.entries??{},r=Array.isArray(e?.allow)?e.allow:[],o=M.filter(a=>n[a]!==void 0||r.includes(a));if(o.length===0)return;let s=n[b]?.config!==void 0;t.logger?.warn?.(`[atbash] found config under former plugin id${o.length>1?"s":""} ${o.map(a=>`"${a}"`).join(", ")} \u2014 this plugin's id is "${b}" and those entries are ignored`+(s?". Remove them to avoid confusion.":`. No "${b}" config found, so the plugin is running on defaults \u2014 move your settings under "${b}".`),{formerIds:o,configured:s})}var F={"0xdac17f958d2ee523a2206206994597c13d831ec7":"USDT","0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48":"USDC","0x6b175474e89094c44da98b954eedeac495271d0f":"DAI","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2":"WETH","0x2260fac5e5542a773aa44fbcfedf7c193bc2c599":"WBTC","0x1f9840a85d5af5bf1d1762f925bdaddc4201f984":"UNI","0x514910771af9ca656af840dff83e8264ecf986ca":"LINK","0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9":"AAVE","0xb0df6379ba1692841965a0745ac1bd3046d79ba3":"ATBASH","0xe9c094187219d9a29382c1a36fc43619c9257777":"ATBASH","0xf8b071428558c657a7a9aa1c43e152e75dd77777":"ATBASH"},A=/\b(0x[a-fA-F0-9]{40})\b/,O=/(0x[a-fA-F0-9]{40})/,C=/\b(transfer|send|swap|approve|erc20)\b/i;function H(t){if(!t)return"ETH";let e=t.toLowerCase(),n=O.exec(e);return n?F[n[1].toLowerCase()]??"other":e==="c60"||e==="eth"?"ETH":e==="atbash"?"ATBASH":e==="usdt"||e==="tether"?"USDT":e==="usdc"?"USDC":"other"}function w(t,...e){for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r.trim()}}function W(t,e){let n=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0,r=n?w(n,"command","cmd","shell_command"):void 0,o=C.test(t),s=r?C.test(r):!1,a=r?A.test(r):!1;if(!o&&!s&&!a)return;let c=l=>r?new RegExp(`--${l}[= ]+(\\S+)`).exec(r)?.[1]:void 0,d=(n?w(n,"token","token_address","asset","currency"):void 0)??c("token");if(!d&&r){let l=A.exec(r);l&&(d=l[1])}let g=(n?w(n,"to","recipient","destination"):void 0)??c("to")??c("recipient"),h=(n?w(n,"amount","value","qty"):void 0)??c("amount"),f=H(d??""),u=r??t;return{operation:/\bswap\b/i.test(u)?"swap":/\b(approve|erc20)\b/i.test(u)?"approve":"transfer",asset:f,amount:h,recipient_status:g?"external":"unspecified",note:"canonicalized pre-judge; raw 0x addresses omitted (redacted upstream)"}}function T(t,e){let n=t??{},r=n.toolName??e.tool?.name??e.toolName??e.name??"unknown",o=n.params??e.params??n.args??e.args??n.arguments??e.arguments,s=JSON.stringify({tool_name:r});return{toolName:r,args:o,context:s,resolved:W(r,o)}}var B=["memory.md","dreams.md","claude.md","agents.md","/.openclaw/","/.claude/projects/","/memory/"];function S(t){let e=t.replace(/\\/g,"/").toLowerCase();return B.some(n=>e.includes(n))}var U=/^\*\*\* (Update|Add|Delete) File:\s*(.+?)\s*$/mg;function z(t,e){let n=t.split(`
2
+ `),r=!1,o=[];for(let s of n){let a=/^\*\*\* (?:Update|Add|Delete) File:\s*(.+?)\s*$/.exec(s);if(a){r=a[1]===e;continue}r&&(s.startsWith("*** ")||s.startsWith("@@")||s.startsWith("+")&&o.push(s.slice(1)))}return o.join(`
3
+ `)}function K(t){if(!t||typeof t!="object")return null;let e=t;if((e.toolName??e.tool_name??"").toString().toLowerCase()!=="apply_patch")return null;let r=e.params??e.args??e.arguments??{},o=r.input;if(typeof o!="string"||o.length===0)return null;let s=o.replace(/\r\n/g,`
4
+ `),a=new RegExp(U.source,"mg"),c,d,g;for(;(g=a.exec(s))!==null;){let[,u,i]=g;if(u!=="Delete"&&S(i)){c=u,d=i;break}}if(!c||!d)return null;let h=z(s,d);return{...e,toolName:c==="Add"?"write":"edit",params:{...r,file_path:d,content:h,new_string:h}}}function p(t){let e=t.trim();return e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}var G=/[|;&`$]|<\(|\)/;function V(t){return G.test(t)}function q(t){if(V(t))return null;let e=t.trim(),n=/^grep\b(?:\s+-\S+)*\s+\S+\s+(.+)$/.exec(e);if(n)return p(n[1]);let r=/^sed\b(?!\s+-i\b)(?:\s+-\S+)*\s+\S+\s+(.+)$/.exec(e);if(r)return p(r[1]);let o=/^(?:cat|less|more|head|tail)\b(?:\s+-\S+(?:\s+\S+)?)*\s+(.+)$/.exec(e);return o?p(o[1]):null}function J(t){if(/[|;&`$]|<\(|\)/.test(t))return null;let e=t.trim(),n=/^(?:echo|printf)\s+(.+?)\s*>>?\s*(\S+)\s*$/.exec(e);if(n)return{content:p(n[1]),path:p(n[2])};let r=/^tee\b(?:\s+-\S+)*\s+(\S+)\s*$/.exec(e);if(r)return{content:"",path:p(r[1])};let o=/^sed\s+-i(?:\s+-\S+)*\s+(\S+)\s+(\S+)\s*$/.exec(e);if(o)return{content:p(o[1]),path:p(o[2])};let s=/^awk\s+-i\s+inplace\b.*\s+(\S+)\s*$/.exec(e);if(s)return{content:"",path:p(s[1])};let a=/^(?:cp|mv)\b(?:\s+-\S+)*\s+\S+\s+(\S+)\s*$/.exec(e);return a?{content:"",path:p(a[1])}:null}var Y=new Set(["exec","bash","shell","run_command","run_bash"]);function X(t){if(!t||typeof t!="object")return null;let e=t,n=(e.toolName??e.tool_name??"").toString().toLowerCase();if(!Y.has(n))return null;let o=e.params??e.args??e.arguments??{},s=o.command??o.cmd??o.script,a=typeof s=="string"?s:null;if(!a||a.length===0)return null;let c=J(a);if(c&&S(c.path))return{...e,toolName:"write",params:{...o,file_path:c.path,content:c.content}};let d=q(a);return d&&S(d)?{...e,toolName:"read",params:{...o,path:d}}:null}function _(t){return K(t)??X(t)??t}function P(t){return t.replace(/^~(?=\/|$)/,(0,R.homedir)())}function k(t,e){return Promise.race([t,new Promise((n,r)=>setTimeout(()=>r(new Error(`judge timed out after ${e}ms`)),e))])}function Q(t){return t.memoryWorkspaceDir?P(t.memoryWorkspaceDir):process.cwd()}function Z(t){if(t.judgeEndpoint)return t.judgeEndpointPolicy==="self-hosted"?{policy:"self-hosted",endpoint:t.judgeEndpoint,verifyPubKey:t.judgeVerifyPubKey??""}:{policy:"default",endpoint:t.judgeEndpoint}}function $(t){let e=t,n=E(e);if(x(e),n.enabled===!1){e.logger?.info?.("[atbash] plugin disabled via config");return}(0,m.setupTelemetry)({enabled:!0,source:"plugin:openclaw"}),process.once("beforeExit",()=>(0,m.shutdownTelemetry)()),process.once("SIGINT",()=>(0,m.shutdownTelemetry)().finally(()=>process.exit(0))),process.once("SIGTERM",()=>(0,m.shutdownTelemetry)().finally(()=>process.exit(0)));let r;try{r=m.Atbash.fromConfig({judge:Z(n),keyPath:n.chromiaSecretPath,orgName:n.orgName,failClosed:n.enforceDecision!==!1,logger:e.logger})}catch(a){let c=a instanceof Error?a.message:String(a);throw e.logger?.warn?.("[atbash] init failed",{error:c}),a}let o=n.enforceDecision!==!1;e.logger?.info?.("[atbash] plugin loaded",{enforceDecision:o});let s=(0,m.createMemoryGuardManager)({auth:r.auth,workspaceDir:Q(n),memoryFilePath:n.memoryFilePath?P(n.memoryFilePath):void 0,ttlMs:n.memorySyncTTLMs,rollbackMinScore:n.memoryRollbackMinScore,memoryPathPatterns:n.memoryPathPatterns,judgeEndpoint:n.judgeEndpoint,judgeVerifyPubKey:n.judgeVerifyPubKey,orgName:n.orgName,enforce:o,debug:!!n.debug,hostLogger:e.logger});if(s.runBootProbe().catch(a=>{e.logger?.warn?.("[atbash] boot probe failed",{error:a instanceof Error?a.message:String(a)})}),!e.on){e.logger?.warn?.("[atbash] on() API not available");return}e.on("before_tool_call",async(a,c)=>{let d=_(a),g=n.judgeTimeoutMs,h;try{let i=s.handleBeforeToolCall(d,c);h=await(g?k(i,g):i)}catch(i){let l=i instanceof Error?i.message:String(i);return e.logger?.warn?.("[atbash] memory guard error",{error:l}),i instanceof m.MemoryIntegrityError||o?{block:!0,blockReason:`Memory guard error: ${l}`,allow:!1,reason:`Memory guard error: ${l}`}:{allow:!0}}if(h)return h;let f;try{let i=r.auditToolCall(T(a,c));f=await(g?k(i,g):i)}catch(i){let l=i instanceof Error?i.message:String(i);return e.logger?.warn?.("[atbash] unexpected error",{error:l}),o?{block:!0,blockReason:`Atbash unavailable: ${l}`,allow:!1,reason:`Atbash unavailable: ${l}`}:{allow:!0}}let u=f.reason??"";switch(f.verdict){case"BLOCK":return e.logger?.warn?.("[atbash] BLOCK",{reason:u}),o?{block:!0,blockReason:u,allow:!1,reason:u}:{allow:!0};case"HOLD":{let i=["Action held for operator review. The agent will not be jailed \u2014 please approve or reject this request from the Atbash dashboard, then ask the agent to try again.",`Reason: ${u}`];f.toolCallId&&i.push(`Tool Call ID: ${f.toolCallId}`);let l=i.join(`
5
+ `);return e.logger?.warn?.("[atbash] HOLD",{reason:u,toolCallId:f.toolCallId}),o?{block:!0,blockReason:l,allow:!1,reason:l}:{allow:!0}}case"ERROR":return e.logger?.warn?.("[atbash] ERROR",{reason:u}),o?{block:!0,blockReason:u,allow:!1,reason:u}:{allow:!0};case"ALLOW":if(f.allow===!0)return e.logger?.info?.("[atbash] ALLOW",{reason:u}),{allow:!0};break}{let i=String(f.verdict);if(e.logger?.warn?.("[atbash] unusable decision",{verdict:i,allow:f.allow,reason:u}),!o)return{allow:!0};let l=`Blocked (unusable Atbash decision ${i}): ${u}`;return{block:!0,blockReason:l,allow:!1,reason:l}}})}
@@ -24,7 +24,8 @@
24
24
  "memoryWorkspaceDir": { "type": "string" },
25
25
  "memoryFilePath": { "type": "string" },
26
26
  "memorySyncTTLMs": { "type": "integer", "minimum": 0, "default": 30000 },
27
- "memoryRollbackMinScore": { "type": "integer", "minimum": 1, "maximum": 10, "default": 1 }
27
+ "memoryRollbackMinScore": { "type": "integer", "minimum": 1, "maximum": 10, "default": 1 },
28
+ "judgeTimeoutMs": { "type": "integer", "minimum": 1000 }
28
29
  }
29
30
  },
30
31
  "uiHints": {
@@ -69,6 +70,10 @@
69
70
  "memoryRollbackMinScore": {
70
71
  "label": "Rollback Score Threshold",
71
72
  "placeholder": "Block memory reads when a rolled-back version scores below this (1-10). Default 1 = never block."
73
+ },
74
+ "judgeTimeoutMs": {
75
+ "label": "Judge Timeout (ms)",
76
+ "placeholder": "e.g. 12000 — max ms to wait for a judge response before failing. Unset = no plugin-level limit."
72
77
  }
73
78
  }
74
79
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atbash/atbash-openclaw",
3
- "version": "0.1.19-dev.1",
3
+ "version": "0.1.19-dev.2",
4
4
  "description": "OpenClaw ATBASH tool-audit plugin. Thin adapter that maps OpenClaw's before_tool_call hook onto @atbash/sdk.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -41,7 +41,7 @@
41
41
  ]
42
42
  },
43
43
  "dependencies": {
44
- "@atbash/sdk": "0.15.0-dev.0"
44
+ "@atbash/sdk": "0.15.1-dev.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/node": "^25.7.0",