@chainpatrol/cli 0.9.0 → 0.11.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 (32) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +16 -2
  3. package/dist/{breakdown-63FAOVL7.js → breakdown-MM5GSZKV.js} +1 -1
  4. package/dist/check-GDKUHVQI.js +203 -0
  5. package/dist/{chunk-BJISZ3CY.js → chunk-37KYJWB3.js} +1 -1
  6. package/dist/{chunk-P4L4N5LM.js → chunk-EPKNZRX6.js} +34 -5
  7. package/dist/{chunk-RIKR2WFT.js → chunk-SX3L6NKR.js} +85 -4
  8. package/dist/{chunk-Z76CUWSS.js → chunk-YXRFUYA6.js} +13 -2
  9. package/dist/cli.js +146 -37
  10. package/dist/{completions-D6SOLU2D.js → completions-62OW3B3Y.js} +1 -1
  11. package/dist/{configs-update-2IOSKZH5.js → configs-update-7X7657PB.js} +1 -1
  12. package/dist/{create-EWS3SFCH.js → create-FL4QQTPN.js} +1 -1
  13. package/dist/{drift-Q3VG3XG3.js → drift-JKBHWWFU.js} +1 -1
  14. package/dist/{found-22B7RZT5.js → found-3WI4XQG4.js} +1 -1
  15. package/dist/{healthcheck-C3AIMUJT.js → healthcheck-EVQVPGWW.js} +1 -1
  16. package/dist/{list-IA4CSOIY.js → list-5DN6X3DP.js} +1 -1
  17. package/dist/{list-DNRWKM5O.js → list-BLNIE4GL.js} +1 -1
  18. package/dist/{list-AYHDFSQG.js → list-E5XNR2YG.js} +1 -1
  19. package/dist/list-JPG2ZSR4.js +137 -0
  20. package/dist/{list-HFWSMLGJ.js → list-ULHPOUJV.js} +2 -2
  21. package/dist/{list-SDBLGBVW.js → list-XDGU6SJQ.js} +1 -1
  22. package/dist/{list-json-CEPGVUGF.js → list-json-R2MIXADX.js} +1 -1
  23. package/dist/organization-MJRKWC4Z.js +75 -0
  24. package/dist/{run-AQMJRFGL.js → run-2YZZGZYN.js} +1 -1
  25. package/dist/{run-YTWNQD5X.js → run-5E5EC3MP.js} +1 -1
  26. package/dist/{run-WJGHJPXN.js → run-EUVRC72M.js} +2 -2
  27. package/dist/{setup-skill-DR4KGQMG.js → setup-skill-HAENFIFQ.js} +2 -2
  28. package/dist/{snapshot-C5MZWJTW.js → snapshot-3FUJICJJ.js} +1 -1
  29. package/dist/{summary-NQDZQEOD.js → summary-RVYQUKWV.js} +1 -1
  30. package/dist/{validate-5DVPSXJP.js → validate-UOVKEAJM.js} +1 -1
  31. package/package.json +1 -1
  32. package/dist/check-YZRIAUOK.js +0 -85
package/dist/cli.js CHANGED
@@ -13,8 +13,8 @@ import {
13
13
  getCliVersion,
14
14
  isSkillInstalled,
15
15
  readInstalledSkillVersion
16
- } from "./chunk-P4L4N5LM.js";
17
- import "./chunk-Z76CUWSS.js";
16
+ } from "./chunk-EPKNZRX6.js";
17
+ import "./chunk-YXRFUYA6.js";
18
18
  import {
19
19
  DateTime
20
20
  } from "./chunk-TFCNKBRC.js";
@@ -92,18 +92,24 @@ var HELP = {
92
92
  usage: "chainpatrol logout"
93
93
  },
94
94
  asset: {
95
- description: "Check whether an asset is BLOCKED, ALLOWED, or UNKNOWN.",
96
- usage: "chainpatrol asset check <content>",
95
+ description: "Check whether one or more assets are BLOCKED, ALLOWED, or UNKNOWN.",
96
+ usage: "chainpatrol asset check <content> [<content> ...]",
97
97
  examples: [
98
98
  "chainpatrol asset check https://phish.example",
99
+ "chainpatrol asset check a.example b.example c.example",
99
100
  "chainpatrol --json asset check 0xabc123\u2026"
100
101
  ]
101
102
  },
102
103
  "asset check": {
103
- description: "Look up an asset (URL, domain, or crypto address) against the ChainPatrol blocklist and external feeds. Returns the aggregated status plus a per-source breakdown.",
104
- usage: "chainpatrol asset check <content>",
104
+ description: "Look up one or more assets (URL, domain, or crypto address) against the ChainPatrol blocklist and external feeds. Returns the aggregated status plus a per-source breakdown. Multiple assets can be passed as positional arguments or via repeated --asset; they are checked in parallel (concurrency 10).",
105
+ usage: "chainpatrol asset check <content> [<content> ...]",
106
+ options: [
107
+ "--asset <content> Asset content (repeatable; alternative to positional args)"
108
+ ],
105
109
  examples: [
106
110
  "chainpatrol asset check https://phish.example",
111
+ "chainpatrol asset check a.example b.example c.example --json",
112
+ "chainpatrol asset check --asset a.example --asset b.example --output csv",
107
113
  "chainpatrol asset check phish.example --output markdown",
108
114
  "chainpatrol --json asset check 0xabc123\u2026"
109
115
  ]
@@ -201,12 +207,28 @@ var HELP = {
201
207
  },
202
208
  metrics: {
203
209
  description: "Query organization metrics and breakdowns.",
204
- usage: "chainpatrol metrics <summary|found|breakdown>",
210
+ usage: "chainpatrol metrics <summary|found|breakdown|organization>",
205
211
  options: ["--org <slug> Organization slug"],
206
212
  examples: [
207
213
  "chainpatrol metrics summary --org acme --this-week",
208
214
  "chainpatrol metrics found --org acme --from 2025-01-01 --to 2025-02-01",
209
- "chainpatrol metrics breakdown --org acme --by day --this-week"
215
+ "chainpatrol metrics breakdown --org acme --by day --this-week",
216
+ "chainpatrol metrics organization --org acme --from 2025-01-01 --to 2025-02-01"
217
+ ]
218
+ },
219
+ "metrics organization": {
220
+ description: "Get organization metrics via the documented GET /organization/metrics endpoint. Works with both API key auth (org derived from key) and session auth (pass --org).",
221
+ usage: "chainpatrol metrics organization [--org <slug>] [--from ISO --to ISO]",
222
+ options: [
223
+ "--org <slug> Organization slug (omit when using an API key)",
224
+ "--brand-slug <slug> Filter by brand slug (requires brands-metrics flag)",
225
+ "--from <iso> Start date (ISO 8601, e.g. 2026-01-01)",
226
+ "--to <iso> End date (ISO 8601)"
227
+ ],
228
+ examples: [
229
+ "chainpatrol metrics organization --org acme",
230
+ "chainpatrol metrics organization --org acme --from 2026-01-01 --to 2026-02-01",
231
+ "CHAINPATROL_API_KEY=... chainpatrol metrics organization --json"
210
232
  ]
211
233
  },
212
234
  "metrics summary": {
@@ -289,6 +311,38 @@ var HELP = {
289
311
  "chainpatrol queues snapshot --all"
290
312
  ]
291
313
  },
314
+ takedowns: {
315
+ description: "List individual takedown records for an organization.",
316
+ usage: "chainpatrol takedowns list [--org <slug>] [filters]",
317
+ examples: [
318
+ "chainpatrol takedowns list --org acme",
319
+ "chainpatrol takedowns list --org acme --takedown-status TODO,IN_PROGRESS",
320
+ "chainpatrol takedowns list --org acme --from 2026-01-01 --to 2026-02-01 --per-page 50"
321
+ ]
322
+ },
323
+ "takedowns list": {
324
+ description: "List takedowns for an organization. Defaults to takedowns updated in the last 30 days. Works with both API key auth (org derived from key) and session auth (pass --org).",
325
+ usage: "chainpatrol takedowns list [--org <slug>] [filters]",
326
+ options: [
327
+ "--org <slug> Organization slug (omit when using an API key)",
328
+ "--query <text> Search asset content (substring match)",
329
+ "--from <iso> Filter by updatedAt >= ISO date",
330
+ "--to <iso> Filter by updatedAt <= ISO date",
331
+ "--asset-type <list> Comma list (URL,TWITTER,TELEGRAM,...)",
332
+ "--takedown-status <list> Comma list (TODO,IN_PROGRESS,COMPLETED,CANCELLED,PENDING_INPUT,...)",
333
+ "--liveness-status <list> Comma list (ALIVE,DEAD,UNKNOWN)",
334
+ "--sort-by <key> Sort key: updatedAt|createdAt|takedownStatus|takedownUpdatedAt",
335
+ "--sort-direction <dir> asc|desc (default desc)",
336
+ "--per-page <n> Page size 1-100 (default 10; --limit also accepted)",
337
+ "--next-page <cursor> Cursor returned from a previous response"
338
+ ],
339
+ examples: [
340
+ "chainpatrol takedowns list --org acme --takedown-status TODO,IN_PROGRESS",
341
+ "chainpatrol takedowns list --org acme --asset-type URL --liveness-status ALIVE",
342
+ "chainpatrol takedowns list --org acme --per-page 100 --output csv",
343
+ "CHAINPATROL_API_KEY=... chainpatrol takedowns list --json"
344
+ ]
345
+ },
292
346
  "queues snapshot": {
293
347
  description: "Snapshot pending review proposals and open takedowns.",
294
348
  usage: "chainpatrol queues snapshot [--org <slug>|--all] [--window-hours <n>]",
@@ -415,6 +469,7 @@ function getTopLevelHelp() {
415
469
  " metrics Query organization metrics and breakdowns",
416
470
  " reports Create and list reports from terminal",
417
471
  " queues Snapshot operations review/takedown queues",
472
+ " takedowns List individual takedown records",
418
473
  " orgs List organizations and filter by status/services",
419
474
  " presets Run saved workflows for common jobs",
420
475
  " setup Install Claude Code skill and shell completions",
@@ -586,6 +641,7 @@ var COMMANDS = [
586
641
  "metrics",
587
642
  "reports",
588
643
  "queues",
644
+ "takedowns",
589
645
  "orgs",
590
646
  "presets",
591
647
  "setup",
@@ -669,6 +725,14 @@ ${getTopLevelHelp()}
669
725
  serviceAutomated: { type: "string" },
670
726
  serviceManual: { type: "string" },
671
727
  query: { type: "string" },
728
+ assetType: { type: "string" },
729
+ takedownStatus: { type: "string" },
730
+ livenessStatus: { type: "string" },
731
+ nextPage: { type: "string" },
732
+ sortBy: { type: "string" },
733
+ sortDirection: { type: "string" },
734
+ perPage: { type: "number" },
735
+ brandSlug: { type: "string" },
672
736
  help: { type: "boolean", shortFlag: "h" },
673
737
  version: { type: "boolean", shortFlag: "V" },
674
738
  quiet: { type: "boolean", default: false, shortFlag: "q" },
@@ -767,18 +831,23 @@ function parseBrandIds() {
767
831
  function parseAssetInputs() {
768
832
  return getRepeatedFlag("asset");
769
833
  }
834
+ function parseCsvList(value) {
835
+ if (!value) return void 0;
836
+ const items = value.split(",").map((item) => item.trim()).filter(Boolean);
837
+ return items.length > 0 ? items : void 0;
838
+ }
770
839
  function parseAttachmentUrls() {
771
840
  const values = getRepeatedFlag("attachment-url").filter(Boolean);
772
841
  return values.length > 0 ? values : void 0;
773
842
  }
774
843
  async function handleConfigsList(org) {
775
844
  if (jsonMode) {
776
- const { listConfigsJson } = await import("./list-json-CEPGVUGF.js");
845
+ const { listConfigsJson } = await import("./list-json-R2MIXADX.js");
777
846
  await listConfigsJson({ org });
778
847
  return;
779
848
  }
780
849
  const { render } = await import("ink");
781
- const { default: ConfigsList } = await import("./list-IA4CSOIY.js");
850
+ const { default: ConfigsList } = await import("./list-5DN6X3DP.js");
782
851
  const { default: React } = await import("react");
783
852
  render(React.createElement(ConfigsList, { org }));
784
853
  }
@@ -875,11 +944,12 @@ async function main() {
875
944
  }
876
945
  case "asset": {
877
946
  if (subcommand === "check") {
878
- const positional = cli.input[2];
879
- const content = positional ?? cli.flags.asset;
880
- const { runAssetCheck } = await import("./check-YZRIAUOK.js");
947
+ const positionals = cli.input.slice(2);
948
+ const flagAssets = parseAssetInputs();
949
+ const contents = [...positionals, ...flagAssets];
950
+ const { runAssetCheck } = await import("./check-GDKUHVQI.js");
881
951
  await runAssetCheck({
882
- content,
952
+ contents,
883
953
  json: jsonMode,
884
954
  outputFormat: cliContext.outputFormat,
885
955
  explain: cliContext.explain
@@ -888,13 +958,13 @@ async function main() {
888
958
  }
889
959
  const hint = subcommand ? suggest(subcommand, ["check"]) : null;
890
960
  throw new Error(
891
- subcommand ? `Unknown subcommand: asset ${subcommand}${hint ? `. Did you mean "asset ${hint}"?` : ""}` : "Usage: chainpatrol asset check <content>"
961
+ subcommand ? `Unknown subcommand: asset ${subcommand}${hint ? `. Did you mean "asset ${hint}"?` : ""}` : "Usage: chainpatrol asset check <content> [<content> ...]"
892
962
  );
893
963
  }
894
964
  case "detections": {
895
965
  const org = await resolveOrg();
896
966
  if (subcommand === "healthcheck") {
897
- const { runDetectionsHealthcheck } = await import("./healthcheck-C3AIMUJT.js");
967
+ const { runDetectionsHealthcheck } = await import("./healthcheck-EVQVPGWW.js");
898
968
  await runDetectionsHealthcheck({
899
969
  org,
900
970
  source: cli.flags.source,
@@ -909,7 +979,7 @@ async function main() {
909
979
  break;
910
980
  }
911
981
  if (subcommand === "validate") {
912
- const { runDetectionsValidate } = await import("./validate-5DVPSXJP.js");
982
+ const { runDetectionsValidate } = await import("./validate-UOVKEAJM.js");
913
983
  await runDetectionsValidate({
914
984
  org,
915
985
  source: cli.flags.source,
@@ -924,7 +994,7 @@ async function main() {
924
994
  break;
925
995
  }
926
996
  if (subcommand === "drift") {
927
- const { runDetectionsDrift } = await import("./drift-Q3VG3XG3.js");
997
+ const { runDetectionsDrift } = await import("./drift-JKBHWWFU.js");
928
998
  await runDetectionsDrift({
929
999
  org,
930
1000
  source: cli.flags.source,
@@ -938,7 +1008,7 @@ async function main() {
938
1008
  break;
939
1009
  }
940
1010
  if (subcommand === "run") {
941
- const { runDetectionsRun } = await import("./run-YTWNQD5X.js");
1011
+ const { runDetectionsRun } = await import("./run-5E5EC3MP.js");
942
1012
  await runDetectionsRun({
943
1013
  org,
944
1014
  configId: cli.flags.configId,
@@ -957,7 +1027,7 @@ async function main() {
957
1027
  break;
958
1028
  }
959
1029
  if (action === "run") {
960
- const { runDetectionsRun } = await import("./run-YTWNQD5X.js");
1030
+ const { runDetectionsRun } = await import("./run-5E5EC3MP.js");
961
1031
  await runDetectionsRun({
962
1032
  org,
963
1033
  configId: cli.flags.configId,
@@ -975,7 +1045,7 @@ async function main() {
975
1045
  throw new Error("detections configs update requires --config-id");
976
1046
  }
977
1047
  const configPatch = getConfigPatchFromSetFlags();
978
- const { runDetectionsConfigsUpdate } = await import("./configs-update-2IOSKZH5.js");
1048
+ const { runDetectionsConfigsUpdate } = await import("./configs-update-7X7657PB.js");
979
1049
  await runDetectionsConfigsUpdate({
980
1050
  org,
981
1051
  configId: cli.flags.configId,
@@ -1000,9 +1070,22 @@ async function main() {
1000
1070
  );
1001
1071
  }
1002
1072
  case "metrics": {
1073
+ if (subcommand === "organization" || subcommand === "org") {
1074
+ const org2 = await tryResolveOrg();
1075
+ const { runMetricsOrganization } = await import("./organization-MJRKWC4Z.js");
1076
+ await runMetricsOrganization({
1077
+ org: org2,
1078
+ brandSlug: cli.flags.brandSlug,
1079
+ from: cli.flags.from,
1080
+ to: cli.flags.to,
1081
+ json: jsonMode,
1082
+ outputFormat: cliContext.outputFormat
1083
+ });
1084
+ break;
1085
+ }
1003
1086
  const org = await resolveOrg();
1004
1087
  if (subcommand === "summary") {
1005
- const { runMetricsSummary } = await import("./summary-NQDZQEOD.js");
1088
+ const { runMetricsSummary } = await import("./summary-RVYQUKWV.js");
1006
1089
  await runMetricsSummary({
1007
1090
  org,
1008
1091
  from: cli.flags.from,
@@ -1014,7 +1097,7 @@ async function main() {
1014
1097
  break;
1015
1098
  }
1016
1099
  if (subcommand === "found") {
1017
- const { runMetricsFound } = await import("./found-22B7RZT5.js");
1100
+ const { runMetricsFound } = await import("./found-3WI4XQG4.js");
1018
1101
  await runMetricsFound({
1019
1102
  org,
1020
1103
  from: cli.flags.from,
@@ -1031,7 +1114,7 @@ async function main() {
1031
1114
  if (!by || !["day", "type", "brand"].includes(by)) {
1032
1115
  throw new Error("metrics breakdown requires --by <day|type|brand>");
1033
1116
  }
1034
- const { runMetricsBreakdown } = await import("./breakdown-63FAOVL7.js");
1117
+ const { runMetricsBreakdown } = await import("./breakdown-MM5GSZKV.js");
1035
1118
  await runMetricsBreakdown({
1036
1119
  org,
1037
1120
  by,
@@ -1043,15 +1126,15 @@ async function main() {
1043
1126
  });
1044
1127
  break;
1045
1128
  }
1046
- const hint = subcommand ? suggest(subcommand, ["summary", "found", "breakdown"]) : null;
1129
+ const hint = subcommand ? suggest(subcommand, ["summary", "found", "breakdown", "organization"]) : null;
1047
1130
  throw new Error(
1048
- subcommand ? `Unknown subcommand: metrics ${subcommand}${hint ? `. Did you mean "metrics ${hint}"?` : ""}` : "Usage: chainpatrol metrics <summary|found|breakdown>"
1131
+ subcommand ? `Unknown subcommand: metrics ${subcommand}${hint ? `. Did you mean "metrics ${hint}"?` : ""}` : "Usage: chainpatrol metrics <summary|found|breakdown|organization>"
1049
1132
  );
1050
1133
  }
1051
1134
  case "reports": {
1052
1135
  if (subcommand === "list") {
1053
1136
  const org = await resolveOrg();
1054
- const { runReportsList } = await import("./list-AYHDFSQG.js");
1137
+ const { runReportsList } = await import("./list-E5XNR2YG.js");
1055
1138
  await runReportsList({
1056
1139
  org,
1057
1140
  limit: cli.flags.limit,
@@ -1067,7 +1150,7 @@ async function main() {
1067
1150
  }
1068
1151
  if (subcommand === "create") {
1069
1152
  const org = await tryResolveOrg();
1070
- const { runReportsCreate } = await import("./create-EWS3SFCH.js");
1153
+ const { runReportsCreate } = await import("./create-FL4QQTPN.js");
1071
1154
  await runReportsCreate({
1072
1155
  org,
1073
1156
  title: cli.flags.title,
@@ -1089,9 +1172,35 @@ async function main() {
1089
1172
  subcommand ? `Unknown subcommand: reports ${subcommand}${hint ? `. Did you mean "reports ${hint}"?` : ""}` : "Usage: chainpatrol reports <create|list>"
1090
1173
  );
1091
1174
  }
1175
+ case "takedowns": {
1176
+ if (subcommand === "list") {
1177
+ const org = await tryResolveOrg();
1178
+ const { runTakedownsList } = await import("./list-JPG2ZSR4.js");
1179
+ await runTakedownsList({
1180
+ org,
1181
+ query: cli.flags.query,
1182
+ from: cli.flags.from,
1183
+ to: cli.flags.to,
1184
+ assetType: parseCsvList(cli.flags.assetType),
1185
+ takedownStatus: parseCsvList(cli.flags.takedownStatus),
1186
+ livenessStatus: parseCsvList(cli.flags.livenessStatus),
1187
+ sortBy: cli.flags.sortBy,
1188
+ sortDirection: cli.flags.sortDirection,
1189
+ perPage: cli.flags.perPage ?? cli.flags.limit,
1190
+ nextPage: cli.flags.nextPage,
1191
+ json: jsonMode,
1192
+ outputFormat: cliContext.outputFormat
1193
+ });
1194
+ break;
1195
+ }
1196
+ const hint = subcommand ? suggest(subcommand, ["list"]) : null;
1197
+ throw new Error(
1198
+ subcommand ? `Unknown subcommand: takedowns ${subcommand}${hint ? `. Did you mean "takedowns ${hint}"?` : ""}` : "Usage: chainpatrol takedowns list [--org <slug>] [filters]"
1199
+ );
1200
+ }
1092
1201
  case "queues": {
1093
1202
  if (subcommand === "snapshot") {
1094
- const { runQueuesSnapshot } = await import("./snapshot-C5MZWJTW.js");
1203
+ const { runQueuesSnapshot } = await import("./snapshot-3FUJICJJ.js");
1095
1204
  await runQueuesSnapshot({
1096
1205
  org: cli.flags.org,
1097
1206
  all: cli.flags.all,
@@ -1109,7 +1218,7 @@ async function main() {
1109
1218
  }
1110
1219
  case "orgs": {
1111
1220
  if (subcommand === "list") {
1112
- const { runOrgsList } = await import("./list-SDBLGBVW.js");
1221
+ const { runOrgsList } = await import("./list-XDGU6SJQ.js");
1113
1222
  await runOrgsList({
1114
1223
  query: cli.flags.query,
1115
1224
  subscriptionStatus: cli.flags.subscriptionStatus,
@@ -1129,7 +1238,7 @@ async function main() {
1129
1238
  }
1130
1239
  case "healthchecks": {
1131
1240
  if (subcommand === "list") {
1132
- const { runHealthchecksList } = await import("./list-DNRWKM5O.js");
1241
+ const { runHealthchecksList } = await import("./list-BLNIE4GL.js");
1133
1242
  await runHealthchecksList({
1134
1243
  json: jsonMode,
1135
1244
  outputFormat: cliContext.outputFormat
@@ -1143,7 +1252,7 @@ async function main() {
1143
1252
  thresholds.minResults = cli.flags.minResults;
1144
1253
  if (cli.flags.lookbackHours !== void 0)
1145
1254
  thresholds.lookbackHours = cli.flags.lookbackHours;
1146
- const { runHealthchecksRun } = await import("./run-AQMJRFGL.js");
1255
+ const { runHealthchecksRun } = await import("./run-2YZZGZYN.js");
1147
1256
  await runHealthchecksRun({
1148
1257
  org,
1149
1258
  id: action,
@@ -1161,7 +1270,7 @@ async function main() {
1161
1270
  }
1162
1271
  case "presets": {
1163
1272
  if (subcommand === "list") {
1164
- const { runPresetsList } = await import("./list-HFWSMLGJ.js");
1273
+ const { runPresetsList } = await import("./list-ULHPOUJV.js");
1165
1274
  await runPresetsList({ outputFormat: cliContext.outputFormat });
1166
1275
  break;
1167
1276
  }
@@ -1172,7 +1281,7 @@ async function main() {
1172
1281
  );
1173
1282
  }
1174
1283
  const org = await resolveOrg();
1175
- const { runPresetsRun } = await import("./run-WJGHJPXN.js");
1284
+ const { runPresetsRun } = await import("./run-EUVRC72M.js");
1176
1285
  await runPresetsRun({
1177
1286
  presetId: action,
1178
1287
  org,
@@ -1189,17 +1298,17 @@ async function main() {
1189
1298
  case "setup":
1190
1299
  case "install":
1191
1300
  case "i": {
1192
- const { setupSkill } = await import("./setup-skill-DR4KGQMG.js");
1301
+ const { setupSkill } = await import("./setup-skill-HAENFIFQ.js");
1193
1302
  setupSkill({ json: jsonMode, cloud: cli.flags.cloud });
1194
1303
  break;
1195
1304
  }
1196
1305
  case "uninstall": {
1197
- const { uninstallSkill } = await import("./setup-skill-DR4KGQMG.js");
1306
+ const { uninstallSkill } = await import("./setup-skill-HAENFIFQ.js");
1198
1307
  uninstallSkill({ json: jsonMode });
1199
1308
  break;
1200
1309
  }
1201
1310
  case "completions": {
1202
- const { printCompletions } = await import("./completions-D6SOLU2D.js");
1311
+ const { printCompletions } = await import("./completions-62OW3B3Y.js");
1203
1312
  printCompletions(subcommand);
1204
1313
  break;
1205
1314
  }
@@ -3,7 +3,7 @@ import {
3
3
  installCompletions,
4
4
  printCompletions,
5
5
  uninstallCompletions
6
- } from "./chunk-Z76CUWSS.js";
6
+ } from "./chunk-YXRFUYA6.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-RIKR2WFT.js";
10
+ } from "./chunk-SX3L6NKR.js";
11
11
  import "./chunk-EGWK6SRQ.js";
12
12
  import "./chunk-TFCNKBRC.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-RIKR2WFT.js";
11
+ } from "./chunk-SX3L6NKR.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-RIKR2WFT.js";
11
+ } from "./chunk-SX3L6NKR.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-RIKR2WFT.js";
7
+ } from "./chunk-SX3L6NKR.js";
8
8
  import "./chunk-EGWK6SRQ.js";
9
9
  import {
10
10
  DateTime
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-RIKR2WFT.js";
11
+ } from "./chunk-SX3L6NKR.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-JCMWDZYY.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-RIKR2WFT.js";
7
+ } from "./chunk-SX3L6NKR.js";
8
8
  import {
9
9
  AuthCorruptedError,
10
10
  AuthExpiredError,
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-RIKR2WFT.js";
7
+ } from "./chunk-SX3L6NKR.js";
8
8
  import "./chunk-EGWK6SRQ.js";
9
9
  import "./chunk-TFCNKBRC.js";
10
10
  import "./chunk-U73SABXK.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-RIKR2WFT.js";
11
+ } from "./chunk-SX3L6NKR.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -0,0 +1,137 @@
1
+ import {
2
+ CliExitError,
3
+ ExitCode
4
+ } from "./chunk-E2LAMILJ.js";
5
+ import {
6
+ printOutput,
7
+ toCsvRows
8
+ } from "./chunk-VFT3TD3E.js";
9
+ import {
10
+ LIVENESS_STATUSES,
11
+ TAKEDOWN_SORT_KEYS,
12
+ TAKEDOWN_STATUSES,
13
+ createApiClient
14
+ } from "./chunk-SX3L6NKR.js";
15
+ import "./chunk-EGWK6SRQ.js";
16
+ import "./chunk-TFCNKBRC.js";
17
+ import "./chunk-U73SABXK.js";
18
+
19
+ // src/commands/takedowns/list.ts
20
+ var TAKEDOWN_STATUS_SET = new Set(TAKEDOWN_STATUSES);
21
+ var LIVENESS_STATUS_SET = new Set(LIVENESS_STATUSES);
22
+ var SORT_KEY_SET = new Set(TAKEDOWN_SORT_KEYS);
23
+ function toRow(takedown) {
24
+ return {
25
+ id: takedown.id,
26
+ status: takedown.status,
27
+ asset: takedown.asset.content,
28
+ assetType: takedown.asset.type,
29
+ livenessStatus: takedown.asset.livenessStatus ?? "",
30
+ brand: takedown.brand?.name ?? "",
31
+ assignee: takedown.assignee?.fullName ?? "",
32
+ createdAt: takedown.createdAt,
33
+ updatedAt: takedown.updatedAt
34
+ };
35
+ }
36
+ function validateEnumValues(values, validSet, flagName) {
37
+ if (!values || values.length === 0) return void 0;
38
+ const invalid = values.filter((value) => !validSet.has(value));
39
+ if (invalid.length > 0) {
40
+ throw new CliExitError(
41
+ `Invalid value(s) for --${flagName}: ${invalid.join(", ")}. Valid: ${Array.from(
42
+ validSet
43
+ ).join(", ")}`,
44
+ ExitCode.USAGE
45
+ );
46
+ }
47
+ return values;
48
+ }
49
+ async function runTakedownsList(options) {
50
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
51
+ const perPage = options.perPage ?? 10;
52
+ if (perPage < 1 || perPage > 100) {
53
+ throw new CliExitError(
54
+ "takedowns list requires --per-page between 1 and 100.",
55
+ ExitCode.USAGE
56
+ );
57
+ }
58
+ const sortDirection = options.sortDirection ?? "desc";
59
+ if (sortDirection !== "asc" && sortDirection !== "desc") {
60
+ throw new CliExitError(
61
+ `Invalid --sort-direction '${sortDirection}'. Use 'asc' or 'desc'.`,
62
+ ExitCode.USAGE
63
+ );
64
+ }
65
+ if (options.sortBy && !SORT_KEY_SET.has(options.sortBy)) {
66
+ throw new CliExitError(
67
+ `Invalid --sort-by '${options.sortBy}'. Valid: ${TAKEDOWN_SORT_KEYS.join(", ")}`,
68
+ ExitCode.USAGE
69
+ );
70
+ }
71
+ const assetType = options.assetType?.length ? options.assetType : void 0;
72
+ const takedownStatus = validateEnumValues(
73
+ options.takedownStatus,
74
+ TAKEDOWN_STATUS_SET,
75
+ "takedown-status"
76
+ );
77
+ const livenessStatus = validateEnumValues(
78
+ options.livenessStatus,
79
+ LIVENESS_STATUS_SET,
80
+ "liveness-status"
81
+ );
82
+ const client = options.apiClient ?? createApiClient();
83
+ const input = {
84
+ organizationSlug: options.org,
85
+ query: options.query,
86
+ startDate: options.from,
87
+ endDate: options.to,
88
+ assetType,
89
+ takedownStatus,
90
+ livenessStatus,
91
+ perPage,
92
+ nextPage: options.nextPage,
93
+ sorting: options.sortBy ? [
94
+ {
95
+ key: options.sortBy,
96
+ direction: sortDirection
97
+ }
98
+ ] : void 0
99
+ };
100
+ const result = await client.listTakedowns(input);
101
+ const rows = result.takedowns.map(toRow);
102
+ printOutput({
103
+ outputFormat,
104
+ json: result,
105
+ markdown: [
106
+ `# Takedowns${options.org ? ` (${options.org})` : ""}`,
107
+ "",
108
+ `- Returned: ${result.takedowns.length}`,
109
+ `- Next page cursor: ${result.next_page ?? "none"}`,
110
+ "",
111
+ ...rows.map(
112
+ (row) => `- #${row.id} [${row.status}] ${row.asset} (${row.assetType}) brand=${row.brand || "-"} updated=${row.updatedAt}`
113
+ )
114
+ ].join("\n"),
115
+ csv: toCsvRows(rows),
116
+ human: () => {
117
+ if (result.takedowns.length === 0) {
118
+ console.log("No takedowns found.");
119
+ return;
120
+ }
121
+ console.log(
122
+ `Takedowns${options.org ? ` for ${options.org}` : ""} (returned ${result.takedowns.length})`
123
+ );
124
+ for (const row of rows) {
125
+ console.log(
126
+ `#${row.id} [${row.status}] ${row.asset} (${row.assetType}) brand=${row.brand || "-"} assignee=${row.assignee || "-"} updated=${row.updatedAt}`
127
+ );
128
+ }
129
+ if (result.next_page) {
130
+ console.log(`Next page cursor: ${result.next_page}`);
131
+ }
132
+ }
133
+ });
134
+ }
135
+ export {
136
+ runTakedownsList
137
+ };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  PRESETS
3
- } from "./chunk-BJISZ3CY.js";
3
+ } from "./chunk-37KYJWB3.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-RIKR2WFT.js";
9
+ import "./chunk-SX3L6NKR.js";
10
10
  import "./chunk-EGWK6SRQ.js";
11
11
  import "./chunk-TFCNKBRC.js";
12
12
  import "./chunk-U73SABXK.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-RIKR2WFT.js";
11
+ } from "./chunk-SX3L6NKR.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApiClient
3
- } from "./chunk-RIKR2WFT.js";
3
+ } from "./chunk-SX3L6NKR.js";
4
4
  import "./chunk-EGWK6SRQ.js";
5
5
  import "./chunk-TFCNKBRC.js";
6
6
  import "./chunk-U73SABXK.js";