@lowwattlabs/clawsec 2.0.1 → 2.1.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/bin/setup-venv.js +51 -11
- package/cli/clawsec.py +1 -1
- package/lib/intel-sync/sync.sh +5 -5
- package/package.json +1 -1
package/bin/setup-venv.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* ClawSec postinstall — sets up Python venv
|
|
3
|
+
* ⚡ ClawSec postinstall — sets up Python venv and runs initial intel sync
|
|
4
4
|
* Called by npm postinstall. Safe to run multiple times.
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -12,23 +12,63 @@ const os = require('os');
|
|
|
12
12
|
const CLAWSEC_HOME = process.env.CLAWSEC_HOME || path.join(os.homedir(), '.clawsec');
|
|
13
13
|
const VENV_DIR = path.join(CLAWSEC_HOME, 'venv');
|
|
14
14
|
const PYTHON = path.join(VENV_DIR, 'bin', 'python3');
|
|
15
|
+
const INTEL_DIR = path.join(CLAWSEC_HOME, 'intel');
|
|
15
16
|
|
|
16
17
|
// Don't fail install if setup fails — user can run clawsec setup later
|
|
17
18
|
try {
|
|
18
|
-
if
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
// Step 1: Create Python venv if needed
|
|
20
|
+
if (!fs.existsSync(PYTHON)) {
|
|
21
|
+
fs.mkdirSync(CLAWSEC_HOME, { recursive: true });
|
|
22
|
+
console.log('⚡ Setting up ClawSec Python environment (first run)...');
|
|
23
|
+
execSync(`python3 -m venv "${VENV_DIR}"`, { stdio: 'inherit' });
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
const PKG_ROOT = path.resolve(__dirname, '..');
|
|
26
|
+
const REQUIREMENTS = path.join(PKG_ROOT, 'requirements.txt');
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
if (fs.existsSync(REQUIREMENTS)) {
|
|
29
|
+
execSync(`"${PYTHON}" -m pip install --quiet --upgrade pip`, { stdio: 'pipe' });
|
|
30
|
+
execSync(`"${PYTHON}" -m pip install --quiet -r "${REQUIREMENTS}"`, { stdio: 'pipe' });
|
|
31
|
+
}
|
|
32
|
+
console.log(' ✅ Python environment ready.');
|
|
33
|
+
}
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
// Step 2: Create intel directories and sync
|
|
36
|
+
const intelDirs = [
|
|
37
|
+
'cisa-kev', 'osv', 'osv/npm', 'osv/PyPI', 'epss',
|
|
38
|
+
'malwarebazaar', 'urlhaus', 'threatfox', 'feodo',
|
|
39
|
+
'yara-rules', 'yara-rules/repo', 'semgrep-rules', 'semgrep-rules/repo'
|
|
40
|
+
];
|
|
41
|
+
for (const d of intelDirs) {
|
|
42
|
+
fs.mkdirSync(path.join(INTEL_DIR, d), { recursive: true });
|
|
31
43
|
}
|
|
44
|
+
fs.mkdirSync(path.join(CLAWSEC_HOME, 'reports'), { recursive: true });
|
|
45
|
+
|
|
46
|
+
// Only sync if intel cache is empty (first install)
|
|
47
|
+
const manifest = path.join(INTEL_DIR, 'manifest.json');
|
|
48
|
+
if (!fs.existsSync(manifest)) {
|
|
49
|
+
console.log('⚡ Downloading threat intel (first run, may take a few minutes)...');
|
|
50
|
+
const PKG_ROOT = path.resolve(__dirname, '..');
|
|
51
|
+
const syncSh = path.join(PKG_ROOT, 'lib', 'intel-sync', 'sync.sh');
|
|
52
|
+
if (fs.existsSync(syncSh)) {
|
|
53
|
+
try {
|
|
54
|
+
execSync(`bash "${syncSh}"`, {
|
|
55
|
+
stdio: 'inherit',
|
|
56
|
+
env: {
|
|
57
|
+
...process.env,
|
|
58
|
+
CLAWSEC_HOME: CLAWSEC_HOME,
|
|
59
|
+
CLAWSEC_INTEL_DIR: INTEL_DIR,
|
|
60
|
+
CLAWSEC_REPORTS_DIR: path.join(CLAWSEC_HOME, 'reports'),
|
|
61
|
+
PATH: `${path.join(os.homedir(), '.local', 'bin')}:${process.env.PATH || '/usr/local/bin:/usr/bin:/bin'}`,
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
} catch {
|
|
65
|
+
// Sync failure is non-fatal — user can run clawsec sync later
|
|
66
|
+
console.log(' ⚠ Intel sync had issues. Run "clawsec sync" to retry.');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log('⚡ ClawSec ready. Run "clawsec scan ./my-skill" to get started.');
|
|
32
72
|
} catch {
|
|
33
73
|
// Postinstall is best-effort. The CLI will try again on first run.
|
|
34
74
|
process.exit(0);
|
package/cli/clawsec.py
CHANGED
|
@@ -19,7 +19,7 @@ import sys
|
|
|
19
19
|
import time
|
|
20
20
|
from pathlib import Path
|
|
21
21
|
|
|
22
|
-
VERSION = "2.0
|
|
22
|
+
VERSION = "2.1.0"
|
|
23
23
|
CLAWSEC_DIR = os.environ.get("CLAWSEC_HOME", os.path.expanduser("~/.clawsec"))
|
|
24
24
|
INTEL_DIR = os.environ.get("CLAWSEC_INTEL_DIR", os.path.join(CLAWSEC_DIR, "intel"))
|
|
25
25
|
REPORTS_DIR = os.environ.get("CLAWSEC_REPORTS_DIR", os.path.join(CLAWSEC_DIR, "reports"))
|
package/lib/intel-sync/sync.sh
CHANGED
|
@@ -31,12 +31,12 @@ usage() {
|
|
|
31
31
|
ALL_SOURCES=(cisa-kev osv epss malwarebazaar urlhaus threatfox feodo yara-rules semgrep-rules)
|
|
32
32
|
|
|
33
33
|
# Ensure intel directories exist
|
|
34
|
-
INTEL_DIR=
|
|
35
|
-
for src in ; do
|
|
36
|
-
mkdir -p
|
|
34
|
+
INTEL_DIR="${CLAWSEC_INTEL_DIR}"
|
|
35
|
+
for src in "${ALL_SOURCES[@]}"; do
|
|
36
|
+
mkdir -p "${INTEL_DIR}/${src}"
|
|
37
37
|
done
|
|
38
|
-
mkdir -p /osv/npm /osv/PyPI
|
|
39
|
-
mkdir -p
|
|
38
|
+
mkdir -p "${INTEL_DIR}/osv/npm" "${INTEL_DIR}/osv/PyPI"
|
|
39
|
+
mkdir -p "${CLAWSEC_REPORTS_DIR}"
|
|
40
40
|
requested_sources=()
|
|
41
41
|
json_output=0
|
|
42
42
|
|