@chainpatrol/cli 0.7.0 → 0.8.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 (30) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/{breakdown-AX6QNTQH.js → breakdown-DXSN7KUF.js} +2 -2
  3. package/dist/{chunk-EEG7T6WT.js → chunk-EGWK6SRQ.js} +5 -0
  4. package/dist/{chunk-LLWKCA3H.js → chunk-F6D645LF.js} +19 -7
  5. package/dist/{chunk-EBJMOX3Q.js → chunk-PZV55KAR.js} +6 -1
  6. package/dist/{chunk-AGXMZFUU.js → chunk-XIHOCIYM.js} +1 -1
  7. package/dist/cli.js +24 -24
  8. package/dist/{configs-update-VROBC2HI.js → configs-update-BBENU2PG.js} +2 -2
  9. package/dist/{create-XTCUNT2C.js → create-SXPAFMPT.js} +2 -2
  10. package/dist/{drift-VOKQJ36G.js → drift-WJD2Z5ZB.js} +2 -2
  11. package/dist/{found-A5HRTJCJ.js → found-4UY3IC5T.js} +2 -2
  12. package/dist/{healthcheck-AQUXVKAO.js → healthcheck-XTQN64DB.js} +2 -2
  13. package/dist/{list-PLZ67PNY.js → list-2PBVBN5K.js} +2 -2
  14. package/dist/{list-5ENZAOFL.js → list-6ELSECNR.js} +2 -2
  15. package/dist/{list-EYRN5JYC.js → list-BGI7IZ55.js} +3 -3
  16. package/dist/{list-CVFXTKNX.js → list-BVUG6RUF.js} +2 -2
  17. package/dist/{list-CGRHTFAS.js → list-IJS66PYW.js} +2 -2
  18. package/dist/{list-json-LEKCCWQU.js → list-json-DWHMAA6S.js} +2 -2
  19. package/dist/{login-C66GRR3Y.js → login-AMEXCOGT.js} +11 -2
  20. package/dist/{login-json-XGMXT5VJ.js → login-json-MPLXCSP4.js} +2 -2
  21. package/dist/{login-plain-CWKOUZKE.js → login-plain-NIJDS3D2.js} +2 -2
  22. package/dist/{logout-LA7VEKON.js → logout-T6Q4IVPU.js} +10 -1
  23. package/dist/{logout-json-4GIJZJ46.js → logout-json-ACXBI6PN.js} +11 -1
  24. package/dist/{run-YHDUUP66.js → run-3W7LSPX2.js} +3 -3
  25. package/dist/{run-OT2X46GT.js → run-4S244KUM.js} +2 -2
  26. package/dist/{run-MS5SA5YL.js → run-M25F7TWI.js} +2 -2
  27. package/dist/{snapshot-4QR4I67P.js → snapshot-MEOOARL3.js} +2 -2
  28. package/dist/{summary-JOCABBCO.js → summary-JYDAPBYX.js} +2 -2
  29. package/dist/{validate-27RUCN7R.js → validate-RI7YKHKH.js} +2 -2
  30. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @chainpatrol/cli
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 11d074f: Support non-interactive authentication via the `CHAINPATROL_API_KEY` env
8
+ var. When set, the CLI sends it as the `x-api-key` header on API calls and
9
+ skips the device-code login flow entirely. `chainpatrol login` reports
10
+ "already authenticated via env var" instead of polling, and
11
+ `chainpatrol logout` refuses to no-op (it tells you to unset the env var).
12
+ Stored Better Auth bearer credentials are still used as a fallback when
13
+ the env var is unset. Headless service accounts (e.g. agent42) should mint
14
+ a USER-type API key via `/staff/api-keys` and set
15
+ `CHAINPATROL_API_KEY=cp_live_…` in their deployment env.
16
+
3
17
  ## 0.7.0
4
18
 
5
19
  ### Minor Changes
@@ -4,8 +4,8 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-LLWKCA3H.js";
8
- import "./chunk-EEG7T6WT.js";
7
+ } from "./chunk-F6D645LF.js";
8
+ import "./chunk-EGWK6SRQ.js";
9
9
  import "./chunk-TFCNKBRC.js";
10
10
  import "./chunk-U73SABXK.js";
11
11
 
@@ -139,6 +139,7 @@ function clearCredentials() {
139
139
  }
140
140
  }
141
141
  function isLoggedIn() {
142
+ if (hasApiKeyEnv()) return true;
142
143
  try {
143
144
  getValidCredentials();
144
145
  return true;
@@ -146,6 +147,9 @@ function isLoggedIn() {
146
147
  return false;
147
148
  }
148
149
  }
150
+ function hasApiKeyEnv() {
151
+ return Boolean(process.env.CHAINPATROL_API_KEY?.trim());
152
+ }
149
153
  function getValidCredentials() {
150
154
  const creds = getCredentials();
151
155
  const expiresMs = new Date(creds.expiresAt).getTime();
@@ -280,6 +284,7 @@ export {
280
284
  storeCredentials,
281
285
  clearCredentials,
282
286
  isLoggedIn,
287
+ hasApiKeyEnv,
283
288
  getValidCredentials,
284
289
  fetchUserEmail,
285
290
  requestDeviceCode,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getValidCredentials
3
- } from "./chunk-EEG7T6WT.js";
3
+ } from "./chunk-EGWK6SRQ.js";
4
4
  import {
5
5
  DateTime
6
6
  } from "./chunk-TFCNKBRC.js";
@@ -18,20 +18,32 @@ function parseIsoDate(value) {
18
18
  return dt.toJSDate();
19
19
  }
20
20
  var REQUEST_TIMEOUT_MS = 3e4;
21
+ function defaultGetCredential() {
22
+ const envKey = process.env.CHAINPATROL_API_KEY;
23
+ if (envKey && envKey.trim().length > 0) {
24
+ return { kind: "api-key", value: envKey.trim() };
25
+ }
26
+ return { kind: "bearer", value: getValidCredentials().accessToken };
27
+ }
21
28
  function createApiClient(options) {
22
29
  const config = getConfig();
23
30
  const apiUrl = options?.apiUrl ?? config.apiUrl;
24
- const getToken = options?.getToken ?? (() => getValidCredentials().accessToken);
31
+ const getCredential = options?.getCredential ?? (options?.getToken ? () => ({ kind: "bearer", value: options.getToken() }) : defaultGetCredential);
25
32
  async function request(path, body) {
26
- const token = getToken();
33
+ const credential = getCredential();
34
+ const headers = {
35
+ "Content-Type": "application/json"
36
+ };
37
+ if (credential.kind === "api-key") {
38
+ headers["x-api-key"] = credential.value;
39
+ } else {
40
+ headers["Authorization"] = `Bearer ${credential.value}`;
41
+ }
27
42
  let res;
28
43
  try {
29
44
  res = await fetch(`${apiUrl}/api/v2${path}`, {
30
45
  method: "POST",
31
- headers: {
32
- "Content-Type": "application/json",
33
- Authorization: `Bearer ${token}`
34
- },
46
+ headers,
35
47
  body: JSON.stringify(body),
36
48
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
37
49
  });
@@ -1,17 +1,22 @@
1
1
  import {
2
2
  fetchUserEmail,
3
3
  getCredentials,
4
+ hasApiKeyEnv,
4
5
  isLoggedIn,
5
6
  pollForToken,
6
7
  requestDeviceCode,
7
8
  storeCredentials
8
- } from "./chunk-EEG7T6WT.js";
9
+ } from "./chunk-EGWK6SRQ.js";
9
10
  import {
10
11
  DateTime
11
12
  } from "./chunk-TFCNKBRC.js";
12
13
 
13
14
  // src/lib/login-flow.ts
14
15
  async function runLoginFlow(emit) {
16
+ if (hasApiKeyEnv()) {
17
+ emit({ type: "already_logged_in", email: null });
18
+ return true;
19
+ }
15
20
  if (isLoggedIn()) {
16
21
  const creds = getCredentials();
17
22
  emit({ type: "already_logged_in", email: creds.email ?? null });
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
11
+ } from "./chunk-F6D645LF.js";
12
12
  import {
13
13
  DateTime
14
14
  } from "./chunk-TFCNKBRC.js";
package/dist/cli.js CHANGED
@@ -754,12 +754,12 @@ function parseAttachmentUrls() {
754
754
  }
755
755
  async function handleConfigsList(org) {
756
756
  if (jsonMode) {
757
- const { listConfigsJson } = await import("./list-json-LEKCCWQU.js");
757
+ const { listConfigsJson } = await import("./list-json-DWHMAA6S.js");
758
758
  await listConfigsJson({ org });
759
759
  return;
760
760
  }
761
761
  const { render } = await import("ink");
762
- const { default: ConfigsList } = await import("./list-5ENZAOFL.js");
762
+ const { default: ConfigsList } = await import("./list-6ELSECNR.js");
763
763
  const { default: React } = await import("react");
764
764
  render(React.createElement(ConfigsList, { org }));
765
765
  }
@@ -814,14 +814,14 @@ async function main() {
814
814
  );
815
815
  }
816
816
  if (jsonMode) {
817
- const { loginJson } = await import("./login-json-XGMXT5VJ.js");
817
+ const { loginJson } = await import("./login-json-MPLXCSP4.js");
818
818
  await loginJson();
819
819
  } else if (!process.stdout.isTTY) {
820
- const { loginPlain } = await import("./login-plain-CWKOUZKE.js");
820
+ const { loginPlain } = await import("./login-plain-NIJDS3D2.js");
821
821
  await loginPlain();
822
822
  } else {
823
823
  const { render } = await import("ink");
824
- const { default: Login } = await import("./login-C66GRR3Y.js");
824
+ const { default: Login } = await import("./login-AMEXCOGT.js");
825
825
  const { default: React } = await import("react");
826
826
  render(React.createElement(Login));
827
827
  }
@@ -829,11 +829,11 @@ async function main() {
829
829
  }
830
830
  case "logout": {
831
831
  if (jsonMode) {
832
- const { logoutJson } = await import("./logout-json-4GIJZJ46.js");
832
+ const { logoutJson } = await import("./logout-json-ACXBI6PN.js");
833
833
  await logoutJson();
834
834
  } else {
835
835
  const { render } = await import("ink");
836
- const { default: Logout } = await import("./logout-LA7VEKON.js");
836
+ const { default: Logout } = await import("./logout-T6Q4IVPU.js");
837
837
  const { default: React } = await import("react");
838
838
  render(React.createElement(Logout));
839
839
  }
@@ -857,7 +857,7 @@ async function main() {
857
857
  case "detections": {
858
858
  const org = await resolveOrg();
859
859
  if (subcommand === "healthcheck") {
860
- const { runDetectionsHealthcheck } = await import("./healthcheck-AQUXVKAO.js");
860
+ const { runDetectionsHealthcheck } = await import("./healthcheck-XTQN64DB.js");
861
861
  await runDetectionsHealthcheck({
862
862
  org,
863
863
  source: cli.flags.source,
@@ -872,7 +872,7 @@ async function main() {
872
872
  break;
873
873
  }
874
874
  if (subcommand === "validate") {
875
- const { runDetectionsValidate } = await import("./validate-27RUCN7R.js");
875
+ const { runDetectionsValidate } = await import("./validate-RI7YKHKH.js");
876
876
  await runDetectionsValidate({
877
877
  org,
878
878
  source: cli.flags.source,
@@ -887,7 +887,7 @@ async function main() {
887
887
  break;
888
888
  }
889
889
  if (subcommand === "drift") {
890
- const { runDetectionsDrift } = await import("./drift-VOKQJ36G.js");
890
+ const { runDetectionsDrift } = await import("./drift-WJD2Z5ZB.js");
891
891
  await runDetectionsDrift({
892
892
  org,
893
893
  source: cli.flags.source,
@@ -901,7 +901,7 @@ async function main() {
901
901
  break;
902
902
  }
903
903
  if (subcommand === "run") {
904
- const { runDetectionsRun } = await import("./run-OT2X46GT.js");
904
+ const { runDetectionsRun } = await import("./run-4S244KUM.js");
905
905
  await runDetectionsRun({
906
906
  org,
907
907
  configId: cli.flags.configId,
@@ -920,7 +920,7 @@ async function main() {
920
920
  break;
921
921
  }
922
922
  if (action === "run") {
923
- const { runDetectionsRun } = await import("./run-OT2X46GT.js");
923
+ const { runDetectionsRun } = await import("./run-4S244KUM.js");
924
924
  await runDetectionsRun({
925
925
  org,
926
926
  configId: cli.flags.configId,
@@ -938,7 +938,7 @@ async function main() {
938
938
  throw new Error("detections configs update requires --config-id");
939
939
  }
940
940
  const configPatch = getConfigPatchFromSetFlags();
941
- const { runDetectionsConfigsUpdate } = await import("./configs-update-VROBC2HI.js");
941
+ const { runDetectionsConfigsUpdate } = await import("./configs-update-BBENU2PG.js");
942
942
  await runDetectionsConfigsUpdate({
943
943
  org,
944
944
  configId: cli.flags.configId,
@@ -965,7 +965,7 @@ async function main() {
965
965
  case "metrics": {
966
966
  const org = await resolveOrg();
967
967
  if (subcommand === "summary") {
968
- const { runMetricsSummary } = await import("./summary-JOCABBCO.js");
968
+ const { runMetricsSummary } = await import("./summary-JYDAPBYX.js");
969
969
  await runMetricsSummary({
970
970
  org,
971
971
  from: cli.flags.from,
@@ -977,7 +977,7 @@ async function main() {
977
977
  break;
978
978
  }
979
979
  if (subcommand === "found") {
980
- const { runMetricsFound } = await import("./found-A5HRTJCJ.js");
980
+ const { runMetricsFound } = await import("./found-4UY3IC5T.js");
981
981
  await runMetricsFound({
982
982
  org,
983
983
  from: cli.flags.from,
@@ -994,7 +994,7 @@ async function main() {
994
994
  if (!by || !["day", "type", "brand"].includes(by)) {
995
995
  throw new Error("metrics breakdown requires --by <day|type|brand>");
996
996
  }
997
- const { runMetricsBreakdown } = await import("./breakdown-AX6QNTQH.js");
997
+ const { runMetricsBreakdown } = await import("./breakdown-DXSN7KUF.js");
998
998
  await runMetricsBreakdown({
999
999
  org,
1000
1000
  by,
@@ -1014,7 +1014,7 @@ async function main() {
1014
1014
  case "reports": {
1015
1015
  if (subcommand === "list") {
1016
1016
  const org = await resolveOrg();
1017
- const { runReportsList } = await import("./list-CVFXTKNX.js");
1017
+ const { runReportsList } = await import("./list-BVUG6RUF.js");
1018
1018
  await runReportsList({
1019
1019
  org,
1020
1020
  limit: cli.flags.limit,
@@ -1030,7 +1030,7 @@ async function main() {
1030
1030
  }
1031
1031
  if (subcommand === "create") {
1032
1032
  const org = await tryResolveOrg();
1033
- const { runReportsCreate } = await import("./create-XTCUNT2C.js");
1033
+ const { runReportsCreate } = await import("./create-SXPAFMPT.js");
1034
1034
  await runReportsCreate({
1035
1035
  org,
1036
1036
  title: cli.flags.title,
@@ -1054,7 +1054,7 @@ async function main() {
1054
1054
  }
1055
1055
  case "queues": {
1056
1056
  if (subcommand === "snapshot") {
1057
- const { runQueuesSnapshot } = await import("./snapshot-4QR4I67P.js");
1057
+ const { runQueuesSnapshot } = await import("./snapshot-MEOOARL3.js");
1058
1058
  await runQueuesSnapshot({
1059
1059
  org: cli.flags.org,
1060
1060
  all: cli.flags.all,
@@ -1072,7 +1072,7 @@ async function main() {
1072
1072
  }
1073
1073
  case "orgs": {
1074
1074
  if (subcommand === "list") {
1075
- const { runOrgsList } = await import("./list-CGRHTFAS.js");
1075
+ const { runOrgsList } = await import("./list-IJS66PYW.js");
1076
1076
  await runOrgsList({
1077
1077
  query: cli.flags.query,
1078
1078
  subscriptionStatus: cli.flags.subscriptionStatus,
@@ -1092,7 +1092,7 @@ async function main() {
1092
1092
  }
1093
1093
  case "healthchecks": {
1094
1094
  if (subcommand === "list") {
1095
- const { runHealthchecksList } = await import("./list-PLZ67PNY.js");
1095
+ const { runHealthchecksList } = await import("./list-2PBVBN5K.js");
1096
1096
  await runHealthchecksList({
1097
1097
  json: jsonMode,
1098
1098
  outputFormat: cliContext.outputFormat
@@ -1106,7 +1106,7 @@ async function main() {
1106
1106
  thresholds.minResults = cli.flags.minResults;
1107
1107
  if (cli.flags.lookbackHours !== void 0)
1108
1108
  thresholds.lookbackHours = cli.flags.lookbackHours;
1109
- const { runHealthchecksRun } = await import("./run-MS5SA5YL.js");
1109
+ const { runHealthchecksRun } = await import("./run-M25F7TWI.js");
1110
1110
  await runHealthchecksRun({
1111
1111
  org,
1112
1112
  id: action,
@@ -1124,7 +1124,7 @@ async function main() {
1124
1124
  }
1125
1125
  case "presets": {
1126
1126
  if (subcommand === "list") {
1127
- const { runPresetsList } = await import("./list-EYRN5JYC.js");
1127
+ const { runPresetsList } = await import("./list-BGI7IZ55.js");
1128
1128
  await runPresetsList({ outputFormat: cliContext.outputFormat });
1129
1129
  break;
1130
1130
  }
@@ -1135,7 +1135,7 @@ async function main() {
1135
1135
  );
1136
1136
  }
1137
1137
  const org = await resolveOrg();
1138
- const { runPresetsRun } = await import("./run-YHDUUP66.js");
1138
+ const { runPresetsRun } = await import("./run-3W7LSPX2.js");
1139
1139
  await runPresetsRun({
1140
1140
  presetId: action,
1141
1141
  org,
@@ -7,8 +7,8 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-LLWKCA3H.js";
11
- import "./chunk-EEG7T6WT.js";
10
+ } from "./chunk-F6D645LF.js";
11
+ import "./chunk-EGWK6SRQ.js";
12
12
  import "./chunk-TFCNKBRC.js";
13
13
  import "./chunk-U73SABXK.js";
14
14
 
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
12
- import "./chunk-EEG7T6WT.js";
11
+ } from "./chunk-F6D645LF.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
12
- import "./chunk-EEG7T6WT.js";
11
+ } from "./chunk-F6D645LF.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
@@ -4,8 +4,8 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-LLWKCA3H.js";
8
- import "./chunk-EEG7T6WT.js";
7
+ } from "./chunk-F6D645LF.js";
8
+ import "./chunk-EGWK6SRQ.js";
9
9
  import {
10
10
  DateTime
11
11
  } from "./chunk-TFCNKBRC.js";
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
12
- import "./chunk-EEG7T6WT.js";
11
+ } from "./chunk-F6D645LF.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
@@ -4,8 +4,8 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-LLWKCA3H.js";
8
- import "./chunk-EEG7T6WT.js";
7
+ } from "./chunk-F6D645LF.js";
8
+ import "./chunk-EGWK6SRQ.js";
9
9
  import "./chunk-TFCNKBRC.js";
10
10
  import "./chunk-U73SABXK.js";
11
11
 
@@ -4,12 +4,12 @@ import {
4
4
  } from "./chunk-JCMWDZYY.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-LLWKCA3H.js";
7
+ } from "./chunk-F6D645LF.js";
8
8
  import {
9
9
  AuthCorruptedError,
10
10
  AuthExpiredError,
11
11
  AuthNotLoggedInError
12
- } from "./chunk-EEG7T6WT.js";
12
+ } from "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  PRESETS
3
- } from "./chunk-AGXMZFUU.js";
3
+ } from "./chunk-XIHOCIYM.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-LLWKCA3H.js";
10
- import "./chunk-EEG7T6WT.js";
9
+ import "./chunk-F6D645LF.js";
10
+ import "./chunk-EGWK6SRQ.js";
11
11
  import "./chunk-TFCNKBRC.js";
12
12
  import "./chunk-U73SABXK.js";
13
13
 
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
12
- import "./chunk-EEG7T6WT.js";
11
+ } from "./chunk-F6D645LF.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
12
- import "./chunk-EEG7T6WT.js";
11
+ } from "./chunk-F6D645LF.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createApiClient
3
- } from "./chunk-LLWKCA3H.js";
4
- import "./chunk-EEG7T6WT.js";
3
+ } from "./chunk-F6D645LF.js";
4
+ import "./chunk-EGWK6SRQ.js";
5
5
  import "./chunk-TFCNKBRC.js";
6
6
  import "./chunk-U73SABXK.js";
7
7
 
@@ -5,15 +5,16 @@ import {
5
5
  import {
6
6
  formatUserCode,
7
7
  isHeadlessEnv
8
- } from "./chunk-EBJMOX3Q.js";
8
+ } from "./chunk-PZV55KAR.js";
9
9
  import {
10
10
  fetchUserEmail,
11
11
  getCredentials,
12
+ hasApiKeyEnv,
12
13
  isLoggedIn,
13
14
  pollForToken,
14
15
  requestDeviceCode,
15
16
  storeCredentials
16
- } from "./chunk-EEG7T6WT.js";
17
+ } from "./chunk-EGWK6SRQ.js";
17
18
  import "./chunk-TFCNKBRC.js";
18
19
  import "./chunk-U73SABXK.js";
19
20
 
@@ -26,6 +27,14 @@ function Login() {
26
27
  const { exit } = useApp();
27
28
  const [state, setState] = useState({ phase: "checking" });
28
29
  useEffect(() => {
30
+ if (hasApiKeyEnv()) {
31
+ setState({
32
+ phase: "already-logged-in",
33
+ email: "(authenticated via CHAINPATROL_API_KEY)"
34
+ });
35
+ setTimeout(() => exit(), 100);
36
+ return;
37
+ }
29
38
  if (isLoggedIn()) {
30
39
  const creds = getCredentials();
31
40
  if (creds.email) {
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  isHeadlessEnv,
3
3
  runLoginFlow
4
- } from "./chunk-EBJMOX3Q.js";
5
- import "./chunk-EEG7T6WT.js";
4
+ } from "./chunk-PZV55KAR.js";
5
+ import "./chunk-EGWK6SRQ.js";
6
6
  import "./chunk-TFCNKBRC.js";
7
7
  import "./chunk-U73SABXK.js";
8
8
 
@@ -2,8 +2,8 @@ import {
2
2
  formatUserCode,
3
3
  isHeadlessEnv,
4
4
  runLoginFlow
5
- } from "./chunk-EBJMOX3Q.js";
6
- import "./chunk-EEG7T6WT.js";
5
+ } from "./chunk-PZV55KAR.js";
6
+ import "./chunk-EGWK6SRQ.js";
7
7
  import "./chunk-TFCNKBRC.js";
8
8
  import "./chunk-U73SABXK.js";
9
9
 
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  clearCredentials,
3
+ hasApiKeyEnv,
3
4
  isLoggedIn
4
- } from "./chunk-EEG7T6WT.js";
5
+ } from "./chunk-EGWK6SRQ.js";
5
6
  import "./chunk-U73SABXK.js";
6
7
 
7
8
  // src/commands/logout.tsx
@@ -9,6 +10,14 @@ import { Text, useApp } from "ink";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
10
11
  function Logout() {
11
12
  const { exit } = useApp();
13
+ if (hasApiKeyEnv()) {
14
+ setTimeout(() => exit(), 100);
15
+ return /* @__PURE__ */ jsxs(Text, { children: [
16
+ "Authenticated via ",
17
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "CHAINPATROL_API_KEY" }),
18
+ "; unset the env var to log out."
19
+ ] });
20
+ }
12
21
  if (!isLoggedIn()) {
13
22
  setTimeout(() => exit(), 100);
14
23
  return /* @__PURE__ */ jsx(Text, { children: "Not currently logged in." });
@@ -1,11 +1,21 @@
1
1
  import {
2
2
  clearCredentials,
3
+ hasApiKeyEnv,
3
4
  isLoggedIn
4
- } from "./chunk-EEG7T6WT.js";
5
+ } from "./chunk-EGWK6SRQ.js";
5
6
  import "./chunk-U73SABXK.js";
6
7
 
7
8
  // src/commands/logout-json.ts
8
9
  async function logoutJson() {
10
+ if (hasApiKeyEnv()) {
11
+ console.log(
12
+ JSON.stringify({
13
+ status: "api_key_env_active",
14
+ message: "Authenticated via CHAINPATROL_API_KEY; unset the env var to log out."
15
+ })
16
+ );
17
+ return;
18
+ }
9
19
  if (!isLoggedIn()) {
10
20
  console.log(JSON.stringify({ status: "not_logged_in" }));
11
21
  return;
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  getPresetDefinition,
3
3
  runPreset
4
- } from "./chunk-AGXMZFUU.js";
4
+ } from "./chunk-XIHOCIYM.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-LLWKCA3H.js";
11
- import "./chunk-EEG7T6WT.js";
10
+ import "./chunk-F6D645LF.js";
11
+ import "./chunk-EGWK6SRQ.js";
12
12
  import "./chunk-TFCNKBRC.js";
13
13
  import "./chunk-U73SABXK.js";
14
14
 
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
12
- import "./chunk-EEG7T6WT.js";
11
+ } from "./chunk-F6D645LF.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
12
- import "./chunk-EEG7T6WT.js";
11
+ } from "./chunk-F6D645LF.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
12
- import "./chunk-EEG7T6WT.js";
11
+ } from "./chunk-F6D645LF.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
@@ -4,8 +4,8 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-LLWKCA3H.js";
8
- import "./chunk-EEG7T6WT.js";
7
+ } from "./chunk-F6D645LF.js";
8
+ import "./chunk-EGWK6SRQ.js";
9
9
  import "./chunk-TFCNKBRC.js";
10
10
  import "./chunk-U73SABXK.js";
11
11
 
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-LLWKCA3H.js";
12
- import "./chunk-EEG7T6WT.js";
11
+ } from "./chunk-F6D645LF.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
15
15
 
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.7.0",
5
+ "version": "0.8.0",
6
6
  "license": "UNLICENSED",
7
7
  "homepage": "https://chainpatrol.com/docs/cli",
8
8
  "keywords": [