@chainpatrol/cli 0.20.0 → 0.21.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 +26 -0
- package/dist/{chunk-3LJTWYT6.js → chunk-4N2YKTJ5.js} +81 -13
- package/dist/cli.js +11 -5
- package/dist/{get-K7VHV5X2.js → get-XN752KSL.js} +15 -2
- package/dist/{list-QXA6GLCV.js → list-MHICJ2TK.js} +37 -4
- package/dist/{setup-skill-A36WQLMU.js → setup-skill-UEOROLCF.js} +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @chainpatrol/cli
|
|
2
2
|
|
|
3
|
+
## 0.21.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b3e77eb: `orgs list` and `orgs get` now surface each organization's "Obligatory
|
|
8
|
+
Organization Admin Approval" state (`Organization.requiresCustomerReview`)
|
|
9
|
+
alongside its per-asset-type scope. The new response field is
|
|
10
|
+
`obligatoryAdminApproval: { active, assetTypes }` — an empty `assetTypes`
|
|
11
|
+
list with `active: true` means approval applies to every asset type
|
|
12
|
+
(matches the in-app UI's behaviour when no narrowing has been configured).
|
|
13
|
+
|
|
14
|
+
`orgs list` also accepts three new filters that compose with the
|
|
15
|
+
existing ones via AND:
|
|
16
|
+
|
|
17
|
+
- `--obligatory-approval-active` / `--obligatory-approval-inactive` —
|
|
18
|
+
filter on the toggle itself.
|
|
19
|
+
- `--obligatory-approval-asset-type <csv>` — return only orgs whose
|
|
20
|
+
approval scope covers every listed asset type (an org's empty
|
|
21
|
+
per-asset-type list still counts as "all types"). Passing this flag
|
|
22
|
+
implies the feature is on, so it can't be combined with
|
|
23
|
+
`--obligatory-approval-inactive`.
|
|
24
|
+
|
|
25
|
+
Server-side work in `@chainpatrol/external-trpc` and `@chainpatrol/validation`
|
|
26
|
+
extends the `/user/orgs` and `/user/orgs/{slug}` schemas accordingly; both
|
|
27
|
+
are private packages and don't need version bumps.
|
|
28
|
+
|
|
3
29
|
## 0.20.0
|
|
4
30
|
|
|
5
31
|
### Minor Changes
|
|
@@ -199,6 +199,12 @@ description: |
|
|
|
199
199
|
"fetch org details", "org info",
|
|
200
200
|
"orgs with takedowns off", "automation off across orgs",
|
|
201
201
|
"which customers have X enabled", "service toggles by org",
|
|
202
|
+
"obligatory admin approval", "obligatory organization admin approval",
|
|
203
|
+
"obligatory approval", "admin approval enabled", "admin approval orgs",
|
|
204
|
+
"requires customer review", "requires admin approval",
|
|
205
|
+
"orgs that require admin approval", "orgs requiring approval",
|
|
206
|
+
"which orgs require approval for twitter", "approval scope",
|
|
207
|
+
"admin approval asset types", "approval per asset type",
|
|
202
208
|
"is this URL blocked", "is this domain blocked", "is this address blocked",
|
|
203
209
|
"check this asset", "asset check", "lookup asset status",
|
|
204
210
|
"what is ARCHIVE_ORG", "what does PAGE mean", "list asset types",
|
|
@@ -656,14 +662,17 @@ Guide. Key signals in the response:
|
|
|
656
662
|
|
|
657
663
|
Use \`--all\` to snapshot every org you have access to instead of a single slug.
|
|
658
664
|
|
|
659
|
-
### \`orgs list\` \u2014 List organizations with subscription status and
|
|
665
|
+
### \`orgs list\` \u2014 List organizations with subscription status, service toggles, and admin-approval scope
|
|
660
666
|
|
|
661
667
|
Returns every organization the caller can see, with each org's
|
|
662
|
-
subscription status (\`PROSPECT\`, \`TRIAL\`, \`ACTIVE\`, \`INTEGRATION\`)
|
|
663
|
-
which services are active
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
668
|
+
subscription status (\`PROSPECT\`, \`TRIAL\`, \`ACTIVE\`, \`INTEGRATION\`),
|
|
669
|
+
which services are active, and the per-org "Obligatory Organization
|
|
670
|
+
Admin Approval" toggle (with its asset-type scope). Use it to answer
|
|
671
|
+
questions like "which customers have takedowns enabled but automation
|
|
672
|
+
off?", "which prospects don't have detection turned on yet?", or "which
|
|
673
|
+
orgs require admin approval before adding Twitter assets to the
|
|
674
|
+
blocklist?" \u2014 filters compose with AND and are applied server-side, so
|
|
675
|
+
one call returns the final list.
|
|
667
676
|
|
|
668
677
|
\`\`\`bash
|
|
669
678
|
chainpatrol --json orgs list \\
|
|
@@ -686,6 +695,34 @@ misleading filters like "reporting.automated=true" that don't mean
|
|
|
686
695
|
anything. \`detection\` and \`darkWebMonitoring\` have always been
|
|
687
696
|
single-flag services.
|
|
688
697
|
|
|
698
|
+
#### Obligatory Organization Admin Approval
|
|
699
|
+
|
|
700
|
+
Each org also has a separate "Obligatory Organization Admin Approval"
|
|
701
|
+
toggle (\`Organization.requiresCustomerReview\` in the schema, surfaced
|
|
702
|
+
on the Services settings page in the app) that gates customer-side
|
|
703
|
+
review of proposals ChainPatrol staff have already approved before
|
|
704
|
+
they're added to the blocklist. It is NOT one of the operational
|
|
705
|
+
services above \u2014 it is an org-policy toggle with its own per-asset-type
|
|
706
|
+
scope.
|
|
707
|
+
|
|
708
|
+
Each org's response includes:
|
|
709
|
+
|
|
710
|
+
\`\`\`json
|
|
711
|
+
{
|
|
712
|
+
"obligatoryAdminApproval": {
|
|
713
|
+
"active": true,
|
|
714
|
+
"assetTypes": ["TWITTER", "URL"]
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
\`\`\`
|
|
718
|
+
|
|
719
|
+
- \`active=true\` + empty \`assetTypes\` means approval applies to
|
|
720
|
+
**all** asset types \u2014 the org has not narrowed the scope.
|
|
721
|
+
- \`active=true\` + a non-empty \`assetTypes\` list means approval is
|
|
722
|
+
required only for those asset types.
|
|
723
|
+
- \`active=false\` means no approval is required; \`assetTypes\` is
|
|
724
|
+
always empty in that case.
|
|
725
|
+
|
|
689
726
|
So per-org JSON looks like:
|
|
690
727
|
|
|
691
728
|
\`\`\`json
|
|
@@ -697,7 +734,8 @@ So per-org JSON looks like:
|
|
|
697
734
|
"takedowns": { "active": true, "automated": false },
|
|
698
735
|
"detection": { "active": true },
|
|
699
736
|
"darkWebMonitoring": { "active": false }
|
|
700
|
-
}
|
|
737
|
+
},
|
|
738
|
+
"obligatoryAdminApproval": { "active": true, "assetTypes": ["TWITTER"] }
|
|
701
739
|
}
|
|
702
740
|
\`\`\`
|
|
703
741
|
|
|
@@ -706,7 +744,7 @@ explain that the flag exists in the DB but has no operational effect and
|
|
|
706
744
|
isn't exposed by the public API \u2014 only \`takedowns.automated\` carries a
|
|
707
745
|
real meaning.
|
|
708
746
|
|
|
709
|
-
Filter flags (all optional, all comma-separated lists):
|
|
747
|
+
Filter flags (all optional, all comma-separated lists where noted):
|
|
710
748
|
|
|
711
749
|
- \`--query <text>\` partial name match (substring, case-insensitive)
|
|
712
750
|
- \`--subscription-status <list>\` one or more of \`PROSPECT\`, \`TRIAL\`,
|
|
@@ -719,6 +757,16 @@ Filter flags (all optional, all comma-separated lists):
|
|
|
719
757
|
meaningful automation toggle. Passing any other service name errors out.
|
|
720
758
|
- \`--service-manual <list>\` services whose automation must be OFF.
|
|
721
759
|
Same restriction \u2014 only \`takedowns\`.
|
|
760
|
+
- \`--obligatory-approval-active\` \u2014 only orgs with admin approval on
|
|
761
|
+
- \`--obligatory-approval-inactive\` \u2014 only orgs with admin approval off
|
|
762
|
+
- \`--obligatory-approval-asset-type <list>\` \u2014 only orgs whose admin
|
|
763
|
+
approval scope covers EVERY listed asset type. The match treats an
|
|
764
|
+
org's empty per-asset-type list as "applies to all asset types", so a
|
|
765
|
+
fully-broad org matches every value passed here. Passing this flag
|
|
766
|
+
implies the feature is on, so it can't be combined with
|
|
767
|
+
\`--obligatory-approval-inactive\`. Use the canonical asset-type enum
|
|
768
|
+
names (\`TWITTER\`, \`URL\`, \`PAGE\`, \u2026); run \`chainpatrol asset types\`
|
|
769
|
+
to see them all.
|
|
722
770
|
|
|
723
771
|
Service names: \`reporting\`, \`reviewing\`, \`protection\`, \`takedowns\`,
|
|
724
772
|
\`detection\`, \`darkWebMonitoring\`.
|
|
@@ -727,16 +775,36 @@ Customers see only orgs they're a member of. Staff/superuser sessions see
|
|
|
727
775
|
every matching org. The response is the same in both cases; visibility is
|
|
728
776
|
enforced server-side.
|
|
729
777
|
|
|
778
|
+
#### Use case: finding which orgs require admin approval for an asset type
|
|
779
|
+
|
|
780
|
+
When a user asks "which orgs require admin approval before blocking
|
|
781
|
+
Twitter assets?", reach straight for the filter \u2014 no client-side
|
|
782
|
+
post-processing needed:
|
|
783
|
+
|
|
784
|
+
\`\`\`bash
|
|
785
|
+
chainpatrol --json orgs list --obligatory-approval-asset-type TWITTER
|
|
786
|
+
\`\`\`
|
|
787
|
+
|
|
788
|
+
To audit just the broad opt-ins ("which orgs require approval for
|
|
789
|
+
everything?"), filter on the toggle and inspect \`assetTypes\` in the
|
|
790
|
+
output \u2014 an empty array means "all":
|
|
791
|
+
|
|
792
|
+
\`\`\`bash
|
|
793
|
+
chainpatrol --json orgs list --obligatory-approval-active \\
|
|
794
|
+
| jq '.organizations[] | select(.obligatoryAdminApproval.assetTypes | length == 0) | .slug'
|
|
795
|
+
\`\`\`
|
|
796
|
+
|
|
730
797
|
### \`orgs get\` \u2014 Get a single organization by slug
|
|
731
798
|
|
|
732
799
|
Look up one organization the caller has access to. Returns the same per-org
|
|
733
800
|
shape as a single row from \`orgs list\` \u2014 \`active\` for every service,
|
|
734
801
|
plus \`automated\` on \`takedowns\` only (see the note above on why other
|
|
735
|
-
services don't expose an automation flag)
|
|
736
|
-
\`
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
802
|
+
services don't expose an automation flag), plus \`obligatoryAdminApproval\`
|
|
803
|
+
(\`active\` + \`assetTypes\`). Anything you could read from \`orgs list\` you
|
|
804
|
+
can also read here without paging or filtering. Use it when the user
|
|
805
|
+
names a specific customer ("show me acme's setup", "is takedowns
|
|
806
|
+
automation on for morpho?", "does this org require admin approval for
|
|
807
|
+
Twitter?") and you don't need the rest of the catalogue.
|
|
740
808
|
|
|
741
809
|
\`\`\`bash
|
|
742
810
|
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-4N2YKTJ5.js";
|
|
17
17
|
import "./chunk-6VTWWGNV.js";
|
|
18
18
|
import {
|
|
19
19
|
DateTime
|
|
@@ -916,6 +916,9 @@ ${getTopLevelHelp()}
|
|
|
916
916
|
serviceInactive: { type: "string" },
|
|
917
917
|
serviceAutomated: { type: "string" },
|
|
918
918
|
serviceManual: { type: "string" },
|
|
919
|
+
obligatoryApprovalActive: { type: "boolean" },
|
|
920
|
+
obligatoryApprovalInactive: { type: "boolean" },
|
|
921
|
+
obligatoryApprovalAssetType: { type: "string" },
|
|
919
922
|
query: { type: "string" },
|
|
920
923
|
assetType: { type: "string" },
|
|
921
924
|
takedownStatus: { type: "string" },
|
|
@@ -1558,7 +1561,7 @@ async function main() {
|
|
|
1558
1561
|
}
|
|
1559
1562
|
case "orgs": {
|
|
1560
1563
|
if (subcommand === "list") {
|
|
1561
|
-
const { runOrgsList } = await import("./list-
|
|
1564
|
+
const { runOrgsList } = await import("./list-MHICJ2TK.js");
|
|
1562
1565
|
await runOrgsList({
|
|
1563
1566
|
query: cli.flags.query,
|
|
1564
1567
|
subscriptionStatus: cli.flags.subscriptionStatus,
|
|
@@ -1566,6 +1569,9 @@ async function main() {
|
|
|
1566
1569
|
serviceInactive: cli.flags.serviceInactive,
|
|
1567
1570
|
serviceAutomated: cli.flags.serviceAutomated,
|
|
1568
1571
|
serviceManual: cli.flags.serviceManual,
|
|
1572
|
+
obligatoryApprovalActive: cli.flags.obligatoryApprovalActive,
|
|
1573
|
+
obligatoryApprovalInactive: cli.flags.obligatoryApprovalInactive,
|
|
1574
|
+
obligatoryApprovalAssetType: cli.flags.obligatoryApprovalAssetType,
|
|
1569
1575
|
json: jsonMode,
|
|
1570
1576
|
outputFormat: cliContext.outputFormat
|
|
1571
1577
|
});
|
|
@@ -1574,7 +1580,7 @@ async function main() {
|
|
|
1574
1580
|
if (subcommand === "get") {
|
|
1575
1581
|
const positionalSlug = action;
|
|
1576
1582
|
const slug = positionalSlug ?? await tryResolveOrg();
|
|
1577
|
-
const { runOrgsGet } = await import("./get-
|
|
1583
|
+
const { runOrgsGet } = await import("./get-XN752KSL.js");
|
|
1578
1584
|
await runOrgsGet({
|
|
1579
1585
|
slug,
|
|
1580
1586
|
json: jsonMode,
|
|
@@ -1705,12 +1711,12 @@ async function main() {
|
|
|
1705
1711
|
case "setup":
|
|
1706
1712
|
case "install":
|
|
1707
1713
|
case "i": {
|
|
1708
|
-
const { setupSkill } = await import("./setup-skill-
|
|
1714
|
+
const { setupSkill } = await import("./setup-skill-UEOROLCF.js");
|
|
1709
1715
|
setupSkill({ json: jsonMode, cloud: cli.flags.cloud });
|
|
1710
1716
|
break;
|
|
1711
1717
|
}
|
|
1712
1718
|
case "uninstall": {
|
|
1713
|
-
const { uninstallSkill } = await import("./setup-skill-
|
|
1719
|
+
const { uninstallSkill } = await import("./setup-skill-UEOROLCF.js");
|
|
1714
1720
|
uninstallSkill({ json: jsonMode });
|
|
1715
1721
|
break;
|
|
1716
1722
|
}
|
|
@@ -26,6 +26,11 @@ function summarizeServices(org) {
|
|
|
26
26
|
if (org.services.darkWebMonitoring.active) parts.push("darkWebMonitoring");
|
|
27
27
|
return parts.length > 0 ? parts.join(" ") : "(no services enabled)";
|
|
28
28
|
}
|
|
29
|
+
function summarizeObligatoryAdminApproval(org) {
|
|
30
|
+
if (!org.obligatoryAdminApproval.active) return "off";
|
|
31
|
+
const types = org.obligatoryAdminApproval.assetTypes;
|
|
32
|
+
return types.length === 0 ? "on (all asset types)" : `on (${types.join(", ")})`;
|
|
33
|
+
}
|
|
29
34
|
async function runOrgsGet(options) {
|
|
30
35
|
const slug = options.slug?.trim();
|
|
31
36
|
if (!slug) {
|
|
@@ -45,7 +50,8 @@ async function runOrgsGet(options) {
|
|
|
45
50
|
`# ${organization.name} (\`${organization.slug}\`)`,
|
|
46
51
|
"",
|
|
47
52
|
`- Subscription status: ${organization.subscriptionStatus}`,
|
|
48
|
-
`- Services: ${summarizeServices(organization)}
|
|
53
|
+
`- Services: ${summarizeServices(organization)}`,
|
|
54
|
+
`- Obligatory admin approval: ${summarizeObligatoryAdminApproval(organization)}`
|
|
49
55
|
].join("\n"),
|
|
50
56
|
csv: toCsvRows([
|
|
51
57
|
{
|
|
@@ -59,13 +65,20 @@ async function runOrgsGet(options) {
|
|
|
59
65
|
// `takedowns` is the only service with a meaningful automation flag.
|
|
60
66
|
takedownsAutomated: organization.services.takedowns.automated,
|
|
61
67
|
detectionActive: organization.services.detection.active,
|
|
62
|
-
darkWebMonitoringActive: organization.services.darkWebMonitoring.active
|
|
68
|
+
darkWebMonitoringActive: organization.services.darkWebMonitoring.active,
|
|
69
|
+
obligatoryAdminApprovalActive: organization.obligatoryAdminApproval.active,
|
|
70
|
+
// Empty list + active=true means "applies to all asset types" — read
|
|
71
|
+
// the active column alongside this one to interpret.
|
|
72
|
+
obligatoryAdminApprovalAssetTypes: organization.obligatoryAdminApproval.assetTypes.join("|")
|
|
63
73
|
}
|
|
64
74
|
]),
|
|
65
75
|
human: () => {
|
|
66
76
|
console.log(`${organization.name} (slug: ${organization.slug})`);
|
|
67
77
|
console.log(` subscriptionStatus: ${organization.subscriptionStatus}`);
|
|
68
78
|
console.log(` services: ${summarizeServices(organization)}`);
|
|
79
|
+
console.log(
|
|
80
|
+
` obligatoryAdminApproval: ${summarizeObligatoryAdminApproval(organization)}`
|
|
81
|
+
);
|
|
69
82
|
}
|
|
70
83
|
});
|
|
71
84
|
}
|
|
@@ -128,13 +128,41 @@ function summarizeServices(org) {
|
|
|
128
128
|
}
|
|
129
129
|
return parts.length > 0 ? parts.join(" ") : "(no services enabled)";
|
|
130
130
|
}
|
|
131
|
+
function summarizeObligatoryAdminApproval(org) {
|
|
132
|
+
if (!org.obligatoryAdminApproval.active) return "off";
|
|
133
|
+
const types = org.obligatoryAdminApproval.assetTypes;
|
|
134
|
+
return types.length === 0 ? "on (all asset types)" : `on (${types.join(", ")})`;
|
|
135
|
+
}
|
|
136
|
+
function buildObligatoryAdminApprovalFilter(options) {
|
|
137
|
+
if (options.obligatoryApprovalActive && options.obligatoryApprovalInactive) {
|
|
138
|
+
throw new CliExitError(
|
|
139
|
+
"Conflicting flags: --obligatory-approval-active and --obligatory-approval-inactive can't both be passed.",
|
|
140
|
+
ExitCode.USAGE
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
const assetTypeStrings = splitCsv(options.obligatoryApprovalAssetType).map(
|
|
144
|
+
(value) => value.toUpperCase()
|
|
145
|
+
);
|
|
146
|
+
if (assetTypeStrings.length > 0 && options.obligatoryApprovalInactive) {
|
|
147
|
+
throw new CliExitError(
|
|
148
|
+
"Conflicting flags: --obligatory-approval-asset-type implies the feature is on, so it can't be combined with --obligatory-approval-inactive.",
|
|
149
|
+
ExitCode.USAGE
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const filter = {};
|
|
153
|
+
if (options.obligatoryApprovalActive) filter.active = true;
|
|
154
|
+
if (options.obligatoryApprovalInactive) filter.active = false;
|
|
155
|
+
if (assetTypeStrings.length > 0) filter.assetTypes = assetTypeStrings;
|
|
156
|
+
return Object.keys(filter).length > 0 ? filter : void 0;
|
|
157
|
+
}
|
|
131
158
|
async function runOrgsList(options) {
|
|
132
159
|
const client = options.apiClient ?? createApiClient();
|
|
133
160
|
const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
|
|
134
161
|
const input = {
|
|
135
162
|
query: options.query ?? "",
|
|
136
163
|
subscriptionStatus: parseSubscriptionStatuses(options.subscriptionStatus),
|
|
137
|
-
services: buildServicesFilter(options)
|
|
164
|
+
services: buildServicesFilter(options),
|
|
165
|
+
obligatoryAdminApproval: buildObligatoryAdminApprovalFilter(options)
|
|
138
166
|
};
|
|
139
167
|
const result = await client.getUserOrgs(input);
|
|
140
168
|
const organizations = result.organizations;
|
|
@@ -145,7 +173,7 @@ async function runOrgsList(options) {
|
|
|
145
173
|
`# Organizations (${organizations.length})`,
|
|
146
174
|
"",
|
|
147
175
|
...organizations.map(
|
|
148
|
-
(org) => `- \`${org.slug}\` \u2014 ${org.name} \u2014 ${org.subscriptionStatus} \u2014 ${summarizeServices(org)}`
|
|
176
|
+
(org) => `- \`${org.slug}\` \u2014 ${org.name} \u2014 ${org.subscriptionStatus} \u2014 ${summarizeServices(org)} \u2014 admin-approval: ${summarizeObligatoryAdminApproval(org)}`
|
|
149
177
|
)
|
|
150
178
|
].join("\n"),
|
|
151
179
|
csv: toCsvRows(
|
|
@@ -160,7 +188,12 @@ async function runOrgsList(options) {
|
|
|
160
188
|
// `takedowns` is the only service with a meaningful automation flag.
|
|
161
189
|
takedownsAutomated: org.services.takedowns.automated,
|
|
162
190
|
detectionActive: org.services.detection.active,
|
|
163
|
-
darkWebMonitoringActive: org.services.darkWebMonitoring.active
|
|
191
|
+
darkWebMonitoringActive: org.services.darkWebMonitoring.active,
|
|
192
|
+
obligatoryAdminApprovalActive: org.obligatoryAdminApproval.active,
|
|
193
|
+
// Empty list + active means "applies to all asset types"; we keep
|
|
194
|
+
// the cell empty in CSV so spreadsheets render it as the natural
|
|
195
|
+
// "no narrowing" value — pair it with the active column.
|
|
196
|
+
obligatoryAdminApprovalAssetTypes: org.obligatoryAdminApproval.assetTypes.join("|")
|
|
164
197
|
}))
|
|
165
198
|
),
|
|
166
199
|
human: () => {
|
|
@@ -173,7 +206,7 @@ async function runOrgsList(options) {
|
|
|
173
206
|
const nameWidth = Math.max(...organizations.map((org) => org.name.length), 4);
|
|
174
207
|
for (const org of organizations) {
|
|
175
208
|
console.log(
|
|
176
|
-
` ${org.slug.padEnd(slugWidth)} ${org.name.padEnd(nameWidth)} ${org.subscriptionStatus.padEnd(11)} ${summarizeServices(org)}`
|
|
209
|
+
` ${org.slug.padEnd(slugWidth)} ${org.name.padEnd(nameWidth)} ${org.subscriptionStatus.padEnd(11)} ${summarizeServices(org)} admin-approval=${summarizeObligatoryAdminApproval(org)}`
|
|
177
210
|
);
|
|
178
211
|
}
|
|
179
212
|
}
|
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.21.0",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"homepage": "https://chainpatrol.com/docs/cli",
|
|
8
8
|
"keywords": [
|