@atbash/atbash-openclaw 0.1.17-dev.0 → 0.1.17

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,12 +7,9 @@ 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 # production
11
- openclaw plugins install @atbash/atbash-openclaw@dev # development
10
+ openclaw plugins install @atbash/atbash-openclaw
12
11
  ```
13
12
 
14
- **The judge endpoint and chain ids are compiled into the build**, so the npm tag selects the environment. Install the plain tag if your agent was onboarded on production, the `@dev` tag if it was onboarded on development; `openclaw plugins list` shows which you have (a `-dev.N` version is the development build). 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.
15
-
16
13
  The plugin signs audit transactions locally with your agent's secp256k1 private key. The key never leaves your machine; only signed bytes plus the corresponding public key are transmitted.
17
14
 
18
15
  ## Get an agent key
@@ -37,40 +34,37 @@ Contact the ATBASH team to register an agent and obtain a key pair.
37
34
 
38
35
  ## Configure it in OpenClaw
39
36
 
40
- `openclaw plugins install` already recorded where the plugin lives, enabled it, and — if you keep a
41
- `plugins.allow` list — added `atbash-openclaw` to it. Never hand-write the install directory: OpenClaw has
42
- moved it between releases and records whichever it used, which is what it loads from. `openclaw plugins list`
43
- shows the current state.
44
-
45
- All that is left is your configuration. Open `~/.openclaw/openclaw.json` and add, keeping the plugins
46
- already there:
37
+ Open `~/.openclaw/openclaw.json` and add:
47
38
 
48
39
  ```json
49
40
  {
50
41
  "plugins": {
42
+ "allow": [
43
+ "openclaw"
44
+ ],
45
+ "load": {
46
+ "paths": [
47
+ "/Users/<your-username>/.openclaw/extensions/openclaw"
48
+ ]
49
+ },
51
50
  "entries": {
52
- "atbash-openclaw": {
51
+ "openclaw": {
53
52
  "enabled": true,
54
53
  "config": {
55
54
  "enabled": true,
56
55
  "enforceDecision": true,
57
- "chromiaSecretPath": "~/.config/atbash/guard-client-key",
58
- "orgName": "<your org name>"
56
+ "chromiaSecretPath": "~/.config/atbash/guard-client-key"
59
57
  },
60
58
  "hooks": {
61
59
  "allowConversationAccess": true,
62
60
  "allowPromptInjection": true
63
- }
61
+ }
64
62
  }
65
63
  }
66
64
  }
67
65
  }
68
66
  ```
69
67
 
70
- The plugin id is `atbash-openclaw` — it comes from the `id` field in this package's `openclaw.plugin.json`,
71
- not from the npm package name. A `plugins.entries` key that does not match the id is not an error: the
72
- plugin loads unconfigured and audits nothing.
73
-
74
68
  ### Config fields
75
69
 
76
70
  | Field | Type | Default | What it does |
@@ -78,19 +72,18 @@ plugin loads unconfigured and audits nothing.
78
72
  | `enabled` | bool | `true` | Master switch. `false` = plugin returns immediately. |
79
73
  | `enforceDecision` | bool | `true` | Surfaced to logs. The plugin always blocks on `BLOCK`. |
80
74
  | `chromiaSecretPath` | string | `~/.config/atbash/guard-client-key` | Path to the agent key file. Supports `~/`. |
81
- | `orgName` | string | — | Organization the agent was onboarded under, spelled as the dashboard shows it. The plugin resolves which chain to query from this, so it is required when the org is on a private chain. |
82
75
  | `debug` | bool | `false` | When `true`, logs a one-line probe for every `before_tool_call` showing `toolName`, top-level event/ctx/args keys, and whether the call was classified as a memory write. Useful for verifying memory-write classifier coverage against real traffic. Logs shape only — argument values are never printed. |
83
76
 
84
77
  ## Updating
85
78
 
86
79
  ```bash
87
- openclaw plugins update atbash-openclaw
80
+ openclaw plugins update @atbash/atbash-openclaw
88
81
  ```
89
82
 
90
83
  ## Uninstalling
91
84
 
92
85
  ```bash
93
- openclaw plugins uninstall atbash-openclaw
86
+ openclaw plugins uninstall @atbash/atbash-openclaw
94
87
  ```
95
88
 
96
89
  The agent key file at `~/.config/atbash/guard-client-key` is **not** removed — delete it manually if you want to retire the agent identity.
@@ -118,19 +111,11 @@ The agent's own tool execution is unaffected — only the data sent to the judge
118
111
  ## Troubleshooting
119
112
 
120
113
  **Tool calls aren't being audited.**
121
- Check `enabled: true` is set both on the entry (`plugins.entries["atbash-openclaw"].enabled`) and inside `config` (`config.enabled`).
114
+ Check `enabled: true` is set both on the entry (`plugins.entries.openclaw.enabled`) and inside `config` (`config.enabled`).
122
115
 
123
116
  **Every tool call is blocked, even safe ones.**
124
117
  The plugin is fail-closed: any pipeline error blocks. Look for `[atbash] …` warnings in the OpenClaw log. Most often: missing key, expired key, or restricted egress.
125
118
 
126
- ## Maintainer release contract
127
-
128
- Development packages are released only through the protected **Publish development package** GitHub workflow. The workflow requires the `npm` environment, the exact `PUBLISH` confirmation, and npm trusted-publisher configuration for this repository and workflow. It never accepts a registry token from package source.
129
-
130
- The release guard refuses a dirty checkout, reads the live package and SDK tags, chooses a collision-free prerelease, copies only Git-tracked files into a temporary staging tree, pins the exact SDK version there, installs and tests from the staged lockfile, cleans and rebuilds `dist`, validates the tarball, rechecks registry state, publishes, and verifies the resulting `dev` tag. The tracked source manifest is never rewritten by a release.
131
-
132
- Because this repository is private, npm provenance statements are not supported. Trusted publishing still removes long-lived npm tokens; configure the protected npm environment and trusted publisher before enabling the workflow.
133
-
134
119
  ## License
135
120
 
136
121
  Proprietary — all rights reserved. See [LICENSE](https://atbash.ai/license). Commercial licensing inquiries: contact the Atbash team.
package/dist/config.js CHANGED
@@ -1,33 +1,5 @@
1
1
  const PLUGIN_ID = "atbash-openclaw";
2
- /**
3
- * Ids this plugin shipped under before it was renamed. OpenClaw matches
4
- * `plugins.entries` keys against the manifest id, so an entry left under one of
5
- * these is inert — no error, no config, and the plugin runs on defaults. That
6
- * silence is what makes the rename expensive, so we say something instead.
7
- */
8
- const FORMER_PLUGIN_IDS = ["openclaw", "atbash-plugin"];
9
2
  /** @internal */
10
3
  export function readPluginConfig(api) {
11
4
  return api.config?.plugins?.entries?.[PLUGIN_ID]?.config ?? {};
12
5
  }
13
- /**
14
- * Warn when configuration is found under a former plugin id.
15
- *
16
- * @internal
17
- */
18
- export function warnOnFormerIdConfig(api) {
19
- const plugins = api.config?.plugins;
20
- const entries = plugins?.entries ?? {};
21
- const allow = Array.isArray(plugins?.allow) ? plugins.allow : [];
22
- const stale = FORMER_PLUGIN_IDS.filter((id) => entries[id] !== undefined || allow.includes(id));
23
- if (stale.length === 0)
24
- return;
25
- const configured = entries[PLUGIN_ID]?.config !== undefined;
26
- api.logger?.warn?.(`[atbash] found config under former plugin id${stale.length > 1 ? "s" : ""} ` +
27
- `${stale.map((id) => `"${id}"`).join(", ")} — this plugin's id is "${PLUGIN_ID}" ` +
28
- `and those entries are ignored` +
29
- (configured
30
- ? ". Remove them to avoid confusion."
31
- : `. No "${PLUGIN_ID}" config found, so the plugin is running on defaults — ` +
32
- `move your settings under "${PLUGIN_ID}".`), { formerIds: stale, configured });
33
- }
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var h=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var P=(r,e)=>{for(var o in e)h(r,o,{get:e[o],enumerable:!0})},Z=(r,e,o,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of T(e))!z.call(r,n)&&n!==o&&h(r,n,{get:()=>e[n],enumerable:!(a=S(e,n))||a.enumerable});return r};var v=r=>Z(h({},"__esModule",{value:!0}),r);var M={};P(M,{default:()=>R});module.exports=v(M);var k=require("os"),c=require("@atbash/sdk");var b="atbash-openclaw",x=["openclaw","atbash-plugin"];function w(r){return r.config?.plugins?.entries?.[b]?.config??{}}function y(r){let e=r.config?.plugins,o=e?.entries??{},a=Array.isArray(e?.allow)?e.allow:[],n=x.filter(t=>o[t]!==void 0||a.includes(t));if(n.length===0)return;let d=o[b]?.config!==void 0;r.logger?.warn?.(`[atbash] found config under former plugin id${n.length>1?"s":""} ${n.map(t=>`"${t}"`).join(", ")} \u2014 this plugin's id is "${b}" and those entries are ignored`+(d?". Remove them to avoid confusion.":`. No "${b}" config found, so the plugin is running on defaults \u2014 move your settings under "${b}".`),{formerIds:n,configured:d})}var D=[/\bsk-ant-[A-Za-z0-9_-]{20,}/g,/\bsk-proj-[A-Za-z0-9_-]{20,}/g,/\bsk-[A-Za-z0-9]{20,}/g,/\b(?:gh[pousr]|github_pat)_[A-Za-z0-9_]{30,}/g,/\bAIza[0-9A-Za-z_-]{35}/g,/\bya29\.[0-9A-Za-z_-]{20,}/g,/\b(?:AKIA|ASIA|AGPA|AROA|ANPA|ANVA|ASCA|AIDA|AIPA)[0-9A-Z]{16}\b/g,/\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g,/\bxox[abprseo]-[A-Za-z0-9-]{10,}/g,/\bSG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,/\bnpm_[A-Za-z0-9]{36,}\b/g,/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g,/\b(?!0x[0-9a-fA-F])(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b)(?=[A-Za-z0-9_-]*[0-9])(?=[A-Za-z0-9_-]*[A-Za-z])(?![0-9a-fA-F]+$)[A-Za-z0-9_-]{32,}\b/g,/(?<![A-Za-z0-9+/])(?=[A-Za-z0-9+/]*[+/])(?=[A-Za-z0-9+/]*[0-9])(?=[A-Za-z0-9+/]*[A-Za-z])[A-Za-z0-9+/]{40,}={0,2}(?![A-Za-z0-9+/=])/g];function A(r){let e=r;for(let o of D)o.lastIndex=0,e=e.replace(o,"[REDACTED]");return e}var F={"0xdac17f958d2ee523a2206206994597c13d831ec7":"USDT","0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48":"USDC","0x6b175474e89094c44da98b954eedeac495271d0f":"DAI","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2":"WETH","0x2260fac5e5542a773aa44fbcfedf7c193bc2c599":"WBTC","0x1f9840a85d5af5bf1d1762f925bdaddc4201f984":"UNI","0x514910771af9ca656af840dff83e8264ecf986ca":"LINK","0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9":"AAVE","0xb0df6379ba1692841965a0745ac1bd3046d79ba3":"ATBASH","0xe9c094187219d9a29382c1a36fc43619c9257777":"ATBASH","0xf8b071428558c657a7a9aa1c43e152e75dd77777":"ATBASH"},_=/\b(0x[a-fA-F0-9]{40})\b/,N=/(0x[a-fA-F0-9]{40})/,E=/\b(transfer|send|swap|approve|erc20)\b/i;function j(r){if(!r)return"ETH";let e=r.toLowerCase(),o=N.exec(e);return o?F[o[1].toLowerCase()]??"other":e==="c60"||e==="eth"?"ETH":e==="atbash"?"ATBASH":e==="usdt"||e==="tether"?"USDT":e==="usdc"?"USDC":"other"}function p(r,...e){for(let o of e){let a=r[o];if(typeof a=="string"&&a.trim())return a.trim()}}function $(r,e){let o=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0,a=o?p(o,"command","cmd","shell_command"):void 0,n=E.test(r),d=a?E.test(a):!1,t=a?_.test(a):!1;if(!n&&!d&&!t)return;let f=m=>a?new RegExp(`--${m}[= ]+(\\S+)`).exec(a)?.[1]:void 0,g=(o?p(o,"token","token_address","asset","currency"):void 0)??f("token");if(!g&&a){let m=_.exec(a);m&&(g=m[1])}let u=(o?p(o,"to","recipient","destination"):void 0)??f("to")??f("recipient"),l=(o?p(o,"amount","value","qty"):void 0)??f("amount"),s=j(g??""),i=a??r;return{operation:/\bswap\b/i.test(i)?"swap":/\b(approve|erc20)\b/i.test(i)?"approve":"transfer",asset:s,amount:l,recipient_status:u?"external":"unspecified",note:"canonicalized pre-judge; raw 0x addresses omitted (redacted upstream)"}}function I(r,e){let o=r??{},a=o.toolName??e.tool?.name??e.toolName??e.name??"unknown",n=o.params??e.params??o.args??e.args??o.arguments??e.arguments,d=JSON.stringify({tool_name:a,run_id:A(e.runId??""),agent_id:A(e.agentId??""),channel_id:A(e.channelId??""),account_id:A(e.accountId??"")});return{toolName:a,args:n,context:d,resolved:$(a,n)}}function C(r){return r.replace(/^~(?=\/|$)/,(0,k.homedir)())}function L(r){return r.memoryWorkspaceDir?C(r.memoryWorkspaceDir):process.cwd()}function O(r){if(r.judgeEndpoint)return r.judgeEndpointPolicy==="self-hosted"?{policy:"self-hosted",endpoint:r.judgeEndpoint,verifyPubKey:r.judgeVerifyPubKey??""}:{policy:"default",endpoint:r.judgeEndpoint}}function R(r){let e=r,o=w(e);if(y(e),o.enabled===!1){e.logger?.info?.("[atbash] plugin disabled via config");return}(0,c.setupTelemetry)({enabled:!0,source:"plugin:openclaw"}),process.once("beforeExit",()=>(0,c.shutdownTelemetry)()),process.once("SIGINT",()=>(0,c.shutdownTelemetry)().finally(()=>process.exit(0))),process.once("SIGTERM",()=>(0,c.shutdownTelemetry)().finally(()=>process.exit(0)));let a;try{a=c.Atbash.fromConfig({judge:O(o),keyPath:o.chromiaSecretPath,orgName:o.orgName,failClosed:o.enforceDecision!==!1,logger:e.logger})}catch(t){let f=t instanceof Error?t.message:String(t);throw e.logger?.warn?.("[atbash] init failed",{error:f}),t}let n=o.enforceDecision!==!1;e.logger?.info?.("[atbash] plugin loaded",{enforceDecision:n});let d=(0,c.createMemoryGuardManager)({auth:a.auth,workspaceDir:L(o),memoryFilePath:o.memoryFilePath?C(o.memoryFilePath):void 0,ttlMs:o.memorySyncTTLMs,rollbackMinScore:o.memoryRollbackMinScore,memoryPathPatterns:o.memoryPathPatterns,judgeEndpoint:o.judgeEndpoint,judgeVerifyPubKey:o.judgeVerifyPubKey,orgName:o.orgName,enforce:n,debug:!!o.debug,hostLogger:e.logger});if(d.runBootProbe().catch(t=>{e.logger?.warn?.("[atbash] boot probe failed",{error:t instanceof Error?t.message:String(t)})}),!e.on){e.logger?.warn?.("[atbash] on() API not available");return}e.on("before_tool_call",async(t,f)=>{let g;try{g=await d.handleBeforeToolCall(t,f)}catch(s){let i=s instanceof Error?s.message:String(s);return e.logger?.warn?.("[atbash] memory guard error",{error:i}),s instanceof c.MemoryIntegrityError||n?{block:!0,blockReason:`Memory guard error: ${i}`,allow:!1,reason:`Memory guard error: ${i}`}:{allow:!0}}if(g)return g;let u;try{u=await a.auditToolCall(I(t,f))}catch(s){let i=s instanceof Error?s.message:String(s);return e.logger?.warn?.("[atbash] unexpected error",{error:i}),n?{block:!0,blockReason:`Atbash unavailable: ${i}`,allow:!1,reason:`Atbash unavailable: ${i}`}:{allow:!0}}let l=u.reason??"";switch(u.verdict){case"BLOCK":return e.logger?.warn?.("[atbash] BLOCK",{reason:l}),n?{block:!0,blockReason:l,allow:!1,reason:l}:{allow:!0};case"HOLD":{let s=["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: ${l}`];u.toolCallId&&s.push(`Tool Call ID: ${u.toolCallId}`);let i=s.join(`
2
- `);return e.logger?.warn?.("[atbash] HOLD",{reason:l,toolCallId:u.toolCallId}),n?{block:!0,blockReason:i,allow:!1,reason:i}:{allow:!0}}case"ERROR":return e.logger?.warn?.("[atbash] ERROR",{reason:l}),n?{block:!0,blockReason:l,allow:!1,reason:l}:{allow:!0};case"ALLOW":if(u.allow===!0)return e.logger?.info?.("[atbash] ALLOW",{reason:l}),{allow:!0};break}{let s=String(u.verdict);if(e.logger?.warn?.("[atbash] unusable decision",{verdict:s,allow:u.allow,reason:l}),!n)return{allow:!0};let i=`Blocked (unusable Atbash decision ${s}): ${l}`;return{block:!0,blockReason:i,allow:!1,reason:i}}})}
1
+ "use strict";var p=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var S=(r,e)=>{for(var a in e)p(r,a,{get:e[a],enumerable:!0})},R=(r,e,a,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of z(e))!C.call(r,n)&&n!==a&&p(r,n,{get:()=>e[n],enumerable:!(o=I(e,n))||o.enumerable});return r};var Z=r=>R(p({},"__esModule",{value:!0}),r);var O={};S(O,{default:()=>k});module.exports=Z(O);var E=require("os"),i=require("@atbash/sdk");var P="atbash-openclaw";function h(r){return r.config?.plugins?.entries?.[P]?.config??{}}var x=[/\bsk-ant-[A-Za-z0-9_-]{20,}/g,/\bsk-proj-[A-Za-z0-9_-]{20,}/g,/\bsk-[A-Za-z0-9]{20,}/g,/\b(?:gh[pousr]|github_pat)_[A-Za-z0-9_]{30,}/g,/\bAIza[0-9A-Za-z_-]{35}/g,/\bya29\.[0-9A-Za-z_-]{20,}/g,/\b(?:AKIA|ASIA|AGPA|AROA|ANPA|ANVA|ASCA|AIDA|AIPA)[0-9A-Z]{16}\b/g,/\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g,/\bxox[abprseo]-[A-Za-z0-9-]{10,}/g,/\bSG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,/\bnpm_[A-Za-z0-9]{36,}\b/g,/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g,/\b(?!0x[0-9a-fA-F])(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b)(?=[A-Za-z0-9_-]*[0-9])(?=[A-Za-z0-9_-]*[A-Za-z])(?![0-9a-fA-F]+$)[A-Za-z0-9_-]{32,}\b/g,/(?<![A-Za-z0-9+/])(?=[A-Za-z0-9+/]*[+/])(?=[A-Za-z0-9+/]*[0-9])(?=[A-Za-z0-9+/]*[A-Za-z])[A-Za-z0-9+/]{40,}={0,2}(?![A-Za-z0-9+/=])/g];function A(r){let e=r;for(let a of x)a.lastIndex=0,e=e.replace(a,"[REDACTED]");return e}var D={"0xdac17f958d2ee523a2206206994597c13d831ec7":"USDT","0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48":"USDC","0x6b175474e89094c44da98b954eedeac495271d0f":"DAI","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2":"WETH","0x2260fac5e5542a773aa44fbcfedf7c193bc2c599":"WBTC","0x1f9840a85d5af5bf1d1762f925bdaddc4201f984":"UNI","0x514910771af9ca656af840dff83e8264ecf986ca":"LINK","0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9":"AAVE","0xb0df6379ba1692841965a0745ac1bd3046d79ba3":"ATBASH","0xe9c094187219d9a29382c1a36fc43619c9257777":"ATBASH","0xf8b071428558c657a7a9aa1c43e152e75dd77777":"ATBASH"},y=/\b(0x[a-fA-F0-9]{40})\b/,v=/(0x[a-fA-F0-9]{40})/,w=/\b(transfer|send|swap|approve|erc20)\b/i;function F(r){if(!r)return"ETH";let e=r.toLowerCase(),a=v.exec(e);return a?D[a[1].toLowerCase()]??"other":e==="c60"||e==="eth"?"ETH":e==="atbash"?"ATBASH":e==="usdt"||e==="tether"?"USDT":e==="usdc"?"USDC":"other"}function m(r,...e){for(let a of e){let o=r[a];if(typeof o=="string"&&o.trim())return o.trim()}}function N(r,e){let a=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0,o=a?m(a,"command","cmd","shell_command"):void 0,n=w.test(r),g=o?w.test(o):!1,t=o?y.test(o):!1;if(!n&&!g&&!t)return;let d=b=>o?new RegExp(`--${b}[= ]+(\\S+)`).exec(o)?.[1]:void 0,f=(a?m(a,"token","token_address","asset","currency"):void 0)??d("token");if(!f&&o){let b=y.exec(o);b&&(f=b[1])}let u=(a?m(a,"to","recipient","destination"):void 0)??d("to")??d("recipient"),l=(a?m(a,"amount","value","qty"):void 0)??d("amount"),s=F(f??""),c=o??r;return{operation:/\bswap\b/i.test(c)?"swap":/\b(approve|erc20)\b/i.test(c)?"approve":"transfer",asset:s,amount:l,recipient_status:u?"external":"unspecified",note:"canonicalized pre-judge; raw 0x addresses omitted (redacted upstream)"}}function _(r,e){let a=r??{},o=a.toolName??e.tool?.name??e.toolName??e.name??"unknown",n=a.params??e.params??a.args??e.args??a.arguments??e.arguments,g=JSON.stringify({tool_name:o,run_id:A(e.runId??""),agent_id:A(e.agentId??""),channel_id:A(e.channelId??""),account_id:A(e.accountId??"")});return{toolName:o,args:n,context:g,resolved:N(o,n)}}function T(r){return r.replace(/^~(?=\/|$)/,(0,E.homedir)())}function j(r){return r.memoryWorkspaceDir?T(r.memoryWorkspaceDir):process.cwd()}function L(r){if(r.judgeEndpoint)return r.judgeEndpointPolicy==="self-hosted"?{policy:"self-hosted",endpoint:r.judgeEndpoint,verifyPubKey:r.judgeVerifyPubKey??""}:{policy:"default",endpoint:r.judgeEndpoint}}function k(r){let e=r,a=h(e);if(a.enabled===!1){e.logger?.info?.("[atbash] plugin disabled via config");return}(0,i.setupTelemetry)({enabled:!0,source:"plugin:openclaw"}),process.once("beforeExit",()=>(0,i.shutdownTelemetry)()),process.once("SIGINT",()=>(0,i.shutdownTelemetry)().finally(()=>process.exit(0))),process.once("SIGTERM",()=>(0,i.shutdownTelemetry)().finally(()=>process.exit(0)));let o;try{o=i.Atbash.fromConfig({judge:L(a),keyPath:a.chromiaSecretPath,orgName:a.orgName,failClosed:a.enforceDecision!==!1,logger:e.logger})}catch(t){let d=t instanceof Error?t.message:String(t);throw e.logger?.warn?.("[atbash] init failed",{error:d}),t}let n=a.enforceDecision!==!1;e.logger?.info?.("[atbash] plugin loaded",{enforceDecision:n});let g=(0,i.createMemoryGuardManager)({auth:o.auth,workspaceDir:j(a),memoryFilePath:a.memoryFilePath?T(a.memoryFilePath):void 0,ttlMs:a.memorySyncTTLMs,rollbackMinScore:a.memoryRollbackMinScore,memoryPathPatterns:a.memoryPathPatterns,judgeEndpoint:a.judgeEndpoint,judgeVerifyPubKey:a.judgeVerifyPubKey,orgName:a.orgName,enforce:n,debug:!!a.debug,hostLogger:e.logger});if(g.runBootProbe().catch(t=>{e.logger?.warn?.("[atbash] boot probe failed",{error:t instanceof Error?t.message:String(t)})}),!e.on){e.logger?.warn?.("[atbash] on() API not available");return}e.on("before_tool_call",async(t,d)=>{let f;try{f=await g.handleBeforeToolCall(t,d)}catch(s){let c=s instanceof Error?s.message:String(s);return e.logger?.warn?.("[atbash] memory guard error",{error:c}),s instanceof i.MemoryIntegrityError||n?{block:!0,blockReason:`Memory guard error: ${c}`,allow:!1,reason:`Memory guard error: ${c}`}:{allow:!0}}if(f)return f;let u;try{u=await o.auditToolCall(_(t,d))}catch(s){let c=s instanceof Error?s.message:String(s);return e.logger?.warn?.("[atbash] unexpected error",{error:c}),n?{block:!0,blockReason:`Atbash unavailable: ${c}`,allow:!1,reason:`Atbash unavailable: ${c}`}:{allow:!0}}let l=u.reason??"";switch(u.verdict){case"BLOCK":return e.logger?.warn?.("[atbash] BLOCK",{reason:l}),n?{block:!0,blockReason:l,allow:!1,reason:l}:{allow:!0};case"HOLD":{let s=["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: ${l}`];u.toolCallId&&s.push(`Tool Call ID: ${u.toolCallId}`);let c=s.join(`
2
+ `);return e.logger?.warn?.("[atbash] HOLD",{reason:l,toolCallId:u.toolCallId}),n?{block:!0,blockReason:c,allow:!1,reason:c}:{allow:!0}}case"ERROR":return e.logger?.warn?.("[atbash] ERROR",{reason:l}),n?{block:!0,blockReason:l,allow:!1,reason:l}:{allow:!0};case"ALLOW":default:return e.logger?.info?.("[atbash] ALLOW",{reason:l}),{allow:!0}}})}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atbash/atbash-openclaw",
3
- "version": "0.1.17-dev.0",
3
+ "version": "0.1.17",
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",
@@ -11,13 +11,10 @@
11
11
  "LICENSE"
12
12
  ],
13
13
  "scripts": {
14
- "build": "node scripts/clean.mjs && tsc && esbuild dist/index.js --bundle --platform=node --external:postchain-client --external:@atbash/sdk --minify --allow-overwrite --outfile=dist/index.js",
14
+ "build": "tsc && esbuild dist/index.js --bundle --platform=node --external:postchain-client --external:@atbash/sdk --minify --allow-overwrite --outfile=dist/index.js",
15
15
  "typecheck": "tsc --noEmit",
16
- "test": "tsc --noEmit && vitest run && node test/build.mjs && node --test test/verdict-handling.test.mjs test/safety-guard-doc.test.mjs",
17
- "test:release": "node --test test/release-guard.test.mjs",
18
- "verify:package": "node scripts/release.mjs --verify-current",
19
- "release": "node scripts/release.mjs --channel latest",
20
- "release:dev": "node scripts/release.mjs --channel dev"
16
+ "release": "npm pkg set \"dependencies[@atbash/sdk]=^$(npm view @atbash/sdk dist-tags.latest)\" && npm version patch --no-git-tag-version && npm run build && npx npm@10 publish --access public",
17
+ "release:dev": "npm pkg set \"dependencies[@atbash/sdk]=$(npm view @atbash/sdk dist-tags.dev)\" && npm version prerelease --preid=dev --no-git-tag-version && npm run build && npx npm@10 publish --access public --tag dev"
21
18
  },
22
19
  "keywords": [
23
20
  "openclaw",
@@ -30,24 +27,17 @@
30
27
  ],
31
28
  "author": "atbash",
32
29
  "license": "LICENSED",
33
- "repository": {
34
- "type": "git",
35
- "url": "https://github.com/Atbash-Ai/atbash-openclaw-plugin",
36
- "directory": "openclaw"
37
- },
38
30
  "openclaw": {
39
31
  "extensions": [
40
32
  "./dist/index.js"
41
33
  ]
42
34
  },
43
35
  "dependencies": {
44
- "@atbash/sdk": "0.10.13-dev.0"
36
+ "@atbash/sdk": "^0.7.1"
45
37
  },
46
38
  "devDependencies": {
47
39
  "@types/node": "^25.7.0",
48
40
  "esbuild": "^0.24.0",
49
- "semver": "7.8.5",
50
- "typescript": "^5.9.3",
51
- "vitest": "^4.1.6"
41
+ "typescript": "^5.9.3"
52
42
  }
53
43
  }
package/LICENSE DELETED
@@ -1,28 +0,0 @@
1
- Atbash CLI — Proprietary Software License
2
-
3
- Copyright (c) 2026 Atbash,
4
- All rights reserved.
5
-
6
- Redistribution and use in source and binary forms, with or without
7
- modification, are permitted provided that the following conditions are met:
8
-
9
- 1. Redistributions of source code must retain the above copyright notice, this
10
- list of conditions and the following disclaimer.
11
- 2. Redistributions in binary form must reproduce the above copyright notice,
12
- this list of conditions and the following disclaimer in the documentation
13
- and/or other materials provided with the distribution.
14
-
15
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
-
26
- The views and conclusions contained in the software and documentation are those
27
- of the authors and should not be interpreted as representing official policies,
28
- either expressed or implied, Atbash.