@chainpatrol/cli 0.15.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @chainpatrol/cli
2
2
 
3
+ ## 0.15.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 92df1cd: Tighten the skill content so agents stop bailing on cross-customer
8
+ totals.
9
+
10
+ After the multi-org `--slugs` shipped in #6555, an agent on the
11
+ new CLI was still answering "I can't easily get this — no `--all`
12
+ aggregation in the CLI" to "how many takedowns across all clients
13
+ in the last 7 days?", because the existing `--slugs` section was
14
+ buried below the per-subcommand details and the agent anchored on
15
+ `metrics summary` (which is single-org and has no `--slugs`).
16
+
17
+ Two changes to fix that without touching code:
18
+
19
+ 1. **Frontload a decision rule.** A new "read this before picking a
20
+ metrics subcommand" block sits at the top of the metrics section,
21
+ names the cross-org phrases ("across all clients", "company-wide",
22
+ "total takedowns", "how many takedowns in the last N days?" with
23
+ no org named, etc.), points at `metrics organization --slugs`,
24
+ and explicitly anti-patterns the common wrong moves (routing to
25
+ Metabase, looping `metrics summary`, bailing with "no cross-org
26
+ aggregation in the CLI"). Includes a copy-and-run two-step
27
+ recipe (`orgs list` → `metrics organization --slugs`).
28
+ 2. **Broaden the `Use when` trigger phrases** to cover the cross-org
29
+ wording explicitly: "how many takedowns", "across all
30
+ clients/customers/orgs/brands", "company-wide", "total/average
31
+ takedowns/threats/reports", "rollup across customers", etc., so
32
+ the skill itself loads when the user asks this kind of question.
33
+
34
+ Skill-only change; no API, handler, or response shape changes.
35
+
3
36
  ## 0.15.0
4
37
 
5
38
  ### Minor Changes
@@ -198,7 +198,13 @@ description: |
198
198
  "orgs with takedowns off", "automation off across orgs",
199
199
  "which customers have X enabled", "service toggles by org",
200
200
  "is this URL blocked", "is this domain blocked", "is this address blocked",
201
- "check this asset", "asset check", "lookup asset status".
201
+ "check this asset", "asset check", "lookup asset status",
202
+ "how many takedowns", "takedowns in the last", "threats taken down",
203
+ "across all clients", "across all customers", "across all orgs",
204
+ "across all brands", "company-wide", "total takedowns", "total threats",
205
+ "total reports", "average takedowns", "average threats", "average per day",
206
+ "average per customer", "average per org", "rollup across customers",
207
+ "sum across orgs", "sum across customers".
202
208
  allowed-tools:
203
209
  - Bash
204
210
  - Read
@@ -661,6 +667,66 @@ and summarize patterns by service or by subscription tier.
661
667
 
662
668
  ### \`metrics summary | found | breakdown | organization\` \u2014 Org metrics for spike/drop analysis
663
669
 
670
+ #### Decision rule \u2014 read this before picking a metrics subcommand
671
+
672
+ When the user asks for a number that **spans more than one customer/org/brand**
673
+ \u2014 phrases like "across all clients", "across all customers", "across all orgs",
674
+ "across all brands", "company-wide", "total takedowns", "total threats",
675
+ "average takedowns per day across customers", "rollup across customers",
676
+ "how many takedowns in the last 7 days?" (no org named) \u2014 the answer is
677
+ **\`chainpatrol metrics organization --slugs <comma-list>\`**, *not*
678
+ \`metrics summary\`. \`summary\`, \`found\`, and \`breakdown\` are
679
+ single-org commands and have no \`--slugs\`; only \`organization\` does.
680
+ The \`--slugs\` form rolls totals + per-day / per-org-per-day averages
681
+ server-side in **one** HTTP call. Full recipe is in the \`--slugs\`
682
+ section below.
683
+
684
+ **Anti-patterns to avoid:**
685
+
686
+ - \u274C "There's no cross-org aggregation in the CLI." There is \u2014 \`metrics
687
+ organization --slugs\`. Don't bail out citing the docs without
688
+ searching for \`--slugs\`.
689
+ - \u274C Looping \`metrics summary --org X\` once per customer to sum
690
+ client-side. \`--slugs\` is one round-trip; the loop is what made
691
+ the endpoint 503-prone in the first place.
692
+ - \u274C Routing the user to Metabase / the data warehouse for a question
693
+ the CLI can answer. Reach for Metabase only when the metric isn't
694
+ in the \`--include\` list (\`reports\`, \`newThreats\`,
695
+ \`threatsWatchlisted\`, \`takedownsFiled\`, \`takedownsCompleted\`,
696
+ \`domainThreats\`, \`twitterThreats\`, \`telegramThreats\`,
697
+ \`otherThreats\`, \`blockedByType\`, \`blockedByDay\`).
698
+ - \u274C "Iterating 100+ orgs one-by-one isn't practical here." Right \u2014
699
+ that's why you don't iterate. You pass \`--slugs\` (cap 50; if more,
700
+ split the list into batches and sum) with \`--include <metric>\`
701
+ to keep each per-org aggregate cheap.
702
+
703
+ #### Common cross-org recipe (copy and run)
704
+
705
+ \`\`\`bash
706
+ # Step 1: get the slugs of every active customer with takedowns enabled
707
+ chainpatrol --json orgs list \\
708
+ --subscription-status ACTIVE \\
709
+ --service-active takedowns
710
+
711
+ # Step 2: feed the slugs into one metrics call. Server fans out and rolls up.
712
+ chainpatrol --json metrics organization \\
713
+ --slugs <comma-list from step 1> \\
714
+ --include takedownsCompleted \\
715
+ --from <YYYY-MM-DD 7 days ago> --to <YYYY-MM-DD today>
716
+
717
+ # Read these fields from the JSON:
718
+ # .metrics.takedownsCompleted \u2190 grand total across all orgs
719
+ # .averages.perDay.takedownsCompleted \u2190 total / windowDays
720
+ # .averages.perOrgPerDay.takedownsCompleted \u2190 total / numOrgs / windowDays
721
+ # .perOrg[slug].metrics.takedownsCompleted \u2190 per-customer breakdown
722
+ \`\`\`
723
+
724
+ Replace \`takedownsCompleted\` with whatever metric the user asked about.
725
+ Replace the date range with whatever window they asked about (default
726
+ 3 months if they didn't say).
727
+
728
+ #### Single-org examples
729
+
664
730
  \`\`\`bash
665
731
  chainpatrol --json metrics summary --org <slug> # defaults to last 3 months
666
732
  chainpatrol --json metrics summary --org <slug> --this-week
package/dist/cli.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  getCliVersion,
14
14
  isSkillInstalled,
15
15
  readInstalledSkillVersion
16
- } from "./chunk-QGKR7EPH.js";
16
+ } from "./chunk-IPN6O3N4.js";
17
17
  import "./chunk-NQT77IB7.js";
18
18
  import {
19
19
  DateTime
@@ -1632,12 +1632,12 @@ async function main() {
1632
1632
  case "setup":
1633
1633
  case "install":
1634
1634
  case "i": {
1635
- const { setupSkill } = await import("./setup-skill-ENJSVGLR.js");
1635
+ const { setupSkill } = await import("./setup-skill-6SDQXFTR.js");
1636
1636
  setupSkill({ json: jsonMode, cloud: cli.flags.cloud });
1637
1637
  break;
1638
1638
  }
1639
1639
  case "uninstall": {
1640
- const { uninstallSkill } = await import("./setup-skill-ENJSVGLR.js");
1640
+ const { uninstallSkill } = await import("./setup-skill-6SDQXFTR.js");
1641
1641
  uninstallSkill({ json: jsonMode });
1642
1642
  break;
1643
1643
  }
@@ -6,7 +6,7 @@ import {
6
6
  readInstalledSkillVersion,
7
7
  setupSkill,
8
8
  uninstallSkill
9
- } from "./chunk-QGKR7EPH.js";
9
+ } from "./chunk-IPN6O3N4.js";
10
10
  import "./chunk-NQT77IB7.js";
11
11
  export {
12
12
  getBundledSkillContent,
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.15.0",
5
+ "version": "0.15.1",
6
6
  "license": "UNLICENSED",
7
7
  "homepage": "https://chainpatrol.com/docs/cli",
8
8
  "keywords": [