@chainpatrol/cli 0.10.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 (31) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +2 -0
  3. package/dist/{breakdown-63FAOVL7.js → breakdown-MM5GSZKV.js} +1 -1
  4. package/dist/{check-7QDINQPT.js → check-GDKUHVQI.js} +1 -1
  5. package/dist/{chunk-BJISZ3CY.js → chunk-37KYJWB3.js} +1 -1
  6. package/dist/{chunk-R2DZGMGT.js → chunk-EPKNZRX6.js} +1 -1
  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 +131 -29
  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-BLJLRCXL.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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @chainpatrol/cli
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 21e4455: Add `chainpatrol takedowns list` and `chainpatrol metrics organization`
8
+ commands so agents can pull per-takedown detail and org-scoped metrics
9
+ from the CLI instead of stopping at `queues snapshot`'s aggregate
10
+ counts.
11
+
12
+ `takedowns list` wraps `POST /takedowns/list` with filters for status,
13
+ asset type, liveness, date range, search, sort, and pagination, and
14
+ emits the standard human/json/markdown/csv shapes. `metrics
15
+ organization` wraps the documented `GET /organization/metrics`
16
+ endpoint, complementing the existing `metrics summary`/`found`/
17
+ `breakdown` subcommands.
18
+
19
+ Both endpoints now also accept a user-session bearer token (pass
20
+ `--org <slug>`) in addition to an API key, so customer-success operators
21
+ logged in via `chainpatrol login` can use them without provisioning a
22
+ key.
23
+
3
24
  ## 0.10.0
4
25
 
5
26
  ### Minor Changes
package/README.md CHANGED
@@ -22,7 +22,9 @@ chainpatrol metrics found --org my-org --this-week
22
22
  chainpatrol reports create --org my-org --title "Phishing report" --asset "https://phish.example:BLOCKED"
23
23
  chainpatrol reports list --org my-org --limit 10
24
24
  chainpatrol metrics breakdown --org my-org --by type --from 2026-01-01 --to 2026-01-08
25
+ chainpatrol metrics organization --org my-org --from 2026-01-01 --to 2026-02-01
25
26
  chainpatrol queues snapshot --all --output markdown
27
+ chainpatrol takedowns list --org my-org --takedown-status TODO,IN_PROGRESS --per-page 50
26
28
  chainpatrol presets run cs-weekly-health --org my-org --output json
27
29
  ```
28
30
 
@@ -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";
@@ -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 {
13
13
  DateTime
14
14
  } from "./chunk-TFCNKBRC.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  installCompletions,
3
3
  uninstallCompletions
4
- } from "./chunk-Z76CUWSS.js";
4
+ } from "./chunk-YXRFUYA6.js";
5
5
 
6
6
  // src/commands/setup-skill.ts
7
7
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, readFileSync as readFileSync3, rmSync } from "fs";
@@ -17,6 +17,26 @@ function parseIsoDate(value) {
17
17
  }
18
18
  return dt.toJSDate();
19
19
  }
20
+ function parseIsoDateString(value) {
21
+ return parseIsoDate(value)?.toISOString();
22
+ }
23
+ var TAKEDOWN_STATUSES = [
24
+ "TODO",
25
+ "IN_PROGRESS",
26
+ "COMPLETED",
27
+ "CANCELLED",
28
+ "PENDING_RETRACTION",
29
+ "RETRACTION_SENT",
30
+ "RETRACTED",
31
+ "PENDING_INPUT"
32
+ ];
33
+ var LIVENESS_STATUSES = ["UNKNOWN", "ALIVE", "DEAD"];
34
+ var TAKEDOWN_SORT_KEYS = [
35
+ "updatedAt",
36
+ "createdAt",
37
+ "takedownStatus",
38
+ "takedownUpdatedAt"
39
+ ];
20
40
  var REQUEST_TIMEOUT_MS = 3e4;
21
41
  function defaultGetCredential() {
22
42
  const envKey = process.env.CHAINPATROL_API_KEY;
@@ -29,16 +49,49 @@ function createApiClient(options) {
29
49
  const config = getConfig();
30
50
  const apiUrl = options?.apiUrl ?? config.apiUrl;
31
51
  const getCredential = options?.getCredential ?? (options?.getToken ? () => ({ kind: "bearer", value: options.getToken() }) : defaultGetCredential);
32
- async function request(path, body) {
52
+ function buildAuthHeaders() {
33
53
  const credential = getCredential();
34
- const headers = {
35
- "Content-Type": "application/json"
36
- };
54
+ const headers = {};
37
55
  if (credential.kind === "api-key") {
38
56
  headers["x-api-key"] = credential.value;
39
57
  } else {
40
58
  headers["Authorization"] = `Bearer ${credential.value}`;
41
59
  }
60
+ return headers;
61
+ }
62
+ async function requestGet(path, query) {
63
+ const headers = buildAuthHeaders();
64
+ const search = new URLSearchParams();
65
+ for (const [key, value] of Object.entries(query)) {
66
+ if (value !== void 0 && value !== "") {
67
+ search.set(key, value);
68
+ }
69
+ }
70
+ const queryString = search.toString();
71
+ const url = `${apiUrl}/api/v2${path}${queryString ? `?${queryString}` : ""}`;
72
+ let res;
73
+ try {
74
+ res = await fetch(url, {
75
+ method: "GET",
76
+ headers,
77
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
78
+ });
79
+ } catch (err) {
80
+ if (err instanceof DOMException && err.name === "TimeoutError") {
81
+ throw new Error(
82
+ "Request timed out. Check your network connection and try again."
83
+ );
84
+ }
85
+ if (err instanceof TypeError && err.code === "ECONNREFUSED") {
86
+ throw new Error(`Cannot connect to ${apiUrl}. Is the server running?`);
87
+ }
88
+ throw new Error("Network error. Check your internet connection and try again.");
89
+ }
90
+ return handleResponse(res);
91
+ }
92
+ async function request(path, body) {
93
+ const headers = buildAuthHeaders();
94
+ headers["Content-Type"] = "application/json";
42
95
  let res;
43
96
  try {
44
97
  res = await fetch(`${apiUrl}/api/v2${path}`, {
@@ -58,6 +111,9 @@ function createApiClient(options) {
58
111
  }
59
112
  throw new Error("Network error. Check your internet connection and try again.");
60
113
  }
114
+ return handleResponse(res);
115
+ }
116
+ async function handleResponse(res) {
61
117
  if (!res.ok) {
62
118
  let errorMessageFromResponse = null;
63
119
  try {
@@ -157,6 +213,28 @@ function createApiClient(options) {
157
213
  reportedByCustomer: input.reportedByCustomer
158
214
  });
159
215
  },
216
+ listTakedowns(input) {
217
+ return request("/takedowns/list", {
218
+ organizationSlug: input.organizationSlug,
219
+ query: input.query,
220
+ startDate: parseIsoDateString(input.startDate),
221
+ endDate: parseIsoDateString(input.endDate),
222
+ assetType: input.assetType,
223
+ takedownStatus: input.takedownStatus,
224
+ livenessStatus: input.livenessStatus,
225
+ sorting: input.sorting,
226
+ per_page: input.perPage,
227
+ next_page: input.nextPage
228
+ });
229
+ },
230
+ getOrganizationMetrics(input) {
231
+ return requestGet("/organization/metrics", {
232
+ organizationSlug: input.organizationSlug,
233
+ brandSlug: input.brandSlug,
234
+ startDate: parseIsoDateString(input.startDate),
235
+ endDate: parseIsoDateString(input.endDate)
236
+ });
237
+ },
160
238
  listHealthchecks() {
161
239
  return request("/healthchecks/list", {});
162
240
  },
@@ -170,5 +248,8 @@ function createApiClient(options) {
170
248
  }
171
249
 
172
250
  export {
251
+ TAKEDOWN_STATUSES,
252
+ LIVENESS_STATUSES,
253
+ TAKEDOWN_SORT_KEYS,
173
254
  createApiClient
174
255
  };
@@ -22,6 +22,7 @@ _chainpatrol() {
22
22
  'metrics:Query organization metrics'
23
23
  'reports:Create and list reports from terminal'
24
24
  'queues:Snapshot operations queues'
25
+ 'takedowns:List individual takedown records'
25
26
  'presets:Run saved workflows'
26
27
  'setup:Install Claude Code skill and shell completions'
27
28
  'uninstall:Remove Claude Code skill and shell completions'
@@ -84,6 +85,7 @@ _chainpatrol() {
84
85
  'summary:Show metrics summary'
85
86
  'found:Show found threats count'
86
87
  'breakdown:Show metrics breakdown'
88
+ 'organization:Get organization metrics (official endpoint)'
87
89
  )
88
90
  _describe 'subcommand' metrics_subcommands
89
91
  ;;
@@ -100,6 +102,11 @@ _chainpatrol() {
100
102
  queues_subcommands=('snapshot:Show queue snapshot')
101
103
  _describe 'subcommand' queues_subcommands
102
104
  ;;
105
+ takedowns)
106
+ local -a takedowns_subcommands
107
+ takedowns_subcommands=('list:List individual takedown records')
108
+ _describe 'subcommand' takedowns_subcommands
109
+ ;;
103
110
  presets)
104
111
  local -a presets_subcommands
105
112
  presets_subcommands=(
@@ -124,7 +131,7 @@ var BASH_COMPLETION = `_chainpatrol() {
124
131
  COMPREPLY=()
125
132
  cur="\${COMP_WORDS[COMP_CWORD]}"
126
133
  prev="\${COMP_WORDS[COMP_CWORD-1]}"
127
- commands="login logout asset configs detections metrics reports queues presets setup uninstall completions help"
134
+ commands="login logout asset configs detections metrics reports queues takedowns presets setup uninstall completions help"
128
135
 
129
136
  case "\${prev}" in
130
137
  chainpatrol)
@@ -144,7 +151,7 @@ var BASH_COMPLETION = `_chainpatrol() {
144
151
  return 0
145
152
  ;;
146
153
  metrics)
147
- COMPREPLY=( $(compgen -W "summary found breakdown" -- "\${cur}") )
154
+ COMPREPLY=( $(compgen -W "summary found breakdown organization" -- "\${cur}") )
148
155
  return 0
149
156
  ;;
150
157
  reports)
@@ -155,6 +162,10 @@ var BASH_COMPLETION = `_chainpatrol() {
155
162
  COMPREPLY=( $(compgen -W "snapshot" -- "\${cur}") )
156
163
  return 0
157
164
  ;;
165
+ takedowns)
166
+ COMPREPLY=( $(compgen -W "list" -- "\${cur}") )
167
+ return 0
168
+ ;;
158
169
  presets)
159
170
  COMPREPLY=( $(compgen -W "list run" -- "\${cur}") )
160
171
  return 0
package/dist/cli.js CHANGED
@@ -13,8 +13,8 @@ import {
13
13
  getCliVersion,
14
14
  isSkillInstalled,
15
15
  readInstalledSkillVersion
16
- } from "./chunk-R2DZGMGT.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";
@@ -207,12 +207,28 @@ var HELP = {
207
207
  },
208
208
  metrics: {
209
209
  description: "Query organization metrics and breakdowns.",
210
- usage: "chainpatrol metrics <summary|found|breakdown>",
210
+ usage: "chainpatrol metrics <summary|found|breakdown|organization>",
211
211
  options: ["--org <slug> Organization slug"],
212
212
  examples: [
213
213
  "chainpatrol metrics summary --org acme --this-week",
214
214
  "chainpatrol metrics found --org acme --from 2025-01-01 --to 2025-02-01",
215
- "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"
216
232
  ]
217
233
  },
218
234
  "metrics summary": {
@@ -295,6 +311,38 @@ var HELP = {
295
311
  "chainpatrol queues snapshot --all"
296
312
  ]
297
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
+ },
298
346
  "queues snapshot": {
299
347
  description: "Snapshot pending review proposals and open takedowns.",
300
348
  usage: "chainpatrol queues snapshot [--org <slug>|--all] [--window-hours <n>]",
@@ -421,6 +469,7 @@ function getTopLevelHelp() {
421
469
  " metrics Query organization metrics and breakdowns",
422
470
  " reports Create and list reports from terminal",
423
471
  " queues Snapshot operations review/takedown queues",
472
+ " takedowns List individual takedown records",
424
473
  " orgs List organizations and filter by status/services",
425
474
  " presets Run saved workflows for common jobs",
426
475
  " setup Install Claude Code skill and shell completions",
@@ -592,6 +641,7 @@ var COMMANDS = [
592
641
  "metrics",
593
642
  "reports",
594
643
  "queues",
644
+ "takedowns",
595
645
  "orgs",
596
646
  "presets",
597
647
  "setup",
@@ -675,6 +725,14 @@ ${getTopLevelHelp()}
675
725
  serviceAutomated: { type: "string" },
676
726
  serviceManual: { type: "string" },
677
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" },
678
736
  help: { type: "boolean", shortFlag: "h" },
679
737
  version: { type: "boolean", shortFlag: "V" },
680
738
  quiet: { type: "boolean", default: false, shortFlag: "q" },
@@ -773,18 +831,23 @@ function parseBrandIds() {
773
831
  function parseAssetInputs() {
774
832
  return getRepeatedFlag("asset");
775
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
+ }
776
839
  function parseAttachmentUrls() {
777
840
  const values = getRepeatedFlag("attachment-url").filter(Boolean);
778
841
  return values.length > 0 ? values : void 0;
779
842
  }
780
843
  async function handleConfigsList(org) {
781
844
  if (jsonMode) {
782
- const { listConfigsJson } = await import("./list-json-CEPGVUGF.js");
845
+ const { listConfigsJson } = await import("./list-json-R2MIXADX.js");
783
846
  await listConfigsJson({ org });
784
847
  return;
785
848
  }
786
849
  const { render } = await import("ink");
787
- const { default: ConfigsList } = await import("./list-IA4CSOIY.js");
850
+ const { default: ConfigsList } = await import("./list-5DN6X3DP.js");
788
851
  const { default: React } = await import("react");
789
852
  render(React.createElement(ConfigsList, { org }));
790
853
  }
@@ -884,7 +947,7 @@ async function main() {
884
947
  const positionals = cli.input.slice(2);
885
948
  const flagAssets = parseAssetInputs();
886
949
  const contents = [...positionals, ...flagAssets];
887
- const { runAssetCheck } = await import("./check-7QDINQPT.js");
950
+ const { runAssetCheck } = await import("./check-GDKUHVQI.js");
888
951
  await runAssetCheck({
889
952
  contents,
890
953
  json: jsonMode,
@@ -901,7 +964,7 @@ async function main() {
901
964
  case "detections": {
902
965
  const org = await resolveOrg();
903
966
  if (subcommand === "healthcheck") {
904
- const { runDetectionsHealthcheck } = await import("./healthcheck-C3AIMUJT.js");
967
+ const { runDetectionsHealthcheck } = await import("./healthcheck-EVQVPGWW.js");
905
968
  await runDetectionsHealthcheck({
906
969
  org,
907
970
  source: cli.flags.source,
@@ -916,7 +979,7 @@ async function main() {
916
979
  break;
917
980
  }
918
981
  if (subcommand === "validate") {
919
- const { runDetectionsValidate } = await import("./validate-5DVPSXJP.js");
982
+ const { runDetectionsValidate } = await import("./validate-UOVKEAJM.js");
920
983
  await runDetectionsValidate({
921
984
  org,
922
985
  source: cli.flags.source,
@@ -931,7 +994,7 @@ async function main() {
931
994
  break;
932
995
  }
933
996
  if (subcommand === "drift") {
934
- const { runDetectionsDrift } = await import("./drift-Q3VG3XG3.js");
997
+ const { runDetectionsDrift } = await import("./drift-JKBHWWFU.js");
935
998
  await runDetectionsDrift({
936
999
  org,
937
1000
  source: cli.flags.source,
@@ -945,7 +1008,7 @@ async function main() {
945
1008
  break;
946
1009
  }
947
1010
  if (subcommand === "run") {
948
- const { runDetectionsRun } = await import("./run-YTWNQD5X.js");
1011
+ const { runDetectionsRun } = await import("./run-5E5EC3MP.js");
949
1012
  await runDetectionsRun({
950
1013
  org,
951
1014
  configId: cli.flags.configId,
@@ -964,7 +1027,7 @@ async function main() {
964
1027
  break;
965
1028
  }
966
1029
  if (action === "run") {
967
- const { runDetectionsRun } = await import("./run-YTWNQD5X.js");
1030
+ const { runDetectionsRun } = await import("./run-5E5EC3MP.js");
968
1031
  await runDetectionsRun({
969
1032
  org,
970
1033
  configId: cli.flags.configId,
@@ -982,7 +1045,7 @@ async function main() {
982
1045
  throw new Error("detections configs update requires --config-id");
983
1046
  }
984
1047
  const configPatch = getConfigPatchFromSetFlags();
985
- const { runDetectionsConfigsUpdate } = await import("./configs-update-2IOSKZH5.js");
1048
+ const { runDetectionsConfigsUpdate } = await import("./configs-update-7X7657PB.js");
986
1049
  await runDetectionsConfigsUpdate({
987
1050
  org,
988
1051
  configId: cli.flags.configId,
@@ -1007,9 +1070,22 @@ async function main() {
1007
1070
  );
1008
1071
  }
1009
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
+ }
1010
1086
  const org = await resolveOrg();
1011
1087
  if (subcommand === "summary") {
1012
- const { runMetricsSummary } = await import("./summary-NQDZQEOD.js");
1088
+ const { runMetricsSummary } = await import("./summary-RVYQUKWV.js");
1013
1089
  await runMetricsSummary({
1014
1090
  org,
1015
1091
  from: cli.flags.from,
@@ -1021,7 +1097,7 @@ async function main() {
1021
1097
  break;
1022
1098
  }
1023
1099
  if (subcommand === "found") {
1024
- const { runMetricsFound } = await import("./found-22B7RZT5.js");
1100
+ const { runMetricsFound } = await import("./found-3WI4XQG4.js");
1025
1101
  await runMetricsFound({
1026
1102
  org,
1027
1103
  from: cli.flags.from,
@@ -1038,7 +1114,7 @@ async function main() {
1038
1114
  if (!by || !["day", "type", "brand"].includes(by)) {
1039
1115
  throw new Error("metrics breakdown requires --by <day|type|brand>");
1040
1116
  }
1041
- const { runMetricsBreakdown } = await import("./breakdown-63FAOVL7.js");
1117
+ const { runMetricsBreakdown } = await import("./breakdown-MM5GSZKV.js");
1042
1118
  await runMetricsBreakdown({
1043
1119
  org,
1044
1120
  by,
@@ -1050,15 +1126,15 @@ async function main() {
1050
1126
  });
1051
1127
  break;
1052
1128
  }
1053
- const hint = subcommand ? suggest(subcommand, ["summary", "found", "breakdown"]) : null;
1129
+ const hint = subcommand ? suggest(subcommand, ["summary", "found", "breakdown", "organization"]) : null;
1054
1130
  throw new Error(
1055
- 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>"
1056
1132
  );
1057
1133
  }
1058
1134
  case "reports": {
1059
1135
  if (subcommand === "list") {
1060
1136
  const org = await resolveOrg();
1061
- const { runReportsList } = await import("./list-AYHDFSQG.js");
1137
+ const { runReportsList } = await import("./list-E5XNR2YG.js");
1062
1138
  await runReportsList({
1063
1139
  org,
1064
1140
  limit: cli.flags.limit,
@@ -1074,7 +1150,7 @@ async function main() {
1074
1150
  }
1075
1151
  if (subcommand === "create") {
1076
1152
  const org = await tryResolveOrg();
1077
- const { runReportsCreate } = await import("./create-EWS3SFCH.js");
1153
+ const { runReportsCreate } = await import("./create-FL4QQTPN.js");
1078
1154
  await runReportsCreate({
1079
1155
  org,
1080
1156
  title: cli.flags.title,
@@ -1096,9 +1172,35 @@ async function main() {
1096
1172
  subcommand ? `Unknown subcommand: reports ${subcommand}${hint ? `. Did you mean "reports ${hint}"?` : ""}` : "Usage: chainpatrol reports <create|list>"
1097
1173
  );
1098
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
+ }
1099
1201
  case "queues": {
1100
1202
  if (subcommand === "snapshot") {
1101
- const { runQueuesSnapshot } = await import("./snapshot-C5MZWJTW.js");
1203
+ const { runQueuesSnapshot } = await import("./snapshot-3FUJICJJ.js");
1102
1204
  await runQueuesSnapshot({
1103
1205
  org: cli.flags.org,
1104
1206
  all: cli.flags.all,
@@ -1116,7 +1218,7 @@ async function main() {
1116
1218
  }
1117
1219
  case "orgs": {
1118
1220
  if (subcommand === "list") {
1119
- const { runOrgsList } = await import("./list-SDBLGBVW.js");
1221
+ const { runOrgsList } = await import("./list-XDGU6SJQ.js");
1120
1222
  await runOrgsList({
1121
1223
  query: cli.flags.query,
1122
1224
  subscriptionStatus: cli.flags.subscriptionStatus,
@@ -1136,7 +1238,7 @@ async function main() {
1136
1238
  }
1137
1239
  case "healthchecks": {
1138
1240
  if (subcommand === "list") {
1139
- const { runHealthchecksList } = await import("./list-DNRWKM5O.js");
1241
+ const { runHealthchecksList } = await import("./list-BLNIE4GL.js");
1140
1242
  await runHealthchecksList({
1141
1243
  json: jsonMode,
1142
1244
  outputFormat: cliContext.outputFormat
@@ -1150,7 +1252,7 @@ async function main() {
1150
1252
  thresholds.minResults = cli.flags.minResults;
1151
1253
  if (cli.flags.lookbackHours !== void 0)
1152
1254
  thresholds.lookbackHours = cli.flags.lookbackHours;
1153
- const { runHealthchecksRun } = await import("./run-AQMJRFGL.js");
1255
+ const { runHealthchecksRun } = await import("./run-2YZZGZYN.js");
1154
1256
  await runHealthchecksRun({
1155
1257
  org,
1156
1258
  id: action,
@@ -1168,7 +1270,7 @@ async function main() {
1168
1270
  }
1169
1271
  case "presets": {
1170
1272
  if (subcommand === "list") {
1171
- const { runPresetsList } = await import("./list-HFWSMLGJ.js");
1273
+ const { runPresetsList } = await import("./list-ULHPOUJV.js");
1172
1274
  await runPresetsList({ outputFormat: cliContext.outputFormat });
1173
1275
  break;
1174
1276
  }
@@ -1179,7 +1281,7 @@ async function main() {
1179
1281
  );
1180
1282
  }
1181
1283
  const org = await resolveOrg();
1182
- const { runPresetsRun } = await import("./run-WJGHJPXN.js");
1284
+ const { runPresetsRun } = await import("./run-EUVRC72M.js");
1183
1285
  await runPresetsRun({
1184
1286
  presetId: action,
1185
1287
  org,
@@ -1196,17 +1298,17 @@ async function main() {
1196
1298
  case "setup":
1197
1299
  case "install":
1198
1300
  case "i": {
1199
- const { setupSkill } = await import("./setup-skill-BLJLRCXL.js");
1301
+ const { setupSkill } = await import("./setup-skill-HAENFIFQ.js");
1200
1302
  setupSkill({ json: jsonMode, cloud: cli.flags.cloud });
1201
1303
  break;
1202
1304
  }
1203
1305
  case "uninstall": {
1204
- const { uninstallSkill } = await import("./setup-skill-BLJLRCXL.js");
1306
+ const { uninstallSkill } = await import("./setup-skill-HAENFIFQ.js");
1205
1307
  uninstallSkill({ json: jsonMode });
1206
1308
  break;
1207
1309
  }
1208
1310
  case "completions": {
1209
- const { printCompletions } = await import("./completions-D6SOLU2D.js");
1311
+ const { printCompletions } = await import("./completions-62OW3B3Y.js");
1210
1312
  printCompletions(subcommand);
1211
1313
  break;
1212
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";
@@ -0,0 +1,75 @@
1
+ import {
2
+ printOutput,
3
+ toCsvRows
4
+ } from "./chunk-VFT3TD3E.js";
5
+ import {
6
+ createApiClient
7
+ } from "./chunk-SX3L6NKR.js";
8
+ import "./chunk-EGWK6SRQ.js";
9
+ import "./chunk-TFCNKBRC.js";
10
+ import "./chunk-U73SABXK.js";
11
+
12
+ // src/commands/metrics/organization.ts
13
+ async function runMetricsOrganization(options) {
14
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
15
+ const client = options.apiClient ?? createApiClient();
16
+ const input = {
17
+ organizationSlug: options.org,
18
+ brandSlug: options.brandSlug,
19
+ startDate: options.from,
20
+ endDate: options.to
21
+ };
22
+ const result = await client.getOrganizationMetrics(input);
23
+ const label = options.org ?? "your organization";
24
+ printOutput({
25
+ outputFormat,
26
+ json: result,
27
+ markdown: [
28
+ `# Organization Metrics (${label})`,
29
+ "",
30
+ `- Reports: ${result.metrics.reports}`,
31
+ `- New threats: ${result.metrics.newThreats}`,
32
+ `- Watchlisted threats: ${result.metrics.threatsWatchlisted}`,
33
+ `- Takedowns filed: ${result.metrics.takedownsFiled}`,
34
+ `- Takedowns completed: ${result.metrics.takedownsCompleted}`,
35
+ `- Domain threats: ${result.metrics.domainThreats}`,
36
+ `- Twitter threats: ${result.metrics.twitterThreats}`,
37
+ `- Telegram threats: ${result.metrics.telegramThreats}`,
38
+ `- Other threats: ${result.metrics.otherThreats}`
39
+ ].join("\n"),
40
+ csv: toCsvRows([
41
+ {
42
+ reports: result.metrics.reports,
43
+ newThreats: result.metrics.newThreats,
44
+ threatsWatchlisted: result.metrics.threatsWatchlisted,
45
+ takedownsFiled: result.metrics.takedownsFiled,
46
+ takedownsCompleted: result.metrics.takedownsCompleted,
47
+ domainThreats: result.metrics.domainThreats,
48
+ twitterThreats: result.metrics.twitterThreats,
49
+ telegramThreats: result.metrics.telegramThreats,
50
+ otherThreats: result.metrics.otherThreats
51
+ }
52
+ ]),
53
+ human: () => {
54
+ console.log(`Organization metrics for ${label}`);
55
+ console.log(`Reports: ${result.metrics.reports}`);
56
+ console.log(`New threats: ${result.metrics.newThreats}`);
57
+ console.log(`Watchlisted threats: ${result.metrics.threatsWatchlisted}`);
58
+ console.log(`Takedowns filed: ${result.metrics.takedownsFiled}`);
59
+ console.log(`Takedowns completed: ${result.metrics.takedownsCompleted}`);
60
+ console.log(
61
+ `Threat breakdown: domains=${result.metrics.domainThreats}, twitter=${result.metrics.twitterThreats}, telegram=${result.metrics.telegramThreats}, other=${result.metrics.otherThreats}`
62
+ );
63
+ if (result.blockedByDay.length > 0) {
64
+ console.log("");
65
+ console.log(`Blocked by day (${result.blockedByDay.length} entries):`);
66
+ for (const entry of result.blockedByDay) {
67
+ console.log(` ${entry.date}: ${entry.count}`);
68
+ }
69
+ }
70
+ }
71
+ });
72
+ }
73
+ export {
74
+ runMetricsOrganization
75
+ };
@@ -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";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  getPresetDefinition,
3
3
  runPreset
4
- } from "./chunk-BJISZ3CY.js";
4
+ } from "./chunk-37KYJWB3.js";
5
5
  import {
6
6
  CliExitError,
7
7
  ExitCode
8
8
  } from "./chunk-E2LAMILJ.js";
9
9
  import "./chunk-VFT3TD3E.js";
10
- import "./chunk-RIKR2WFT.js";
10
+ import "./chunk-SX3L6NKR.js";
11
11
  import "./chunk-EGWK6SRQ.js";
12
12
  import "./chunk-TFCNKBRC.js";
13
13
  import "./chunk-U73SABXK.js";
@@ -6,8 +6,8 @@ import {
6
6
  readInstalledSkillVersion,
7
7
  setupSkill,
8
8
  uninstallSkill
9
- } from "./chunk-R2DZGMGT.js";
10
- import "./chunk-Z76CUWSS.js";
9
+ } from "./chunk-EPKNZRX6.js";
10
+ import "./chunk-YXRFUYA6.js";
11
11
  export {
12
12
  getBundledSkillContent,
13
13
  getBundledSkillVersion,
@@ -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 "./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";
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.10.0",
5
+ "version": "0.11.0",
6
6
  "license": "UNLICENSED",
7
7
  "homepage": "https://chainpatrol.com/docs/cli",
8
8
  "keywords": [