clawmoat 0.7.0 → 1.0.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/.dockerignore +9 -0
- package/CHANGELOG.md +18 -0
- package/CONTRIBUTING.md +4 -2
- package/DEMO.md +87 -0
- package/Dockerfile +5 -18
- package/README.md +294 -8
- package/SECURITY.md +58 -10
- package/THREAT_MODEL.md +129 -0
- package/agent/README.md +131 -0
- package/agent/index.js +471 -0
- package/agent/install-service.sh +94 -0
- package/agent/openclaw-hook.js +453 -0
- package/agent/provider-setup.js +649 -0
- package/agent/setup.js +274 -0
- package/assets/BADGE-USAGE.md +20 -0
- package/assets/clawmoat-badge.svg +21 -0
- package/bin/clawmoat.js +468 -111
- package/docs/affiliates/dashboard.html +124 -0
- package/docs/affiliates/index.html +236 -0
- package/docs/agent-install.html +183 -0
- package/docs/ai-agent-security-scanner.html +10 -6
- package/docs/badge/index.html +149 -0
- package/docs/badge/scanning.svg +23 -0
- package/docs/blog/386-malicious-skills.html +262 -0
- package/docs/blog/40000-exposed-openclaw-instances.html +201 -0
- package/docs/blog/agent-trust-protocol.html +198 -0
- package/docs/blog/ai-agent-earns-commissions.html +230 -0
- package/docs/blog/bugmageddon-agent-firewall.html +174 -0
- package/docs/blog/calculator-math.html +180 -0
- package/docs/blog/clawmoat-vs-llamafirewall-nemo-guardrails.html +229 -0
- package/docs/blog/host-guardian-launch.html +18 -8
- package/docs/blog/ibm-experts-agent-runtime-protection.html +247 -0
- package/docs/blog/index.html +211 -9
- package/docs/blog/langchain-security-tutorial.html +18 -8
- package/docs/blog/mcp-30-cves-security-crisis.html +286 -0
- package/docs/blog/meta-researcher-rogue-agent.html +201 -0
- package/docs/blog/microsoft-openclaw-workstation-security.html +235 -0
- package/docs/blog/nist-ai-agent-standards-clawmoat.html +377 -0
- package/docs/blog/oasis-websocket-hijack.html +212 -0
- package/docs/blog/ollama-openclaw-security.html +160 -0
- package/docs/blog/openclaw-enterprise-readiness-claw10.html +199 -0
- package/docs/blog/openclaw-security-reckoning-2026.html +368 -0
- package/docs/blog/owasp-agentic-ai-top10.html +18 -8
- package/docs/blog/securing-ai-agents.html +18 -8
- package/docs/blog/supply-chain-agents.html +18 -8
- package/docs/business/index.html +525 -0
- package/docs/business/install.html +261 -0
- package/docs/checklist.html +174 -0
- package/docs/compare/index.html +122 -0
- package/docs/compare/lakera/index.html +62 -0
- package/docs/compare/llm-guard/index.html +49 -0
- package/docs/compare/snyk-agent-scan/index.html +63 -0
- package/docs/compare.html +10 -6
- package/docs/dashboard/index.html +520 -0
- package/docs/finance/index.html +220 -0
- package/docs/guides/business-deployment.html +770 -0
- package/docs/hall-of-fame.html +174 -0
- package/docs/index.html +447 -154
- package/docs/install.sh +557 -0
- package/docs/integrations/langchain.html +14 -6
- package/docs/integrations/openai.html +14 -6
- package/docs/integrations/openclaw.html +55 -7
- package/docs/plans/2026-03-26-threat-intel-api.md +255 -0
- package/docs/plans/2026-04-14-bugmageddon-marketing-pack.md +329 -0
- package/docs/plans/2026-04-14-clawmoat-v1-bugmageddon.md +248 -0
- package/docs/plans/2026-04-14-v1-release-update.md +91 -0
- package/docs/plans/2026-04-19-supabase-audit.md +68 -0
- package/docs/plans/2026-05-12-sales-push.md +303 -0
- package/docs/playground/index.html +893 -0
- package/docs/playground.html +4 -7
- package/docs/privacy-policy/index.html +122 -0
- package/docs/rfcs/defense-in-depth.md +467 -0
- package/docs/scan/index.html +358 -0
- package/docs/services/case-study.html +255 -0
- package/docs/services/downloads/install-openclaw.bat +45 -0
- package/docs/services/downloads/install-openclaw.command +38 -0
- package/docs/services/downloads/install-openclaw.sh +38 -0
- package/docs/services/get-started.html +165 -0
- package/docs/services/index.html +598 -0
- package/docs/services/multi-agent-security.html +284 -0
- package/docs/services/one-pager.html +99 -0
- package/docs/services/pitch-deck.html +229 -0
- package/docs/services/roi-calculator.html +258 -0
- package/docs/sitemap.xml +192 -2
- package/docs/support/index.html +135 -0
- package/docs/templates/customer-service/HEARTBEAT.md +61 -0
- package/docs/templates/customer-service/MEMORY.md +89 -0
- package/docs/templates/customer-service/SOUL.md +41 -0
- package/docs/templates/customer-service/USER.md +56 -0
- package/docs/templates/executive/HEARTBEAT.md +86 -0
- package/docs/templates/executive/MEMORY.md +92 -0
- package/docs/templates/executive/SOUL.md +44 -0
- package/docs/templates/executive/USER.md +62 -0
- package/docs/templates/finance/HEARTBEAT.md +58 -0
- package/docs/templates/finance/MEMORY.md +87 -0
- package/docs/templates/finance/SOUL.md +38 -0
- package/docs/templates/finance/USER.md +53 -0
- package/docs/templates/index.html +115 -0
- package/docs/templates/operations/HEARTBEAT.md +63 -0
- package/docs/templates/operations/MEMORY.md +68 -0
- package/docs/templates/operations/SOUL.md +38 -0
- package/docs/templates/operations/USER.md +49 -0
- package/docs/templates/sales/HEARTBEAT.md +55 -0
- package/docs/templates/sales/MEMORY.md +89 -0
- package/docs/templates/sales/SOUL.md +34 -0
- package/docs/templates/sales/USER.md +54 -0
- package/docs/terms-of-service/index.html +122 -0
- package/eslint.config.js +32 -0
- package/evals/README.md +29 -0
- package/evals/cases.json +390 -0
- package/evals/results.md +68 -0
- package/evals/run.js +180 -0
- package/examples/basic-usage.js +38 -0
- package/examples/demo-attack/demo.js +186 -0
- package/examples/python-quickstart/README.md +54 -0
- package/examples/python-quickstart/clawmoat_client.py +167 -0
- package/examples/video-demo/README.md +14 -0
- package/examples/video-demo/scene-a-normal.js +29 -0
- package/examples/video-demo/scene-b-attack-arrives.js +31 -0
- package/examples/video-demo/scene-c-hijack.js +44 -0
- package/examples/video-demo/scene-d-clawmoat.js +46 -0
- package/integrations/crewai/README.md +32 -0
- package/integrations/crewai/clawmoat_crewai/__init__.py +17 -0
- package/integrations/crewai/clawmoat_crewai/guard.py +103 -0
- package/integrations/crewai/pyproject.toml +21 -0
- package/integrations/langchain/README.md +91 -0
- package/integrations/langchain/clawmoat_langchain/__init__.py +17 -0
- package/integrations/langchain/clawmoat_langchain/callback.py +489 -0
- package/integrations/langchain/pyproject.toml +32 -0
- package/integrations/litellm/README.md +324 -0
- package/integrations/litellm/clawmoat_litellm/__init__.py +21 -0
- package/integrations/litellm/clawmoat_litellm/callback.py +329 -0
- package/integrations/litellm/clawmoat_litellm/proxy_middleware.py +224 -0
- package/integrations/litellm/pyproject.toml +74 -0
- package/integrations/openai-agents/README.md +392 -0
- package/integrations/openai-agents/clawmoat_openai_agents/__init__.py +20 -0
- package/integrations/openai-agents/clawmoat_openai_agents/guardrail.py +431 -0
- package/integrations/openai-agents/clawmoat_openai_agents/middleware.py +311 -0
- package/integrations/openai-agents/pyproject.toml +76 -0
- package/package.json +6 -5
- package/plugins/openclaw-adapter/PHASE1.md +439 -0
- package/plugins/openclaw-adapter/README.md +103 -0
- package/plugins/openclaw-adapter/SPEC.md +1644 -0
- package/plugins/openclaw-adapter/package.json +31 -0
- package/plugins/openclaw-adapter/src/index.test.ts +226 -0
- package/plugins/openclaw-adapter/src/index.ts +140 -0
- package/plugins/openclaw-adapter/tsconfig.json +14 -0
- package/server/data/threats.json +290 -0
- package/server/index.js +224 -10
- package/src/adapters/express.js +161 -0
- package/src/adapters/index.js +92 -0
- package/src/adapters/langchain.js +185 -0
- package/src/approval/index.js +456 -0
- package/src/ban-scanner.js +200 -0
- package/src/boundary-scanner.js +296 -0
- package/src/ci-scanner.js +279 -0
- package/src/code-scanner.js +245 -0
- package/src/enforce.js +166 -0
- package/src/finance/index.js +585 -0
- package/src/finance/mcp-firewall.js +486 -0
- package/src/formatters/json.js +80 -0
- package/src/formatters/sarif.js +388 -0
- package/src/guardian/alerts.js +34 -3
- package/src/guardian/gateway-monitor.js +590 -0
- package/src/guardian/index.js +41 -2
- package/src/index.js +105 -0
- package/src/integrations/agentmesh.js +501 -0
- package/src/language-detector.js +201 -0
- package/src/mcp-scanner.js +253 -0
- package/src/multimodal/index.js +579 -0
- package/src/obfuscation-scanner.js +457 -0
- package/src/policy-engine.js +402 -0
- package/src/scanners/dependency-attacks.js +128 -0
- package/src/scanners/prompt-injection.js +18 -0
- package/src/scanners/supply-chain.js +14 -0
- package/src/templates/default-config.yml +90 -0
- package/src/vuln-ops/exploitability.js +46 -0
- package/src/watch/live-monitor.js +720 -0
package/agent/setup.js
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ClawMoat Agent Setup
|
|
4
|
+
*
|
|
5
|
+
* Interactive setup: prompts for API key, tests it, writes config,
|
|
6
|
+
* optionally installs as a systemd user service.
|
|
7
|
+
*
|
|
8
|
+
* Usage: node agent/setup.js [--api-key <key>] [--no-service]
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const os = require('os');
|
|
16
|
+
const https = require('https');
|
|
17
|
+
const readline = require('readline');
|
|
18
|
+
const { execSync, exec } = require('child_process');
|
|
19
|
+
|
|
20
|
+
const CONFIG_DIR = path.join(os.homedir(), '.clawmoat');
|
|
21
|
+
const CONFIG_PATH = path.join(CONFIG_DIR, 'agent.json');
|
|
22
|
+
const AUDIT_LOG = path.join(CONFIG_DIR, 'audit.log');
|
|
23
|
+
|
|
24
|
+
// Parse args
|
|
25
|
+
const args = process.argv.slice(2);
|
|
26
|
+
const NO_SERVICE = args.includes('--no-service');
|
|
27
|
+
const API_KEY_ARG = (() => {
|
|
28
|
+
const i = args.indexOf('--api-key');
|
|
29
|
+
return i >= 0 ? args[i + 1] : null;
|
|
30
|
+
})();
|
|
31
|
+
|
|
32
|
+
const rl = readline.createInterface({
|
|
33
|
+
input: process.stdin,
|
|
34
|
+
output: process.stdout,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
function ask(question, defaultVal) {
|
|
38
|
+
return new Promise(resolve => {
|
|
39
|
+
const suffix = defaultVal ? ` [${defaultVal}]` : '';
|
|
40
|
+
rl.question(`${question}${suffix}: `, answer => {
|
|
41
|
+
resolve(answer.trim() || defaultVal || '');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function askYN(question, defaultYes = true) {
|
|
47
|
+
const suffix = defaultYes ? '[Y/n]' : '[y/N]';
|
|
48
|
+
return new Promise(resolve => {
|
|
49
|
+
rl.question(`${question} ${suffix}: `, answer => {
|
|
50
|
+
const a = answer.trim().toLowerCase();
|
|
51
|
+
if (!a) resolve(defaultYes);
|
|
52
|
+
else resolve(a === 'y' || a === 'yes');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function testApiKey(apiKey, dashboardUrl) {
|
|
58
|
+
return new Promise((resolve) => {
|
|
59
|
+
if (!apiKey || apiKey === 'cm_live_...') {
|
|
60
|
+
resolve({ ok: false, error: 'No API key provided' });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const url = new URL('/api/agent/verify', dashboardUrl);
|
|
65
|
+
const body = JSON.stringify({ source: 'local-agent', version: '1.0.0' });
|
|
66
|
+
|
|
67
|
+
const req = https.request({
|
|
68
|
+
hostname: url.hostname,
|
|
69
|
+
port: url.port || 443,
|
|
70
|
+
path: url.pathname,
|
|
71
|
+
method: 'POST',
|
|
72
|
+
headers: {
|
|
73
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
74
|
+
'Content-Type': 'application/json',
|
|
75
|
+
'Content-Length': Buffer.byteLength(body),
|
|
76
|
+
},
|
|
77
|
+
timeout: 8000,
|
|
78
|
+
}, res => {
|
|
79
|
+
let data = '';
|
|
80
|
+
res.on('data', c => data += c);
|
|
81
|
+
res.on('end', () => {
|
|
82
|
+
if (res.statusCode === 200 || res.statusCode === 201) {
|
|
83
|
+
resolve({ ok: true });
|
|
84
|
+
} else if (res.statusCode === 401 || res.statusCode === 403) {
|
|
85
|
+
resolve({ ok: false, error: 'Invalid API key' });
|
|
86
|
+
} else if (res.statusCode === 404) {
|
|
87
|
+
// Endpoint may not exist yet — treat as "key format ok, endpoint pending"
|
|
88
|
+
resolve({ ok: true, warning: 'Verify endpoint not found (dashboard may not have it yet)' });
|
|
89
|
+
} else {
|
|
90
|
+
resolve({ ok: false, error: `HTTP ${res.statusCode}` });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
req.on('error', e => resolve({ ok: false, error: e.message }));
|
|
95
|
+
req.on('timeout', () => { req.destroy(); resolve({ ok: false, error: 'Timeout' }); });
|
|
96
|
+
req.write(body);
|
|
97
|
+
req.end();
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function detectSystemd() {
|
|
102
|
+
try {
|
|
103
|
+
execSync('systemctl --user status', { stdio: 'pipe' });
|
|
104
|
+
return true;
|
|
105
|
+
} catch (e) {
|
|
106
|
+
// In WSL2, systemd might not be running
|
|
107
|
+
try {
|
|
108
|
+
execSync('which systemctl', { stdio: 'pipe' });
|
|
109
|
+
return true;
|
|
110
|
+
} catch {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function installService(agentDir) {
|
|
117
|
+
const agentScript = path.join(agentDir, 'index.js');
|
|
118
|
+
const nodeBin = process.execPath;
|
|
119
|
+
const serviceScript = path.join(agentDir, 'install-service.sh');
|
|
120
|
+
|
|
121
|
+
console.log('\nInstalling systemd user service...');
|
|
122
|
+
|
|
123
|
+
return new Promise((resolve) => {
|
|
124
|
+
exec(`bash "${serviceScript}" "${nodeBin}" "${agentScript}"`, (err, stdout, stderr) => {
|
|
125
|
+
if (err) {
|
|
126
|
+
console.error('Service installation failed:', err.message);
|
|
127
|
+
if (stderr) console.error(stderr);
|
|
128
|
+
resolve(false);
|
|
129
|
+
} else {
|
|
130
|
+
console.log(stdout);
|
|
131
|
+
resolve(true);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Simple Y/N using a fresh readline (for use after main rl is closed)
|
|
138
|
+
function askYNSimple(question, defaultYes = true) {
|
|
139
|
+
const rlTemp = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
140
|
+
const suffix = defaultYes ? '[Y/n]' : '[y/N]';
|
|
141
|
+
return new Promise(resolve => {
|
|
142
|
+
rlTemp.question(`${question} ${suffix}: `, answer => {
|
|
143
|
+
rlTemp.close();
|
|
144
|
+
const a = answer.trim().toLowerCase();
|
|
145
|
+
if (!a) resolve(defaultYes);
|
|
146
|
+
else resolve(a === 'y' || a === 'yes');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function main() {
|
|
152
|
+
console.log('\n╔════════════════════════════════════╗');
|
|
153
|
+
console.log('║ ClawMoat Local Agent — Setup ║');
|
|
154
|
+
console.log('╚════════════════════════════════════╝\n');
|
|
155
|
+
|
|
156
|
+
// Load existing config if present
|
|
157
|
+
let existing = {};
|
|
158
|
+
try {
|
|
159
|
+
existing = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
|
|
160
|
+
console.log('Found existing config at', CONFIG_PATH);
|
|
161
|
+
} catch {}
|
|
162
|
+
|
|
163
|
+
// API Key
|
|
164
|
+
let apiKey = API_KEY_ARG || existing.apiKey || '';
|
|
165
|
+
if (!apiKey || apiKey === 'cm_live_...') {
|
|
166
|
+
console.log('Get your API key from: https://app.clawmoat.com/settings/api-keys\n');
|
|
167
|
+
apiKey = await ask('Enter your ClawMoat API key (cm_live_...)');
|
|
168
|
+
} else {
|
|
169
|
+
console.log(`API key: ${apiKey.slice(0, 12)}...`);
|
|
170
|
+
const change = await askYN('Change API key?', false);
|
|
171
|
+
if (change) {
|
|
172
|
+
apiKey = await ask('Enter new API key');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Dashboard URL
|
|
177
|
+
const dashboardUrl = await ask('Dashboard URL', existing.dashboardUrl || 'https://app.clawmoat.com');
|
|
178
|
+
|
|
179
|
+
// Test the key
|
|
180
|
+
if (apiKey && apiKey !== 'cm_live_...') {
|
|
181
|
+
process.stdout.write('Testing API key... ');
|
|
182
|
+
const test = await testApiKey(apiKey, dashboardUrl);
|
|
183
|
+
if (test.ok) {
|
|
184
|
+
console.log('✓ OK' + (test.warning ? ` (${test.warning})` : ''));
|
|
185
|
+
} else {
|
|
186
|
+
console.log('✗ Failed:', test.error);
|
|
187
|
+
const cont = await askYN('Continue anyway?', false);
|
|
188
|
+
if (!cont) {
|
|
189
|
+
rl.close();
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Scan settings
|
|
196
|
+
console.log('\nScan settings:');
|
|
197
|
+
const scanInbound = await askYN('Scan inbound messages?', existing.scanInbound !== false);
|
|
198
|
+
const scanOutbound = await askYN('Scan outbound messages?', existing.scanOutbound !== false);
|
|
199
|
+
const scanToolCalls = await askYN('Scan tool calls?', existing.scanToolCalls !== false);
|
|
200
|
+
const reportToCloud = await askYN('Report findings to cloud dashboard?', existing.reportToCloud !== false);
|
|
201
|
+
|
|
202
|
+
// Write config
|
|
203
|
+
const config = {
|
|
204
|
+
apiKey,
|
|
205
|
+
dashboardUrl,
|
|
206
|
+
scanInbound,
|
|
207
|
+
scanOutbound,
|
|
208
|
+
scanToolCalls,
|
|
209
|
+
auditLog: existing.auditLog || '~/.clawmoat/audit.log',
|
|
210
|
+
reportToCloud,
|
|
211
|
+
updatedAt: new Date().toISOString(),
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
215
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
216
|
+
fs.chmodSync(CONFIG_PATH, 0o600);
|
|
217
|
+
console.log(`\n✓ Config written to ${CONFIG_PATH}`);
|
|
218
|
+
|
|
219
|
+
// Ensure audit log dir exists
|
|
220
|
+
fs.mkdirSync(path.dirname(AUDIT_LOG), { recursive: true });
|
|
221
|
+
if (!fs.existsSync(AUDIT_LOG)) {
|
|
222
|
+
fs.writeFileSync(AUDIT_LOG, '');
|
|
223
|
+
console.log(`✓ Audit log initialized at ${AUDIT_LOG}`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Service installation
|
|
227
|
+
if (!NO_SERVICE) {
|
|
228
|
+
const hasSystemd = detectSystemd();
|
|
229
|
+
const isWSL = fs.existsSync('/proc/version') &&
|
|
230
|
+
fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
|
|
231
|
+
|
|
232
|
+
if (isWSL) {
|
|
233
|
+
console.log('\nNote: Running in WSL2. Systemd service requires systemd enabled in WSL.');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (hasSystemd) {
|
|
237
|
+
const installSvc = await askYN('\nInstall as systemd user service (auto-start)?', true);
|
|
238
|
+
if (installSvc) {
|
|
239
|
+
const agentDir = path.dirname(__filename);
|
|
240
|
+
await installService(agentDir);
|
|
241
|
+
}
|
|
242
|
+
} else {
|
|
243
|
+
console.log('\nSystemd not available. To run manually:');
|
|
244
|
+
console.log(` node ${path.join(path.dirname(__filename), 'index.js')}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// AI Provider setup
|
|
249
|
+
rl.close(); // close current rl before handing off
|
|
250
|
+
const setupProviders = await askYNSimple('\nConfigure AI providers (Claude / ChatGPT / Kimi)?', true);
|
|
251
|
+
if (setupProviders) {
|
|
252
|
+
try {
|
|
253
|
+
const { cmdSetup } = require('./provider-setup');
|
|
254
|
+
await cmdSetup();
|
|
255
|
+
} catch (e) {
|
|
256
|
+
console.log(`\nProvider setup skipped: ${e.message}`);
|
|
257
|
+
console.log('Run later with: clawmoat providers setup');
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
console.log('\n✓ Setup complete!\n');
|
|
262
|
+
console.log('To start the agent:');
|
|
263
|
+
console.log(` node ${path.join(path.dirname(__filename), 'index.js')}`);
|
|
264
|
+
console.log('\nTo run in verbose mode:');
|
|
265
|
+
console.log(` node ${path.join(path.dirname(__filename), 'index.js')} --verbose`);
|
|
266
|
+
console.log('\nTo reconfigure providers:');
|
|
267
|
+
console.log(' clawmoat providers setup');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
main().catch(e => {
|
|
271
|
+
console.error('Setup failed:', e);
|
|
272
|
+
rl.close();
|
|
273
|
+
process.exit(1);
|
|
274
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# ClawMoat Security Badges
|
|
2
|
+
|
|
3
|
+
## Quick badge (shields.io)
|
|
4
|
+
```markdown
|
|
5
|
+
[](https://github.com/darfaz/clawmoat)
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
## Static SVG badge
|
|
9
|
+
```markdown
|
|
10
|
+
[](https://github.com/darfaz/clawmoat)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## HTML version
|
|
14
|
+
```html
|
|
15
|
+
<a href="https://github.com/darfaz/clawmoat">
|
|
16
|
+
<img src="https://img.shields.io/badge/🛡️_ClawMoat-secured-brightgreen" alt="ClawMoat Security">
|
|
17
|
+
</a>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Add this to your README to show your project uses ClawMoat for runtime security.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="174" height="20" role="img" aria-label="ClawMoat: secured">
|
|
2
|
+
<title>ClawMoat: secured</title>
|
|
3
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
4
|
+
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
5
|
+
<stop offset="1" stop-opacity=".1"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<clipPath id="r">
|
|
8
|
+
<rect width="174" height="20" rx="3" fill="#fff"/>
|
|
9
|
+
</clipPath>
|
|
10
|
+
<g clip-path="url(#r)">
|
|
11
|
+
<rect width="95" height="20" fill="#555"/>
|
|
12
|
+
<rect x="95" width="79" height="20" fill="#4c1"/>
|
|
13
|
+
<rect width="174" height="20" fill="url(#s)"/>
|
|
14
|
+
</g>
|
|
15
|
+
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
|
|
16
|
+
<text aria-hidden="true" x="485" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="850" lengthAdjust="spacing">🛡️ ClawMoat</text>
|
|
17
|
+
<text x="485" y="140" transform="scale(.1)" fill="#fff" textLength="850" lengthAdjust="spacing">🛡️ ClawMoat</text>
|
|
18
|
+
<text aria-hidden="true" x="1335" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="690" lengthAdjust="spacing">secured</text>
|
|
19
|
+
<text x="1335" y="140" transform="scale(.1)" fill="#fff" textLength="690" lengthAdjust="spacing">secured</text>
|
|
20
|
+
</g>
|
|
21
|
+
</svg>
|