@chainpatrol/cli 1.1.0 → 1.3.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
CHANGED
|
@@ -1,5 +1,94 @@
|
|
|
1
1
|
# @chainpatrol/cli
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 08b9976: Broaden the public API surface across Reports, Takedowns, Detections,
|
|
8
|
+
Detection Configs, and Assets. Everything additive — no removed fields,
|
|
9
|
+
no renames — so existing callers are unaffected.
|
|
10
|
+
|
|
11
|
+
**Detections (`listDetections`)** — new fields on each `DetectionListItem`:
|
|
12
|
+
`reason` (free-text explanation of why the detection fired), `score` (raw
|
|
13
|
+
0–1 model score), `configId` (which `ThreatDetectionConfig` produced the
|
|
14
|
+
hit), `reportedAt` (when it transitioned to `REPORTED`, nullable), and
|
|
15
|
+
`brands[]` (brand associations).
|
|
16
|
+
|
|
17
|
+
**Detection Configs (`listDetectionConfigs`)** — each `ConfigEntry` now
|
|
18
|
+
carries `description` (nullable), `createdAt`, and `updatedAt` so
|
|
19
|
+
integrators can spot silent or stale configs.
|
|
20
|
+
|
|
21
|
+
**Reports** — `listOrganizationReports` gains `slaDueAt` (SLA deadline),
|
|
22
|
+
`externalSubmissionLink` (original external source URL when submitted from
|
|
23
|
+
a third-party surface), and `duplicateOfId` (canonical report ID when this
|
|
24
|
+
one is a duplicate). Type gaps are also closed: `imageDisplay`,
|
|
25
|
+
`favoritedAt`, `attachments[]`, and `proposals.asset.scans[]` were already
|
|
26
|
+
returned by the handler but omitted from the SDK type — they're now
|
|
27
|
+
declared. `searchReports` (`report/search-external`) response now
|
|
28
|
+
surfaces the `title` and `createdAt` fields the handler already fetched.
|
|
29
|
+
|
|
30
|
+
**Takedowns (`listTakedowns`)** — each `TakedownItem` gains `externalId`
|
|
31
|
+
(vendor's own reference — CleanDNS report ID / registrar ticket, for
|
|
32
|
+
reconciliation), `hasFilingDelay`, `hasLivenessCheckDelay` (staff-set
|
|
33
|
+
flags used by median-time metrics), and `asset.blockedAt`.
|
|
34
|
+
|
|
35
|
+
**Takedowns (`getTakedown`)** — the response was previously bare
|
|
36
|
+
(`{ assetContent, takedownStatus, createdAt, updatedAt }`). It's now
|
|
37
|
+
fully built out with `asset` details (id / content / type /
|
|
38
|
+
`livenessStatus` / `blockedAt`) and a nested `takedown` record (id /
|
|
39
|
+
status / `externalId` / delay flags / assignee / brand / tasks[]). The
|
|
40
|
+
original top-level fields (`takedownStatus`, `createdAt`, `updatedAt`)
|
|
41
|
+
are preserved for existing callers.
|
|
42
|
+
|
|
43
|
+
**Assets — `livenessStatus` + `blockedAt` parity.** `listAssets`,
|
|
44
|
+
`listOrganizationAssets`, `assetSearch` (`.asset`), and `listThreats`
|
|
45
|
+
(`livenessStatus` only, `blockedAt` already there) now consistently
|
|
46
|
+
return both fields. `listAssets` also fixes a bug where each returned
|
|
47
|
+
row's `id` was stripped from the response mapper (the column was already
|
|
48
|
+
selected). Note: `assetCheck` is intentionally deferred — its response
|
|
49
|
+
goes through `@chainpatrol/asset`'s own `checkAsset()` contract; parity
|
|
50
|
+
there needs a scoped follow-up in the asset package.
|
|
51
|
+
|
|
52
|
+
Server-side work in `@chainpatrol/external-trpc`, `@chainpatrol/core`,
|
|
53
|
+
`@chainpatrol/validation`, and `@chainpatrol/database` backs the new
|
|
54
|
+
fields; those are private packages and don't need version bumps. Also
|
|
55
|
+
adds a `/// @deprecated` doc-comment to `Report.threatLevel` in the
|
|
56
|
+
Prisma schema — the field is not surfaced through the public API and no
|
|
57
|
+
in-app UI reads it; the column stays for now, removal is a separate
|
|
58
|
+
destructive migration.
|
|
59
|
+
|
|
60
|
+
### Patch Changes
|
|
61
|
+
|
|
62
|
+
- Updated dependencies [08b9976]
|
|
63
|
+
- @chainpatrol/sdk@1.3.0
|
|
64
|
+
|
|
65
|
+
## 1.2.0
|
|
66
|
+
|
|
67
|
+
### Minor Changes
|
|
68
|
+
|
|
69
|
+
- 3faffa0: Surface the sibling visibility knobs, brand-facing metadata, and portal
|
|
70
|
+
customization on the `/user/orgs` and `/user/orgs/{slug}` responses, on
|
|
71
|
+
`UserOrg` in the SDK, and in `chainpatrol orgs get` / `chainpatrol orgs list`
|
|
72
|
+
output (human, markdown, CSV, and JSON):
|
|
73
|
+
|
|
74
|
+
- `reportVisibility` (`PUBLIC` / `PRIVATE`) — sibling of `portalVisibility`.
|
|
75
|
+
- `metricsVisibility` (`PUBLIC` / `PRIVATE` / `DISABLED`) — sibling of the
|
|
76
|
+
above.
|
|
77
|
+
- `brandMetadata` — `{ websiteUrl, twitterHandle, securityContactEmail,
|
|
78
|
+
industry }`, all nullable.
|
|
79
|
+
- `portalCustomization` — `{ useCustomDetails, name, slug, avatarUrl,
|
|
80
|
+
bannerEnabled, bannerContent }` for the customer-configurable portal
|
|
81
|
+
presentation.
|
|
82
|
+
|
|
83
|
+
Server-side work in `@chainpatrol/external-trpc` and `@chainpatrol/validation`
|
|
84
|
+
supports the new fields; both are private packages and don't need version
|
|
85
|
+
bumps.
|
|
86
|
+
|
|
87
|
+
### Patch Changes
|
|
88
|
+
|
|
89
|
+
- Updated dependencies [3faffa0]
|
|
90
|
+
- @chainpatrol/sdk@1.2.0
|
|
91
|
+
|
|
3
92
|
## 1.1.0
|
|
4
93
|
|
|
5
94
|
### Minor Changes
|
package/dist/cli.js
CHANGED
|
@@ -1606,7 +1606,7 @@ async function main() {
|
|
|
1606
1606
|
}
|
|
1607
1607
|
case "orgs": {
|
|
1608
1608
|
if (subcommand === "list") {
|
|
1609
|
-
const { runOrgsList } = await import("./list-
|
|
1609
|
+
const { runOrgsList } = await import("./list-BAPTZNTM.js");
|
|
1610
1610
|
await runOrgsList({
|
|
1611
1611
|
query: cli.flags.query,
|
|
1612
1612
|
subscriptionStatus: cli.flags.subscriptionStatus,
|
|
@@ -1628,7 +1628,7 @@ async function main() {
|
|
|
1628
1628
|
if (subcommand === "get") {
|
|
1629
1629
|
const positionalSlug = action;
|
|
1630
1630
|
const slug = positionalSlug ?? await tryResolveOrg();
|
|
1631
|
-
const { runOrgsGet } = await import("./get-
|
|
1631
|
+
const { runOrgsGet } = await import("./get-SM5KGJVA.js");
|
|
1632
1632
|
await runOrgsGet({
|
|
1633
1633
|
slug,
|
|
1634
1634
|
json: jsonMode,
|
|
@@ -56,6 +56,27 @@ function summarizeLegalDocuments(org) {
|
|
|
56
56
|
const poa = org.legalDocuments.powerOfAttorney.present ? "yes" : "no";
|
|
57
57
|
return `LOA=${loa} POA=${poa}`;
|
|
58
58
|
}
|
|
59
|
+
function summarizeVisibility(org) {
|
|
60
|
+
return `portal=${org.portalVisibility} reports=${org.reportVisibility} metrics=${org.metricsVisibility}`;
|
|
61
|
+
}
|
|
62
|
+
function summarizeBrandMetadata(org) {
|
|
63
|
+
const { websiteUrl, twitterHandle, securityContactEmail, industry } = org.brandMetadata;
|
|
64
|
+
const parts = [];
|
|
65
|
+
if (industry) parts.push(`industry=${industry}`);
|
|
66
|
+
if (websiteUrl) parts.push(`website=${websiteUrl}`);
|
|
67
|
+
if (twitterHandle) parts.push(`twitter=${twitterHandle}`);
|
|
68
|
+
if (securityContactEmail) parts.push(`security-contact=${securityContactEmail}`);
|
|
69
|
+
return parts.length > 0 ? parts.join(" ") : "(none set)";
|
|
70
|
+
}
|
|
71
|
+
function summarizePortalCustomization(org) {
|
|
72
|
+
const c = org.portalCustomization;
|
|
73
|
+
const parts = [];
|
|
74
|
+
parts.push(c.useCustomDetails ? "custom-details=on" : "custom-details=off");
|
|
75
|
+
if (c.name) parts.push(`name=${c.name}`);
|
|
76
|
+
if (c.slug) parts.push(`slug=${c.slug}`);
|
|
77
|
+
parts.push(c.bannerEnabled ? "banner=on" : "banner=off");
|
|
78
|
+
return parts.join(" ");
|
|
79
|
+
}
|
|
59
80
|
function summarizeTrademarks(org) {
|
|
60
81
|
const count = org.trademarkRegistrations.length;
|
|
61
82
|
if (count === 0) return "none";
|
|
@@ -82,7 +103,11 @@ async function runOrgsGet(options) {
|
|
|
82
103
|
"",
|
|
83
104
|
`- Contact URL: ${organization.contactUrl ?? "(not set)"}`,
|
|
84
105
|
`- Subscription status: ${organization.subscriptionStatus}`,
|
|
85
|
-
`-
|
|
106
|
+
`- Visibility: ${summarizeVisibility(organization)}`,
|
|
107
|
+
`- Brand metadata: ${summarizeBrandMetadata(organization)}`,
|
|
108
|
+
`- Portal customization: ${summarizePortalCustomization(organization)}`,
|
|
109
|
+
organization.portalCustomization.avatarUrl ? ` - Custom avatar: ${organization.portalCustomization.avatarUrl}` : "",
|
|
110
|
+
organization.portalCustomization.bannerEnabled && organization.portalCustomization.bannerContent ? ` - Banner content: ${organization.portalCustomization.bannerContent}` : "",
|
|
86
111
|
`- Services: ${summarizeServices(organization)}`,
|
|
87
112
|
`- Integrations: ${summarizeIntegrations(organization)}`,
|
|
88
113
|
`- Obligatory admin approval: ${summarizeObligatoryAdminApproval(organization)}`,
|
|
@@ -102,6 +127,18 @@ async function runOrgsGet(options) {
|
|
|
102
127
|
contactUrl: organization.contactUrl ?? "",
|
|
103
128
|
subscriptionStatus: organization.subscriptionStatus,
|
|
104
129
|
portalVisibility: organization.portalVisibility,
|
|
130
|
+
reportVisibility: organization.reportVisibility,
|
|
131
|
+
metricsVisibility: organization.metricsVisibility,
|
|
132
|
+
industry: organization.brandMetadata.industry ?? "",
|
|
133
|
+
websiteUrl: organization.brandMetadata.websiteUrl ?? "",
|
|
134
|
+
twitterHandle: organization.brandMetadata.twitterHandle ?? "",
|
|
135
|
+
securityContactEmail: organization.brandMetadata.securityContactEmail ?? "",
|
|
136
|
+
portalUseCustomDetails: organization.portalCustomization.useCustomDetails,
|
|
137
|
+
portalName: organization.portalCustomization.name ?? "",
|
|
138
|
+
portalSlug: organization.portalCustomization.slug ?? "",
|
|
139
|
+
portalAvatarUrl: organization.portalCustomization.avatarUrl ?? "",
|
|
140
|
+
portalBannerEnabled: organization.portalCustomization.bannerEnabled,
|
|
141
|
+
portalBannerContent: organization.portalCustomization.bannerContent ?? "",
|
|
105
142
|
reportingActive: organization.services.reporting.active,
|
|
106
143
|
reviewingActive: organization.services.reviewing.active,
|
|
107
144
|
protectionActive: organization.services.protection.active,
|
|
@@ -135,7 +172,17 @@ async function runOrgsGet(options) {
|
|
|
135
172
|
console.log(`${organization.name} (slug: ${organization.slug})`);
|
|
136
173
|
console.log(` contactUrl: ${organization.contactUrl ?? "(not set)"}`);
|
|
137
174
|
console.log(` subscriptionStatus: ${organization.subscriptionStatus}`);
|
|
138
|
-
console.log(`
|
|
175
|
+
console.log(` visibility: ${summarizeVisibility(organization)}`);
|
|
176
|
+
console.log(` brandMetadata: ${summarizeBrandMetadata(organization)}`);
|
|
177
|
+
console.log(` portalCustomization: ${summarizePortalCustomization(organization)}`);
|
|
178
|
+
if (organization.portalCustomization.avatarUrl) {
|
|
179
|
+
console.log(` custom avatar: ${organization.portalCustomization.avatarUrl}`);
|
|
180
|
+
}
|
|
181
|
+
if (organization.portalCustomization.bannerEnabled && organization.portalCustomization.bannerContent) {
|
|
182
|
+
console.log(
|
|
183
|
+
` banner content: ${organization.portalCustomization.bannerContent}`
|
|
184
|
+
);
|
|
185
|
+
}
|
|
139
186
|
console.log(` services: ${summarizeServices(organization)}`);
|
|
140
187
|
console.log(` integrations: ${summarizeIntegrations(organization)}`);
|
|
141
188
|
console.log(
|
|
@@ -215,6 +215,9 @@ function summarizeLegalDocuments(org) {
|
|
|
215
215
|
const poa = org.legalDocuments.powerOfAttorney.present ? "yes" : "no";
|
|
216
216
|
return `LOA=${loa} POA=${poa}`;
|
|
217
217
|
}
|
|
218
|
+
function summarizeVisibility(org) {
|
|
219
|
+
return `portal=${org.portalVisibility} reports=${org.reportVisibility} metrics=${org.metricsVisibility}`;
|
|
220
|
+
}
|
|
218
221
|
function summarizeTrademarks(org) {
|
|
219
222
|
const count = org.trademarkRegistrations.length;
|
|
220
223
|
return count === 0 ? "0" : `${count}`;
|
|
@@ -238,7 +241,7 @@ async function runOrgsList(options) {
|
|
|
238
241
|
`# Organizations (${organizations.length})`,
|
|
239
242
|
"",
|
|
240
243
|
...organizations.map(
|
|
241
|
-
(org) => `- \`${org.slug}\` \u2014 ${org.name} \u2014 ${org.subscriptionStatus} \u2014
|
|
244
|
+
(org) => `- \`${org.slug}\` \u2014 ${org.name} \u2014 ${org.subscriptionStatus} \u2014 visibility: ${summarizeVisibility(org)} \u2014 contact: ${org.contactUrl ?? "(not set)"} \u2014 ${summarizeServices(org)} \u2014 integrations: ${summarizeIntegrations(org)} \u2014 admin-approval: ${summarizeObligatoryAdminApproval(org)} \u2014 pending-approval: ${summarizePendingApprovals(org)} \u2014 legal: ${summarizeLegalDocuments(org)} \u2014 trademarks: ${summarizeTrademarks(org)}`
|
|
242
245
|
)
|
|
243
246
|
].join("\n"),
|
|
244
247
|
csv: toCsvRows(
|
|
@@ -248,6 +251,18 @@ async function runOrgsList(options) {
|
|
|
248
251
|
contactUrl: org.contactUrl ?? "",
|
|
249
252
|
subscriptionStatus: org.subscriptionStatus,
|
|
250
253
|
portalVisibility: org.portalVisibility,
|
|
254
|
+
reportVisibility: org.reportVisibility,
|
|
255
|
+
metricsVisibility: org.metricsVisibility,
|
|
256
|
+
industry: org.brandMetadata.industry ?? "",
|
|
257
|
+
websiteUrl: org.brandMetadata.websiteUrl ?? "",
|
|
258
|
+
twitterHandle: org.brandMetadata.twitterHandle ?? "",
|
|
259
|
+
securityContactEmail: org.brandMetadata.securityContactEmail ?? "",
|
|
260
|
+
portalUseCustomDetails: org.portalCustomization.useCustomDetails,
|
|
261
|
+
portalName: org.portalCustomization.name ?? "",
|
|
262
|
+
portalSlug: org.portalCustomization.slug ?? "",
|
|
263
|
+
portalAvatarUrl: org.portalCustomization.avatarUrl ?? "",
|
|
264
|
+
portalBannerEnabled: org.portalCustomization.bannerEnabled,
|
|
265
|
+
portalBannerContent: org.portalCustomization.bannerContent ?? "",
|
|
251
266
|
reportingActive: org.services.reporting.active,
|
|
252
267
|
reviewingActive: org.services.reviewing.active,
|
|
253
268
|
protectionActive: org.services.protection.active,
|
|
@@ -286,7 +301,7 @@ async function runOrgsList(options) {
|
|
|
286
301
|
for (const org of organizations) {
|
|
287
302
|
const contact = org.contactUrl ?? "(no contact)";
|
|
288
303
|
console.log(
|
|
289
|
-
` ${org.slug.padEnd(slugWidth)} ${org.name.padEnd(nameWidth)} ${org.subscriptionStatus.padEnd(11)}
|
|
304
|
+
` ${org.slug.padEnd(slugWidth)} ${org.name.padEnd(nameWidth)} ${org.subscriptionStatus.padEnd(11)} visibility=${summarizeVisibility(org)} ${contact} ${summarizeServices(org)} integrations=${summarizeIntegrations(org)} admin-approval=${summarizeObligatoryAdminApproval(org)} pending-approval=${summarizePendingApprovals(org)} legal=${summarizeLegalDocuments(org)} trademarks=${summarizeTrademarks(org)}`
|
|
290
305
|
);
|
|
291
306
|
}
|
|
292
307
|
}
|
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": "1.
|
|
5
|
+
"version": "1.3.0",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"homepage": "https://chainpatrol.com/docs/cli",
|
|
8
8
|
"keywords": [
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"lint": "npx oxlint ."
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@chainpatrol/sdk": "1.
|
|
36
|
+
"@chainpatrol/sdk": "1.3.0",
|
|
37
37
|
"ink": "^7.0.1",
|
|
38
38
|
"meow": "^14.1.0",
|
|
39
39
|
"open": "^11.0.0",
|