@aexol/spectral 0.9.228 → 0.9.230

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.
@@ -1 +1 @@
1
- {"version":3,"file":"auth-helper.d.ts","sourceRoot":"","sources":["../src/auth-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAOrB,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY;IACvB,4DAA4D;;IAE5D,6EAA6E;;IAE7E,2DAA2D;;IAE3D,uCAAuC;;CAE/B,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AA8F3E;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,GAAE,MAAyB,EACpC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,WAAW,CAAC,CAmEtB;AAMD,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAUjD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAgErE"}
1
+ {"version":3,"file":"auth-helper.d.ts","sourceRoot":"","sources":["../src/auth-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAOrB,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY;IACvB,4DAA4D;;IAE5D,6EAA6E;;IAE7E,2DAA2D;;IAE3D,uCAAuC;;CAE/B,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AA8F3E;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,GAAE,MAAyB,EACpC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,WAAW,CAAC,CAmEtB;AAMD,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAUjD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAuErE"}
@@ -208,15 +208,21 @@ export async function ensureAuthenticated() {
208
208
  }
209
209
  const existingCfg = await readConfig();
210
210
  const apiUrl = existingCfg?.apiUrl ?? process.env.SPECTRAL_MCP_URL ?? DEFAULT_API_URL;
211
- const token = existingCfg?.teamApiKey || existingCfg?.userJwt || "";
211
+ // Chain: team key, then user key, then the OAuth JWT.
212
+ const token = existingCfg?.teamApiKey || existingCfg?.userApiKey || existingCfg?.userJwt || "";
212
213
  // If we have a token, verify it still works
213
214
  if (token) {
214
- // If the stored user JWT is locally known to be expired, skip the network roundtrip
215
- if (existingCfg?.userJwt && isJwtExpired(existingCfg.userJwt)) {
216
- // userJwt expired — if we have a teamApiKey, try that before re-auth
217
- if (existingCfg?.teamApiKey) {
215
+ // The stored user JWT is locally known to be expired and it is the token
216
+ // we'd use (no team/user API key ahead of it in the chain) — skip the
217
+ // network roundtrip for the JWT itself, but try the API-key fallbacks
218
+ // before triggering the OAuth browser flow.
219
+ const tokenIsExpiredUserJwt = token === existingCfg?.userJwt && isJwtExpired(existingCfg.userJwt);
220
+ if (tokenIsExpiredUserJwt) {
221
+ // userJwt expired — if we have an API key, try that before re-auth
222
+ const fallbackToken = existingCfg?.teamApiKey ?? existingCfg?.userApiKey;
223
+ if (fallbackToken) {
218
224
  try {
219
- const client = new AexolMcpClient(apiUrl, existingCfg.teamApiKey);
225
+ const client = new AexolMcpClient(apiUrl, fallbackToken);
220
226
  await client.listTools();
221
227
  return { ok: true, config: existingCfg };
222
228
  }
@@ -225,10 +231,10 @@ export async function ensureAuthenticated() {
225
231
  const msg = err instanceof Error ? err.message : String(err);
226
232
  return { ok: false, config: existingCfg, reason: `Backend unreachable: ${msg}` };
227
233
  }
228
- // teamApiKey also failed — fall through to OAuth
234
+ // API key also failed — fall through to OAuth
229
235
  }
230
236
  }
231
- // no teamApiKey — fall through to OAuth
237
+ // no API key — fall through to OAuth
232
238
  }
233
239
  else {
234
240
  try {
@@ -2,10 +2,12 @@
2
2
  * `spectral login` — interactive authentication against the Aexol MCP backend.
3
3
  *
4
4
  * Flow:
5
- * 1. Choose auth method: Team API key or OAuth (browser).
6
- * 2a. API key: prompt for team API key (masked input). Verify the
7
- * sk-aexol-team- prefix locally so we don't send obviously-wrong
8
- * credentials. The API URL is taken from env or the hard default.
5
+ * 1. Choose auth method: Team API key, User API key, or OAuth (browser).
6
+ * 2a. API keys: prompt for the key (masked input). Verify the
7
+ * sk-aexol-team- / sk-aexol-user- prefix locally so we don't send
8
+ * obviously-wrong credentials. The API URL is taken from env or the
9
+ * hard default. A user key (sk-aexol-user-) is pinned to a team but
10
+ * owned by a single user — machines registered with it are PRIVATE.
9
11
  * 2b. OAuth: open browser for Aexol Studio authorization.
10
12
  * 3. Verify reachability + auth by calling tools/list against the URL.
11
13
  * 4. On success: persist to ~/.spectral/config.json (mode 0600).
@@ -19,6 +21,12 @@
19
21
  */
20
22
  export interface PerformLoginOptions {
21
23
  apiUrl: string;
24
+ /**
25
+ * API key to verify. Accepts both the team prefix ("sk-aexol-team-") and
26
+ * the user prefix ("sk-aexol-user-"). The key kind determines how it is
27
+ * persisted: a team key sets `teamApiKey` (clearing any stale `userApiKey`),
28
+ * a user key sets `userApiKey`.
29
+ */
22
30
  teamApiKey: string;
23
31
  }
24
32
  export interface PerformLoginResult {
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAiBH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAqCzF;AAED,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAqF9C"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAoBH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoDzF;AAED,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAyF9C"}
@@ -2,10 +2,12 @@
2
2
  * `spectral login` — interactive authentication against the Aexol MCP backend.
3
3
  *
4
4
  * Flow:
5
- * 1. Choose auth method: Team API key or OAuth (browser).
6
- * 2a. API key: prompt for team API key (masked input). Verify the
7
- * sk-aexol-team- prefix locally so we don't send obviously-wrong
8
- * credentials. The API URL is taken from env or the hard default.
5
+ * 1. Choose auth method: Team API key, User API key, or OAuth (browser).
6
+ * 2a. API keys: prompt for the key (masked input). Verify the
7
+ * sk-aexol-team- / sk-aexol-user- prefix locally so we don't send
8
+ * obviously-wrong credentials. The API URL is taken from env or the
9
+ * hard default. A user key (sk-aexol-user-) is pinned to a team but
10
+ * owned by a single user — machines registered with it are PRIVATE.
9
11
  * 2b. OAuth: open browser for Aexol Studio authorization.
10
12
  * 3. Verify reachability + auth by calling tools/list against the URL.
11
13
  * 4. On success: persist to ~/.spectral/config.json (mode 0600).
@@ -19,7 +21,7 @@
19
21
  */
20
22
  import { password, select } from "@inquirer/prompts";
21
23
  import pc from "picocolors";
22
- import { TEAM_API_KEY_PREFIX, getApiUrl, getConfigFile, validateTeamApiKey, writeConfig, } from "../config.js";
24
+ import { TEAM_API_KEY_PREFIX, USER_API_KEY_PREFIX, getApiUrl, getConfigFile, readConfig, validateTeamApiKey, validateUserApiKey, writeConfig, } from "../config.js";
23
25
  import { AexolMcpClient, AexolMcpError } from "../mcp-client.js";
24
26
  import { runOAuthFlow, OAUTH_REASON } from "../auth-helper.js";
25
27
  /**
@@ -37,8 +39,10 @@ export async function performLogin(opts) {
37
39
  if (!apiUrl) {
38
40
  throw new Error("API URL is required");
39
41
  }
40
- if (!validateTeamApiKey(teamApiKey)) {
41
- throw new Error(`Invalid API key prefix: token must start with "${TEAM_API_KEY_PREFIX}"`);
42
+ const isTeamKey = validateTeamApiKey(teamApiKey);
43
+ const isUserKey = validateUserApiKey(teamApiKey);
44
+ if (!isTeamKey && !isUserKey) {
45
+ throw new Error(`Invalid API key prefix: token must start with "${TEAM_API_KEY_PREFIX}" or "${USER_API_KEY_PREFIX}"`);
42
46
  }
43
47
  const client = new AexolMcpClient(apiUrl, teamApiKey);
44
48
  let toolCount;
@@ -59,7 +63,20 @@ export async function performLogin(opts) {
59
63
  const msg = err instanceof Error ? err.message : String(err);
60
64
  throw new Error(`Could not reach ${apiUrl}: ${msg}`);
61
65
  }
62
- const cfg = { apiUrl, teamApiKey };
66
+ // Preserve credentials we didn't just verify — most importantly the user JWT
67
+ // from a previous OAuth login (previously overwritten here, silently dropping
68
+ // Studio auth). A team-key login clears any stale userApiKey so the explicit
69
+ // choice of team auth isn't later overridden by registration priority; a
70
+ // user-key login keeps the team key (both stay valid for the team).
71
+ const existing = await readConfig();
72
+ const cfg = isTeamKey
73
+ ? { apiUrl, teamApiKey, userJwt: existing?.userJwt }
74
+ : {
75
+ apiUrl,
76
+ teamApiKey: existing?.teamApiKey ?? "",
77
+ userApiKey: teamApiKey,
78
+ userJwt: existing?.userJwt,
79
+ };
63
80
  await writeConfig(cfg);
64
81
  return { toolCount };
65
82
  }
@@ -73,6 +90,7 @@ export async function runLogin() {
73
90
  message: "How would you like to authenticate?",
74
91
  choices: [
75
92
  { name: "Team API key", value: "apikey" },
93
+ { name: "User API key", value: "userkey" },
76
94
  { name: "OAuth (browser)", value: "oauth" },
77
95
  ],
78
96
  });
@@ -90,19 +108,22 @@ export async function runLogin() {
90
108
  await runLoginOAuth();
91
109
  return;
92
110
  }
93
- // Team API key flow: no URL prompt — use env or default.
111
+ // API key flow: no URL prompt — use env or default.
94
112
  const apiUrl = getApiUrl();
95
- let teamApiKey;
113
+ const isUserKey = authMethod === "userkey";
114
+ const keyPrefix = isUserKey ? USER_API_KEY_PREFIX : TEAM_API_KEY_PREFIX;
115
+ let apiKey;
96
116
  try {
97
- teamApiKey = (await password({
98
- message: `Team API key (starts with "${TEAM_API_KEY_PREFIX}")`,
117
+ apiKey = (await password({
118
+ message: `${isUserKey ? "User" : "Team"} API key (starts with "${keyPrefix}")`,
99
119
  mask: "*",
100
120
  validate: (v) => {
101
121
  const trimmed = v.trim();
102
122
  if (trimmed.length === 0)
103
123
  return "Token is required";
104
- if (!validateTeamApiKey(trimmed)) {
105
- return `Token must start with "${TEAM_API_KEY_PREFIX}"`;
124
+ const valid = isUserKey ? validateUserApiKey(trimmed) : validateTeamApiKey(trimmed);
125
+ if (!valid) {
126
+ return `Token must start with "${keyPrefix}"`;
106
127
  }
107
128
  return true;
108
129
  },
@@ -119,7 +140,7 @@ export async function runLogin() {
119
140
  process.stdout.write(pc.dim(`\nVerifying credentials against ${apiUrl} ...\n`));
120
141
  let result;
121
142
  try {
122
- result = await performLogin({ apiUrl, teamApiKey });
143
+ result = await performLogin({ apiUrl, teamApiKey: apiKey });
123
144
  }
124
145
  catch (err) {
125
146
  const msg = err instanceof Error ? err.message : String(err);
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAwBH,OAAO,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AAYlE,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAarE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAazD;AAED,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA6B9D;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uCAAuC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,KAAK,EAAE,YAAY,CAAC;IACpB,wDAAwD;IACxD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,EAAE,WAAW,CAAC;IACnB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CA4kBlF;AAmFD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAc5E"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAwBH,OAAO,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AAYlE,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAarE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAazD;AAED,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA6B9D;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uCAAuC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,KAAK,EAAE,YAAY,CAAC;IACpB,wDAAwD;IACxD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,EAAE,WAAW,CAAC;IACnB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CA+kBlF;AAmFD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAc5E"}
@@ -172,6 +172,7 @@ export async function runServe(opts = {}) {
172
172
  registration = await ensureMachineRegistered({
173
173
  backendUrl,
174
174
  apiKey: cfg.teamApiKey,
175
+ userApiKey: cfg.userApiKey,
175
176
  userJwt: cfg.userJwt,
176
177
  machineNameOverride: opts.machineName,
177
178
  version,
@@ -213,6 +214,7 @@ export async function runServe(opts = {}) {
213
214
  const newReg = await ensureMachineRegistered({
214
215
  backendUrl,
215
216
  apiKey: cfg.teamApiKey,
217
+ userApiKey: cfg.userApiKey,
216
218
  userJwt: cfg.userJwt,
217
219
  machineNameOverride: opts.machineName,
218
220
  version,
@@ -476,6 +478,7 @@ export async function runServe(opts = {}) {
476
478
  const newReg = await ensureMachineRegistered({
477
479
  backendUrl,
478
480
  apiKey: cfg.teamApiKey,
481
+ userApiKey: cfg.userApiKey,
479
482
  userJwt: cfg.userJwt,
480
483
  machineNameOverride: opts.machineName,
481
484
  version,
package/dist/config.d.ts CHANGED
@@ -12,9 +12,22 @@
12
12
  */
13
13
  export declare const DEFAULT_API_URL = "https://api.aexol.ai/mcp";
14
14
  export declare const TEAM_API_KEY_PREFIX = "sk-aexol-team-";
15
+ export declare const USER_API_KEY_PREFIX = "sk-aexol-user-";
15
16
  export interface SpectralConfig {
16
17
  apiUrl: string;
18
+ /**
19
+ * Team API key ("sk-aexol-team-"). Normalized to "" when absent — e.g. an
20
+ * OAuth-only login stores no team key. At least one of `teamApiKey`,
21
+ * `userApiKey`, or `userJwt` must be present for the config to be valid.
22
+ */
17
23
  teamApiKey: string;
24
+ /**
25
+ * User API key ("sk-aexol-user-"), pinned to a team but owned by a single
26
+ * user. Machines registered with it are PRIVATE with `ownerId` derived from
27
+ * the key. Takes priority over `teamApiKey` for machine registration
28
+ * (see `relay/registration.ts`).
29
+ */
30
+ userApiKey?: string;
18
31
  /** User JWT from OAuth login. When present, used for machine registration (owns the machine). */
19
32
  userJwt?: string;
20
33
  }
@@ -40,6 +53,8 @@ export declare const CONFIG_FILE: string;
40
53
  export declare function getApiUrl(stored?: string): string;
41
54
  /** Validate the team API key prefix. The full token check happens server-side. */
42
55
  export declare function validateTeamApiKey(key: unknown): key is string;
56
+ /** Validate the user API key prefix. The full token check happens server-side. */
57
+ export declare function validateUserApiKey(key: unknown): key is string;
43
58
  /** Read config; returns null if missing or malformed. Never throws. */
44
59
  export declare function readConfig(): Promise<SpectralConfig | null>;
45
60
  /** Persist config with restrictive permissions (dir 0700, file 0600). */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,QAAiB,CAAC;AACzC,eAAO,MAAM,WAAW,QAAkB,CAAC;AAE3C,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAE9D;AAED,uEAAuE;AACvE,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA2BjE;AAED,yEAAyE;AACzE,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpE;AAED,+FAA+F;AAC/F,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CASrD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,QAAiB,CAAC;AACzC,eAAO,MAAM,WAAW,QAAkB,CAAC;AAE3C,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAE9D;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAE9D;AAED,uEAAuE;AACvE,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAgCjE;AAED,yEAAyE;AACzE,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpE;AAED,+FAA+F;AAC/F,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CASrD"}
package/dist/config.js CHANGED
@@ -15,6 +15,7 @@ import { homedir } from "node:os";
15
15
  import { dirname, join } from "node:path";
16
16
  export const DEFAULT_API_URL = "https://api.aexol.ai/mcp";
17
17
  export const TEAM_API_KEY_PREFIX = "sk-aexol-team-";
18
+ export const USER_API_KEY_PREFIX = "sk-aexol-user-";
18
19
  /**
19
20
  * Resolve the directory used to store Spectral configuration.
20
21
  *
@@ -45,6 +46,10 @@ export function getApiUrl(stored) {
45
46
  export function validateTeamApiKey(key) {
46
47
  return typeof key === "string" && key.startsWith(TEAM_API_KEY_PREFIX);
47
48
  }
49
+ /** Validate the user API key prefix. The full token check happens server-side. */
50
+ export function validateUserApiKey(key) {
51
+ return typeof key === "string" && key.startsWith(USER_API_KEY_PREFIX);
52
+ }
48
53
  /** Read config; returns null if missing or malformed. Never throws. */
49
54
  export async function readConfig() {
50
55
  let raw;
@@ -64,11 +69,15 @@ export async function readConfig() {
64
69
  const userJwt = typeof parsed.userJwt === "string" && parsed.userJwt.length > 0
65
70
  ? parsed.userJwt
66
71
  : undefined;
67
- if (!teamApiKey && !userJwt)
72
+ const userApiKey = typeof parsed.userApiKey === "string" && parsed.userApiKey.length > 0
73
+ ? parsed.userApiKey
74
+ : undefined;
75
+ if (!teamApiKey && !userApiKey && !userJwt)
68
76
  return null;
69
77
  return {
70
78
  apiUrl: parsed.apiUrl,
71
79
  teamApiKey,
80
+ userApiKey,
72
81
  userJwt,
73
82
  };
74
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../../src/generated/zeus/const.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAC,GAAG,CAwyB5C,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAC,GAAG,CA0lC1C,CAAA;AAED,eAAO,MAAM,GAAG;;;;CAIf,CAAA"}
1
+ {"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../../src/generated/zeus/const.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAC,GAAG,CA0zB5C,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAC,GAAG,CAumC1C,CAAA;AAED,eAAO,MAAM,GAAG;;;;CAIf,CAAA"}
@@ -4,6 +4,7 @@ export const AllTypesProps = {
4
4
  TeamRole: "enum",
5
5
  TeamUsageTaskType: "enum",
6
6
  CreateTeamApiKeyInput: {},
7
+ CreateUserApiKeyInput: {},
7
8
  TeamInviteStatus: "enum",
8
9
  CreateReferralCampaignInput: {
9
10
  expiresAt: "DateTime"
@@ -103,6 +104,7 @@ export const AllTypesProps = {
103
104
  filter: "TeamUsageFilterInput"
104
105
  },
105
106
  teamApiKeys: {},
107
+ myApiKeys: {},
106
108
  teamInvites: {},
107
109
  validateTeamInvite: {},
108
110
  teamReferralCampaigns: {},
@@ -260,6 +262,11 @@ export const AllTypesProps = {
260
262
  },
261
263
  revokeTeamApiKey: {},
262
264
  regenerateTeamApiKey: {},
265
+ createUserApiKey: {
266
+ input: "CreateUserApiKeyInput"
267
+ },
268
+ revokeUserApiKey: {},
269
+ regenerateUserApiKey: {},
263
270
  createTeamMcpServer: {
264
271
  input: "CreateTeamMcpServerInput"
265
272
  },
@@ -315,6 +322,7 @@ export const AllTypesProps = {
315
322
  input: "UpdateAgentInput"
316
323
  },
317
324
  deleteAgent: {},
325
+ duplicateAgent: {},
318
326
  refineFromTask: {
319
327
  input: "RefineFromTaskInput"
320
328
  },
@@ -536,6 +544,14 @@ export const ReturnTypes = {
536
544
  lastUsedAt: "DateTime",
537
545
  createdAt: "DateTime"
538
546
  },
547
+ UserApiKey: {
548
+ id: "ID",
549
+ name: "String",
550
+ apiKey: "String",
551
+ teamId: "ID",
552
+ lastUsedAt: "DateTime",
553
+ createdAt: "DateTime"
554
+ },
539
555
  TeamInvite: {
540
556
  id: "ID",
541
557
  teamId: "ID",
@@ -947,6 +963,7 @@ export const ReturnTypes = {
947
963
  team: "Team",
948
964
  teamUsage: "TeamUsage",
949
965
  teamApiKeys: "TeamApiKey",
966
+ myApiKeys: "UserApiKey",
950
967
  teamInvites: "TeamInvite",
951
968
  validateTeamInvite: "TeamInviteValidation",
952
969
  teamReferralCampaigns: "ReferralCampaign",
@@ -1052,6 +1069,9 @@ export const ReturnTypes = {
1052
1069
  createTeamApiKey: "TeamApiKey",
1053
1070
  revokeTeamApiKey: "Boolean",
1054
1071
  regenerateTeamApiKey: "TeamApiKey",
1072
+ createUserApiKey: "UserApiKey",
1073
+ revokeUserApiKey: "Boolean",
1074
+ regenerateUserApiKey: "UserApiKey",
1055
1075
  createTeamMcpServer: "TeamMcpServer",
1056
1076
  updateTeamMcpServer: "TeamMcpServer",
1057
1077
  deleteTeamMcpServer: "Boolean",
@@ -1079,6 +1099,7 @@ export const ReturnTypes = {
1079
1099
  createAgent: "Agent",
1080
1100
  updateAgent: "Agent",
1081
1101
  deleteAgent: "Boolean",
1102
+ duplicateAgent: "Agent",
1082
1103
  refineFromTask: "FromTask",
1083
1104
  refineAexolContent: "FromTask",
1084
1105
  evaluatePromptQuality: "PromptQualityResult",
@@ -340,6 +340,20 @@ export type ValueTypes = {
340
340
  teamId: ValueTypes["ID"] | Variable<any, string>;
341
341
  name: string | Variable<any, string>;
342
342
  };
343
+ ["UserApiKey"]: AliasType<{
344
+ id?: boolean | `@${string}`;
345
+ name?: boolean | `@${string}`;
346
+ apiKey?: boolean | `@${string}`;
347
+ teamId?: boolean | `@${string}`;
348
+ lastUsedAt?: boolean | `@${string}`;
349
+ createdAt?: boolean | `@${string}`;
350
+ __typename?: boolean | `@${string}`;
351
+ ['...on UserApiKey']?: Omit<ValueTypes["UserApiKey"], "...on UserApiKey">;
352
+ }>;
353
+ ["CreateUserApiKeyInput"]: {
354
+ teamId: ValueTypes["ID"] | Variable<any, string>;
355
+ name: string | Variable<any, string>;
356
+ };
343
357
  ["TeamInvite"]: AliasType<{
344
358
  id?: boolean | `@${string}`;
345
359
  teamId?: boolean | `@${string}`;
@@ -1101,6 +1115,9 @@ export type ValueTypes = {
1101
1115
  teamApiKeys?: [{
1102
1116
  teamId: ValueTypes["ID"] | Variable<any, string>;
1103
1117
  }, ValueTypes["TeamApiKey"]];
1118
+ myApiKeys?: [{
1119
+ teamId?: ValueTypes["ID"] | undefined | null | Variable<any, string>;
1120
+ }, ValueTypes["UserApiKey"]];
1104
1121
  teamInvites?: [{
1105
1122
  teamId: ValueTypes["ID"] | Variable<any, string>;
1106
1123
  }, ValueTypes["TeamInvite"]];
@@ -1480,6 +1497,15 @@ export type ValueTypes = {
1480
1497
  regenerateTeamApiKey?: [{
1481
1498
  id: ValueTypes["ID"] | Variable<any, string>;
1482
1499
  }, ValueTypes["TeamApiKey"]];
1500
+ createUserApiKey?: [{
1501
+ input: ValueTypes["CreateUserApiKeyInput"] | Variable<any, string>;
1502
+ }, ValueTypes["UserApiKey"]];
1503
+ revokeUserApiKey?: [{
1504
+ id: ValueTypes["ID"] | Variable<any, string>;
1505
+ }, boolean | `@${string}`];
1506
+ regenerateUserApiKey?: [{
1507
+ id: ValueTypes["ID"] | Variable<any, string>;
1508
+ }, ValueTypes["UserApiKey"]];
1483
1509
  createTeamMcpServer?: [{
1484
1510
  input: ValueTypes["CreateTeamMcpServerInput"] | Variable<any, string>;
1485
1511
  }, ValueTypes["TeamMcpServer"]];
@@ -1581,6 +1607,11 @@ export type ValueTypes = {
1581
1607
  id: ValueTypes["ID"] | Variable<any, string>;
1582
1608
  teamId: ValueTypes["ID"] | Variable<any, string>;
1583
1609
  }, boolean | `@${string}`];
1610
+ duplicateAgent?: [{
1611
+ id: ValueTypes["ID"] | Variable<any, string>;
1612
+ teamId: ValueTypes["ID"] | Variable<any, string>;
1613
+ name?: string | undefined | null | Variable<any, string>;
1614
+ }, ValueTypes["Agent"]];
1584
1615
  refineFromTask?: [{
1585
1616
  input: ValueTypes["RefineFromTaskInput"] | Variable<any, string>;
1586
1617
  }, ValueTypes["FromTask"]];
@@ -2654,6 +2685,19 @@ export type ResolverInputTypes = {
2654
2685
  teamId: ResolverInputTypes["ID"];
2655
2686
  name: string;
2656
2687
  };
2688
+ ["UserApiKey"]: AliasType<{
2689
+ id?: boolean | `@${string}`;
2690
+ name?: boolean | `@${string}`;
2691
+ apiKey?: boolean | `@${string}`;
2692
+ teamId?: boolean | `@${string}`;
2693
+ lastUsedAt?: boolean | `@${string}`;
2694
+ createdAt?: boolean | `@${string}`;
2695
+ __typename?: boolean | `@${string}`;
2696
+ }>;
2697
+ ["CreateUserApiKeyInput"]: {
2698
+ teamId: ResolverInputTypes["ID"];
2699
+ name: string;
2700
+ };
2657
2701
  ["TeamInvite"]: AliasType<{
2658
2702
  id?: boolean | `@${string}`;
2659
2703
  teamId?: boolean | `@${string}`;
@@ -3369,6 +3413,9 @@ export type ResolverInputTypes = {
3369
3413
  teamApiKeys?: [{
3370
3414
  teamId: ResolverInputTypes["ID"];
3371
3415
  }, ResolverInputTypes["TeamApiKey"]];
3416
+ myApiKeys?: [{
3417
+ teamId?: ResolverInputTypes["ID"] | undefined | null;
3418
+ }, ResolverInputTypes["UserApiKey"]];
3372
3419
  teamInvites?: [{
3373
3420
  teamId: ResolverInputTypes["ID"];
3374
3421
  }, ResolverInputTypes["TeamInvite"]];
@@ -3747,6 +3794,15 @@ export type ResolverInputTypes = {
3747
3794
  regenerateTeamApiKey?: [{
3748
3795
  id: ResolverInputTypes["ID"];
3749
3796
  }, ResolverInputTypes["TeamApiKey"]];
3797
+ createUserApiKey?: [{
3798
+ input: ResolverInputTypes["CreateUserApiKeyInput"];
3799
+ }, ResolverInputTypes["UserApiKey"]];
3800
+ revokeUserApiKey?: [{
3801
+ id: ResolverInputTypes["ID"];
3802
+ }, boolean | `@${string}`];
3803
+ regenerateUserApiKey?: [{
3804
+ id: ResolverInputTypes["ID"];
3805
+ }, ResolverInputTypes["UserApiKey"]];
3750
3806
  createTeamMcpServer?: [{
3751
3807
  input: ResolverInputTypes["CreateTeamMcpServerInput"];
3752
3808
  }, ResolverInputTypes["TeamMcpServer"]];
@@ -3848,6 +3904,11 @@ export type ResolverInputTypes = {
3848
3904
  id: ResolverInputTypes["ID"];
3849
3905
  teamId: ResolverInputTypes["ID"];
3850
3906
  }, boolean | `@${string}`];
3907
+ duplicateAgent?: [{
3908
+ id: ResolverInputTypes["ID"];
3909
+ teamId: ResolverInputTypes["ID"];
3910
+ name?: string | undefined | null;
3911
+ }, ResolverInputTypes["Agent"]];
3851
3912
  refineFromTask?: [{
3852
3913
  input: ResolverInputTypes["RefineFromTaskInput"];
3853
3914
  }, ResolverInputTypes["FromTask"]];
@@ -4881,6 +4942,18 @@ export type ModelTypes = {
4881
4942
  teamId: ModelTypes["ID"];
4882
4943
  name: string;
4883
4944
  };
4945
+ ["UserApiKey"]: {
4946
+ id: ModelTypes["ID"];
4947
+ name: string;
4948
+ apiKey: string;
4949
+ teamId: ModelTypes["ID"];
4950
+ lastUsedAt?: ModelTypes["DateTime"] | undefined | null;
4951
+ createdAt: ModelTypes["DateTime"];
4952
+ };
4953
+ ["CreateUserApiKeyInput"]: {
4954
+ teamId: ModelTypes["ID"];
4955
+ name: string;
4956
+ };
4884
4957
  ["TeamInvite"]: {
4885
4958
  id: ModelTypes["ID"];
4886
4959
  teamId: ModelTypes["ID"];
@@ -5540,6 +5613,7 @@ export type ModelTypes = {
5540
5613
  team?: ModelTypes["Team"] | undefined | null;
5541
5614
  teamUsage: ModelTypes["TeamUsage"];
5542
5615
  teamApiKeys: Array<ModelTypes["TeamApiKey"]>;
5616
+ myApiKeys: Array<ModelTypes["UserApiKey"]>;
5543
5617
  teamInvites: Array<ModelTypes["TeamInvite"]>;
5544
5618
  validateTeamInvite: ModelTypes["TeamInviteValidation"];
5545
5619
  teamReferralCampaigns: Array<ModelTypes["ReferralCampaign"]>;
@@ -5645,6 +5719,9 @@ export type ModelTypes = {
5645
5719
  createTeamApiKey: ModelTypes["TeamApiKey"];
5646
5720
  revokeTeamApiKey: boolean;
5647
5721
  regenerateTeamApiKey: ModelTypes["TeamApiKey"];
5722
+ createUserApiKey: ModelTypes["UserApiKey"];
5723
+ revokeUserApiKey: boolean;
5724
+ regenerateUserApiKey: ModelTypes["UserApiKey"];
5648
5725
  createTeamMcpServer: ModelTypes["TeamMcpServer"];
5649
5726
  updateTeamMcpServer: ModelTypes["TeamMcpServer"];
5650
5727
  deleteTeamMcpServer: boolean;
@@ -5672,6 +5749,7 @@ export type ModelTypes = {
5672
5749
  createAgent: ModelTypes["Agent"];
5673
5750
  updateAgent: ModelTypes["Agent"];
5674
5751
  deleteAgent: boolean;
5752
+ duplicateAgent: ModelTypes["Agent"];
5675
5753
  refineFromTask: ModelTypes["FromTask"];
5676
5754
  refineAexolContent: ModelTypes["FromTask"];
5677
5755
  evaluatePromptQuality: ModelTypes["PromptQualityResult"];
@@ -6464,6 +6542,20 @@ export type GraphQLTypes = {
6464
6542
  teamId: GraphQLTypes["ID"];
6465
6543
  name: string;
6466
6544
  };
6545
+ ["UserApiKey"]: {
6546
+ __typename: "UserApiKey";
6547
+ id: GraphQLTypes["ID"];
6548
+ name: string;
6549
+ apiKey: string;
6550
+ teamId: GraphQLTypes["ID"];
6551
+ lastUsedAt?: GraphQLTypes["DateTime"] | undefined | null;
6552
+ createdAt: GraphQLTypes["DateTime"];
6553
+ ['...on UserApiKey']: Omit<GraphQLTypes["UserApiKey"], "...on UserApiKey">;
6554
+ };
6555
+ ["CreateUserApiKeyInput"]: {
6556
+ teamId: GraphQLTypes["ID"];
6557
+ name: string;
6558
+ };
6467
6559
  ["TeamInvite"]: {
6468
6560
  __typename: "TeamInvite";
6469
6561
  id: GraphQLTypes["ID"];
@@ -7216,6 +7308,7 @@ export type GraphQLTypes = {
7216
7308
  team?: GraphQLTypes["Team"] | undefined | null;
7217
7309
  teamUsage: GraphQLTypes["TeamUsage"];
7218
7310
  teamApiKeys: Array<GraphQLTypes["TeamApiKey"]>;
7311
+ myApiKeys: Array<GraphQLTypes["UserApiKey"]>;
7219
7312
  teamInvites: Array<GraphQLTypes["TeamInvite"]>;
7220
7313
  validateTeamInvite: GraphQLTypes["TeamInviteValidation"];
7221
7314
  teamReferralCampaigns: Array<GraphQLTypes["ReferralCampaign"]>;
@@ -7323,6 +7416,9 @@ export type GraphQLTypes = {
7323
7416
  createTeamApiKey: GraphQLTypes["TeamApiKey"];
7324
7417
  revokeTeamApiKey: boolean;
7325
7418
  regenerateTeamApiKey: GraphQLTypes["TeamApiKey"];
7419
+ createUserApiKey: GraphQLTypes["UserApiKey"];
7420
+ revokeUserApiKey: boolean;
7421
+ regenerateUserApiKey: GraphQLTypes["UserApiKey"];
7326
7422
  createTeamMcpServer: GraphQLTypes["TeamMcpServer"];
7327
7423
  updateTeamMcpServer: GraphQLTypes["TeamMcpServer"];
7328
7424
  deleteTeamMcpServer: boolean;
@@ -7350,6 +7446,7 @@ export type GraphQLTypes = {
7350
7446
  createAgent: GraphQLTypes["Agent"];
7351
7447
  updateAgent: GraphQLTypes["Agent"];
7352
7448
  deleteAgent: boolean;
7449
+ duplicateAgent: GraphQLTypes["Agent"];
7353
7450
  refineFromTask: GraphQLTypes["FromTask"];
7354
7451
  refineAexolContent: GraphQLTypes["FromTask"];
7355
7452
  evaluatePromptQuality: GraphQLTypes["PromptQualityResult"];
@@ -8312,6 +8409,7 @@ type ZEUS_VARIABLES = {
8312
8409
  ["TeamRole"]: ValueTypes["TeamRole"];
8313
8410
  ["TeamUsageTaskType"]: ValueTypes["TeamUsageTaskType"];
8314
8411
  ["CreateTeamApiKeyInput"]: ValueTypes["CreateTeamApiKeyInput"];
8412
+ ["CreateUserApiKeyInput"]: ValueTypes["CreateUserApiKeyInput"];
8315
8413
  ["TeamInviteStatus"]: ValueTypes["TeamInviteStatus"];
8316
8414
  ["CreateReferralCampaignInput"]: ValueTypes["CreateReferralCampaignInput"];
8317
8415
  ["UpdateReferralCampaignInput"]: ValueTypes["UpdateReferralCampaignInput"];