@chainpatrol/cli 0.12.0 → 0.14.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/CHANGELOG.md +56 -0
- package/dist/{breakdown-KCTKQNDY.js → breakdown-K5Q6TDKE.js} +21 -6
- package/dist/{check-P5JJJNEX.js → check-NJH7BUIM.js} +1 -1
- package/dist/{chunk-W42ITB5J.js → chunk-6X5BFFXA.js} +77 -5
- package/dist/{chunk-DJVB73FL.js → chunk-BIKTBRER.js} +1 -1
- package/dist/chunk-S37VFIZY.js +66 -0
- package/dist/{chunk-OSRFCVBT.js → chunk-YZEMTNCX.js} +26 -2
- package/dist/cli.js +53 -43
- package/dist/{configs-update-3ZVXGADV.js → configs-update-ON67NMXA.js} +1 -1
- package/dist/{create-DFH2G7RH.js → create-W5S2ZPVC.js} +1 -1
- package/dist/{drift-T74V2C3J.js → drift-ZOLDE24A.js} +1 -1
- package/dist/found-M5MX4VXK.js +59 -0
- package/dist/{healthcheck-HZYEIIOR.js → healthcheck-PFYP6PNW.js} +1 -1
- package/dist/{list-PBAXQSL5.js → list-5TMGSHFC.js} +1 -1
- package/dist/{list-QUFY4IP7.js → list-AHWEE3YZ.js} +1 -1
- package/dist/{list-IYJBKE2F.js → list-B5KLEFHA.js} +1 -1
- package/dist/{list-ZFPML3ZR.js → list-FV5IYCG4.js} +1 -1
- package/dist/{list-23QQYAV5.js → list-GKC7PEU5.js} +1 -1
- package/dist/{list-YCT6DYDI.js → list-HGYBEYOV.js} +1 -1
- package/dist/{list-YRJPN4PI.js → list-ISP5JL4M.js} +1 -1
- package/dist/{list-WX5G3IOF.js → list-LNNIEVB4.js} +2 -2
- package/dist/{list-WJQT2XLE.js → list-TUMVDWIZ.js} +1 -1
- package/dist/{list-I7SBGA52.js → list-VP5IY2SZ.js} +1 -1
- package/dist/{list-EIVPGMWJ.js → list-Z7RJWZH5.js} +1 -1
- package/dist/{list-json-T2Z7NV7G.js → list-json-QC6X25LI.js} +1 -1
- package/dist/organization-VSQQAGBS.js +105 -0
- package/dist/{run-CJGN6TX4.js → run-HRFJORDS.js} +1 -1
- package/dist/{run-BHEXWBAS.js → run-KDNQIR5E.js} +2 -2
- package/dist/{run-MSO6IXEV.js → run-VHFXOCGS.js} +1 -1
- package/dist/{search-WPSKQGUS.js → search-NOSQW75S.js} +1 -1
- package/dist/{setup-skill-FA4STSGA.js → setup-skill-Q6PCFIDE.js} +1 -1
- package/dist/{snapshot-ZWAHEG64.js → snapshot-55UV26NQ.js} +1 -1
- package/dist/{summary-Y2LG6UJM.js → summary-QUCLZYX6.js} +19 -6
- package/dist/{validate-SM5DD7I2.js → validate-TPG47SYS.js} +1 -1
- package/dist/{whoami-DH5HVLFN.js → whoami-Y3ZJGN4O.js} +1 -1
- package/package.json +1 -1
- package/dist/found-EVXJZGYX.js +0 -95
- package/dist/organization-IIIOSTHF.js +0 -75
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveDateRange
|
|
3
|
+
} from "./chunk-S37VFIZY.js";
|
|
4
|
+
import {
|
|
5
|
+
printOutput,
|
|
6
|
+
toCsvRows
|
|
7
|
+
} from "./chunk-VFT3TD3E.js";
|
|
8
|
+
import {
|
|
9
|
+
ORGANIZATION_METRICS_INCLUDE_FIELDS,
|
|
10
|
+
createApiClient
|
|
11
|
+
} from "./chunk-YZEMTNCX.js";
|
|
12
|
+
import "./chunk-EGWK6SRQ.js";
|
|
13
|
+
import "./chunk-TFCNKBRC.js";
|
|
14
|
+
import "./chunk-U73SABXK.js";
|
|
15
|
+
|
|
16
|
+
// src/commands/metrics/organization.ts
|
|
17
|
+
var INCLUDE_VALUES = new Set(ORGANIZATION_METRICS_INCLUDE_FIELDS);
|
|
18
|
+
function parseIncludeList(raw) {
|
|
19
|
+
if (!raw || raw.length === 0) return void 0;
|
|
20
|
+
const fields = [];
|
|
21
|
+
for (const value of raw) {
|
|
22
|
+
if (!INCLUDE_VALUES.has(value)) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Unknown --include value: '${value}'. Allowed: ${ORGANIZATION_METRICS_INCLUDE_FIELDS.join(", ")}`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
fields.push(value);
|
|
28
|
+
}
|
|
29
|
+
return fields;
|
|
30
|
+
}
|
|
31
|
+
async function runMetricsOrganization(options) {
|
|
32
|
+
const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
|
|
33
|
+
const client = options.apiClient ?? createApiClient();
|
|
34
|
+
const range = resolveDateRange({
|
|
35
|
+
from: options.from,
|
|
36
|
+
to: options.to,
|
|
37
|
+
thisWeek: options.thisWeek
|
|
38
|
+
});
|
|
39
|
+
const include = parseIncludeList(options.include);
|
|
40
|
+
const input = {
|
|
41
|
+
organizationSlug: options.org,
|
|
42
|
+
brandSlug: options.brandSlug,
|
|
43
|
+
startDate: range.startDate,
|
|
44
|
+
endDate: range.endDate,
|
|
45
|
+
include
|
|
46
|
+
};
|
|
47
|
+
const result = await client.getOrganizationMetrics(input);
|
|
48
|
+
const label = options.org ?? "your organization";
|
|
49
|
+
const includeLabel = include ? ` (include: ${include.join(", ")})` : "";
|
|
50
|
+
const metricLines = [
|
|
51
|
+
["Reports", result.metrics.reports],
|
|
52
|
+
["New threats", result.metrics.newThreats],
|
|
53
|
+
["Watchlisted threats", result.metrics.threatsWatchlisted],
|
|
54
|
+
["Takedowns filed", result.metrics.takedownsFiled],
|
|
55
|
+
["Takedowns completed", result.metrics.takedownsCompleted],
|
|
56
|
+
["Domain threats", result.metrics.domainThreats],
|
|
57
|
+
["Twitter threats", result.metrics.twitterThreats],
|
|
58
|
+
["Telegram threats", result.metrics.telegramThreats],
|
|
59
|
+
["Other threats", result.metrics.otherThreats]
|
|
60
|
+
];
|
|
61
|
+
const populatedMetricLines = metricLines.filter(([, value]) => value !== null);
|
|
62
|
+
printOutput({
|
|
63
|
+
outputFormat,
|
|
64
|
+
json: { ...result, range, include: include ?? null },
|
|
65
|
+
markdown: [
|
|
66
|
+
`# Organization Metrics (${label}) \u2014 ${range.label}${includeLabel}`,
|
|
67
|
+
"",
|
|
68
|
+
`- Range: ${range.startDate} \u2192 ${range.endDate}`,
|
|
69
|
+
...populatedMetricLines.map(([name, value]) => `- ${name}: ${value}`)
|
|
70
|
+
].join("\n"),
|
|
71
|
+
csv: toCsvRows([
|
|
72
|
+
{
|
|
73
|
+
rangeLabel: range.label,
|
|
74
|
+
startDate: range.startDate,
|
|
75
|
+
endDate: range.endDate,
|
|
76
|
+
reports: result.metrics.reports,
|
|
77
|
+
newThreats: result.metrics.newThreats,
|
|
78
|
+
threatsWatchlisted: result.metrics.threatsWatchlisted,
|
|
79
|
+
takedownsFiled: result.metrics.takedownsFiled,
|
|
80
|
+
takedownsCompleted: result.metrics.takedownsCompleted,
|
|
81
|
+
domainThreats: result.metrics.domainThreats,
|
|
82
|
+
twitterThreats: result.metrics.twitterThreats,
|
|
83
|
+
telegramThreats: result.metrics.telegramThreats,
|
|
84
|
+
otherThreats: result.metrics.otherThreats
|
|
85
|
+
}
|
|
86
|
+
]),
|
|
87
|
+
human: () => {
|
|
88
|
+
console.log(`Organization metrics for ${label} \u2014 ${range.label}${includeLabel}`);
|
|
89
|
+
console.log(`Range: ${range.startDate} \u2192 ${range.endDate}`);
|
|
90
|
+
for (const [name, value] of populatedMetricLines) {
|
|
91
|
+
console.log(`${name}: ${value}`);
|
|
92
|
+
}
|
|
93
|
+
if (result.blockedByDay && result.blockedByDay.length > 0) {
|
|
94
|
+
console.log("");
|
|
95
|
+
console.log(`Blocked by day (${result.blockedByDay.length} entries):`);
|
|
96
|
+
for (const entry of result.blockedByDay) {
|
|
97
|
+
console.log(` ${entry.date}: ${entry.count}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
export {
|
|
104
|
+
runMetricsOrganization
|
|
105
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getPresetDefinition,
|
|
3
3
|
runPreset
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BIKTBRER.js";
|
|
5
5
|
import {
|
|
6
6
|
CliExitError,
|
|
7
7
|
ExitCode
|
|
8
8
|
} from "./chunk-E2LAMILJ.js";
|
|
9
9
|
import "./chunk-VFT3TD3E.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-YZEMTNCX.js";
|
|
11
11
|
import "./chunk-EGWK6SRQ.js";
|
|
12
12
|
import "./chunk-TFCNKBRC.js";
|
|
13
13
|
import "./chunk-U73SABXK.js";
|
|
@@ -1,30 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveDateRange
|
|
3
|
+
} from "./chunk-S37VFIZY.js";
|
|
1
4
|
import {
|
|
2
5
|
printOutput,
|
|
3
6
|
toCsvRows
|
|
4
7
|
} from "./chunk-VFT3TD3E.js";
|
|
5
8
|
import {
|
|
6
9
|
createApiClient
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-YZEMTNCX.js";
|
|
8
11
|
import "./chunk-EGWK6SRQ.js";
|
|
9
12
|
import "./chunk-TFCNKBRC.js";
|
|
10
13
|
import "./chunk-U73SABXK.js";
|
|
11
14
|
|
|
12
15
|
// src/commands/metrics/summary.ts
|
|
13
16
|
async function runMetricsSummary(options) {
|
|
17
|
+
const range = resolveDateRange({
|
|
18
|
+
from: options.from,
|
|
19
|
+
to: options.to,
|
|
20
|
+
thisWeek: options.thisWeek
|
|
21
|
+
});
|
|
14
22
|
const client = options.apiClient ?? createApiClient();
|
|
15
23
|
const result = await client.getMetricsSummary({
|
|
16
24
|
slug: options.org,
|
|
17
|
-
startDate:
|
|
18
|
-
endDate:
|
|
25
|
+
startDate: range.startDate,
|
|
26
|
+
endDate: range.endDate,
|
|
19
27
|
brandIds: options.brandIds
|
|
20
28
|
});
|
|
21
29
|
const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
|
|
22
30
|
printOutput({
|
|
23
31
|
outputFormat,
|
|
24
|
-
json: result,
|
|
32
|
+
json: { ...result, range },
|
|
25
33
|
markdown: [
|
|
26
|
-
`# Metrics Summary (${options.org})`,
|
|
34
|
+
`# Metrics Summary (${options.org}) \u2014 ${range.label}`,
|
|
27
35
|
"",
|
|
36
|
+
`- Range: ${range.startDate} \u2192 ${range.endDate}`,
|
|
28
37
|
`- Reports: ${result.metrics.reports}`,
|
|
29
38
|
`- New threats: ${result.metrics.newThreats}`,
|
|
30
39
|
`- Watchlisted threats: ${result.metrics.threatsWatchlisted}`,
|
|
@@ -33,6 +42,9 @@ async function runMetricsSummary(options) {
|
|
|
33
42
|
].join("\n"),
|
|
34
43
|
csv: toCsvRows([
|
|
35
44
|
{
|
|
45
|
+
rangeLabel: range.label,
|
|
46
|
+
startDate: range.startDate,
|
|
47
|
+
endDate: range.endDate,
|
|
36
48
|
reports: result.metrics.reports,
|
|
37
49
|
newThreats: result.metrics.newThreats,
|
|
38
50
|
threatsWatchlisted: result.metrics.threatsWatchlisted,
|
|
@@ -45,7 +57,8 @@ async function runMetricsSummary(options) {
|
|
|
45
57
|
}
|
|
46
58
|
]),
|
|
47
59
|
human: () => {
|
|
48
|
-
console.log(`Metrics summary for ${options.org}`);
|
|
60
|
+
console.log(`Metrics summary for ${options.org} \u2014 ${range.label}`);
|
|
61
|
+
console.log(`Range: ${range.startDate} \u2192 ${range.endDate}`);
|
|
49
62
|
console.log(`Reports: ${result.metrics.reports}`);
|
|
50
63
|
console.log(`New threats: ${result.metrics.newThreats}`);
|
|
51
64
|
console.log(`Watchlisted threats: ${result.metrics.threatsWatchlisted}`);
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@chainpatrol/cli",
|
|
3
3
|
"description": "The official ChainPatrol CLI — terminal interface for threat detection",
|
|
4
4
|
"author": "Umar Ahmed <umar@chainpatrol.io>",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.14.0",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"homepage": "https://chainpatrol.com/docs/cli",
|
|
8
8
|
"keywords": [
|
package/dist/found-EVXJZGYX.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
printOutput,
|
|
3
|
-
toCsvRows
|
|
4
|
-
} from "./chunk-VFT3TD3E.js";
|
|
5
|
-
import {
|
|
6
|
-
createApiClient
|
|
7
|
-
} from "./chunk-OSRFCVBT.js";
|
|
8
|
-
import "./chunk-EGWK6SRQ.js";
|
|
9
|
-
import {
|
|
10
|
-
DateTime
|
|
11
|
-
} from "./chunk-TFCNKBRC.js";
|
|
12
|
-
import "./chunk-U73SABXK.js";
|
|
13
|
-
|
|
14
|
-
// src/lib/date-range.ts
|
|
15
|
-
function resolveDateRange({
|
|
16
|
-
from,
|
|
17
|
-
to,
|
|
18
|
-
thisWeek
|
|
19
|
-
}) {
|
|
20
|
-
if (from && to) {
|
|
21
|
-
return {
|
|
22
|
-
startDate: DateTime.fromISO(from).toUTC().toISO() ?? from,
|
|
23
|
-
endDate: DateTime.fromISO(to).toUTC().toISO() ?? to
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
if (from && !to) {
|
|
27
|
-
const now2 = DateTime.now().toUTC();
|
|
28
|
-
return {
|
|
29
|
-
startDate: DateTime.fromISO(from).toUTC().toISO() ?? from,
|
|
30
|
-
endDate: now2.toISO() ?? ""
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
if (!from && to) {
|
|
34
|
-
const end = DateTime.fromISO(to).toUTC();
|
|
35
|
-
return {
|
|
36
|
-
startDate: end.minus({ days: 7 }).toISO() ?? "",
|
|
37
|
-
endDate: end.toISO() ?? to
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
if (thisWeek) {
|
|
41
|
-
const now2 = DateTime.now().toUTC();
|
|
42
|
-
return {
|
|
43
|
-
startDate: now2.startOf("week").toISO() ?? now2.minus({ days: 7 }).toISO() ?? "",
|
|
44
|
-
endDate: now2.endOf("week").toISO() ?? now2.toISO() ?? ""
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const now = DateTime.now().toUTC();
|
|
48
|
-
return {
|
|
49
|
-
startDate: now.minus({ days: 7 }).toISO() ?? "",
|
|
50
|
-
endDate: now.toISO() ?? ""
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// src/commands/metrics/found.ts
|
|
55
|
-
async function runMetricsFound(options) {
|
|
56
|
-
const range = resolveDateRange({
|
|
57
|
-
from: options.from,
|
|
58
|
-
to: options.to,
|
|
59
|
-
thisWeek: options.thisWeek
|
|
60
|
-
});
|
|
61
|
-
const client = options.apiClient ?? createApiClient();
|
|
62
|
-
const result = await client.getMetricsFound({
|
|
63
|
-
slug: options.org,
|
|
64
|
-
startDate: range.startDate,
|
|
65
|
-
endDate: range.endDate,
|
|
66
|
-
brandIds: options.brandIds
|
|
67
|
-
});
|
|
68
|
-
const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
|
|
69
|
-
printOutput({
|
|
70
|
-
outputFormat,
|
|
71
|
-
json: result,
|
|
72
|
-
markdown: [
|
|
73
|
-
`# Found Threats (${options.org})`,
|
|
74
|
-
"",
|
|
75
|
-
`- Metric: ${result.metric}`,
|
|
76
|
-
`- Found: ${result.found}`,
|
|
77
|
-
`- Range: ${range.startDate} -> ${range.endDate}`
|
|
78
|
-
].join("\n"),
|
|
79
|
-
csv: toCsvRows([
|
|
80
|
-
{
|
|
81
|
-
metric: result.metric,
|
|
82
|
-
found: result.found,
|
|
83
|
-
startDate: range.startDate,
|
|
84
|
-
endDate: range.endDate
|
|
85
|
-
}
|
|
86
|
-
]),
|
|
87
|
-
human: () => {
|
|
88
|
-
console.log(`Found threats (${result.metric}) for ${options.org}: ${result.found}`);
|
|
89
|
-
console.log(`Range: ${range.startDate} -> ${range.endDate}`);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
export {
|
|
94
|
-
runMetricsFound
|
|
95
|
-
};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
printOutput,
|
|
3
|
-
toCsvRows
|
|
4
|
-
} from "./chunk-VFT3TD3E.js";
|
|
5
|
-
import {
|
|
6
|
-
createApiClient
|
|
7
|
-
} from "./chunk-OSRFCVBT.js";
|
|
8
|
-
import "./chunk-EGWK6SRQ.js";
|
|
9
|
-
import "./chunk-TFCNKBRC.js";
|
|
10
|
-
import "./chunk-U73SABXK.js";
|
|
11
|
-
|
|
12
|
-
// src/commands/metrics/organization.ts
|
|
13
|
-
async function runMetricsOrganization(options) {
|
|
14
|
-
const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
|
|
15
|
-
const client = options.apiClient ?? createApiClient();
|
|
16
|
-
const input = {
|
|
17
|
-
organizationSlug: options.org,
|
|
18
|
-
brandSlug: options.brandSlug,
|
|
19
|
-
startDate: options.from,
|
|
20
|
-
endDate: options.to
|
|
21
|
-
};
|
|
22
|
-
const result = await client.getOrganizationMetrics(input);
|
|
23
|
-
const label = options.org ?? "your organization";
|
|
24
|
-
printOutput({
|
|
25
|
-
outputFormat,
|
|
26
|
-
json: result,
|
|
27
|
-
markdown: [
|
|
28
|
-
`# Organization Metrics (${label})`,
|
|
29
|
-
"",
|
|
30
|
-
`- Reports: ${result.metrics.reports}`,
|
|
31
|
-
`- New threats: ${result.metrics.newThreats}`,
|
|
32
|
-
`- Watchlisted threats: ${result.metrics.threatsWatchlisted}`,
|
|
33
|
-
`- Takedowns filed: ${result.metrics.takedownsFiled}`,
|
|
34
|
-
`- Takedowns completed: ${result.metrics.takedownsCompleted}`,
|
|
35
|
-
`- Domain threats: ${result.metrics.domainThreats}`,
|
|
36
|
-
`- Twitter threats: ${result.metrics.twitterThreats}`,
|
|
37
|
-
`- Telegram threats: ${result.metrics.telegramThreats}`,
|
|
38
|
-
`- Other threats: ${result.metrics.otherThreats}`
|
|
39
|
-
].join("\n"),
|
|
40
|
-
csv: toCsvRows([
|
|
41
|
-
{
|
|
42
|
-
reports: result.metrics.reports,
|
|
43
|
-
newThreats: result.metrics.newThreats,
|
|
44
|
-
threatsWatchlisted: result.metrics.threatsWatchlisted,
|
|
45
|
-
takedownsFiled: result.metrics.takedownsFiled,
|
|
46
|
-
takedownsCompleted: result.metrics.takedownsCompleted,
|
|
47
|
-
domainThreats: result.metrics.domainThreats,
|
|
48
|
-
twitterThreats: result.metrics.twitterThreats,
|
|
49
|
-
telegramThreats: result.metrics.telegramThreats,
|
|
50
|
-
otherThreats: result.metrics.otherThreats
|
|
51
|
-
}
|
|
52
|
-
]),
|
|
53
|
-
human: () => {
|
|
54
|
-
console.log(`Organization metrics for ${label}`);
|
|
55
|
-
console.log(`Reports: ${result.metrics.reports}`);
|
|
56
|
-
console.log(`New threats: ${result.metrics.newThreats}`);
|
|
57
|
-
console.log(`Watchlisted threats: ${result.metrics.threatsWatchlisted}`);
|
|
58
|
-
console.log(`Takedowns filed: ${result.metrics.takedownsFiled}`);
|
|
59
|
-
console.log(`Takedowns completed: ${result.metrics.takedownsCompleted}`);
|
|
60
|
-
console.log(
|
|
61
|
-
`Threat breakdown: domains=${result.metrics.domainThreats}, twitter=${result.metrics.twitterThreats}, telegram=${result.metrics.telegramThreats}, other=${result.metrics.otherThreats}`
|
|
62
|
-
);
|
|
63
|
-
if (result.blockedByDay.length > 0) {
|
|
64
|
-
console.log("");
|
|
65
|
-
console.log(`Blocked by day (${result.blockedByDay.length} entries):`);
|
|
66
|
-
for (const entry of result.blockedByDay) {
|
|
67
|
-
console.log(` ${entry.date}: ${entry.count}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
export {
|
|
74
|
-
runMetricsOrganization
|
|
75
|
-
};
|