@chainpatrol/cli 0.17.0 → 0.18.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 +33 -0
- package/dist/{chunk-75H4KTIQ.js → chunk-MDDC4F6Q.js} +50 -14
- package/dist/cli.js +9 -9
- package/dist/{get-BPTWCJ6H.js → get-YFYSJFBC.js} +6 -7
- package/dist/{list-OEJV4UNQ.js → list-XUYCZG7S.js} +12 -10
- package/dist/{setup-skill-RPVW2CCQ.js → setup-skill-Z6SBI6GC.js} +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @chainpatrol/cli
|
|
2
2
|
|
|
3
|
+
## 0.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0825606: Drop `automated` from the per-service shape of `orgs list` / `orgs get`
|
|
8
|
+
(and the matching `/user/orgs` and `/user/orgs/{slug}` public APIs) for
|
|
9
|
+
every service except `takedowns`. `automated` only ever had operational
|
|
10
|
+
meaning for takedowns — it controls whether ChainPatrol files the
|
|
11
|
+
takedown on its own. The `isAutomated*Active` columns on
|
|
12
|
+
reporting/reviewing/protection have no runtime effect, so exposing them
|
|
13
|
+
in the public API only invited misleading filters and CSV columns.
|
|
14
|
+
|
|
15
|
+
Concretely:
|
|
16
|
+
|
|
17
|
+
- API response: `services.reporting`, `services.reviewing`, and
|
|
18
|
+
`services.protection` now return `{ "active": boolean }` only.
|
|
19
|
+
`services.takedowns` still returns `{ "active": boolean, "automated":
|
|
20
|
+
boolean }`. `detection` and `darkWebMonitoring` are unchanged.
|
|
21
|
+
- API services filter: same — `reporting`, `reviewing`, and
|
|
22
|
+
`protection` no longer accept an `automated` filter. Only
|
|
23
|
+
`takedowns` does.
|
|
24
|
+
- CLI: `--service-automated` / `--service-manual` now only accept
|
|
25
|
+
`takedowns`. Passing any other service name errors out with a
|
|
26
|
+
clearer message.
|
|
27
|
+
- CLI CSV output: drops the `reportingAutomated` / `reviewingAutomated`
|
|
28
|
+
/ `protectionAutomated` columns. Only `takedownsAutomated` remains.
|
|
29
|
+
- Skill description and OpenAPI endpoint descriptions explain the
|
|
30
|
+
new shape.
|
|
31
|
+
|
|
32
|
+
Server-side work in @chainpatrol/external-trpc and @chainpatrol/validation
|
|
33
|
+
supports the new shape; both are private packages and don't need
|
|
34
|
+
version bumps.
|
|
35
|
+
|
|
3
36
|
## 0.17.0
|
|
4
37
|
|
|
5
38
|
### Minor Changes
|
|
@@ -626,10 +626,10 @@ Use \`--all\` to snapshot every org you have access to instead of a single slug.
|
|
|
626
626
|
|
|
627
627
|
Returns every organization the caller can see, with each org's
|
|
628
628
|
subscription status (\`PROSPECT\`, \`TRIAL\`, \`ACTIVE\`, \`INTEGRATION\`) and
|
|
629
|
-
which services are active
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
629
|
+
which services are active. Use it to answer questions like "which
|
|
630
|
+
customers have takedowns enabled but automation off?" or "which prospects
|
|
631
|
+
don't have detection turned on yet?" \u2014 filters compose with AND and are
|
|
632
|
+
applied server-side, so one call returns the final list.
|
|
633
633
|
|
|
634
634
|
\`\`\`bash
|
|
635
635
|
chainpatrol --json orgs list \\
|
|
@@ -638,6 +638,40 @@ chainpatrol --json orgs list \\
|
|
|
638
638
|
--service-manual takedowns
|
|
639
639
|
\`\`\`
|
|
640
640
|
|
|
641
|
+
#### Per-service response shape \u2014 \`automated\` is takedowns-only
|
|
642
|
+
|
|
643
|
+
Every service exposes an \`active\` boolean. **Only \`takedowns\`
|
|
644
|
+
additionally exposes \`automated\`** \u2014 that is the one service where the
|
|
645
|
+
manual-vs-automated distinction changes real platform behavior (whether
|
|
646
|
+
ChainPatrol files the takedown on its own, or queues it for a human to
|
|
647
|
+
file). \`reporting\`, \`reviewing\`, and \`protection\` have backing
|
|
648
|
+
\`isAutomated*Active\` columns in the database, but those flags have no
|
|
649
|
+
operational effect today, so the API deliberately omits them from both
|
|
650
|
+
the response and the \`services\` filter \u2014 surfacing them would invite
|
|
651
|
+
misleading filters like "reporting.automated=true" that don't mean
|
|
652
|
+
anything. \`detection\` and \`darkWebMonitoring\` have always been
|
|
653
|
+
single-flag services.
|
|
654
|
+
|
|
655
|
+
So per-org JSON looks like:
|
|
656
|
+
|
|
657
|
+
\`\`\`json
|
|
658
|
+
{
|
|
659
|
+
"services": {
|
|
660
|
+
"reporting": { "active": true },
|
|
661
|
+
"reviewing": { "active": true },
|
|
662
|
+
"protection": { "active": false },
|
|
663
|
+
"takedowns": { "active": true, "automated": false },
|
|
664
|
+
"detection": { "active": true },
|
|
665
|
+
"darkWebMonitoring": { "active": false }
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
\`\`\`
|
|
669
|
+
|
|
670
|
+
When a user asks about "automated reporting / reviewing / protection",
|
|
671
|
+
explain that the flag exists in the DB but has no operational effect and
|
|
672
|
+
isn't exposed by the public API \u2014 only \`takedowns.automated\` carries a
|
|
673
|
+
real meaning.
|
|
674
|
+
|
|
641
675
|
Filter flags (all optional, all comma-separated lists):
|
|
642
676
|
|
|
643
677
|
- \`--query <text>\` partial name match (substring, case-insensitive)
|
|
@@ -646,11 +680,11 @@ Filter flags (all optional, all comma-separated lists):
|
|
|
646
680
|
through this filter \u2014 \`orgs list\` only ever returns live customers.
|
|
647
681
|
- \`--service-active <list>\` services that must be active
|
|
648
682
|
- \`--service-inactive <list>\` services that must be inactive
|
|
649
|
-
- \`--service-automated <list>\` services whose automation must be ON
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
- \`--service-manual <list>\` services whose automation must be OFF
|
|
653
|
-
|
|
683
|
+
- \`--service-automated <list>\` services whose automation must be ON.
|
|
684
|
+
**Only \`takedowns\` is accepted** \u2014 the other services don't have a
|
|
685
|
+
meaningful automation toggle. Passing any other service name errors out.
|
|
686
|
+
- \`--service-manual <list>\` services whose automation must be OFF.
|
|
687
|
+
Same restriction \u2014 only \`takedowns\`.
|
|
654
688
|
|
|
655
689
|
Service names: \`reporting\`, \`reviewing\`, \`protection\`, \`takedowns\`,
|
|
656
690
|
\`detection\`, \`darkWebMonitoring\`.
|
|
@@ -662,11 +696,13 @@ enforced server-side.
|
|
|
662
696
|
### \`orgs get\` \u2014 Get a single organization by slug
|
|
663
697
|
|
|
664
698
|
Look up one organization the caller has access to. Returns the same per-org
|
|
665
|
-
shape as a single row from \`orgs list\`
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
699
|
+
shape as a single row from \`orgs list\` \u2014 \`active\` for every service,
|
|
700
|
+
plus \`automated\` on \`takedowns\` only (see the note above on why other
|
|
701
|
+
services don't expose an automation flag). Anything you could read from
|
|
702
|
+
\`orgs list\` you can also read here without paging or filtering. Use it
|
|
703
|
+
when the user names a specific customer ("show me acme's setup", "is
|
|
704
|
+
takedowns automation on for morpho?") and you don't need the rest of the
|
|
705
|
+
catalogue.
|
|
670
706
|
|
|
671
707
|
\`\`\`bash
|
|
672
708
|
chainpatrol orgs get <slug>
|
package/dist/cli.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getCliVersion,
|
|
14
14
|
isSkillInstalled,
|
|
15
15
|
readInstalledSkillVersion
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-MDDC4F6Q.js";
|
|
17
17
|
import "./chunk-NQT77IB7.js";
|
|
18
18
|
import {
|
|
19
19
|
DateTime
|
|
@@ -513,15 +513,15 @@ var HELP = {
|
|
|
513
513
|
examples: ["chainpatrol orgs asset-groups list --output csv"]
|
|
514
514
|
},
|
|
515
515
|
"orgs list": {
|
|
516
|
-
description: "List organizations with their subscription status and per-service active
|
|
516
|
+
description: "List organizations with their subscription status and per-service active flag (plus `automated` for takedowns only \u2014 that's the one service where manual-vs-automated changes real platform behavior). All filters compose with AND.",
|
|
517
517
|
usage: "chainpatrol orgs list [filters]",
|
|
518
518
|
options: [
|
|
519
519
|
"--query <text> Partial name match (substring, case-insensitive)",
|
|
520
520
|
"--subscription-status <l> Comma-separated list (PROSPECT,TRIAL,ACTIVE,INTEGRATION)",
|
|
521
521
|
"--service-active <l> Comma-separated services that must be active",
|
|
522
522
|
"--service-inactive <l> Comma-separated services that must be inactive",
|
|
523
|
-
"--service-automated <l> Services whose automation must be ON (
|
|
524
|
-
"--service-manual <l> Services whose automation must be OFF (
|
|
523
|
+
"--service-automated <l> Services whose automation must be ON (only `takedowns` is accepted \u2014 the other services have no meaningful automation toggle)",
|
|
524
|
+
"--service-manual <l> Services whose automation must be OFF (only `takedowns` is accepted)"
|
|
525
525
|
],
|
|
526
526
|
examples: [
|
|
527
527
|
"chainpatrol orgs list --subscription-status ACTIVE",
|
|
@@ -530,7 +530,7 @@ var HELP = {
|
|
|
530
530
|
]
|
|
531
531
|
},
|
|
532
532
|
"orgs get": {
|
|
533
|
-
description: "Get a single organization by slug. Returns the same shape as one row of `orgs list` (subscription status + per-service active
|
|
533
|
+
description: "Get a single organization by slug. Returns the same shape as one row of `orgs list` (subscription status + per-service active flag, with `automated` exposed only for takedowns \u2014 the one service where manual-vs-automated changes real platform behavior). Caller must have access: org-scoped API keys must match the slug, user sessions/keys need an active membership unless the user is staff.",
|
|
534
534
|
usage: "chainpatrol orgs get <slug>",
|
|
535
535
|
options: [
|
|
536
536
|
"--org <slug> Use the saved default org instead of a positional argument."
|
|
@@ -1538,7 +1538,7 @@ async function main() {
|
|
|
1538
1538
|
}
|
|
1539
1539
|
case "orgs": {
|
|
1540
1540
|
if (subcommand === "list") {
|
|
1541
|
-
const { runOrgsList } = await import("./list-
|
|
1541
|
+
const { runOrgsList } = await import("./list-XUYCZG7S.js");
|
|
1542
1542
|
await runOrgsList({
|
|
1543
1543
|
query: cli.flags.query,
|
|
1544
1544
|
subscriptionStatus: cli.flags.subscriptionStatus,
|
|
@@ -1554,7 +1554,7 @@ async function main() {
|
|
|
1554
1554
|
if (subcommand === "get") {
|
|
1555
1555
|
const positionalSlug = action;
|
|
1556
1556
|
const slug = positionalSlug ?? await tryResolveOrg();
|
|
1557
|
-
const { runOrgsGet } = await import("./get-
|
|
1557
|
+
const { runOrgsGet } = await import("./get-YFYSJFBC.js");
|
|
1558
1558
|
await runOrgsGet({
|
|
1559
1559
|
slug,
|
|
1560
1560
|
json: jsonMode,
|
|
@@ -1664,12 +1664,12 @@ async function main() {
|
|
|
1664
1664
|
case "setup":
|
|
1665
1665
|
case "install":
|
|
1666
1666
|
case "i": {
|
|
1667
|
-
const { setupSkill } = await import("./setup-skill-
|
|
1667
|
+
const { setupSkill } = await import("./setup-skill-Z6SBI6GC.js");
|
|
1668
1668
|
setupSkill({ json: jsonMode, cloud: cli.flags.cloud });
|
|
1669
1669
|
break;
|
|
1670
1670
|
}
|
|
1671
1671
|
case "uninstall": {
|
|
1672
|
-
const { uninstallSkill } = await import("./setup-skill-
|
|
1672
|
+
const { uninstallSkill } = await import("./setup-skill-Z6SBI6GC.js");
|
|
1673
1673
|
uninstallSkill({ json: jsonMode });
|
|
1674
1674
|
break;
|
|
1675
1675
|
}
|
|
@@ -16,11 +16,12 @@ import "./chunk-U73SABXK.js";
|
|
|
16
16
|
// src/commands/orgs/get.ts
|
|
17
17
|
function summarizeServices(org) {
|
|
18
18
|
const parts = [];
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (!entry.active) continue;
|
|
22
|
-
parts.push(`${service}=${entry.automated ? "auto" : "manual"}`);
|
|
19
|
+
if (org.services.takedowns.active) {
|
|
20
|
+
parts.push(`takedowns=${org.services.takedowns.automated ? "auto" : "manual"}`);
|
|
23
21
|
}
|
|
22
|
+
if (org.services.reporting.active) parts.push("reporting");
|
|
23
|
+
if (org.services.reviewing.active) parts.push("reviewing");
|
|
24
|
+
if (org.services.protection.active) parts.push("protection");
|
|
24
25
|
if (org.services.detection.active) parts.push("detection");
|
|
25
26
|
if (org.services.darkWebMonitoring.active) parts.push("darkWebMonitoring");
|
|
26
27
|
return parts.length > 0 ? parts.join(" ") : "(no services enabled)";
|
|
@@ -52,12 +53,10 @@ async function runOrgsGet(options) {
|
|
|
52
53
|
name: organization.name,
|
|
53
54
|
subscriptionStatus: organization.subscriptionStatus,
|
|
54
55
|
reportingActive: organization.services.reporting.active,
|
|
55
|
-
reportingAutomated: organization.services.reporting.automated,
|
|
56
56
|
reviewingActive: organization.services.reviewing.active,
|
|
57
|
-
reviewingAutomated: organization.services.reviewing.automated,
|
|
58
57
|
protectionActive: organization.services.protection.active,
|
|
59
|
-
protectionAutomated: organization.services.protection.automated,
|
|
60
58
|
takedownsActive: organization.services.takedowns.active,
|
|
59
|
+
// `takedowns` is the only service with a meaningful automation flag.
|
|
61
60
|
takedownsAutomated: organization.services.takedowns.automated,
|
|
62
61
|
detectionActive: organization.services.detection.active,
|
|
63
62
|
darkWebMonitoringActive: organization.services.darkWebMonitoring.active
|
|
@@ -20,8 +20,14 @@ var VALID_SUBSCRIPTION_STATUSES = /* @__PURE__ */ new Set([
|
|
|
20
20
|
"ACTIVE",
|
|
21
21
|
"INTEGRATION"
|
|
22
22
|
]);
|
|
23
|
-
var DUAL_SERVICES = ["
|
|
24
|
-
var SINGLE_SERVICES = [
|
|
23
|
+
var DUAL_SERVICES = ["takedowns"];
|
|
24
|
+
var SINGLE_SERVICES = [
|
|
25
|
+
"reporting",
|
|
26
|
+
"reviewing",
|
|
27
|
+
"protection",
|
|
28
|
+
"detection",
|
|
29
|
+
"darkWebMonitoring"
|
|
30
|
+
];
|
|
25
31
|
var ALL_SERVICES = [...DUAL_SERVICES, ...SINGLE_SERVICES];
|
|
26
32
|
function splitCsv(value) {
|
|
27
33
|
if (!value) return [];
|
|
@@ -60,7 +66,7 @@ function parseServiceList(raw, flagName) {
|
|
|
60
66
|
function requireDualService(service, flagName) {
|
|
61
67
|
if (!DUAL_SERVICES.includes(service)) {
|
|
62
68
|
throw new CliExitError(
|
|
63
|
-
`Service '${service}' does not have
|
|
69
|
+
`Service '${service}' does not have a meaningful automation toggle and can't be used with --${flagName}. Only 'takedowns' supports --service-automated / --service-manual; use --service-active / --service-inactive for the others.`,
|
|
64
70
|
ExitCode.USAGE
|
|
65
71
|
);
|
|
66
72
|
}
|
|
@@ -114,10 +120,8 @@ function buildServicesFilter(options) {
|
|
|
114
120
|
}
|
|
115
121
|
function summarizeServices(org) {
|
|
116
122
|
const parts = [];
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (!entry.active) continue;
|
|
120
|
-
parts.push(`${service}=${entry.automated ? "auto" : "manual"}`);
|
|
123
|
+
if (org.services.takedowns.active) {
|
|
124
|
+
parts.push(`takedowns=${org.services.takedowns.automated ? "auto" : "manual"}`);
|
|
121
125
|
}
|
|
122
126
|
for (const service of SINGLE_SERVICES) {
|
|
123
127
|
if (org.services[service].active) parts.push(service);
|
|
@@ -150,12 +154,10 @@ async function runOrgsList(options) {
|
|
|
150
154
|
name: org.name,
|
|
151
155
|
subscriptionStatus: org.subscriptionStatus,
|
|
152
156
|
reportingActive: org.services.reporting.active,
|
|
153
|
-
reportingAutomated: org.services.reporting.automated,
|
|
154
157
|
reviewingActive: org.services.reviewing.active,
|
|
155
|
-
reviewingAutomated: org.services.reviewing.automated,
|
|
156
158
|
protectionActive: org.services.protection.active,
|
|
157
|
-
protectionAutomated: org.services.protection.automated,
|
|
158
159
|
takedownsActive: org.services.takedowns.active,
|
|
160
|
+
// `takedowns` is the only service with a meaningful automation flag.
|
|
159
161
|
takedownsAutomated: org.services.takedowns.automated,
|
|
160
162
|
detectionActive: org.services.detection.active,
|
|
161
163
|
darkWebMonitoringActive: org.services.darkWebMonitoring.active
|
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.18.0",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"homepage": "https://chainpatrol.com/docs/cli",
|
|
8
8
|
"keywords": [
|