@chainpatrol/cli 1.5.0 → 1.7.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +6 -1
  3. package/dist/{breakdown-5DJMXRK4.js → breakdown-2HAZ2MX5.js} +1 -1
  4. package/dist/{check-5P3EXVSN.js → check-5LJI7N5I.js} +1 -1
  5. package/dist/{chunk-OFUIYMPD.js → chunk-322AVMUH.js} +4 -0
  6. package/dist/{chunk-6VTWWGNV.js → chunk-7BZUQSRO.js} +12 -1
  7. package/dist/{chunk-PEX2A3IL.js → chunk-FPCN4SNK.js} +1 -1
  8. package/dist/{chunk-MM5OAY2U.js → chunk-YMO4QK6Q.js} +1 -1
  9. package/dist/cli.js +153 -44
  10. package/dist/{completions-ILC76OX5.js → completions-3ESPMO65.js} +1 -1
  11. package/dist/{configs-update-TAYT4JTU.js → configs-update-N7ZIWWKQ.js} +1 -1
  12. package/dist/{create-UXRULUR7.js → create-4ZJ7DXHX.js} +1 -1
  13. package/dist/{drift-TCZELVHO.js → drift-BGWNH6QE.js} +1 -1
  14. package/dist/{found-NCP6H2SD.js → found-QOARB5G2.js} +1 -1
  15. package/dist/{get-SM5KGJVA.js → get-ON5JOCV7.js} +1 -1
  16. package/dist/{healthcheck-5YEZCTXC.js → healthcheck-34LQTSVZ.js} +1 -1
  17. package/dist/{list-MPSB2DYU.js → list-5TKOWBC4.js} +2 -1
  18. package/dist/{list-2RHEVI2T.js → list-6CAKS43I.js} +1 -1
  19. package/dist/{list-WQBXC3QS.js → list-AG6LWNMN.js} +1 -1
  20. package/dist/{list-W6JZUNS2.js → list-DJFIKDY6.js} +1 -1
  21. package/dist/{list-4YBWU2JZ.js → list-IVFZGLKN.js} +1 -1
  22. package/dist/{list-23C72EH4.js → list-JG5ARDTR.js} +2 -2
  23. package/dist/{list-BAPTZNTM.js → list-MHOHKFXT.js} +1 -1
  24. package/dist/{list-TA4HYD66.js → list-PAJBOVN2.js} +1 -1
  25. package/dist/{list-QLMFMYU6.js → list-SJFJT4V3.js} +1 -1
  26. package/dist/{list-SCA73PLA.js → list-UPY6PHY4.js} +1 -1
  27. package/dist/{list-GEJQ6N2Y.js → list-UXYGISAK.js} +1 -1
  28. package/dist/{list-QJYRXPXM.js → list-W6CF25ZS.js} +1 -1
  29. package/dist/{list-json-NJ5IFRDE.js → list-json-ZR3XOQPJ.js} +1 -1
  30. package/dist/{organization-N6RMWKJM.js → organization-YAID36GZ.js} +1 -1
  31. package/dist/review-7A7WV73T.js +270 -0
  32. package/dist/{run-RRG7D4SN.js → run-AIYPHWFJ.js} +1 -1
  33. package/dist/{run-KOZXEYTL.js → run-LZZOV4HG.js} +1 -1
  34. package/dist/{run-TUADYLU7.js → run-YP4O5VXZ.js} +2 -2
  35. package/dist/{search-Y37B2JVP.js → search-IWS42COG.js} +2 -2
  36. package/dist/{search-M6EKPO4D.js → search-OGGKNPUJ.js} +1 -1
  37. package/dist/{setup-skill-RRTDEOR4.js → setup-skill-LP5Z3Z5T.js} +2 -2
  38. package/dist/{snapshot-RFGSAHO7.js → snapshot-TLSOPK7C.js} +1 -1
  39. package/dist/{summary-XCN3DRYP.js → summary-XA3PVJIW.js} +1 -1
  40. package/dist/takedown-time-ARGVSPL6.js +87 -0
  41. package/dist/{validate-OYTNB2ZM.js → validate-WB5367QN.js} +1 -1
  42. package/dist/{whoami-5WCW3FOZ.js → whoami-YE3V6I65.js} +1 -1
  43. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -13,8 +13,8 @@ import {
13
13
  getCliVersion,
14
14
  isSkillInstalled,
15
15
  readInstalledSkillVersion
16
- } from "./chunk-MM5OAY2U.js";
17
- import "./chunk-6VTWWGNV.js";
16
+ } from "./chunk-YMO4QK6Q.js";
17
+ import "./chunk-7BZUQSRO.js";
18
18
  import {
19
19
  DateTime
20
20
  } from "./chunk-TFCNKBRC.js";
@@ -286,6 +286,7 @@ var HELP = {
286
286
  "chainpatrol metrics summary --org acme --this-week",
287
287
  "chainpatrol metrics found --org acme --from 2025-01-01 --to 2025-02-01",
288
288
  "chainpatrol metrics breakdown --org acme --by day --this-week",
289
+ "chainpatrol metrics takedown-time --org acme --from 2025-01-01 --to 2025-02-01",
289
290
  "chainpatrol metrics organization --org acme --from 2025-01-01 --to 2025-02-01"
290
291
  ]
291
292
  },
@@ -346,6 +347,17 @@ var HELP = {
346
347
  "--brand <ids> Comma-separated brand IDs"
347
348
  ]
348
349
  },
350
+ "metrics takedown-time": {
351
+ description: "Median time from takedown start to completion, per asset type. Defaults to the trailing 3 months if no date range is given.",
352
+ usage: "chainpatrol metrics takedown-time --org <slug> [--from ISO --to ISO|--this-week]",
353
+ options: [
354
+ "--org <slug> Organization slug",
355
+ "--from <iso> Start date (ISO 8601)",
356
+ "--to <iso> End date (ISO 8601); a date-only value covers the whole day",
357
+ "--this-week Use the current ISO week (overrides default)",
358
+ "--brand <ids> Comma-separated brand IDs"
359
+ ]
360
+ },
349
361
  reports: {
350
362
  description: "Create, list, and search reports from the terminal.",
351
363
  usage: "chainpatrol reports <create|list|search>",
@@ -426,6 +438,39 @@ var HELP = {
426
438
  "chainpatrol reports list --org acme --needs-customer-review"
427
439
  ]
428
440
  },
441
+ proposals: {
442
+ description: "Review the proposals waiting on your organization.",
443
+ usage: "chainpatrol proposals review <proposalId> [options]",
444
+ examples: [
445
+ "chainpatrol reports list --org acme --needs-customer-review",
446
+ 'chainpatrol proposals review 4321 --asset-id 987 --decision approve --label "General Phishing"',
447
+ "chainpatrol proposals review 4321 --asset-id 987 --decision reject --reject-reason irrelevant"
448
+ ]
449
+ },
450
+ "proposals review": {
451
+ description: "Approve, reject, or watchlist a proposal that is waiting on your organization's review \u2014 the same queue the Review page shows and `reports list --needs-customer-review` returns. Find the proposal and asset IDs in that listing's `proposals[].id` and `proposals[].asset.id`. A review cannot be undone over the API, so the command asks for confirmation unless you pass --yes, and it is capped at 10 reviews per organization per day across all of the org's API credentials.",
452
+ usage: "chainpatrol proposals review <proposalId> --asset-id <id> --decision <approve|reject|watchlist> [options]",
453
+ options: [
454
+ "--proposal-id <id> Proposal to review (alternative to the positional arg)",
455
+ "--asset-id <id> Asset the proposal targets; must match, or the API returns 409",
456
+ "--decision <d> approve|reject|watchlist (watchlist rejects and parks the asset)",
457
+ '--label <text> Block label, required when approving. Quote it: e.g. "General Phishing", "Brand Impersonation", "Employee Impersonation", "Fake Employee", "Targeting Org Users", "C2 Server", "False Positive"',
458
+ "--brand-id <id> Brand the asset impersonates; required for Brand/Employee Impersonation",
459
+ "--reject-reason <r> Required when rejecting: irrelevant|no_malicious_activity|insufficient_evidence|not_targeting_org|decayed",
460
+ "--watchlist-reason <r> Required when watchlisting: DEAD|PARKING|NOT_ENOUGH_EVIDENCE|OTHER",
461
+ "--note <text> Free-text detail; required when --watchlist-reason OTHER",
462
+ "--org <slug> Organization slug (optional for org-scoped API keys)",
463
+ "--yes Skip the confirmation prompt (required when not on a TTY)",
464
+ "--dry-run Preview the payload without submitting"
465
+ ],
466
+ examples: [
467
+ 'chainpatrol proposals review 4321 --asset-id 987 --decision approve --label "General Phishing" --yes',
468
+ 'chainpatrol proposals review 4321 --asset-id 987 --decision approve --label "Brand Impersonation" --brand-id 12 --yes',
469
+ "chainpatrol proposals review 4321 --asset-id 987 --decision reject --reject-reason no_malicious_activity --yes",
470
+ 'chainpatrol proposals review 4321 --asset-id 987 --decision watchlist --watchlist-reason OTHER --note "Registrar suspended it" --yes',
471
+ "chainpatrol proposals review 4321 --asset-id 987 --decision reject --reject-reason decayed --dry-run"
472
+ ]
473
+ },
429
474
  queues: {
430
475
  description: "Snapshot operations review/takedown queues.",
431
476
  usage: "chainpatrol queues snapshot [--org <slug>|--all]",
@@ -523,9 +568,10 @@ var HELP = {
523
568
  usage: "chainpatrol orgs assets list [filters]"
524
569
  },
525
570
  "orgs assets list": {
526
- description: "List assets belonging to your organization's allowlist. Org is derived from your API key. Supports filtering by type, group, and search query.",
571
+ description: "List assets belonging to an organization's allowlist. Pass --org <slug> to choose one, or omit it to use the org tied to your API key. Supports filtering by type, group, and search query.",
527
572
  usage: "chainpatrol orgs assets list [filters]",
528
573
  options: [
574
+ "--org <slug> Organization slug (omit for org-scoped API keys)",
529
575
  "--asset-type <type> Filter by asset type (URL, ADDRESS, ...)",
530
576
  "--type <type> Alias for --asset-type",
531
577
  "--group-id <n> Filter by group ID. Use -1 for ungrouped assets only",
@@ -535,6 +581,7 @@ var HELP = {
535
581
  ],
536
582
  examples: [
537
583
  "chainpatrol orgs assets list --asset-type URL",
584
+ "chainpatrol orgs assets list --org acme --per-page 1000",
538
585
  "chainpatrol orgs assets list --group-id 12 --per-page 250 --output csv"
539
586
  ]
540
587
  },
@@ -681,6 +728,7 @@ function getTopLevelHelp() {
681
728
  " healthchecks List and run organization healthchecks",
682
729
  " metrics Query organization metrics and breakdowns",
683
730
  " reports Create, list, and search reports from terminal",
731
+ " proposals Review proposals waiting on your organization",
684
732
  " queues Snapshot operations review/takedown queues",
685
733
  " takedowns List individual takedown records",
686
734
  " threats List confirmed threats blocked by ChainPatrol",
@@ -854,6 +902,7 @@ var COMMANDS = [
854
902
  "healthchecks",
855
903
  "metrics",
856
904
  "reports",
905
+ "proposals",
857
906
  "queues",
858
907
  "takedowns",
859
908
  "threats",
@@ -936,6 +985,15 @@ ${getTopLevelHelp()}
936
985
  search: { type: "string" },
937
986
  reportedByCustomer: { type: "boolean" },
938
987
  needsCustomerReview: { type: "boolean" },
988
+ proposalId: { type: "number" },
989
+ assetId: { type: "number" },
990
+ decision: { type: "string" },
991
+ label: { type: "string" },
992
+ brandId: { type: "number" },
993
+ rejectReason: { type: "string" },
994
+ watchlistReason: { type: "string" },
995
+ note: { type: "string" },
996
+ yes: { type: "boolean", default: false },
939
997
  attachmentUrl: { type: "string" },
940
998
  contactInfo: { type: "string" },
941
999
  externalSubmissionLink: { type: "string" },
@@ -1115,12 +1173,12 @@ function parseAttachmentUrls() {
1115
1173
  }
1116
1174
  async function handleConfigsList(org) {
1117
1175
  if (jsonMode) {
1118
- const { listConfigsJson } = await import("./list-json-NJ5IFRDE.js");
1176
+ const { listConfigsJson } = await import("./list-json-ZR3XOQPJ.js");
1119
1177
  await listConfigsJson({ org });
1120
1178
  return;
1121
1179
  }
1122
1180
  const { render } = await import("ink");
1123
- const { default: ConfigsList } = await import("./list-2RHEVI2T.js");
1181
+ const { default: ConfigsList } = await import("./list-6CAKS43I.js");
1124
1182
  const { default: React } = await import("react");
1125
1183
  render(React.createElement(ConfigsList, { org }));
1126
1184
  }
@@ -1159,7 +1217,7 @@ async function main() {
1159
1217
  return;
1160
1218
  }
1161
1219
  if (cliContext.dryRun) {
1162
- const dryRunSupported = command === "reports" && subcommand === "create" || command === "detections" && subcommand === "run" || command === "detections" && subcommand === "configs" && action === "run" || command === "detections" && subcommand === "configs" && action === "update";
1220
+ const dryRunSupported = command === "reports" && subcommand === "create" || command === "proposals" && subcommand === "review" || command === "detections" && subcommand === "run" || command === "detections" && subcommand === "configs" && action === "run" || command === "detections" && subcommand === "configs" && action === "update";
1163
1221
  if (!dryRunSupported) {
1164
1222
  throw new CliExitError(
1165
1223
  "--dry-run is only supported for mutation commands.",
@@ -1220,7 +1278,7 @@ async function main() {
1220
1278
  const positionals = cli.input.slice(2);
1221
1279
  const flagAssets = parseAssetInputs();
1222
1280
  const contents = [...positionals, ...flagAssets];
1223
- const { runAssetCheck } = await import("./check-5P3EXVSN.js");
1281
+ const { runAssetCheck } = await import("./check-5LJI7N5I.js");
1224
1282
  await runAssetCheck({
1225
1283
  contents,
1226
1284
  json: jsonMode,
@@ -1230,7 +1288,7 @@ async function main() {
1230
1288
  break;
1231
1289
  }
1232
1290
  if (subcommand === "list") {
1233
- const { runAssetList } = await import("./list-GEJQ6N2Y.js");
1291
+ const { runAssetList } = await import("./list-UXYGISAK.js");
1234
1292
  await runAssetList({
1235
1293
  type: cli.flags.type ?? cli.flags.assetType,
1236
1294
  status: cli.flags.assetStatus ?? cli.flags.status,
@@ -1255,7 +1313,7 @@ async function main() {
1255
1313
  }
1256
1314
  return n;
1257
1315
  });
1258
- const { runAssetSearch } = await import("./search-Y37B2JVP.js");
1316
+ const { runAssetSearch } = await import("./search-IWS42COG.js");
1259
1317
  await runAssetSearch({
1260
1318
  contents: contents.length > 0 ? contents : void 0,
1261
1319
  ids: ids.length > 0 ? ids : void 0,
@@ -1280,7 +1338,7 @@ async function main() {
1280
1338
  case "detections": {
1281
1339
  const org = await resolveOrg();
1282
1340
  if (subcommand === "healthcheck") {
1283
- const { runDetectionsHealthcheck } = await import("./healthcheck-5YEZCTXC.js");
1341
+ const { runDetectionsHealthcheck } = await import("./healthcheck-34LQTSVZ.js");
1284
1342
  await runDetectionsHealthcheck({
1285
1343
  org,
1286
1344
  source: cli.flags.source,
@@ -1295,7 +1353,7 @@ async function main() {
1295
1353
  break;
1296
1354
  }
1297
1355
  if (subcommand === "validate") {
1298
- const { runDetectionsValidate } = await import("./validate-OYTNB2ZM.js");
1356
+ const { runDetectionsValidate } = await import("./validate-WB5367QN.js");
1299
1357
  await runDetectionsValidate({
1300
1358
  org,
1301
1359
  source: cli.flags.source,
@@ -1310,7 +1368,7 @@ async function main() {
1310
1368
  break;
1311
1369
  }
1312
1370
  if (subcommand === "drift") {
1313
- const { runDetectionsDrift } = await import("./drift-TCZELVHO.js");
1371
+ const { runDetectionsDrift } = await import("./drift-BGWNH6QE.js");
1314
1372
  await runDetectionsDrift({
1315
1373
  org,
1316
1374
  source: cli.flags.source,
@@ -1324,7 +1382,7 @@ async function main() {
1324
1382
  break;
1325
1383
  }
1326
1384
  if (subcommand === "run") {
1327
- const { runDetectionsRun } = await import("./run-KOZXEYTL.js");
1385
+ const { runDetectionsRun } = await import("./run-LZZOV4HG.js");
1328
1386
  await runDetectionsRun({
1329
1387
  org,
1330
1388
  configId: cli.flags.configId,
@@ -1338,7 +1396,7 @@ async function main() {
1338
1396
  break;
1339
1397
  }
1340
1398
  if (subcommand === "list") {
1341
- const { runDetectionsList } = await import("./list-W6JZUNS2.js");
1399
+ const { runDetectionsList } = await import("./list-DJFIKDY6.js");
1342
1400
  await runDetectionsList({
1343
1401
  org,
1344
1402
  cursor: cli.flags.cursor,
@@ -1367,7 +1425,7 @@ async function main() {
1367
1425
  break;
1368
1426
  }
1369
1427
  if (action === "run") {
1370
- const { runDetectionsRun } = await import("./run-KOZXEYTL.js");
1428
+ const { runDetectionsRun } = await import("./run-LZZOV4HG.js");
1371
1429
  await runDetectionsRun({
1372
1430
  org,
1373
1431
  configId: cli.flags.configId,
@@ -1385,7 +1443,7 @@ async function main() {
1385
1443
  throw new Error("detections configs update requires --config-id");
1386
1444
  }
1387
1445
  const configPatch = getConfigPatchFromSetFlags();
1388
- const { runDetectionsConfigsUpdate } = await import("./configs-update-TAYT4JTU.js");
1446
+ const { runDetectionsConfigsUpdate } = await import("./configs-update-N7ZIWWKQ.js");
1389
1447
  await runDetectionsConfigsUpdate({
1390
1448
  org,
1391
1449
  configId: cli.flags.configId,
@@ -1421,7 +1479,7 @@ async function main() {
1421
1479
  const slugs = parseCsvList(cli.flags.slugs);
1422
1480
  const allMyOrgs = cli.flags.allMyOrgs;
1423
1481
  const org2 = slugs && slugs.length > 0 || allMyOrgs ? void 0 : await tryResolveOrg();
1424
- const { runMetricsOrganization } = await import("./organization-N6RMWKJM.js");
1482
+ const { runMetricsOrganization } = await import("./organization-YAID36GZ.js");
1425
1483
  await runMetricsOrganization({
1426
1484
  org: org2,
1427
1485
  slugs,
@@ -1440,7 +1498,7 @@ async function main() {
1440
1498
  }
1441
1499
  const org = await resolveOrg();
1442
1500
  if (subcommand === "summary") {
1443
- const { runMetricsSummary } = await import("./summary-XCN3DRYP.js");
1501
+ const { runMetricsSummary } = await import("./summary-XA3PVJIW.js");
1444
1502
  await runMetricsSummary({
1445
1503
  org,
1446
1504
  from: cli.flags.from,
@@ -1453,7 +1511,7 @@ async function main() {
1453
1511
  break;
1454
1512
  }
1455
1513
  if (subcommand === "found") {
1456
- const { runMetricsFound } = await import("./found-NCP6H2SD.js");
1514
+ const { runMetricsFound } = await import("./found-QOARB5G2.js");
1457
1515
  await runMetricsFound({
1458
1516
  org,
1459
1517
  from: cli.flags.from,
@@ -1465,12 +1523,25 @@ async function main() {
1465
1523
  });
1466
1524
  break;
1467
1525
  }
1526
+ if (subcommand === "takedown-time" || subcommand === "takedownTime") {
1527
+ const { runMetricsTakedownTime } = await import("./takedown-time-ARGVSPL6.js");
1528
+ await runMetricsTakedownTime({
1529
+ org,
1530
+ from: cli.flags.from,
1531
+ to: cli.flags.to,
1532
+ thisWeek: cli.flags.thisWeek,
1533
+ brandIds: parseBrandIds(),
1534
+ json: jsonMode,
1535
+ outputFormat: cliContext.outputFormat
1536
+ });
1537
+ break;
1538
+ }
1468
1539
  if (subcommand === "breakdown") {
1469
1540
  const by = cli.flags.by;
1470
1541
  if (!by || !["day", "type", "brand"].includes(by)) {
1471
1542
  throw new Error("metrics breakdown requires --by <day|type|brand>");
1472
1543
  }
1473
- const { runMetricsBreakdown } = await import("./breakdown-5DJMXRK4.js");
1544
+ const { runMetricsBreakdown } = await import("./breakdown-2HAZ2MX5.js");
1474
1545
  await runMetricsBreakdown({
1475
1546
  org,
1476
1547
  by,
@@ -1483,15 +1554,21 @@ async function main() {
1483
1554
  });
1484
1555
  break;
1485
1556
  }
1486
- const hint = subcommand ? suggest(subcommand, ["summary", "found", "breakdown", "organization"]) : null;
1557
+ const hint = subcommand ? suggest(subcommand, [
1558
+ "summary",
1559
+ "found",
1560
+ "breakdown",
1561
+ "takedown-time",
1562
+ "organization"
1563
+ ]) : null;
1487
1564
  throw new Error(
1488
- subcommand ? `Unknown subcommand: metrics ${subcommand}${hint ? `. Did you mean "metrics ${hint}"?` : ""}` : "Usage: chainpatrol metrics <summary|found|breakdown|organization>"
1565
+ subcommand ? `Unknown subcommand: metrics ${subcommand}${hint ? `. Did you mean "metrics ${hint}"?` : ""}` : "Usage: chainpatrol metrics <summary|found|breakdown|takedown-time|organization>"
1489
1566
  );
1490
1567
  }
1491
1568
  case "reports": {
1492
1569
  if (subcommand === "list") {
1493
1570
  const org = await resolveOrg();
1494
- const { runReportsList } = await import("./list-WQBXC3QS.js");
1571
+ const { runReportsList } = await import("./list-AG6LWNMN.js");
1495
1572
  await runReportsList({
1496
1573
  org,
1497
1574
  limit: cli.flags.limit,
@@ -1522,7 +1599,7 @@ async function main() {
1522
1599
  }
1523
1600
  if (subcommand === "create") {
1524
1601
  const org = await tryResolveOrg();
1525
- const { runReportsCreate } = await import("./create-UXRULUR7.js");
1602
+ const { runReportsCreate } = await import("./create-4ZJ7DXHX.js");
1526
1603
  await runReportsCreate({
1527
1604
  org,
1528
1605
  title: cli.flags.title,
@@ -1544,7 +1621,7 @@ async function main() {
1544
1621
  const positionals = cli.input.slice(2);
1545
1622
  const flagAssets = parseAssetInputs();
1546
1623
  const assetContents = [...positionals, ...flagAssets];
1547
- const { runReportsSearch } = await import("./search-M6EKPO4D.js");
1624
+ const { runReportsSearch } = await import("./search-OGGKNPUJ.js");
1548
1625
  await runReportsSearch({
1549
1626
  assetContents,
1550
1627
  org,
@@ -1560,9 +1637,38 @@ async function main() {
1560
1637
  subcommand ? `Unknown subcommand: reports ${subcommand}${hint ? `. Did you mean "reports ${hint}"?` : ""}` : "Usage: chainpatrol reports <create|list|search>"
1561
1638
  );
1562
1639
  }
1640
+ case "proposals": {
1641
+ if (subcommand === "review") {
1642
+ const org = await tryResolveOrg();
1643
+ const positionalProposalId = cli.input[2];
1644
+ const { runProposalsReview } = await import("./review-7A7WV73T.js");
1645
+ await runProposalsReview({
1646
+ org,
1647
+ proposalId: cli.flags.proposalId ?? (positionalProposalId ? Number(positionalProposalId) : void 0),
1648
+ assetId: cli.flags.assetId,
1649
+ decision: cli.flags.decision,
1650
+ label: cli.flags.label,
1651
+ brandId: cli.flags.brandId,
1652
+ rejectReason: cli.flags.rejectReason,
1653
+ watchlistReason: cli.flags.watchlistReason,
1654
+ note: cli.flags.note,
1655
+ yes: cli.flags.yes,
1656
+ noInput: cli.flags.noInput,
1657
+ json: jsonMode,
1658
+ outputFormat: cliContext.outputFormat,
1659
+ explain: cliContext.explain,
1660
+ dryRun: cliContext.dryRun
1661
+ });
1662
+ break;
1663
+ }
1664
+ const hint = subcommand ? suggest(subcommand, ["review"]) : null;
1665
+ throw new Error(
1666
+ subcommand ? `Unknown subcommand: proposals ${subcommand}${hint ? `. Did you mean "proposals ${hint}"?` : ""}` : "Usage: chainpatrol proposals review <proposalId> --asset-id <id> --decision <approve|reject|watchlist>"
1667
+ );
1668
+ }
1563
1669
  case "threats": {
1564
1670
  if (subcommand === "list") {
1565
- const { runThreatsList } = await import("./list-SCA73PLA.js");
1671
+ const { runThreatsList } = await import("./list-UPY6PHY4.js");
1566
1672
  await runThreatsList({
1567
1673
  query: cli.flags.query,
1568
1674
  from: cli.flags.from,
@@ -1585,7 +1691,7 @@ async function main() {
1585
1691
  case "takedowns": {
1586
1692
  if (subcommand === "list") {
1587
1693
  const org = await tryResolveOrg();
1588
- const { runTakedownsList } = await import("./list-TA4HYD66.js");
1694
+ const { runTakedownsList } = await import("./list-PAJBOVN2.js");
1589
1695
  await runTakedownsList({
1590
1696
  org,
1591
1697
  query: cli.flags.query,
@@ -1616,7 +1722,7 @@ async function main() {
1616
1722
  }
1617
1723
  case "queues": {
1618
1724
  if (subcommand === "snapshot") {
1619
- const { runQueuesSnapshot } = await import("./snapshot-RFGSAHO7.js");
1725
+ const { runQueuesSnapshot } = await import("./snapshot-TLSOPK7C.js");
1620
1726
  await runQueuesSnapshot({
1621
1727
  org: cli.flags.org,
1622
1728
  all: cli.flags.all,
@@ -1634,7 +1740,7 @@ async function main() {
1634
1740
  }
1635
1741
  case "orgs": {
1636
1742
  if (subcommand === "list") {
1637
- const { runOrgsList } = await import("./list-BAPTZNTM.js");
1743
+ const { runOrgsList } = await import("./list-MHOHKFXT.js");
1638
1744
  await runOrgsList({
1639
1745
  query: cli.flags.query,
1640
1746
  subscriptionStatus: cli.flags.subscriptionStatus,
@@ -1656,7 +1762,7 @@ async function main() {
1656
1762
  if (subcommand === "get") {
1657
1763
  const positionalSlug = action;
1658
1764
  const slug = positionalSlug ?? await tryResolveOrg();
1659
- const { runOrgsGet } = await import("./get-SM5KGJVA.js");
1765
+ const { runOrgsGet } = await import("./get-ON5JOCV7.js");
1660
1766
  await runOrgsGet({
1661
1767
  slug,
1662
1768
  json: jsonMode,
@@ -1666,8 +1772,11 @@ async function main() {
1666
1772
  }
1667
1773
  if (subcommand === "assets") {
1668
1774
  if (action === "list") {
1669
- const { runOrgsAssetsList } = await import("./list-MPSB2DYU.js");
1775
+ const { runOrgsAssetsList } = await import("./list-5TKOWBC4.js");
1670
1776
  await runOrgsAssetsList({
1777
+ // Optional: organization-scoped API keys resolve the org from the
1778
+ // key, so only pass a slug when one is actually available.
1779
+ slug: await tryResolveOrg(),
1671
1780
  type: cli.flags.type ?? cli.flags.assetType,
1672
1781
  groupId: cli.flags.groupId,
1673
1782
  query: cli.flags.query ?? cli.flags.search,
@@ -1682,7 +1791,7 @@ async function main() {
1682
1791
  }
1683
1792
  if (subcommand === "asset-groups") {
1684
1793
  if (action === "list") {
1685
- const { runOrgsAssetGroupsList } = await import("./list-QLMFMYU6.js");
1794
+ const { runOrgsAssetGroupsList } = await import("./list-SJFJT4V3.js");
1686
1795
  await runOrgsAssetGroupsList({
1687
1796
  json: jsonMode,
1688
1797
  outputFormat: cliContext.outputFormat
@@ -1699,12 +1808,12 @@ async function main() {
1699
1808
  case "brands": {
1700
1809
  if (subcommand === "list") {
1701
1810
  const rawType = cli.flags.type?.toUpperCase();
1702
- if (rawType && rawType !== "ORGANIZATION" && rawType !== "INDIVIDUAL") {
1811
+ if (rawType && rawType !== "ORGANIZATION" && rawType !== "INDIVIDUAL" && rawType !== "PRODUCT") {
1703
1812
  throw new Error(
1704
- "brands list --type must be ORGANIZATION or INDIVIDUAL (case-insensitive)."
1813
+ "brands list --type must be ORGANIZATION, INDIVIDUAL, or PRODUCT (case-insensitive)."
1705
1814
  );
1706
1815
  }
1707
- const { runBrandsList } = await import("./list-4YBWU2JZ.js");
1816
+ const { runBrandsList } = await import("./list-IVFZGLKN.js");
1708
1817
  await runBrandsList({
1709
1818
  type: rawType,
1710
1819
  json: jsonMode,
@@ -1714,11 +1823,11 @@ async function main() {
1714
1823
  }
1715
1824
  const hint = subcommand ? suggest(subcommand, ["list"]) : null;
1716
1825
  throw new Error(
1717
- subcommand ? `Unknown subcommand: brands ${subcommand}${hint ? `. Did you mean "brands ${hint}"?` : ""}` : "Usage: chainpatrol brands list [--type ORGANIZATION|INDIVIDUAL]"
1826
+ subcommand ? `Unknown subcommand: brands ${subcommand}${hint ? `. Did you mean "brands ${hint}"?` : ""}` : "Usage: chainpatrol brands list [--type ORGANIZATION|INDIVIDUAL|PRODUCT]"
1718
1827
  );
1719
1828
  }
1720
1829
  case "whoami": {
1721
- const { runWhoami } = await import("./whoami-5WCW3FOZ.js");
1830
+ const { runWhoami } = await import("./whoami-YE3V6I65.js");
1722
1831
  await runWhoami({
1723
1832
  json: jsonMode,
1724
1833
  outputFormat: cliContext.outputFormat
@@ -1727,7 +1836,7 @@ async function main() {
1727
1836
  }
1728
1837
  case "healthchecks": {
1729
1838
  if (subcommand === "list") {
1730
- const { runHealthchecksList } = await import("./list-QJYRXPXM.js");
1839
+ const { runHealthchecksList } = await import("./list-W6CF25ZS.js");
1731
1840
  await runHealthchecksList({
1732
1841
  json: jsonMode,
1733
1842
  outputFormat: cliContext.outputFormat
@@ -1741,7 +1850,7 @@ async function main() {
1741
1850
  thresholds.minResults = cli.flags.minResults;
1742
1851
  if (cli.flags.lookbackHours !== void 0)
1743
1852
  thresholds.lookbackHours = cli.flags.lookbackHours;
1744
- const { runHealthchecksRun } = await import("./run-RRG7D4SN.js");
1853
+ const { runHealthchecksRun } = await import("./run-AIYPHWFJ.js");
1745
1854
  await runHealthchecksRun({
1746
1855
  org,
1747
1856
  id: action,
@@ -1759,7 +1868,7 @@ async function main() {
1759
1868
  }
1760
1869
  case "presets": {
1761
1870
  if (subcommand === "list") {
1762
- const { runPresetsList } = await import("./list-23C72EH4.js");
1871
+ const { runPresetsList } = await import("./list-JG5ARDTR.js");
1763
1872
  await runPresetsList({ outputFormat: cliContext.outputFormat });
1764
1873
  break;
1765
1874
  }
@@ -1770,7 +1879,7 @@ async function main() {
1770
1879
  );
1771
1880
  }
1772
1881
  const org = await resolveOrg();
1773
- const { runPresetsRun } = await import("./run-TUADYLU7.js");
1882
+ const { runPresetsRun } = await import("./run-YP4O5VXZ.js");
1774
1883
  await runPresetsRun({
1775
1884
  presetId: action,
1776
1885
  org,
@@ -1787,17 +1896,17 @@ async function main() {
1787
1896
  case "setup":
1788
1897
  case "install":
1789
1898
  case "i": {
1790
- const { setupSkill } = await import("./setup-skill-RRTDEOR4.js");
1899
+ const { setupSkill } = await import("./setup-skill-LP5Z3Z5T.js");
1791
1900
  setupSkill({ json: jsonMode, cloud: cli.flags.cloud });
1792
1901
  break;
1793
1902
  }
1794
1903
  case "uninstall": {
1795
- const { uninstallSkill } = await import("./setup-skill-RRTDEOR4.js");
1904
+ const { uninstallSkill } = await import("./setup-skill-LP5Z3Z5T.js");
1796
1905
  uninstallSkill({ json: jsonMode });
1797
1906
  break;
1798
1907
  }
1799
1908
  case "completions": {
1800
- const { printCompletions } = await import("./completions-ILC76OX5.js");
1909
+ const { printCompletions } = await import("./completions-3ESPMO65.js");
1801
1910
  printCompletions(subcommand);
1802
1911
  break;
1803
1912
  }
@@ -3,7 +3,7 @@ import {
3
3
  installCompletions,
4
4
  printCompletions,
5
5
  uninstallCompletions
6
- } from "./chunk-6VTWWGNV.js";
6
+ } from "./chunk-7BZUQSRO.js";
7
7
  export {
8
8
  getCompletionScript,
9
9
  installCompletions,
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-OFUIYMPD.js";
10
+ } from "./chunk-322AVMUH.js";
11
11
  import "./chunk-EGWK6SRQ.js";
12
12
  import "./chunk-U73SABXK.js";
13
13
 
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-OFUIYMPD.js";
11
+ } from "./chunk-322AVMUH.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-U73SABXK.js";
14
14
 
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-OFUIYMPD.js";
11
+ } from "./chunk-322AVMUH.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-U73SABXK.js";
14
14
 
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-OFUIYMPD.js";
10
+ } from "./chunk-322AVMUH.js";
11
11
  import "./chunk-TFCNKBRC.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-U73SABXK.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-OFUIYMPD.js";
11
+ } from "./chunk-322AVMUH.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-U73SABXK.js";
14
14
 
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-OFUIYMPD.js";
11
+ } from "./chunk-322AVMUH.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-U73SABXK.js";
14
14
 
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-OFUIYMPD.js";
11
+ } from "./chunk-322AVMUH.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-U73SABXK.js";
14
14
 
@@ -37,6 +37,7 @@ async function runOrgsAssetsList(options) {
37
37
  }
38
38
  const client = options.apiClient ?? createApiClient();
39
39
  const input = {
40
+ slug: options.slug,
40
41
  type: options.type ? options.type.toUpperCase() : void 0,
41
42
  groupId: options.groupId,
42
43
  query: options.query,
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-JCMWDZYY.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-OFUIYMPD.js";
7
+ } from "./chunk-322AVMUH.js";
8
8
  import {
9
9
  AuthCorruptedError,
10
10
  AuthExpiredError,
@@ -10,7 +10,7 @@ import {
10
10
  REPORT_REVIEW_DECISIONS,
11
11
  REPORT_STATUSES,
12
12
  createApiClient
13
- } from "./chunk-OFUIYMPD.js";
13
+ } from "./chunk-322AVMUH.js";
14
14
  import "./chunk-EGWK6SRQ.js";
15
15
  import "./chunk-U73SABXK.js";
16
16
 
@@ -12,7 +12,7 @@ import {
12
12
  LIVENESS_FILTER_VALUES,
13
13
  WATCHLIST_FILTER_VALUES,
14
14
  createApiClient
15
- } from "./chunk-OFUIYMPD.js";
15
+ } from "./chunk-322AVMUH.js";
16
16
  import "./chunk-EGWK6SRQ.js";
17
17
  import "./chunk-U73SABXK.js";
18
18
 
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-OFUIYMPD.js";
7
+ } from "./chunk-322AVMUH.js";
8
8
  import "./chunk-EGWK6SRQ.js";
9
9
  import "./chunk-U73SABXK.js";
10
10
 
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  PRESETS
3
- } from "./chunk-PEX2A3IL.js";
3
+ } from "./chunk-FPCN4SNK.js";
4
4
  import "./chunk-E2LAMILJ.js";
5
5
  import {
6
6
  printOutput,
7
7
  toCsvRows
8
8
  } from "./chunk-VFT3TD3E.js";
9
- import "./chunk-OFUIYMPD.js";
9
+ import "./chunk-322AVMUH.js";
10
10
  import "./chunk-TFCNKBRC.js";
11
11
  import "./chunk-EGWK6SRQ.js";
12
12
  import "./chunk-U73SABXK.js";