agent-security-scanner-mcp 3.10.3 → 3.12.0

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/src/cli/audit.js CHANGED
@@ -1,10 +1,11 @@
1
1
  // src/cli/audit.js — OpenClaw configuration security audit (stub)
2
2
 
3
3
  export async function runAudit(args) {
4
- console.log('\n Security Audit [EXPERIMENTAL STUB]\n');
4
+ const allowStub = args.includes('--allow-stub');
5
+
6
+ console.log('\n Security Audit [NOT YET IMPLEMENTED]\n');
5
7
  console.log(' This command will check your OpenClaw configuration for security issues.');
6
- console.log(' Full implementation coming in Sprint 3.\n');
7
- console.log(' WARNING: This is an experimental stub. No actual checks are performed.\n');
8
+ console.log(' Implementation is in progress.\n');
8
9
  console.log(' Planned checks (60+):');
9
10
  console.log(' - Gateway: bind mode, auth, token strength, HTTPS, CORS');
10
11
  console.log(' - Permissions: config files, credentials, session transcripts');
@@ -15,4 +16,10 @@ export async function runAudit(args) {
15
16
  console.log(' - Plugins: unsigned, permissive, outdated');
16
17
  console.log(' - Credentials: plaintext secrets, exposed API keys\n');
17
18
  console.log(' OWASP ASI Top 10 mapping for all findings.\n');
19
+
20
+ if (!allowStub) {
21
+ console.error(' ERROR: audit is not yet implemented. No checks were performed.');
22
+ console.error(' Pass --allow-stub to suppress this error in CI.\n');
23
+ throw new Error('audit command is not yet implemented');
24
+ }
18
25
  }
package/src/cli/demo.js CHANGED
@@ -4,6 +4,7 @@ import { join } from "path";
4
4
  import { createInterface } from "readline";
5
5
  import { dirname } from "path";
6
6
  import { fileURLToPath } from "url";
7
+ import { resolvePythonCommand, pythonArgs } from "../python.js";
7
8
 
8
9
  // Handle both ESM and CJS bundling (Smithery bundles to CJS)
9
10
  let __dirname;
@@ -178,22 +179,11 @@ export async function runDemo(args) {
178
179
 
179
180
  // Run the analyzer
180
181
  const analyzerPath = join(__dirname, '..', '..', 'analyzer.py');
181
- let pythonCmd = 'python3';
182
- const py3 = checkCommand('python3', ['--version']);
183
- if (!py3.ok) {
184
- const py = checkCommand('python', ['--version']);
185
- if (py.ok && py.output.includes('3.')) {
186
- pythonCmd = 'python';
187
- } else {
188
- console.log(` Error: Python 3 not found. Run "npx agent-security-scanner-mcp doctor" to diagnose.\n`);
189
- unlinkSync(filepath);
190
- process.exit(1);
191
- }
192
- }
182
+ const pythonCmd = resolvePythonCommand();
193
183
 
194
184
  let results;
195
185
  try {
196
- const output = execFileSync(pythonCmd, [analyzerPath, filepath], { timeout: 30000, encoding: 'utf-8' });
186
+ const output = execFileSync(pythonCmd, [...pythonArgs(), analyzerPath, filepath], { timeout: 30000, encoding: 'utf-8' });
197
187
  results = JSON.parse(output);
198
188
  } catch (e) {
199
189
  console.log(` Error running analyzer: ${e.message}\n`);
package/src/cli/doctor.js CHANGED
@@ -4,6 +4,7 @@ import { dirname, join } from "path";
4
4
  import { homedir, platform } from "os";
5
5
  import { fileURLToPath } from "url";
6
6
  import { getDaemonClient } from '../daemon-client.js';
7
+ import { resolvePythonCommand, pythonArgs } from '../python.js';
7
8
 
8
9
  // Handle both ESM and CJS bundling (Smithery bundles to CJS)
9
10
  let __dirname;
@@ -123,22 +124,23 @@ export async function runDoctor(args) {
123
124
  issues++;
124
125
  }
125
126
 
126
- // 2. Python 3
127
+ // 2. Python 3 (uses the same resolver as the runtime)
127
128
  let pythonCmd = null;
128
- const py3 = checkCommand('python3', ['--version']);
129
- if (py3.ok) {
130
- pythonCmd = 'python3';
131
- console.log(` \u2713 ${py3.output}`);
132
- } else {
133
- const py = checkCommand('python', ['--version']);
134
- if (py.ok && py.output.includes('3.')) {
135
- pythonCmd = 'python';
136
- console.log(` \u2713 ${py.output}`);
129
+ try {
130
+ pythonCmd = resolvePythonCommand();
131
+ const pyVer = checkCommand(pythonCmd, [...pythonArgs(), '--version']);
132
+ if (pyVer.ok) {
133
+ console.log(` \u2713 ${pyVer.output} (resolved as '${pythonCmd}${pythonArgs().length ? ' ' + pythonArgs().join(' ') : ''}')`);
137
134
  } else {
135
+ pythonCmd = null;
138
136
  console.log(` \u2717 Python 3 not found`);
139
137
  console.log(` Install: https://python.org/downloads/`);
140
138
  issues++;
141
139
  }
140
+ } catch {
141
+ console.log(` \u2717 Python 3 not found`);
142
+ console.log(` Install: https://python.org/downloads/`);
143
+ issues++;
142
144
  }
143
145
 
144
146
  // 3. analyzer.py reachable
@@ -173,7 +175,7 @@ export async function runDoctor(args) {
173
175
 
174
176
  // 4. Python can import yaml (analyzer dependency check)
175
177
  if (pythonCmd && existsSync(analyzerPath)) {
176
- const yamlCheck = checkCommand(pythonCmd, ['-c', 'import yaml; print("ok")']);
178
+ const yamlCheck = checkCommand(pythonCmd, [...pythonArgs(), '-c', 'import yaml; print("ok")']);
177
179
  if (yamlCheck.ok && yamlCheck.output === 'ok') {
178
180
  console.log(` \u2713 Analyzer engine ready (PyYAML installed)`);
179
181
  } else {
@@ -184,7 +186,7 @@ export async function runDoctor(args) {
184
186
 
185
187
  // 5. tree-sitter AST engine (optional but recommended)
186
188
  if (pythonCmd) {
187
- const tsCheck = checkCommand(pythonCmd, ['-c', 'import tree_sitter; print(tree_sitter.__version__)']);
189
+ const tsCheck = checkCommand(pythonCmd, [...pythonArgs(), '-c', 'import tree_sitter; print(tree_sitter.__version__)']);
188
190
  if (tsCheck.ok && tsCheck.output) {
189
191
  console.log(` \u2713 AST engine ready (tree-sitter ${tsCheck.output})`);
190
192
  } else {
@@ -193,7 +195,7 @@ export async function runDoctor(args) {
193
195
  console.log(` Installing tree-sitter dependencies...`);
194
196
  const requirementsPath = join(__dirname, '..', '..', 'requirements.txt');
195
197
  if (existsSync(requirementsPath)) {
196
- const installResult = checkCommand(pythonCmd, ['-m', 'pip', 'install', '-r', requirementsPath, '--user', '--quiet']);
198
+ const installResult = checkCommand(pythonCmd, [...pythonArgs(), '-m', 'pip', 'install', '-r', requirementsPath, '--user', '--quiet']);
197
199
  if (installResult.ok) {
198
200
  console.log(` \u2713 Fixed: tree-sitter dependencies installed — AST engine enabled`);
199
201
  fixed++;
package/src/cli/harden.js CHANGED
@@ -1,10 +1,11 @@
1
1
  // src/cli/harden.js — OpenClaw auto-hardening (stub)
2
2
 
3
3
  export async function runHarden(args) {
4
- console.log('\n Auto-Hardening [EXPERIMENTAL STUB]\n');
4
+ const allowStub = args.includes('--allow-stub');
5
+
6
+ console.log('\n Auto-Hardening [NOT YET IMPLEMENTED]\n');
5
7
  console.log(' This command will automatically fix security issues in your OpenClaw config.');
6
- console.log(' Full implementation coming in Sprint 3.\n');
7
- console.log(' WARNING: This is an experimental stub. No actions are performed.\n');
8
+ console.log(' Implementation is in progress.\n');
8
9
  console.log(' Planned actions:');
9
10
  console.log(' - Bind gateway to 127.0.0.1');
10
11
  console.log(' - Enable token authentication');
@@ -12,4 +13,10 @@ export async function runHarden(args) {
12
13
  console.log(' - Disable mDNS discovery');
13
14
  console.log(' - Remove plaintext credentials\n');
14
15
  console.log(' Usage: agent-security-scanner-mcp harden --fix [--dry-run]\n');
16
+
17
+ if (!allowStub) {
18
+ console.error(' ERROR: harden is not yet implemented. No actions were performed.');
19
+ console.error(' Pass --allow-stub to suppress this error in CI.\n');
20
+ throw new Error('harden command is not yet implemented');
21
+ }
15
22
  }
package/src/cli/init.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { readFileSync, existsSync, writeFileSync, copyFileSync, mkdirSync } from "fs";
2
2
  import { spawnSync } from "child_process";
3
3
  import { dirname, join } from "path";
4
+ import { fileURLToPath } from "url";
4
5
  import { homedir, platform } from "os";
5
6
  import { createInterface } from "readline";
6
7
 
@@ -167,8 +168,13 @@ async function installOpenClawSkill(client, flags) {
167
168
  const skillFile = client.configPath();
168
169
 
169
170
  // Find the source skill file (bundled with the package)
170
- const __dirname = dirname(new URL(import.meta.url).pathname);
171
- const sourceSkill = join(__dirname, '..', '..', 'skills', 'openclaw', 'SKILL.md');
171
+ let __initDir;
172
+ try {
173
+ __initDir = dirname(fileURLToPath(import.meta.url));
174
+ } catch {
175
+ __initDir = process.cwd();
176
+ }
177
+ const sourceSkill = join(__initDir, '..', '..', 'skills', 'openclaw', 'SKILL.md');
172
178
 
173
179
  console.log(`\n Client: ${client.name}`);
174
180
  console.log(` Skill: ${skillDir}`);
@@ -248,9 +254,9 @@ async function installCodexMCP(flags, serverName) {
248
254
  console.log(` Config: ~/.codex/config.toml (managed by codex CLI)`);
249
255
  console.log(` OS: ${platform()} (${process.arch})\n`);
250
256
 
251
- // Check codex CLI is available
252
- const which = spawnSync('which', ['codex'], { encoding: 'utf-8' });
253
- if (which.status !== 0) {
257
+ // Check codex CLI is available (cross-platform: probe directly instead of using which/where)
258
+ const codexCheck = spawnSync('codex', ['--version'], { encoding: 'utf-8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] });
259
+ if (codexCheck.status !== 0 || codexCheck.error) {
254
260
  console.error(` ERROR: 'codex' CLI not found in PATH.`);
255
261
  console.error(` Install it first: https://github.com/openai/codex\n`);
256
262
  process.exit(1);