@chainpatrol/cli 0.18.0 → 0.19.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 (37) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/{breakdown-ETSF2BZ3.js → breakdown-3LJBT3JQ.js} +1 -1
  3. package/dist/{check-EMGFDXUO.js → check-G64UQCEL.js} +1 -1
  4. package/dist/{chunk-HGAQBGGL.js → chunk-2JZAPTY6.js} +1 -1
  5. package/dist/{chunk-DPLUSURP.js → chunk-O7TMOF4W.js} +3 -0
  6. package/dist/{chunk-MDDC4F6Q.js → chunk-UDGJEN4M.js} +223 -1
  7. package/dist/cli.js +55 -33
  8. package/dist/{configs-update-EKNLIRA6.js → configs-update-MVX7Q5NW.js} +1 -1
  9. package/dist/{create-M4PV5VVU.js → create-ANCO4FXB.js} +1 -1
  10. package/dist/{drift-RQKTGJWB.js → drift-SHPMEJDU.js} +1 -1
  11. package/dist/{found-LVYBEOS6.js → found-OPL4HWOW.js} +1 -1
  12. package/dist/{get-YFYSJFBC.js → get-K7VHV5X2.js} +1 -1
  13. package/dist/{healthcheck-J6BIZEG7.js → healthcheck-QNLFKAXM.js} +1 -1
  14. package/dist/list-4VKMEKZS.js +64 -0
  15. package/dist/{list-CNF2FGLN.js → list-AQ7E23T3.js} +1 -1
  16. package/dist/{list-JCJHIJM4.js → list-FJBWSGTD.js} +2 -2
  17. package/dist/{list-O36VWTWR.js → list-FVFF4VW3.js} +1 -1
  18. package/dist/{list-S5Y6GW43.js → list-FWXQUOCP.js} +1 -1
  19. package/dist/{list-E2JVJNHV.js → list-Q5PRMAN5.js} +1 -1
  20. package/dist/{list-O62BZKQ5.js → list-QHEFB4KE.js} +1 -1
  21. package/dist/{list-XUYCZG7S.js → list-QXA6GLCV.js} +1 -1
  22. package/dist/{list-LKNCICLT.js → list-SWHKM5R6.js} +1 -1
  23. package/dist/{list-44BQZHJD.js → list-WPPNX7G3.js} +1 -1
  24. package/dist/{list-AEM2KSO4.js → list-X4Z3CPO7.js} +1 -1
  25. package/dist/{list-2ENAEZVP.js → list-XSIXAHOG.js} +1 -1
  26. package/dist/{list-json-ZTS5GXNA.js → list-json-B5L5PXKH.js} +1 -1
  27. package/dist/{organization-PFPBZXJZ.js → organization-SOMHMGTM.js} +1 -1
  28. package/dist/{run-R3RR6XQF.js → run-J5TQ2YC2.js} +1 -1
  29. package/dist/{run-HS2EEOM6.js → run-RV6P2OCD.js} +1 -1
  30. package/dist/{run-LKPKTH3W.js → run-YAAMSWKK.js} +2 -2
  31. package/dist/{search-EBXEP7XC.js → search-FQUR75WR.js} +1 -1
  32. package/dist/{setup-skill-Z6SBI6GC.js → setup-skill-F7437RT3.js} +1 -1
  33. package/dist/{snapshot-GNZMYTXT.js → snapshot-2GDJMN3L.js} +1 -1
  34. package/dist/{summary-POVQC6B7.js → summary-LF53KXRR.js} +1 -1
  35. package/dist/{validate-QE2F4PYY.js → validate-UYKOMUEI.js} +1 -1
  36. package/dist/{whoami-24KUJUN4.js → whoami-OYOG63BX.js} +1 -1
  37. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,60 @@
1
1
  # @chainpatrol/cli
2
2
 
3
+ ## 0.19.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 477a431: Add proper brand support across metrics and listings so agents can run a
8
+ real "trend search" on an org.
9
+
10
+ ## New: list brands for an org
11
+
12
+ `GET /organization/brands` (CLI: `chainpatrol brands list`) returns every
13
+ brand belonging to the caller's org — both parent / product brands
14
+ (`type: ORGANIZATION`) and individual / employee brands (`type:
15
+ INDIVIDUAL`) — in one call. Soft-deleted brands are excluded. Use
16
+ `--type INDIVIDUAL` to filter to employee brands only. The endpoint is
17
+ org-scoped via auth, no extra args.
18
+
19
+ ## Fixed: brand filter actually applies on metrics
20
+
21
+ Two server-side bugs the trend-search docs ran into:
22
+
23
+ 1. `GET /organization/metrics` with `brandSlug` was filtering the scalar
24
+ metrics (`reports`, `newThreats`, `takedownsFiled`, ...) but **not**
25
+ `blockedByType` / `blockedByDay`, which silently returned org-wide
26
+ totals. A caller drilling into a single brand would see "this brand
27
+ is being attacked on YouTube" when YouTube was really just an
28
+ org-wide trend.
29
+ 2. `POST /metrics/breakdown` with `by: "brand"` was ignoring the
30
+ `brandIds` input filter — `getThreatsBlockedPerBrand()` always
31
+ returned every brand. The function now accepts `brandIds` and the
32
+ handler passes the input through.
33
+
34
+ Both are now wired through correctly. `metrics organization
35
+ --brand-slug <slug> --include blockedByType,blockedByDay` returns
36
+ real brand-scoped time series, and `metrics breakdown --by brand
37
+ --brand <id>` actually narrows to the requested brand(s).
38
+
39
+ ## Skill: full trend-search guide
40
+
41
+ Documents three trend signals the agent can answer from existing
42
+ commands, with concrete current-vs-baseline recipes:
43
+
44
+ 1. Spike in a specific asset type (`metrics breakdown --by type`).
45
+ 2. Spike in overall threat volume (`metrics breakdown --by day` +
46
+ `metrics organization`).
47
+ 3. Spike on a specific sub-brand (`brands list` → join → `metrics
48
+ breakdown --by brand` → `metrics organization --brand-slug`).
49
+ Employee vs. product distinction now comes straight from the brand
50
+ roster.
51
+
52
+ Server-side procedures + validation schemas live in the private
53
+ `@chainpatrol/external-trpc`, `@chainpatrol/validation`, and
54
+ `@chainpatrol/metrics` packages and ship together with this CLI
55
+ release, but are not listed in the frontmatter because they are
56
+ private.
57
+
3
58
  ## 0.18.0
4
59
 
5
60
  ### Minor Changes
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-DPLUSURP.js";
10
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.js";
12
12
  import {
13
13
  DateTime
14
14
  } from "./chunk-TFCNKBRC.js";
@@ -392,6 +392,9 @@ function createApiClient(options) {
392
392
  {}
393
393
  );
394
394
  },
395
+ listOrganizationBrands() {
396
+ return requestGet("/organization/brands", {});
397
+ },
395
398
  getCurrentUser() {
396
399
  return request("/user/me", {});
397
400
  },
@@ -206,7 +206,15 @@ description: |
206
206
  "across all brands", "company-wide", "total takedowns", "total threats",
207
207
  "total reports", "average takedowns", "average threats", "average per day",
208
208
  "average per customer", "average per org", "rollup across customers",
209
- "sum across orgs", "sum across customers".
209
+ "sum across orgs", "sum across customers",
210
+ "trends in org", "search for trends", "trend search", "look for trends",
211
+ "any trends", "trending threats", "spike in asset type",
212
+ "spike in threat volume", "coordinated attack", "spike check",
213
+ "anything unusual", "anything new for", "what's new for",
214
+ "employee being targeted", "spike on a sub-brand", "spike on a brand",
215
+ "sub-brand spike",
216
+ "list brands", "brands for org", "list sub-brands", "employee brands",
217
+ "individual brands", "brand list", "all brands in org".
210
218
  allowed-tools:
211
219
  - Bash
212
220
  - Read
@@ -732,6 +740,36 @@ takedowns?", reach for \`orgs list\` \u2014 it's the only command that exposes
732
740
  service flags across multiple orgs in one call. Run it in \`--json\` mode
733
741
  and summarize patterns by service or by subscription tier.
734
742
 
743
+ ### \`brands list\` \u2014 List the brands (sub-brands) belonging to an org
744
+
745
+ Returns every brand for the org the caller is authenticated as, both
746
+ parent / product brands (\`type: "ORGANIZATION"\`) and individual /
747
+ employee brands (\`type: "INDIVIDUAL"\`). Soft-deleted brands are excluded.
748
+ The endpoint is org-scoped and inferred from auth \u2014 there's no \`--org\`
749
+ flag \u2014 so org-scoped API keys, user API keys, and user sessions all work
750
+ without extra arguments.
751
+
752
+ \`\`\`bash
753
+ chainpatrol brands list # all brands
754
+ chainpatrol brands list --type INDIVIDUAL # employee / person brands only
755
+ chainpatrol brands list --type ORGANIZATION # product / parent brands only
756
+ chainpatrol --json brands list # machine-readable
757
+ \`\`\`
758
+
759
+ Each entry has \`{ id, slug, name, type, description, brandGroupId, createdAt }\`.
760
+ Use this when you need to:
761
+
762
+ - Distinguish employee vs. product brands ahead of time \u2014 e.g. while
763
+ running a trend search and you want to highlight which spiking
764
+ sub-brands are employees so the user gets a direct heads-up to the
765
+ person involved.
766
+ - Resolve a brand name the user mentions to its \`slug\` for use with
767
+ \`metrics organization --brand-slug <slug>\` or as a \`brandId\` for
768
+ \`takedowns list --brand <id>\`.
769
+ - Audit a customer's setup \u2014 "how many employee brands does this org
770
+ protect?" or "are there brands the org set up but never wired into a
771
+ detection config?"
772
+
735
773
  ### \`metrics summary | found | breakdown | organization\` \u2014 Org metrics for spike/drop analysis
736
774
 
737
775
  #### Decision rule \u2014 read this before picking a metrics subcommand
@@ -1416,6 +1454,190 @@ Until a dedicated probe command exists:
1416
1454
  In both cases, if liveness looks miscalibrated for a class of assets,
1417
1455
  notify ChainPatrol engineering \u2014 the checker likely needs a tuning pass for
1418
1456
  that platform.
1457
+
1458
+ ## Organization Trend Search Guide
1459
+
1460
+ Trend search asks "what's changed recently for this org?" \u2014 the answer can
1461
+ surface coordinated attacks, new attack channels, or campaigns targeting
1462
+ specific people, **before** they show up as a healthcheck failure. Unlike
1463
+ the HealthCheck Guide above (which grades single signals against
1464
+ thresholds), trend search compares a recent window to a baseline window
1465
+ and flags ratios, not absolute counts. A trend is interesting even when
1466
+ the pipeline is keeping up with it \u2014 the user usually wants to know.
1467
+
1468
+ When the user asks something like:
1469
+
1470
+ - "are there any trends in org X?"
1471
+ - "search for trends in <org>"
1472
+ - "anything unusual happening with <org> lately?"
1473
+ - "any spikes for <org>?"
1474
+ - "what's new for <org> this week?"
1475
+ - "is anyone targeting <org>'s employees more than usual?"
1476
+ - "are we seeing more YouTube/Telegram/etc. threats for <org>?"
1477
+
1478
+ \u2026run the three trend checks below in parallel (single message, multiple
1479
+ Bash calls) and surface anything where the current rate is \u2265 2\xD7 the
1480
+ baseline AND clears a small absolute floor.
1481
+
1482
+ ### How to compute "current vs. baseline" rates
1483
+
1484
+ Pick two non-overlapping windows: a **current** window the user cares about
1485
+ (default last 7 days) and a **baseline** window ending where the current
1486
+ one starts (default the prior ~90 days, i.e. \`current_start - 90d\` \u2192
1487
+ \`current_start - 1d\`). For any breakdown bucket, compute:
1488
+
1489
+ \`\`\`
1490
+ current_per_day = current_count / current_window_days
1491
+ baseline_per_day = baseline_count / baseline_window_days
1492
+ ratio = current_per_day / max(baseline_per_day, epsilon)
1493
+ \`\`\`
1494
+
1495
+ Flag a bucket if \`ratio >= 2\` AND \`current_count >= 5\`. The floor
1496
+ suppresses noise on orgs with near-zero baseline activity (a single new
1497
+ YouTube report jumping the rate from 0 to 1/day shouldn't trigger). If
1498
+ the user gives a different window ("last 3 days", "this month"), adjust
1499
+ both windows proportionally and keep the same ratio threshold.
1500
+
1501
+ ### Trend 1 \u2014 Spike in a specific asset type
1502
+
1503
+ A sudden jump in threats on a platform the org doesn't usually see
1504
+ traffic on ("normally you don't get targeted on YouTube much, but now
1505
+ there's a spike there") is worth flagging \u2014 it usually means an attacker
1506
+ has discovered a new channel that works for them. Even when the absolute
1507
+ number is small, the *ratio* against the org's normal mix is what
1508
+ matters.
1509
+
1510
+ Use \`metrics breakdown --by type\` over both windows:
1511
+
1512
+ \`\`\`bash
1513
+ # Current window \u2014 last 7 days, broken out by asset type
1514
+ chainpatrol --json metrics breakdown --org <slug> --by type \\
1515
+ --from <YYYY-MM-DD 7d ago> --to <YYYY-MM-DD today>
1516
+
1517
+ # Baseline window \u2014 prior ~90 days ending where the current window starts
1518
+ chainpatrol --json metrics breakdown --org <slug> --by type \\
1519
+ --from <YYYY-MM-DD 97d ago> --to <YYYY-MM-DD 8d ago>
1520
+ \`\`\`
1521
+
1522
+ Each entry in \`.points\` has \`{ type, count }\`. Join the two windows on
1523
+ \`type\`, apply the ratio rule above, and report each flagged type.
1524
+
1525
+ Cross-reference any flagged type with \`configs list --org <slug>\` \u2014 if
1526
+ the spike is on Twitter / X but \`twitter_post_search\` is disabled, the
1527
+ detection source for that channel isn't even running for this org and
1528
+ the spike is being caught by something else (likely customer reports);
1529
+ suggest turning it on.
1530
+
1531
+ ### Trend 2 \u2014 Spike in overall threat volume
1532
+
1533
+ A sharp rise in total threats across the org \u2014 regardless of type or
1534
+ brand \u2014 usually means a coordinated attack or campaign is underway. This
1535
+ isn't a healthcheck (reviewing and takedowns may be keeping up just
1536
+ fine), but the security team still wants to know so they can warn
1537
+ customers / employees / partners.
1538
+
1539
+ \`\`\`bash
1540
+ # Daily volume for the last ~6 weeks \u2014 enough to eyeball a baseline AND
1541
+ # see the spike on the right edge of the series.
1542
+ chainpatrol --json metrics breakdown --org <slug> --by day \\
1543
+ --from <YYYY-MM-DD 42d ago> --to <YYYY-MM-DD today>
1544
+ \`\`\`
1545
+
1546
+ Read \`.points\` (one entry per day). Take the trailing 7-day average and
1547
+ compare against the prior ~5 weeks (the same 2\xD7 / floor rule). For round
1548
+ totals to quote to the user, also pull:
1549
+
1550
+ \`\`\`bash
1551
+ # Two calls \u2014 current and baseline windows \u2014 using --include to skip
1552
+ # the per-type / per-day series and keep the call cheap.
1553
+ chainpatrol --json metrics organization --org <slug> \\
1554
+ --include reports,newThreats,threatsWatchlisted \\
1555
+ --from <current_from> --to <current_to>
1556
+
1557
+ chainpatrol --json metrics organization --org <slug> \\
1558
+ --include reports,newThreats,threatsWatchlisted \\
1559
+ --from <baseline_from> --to <baseline_to>
1560
+ \`\`\`
1561
+
1562
+ When volume spikes broadly, also skim \`reports list --reported-by-customer\`
1563
+ for the same window \u2014 a wave of customer reports often arrives a few hours
1564
+ ahead of automated detection on a real coordinated push.
1565
+
1566
+ ### Trend 3 \u2014 Spike on a specific sub-brand (especially employee brands)
1567
+
1568
+ Sub-brands the org has set up for individual people \u2014 employees,
1569
+ executives, public figures \u2014 are high-signal targets. A sudden spike on
1570
+ one usually means an attacker is impersonating that person specifically,
1571
+ which is materially different from a generic phishing wave and usually
1572
+ warrants a direct heads-up to the person involved. In the database these
1573
+ are \`Brand\` rows with \`type: INDIVIDUAL\` (vs. \`ORGANIZATION\` for
1574
+ product / parent brands).
1575
+
1576
+ **Step 1: Pull the brand roster** so you can label each spike as
1577
+ "employee" or "product" without asking the user.
1578
+
1579
+ \`\`\`bash
1580
+ chainpatrol --json brands list
1581
+ \`\`\`
1582
+
1583
+ Build a map of \`slug \u2192 type\` from the response so the next step's
1584
+ findings can be tagged \`(employee)\` or \`(product)\` automatically.
1585
+
1586
+ **Step 2: Run the breakdown over both windows.**
1587
+
1588
+ \`\`\`bash
1589
+ # Current window \u2014 last 7 days, broken out by sub-brand
1590
+ chainpatrol --json metrics breakdown --org <slug> --by brand \\
1591
+ --from <YYYY-MM-DD 7d ago> --to <YYYY-MM-DD today>
1592
+
1593
+ # Baseline window \u2014 prior ~90 days
1594
+ chainpatrol --json metrics breakdown --org <slug> --by brand \\
1595
+ --from <YYYY-MM-DD 97d ago> --to <YYYY-MM-DD 8d ago>
1596
+ \`\`\`
1597
+
1598
+ Each entry in \`.points\` has \`{ brandId, brandSlug, brandName, count }\`.
1599
+ Apply the ratio rule, join against the \`slug \u2192 type\` map from Step 1,
1600
+ and report each spiking sub-brand by name plus its type.
1601
+
1602
+ **Step 3: Drill into the flagged brand** with \`metrics organization
1603
+ --brand-slug <slug>\` for a per-day / per-type breakdown scoped to that
1604
+ brand only. The server applies the brand filter to the scalar metrics
1605
+ (\`newThreats\`, \`takedownsFiled\`, etc.) AND to \`blockedByType\` /
1606
+ \`blockedByDay\`, so the time series and per-asset-type counts are real
1607
+ brand-only data:
1608
+
1609
+ \`\`\`bash
1610
+ chainpatrol --json metrics organization --org <slug> \\
1611
+ --brand-slug <brand-slug> \\
1612
+ --include newThreats,blockedByType,blockedByDay \\
1613
+ --from <YYYY-MM-DD 7d ago> --to <YYYY-MM-DD today>
1614
+ \`\`\`
1615
+
1616
+ If multiple \`INDIVIDUAL\` brands are spiking at the same time, treat that
1617
+ as a stronger signal than a single one \u2014 likely a campaign targeting the
1618
+ company's people rather than a single impersonation. Prioritize those
1619
+ findings over single-brand spikes when summarizing.
1620
+
1621
+ ### Reporting trend findings
1622
+
1623
+ Report each spiking bucket as its own finding with: the trend it falls
1624
+ under (asset type / overall volume / sub-brand), the current vs. baseline
1625
+ rate (e.g. "youtube: 12/day last 7d vs. 1.2/day prior 90d, \xD710
1626
+ baseline"), and a one-line follow-up:
1627
+
1628
+ - Asset-type spike \u2192 check \`configs list\` for the matching detection
1629
+ source and turn it on if it's off.
1630
+ - Overall-volume spike \u2192 flag a possible coordinated campaign; suggest
1631
+ the security team look at the recent \`reports list\` for shared
1632
+ infrastructure (sender, registrar, hosting).
1633
+ - Sub-brand spike \u2192 look up \`type\` via \`brands list\`; if
1634
+ \`INDIVIDUAL\`, suggest a direct heads-up to that person; if
1635
+ \`ORGANIZATION\`, suggest a product-team alert.
1636
+
1637
+ If none of the three trends fire above the 2\xD7 / floor thresholds, say so
1638
+ explicitly ("no significant trends in the last 7 days vs. the prior 90")
1639
+ rather than dumping every breakdown number \u2014 the absence is the
1640
+ finding.
1419
1641
  `;
1420
1642
  }
1421
1643
  function getBundledSkillVersion() {
package/dist/cli.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  getCliVersion,
14
14
  isSkillInstalled,
15
15
  readInstalledSkillVersion
16
- } from "./chunk-MDDC4F6Q.js";
16
+ } from "./chunk-UDGJEN4M.js";
17
17
  import "./chunk-NQT77IB7.js";
18
18
  import {
19
19
  DateTime
@@ -819,6 +819,7 @@ var COMMANDS = [
819
819
  "takedowns",
820
820
  "threats",
821
821
  "orgs",
822
+ "brands",
822
823
  "presets",
823
824
  "setup",
824
825
  "uninstall",
@@ -1054,12 +1055,12 @@ function parseAttachmentUrls() {
1054
1055
  }
1055
1056
  async function handleConfigsList(org) {
1056
1057
  if (jsonMode) {
1057
- const { listConfigsJson } = await import("./list-json-ZTS5GXNA.js");
1058
+ const { listConfigsJson } = await import("./list-json-B5L5PXKH.js");
1058
1059
  await listConfigsJson({ org });
1059
1060
  return;
1060
1061
  }
1061
1062
  const { render } = await import("ink");
1062
- const { default: ConfigsList } = await import("./list-AEM2KSO4.js");
1063
+ const { default: ConfigsList } = await import("./list-X4Z3CPO7.js");
1063
1064
  const { default: React } = await import("react");
1064
1065
  render(React.createElement(ConfigsList, { org }));
1065
1066
  }
@@ -1159,7 +1160,7 @@ async function main() {
1159
1160
  const positionals = cli.input.slice(2);
1160
1161
  const flagAssets = parseAssetInputs();
1161
1162
  const contents = [...positionals, ...flagAssets];
1162
- const { runAssetCheck } = await import("./check-EMGFDXUO.js");
1163
+ const { runAssetCheck } = await import("./check-G64UQCEL.js");
1163
1164
  await runAssetCheck({
1164
1165
  contents,
1165
1166
  json: jsonMode,
@@ -1169,7 +1170,7 @@ async function main() {
1169
1170
  break;
1170
1171
  }
1171
1172
  if (subcommand === "list") {
1172
- const { runAssetList } = await import("./list-2ENAEZVP.js");
1173
+ const { runAssetList } = await import("./list-XSIXAHOG.js");
1173
1174
  await runAssetList({
1174
1175
  type: cli.flags.type ?? cli.flags.assetType,
1175
1176
  status: cli.flags.assetStatus ?? cli.flags.status,
@@ -1190,7 +1191,7 @@ async function main() {
1190
1191
  case "detections": {
1191
1192
  const org = await resolveOrg();
1192
1193
  if (subcommand === "healthcheck") {
1193
- const { runDetectionsHealthcheck } = await import("./healthcheck-J6BIZEG7.js");
1194
+ const { runDetectionsHealthcheck } = await import("./healthcheck-QNLFKAXM.js");
1194
1195
  await runDetectionsHealthcheck({
1195
1196
  org,
1196
1197
  source: cli.flags.source,
@@ -1205,7 +1206,7 @@ async function main() {
1205
1206
  break;
1206
1207
  }
1207
1208
  if (subcommand === "validate") {
1208
- const { runDetectionsValidate } = await import("./validate-QE2F4PYY.js");
1209
+ const { runDetectionsValidate } = await import("./validate-UYKOMUEI.js");
1209
1210
  await runDetectionsValidate({
1210
1211
  org,
1211
1212
  source: cli.flags.source,
@@ -1220,7 +1221,7 @@ async function main() {
1220
1221
  break;
1221
1222
  }
1222
1223
  if (subcommand === "drift") {
1223
- const { runDetectionsDrift } = await import("./drift-RQKTGJWB.js");
1224
+ const { runDetectionsDrift } = await import("./drift-SHPMEJDU.js");
1224
1225
  await runDetectionsDrift({
1225
1226
  org,
1226
1227
  source: cli.flags.source,
@@ -1234,7 +1235,7 @@ async function main() {
1234
1235
  break;
1235
1236
  }
1236
1237
  if (subcommand === "run") {
1237
- const { runDetectionsRun } = await import("./run-HS2EEOM6.js");
1238
+ const { runDetectionsRun } = await import("./run-RV6P2OCD.js");
1238
1239
  await runDetectionsRun({
1239
1240
  org,
1240
1241
  configId: cli.flags.configId,
@@ -1248,7 +1249,7 @@ async function main() {
1248
1249
  break;
1249
1250
  }
1250
1251
  if (subcommand === "list") {
1251
- const { runDetectionsList } = await import("./list-LKNCICLT.js");
1252
+ const { runDetectionsList } = await import("./list-SWHKM5R6.js");
1252
1253
  await runDetectionsList({
1253
1254
  org,
1254
1255
  cursor: cli.flags.cursor,
@@ -1277,7 +1278,7 @@ async function main() {
1277
1278
  break;
1278
1279
  }
1279
1280
  if (action === "run") {
1280
- const { runDetectionsRun } = await import("./run-HS2EEOM6.js");
1281
+ const { runDetectionsRun } = await import("./run-RV6P2OCD.js");
1281
1282
  await runDetectionsRun({
1282
1283
  org,
1283
1284
  configId: cli.flags.configId,
@@ -1295,7 +1296,7 @@ async function main() {
1295
1296
  throw new Error("detections configs update requires --config-id");
1296
1297
  }
1297
1298
  const configPatch = getConfigPatchFromSetFlags();
1298
- const { runDetectionsConfigsUpdate } = await import("./configs-update-EKNLIRA6.js");
1299
+ const { runDetectionsConfigsUpdate } = await import("./configs-update-MVX7Q5NW.js");
1299
1300
  await runDetectionsConfigsUpdate({
1300
1301
  org,
1301
1302
  configId: cli.flags.configId,
@@ -1331,7 +1332,7 @@ async function main() {
1331
1332
  const slugs = parseCsvList(cli.flags.slugs);
1332
1333
  const allMyOrgs = cli.flags.allMyOrgs;
1333
1334
  const org2 = slugs && slugs.length > 0 || allMyOrgs ? void 0 : await tryResolveOrg();
1334
- const { runMetricsOrganization } = await import("./organization-PFPBZXJZ.js");
1335
+ const { runMetricsOrganization } = await import("./organization-SOMHMGTM.js");
1335
1336
  await runMetricsOrganization({
1336
1337
  org: org2,
1337
1338
  slugs,
@@ -1350,7 +1351,7 @@ async function main() {
1350
1351
  }
1351
1352
  const org = await resolveOrg();
1352
1353
  if (subcommand === "summary") {
1353
- const { runMetricsSummary } = await import("./summary-POVQC6B7.js");
1354
+ const { runMetricsSummary } = await import("./summary-LF53KXRR.js");
1354
1355
  await runMetricsSummary({
1355
1356
  org,
1356
1357
  from: cli.flags.from,
@@ -1363,7 +1364,7 @@ async function main() {
1363
1364
  break;
1364
1365
  }
1365
1366
  if (subcommand === "found") {
1366
- const { runMetricsFound } = await import("./found-LVYBEOS6.js");
1367
+ const { runMetricsFound } = await import("./found-OPL4HWOW.js");
1367
1368
  await runMetricsFound({
1368
1369
  org,
1369
1370
  from: cli.flags.from,
@@ -1380,7 +1381,7 @@ async function main() {
1380
1381
  if (!by || !["day", "type", "brand"].includes(by)) {
1381
1382
  throw new Error("metrics breakdown requires --by <day|type|brand>");
1382
1383
  }
1383
- const { runMetricsBreakdown } = await import("./breakdown-ETSF2BZ3.js");
1384
+ const { runMetricsBreakdown } = await import("./breakdown-3LJBT3JQ.js");
1384
1385
  await runMetricsBreakdown({
1385
1386
  org,
1386
1387
  by,
@@ -1401,7 +1402,7 @@ async function main() {
1401
1402
  case "reports": {
1402
1403
  if (subcommand === "list") {
1403
1404
  const org = await resolveOrg();
1404
- const { runReportsList } = await import("./list-44BQZHJD.js");
1405
+ const { runReportsList } = await import("./list-WPPNX7G3.js");
1405
1406
  await runReportsList({
1406
1407
  org,
1407
1408
  limit: cli.flags.limit,
@@ -1429,7 +1430,7 @@ async function main() {
1429
1430
  }
1430
1431
  if (subcommand === "create") {
1431
1432
  const org = await tryResolveOrg();
1432
- const { runReportsCreate } = await import("./create-M4PV5VVU.js");
1433
+ const { runReportsCreate } = await import("./create-ANCO4FXB.js");
1433
1434
  await runReportsCreate({
1434
1435
  org,
1435
1436
  title: cli.flags.title,
@@ -1450,7 +1451,7 @@ async function main() {
1450
1451
  const positionals = cli.input.slice(2);
1451
1452
  const flagAssets = parseAssetInputs();
1452
1453
  const assetContents = [...positionals, ...flagAssets];
1453
- const { runReportsSearch } = await import("./search-EBXEP7XC.js");
1454
+ const { runReportsSearch } = await import("./search-FQUR75WR.js");
1454
1455
  await runReportsSearch({
1455
1456
  assetContents,
1456
1457
  reportedByCustomer: cli.flags.reportedByCustomer,
@@ -1466,7 +1467,7 @@ async function main() {
1466
1467
  }
1467
1468
  case "threats": {
1468
1469
  if (subcommand === "list") {
1469
- const { runThreatsList } = await import("./list-E2JVJNHV.js");
1470
+ const { runThreatsList } = await import("./list-Q5PRMAN5.js");
1470
1471
  await runThreatsList({
1471
1472
  query: cli.flags.query,
1472
1473
  from: cli.flags.from,
@@ -1489,7 +1490,7 @@ async function main() {
1489
1490
  case "takedowns": {
1490
1491
  if (subcommand === "list") {
1491
1492
  const org = await tryResolveOrg();
1492
- const { runTakedownsList } = await import("./list-S5Y6GW43.js");
1493
+ const { runTakedownsList } = await import("./list-FWXQUOCP.js");
1493
1494
  await runTakedownsList({
1494
1495
  org,
1495
1496
  query: cli.flags.query,
@@ -1520,7 +1521,7 @@ async function main() {
1520
1521
  }
1521
1522
  case "queues": {
1522
1523
  if (subcommand === "snapshot") {
1523
- const { runQueuesSnapshot } = await import("./snapshot-GNZMYTXT.js");
1524
+ const { runQueuesSnapshot } = await import("./snapshot-2GDJMN3L.js");
1524
1525
  await runQueuesSnapshot({
1525
1526
  org: cli.flags.org,
1526
1527
  all: cli.flags.all,
@@ -1538,7 +1539,7 @@ async function main() {
1538
1539
  }
1539
1540
  case "orgs": {
1540
1541
  if (subcommand === "list") {
1541
- const { runOrgsList } = await import("./list-XUYCZG7S.js");
1542
+ const { runOrgsList } = await import("./list-QXA6GLCV.js");
1542
1543
  await runOrgsList({
1543
1544
  query: cli.flags.query,
1544
1545
  subscriptionStatus: cli.flags.subscriptionStatus,
@@ -1554,7 +1555,7 @@ async function main() {
1554
1555
  if (subcommand === "get") {
1555
1556
  const positionalSlug = action;
1556
1557
  const slug = positionalSlug ?? await tryResolveOrg();
1557
- const { runOrgsGet } = await import("./get-YFYSJFBC.js");
1558
+ const { runOrgsGet } = await import("./get-K7VHV5X2.js");
1558
1559
  await runOrgsGet({
1559
1560
  slug,
1560
1561
  json: jsonMode,
@@ -1564,7 +1565,7 @@ async function main() {
1564
1565
  }
1565
1566
  if (subcommand === "assets") {
1566
1567
  if (action === "list") {
1567
- const { runOrgsAssetsList } = await import("./list-O62BZKQ5.js");
1568
+ const { runOrgsAssetsList } = await import("./list-QHEFB4KE.js");
1568
1569
  await runOrgsAssetsList({
1569
1570
  type: cli.flags.type ?? cli.flags.assetType,
1570
1571
  groupId: cli.flags.groupId,
@@ -1580,7 +1581,7 @@ async function main() {
1580
1581
  }
1581
1582
  if (subcommand === "asset-groups") {
1582
1583
  if (action === "list") {
1583
- const { runOrgsAssetGroupsList } = await import("./list-O36VWTWR.js");
1584
+ const { runOrgsAssetGroupsList } = await import("./list-FVFF4VW3.js");
1584
1585
  await runOrgsAssetGroupsList({
1585
1586
  json: jsonMode,
1586
1587
  outputFormat: cliContext.outputFormat
@@ -1594,8 +1595,29 @@ async function main() {
1594
1595
  subcommand ? `Unknown subcommand: orgs ${subcommand}${hint ? `. Did you mean "orgs ${hint}"?` : ""}` : "Usage: chainpatrol orgs <list|get <slug>|assets list|asset-groups list> [filters]"
1595
1596
  );
1596
1597
  }
1598
+ case "brands": {
1599
+ if (subcommand === "list") {
1600
+ const rawType = cli.flags.type?.toUpperCase();
1601
+ if (rawType && rawType !== "ORGANIZATION" && rawType !== "INDIVIDUAL") {
1602
+ throw new Error(
1603
+ "brands list --type must be ORGANIZATION or INDIVIDUAL (case-insensitive)."
1604
+ );
1605
+ }
1606
+ const { runBrandsList } = await import("./list-4VKMEKZS.js");
1607
+ await runBrandsList({
1608
+ type: rawType,
1609
+ json: jsonMode,
1610
+ outputFormat: cliContext.outputFormat
1611
+ });
1612
+ break;
1613
+ }
1614
+ const hint = subcommand ? suggest(subcommand, ["list"]) : null;
1615
+ throw new Error(
1616
+ subcommand ? `Unknown subcommand: brands ${subcommand}${hint ? `. Did you mean "brands ${hint}"?` : ""}` : "Usage: chainpatrol brands list [--type ORGANIZATION|INDIVIDUAL]"
1617
+ );
1618
+ }
1597
1619
  case "whoami": {
1598
- const { runWhoami } = await import("./whoami-24KUJUN4.js");
1620
+ const { runWhoami } = await import("./whoami-OYOG63BX.js");
1599
1621
  await runWhoami({
1600
1622
  json: jsonMode,
1601
1623
  outputFormat: cliContext.outputFormat
@@ -1604,7 +1626,7 @@ async function main() {
1604
1626
  }
1605
1627
  case "healthchecks": {
1606
1628
  if (subcommand === "list") {
1607
- const { runHealthchecksList } = await import("./list-CNF2FGLN.js");
1629
+ const { runHealthchecksList } = await import("./list-AQ7E23T3.js");
1608
1630
  await runHealthchecksList({
1609
1631
  json: jsonMode,
1610
1632
  outputFormat: cliContext.outputFormat
@@ -1618,7 +1640,7 @@ async function main() {
1618
1640
  thresholds.minResults = cli.flags.minResults;
1619
1641
  if (cli.flags.lookbackHours !== void 0)
1620
1642
  thresholds.lookbackHours = cli.flags.lookbackHours;
1621
- const { runHealthchecksRun } = await import("./run-R3RR6XQF.js");
1643
+ const { runHealthchecksRun } = await import("./run-J5TQ2YC2.js");
1622
1644
  await runHealthchecksRun({
1623
1645
  org,
1624
1646
  id: action,
@@ -1636,7 +1658,7 @@ async function main() {
1636
1658
  }
1637
1659
  case "presets": {
1638
1660
  if (subcommand === "list") {
1639
- const { runPresetsList } = await import("./list-JCJHIJM4.js");
1661
+ const { runPresetsList } = await import("./list-FJBWSGTD.js");
1640
1662
  await runPresetsList({ outputFormat: cliContext.outputFormat });
1641
1663
  break;
1642
1664
  }
@@ -1647,7 +1669,7 @@ async function main() {
1647
1669
  );
1648
1670
  }
1649
1671
  const org = await resolveOrg();
1650
- const { runPresetsRun } = await import("./run-LKPKTH3W.js");
1672
+ const { runPresetsRun } = await import("./run-YAAMSWKK.js");
1651
1673
  await runPresetsRun({
1652
1674
  presetId: action,
1653
1675
  org,
@@ -1664,12 +1686,12 @@ async function main() {
1664
1686
  case "setup":
1665
1687
  case "install":
1666
1688
  case "i": {
1667
- const { setupSkill } = await import("./setup-skill-Z6SBI6GC.js");
1689
+ const { setupSkill } = await import("./setup-skill-F7437RT3.js");
1668
1690
  setupSkill({ json: jsonMode, cloud: cli.flags.cloud });
1669
1691
  break;
1670
1692
  }
1671
1693
  case "uninstall": {
1672
- const { uninstallSkill } = await import("./setup-skill-Z6SBI6GC.js");
1694
+ const { uninstallSkill } = await import("./setup-skill-F7437RT3.js");
1673
1695
  uninstallSkill({ json: jsonMode });
1674
1696
  break;
1675
1697
  }
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-DPLUSURP.js";
10
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-DPLUSURP.js";
10
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -0,0 +1,64 @@
1
+ import {
2
+ printOutput,
3
+ toCsvRows
4
+ } from "./chunk-VFT3TD3E.js";
5
+ import {
6
+ createApiClient
7
+ } from "./chunk-O7TMOF4W.js";
8
+ import "./chunk-EGWK6SRQ.js";
9
+ import "./chunk-TFCNKBRC.js";
10
+ import "./chunk-U73SABXK.js";
11
+
12
+ // src/commands/brands/list.ts
13
+ function toRow(brand) {
14
+ return {
15
+ id: brand.id,
16
+ slug: brand.slug,
17
+ name: brand.name,
18
+ type: brand.type,
19
+ description: brand.description ?? "",
20
+ brandGroupId: brand.brandGroupId,
21
+ createdAt: brand.createdAt
22
+ };
23
+ }
24
+ async function runBrandsList(options) {
25
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
26
+ const client = options.apiClient ?? createApiClient();
27
+ const result = await client.listOrganizationBrands();
28
+ const brands = options.type ? result.brands.filter((brand) => brand.type === options.type) : result.brands;
29
+ const rows = brands.map(toRow);
30
+ printOutput({
31
+ outputFormat,
32
+ json: options.type ? { ...result, brands } : result,
33
+ markdown: [
34
+ "# Organization brands",
35
+ "",
36
+ `- Returned: ${brands.length}${options.type ? ` (filtered to type=${options.type})` : ""}`,
37
+ "",
38
+ ...rows.map(
39
+ (row) => `- #${row.id} ${row.name} (slug=${row.slug}, type=${row.type}${row.brandGroupId !== null ? `, groupId=${row.brandGroupId}` : ""})`
40
+ )
41
+ ].join("\n"),
42
+ csv: toCsvRows(rows),
43
+ human: () => {
44
+ if (brands.length === 0) {
45
+ console.log(
46
+ options.type ? `No brands of type ${options.type} found.` : "No brands found."
47
+ );
48
+ return;
49
+ }
50
+ console.log(
51
+ `Organization brands \u2014 returned ${brands.length}${options.type ? ` (type=${options.type})` : ""}`
52
+ );
53
+ for (const row of rows) {
54
+ const group = row.brandGroupId !== null ? ` groupId=${row.brandGroupId}` : "";
55
+ console.log(
56
+ `#${row.id} ${row.name} (slug=${row.slug}, type=${row.type}${group})`
57
+ );
58
+ }
59
+ }
60
+ });
61
+ }
62
+ export {
63
+ runBrandsList
64
+ };
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-DPLUSURP.js";
7
+ } from "./chunk-O7TMOF4W.js";
8
8
  import "./chunk-EGWK6SRQ.js";
9
9
  import "./chunk-TFCNKBRC.js";
10
10
  import "./chunk-U73SABXK.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  PRESETS
3
- } from "./chunk-HGAQBGGL.js";
3
+ } from "./chunk-2JZAPTY6.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-DPLUSURP.js";
9
+ import "./chunk-O7TMOF4W.js";
10
10
  import "./chunk-EGWK6SRQ.js";
11
11
  import "./chunk-TFCNKBRC.js";
12
12
  import "./chunk-U73SABXK.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-DPLUSURP.js";
7
+ } from "./chunk-O7TMOF4W.js";
8
8
  import "./chunk-EGWK6SRQ.js";
9
9
  import "./chunk-TFCNKBRC.js";
10
10
  import "./chunk-U73SABXK.js";
@@ -11,7 +11,7 @@ import {
11
11
  TAKEDOWN_SORT_KEYS,
12
12
  TAKEDOWN_STATUSES,
13
13
  createApiClient
14
- } from "./chunk-DPLUSURP.js";
14
+ } from "./chunk-O7TMOF4W.js";
15
15
  import "./chunk-EGWK6SRQ.js";
16
16
  import "./chunk-TFCNKBRC.js";
17
17
  import "./chunk-U73SABXK.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -12,7 +12,7 @@ import {
12
12
  LIVENESS_FILTER_VALUES,
13
13
  WATCHLIST_FILTER_VALUES,
14
14
  createApiClient
15
- } from "./chunk-DPLUSURP.js";
15
+ } from "./chunk-O7TMOF4W.js";
16
16
  import "./chunk-EGWK6SRQ.js";
17
17
  import "./chunk-TFCNKBRC.js";
18
18
  import "./chunk-U73SABXK.js";
@@ -10,7 +10,7 @@ import {
10
10
  REPORT_REVIEW_DECISIONS,
11
11
  REPORT_STATUSES,
12
12
  createApiClient
13
- } from "./chunk-DPLUSURP.js";
13
+ } from "./chunk-O7TMOF4W.js";
14
14
  import "./chunk-EGWK6SRQ.js";
15
15
  import "./chunk-TFCNKBRC.js";
16
16
  import "./chunk-U73SABXK.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-JCMWDZYY.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-DPLUSURP.js";
7
+ } from "./chunk-O7TMOF4W.js";
8
8
  import {
9
9
  AuthCorruptedError,
10
10
  AuthExpiredError,
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
3
+ } from "./chunk-O7TMOF4W.js";
4
4
  import "./chunk-EGWK6SRQ.js";
5
5
  import "./chunk-TFCNKBRC.js";
6
6
  import "./chunk-U73SABXK.js";
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  ORGANIZATION_METRICS_INCLUDE_FIELDS,
10
10
  createApiClient
11
- } from "./chunk-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.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-HGAQBGGL.js";
4
+ } from "./chunk-2JZAPTY6.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-DPLUSURP.js";
10
+ import "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -6,7 +6,7 @@ import {
6
6
  readInstalledSkillVersion,
7
7
  setupSkill,
8
8
  uninstallSkill
9
- } from "./chunk-MDDC4F6Q.js";
9
+ } from "./chunk-UDGJEN4M.js";
10
10
  import "./chunk-NQT77IB7.js";
11
11
  export {
12
12
  getBundledSkillContent,
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-DPLUSURP.js";
10
+ } from "./chunk-O7TMOF4W.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-DPLUSURP.js";
11
+ } from "./chunk-O7TMOF4W.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-VFT3TD3E.js";
4
4
  import {
5
5
  createApiClient
6
- } from "./chunk-DPLUSURP.js";
6
+ } from "./chunk-O7TMOF4W.js";
7
7
  import "./chunk-EGWK6SRQ.js";
8
8
  import "./chunk-TFCNKBRC.js";
9
9
  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.18.0",
5
+ "version": "0.19.0",
6
6
  "license": "UNLICENSED",
7
7
  "homepage": "https://chainpatrol.com/docs/cli",
8
8
  "keywords": [