cipher-security 5.1.0 → 5.2.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/cipher.js +103 -50
- package/lib/gateway/commands.js +14 -8
- package/package.json +1 -1
package/bin/cipher.js
CHANGED
|
@@ -23,61 +23,81 @@ import { spawn } from 'node:child_process';
|
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
24
24
|
|
|
25
25
|
const args = process.argv.slice(2);
|
|
26
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
27
|
+
const pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf8'));
|
|
26
28
|
|
|
27
29
|
if (args[0] === '--version' || args[0] === '-V') {
|
|
28
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
29
|
-
const pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf8'));
|
|
30
30
|
console.log(pkg.version);
|
|
31
31
|
process.exit(0);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
if (args[0] === '--help' || args[0] === '-h') {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
35
|
+
const CYN = '\x1b[36m';
|
|
36
|
+
const B = '\x1b[1m';
|
|
37
|
+
const D = '\x1b[2m';
|
|
38
|
+
const R = '\x1b[0m';
|
|
39
|
+
const GRN = '\x1b[32m';
|
|
40
|
+
|
|
41
|
+
console.log(`${CYN}${B}
|
|
42
|
+
██████╗██╗██████╗ ██╗ ██╗███████╗██████╗
|
|
43
|
+
██╔════╝██║██╔══██╗██║ ██║██╔════╝██╔══██╗
|
|
44
|
+
██║ ██║██████╔╝███████║█████╗ ██████╔╝
|
|
45
|
+
██║ ██║██╔═══╝ ██╔══██║██╔══╝ ██╔══██╗
|
|
46
|
+
╚██████╗██║██║ ██║ ██║███████╗██║ ██║
|
|
47
|
+
╚═════╝╚═╝╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝${R}
|
|
48
|
+
${D}Claude Integrated Privacy & Hardening Expert Resource${R} ${D}v${pkg.version}${R}
|
|
49
|
+
|
|
50
|
+
${B}Usage:${R} cipher [command] [options]
|
|
51
|
+
cipher <query> ${D}Freeform security query${R}
|
|
52
|
+
|
|
53
|
+
${B}Commands:${R}
|
|
54
|
+
${GRN}query${R} Run a security query
|
|
55
|
+
${GRN}scan${R} Run a security scan
|
|
56
|
+
${GRN}compliance${R} Run compliance checks (39 frameworks)
|
|
57
|
+
${GRN}search${R} Search security data
|
|
58
|
+
${GRN}osint${R} OSINT intelligence tools
|
|
59
|
+
${GRN}diff${R} Analyze git diff for security issues
|
|
60
|
+
${GRN}sarif${R} SARIF report tools
|
|
61
|
+
|
|
62
|
+
${GRN}status${R} Show system status
|
|
63
|
+
${GRN}doctor${R} Diagnose installation health
|
|
64
|
+
${GRN}version${R} Print version information
|
|
65
|
+
${GRN}setup${R} Run setup wizard
|
|
66
|
+
${GRN}update${R} Update CIPHER to latest version
|
|
67
|
+
|
|
68
|
+
${GRN}domains${R} List skill domains
|
|
69
|
+
${GRN}skills${R} Search skills
|
|
70
|
+
${GRN}store${R} Store findings in memory
|
|
71
|
+
${GRN}stats${R} Show statistics
|
|
72
|
+
${GRN}leaderboard${R} Skill effectiveness metrics
|
|
73
|
+
${GRN}marketplace${R} Browse skill marketplace
|
|
74
|
+
|
|
75
|
+
${GRN}api${R} Start REST API server
|
|
76
|
+
${GRN}mcp${R} Start MCP server (stdio)
|
|
77
|
+
${GRN}bot${R} Start Signal bot
|
|
78
|
+
|
|
79
|
+
${GRN}workflow${R} Generate CI/CD security workflow
|
|
80
|
+
${GRN}memory-export${R} Export memory to JSON
|
|
81
|
+
${GRN}memory-import${R} Import memory from JSON
|
|
82
|
+
${GRN}feedback${R} Run skill improvement loop
|
|
83
|
+
${GRN}ingest${R} Re-index knowledge base
|
|
84
|
+
${GRN}plugin${R} Manage plugins
|
|
85
|
+
${GRN}setup-signal${R} Configure Signal integration
|
|
86
|
+
${GRN}score${R} Score response quality
|
|
87
|
+
${GRN}dashboard${R} System dashboard
|
|
88
|
+
${GRN}web${R} Web interface (use cipher api)
|
|
89
|
+
|
|
90
|
+
${B}Options:${R}
|
|
74
91
|
--version, -V Print version and exit
|
|
75
92
|
--help, -h Print this help and exit
|
|
93
|
+
--autonomous Run in autonomous mode (cipher blue --autonomous "task")
|
|
94
|
+
--backend Override LLM backend (ollama, claude, litellm)
|
|
95
|
+
--no-stream Disable streaming output
|
|
76
96
|
|
|
77
|
-
Environment
|
|
97
|
+
${B}Environment:${R}
|
|
78
98
|
CIPHER_DEBUG=1 Enable verbose debug logging
|
|
79
99
|
|
|
80
|
-
Documentation: https://github.com/defconxt/CIPHER`);
|
|
100
|
+
${D}Documentation: https://github.com/defconxt/CIPHER${R}`);
|
|
81
101
|
process.exit(0);
|
|
82
102
|
}
|
|
83
103
|
|
|
@@ -274,7 +294,7 @@ async function formatBridgeResult(result, commandName = '') {
|
|
|
274
294
|
|
|
275
295
|
if (commandName === 'doctor' && result.checks) {
|
|
276
296
|
const { header, formatDoctorChecks, divider, success, warn } = await import('../lib/brand.js');
|
|
277
|
-
header('Health Check'
|
|
297
|
+
header('Health Check');
|
|
278
298
|
divider();
|
|
279
299
|
process.stderr.write(formatDoctorChecks(result.checks) + '\n');
|
|
280
300
|
divider();
|
|
@@ -287,6 +307,20 @@ async function formatBridgeResult(result, commandName = '') {
|
|
|
287
307
|
return;
|
|
288
308
|
}
|
|
289
309
|
|
|
310
|
+
if (commandName === 'status' && result.status) {
|
|
311
|
+
const { header, status: statusDot, divider } = await import('../lib/brand.js');
|
|
312
|
+
header('Status');
|
|
313
|
+
divider();
|
|
314
|
+
statusDot('Backend', result.backend ? 'ok' : 'warn', result.backend || 'not configured');
|
|
315
|
+
statusDot('Config', result.config?.valid ? 'ok' : 'fail', result.config?.valid ? 'valid' : 'invalid or missing');
|
|
316
|
+
if (result.memory) {
|
|
317
|
+
statusDot('Memory', 'ok', `${result.memory.total} entries (${result.memory.active} active)`);
|
|
318
|
+
}
|
|
319
|
+
divider();
|
|
320
|
+
console.log(JSON.stringify(result, null, 2));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
|
|
290
324
|
// Text-mode result — print output directly (pre-formatted from CliRunner)
|
|
291
325
|
if ('output' in result) {
|
|
292
326
|
if (result.output) {
|
|
@@ -298,8 +332,10 @@ async function formatBridgeResult(result, commandName = '') {
|
|
|
298
332
|
return;
|
|
299
333
|
}
|
|
300
334
|
|
|
301
|
-
// Structured JSON result — pretty-print
|
|
302
|
-
|
|
335
|
+
// Structured JSON result — pretty-print (skip empty objects from branded commands)
|
|
336
|
+
if (Object.keys(result).length > 0) {
|
|
337
|
+
console.log(JSON.stringify(result, null, 2));
|
|
338
|
+
}
|
|
303
339
|
return;
|
|
304
340
|
}
|
|
305
341
|
|
|
@@ -430,11 +466,28 @@ if (mode === 'native') {
|
|
|
430
466
|
mcp.startStdio();
|
|
431
467
|
// ── Bot command: Signal bot ──────────────────────────────────────────
|
|
432
468
|
} else if (command === 'bot') {
|
|
469
|
+
const { banner, header, info, warn, divider } = await import('../lib/brand.js');
|
|
470
|
+
const svc = commandArgs.find((a, i) => commandArgs[i - 1] === '--service') || process.env.SIGNAL_SERVICE || '';
|
|
471
|
+
const phone = commandArgs.find((a, i) => commandArgs[i - 1] === '--phone') || process.env.SIGNAL_PHONE_NUMBER || '';
|
|
472
|
+
|
|
473
|
+
banner(pkg.version);
|
|
474
|
+
header('Signal Bot');
|
|
475
|
+
|
|
476
|
+
if (!svc || !phone) {
|
|
477
|
+
divider();
|
|
478
|
+
warn('Signal is not configured.');
|
|
479
|
+
info('Run: cipher setup-signal');
|
|
480
|
+
divider();
|
|
481
|
+
process.exit(1);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
info(`Service: ${svc}`);
|
|
485
|
+
info(`Phone: ${phone}`);
|
|
486
|
+
divider();
|
|
487
|
+
info('Starting bot...');
|
|
488
|
+
|
|
433
489
|
const { runBot } = await import('../lib/bot/bot.js');
|
|
434
|
-
runBot({
|
|
435
|
-
signalService: commandArgs.find((a, i) => commandArgs[i - 1] === '--service') || '',
|
|
436
|
-
phoneNumber: commandArgs.find((a, i) => commandArgs[i - 1] === '--phone') || '',
|
|
437
|
-
});
|
|
490
|
+
runBot({ signalService: svc, phoneNumber: phone });
|
|
438
491
|
// ── Query command: streaming via Gateway or non-streaming via handler ──
|
|
439
492
|
} else if (command === 'query') {
|
|
440
493
|
const queryText = commandArgs.filter(a => !a.startsWith('-')).join(' ');
|
package/lib/gateway/commands.js
CHANGED
|
@@ -821,12 +821,18 @@ export async function handleWeb(args = {}) {
|
|
|
821
821
|
// ---------------------------------------------------------------------------
|
|
822
822
|
|
|
823
823
|
export async function handleSetupSignal() {
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
824
|
+
const brand = await import('../brand.js');
|
|
825
|
+
brand.header('Signal Setup');
|
|
826
|
+
brand.divider();
|
|
827
|
+
brand.info('Set the following environment variables:');
|
|
828
|
+
process.stderr.write('\n');
|
|
829
|
+
process.stderr.write(' SIGNAL_SERVICE Signal API service URL\n');
|
|
830
|
+
process.stderr.write(' SIGNAL_PHONE_NUMBER Bot phone number (E.164 format)\n');
|
|
831
|
+
process.stderr.write(' SIGNAL_WHITELIST Comma-separated allowed numbers\n');
|
|
832
|
+
process.stderr.write('\n');
|
|
833
|
+
brand.info('Then run: cipher bot');
|
|
834
|
+
brand.divider();
|
|
835
|
+
return {};
|
|
830
836
|
}
|
|
831
837
|
|
|
832
838
|
// ---------------------------------------------------------------------------
|
|
@@ -857,7 +863,7 @@ export async function handleUpdate(args = {}) {
|
|
|
857
863
|
|
|
858
864
|
if (latest === currentVersion) {
|
|
859
865
|
brand.success(`Already up to date (${currentVersion})`);
|
|
860
|
-
return {
|
|
866
|
+
return {};
|
|
861
867
|
}
|
|
862
868
|
|
|
863
869
|
brand.warn(`New version available: ${latest}`);
|
|
@@ -870,7 +876,7 @@ export async function handleUpdate(args = {}) {
|
|
|
870
876
|
});
|
|
871
877
|
|
|
872
878
|
brand.success(`Updated ${currentVersion} → ${latest}`);
|
|
873
|
-
return {
|
|
879
|
+
return {};
|
|
874
880
|
} catch (err) {
|
|
875
881
|
brand.error(`Update failed: ${err.message}`);
|
|
876
882
|
return { error: true, message: `Update failed: ${err.message}` };
|