claude-warden 1.1.6 → 1.1.8
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/.claude-plugin/plugin.json +1 -1
- package/dist/index.cjs +64 -18
- package/package.json +4 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-warden",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "Smart command safety filter for Claude Code — parses shell pipelines and evaluates per-command safety rules to auto-approve safe commands and block dangerous ones",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "banyudu"
|
package/dist/index.cjs
CHANGED
|
@@ -18139,6 +18139,10 @@ var require_dist2 = __commonJS({
|
|
|
18139
18139
|
var import_bash_parser = __toESM(require_src(), 1);
|
|
18140
18140
|
var import_path = require("path");
|
|
18141
18141
|
var HEREDOC_REGEX = /<<-?\s*['"]?\w+['"]?/;
|
|
18142
|
+
function preprocessCatHeredocs(input) {
|
|
18143
|
+
const regex = /\$\(cat\s+<<-?\s*['"]?(\w+)['"]?\n([\s\S]*?)\n\1\s*\)/g;
|
|
18144
|
+
return input.replace(regex, "__HEREDOC_TEXT__");
|
|
18145
|
+
}
|
|
18142
18146
|
function convertCommand(node) {
|
|
18143
18147
|
if (!node.name) return null;
|
|
18144
18148
|
const command = node.name.text.includes("/") ? (0, import_path.basename)(node.name.text) : node.name.text;
|
|
@@ -18254,36 +18258,78 @@ function walkNode(node, result) {
|
|
|
18254
18258
|
break;
|
|
18255
18259
|
}
|
|
18256
18260
|
}
|
|
18257
|
-
function
|
|
18258
|
-
if (!
|
|
18259
|
-
|
|
18260
|
-
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
if (!cmdPart) {
|
|
18266
|
-
return { commands: [], hasSubshell: false, subshellCommands: [], parseError: true };
|
|
18261
|
+
function hasHeredocRedirect(node) {
|
|
18262
|
+
if (!node.suffix) return false;
|
|
18263
|
+
return node.suffix.some((s) => s.type === "dless" || s.type === "dlessdash");
|
|
18264
|
+
}
|
|
18265
|
+
function astHasHeredoc(ast) {
|
|
18266
|
+
function check(node) {
|
|
18267
|
+
if (node.type === "Command") {
|
|
18268
|
+
if (hasHeredocRedirect(node)) return true;
|
|
18267
18269
|
}
|
|
18268
|
-
|
|
18269
|
-
|
|
18270
|
-
|
|
18271
|
-
|
|
18272
|
-
|
|
18270
|
+
for (const [key, value] of Object.entries(node)) {
|
|
18271
|
+
if (key === "commandAST" || key === "expansion") continue;
|
|
18272
|
+
if (Array.isArray(value)) {
|
|
18273
|
+
for (const child of value) {
|
|
18274
|
+
if (child && typeof child === "object" && "type" in child && check(child)) return true;
|
|
18275
|
+
}
|
|
18276
|
+
} else if (value && typeof value === "object" && "type" in value) {
|
|
18277
|
+
if (check(value)) return true;
|
|
18273
18278
|
}
|
|
18274
|
-
return { commands: result.commands, hasSubshell: true, subshellCommands: result.subshellCommands, parseError: false };
|
|
18275
|
-
} catch {
|
|
18276
|
-
return { commands: [], hasSubshell: true, subshellCommands: [], parseError: true };
|
|
18277
18279
|
}
|
|
18280
|
+
return false;
|
|
18281
|
+
}
|
|
18282
|
+
for (const cmd of ast.commands) {
|
|
18283
|
+
if (check(cmd)) return true;
|
|
18284
|
+
}
|
|
18285
|
+
return false;
|
|
18286
|
+
}
|
|
18287
|
+
function parseCommand(input) {
|
|
18288
|
+
if (!input || !input.trim()) {
|
|
18289
|
+
return { commands: [], hasSubshell: false, subshellCommands: [], parseError: false };
|
|
18278
18290
|
}
|
|
18291
|
+
input = preprocessCatHeredocs(input);
|
|
18279
18292
|
try {
|
|
18280
18293
|
const ast = (0, import_bash_parser.default)(input);
|
|
18281
18294
|
const result = { commands: [], hasSubshell: false, subshellCommands: [] };
|
|
18295
|
+
if (astHasHeredoc(ast)) {
|
|
18296
|
+
const firstLine = input.split("\n")[0];
|
|
18297
|
+
const cmdPart = firstLine.replace(/<<-?\s*['"]?\w+['"]?.*$/, "").trim();
|
|
18298
|
+
if (!cmdPart) {
|
|
18299
|
+
return { commands: [], hasSubshell: false, subshellCommands: [], parseError: true };
|
|
18300
|
+
}
|
|
18301
|
+
try {
|
|
18302
|
+
const cmdAst = (0, import_bash_parser.default)(cmdPart);
|
|
18303
|
+
for (const cmd of cmdAst.commands) {
|
|
18304
|
+
walkNode(cmd, result);
|
|
18305
|
+
}
|
|
18306
|
+
return { commands: result.commands, hasSubshell: true, subshellCommands: result.subshellCommands, parseError: false };
|
|
18307
|
+
} catch {
|
|
18308
|
+
return { commands: [], hasSubshell: true, subshellCommands: [], parseError: true };
|
|
18309
|
+
}
|
|
18310
|
+
}
|
|
18282
18311
|
for (const cmd of ast.commands) {
|
|
18283
18312
|
walkNode(cmd, result);
|
|
18284
18313
|
}
|
|
18285
18314
|
return { commands: result.commands, hasSubshell: result.hasSubshell, subshellCommands: result.subshellCommands, parseError: false };
|
|
18286
18315
|
} catch {
|
|
18316
|
+
if (HEREDOC_REGEX.test(input)) {
|
|
18317
|
+
const firstLine = input.split("\n")[0];
|
|
18318
|
+
const cmdPart = firstLine.replace(/<<-?\s*['"]?\w+['"]?.*$/, "").trim();
|
|
18319
|
+
if (!cmdPart) {
|
|
18320
|
+
return { commands: [], hasSubshell: true, subshellCommands: [], parseError: true };
|
|
18321
|
+
}
|
|
18322
|
+
try {
|
|
18323
|
+
const ast = (0, import_bash_parser.default)(cmdPart);
|
|
18324
|
+
const result = { commands: [], hasSubshell: false, subshellCommands: [] };
|
|
18325
|
+
for (const cmd of ast.commands) {
|
|
18326
|
+
walkNode(cmd, result);
|
|
18327
|
+
}
|
|
18328
|
+
return { commands: result.commands, hasSubshell: true, subshellCommands: result.subshellCommands, parseError: false };
|
|
18329
|
+
} catch {
|
|
18330
|
+
return { commands: [], hasSubshell: true, subshellCommands: [], parseError: true };
|
|
18331
|
+
}
|
|
18332
|
+
}
|
|
18287
18333
|
return { commands: [], hasSubshell: false, subshellCommands: [], parseError: true };
|
|
18288
18334
|
}
|
|
18289
18335
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-warden",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "Smart command safety filter for Claude Code — auto-approves safe commands, blocks dangerous ones",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -35,7 +35,9 @@
|
|
|
35
35
|
"test:watch": "vitest",
|
|
36
36
|
"typecheck": "tsc --noEmit",
|
|
37
37
|
"eval": "node dist/index.cjs",
|
|
38
|
-
"
|
|
38
|
+
"sync-plugin-version": "node -e \"const p=require('./package.json'),fs=require('fs'),f='.claude-plugin/plugin.json',j=JSON.parse(fs.readFileSync(f));j.version=p.version;fs.writeFileSync(f,JSON.stringify(j,null,2)+'\\n')\"",
|
|
39
|
+
"prepublishOnly": "pnpm run sync-plugin-version && pnpm run build && pnpm run test",
|
|
40
|
+
"postpublish": "claude plugin update claude-warden@local 2>/dev/null; claude plugin update claude-warden@claude-warden 2>/dev/null; echo 'Plugin caches updated'"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@types/node": "^20.0.0",
|