chainlesschain 0.66.0 → 0.81.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/package.json +1 -1
- package/src/commands/a2a.js +380 -0
- package/src/commands/bi.js +348 -0
- package/src/commands/crosschain.js +218 -0
- package/src/commands/dlp.js +341 -0
- package/src/commands/evomap.js +394 -0
- package/src/commands/federation.js +283 -0
- package/src/commands/inference.js +318 -0
- package/src/commands/lowcode.js +356 -0
- package/src/commands/marketplace.js +256 -0
- package/src/commands/privacy.js +321 -0
- package/src/commands/reputation.js +261 -0
- package/src/commands/siem.js +246 -0
- package/src/commands/sla.js +259 -0
- package/src/commands/stress.js +230 -0
- package/src/commands/terraform.js +245 -0
- package/src/commands/zkp.js +335 -0
- package/src/lib/a2a-protocol.js +451 -0
- package/src/lib/app-builder.js +239 -0
- package/src/lib/bi-engine.js +338 -0
- package/src/lib/cross-chain.js +345 -0
- package/src/lib/dlp-engine.js +389 -0
- package/src/lib/evomap-federation.js +177 -0
- package/src/lib/evomap-governance.js +276 -0
- package/src/lib/federation-hardening.js +259 -0
- package/src/lib/inference-network.js +330 -0
- package/src/lib/privacy-computing.js +427 -0
- package/src/lib/reputation-optimizer.js +299 -0
- package/src/lib/siem-exporter.js +333 -0
- package/src/lib/skill-marketplace.js +325 -0
- package/src/lib/sla-manager.js +275 -0
- package/src/lib/stress-tester.js +330 -0
- package/src/lib/terraform-manager.js +363 -0
- package/src/lib/zkp-engine.js +274 -0
|
@@ -18,6 +18,22 @@ import {
|
|
|
18
18
|
listOptimizationRuns,
|
|
19
19
|
applyOptimizedParams,
|
|
20
20
|
OPTIMIZATION_OBJECTIVES,
|
|
21
|
+
// V2 (Phase 60)
|
|
22
|
+
RUN_STATUS_V2,
|
|
23
|
+
OBJECTIVE_V2,
|
|
24
|
+
DECAY_MODEL_V2,
|
|
25
|
+
ANOMALY_METHOD_V2,
|
|
26
|
+
REPUTATION_DEFAULT_MAX_CONCURRENT,
|
|
27
|
+
setMaxConcurrentOptimizations,
|
|
28
|
+
getMaxConcurrentOptimizations,
|
|
29
|
+
getActiveOptimizationCount,
|
|
30
|
+
startOptimizationV2,
|
|
31
|
+
completeOptimization,
|
|
32
|
+
cancelOptimization,
|
|
33
|
+
failOptimization,
|
|
34
|
+
applyOptimization,
|
|
35
|
+
setRunStatus,
|
|
36
|
+
getReputationStatsV2,
|
|
21
37
|
} from "../lib/reputation-optimizer.js";
|
|
22
38
|
|
|
23
39
|
function _dbFromCtx(ctx) {
|
|
@@ -346,4 +362,249 @@ export function registerReputationCommand(program) {
|
|
|
346
362
|
for (const v of values) logger.log(` ${chalk.cyan(v)}`);
|
|
347
363
|
}
|
|
348
364
|
});
|
|
365
|
+
|
|
366
|
+
/* ── V2 (Phase 60) ───────────────────────────────────────── */
|
|
367
|
+
|
|
368
|
+
rep
|
|
369
|
+
.command("run-statuses")
|
|
370
|
+
.description(
|
|
371
|
+
"List V2 run statuses (running/complete/applied/failed/cancelled)",
|
|
372
|
+
)
|
|
373
|
+
.option("--json", "Output as JSON")
|
|
374
|
+
.action((options) => {
|
|
375
|
+
const values = Object.values(RUN_STATUS_V2);
|
|
376
|
+
if (options.json) console.log(JSON.stringify(values, null, 2));
|
|
377
|
+
else for (const v of values) logger.log(` ${chalk.cyan(v)}`);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
rep
|
|
381
|
+
.command("v2-objectives")
|
|
382
|
+
.description("List V2 objectives (frozen enum)")
|
|
383
|
+
.option("--json", "Output as JSON")
|
|
384
|
+
.action((options) => {
|
|
385
|
+
const values = Object.values(OBJECTIVE_V2);
|
|
386
|
+
if (options.json) console.log(JSON.stringify(values, null, 2));
|
|
387
|
+
else for (const v of values) logger.log(` ${chalk.cyan(v)}`);
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
rep
|
|
391
|
+
.command("decay-models")
|
|
392
|
+
.description("List V2 decay models (frozen enum)")
|
|
393
|
+
.option("--json", "Output as JSON")
|
|
394
|
+
.action((options) => {
|
|
395
|
+
const values = Object.values(DECAY_MODEL_V2);
|
|
396
|
+
if (options.json) console.log(JSON.stringify(values, null, 2));
|
|
397
|
+
else for (const v of values) logger.log(` ${chalk.cyan(v)}`);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
rep
|
|
401
|
+
.command("anomaly-methods")
|
|
402
|
+
.description("List V2 anomaly methods (frozen enum)")
|
|
403
|
+
.option("--json", "Output as JSON")
|
|
404
|
+
.action((options) => {
|
|
405
|
+
const values = Object.values(ANOMALY_METHOD_V2);
|
|
406
|
+
if (options.json) console.log(JSON.stringify(values, null, 2));
|
|
407
|
+
else for (const v of values) logger.log(` ${chalk.cyan(v)}`);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
rep
|
|
411
|
+
.command("default-max-concurrent")
|
|
412
|
+
.description("Show default max concurrent optimizations")
|
|
413
|
+
.action(() => {
|
|
414
|
+
logger.log(` ${REPUTATION_DEFAULT_MAX_CONCURRENT}`);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
rep
|
|
418
|
+
.command("max-concurrent")
|
|
419
|
+
.description("Show current max concurrent optimizations")
|
|
420
|
+
.action(() => {
|
|
421
|
+
logger.log(` ${getMaxConcurrentOptimizations()}`);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
rep
|
|
425
|
+
.command("active-optimization-count")
|
|
426
|
+
.description("Show count of currently-RUNNING optimizations")
|
|
427
|
+
.action(() => {
|
|
428
|
+
logger.log(` ${getActiveOptimizationCount()}`);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
rep
|
|
432
|
+
.command("set-max-concurrent <n>")
|
|
433
|
+
.description("Set the concurrency cap for RUNNING optimizations")
|
|
434
|
+
.action((n) => {
|
|
435
|
+
try {
|
|
436
|
+
const v = setMaxConcurrentOptimizations(Number(n));
|
|
437
|
+
logger.success(`Max concurrent = ${v}`);
|
|
438
|
+
} catch (err) {
|
|
439
|
+
logger.error(`Failed: ${err.message}`);
|
|
440
|
+
process.exit(1);
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
rep
|
|
445
|
+
.command("start-v2")
|
|
446
|
+
.description(
|
|
447
|
+
"Start a V2 optimization (RUNNING only, driven by complete/cancel/fail)",
|
|
448
|
+
)
|
|
449
|
+
.option(
|
|
450
|
+
"-o, --objective <name>",
|
|
451
|
+
"Objective (accuracy|fairness|resilience|convergence_speed)",
|
|
452
|
+
"accuracy",
|
|
453
|
+
)
|
|
454
|
+
.option("-i, --iterations <n>", "Iteration count", parseInt, 50)
|
|
455
|
+
.option("--json", "Output as JSON")
|
|
456
|
+
.action(async (options) => {
|
|
457
|
+
try {
|
|
458
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
459
|
+
const db = _dbFromCtx(ctx);
|
|
460
|
+
const run = startOptimizationV2(db, {
|
|
461
|
+
objective: options.objective,
|
|
462
|
+
iterations: options.iterations,
|
|
463
|
+
});
|
|
464
|
+
if (options.json) console.log(JSON.stringify(run, null, 2));
|
|
465
|
+
else {
|
|
466
|
+
logger.success(`Optimization started [${run.status}]`);
|
|
467
|
+
logger.log(` ${chalk.bold("Run ID:")} ${chalk.cyan(run.runId)}`);
|
|
468
|
+
logger.log(` ${chalk.bold("Objective:")} ${run.objective}`);
|
|
469
|
+
logger.log(` ${chalk.bold("Iterations:")} ${run.iterations}`);
|
|
470
|
+
}
|
|
471
|
+
await shutdown();
|
|
472
|
+
} catch (err) {
|
|
473
|
+
logger.error(`Failed: ${err.message}`);
|
|
474
|
+
process.exit(1);
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
rep
|
|
479
|
+
.command("complete <run-id>")
|
|
480
|
+
.description(
|
|
481
|
+
"Complete a V2 optimization (RUNNING → COMPLETE, runs iterations)",
|
|
482
|
+
)
|
|
483
|
+
.option("--json", "Output as JSON")
|
|
484
|
+
.action(async (runId, options) => {
|
|
485
|
+
try {
|
|
486
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
487
|
+
const db = _dbFromCtx(ctx);
|
|
488
|
+
const result = completeOptimization(db, runId);
|
|
489
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
490
|
+
else {
|
|
491
|
+
logger.success(`Completed [${result.status}]`);
|
|
492
|
+
logger.log(` ${chalk.bold("Best score:")} ${result.bestScore}`);
|
|
493
|
+
logger.log(
|
|
494
|
+
` ${chalk.bold("Best params:")} ${JSON.stringify(result.bestParams)}`,
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
await shutdown();
|
|
498
|
+
} catch (err) {
|
|
499
|
+
logger.error(`Failed: ${err.message}`);
|
|
500
|
+
process.exit(1);
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
rep
|
|
505
|
+
.command("cancel <run-id>")
|
|
506
|
+
.description("Cancel a V2 RUNNING optimization")
|
|
507
|
+
.action(async (runId) => {
|
|
508
|
+
try {
|
|
509
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
510
|
+
const db = _dbFromCtx(ctx);
|
|
511
|
+
const result = cancelOptimization(db, runId);
|
|
512
|
+
logger.success(`Cancelled [${result.status}]`);
|
|
513
|
+
await shutdown();
|
|
514
|
+
} catch (err) {
|
|
515
|
+
logger.error(`Failed: ${err.message}`);
|
|
516
|
+
process.exit(1);
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
rep
|
|
521
|
+
.command("fail <run-id>")
|
|
522
|
+
.description("Fail a V2 RUNNING optimization")
|
|
523
|
+
.option("--message <msg>", "Error message")
|
|
524
|
+
.action(async (runId, options) => {
|
|
525
|
+
try {
|
|
526
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
527
|
+
const db = _dbFromCtx(ctx);
|
|
528
|
+
const result = failOptimization(db, runId, options.message);
|
|
529
|
+
logger.success(`Failed [${result.status}]`);
|
|
530
|
+
if (result.errorMessage)
|
|
531
|
+
logger.log(` ${chalk.bold("Error:")} ${result.errorMessage}`);
|
|
532
|
+
await shutdown();
|
|
533
|
+
} catch (err) {
|
|
534
|
+
logger.error(`Failed: ${err.message}`);
|
|
535
|
+
process.exit(1);
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
rep
|
|
540
|
+
.command("apply-v2 <run-id>")
|
|
541
|
+
.description("Apply a V2 COMPLETE optimization (COMPLETE → APPLIED)")
|
|
542
|
+
.action(async (runId) => {
|
|
543
|
+
try {
|
|
544
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
545
|
+
const db = _dbFromCtx(ctx);
|
|
546
|
+
const result = applyOptimization(db, runId);
|
|
547
|
+
logger.success(`Applied [${result.status}]`);
|
|
548
|
+
await shutdown();
|
|
549
|
+
} catch (err) {
|
|
550
|
+
logger.error(`Failed: ${err.message}`);
|
|
551
|
+
process.exit(1);
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
rep
|
|
556
|
+
.command("set-status <run-id> <status>")
|
|
557
|
+
.description("Set V2 run status via the state machine")
|
|
558
|
+
.option("--message <msg>", "Error message (FAILED only)")
|
|
559
|
+
.option("--json", "Output as JSON")
|
|
560
|
+
.action(async (runId, status, options) => {
|
|
561
|
+
try {
|
|
562
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
563
|
+
const db = _dbFromCtx(ctx);
|
|
564
|
+
const patch = options.message ? { errorMessage: options.message } : {};
|
|
565
|
+
const result = setRunStatus(db, runId, status, patch);
|
|
566
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
567
|
+
else logger.success(`Status = ${result.status}`);
|
|
568
|
+
await shutdown();
|
|
569
|
+
} catch (err) {
|
|
570
|
+
logger.error(`Failed: ${err.message}`);
|
|
571
|
+
process.exit(1);
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
rep
|
|
576
|
+
.command("stats-v2")
|
|
577
|
+
.description("V2 aggregated stats")
|
|
578
|
+
.option("--json", "Output as JSON")
|
|
579
|
+
.action(async (options) => {
|
|
580
|
+
try {
|
|
581
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
582
|
+
_dbFromCtx(ctx);
|
|
583
|
+
const stats = getReputationStatsV2();
|
|
584
|
+
if (options.json) console.log(JSON.stringify(stats, null, 2));
|
|
585
|
+
else {
|
|
586
|
+
logger.log(` ${chalk.bold("Total runs:")} ${stats.totalRuns}`);
|
|
587
|
+
logger.log(` ${chalk.bold("Active:")} ${stats.activeRuns}`);
|
|
588
|
+
logger.log(
|
|
589
|
+
` ${chalk.bold("Max concurrent:")} ${stats.maxConcurrentOptimizations}`,
|
|
590
|
+
);
|
|
591
|
+
logger.log(` ${chalk.bold("By status:")}`);
|
|
592
|
+
for (const [k, v] of Object.entries(stats.byStatus))
|
|
593
|
+
logger.log(` ${k.padEnd(12)} ${v}`);
|
|
594
|
+
logger.log(` ${chalk.bold("By objective:")}`);
|
|
595
|
+
for (const [k, v] of Object.entries(stats.byObjective))
|
|
596
|
+
logger.log(` ${k.padEnd(20)} ${v}`);
|
|
597
|
+
logger.log(
|
|
598
|
+
` ${chalk.bold("Observations:")} ${stats.observations.totalObservations} (${stats.observations.totalDids} DIDs)`,
|
|
599
|
+
);
|
|
600
|
+
logger.log(
|
|
601
|
+
` ${chalk.bold("Best score ever:")} ${stats.bestScoreEver}`,
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
await shutdown();
|
|
605
|
+
} catch (err) {
|
|
606
|
+
logger.error(`Failed: ${err.message}`);
|
|
607
|
+
process.exit(1);
|
|
608
|
+
}
|
|
609
|
+
});
|
|
349
610
|
}
|
package/src/commands/siem.js
CHANGED
|
@@ -12,6 +12,19 @@ import {
|
|
|
12
12
|
addTarget,
|
|
13
13
|
exportLogs,
|
|
14
14
|
getSIEMStats,
|
|
15
|
+
SIEM_FORMAT,
|
|
16
|
+
SIEM_TARGET_TYPE,
|
|
17
|
+
SIEM_SEVERITY,
|
|
18
|
+
SIEM_TARGET_STATUS,
|
|
19
|
+
SIEM_DEFAULT_BATCH_SIZE,
|
|
20
|
+
severityToCEF,
|
|
21
|
+
formatLog,
|
|
22
|
+
addTargetV2,
|
|
23
|
+
removeTarget,
|
|
24
|
+
setTargetStatus,
|
|
25
|
+
exportLogsV2,
|
|
26
|
+
getSIEMStatsV2,
|
|
27
|
+
listTargetsByStatus,
|
|
15
28
|
} from "../lib/siem-exporter.js";
|
|
16
29
|
|
|
17
30
|
export function registerSiemCommand(program) {
|
|
@@ -147,6 +160,239 @@ export function registerSiemCommand(program) {
|
|
|
147
160
|
}
|
|
148
161
|
}
|
|
149
162
|
|
|
163
|
+
await shutdown();
|
|
164
|
+
} catch (err) {
|
|
165
|
+
logger.error(`Failed: ${err.message}`);
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// ═══════════════════════════════════════════════════════════════
|
|
171
|
+
// V2 Canonical Subcommands (Phase 51)
|
|
172
|
+
// ═══════════════════════════════════════════════════════════════
|
|
173
|
+
|
|
174
|
+
siem
|
|
175
|
+
.command("formats")
|
|
176
|
+
.description("List SIEM export formats (V2)")
|
|
177
|
+
.action(() => {
|
|
178
|
+
console.log(JSON.stringify(Object.values(SIEM_FORMAT), null, 2));
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
siem
|
|
182
|
+
.command("target-types")
|
|
183
|
+
.description("List SIEM target types (V2)")
|
|
184
|
+
.action(() => {
|
|
185
|
+
console.log(JSON.stringify(Object.values(SIEM_TARGET_TYPE), null, 2));
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
siem
|
|
189
|
+
.command("severities")
|
|
190
|
+
.description("List SIEM severity levels (V2)")
|
|
191
|
+
.action(() => {
|
|
192
|
+
console.log(JSON.stringify(Object.values(SIEM_SEVERITY), null, 2));
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
siem
|
|
196
|
+
.command("statuses")
|
|
197
|
+
.description("List SIEM target statuses (V2)")
|
|
198
|
+
.action(() => {
|
|
199
|
+
console.log(JSON.stringify(Object.values(SIEM_TARGET_STATUS), null, 2));
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
siem
|
|
203
|
+
.command("default-batch-size")
|
|
204
|
+
.description("Show default SIEM batch size (V2)")
|
|
205
|
+
.action(() => {
|
|
206
|
+
console.log(JSON.stringify({ batchSize: SIEM_DEFAULT_BATCH_SIZE }));
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
siem
|
|
210
|
+
.command("severity-cef <severity>")
|
|
211
|
+
.description("Map a SIEM severity to its CEF integer (0-10)")
|
|
212
|
+
.action((severity) => {
|
|
213
|
+
try {
|
|
214
|
+
console.log(JSON.stringify({ severity, cef: severityToCEF(severity) }));
|
|
215
|
+
} catch (err) {
|
|
216
|
+
logger.error(`Failed: ${err.message}`);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
siem
|
|
222
|
+
.command("format-log <format>")
|
|
223
|
+
.description("Format a JSON log payload as cef|leef|json")
|
|
224
|
+
.option("-l, --log <json>", "Log object as JSON", "{}")
|
|
225
|
+
.action((format, options) => {
|
|
226
|
+
try {
|
|
227
|
+
const log = JSON.parse(options.log);
|
|
228
|
+
const result = formatLog(format, log);
|
|
229
|
+
console.log(
|
|
230
|
+
typeof result === "string" ? result : JSON.stringify(result, null, 2),
|
|
231
|
+
);
|
|
232
|
+
} catch (err) {
|
|
233
|
+
logger.error(`Failed: ${err.message}`);
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
siem
|
|
239
|
+
.command("add-target-v2")
|
|
240
|
+
.description("Add a SIEM target via canonical options (V2)")
|
|
241
|
+
.option("-t, --type <type>", "Target type")
|
|
242
|
+
.option("-u, --url <url>", "Target URL")
|
|
243
|
+
.option("-f, --format <fmt>", "Export format", "json")
|
|
244
|
+
.option("-c, --config <json>", "Config JSON", "{}")
|
|
245
|
+
.action(async (options) => {
|
|
246
|
+
try {
|
|
247
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
248
|
+
if (!ctx.db) {
|
|
249
|
+
logger.error("Database not available");
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
const db = ctx.db.getDatabase();
|
|
253
|
+
ensureSIEMTables(db);
|
|
254
|
+
|
|
255
|
+
let config = {};
|
|
256
|
+
try {
|
|
257
|
+
config = JSON.parse(options.config);
|
|
258
|
+
} catch (_err) {
|
|
259
|
+
logger.error("Invalid --config JSON");
|
|
260
|
+
process.exit(1);
|
|
261
|
+
}
|
|
262
|
+
const target = addTargetV2(db, {
|
|
263
|
+
type: options.type,
|
|
264
|
+
url: options.url,
|
|
265
|
+
format: options.format,
|
|
266
|
+
config,
|
|
267
|
+
});
|
|
268
|
+
console.log(JSON.stringify(target, null, 2));
|
|
269
|
+
|
|
270
|
+
await shutdown();
|
|
271
|
+
} catch (err) {
|
|
272
|
+
logger.error(`Failed: ${err.message}`);
|
|
273
|
+
process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
siem
|
|
278
|
+
.command("remove-target <target-id>")
|
|
279
|
+
.description("Remove a SIEM target (V2)")
|
|
280
|
+
.action(async (targetId) => {
|
|
281
|
+
try {
|
|
282
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
283
|
+
if (!ctx.db) {
|
|
284
|
+
logger.error("Database not available");
|
|
285
|
+
process.exit(1);
|
|
286
|
+
}
|
|
287
|
+
const db = ctx.db.getDatabase();
|
|
288
|
+
ensureSIEMTables(db);
|
|
289
|
+
|
|
290
|
+
console.log(JSON.stringify(removeTarget(db, targetId), null, 2));
|
|
291
|
+
|
|
292
|
+
await shutdown();
|
|
293
|
+
} catch (err) {
|
|
294
|
+
logger.error(`Failed: ${err.message}`);
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
siem
|
|
300
|
+
.command("set-status <target-id> <status>")
|
|
301
|
+
.description("Transition a SIEM target's status (V2)")
|
|
302
|
+
.action(async (targetId, status) => {
|
|
303
|
+
try {
|
|
304
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
305
|
+
if (!ctx.db) {
|
|
306
|
+
logger.error("Database not available");
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
309
|
+
const db = ctx.db.getDatabase();
|
|
310
|
+
ensureSIEMTables(db);
|
|
311
|
+
|
|
312
|
+
console.log(
|
|
313
|
+
JSON.stringify(setTargetStatus(db, targetId, status), null, 2),
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
await shutdown();
|
|
317
|
+
} catch (err) {
|
|
318
|
+
logger.error(`Failed: ${err.message}`);
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
siem
|
|
324
|
+
.command("export-v2 <target-id>")
|
|
325
|
+
.description("Batch-export logs to a target (V2)")
|
|
326
|
+
.option("-l, --logs <json>", "Logs as JSON array", "[]")
|
|
327
|
+
.option("-b, --batch-size <n>", "Batch size override")
|
|
328
|
+
.action(async (targetId, options) => {
|
|
329
|
+
try {
|
|
330
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
331
|
+
if (!ctx.db) {
|
|
332
|
+
logger.error("Database not available");
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
const db = ctx.db.getDatabase();
|
|
336
|
+
ensureSIEMTables(db);
|
|
337
|
+
|
|
338
|
+
let logs = [];
|
|
339
|
+
try {
|
|
340
|
+
logs = JSON.parse(options.logs);
|
|
341
|
+
} catch (_err) {
|
|
342
|
+
logger.error("Invalid --logs JSON");
|
|
343
|
+
process.exit(1);
|
|
344
|
+
}
|
|
345
|
+
const r = exportLogsV2(db, {
|
|
346
|
+
targetId,
|
|
347
|
+
logs,
|
|
348
|
+
batchSize: options.batchSize ? Number(options.batchSize) : undefined,
|
|
349
|
+
});
|
|
350
|
+
console.log(JSON.stringify(r, null, 2));
|
|
351
|
+
|
|
352
|
+
await shutdown();
|
|
353
|
+
} catch (err) {
|
|
354
|
+
logger.error(`Failed: ${err.message}`);
|
|
355
|
+
process.exit(1);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
siem
|
|
360
|
+
.command("stats-v2")
|
|
361
|
+
.description("Show extended SIEM stats (byFormat/byType/byStatus, V2)")
|
|
362
|
+
.action(async () => {
|
|
363
|
+
try {
|
|
364
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
365
|
+
if (!ctx.db) {
|
|
366
|
+
logger.error("Database not available");
|
|
367
|
+
process.exit(1);
|
|
368
|
+
}
|
|
369
|
+
const db = ctx.db.getDatabase();
|
|
370
|
+
ensureSIEMTables(db);
|
|
371
|
+
|
|
372
|
+
console.log(JSON.stringify(getSIEMStatsV2(), null, 2));
|
|
373
|
+
|
|
374
|
+
await shutdown();
|
|
375
|
+
} catch (err) {
|
|
376
|
+
logger.error(`Failed: ${err.message}`);
|
|
377
|
+
process.exit(1);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
siem
|
|
382
|
+
.command("by-status <status>")
|
|
383
|
+
.description("List SIEM targets filtered by status (V2)")
|
|
384
|
+
.action(async (status) => {
|
|
385
|
+
try {
|
|
386
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
387
|
+
if (!ctx.db) {
|
|
388
|
+
logger.error("Database not available");
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
391
|
+
const db = ctx.db.getDatabase();
|
|
392
|
+
ensureSIEMTables(db);
|
|
393
|
+
|
|
394
|
+
console.log(JSON.stringify(listTargetsByStatus(status), null, 2));
|
|
395
|
+
|
|
150
396
|
await shutdown();
|
|
151
397
|
} catch (err) {
|
|
152
398
|
logger.error(`Failed: ${err.message}`);
|