@chainpatrol/cli 0.16.0 → 0.17.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 (36) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/{breakdown-PQXHY2VO.js → breakdown-ETSF2BZ3.js} +1 -1
  3. package/dist/{check-5B4EPWOZ.js → check-EMGFDXUO.js} +1 -1
  4. package/dist/{chunk-TTLGCRRR.js → chunk-75H4KTIQ.js} +31 -0
  5. package/dist/{chunk-JEBZIBRI.js → chunk-DPLUSURP.js} +6 -0
  6. package/dist/{chunk-CJPWEWGS.js → chunk-HGAQBGGL.js} +1 -1
  7. package/dist/cli.js +60 -36
  8. package/dist/{configs-update-6BYB7M37.js → configs-update-EKNLIRA6.js} +1 -1
  9. package/dist/{create-Y6Z4L656.js → create-M4PV5VVU.js} +1 -1
  10. package/dist/{drift-5EZK2JA5.js → drift-RQKTGJWB.js} +1 -1
  11. package/dist/{found-XRJZ4SSY.js → found-LVYBEOS6.js} +1 -1
  12. package/dist/get-BPTWCJ6H.js +75 -0
  13. package/dist/{healthcheck-47MU5AZ7.js → healthcheck-J6BIZEG7.js} +1 -1
  14. package/dist/{list-G2F2IFEU.js → list-2ENAEZVP.js} +1 -1
  15. package/dist/{list-2JCBA3Q2.js → list-44BQZHJD.js} +1 -1
  16. package/dist/{list-GPWZ52JD.js → list-AEM2KSO4.js} +1 -1
  17. package/dist/{list-AYXZG3I6.js → list-CNF2FGLN.js} +1 -1
  18. package/dist/{list-JD4U2SBV.js → list-E2JVJNHV.js} +1 -1
  19. package/dist/{list-WBZIULUS.js → list-JCJHIJM4.js} +2 -2
  20. package/dist/{list-FGDMMAPM.js → list-LKNCICLT.js} +1 -1
  21. package/dist/{list-IA2LRT4X.js → list-O36VWTWR.js} +1 -1
  22. package/dist/{list-QC7DUKFD.js → list-O62BZKQ5.js} +1 -1
  23. package/dist/{list-KFFNLKZK.js → list-OEJV4UNQ.js} +1 -1
  24. package/dist/{list-ZIM2MR2Q.js → list-S5Y6GW43.js} +1 -1
  25. package/dist/{list-json-DXPR3UEY.js → list-json-ZTS5GXNA.js} +1 -1
  26. package/dist/{organization-NR6JCD5I.js → organization-PFPBZXJZ.js} +1 -1
  27. package/dist/{run-HDEKIP4L.js → run-HS2EEOM6.js} +1 -1
  28. package/dist/{run-ANHA5JFB.js → run-LKPKTH3W.js} +2 -2
  29. package/dist/{run-EJBBPBOR.js → run-R3RR6XQF.js} +1 -1
  30. package/dist/{search-PBVQ7473.js → search-EBXEP7XC.js} +1 -1
  31. package/dist/{setup-skill-2RKWIVGS.js → setup-skill-RPVW2CCQ.js} +1 -1
  32. package/dist/{snapshot-U53T5Q2M.js → snapshot-GNZMYTXT.js} +1 -1
  33. package/dist/{summary-2IXOMOIA.js → summary-POVQC6B7.js} +1 -1
  34. package/dist/{validate-LXE3JPET.js → validate-QE2F4PYY.js} +1 -1
  35. package/dist/{whoami-4XDWPKVV.js → whoami-24KUJUN4.js} +1 -1
  36. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @chainpatrol/cli
2
2
 
3
+ ## 0.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 27b18af: Adds `chainpatrol orgs get <slug>` for fetching a single accessible
8
+ organization, backed by a new public `GET /user/orgs/{slug}` endpoint.
9
+ Returns the same per-org shape as one row of `orgs list` (subscription
10
+ status + per-service active/automated flags) and reuses the same access
11
+ gating: org-scoped API keys must match the slug, user sessions / user-scoped
12
+ API keys need an active membership unless the caller is staff. The bundled
13
+ Claude Code skill (`/chainpatrol`) is updated to document the new command.
14
+ Server-side procedure + validation live in the private `@chainpatrol/external-trpc`
15
+ and `@chainpatrol/validation` packages and ship together with this CLI
16
+ release, but are not listed in the frontmatter because they are private.
17
+
3
18
  ## 0.16.0
4
19
 
5
20
  ### Minor Changes
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-JEBZIBRI.js";
10
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -195,6 +195,8 @@ description: |
195
195
  "customer reports", "reports reported by customer", "find detection gaps",
196
196
  "org healthcheck", "organization health check", "audit my org",
197
197
  "what's wrong with org", "review org setup", "list orgs", "list organizations",
198
+ "get org", "get organization", "show org details", "org by slug",
199
+ "fetch org details", "org info",
198
200
  "orgs with takedowns off", "automation off across orgs",
199
201
  "which customers have X enabled", "service toggles by org",
200
202
  "is this URL blocked", "is this domain blocked", "is this address blocked",
@@ -657,6 +659,35 @@ Customers see only orgs they're a member of. Staff/superuser sessions see
657
659
  every matching org. The response is the same in both cases; visibility is
658
660
  enforced server-side.
659
661
 
662
+ ### \`orgs get\` \u2014 Get a single organization by slug
663
+
664
+ Look up one organization the caller has access to. Returns the same per-org
665
+ shape as a single row from \`orgs list\` (subscription status + per-service
666
+ active/automated flags), so anything you could read from \`orgs list\` you
667
+ can also read here without paging or filtering. Use it when the user names
668
+ a specific customer ("show me acme's setup", "is takedowns automation on
669
+ for morpho?") and you don't need the rest of the catalogue.
670
+
671
+ \`\`\`bash
672
+ chainpatrol orgs get <slug>
673
+ chainpatrol --json orgs get <slug>
674
+ \`\`\`
675
+
676
+ Permission rules match \`orgs list\`:
677
+
678
+ - Org-scoped API keys: must match the slug \u2014 querying another org returns
679
+ 403.
680
+ - User sessions / user-scoped API keys: need an active OrganizationMembership
681
+ on the slug. Staff/superusers can read any org.
682
+ - Soft-deleted orgs are not returned (404). A 404 also fires for orgs the
683
+ caller would not be authorized to see \u2014 the endpoint deliberately does
684
+ not distinguish "doesn't exist" from "you can't see this" beyond the
685
+ generic 403/404 envelope.
686
+
687
+ Prefer \`orgs get\` over \`orgs list\` + client-side filter whenever the
688
+ caller already knows the slug; it's one round-trip and side-steps the
689
+ list filters entirely.
690
+
660
691
  #### Use case: finding service configuration gaps across the customer base
661
692
 
662
693
  When the user asks something like "which customers are paying us but don't
@@ -297,6 +297,12 @@ function createApiClient(options) {
297
297
  getUserOrgs(input) {
298
298
  return request("/user/orgs", input);
299
299
  },
300
+ getUserOrg(input) {
301
+ return requestGet(
302
+ `/user/orgs/${encodeURIComponent(input.slug)}`,
303
+ {}
304
+ );
305
+ },
300
306
  listAssets(input) {
301
307
  return request("/asset/list", {
302
308
  type: input.type,
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.js";
12
12
  import {
13
13
  DateTime
14
14
  } from "./chunk-TFCNKBRC.js";
package/dist/cli.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  getCliVersion,
14
14
  isSkillInstalled,
15
15
  readInstalledSkillVersion
16
- } from "./chunk-TTLGCRRR.js";
16
+ } from "./chunk-75H4KTIQ.js";
17
17
  import "./chunk-NQT77IB7.js";
18
18
  import {
19
19
  DateTime
@@ -474,10 +474,11 @@ var HELP = {
474
474
  ]
475
475
  },
476
476
  orgs: {
477
- description: "List organizations, their assets, and asset groups. Top-level `orgs list` lists organizations accessible to you; the nested subcommands operate on the org tied to your API key.",
478
- usage: "chainpatrol orgs <list|assets list|asset-groups list>",
477
+ description: "List organizations, their assets, and asset groups. Top-level `orgs list` lists organizations accessible to you; `orgs get <slug>` returns details for a single accessible org; the nested subcommands operate on the org tied to your API key.",
478
+ usage: "chainpatrol orgs <list|get <slug>|assets list|asset-groups list>",
479
479
  examples: [
480
480
  "chainpatrol orgs list",
481
+ "chainpatrol orgs get acme",
481
482
  "chainpatrol orgs assets list --asset-type URL",
482
483
  "chainpatrol orgs asset-groups list"
483
484
  ]
@@ -528,6 +529,18 @@ var HELP = {
528
529
  "chainpatrol --json orgs list --subscription-status ACTIVE,TRIAL --service-active detection"
529
530
  ]
530
531
  },
532
+ "orgs get": {
533
+ description: "Get a single organization by slug. Returns the same shape as one row of `orgs list` (subscription status + per-service active/automated flags). Caller must have access: org-scoped API keys must match the slug, user sessions/keys need an active membership unless the user is staff.",
534
+ usage: "chainpatrol orgs get <slug>",
535
+ options: [
536
+ "--org <slug> Use the saved default org instead of a positional argument."
537
+ ],
538
+ examples: [
539
+ "chainpatrol orgs get acme",
540
+ "chainpatrol --json orgs get acme",
541
+ "chainpatrol orgs get acme --output markdown"
542
+ ]
543
+ },
531
544
  healthchecks: {
532
545
  description: "Run organization healthchecks via the public API. Use `list` to see every available check (including planned ones not yet implemented on the backend) and `run` to execute one or all implemented checks.",
533
546
  usage: "chainpatrol healthchecks <list|run <id>|run --all>",
@@ -1041,12 +1054,12 @@ function parseAttachmentUrls() {
1041
1054
  }
1042
1055
  async function handleConfigsList(org) {
1043
1056
  if (jsonMode) {
1044
- const { listConfigsJson } = await import("./list-json-DXPR3UEY.js");
1057
+ const { listConfigsJson } = await import("./list-json-ZTS5GXNA.js");
1045
1058
  await listConfigsJson({ org });
1046
1059
  return;
1047
1060
  }
1048
1061
  const { render } = await import("ink");
1049
- const { default: ConfigsList } = await import("./list-GPWZ52JD.js");
1062
+ const { default: ConfigsList } = await import("./list-AEM2KSO4.js");
1050
1063
  const { default: React } = await import("react");
1051
1064
  render(React.createElement(ConfigsList, { org }));
1052
1065
  }
@@ -1146,7 +1159,7 @@ async function main() {
1146
1159
  const positionals = cli.input.slice(2);
1147
1160
  const flagAssets = parseAssetInputs();
1148
1161
  const contents = [...positionals, ...flagAssets];
1149
- const { runAssetCheck } = await import("./check-5B4EPWOZ.js");
1162
+ const { runAssetCheck } = await import("./check-EMGFDXUO.js");
1150
1163
  await runAssetCheck({
1151
1164
  contents,
1152
1165
  json: jsonMode,
@@ -1156,7 +1169,7 @@ async function main() {
1156
1169
  break;
1157
1170
  }
1158
1171
  if (subcommand === "list") {
1159
- const { runAssetList } = await import("./list-G2F2IFEU.js");
1172
+ const { runAssetList } = await import("./list-2ENAEZVP.js");
1160
1173
  await runAssetList({
1161
1174
  type: cli.flags.type ?? cli.flags.assetType,
1162
1175
  status: cli.flags.assetStatus ?? cli.flags.status,
@@ -1177,7 +1190,7 @@ async function main() {
1177
1190
  case "detections": {
1178
1191
  const org = await resolveOrg();
1179
1192
  if (subcommand === "healthcheck") {
1180
- const { runDetectionsHealthcheck } = await import("./healthcheck-47MU5AZ7.js");
1193
+ const { runDetectionsHealthcheck } = await import("./healthcheck-J6BIZEG7.js");
1181
1194
  await runDetectionsHealthcheck({
1182
1195
  org,
1183
1196
  source: cli.flags.source,
@@ -1192,7 +1205,7 @@ async function main() {
1192
1205
  break;
1193
1206
  }
1194
1207
  if (subcommand === "validate") {
1195
- const { runDetectionsValidate } = await import("./validate-LXE3JPET.js");
1208
+ const { runDetectionsValidate } = await import("./validate-QE2F4PYY.js");
1196
1209
  await runDetectionsValidate({
1197
1210
  org,
1198
1211
  source: cli.flags.source,
@@ -1207,7 +1220,7 @@ async function main() {
1207
1220
  break;
1208
1221
  }
1209
1222
  if (subcommand === "drift") {
1210
- const { runDetectionsDrift } = await import("./drift-5EZK2JA5.js");
1223
+ const { runDetectionsDrift } = await import("./drift-RQKTGJWB.js");
1211
1224
  await runDetectionsDrift({
1212
1225
  org,
1213
1226
  source: cli.flags.source,
@@ -1221,7 +1234,7 @@ async function main() {
1221
1234
  break;
1222
1235
  }
1223
1236
  if (subcommand === "run") {
1224
- const { runDetectionsRun } = await import("./run-HDEKIP4L.js");
1237
+ const { runDetectionsRun } = await import("./run-HS2EEOM6.js");
1225
1238
  await runDetectionsRun({
1226
1239
  org,
1227
1240
  configId: cli.flags.configId,
@@ -1235,7 +1248,7 @@ async function main() {
1235
1248
  break;
1236
1249
  }
1237
1250
  if (subcommand === "list") {
1238
- const { runDetectionsList } = await import("./list-FGDMMAPM.js");
1251
+ const { runDetectionsList } = await import("./list-LKNCICLT.js");
1239
1252
  await runDetectionsList({
1240
1253
  org,
1241
1254
  cursor: cli.flags.cursor,
@@ -1264,7 +1277,7 @@ async function main() {
1264
1277
  break;
1265
1278
  }
1266
1279
  if (action === "run") {
1267
- const { runDetectionsRun } = await import("./run-HDEKIP4L.js");
1280
+ const { runDetectionsRun } = await import("./run-HS2EEOM6.js");
1268
1281
  await runDetectionsRun({
1269
1282
  org,
1270
1283
  configId: cli.flags.configId,
@@ -1282,7 +1295,7 @@ async function main() {
1282
1295
  throw new Error("detections configs update requires --config-id");
1283
1296
  }
1284
1297
  const configPatch = getConfigPatchFromSetFlags();
1285
- const { runDetectionsConfigsUpdate } = await import("./configs-update-6BYB7M37.js");
1298
+ const { runDetectionsConfigsUpdate } = await import("./configs-update-EKNLIRA6.js");
1286
1299
  await runDetectionsConfigsUpdate({
1287
1300
  org,
1288
1301
  configId: cli.flags.configId,
@@ -1318,7 +1331,7 @@ async function main() {
1318
1331
  const slugs = parseCsvList(cli.flags.slugs);
1319
1332
  const allMyOrgs = cli.flags.allMyOrgs;
1320
1333
  const org2 = slugs && slugs.length > 0 || allMyOrgs ? void 0 : await tryResolveOrg();
1321
- const { runMetricsOrganization } = await import("./organization-NR6JCD5I.js");
1334
+ const { runMetricsOrganization } = await import("./organization-PFPBZXJZ.js");
1322
1335
  await runMetricsOrganization({
1323
1336
  org: org2,
1324
1337
  slugs,
@@ -1337,7 +1350,7 @@ async function main() {
1337
1350
  }
1338
1351
  const org = await resolveOrg();
1339
1352
  if (subcommand === "summary") {
1340
- const { runMetricsSummary } = await import("./summary-2IXOMOIA.js");
1353
+ const { runMetricsSummary } = await import("./summary-POVQC6B7.js");
1341
1354
  await runMetricsSummary({
1342
1355
  org,
1343
1356
  from: cli.flags.from,
@@ -1350,7 +1363,7 @@ async function main() {
1350
1363
  break;
1351
1364
  }
1352
1365
  if (subcommand === "found") {
1353
- const { runMetricsFound } = await import("./found-XRJZ4SSY.js");
1366
+ const { runMetricsFound } = await import("./found-LVYBEOS6.js");
1354
1367
  await runMetricsFound({
1355
1368
  org,
1356
1369
  from: cli.flags.from,
@@ -1367,7 +1380,7 @@ async function main() {
1367
1380
  if (!by || !["day", "type", "brand"].includes(by)) {
1368
1381
  throw new Error("metrics breakdown requires --by <day|type|brand>");
1369
1382
  }
1370
- const { runMetricsBreakdown } = await import("./breakdown-PQXHY2VO.js");
1383
+ const { runMetricsBreakdown } = await import("./breakdown-ETSF2BZ3.js");
1371
1384
  await runMetricsBreakdown({
1372
1385
  org,
1373
1386
  by,
@@ -1388,7 +1401,7 @@ async function main() {
1388
1401
  case "reports": {
1389
1402
  if (subcommand === "list") {
1390
1403
  const org = await resolveOrg();
1391
- const { runReportsList } = await import("./list-2JCBA3Q2.js");
1404
+ const { runReportsList } = await import("./list-44BQZHJD.js");
1392
1405
  await runReportsList({
1393
1406
  org,
1394
1407
  limit: cli.flags.limit,
@@ -1416,7 +1429,7 @@ async function main() {
1416
1429
  }
1417
1430
  if (subcommand === "create") {
1418
1431
  const org = await tryResolveOrg();
1419
- const { runReportsCreate } = await import("./create-Y6Z4L656.js");
1432
+ const { runReportsCreate } = await import("./create-M4PV5VVU.js");
1420
1433
  await runReportsCreate({
1421
1434
  org,
1422
1435
  title: cli.flags.title,
@@ -1437,7 +1450,7 @@ async function main() {
1437
1450
  const positionals = cli.input.slice(2);
1438
1451
  const flagAssets = parseAssetInputs();
1439
1452
  const assetContents = [...positionals, ...flagAssets];
1440
- const { runReportsSearch } = await import("./search-PBVQ7473.js");
1453
+ const { runReportsSearch } = await import("./search-EBXEP7XC.js");
1441
1454
  await runReportsSearch({
1442
1455
  assetContents,
1443
1456
  reportedByCustomer: cli.flags.reportedByCustomer,
@@ -1453,7 +1466,7 @@ async function main() {
1453
1466
  }
1454
1467
  case "threats": {
1455
1468
  if (subcommand === "list") {
1456
- const { runThreatsList } = await import("./list-JD4U2SBV.js");
1469
+ const { runThreatsList } = await import("./list-E2JVJNHV.js");
1457
1470
  await runThreatsList({
1458
1471
  query: cli.flags.query,
1459
1472
  from: cli.flags.from,
@@ -1476,7 +1489,7 @@ async function main() {
1476
1489
  case "takedowns": {
1477
1490
  if (subcommand === "list") {
1478
1491
  const org = await tryResolveOrg();
1479
- const { runTakedownsList } = await import("./list-ZIM2MR2Q.js");
1492
+ const { runTakedownsList } = await import("./list-S5Y6GW43.js");
1480
1493
  await runTakedownsList({
1481
1494
  org,
1482
1495
  query: cli.flags.query,
@@ -1507,7 +1520,7 @@ async function main() {
1507
1520
  }
1508
1521
  case "queues": {
1509
1522
  if (subcommand === "snapshot") {
1510
- const { runQueuesSnapshot } = await import("./snapshot-U53T5Q2M.js");
1523
+ const { runQueuesSnapshot } = await import("./snapshot-GNZMYTXT.js");
1511
1524
  await runQueuesSnapshot({
1512
1525
  org: cli.flags.org,
1513
1526
  all: cli.flags.all,
@@ -1525,7 +1538,7 @@ async function main() {
1525
1538
  }
1526
1539
  case "orgs": {
1527
1540
  if (subcommand === "list") {
1528
- const { runOrgsList } = await import("./list-KFFNLKZK.js");
1541
+ const { runOrgsList } = await import("./list-OEJV4UNQ.js");
1529
1542
  await runOrgsList({
1530
1543
  query: cli.flags.query,
1531
1544
  subscriptionStatus: cli.flags.subscriptionStatus,
@@ -1538,9 +1551,20 @@ async function main() {
1538
1551
  });
1539
1552
  break;
1540
1553
  }
1554
+ if (subcommand === "get") {
1555
+ const positionalSlug = action;
1556
+ const slug = positionalSlug ?? await tryResolveOrg();
1557
+ const { runOrgsGet } = await import("./get-BPTWCJ6H.js");
1558
+ await runOrgsGet({
1559
+ slug,
1560
+ json: jsonMode,
1561
+ outputFormat: cliContext.outputFormat
1562
+ });
1563
+ break;
1564
+ }
1541
1565
  if (subcommand === "assets") {
1542
1566
  if (action === "list") {
1543
- const { runOrgsAssetsList } = await import("./list-QC7DUKFD.js");
1567
+ const { runOrgsAssetsList } = await import("./list-O62BZKQ5.js");
1544
1568
  await runOrgsAssetsList({
1545
1569
  type: cli.flags.type ?? cli.flags.assetType,
1546
1570
  groupId: cli.flags.groupId,
@@ -1556,7 +1580,7 @@ async function main() {
1556
1580
  }
1557
1581
  if (subcommand === "asset-groups") {
1558
1582
  if (action === "list") {
1559
- const { runOrgsAssetGroupsList } = await import("./list-IA2LRT4X.js");
1583
+ const { runOrgsAssetGroupsList } = await import("./list-O36VWTWR.js");
1560
1584
  await runOrgsAssetGroupsList({
1561
1585
  json: jsonMode,
1562
1586
  outputFormat: cliContext.outputFormat
@@ -1565,13 +1589,13 @@ async function main() {
1565
1589
  }
1566
1590
  throw new Error("Usage: chainpatrol orgs asset-groups list");
1567
1591
  }
1568
- const hint = subcommand ? suggest(subcommand, ["list", "assets", "asset-groups"]) : null;
1592
+ const hint = subcommand ? suggest(subcommand, ["list", "get", "assets", "asset-groups"]) : null;
1569
1593
  throw new Error(
1570
- subcommand ? `Unknown subcommand: orgs ${subcommand}${hint ? `. Did you mean "orgs ${hint}"?` : ""}` : "Usage: chainpatrol orgs <list|assets list|asset-groups list> [filters]"
1594
+ subcommand ? `Unknown subcommand: orgs ${subcommand}${hint ? `. Did you mean "orgs ${hint}"?` : ""}` : "Usage: chainpatrol orgs <list|get <slug>|assets list|asset-groups list> [filters]"
1571
1595
  );
1572
1596
  }
1573
1597
  case "whoami": {
1574
- const { runWhoami } = await import("./whoami-4XDWPKVV.js");
1598
+ const { runWhoami } = await import("./whoami-24KUJUN4.js");
1575
1599
  await runWhoami({
1576
1600
  json: jsonMode,
1577
1601
  outputFormat: cliContext.outputFormat
@@ -1580,7 +1604,7 @@ async function main() {
1580
1604
  }
1581
1605
  case "healthchecks": {
1582
1606
  if (subcommand === "list") {
1583
- const { runHealthchecksList } = await import("./list-AYXZG3I6.js");
1607
+ const { runHealthchecksList } = await import("./list-CNF2FGLN.js");
1584
1608
  await runHealthchecksList({
1585
1609
  json: jsonMode,
1586
1610
  outputFormat: cliContext.outputFormat
@@ -1594,7 +1618,7 @@ async function main() {
1594
1618
  thresholds.minResults = cli.flags.minResults;
1595
1619
  if (cli.flags.lookbackHours !== void 0)
1596
1620
  thresholds.lookbackHours = cli.flags.lookbackHours;
1597
- const { runHealthchecksRun } = await import("./run-EJBBPBOR.js");
1621
+ const { runHealthchecksRun } = await import("./run-R3RR6XQF.js");
1598
1622
  await runHealthchecksRun({
1599
1623
  org,
1600
1624
  id: action,
@@ -1612,7 +1636,7 @@ async function main() {
1612
1636
  }
1613
1637
  case "presets": {
1614
1638
  if (subcommand === "list") {
1615
- const { runPresetsList } = await import("./list-WBZIULUS.js");
1639
+ const { runPresetsList } = await import("./list-JCJHIJM4.js");
1616
1640
  await runPresetsList({ outputFormat: cliContext.outputFormat });
1617
1641
  break;
1618
1642
  }
@@ -1623,7 +1647,7 @@ async function main() {
1623
1647
  );
1624
1648
  }
1625
1649
  const org = await resolveOrg();
1626
- const { runPresetsRun } = await import("./run-ANHA5JFB.js");
1650
+ const { runPresetsRun } = await import("./run-LKPKTH3W.js");
1627
1651
  await runPresetsRun({
1628
1652
  presetId: action,
1629
1653
  org,
@@ -1640,12 +1664,12 @@ async function main() {
1640
1664
  case "setup":
1641
1665
  case "install":
1642
1666
  case "i": {
1643
- const { setupSkill } = await import("./setup-skill-2RKWIVGS.js");
1667
+ const { setupSkill } = await import("./setup-skill-RPVW2CCQ.js");
1644
1668
  setupSkill({ json: jsonMode, cloud: cli.flags.cloud });
1645
1669
  break;
1646
1670
  }
1647
1671
  case "uninstall": {
1648
- const { uninstallSkill } = await import("./setup-skill-2RKWIVGS.js");
1672
+ const { uninstallSkill } = await import("./setup-skill-RPVW2CCQ.js");
1649
1673
  uninstallSkill({ json: jsonMode });
1650
1674
  break;
1651
1675
  }
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-JEBZIBRI.js";
10
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
10
+ } from "./chunk-DPLUSURP.js";
11
11
  import "./chunk-EGWK6SRQ.js";
12
12
  import "./chunk-TFCNKBRC.js";
13
13
  import "./chunk-U73SABXK.js";
@@ -0,0 +1,75 @@
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
+ createApiClient
11
+ } from "./chunk-DPLUSURP.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
+ import "./chunk-TFCNKBRC.js";
14
+ import "./chunk-U73SABXK.js";
15
+
16
+ // src/commands/orgs/get.ts
17
+ function summarizeServices(org) {
18
+ const parts = [];
19
+ for (const service of ["reporting", "reviewing", "protection", "takedowns"]) {
20
+ const entry = org.services[service];
21
+ if (!entry.active) continue;
22
+ parts.push(`${service}=${entry.automated ? "auto" : "manual"}`);
23
+ }
24
+ if (org.services.detection.active) parts.push("detection");
25
+ if (org.services.darkWebMonitoring.active) parts.push("darkWebMonitoring");
26
+ return parts.length > 0 ? parts.join(" ") : "(no services enabled)";
27
+ }
28
+ async function runOrgsGet(options) {
29
+ const slug = options.slug?.trim();
30
+ if (!slug) {
31
+ throw new CliExitError(
32
+ "orgs get requires an organization slug. Example: chainpatrol orgs get acme",
33
+ ExitCode.USAGE
34
+ );
35
+ }
36
+ const client = options.apiClient ?? createApiClient();
37
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
38
+ const result = await client.getUserOrg({ slug });
39
+ const { organization } = result;
40
+ printOutput({
41
+ outputFormat,
42
+ json: result,
43
+ markdown: [
44
+ `# ${organization.name} (\`${organization.slug}\`)`,
45
+ "",
46
+ `- Subscription status: ${organization.subscriptionStatus}`,
47
+ `- Services: ${summarizeServices(organization)}`
48
+ ].join("\n"),
49
+ csv: toCsvRows([
50
+ {
51
+ slug: organization.slug,
52
+ name: organization.name,
53
+ subscriptionStatus: organization.subscriptionStatus,
54
+ reportingActive: organization.services.reporting.active,
55
+ reportingAutomated: organization.services.reporting.automated,
56
+ reviewingActive: organization.services.reviewing.active,
57
+ reviewingAutomated: organization.services.reviewing.automated,
58
+ protectionActive: organization.services.protection.active,
59
+ protectionAutomated: organization.services.protection.automated,
60
+ takedownsActive: organization.services.takedowns.active,
61
+ takedownsAutomated: organization.services.takedowns.automated,
62
+ detectionActive: organization.services.detection.active,
63
+ darkWebMonitoringActive: organization.services.darkWebMonitoring.active
64
+ }
65
+ ]),
66
+ human: () => {
67
+ console.log(`${organization.name} (slug: ${organization.slug})`);
68
+ console.log(` subscriptionStatus: ${organization.subscriptionStatus}`);
69
+ console.log(` services: ${summarizeServices(organization)}`);
70
+ }
71
+ });
72
+ }
73
+ export {
74
+ runOrgsGet
75
+ };
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -10,7 +10,7 @@ import {
10
10
  REPORT_REVIEW_DECISIONS,
11
11
  REPORT_STATUSES,
12
12
  createApiClient
13
- } from "./chunk-JEBZIBRI.js";
13
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
7
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
7
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  PRESETS
3
- } from "./chunk-CJPWEWGS.js";
3
+ } from "./chunk-HGAQBGGL.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-JEBZIBRI.js";
9
+ import "./chunk-DPLUSURP.js";
10
10
  import "./chunk-EGWK6SRQ.js";
11
11
  import "./chunk-TFCNKBRC.js";
12
12
  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-JEBZIBRI.js";
15
+ } from "./chunk-DPLUSURP.js";
16
16
  import "./chunk-EGWK6SRQ.js";
17
17
  import "./chunk-TFCNKBRC.js";
18
18
  import "./chunk-U73SABXK.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-JEBZIBRI.js";
7
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -11,7 +11,7 @@ import {
11
11
  TAKEDOWN_SORT_KEYS,
12
12
  TAKEDOWN_STATUSES,
13
13
  createApiClient
14
- } from "./chunk-JEBZIBRI.js";
14
+ } from "./chunk-DPLUSURP.js";
15
15
  import "./chunk-EGWK6SRQ.js";
16
16
  import "./chunk-TFCNKBRC.js";
17
17
  import "./chunk-U73SABXK.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApiClient
3
- } from "./chunk-JEBZIBRI.js";
3
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-CJPWEWGS.js";
4
+ } from "./chunk-HGAQBGGL.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-JEBZIBRI.js";
10
+ import "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-TTLGCRRR.js";
9
+ } from "./chunk-75H4KTIQ.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
10
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
11
+ } from "./chunk-DPLUSURP.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-JEBZIBRI.js";
6
+ } from "./chunk-DPLUSURP.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.16.0",
5
+ "version": "0.17.0",
6
6
  "license": "UNLICENSED",
7
7
  "homepage": "https://chainpatrol.com/docs/cli",
8
8
  "keywords": [