@primitivedotdev/cli 0.35.0 → 0.36.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.
- package/dist/{cli-config-SktG2dzR.js → cli-config-D7wN_PBc.js} +59 -49
- package/dist/oclif/index.js +1322 -374
- package/dist/oclif/root-signup-hint.js +12 -11
- package/man/primitive.1 +2 -5
- package/package.json +1 -1
|
@@ -620,44 +620,21 @@ const createClient = (config = {}) => {
|
|
|
620
620
|
* `.forward`) still lives in sdk-node because it needs the
|
|
621
621
|
* `ReceivedEmail` type from the webhook parsing surface.
|
|
622
622
|
*/
|
|
623
|
-
const
|
|
624
|
-
const DEFAULT_API_BASE_URL_2 = "https://api.primitive.dev/v1";
|
|
623
|
+
const DEFAULT_API_BASE_URL = "https://api.primitive.dev/v1";
|
|
625
624
|
function createDefaultAuth(apiKey) {
|
|
626
625
|
return (security) => {
|
|
627
626
|
if (security.type === "http" && security.scheme === "bearer") return apiKey;
|
|
628
627
|
};
|
|
629
628
|
}
|
|
630
629
|
var PrimitiveApiClient = class {
|
|
631
|
-
/**
|
|
632
|
-
* Generated client targeting the primary API host (apiBaseUrl1). Use
|
|
633
|
-
* this when passing `client: ...` to a generated operation function
|
|
634
|
-
* for every endpoint EXCEPT attachment-capable message sends. The
|
|
635
|
-
* hand-written PrimitiveClient.send / .reply / .forward methods on
|
|
636
|
-
* the subclass route those sends to the host-2 client internally.
|
|
637
|
-
*/
|
|
638
630
|
client;
|
|
639
|
-
/**
|
|
640
|
-
* @internal Generated client targeting the attachments-supporting
|
|
641
|
-
* send host (apiBaseUrl2). Used by PrimitiveClient.send() and
|
|
642
|
-
* PrimitiveClient.reply() under the hood. Exposed for the CLI's
|
|
643
|
-
* hand-rolled send/reply commands, which call generated operations
|
|
644
|
-
* directly; not part of the publicly-documented SDK surface.
|
|
645
|
-
* Customer code should call .send() / .reply() on the subclass
|
|
646
|
-
* instead.
|
|
647
|
-
*/
|
|
648
|
-
_sendClient;
|
|
649
631
|
constructor(options = {}) {
|
|
650
|
-
const { apiKey, auth,
|
|
632
|
+
const { apiKey, auth, apiBaseUrl = DEFAULT_API_BASE_URL, ...config } = options;
|
|
651
633
|
const resolvedAuth = auth ?? createDefaultAuth(apiKey);
|
|
652
634
|
this.client = createClient(createConfig({
|
|
653
635
|
...config,
|
|
654
636
|
auth: resolvedAuth,
|
|
655
|
-
baseUrl:
|
|
656
|
-
}));
|
|
657
|
-
this._sendClient = createClient(createConfig({
|
|
658
|
-
...config,
|
|
659
|
-
auth: resolvedAuth,
|
|
660
|
-
baseUrl: apiBaseUrl2
|
|
637
|
+
baseUrl: apiBaseUrl
|
|
661
638
|
}));
|
|
662
639
|
}
|
|
663
640
|
getConfig() {
|
|
@@ -849,6 +826,11 @@ function requireString(value, key) {
|
|
|
849
826
|
if (typeof raw !== "string" || raw.trim().length === 0) throw new Error(`Stored Primitive CLI credentials are malformed: ${key} must be a non-empty string. ${MALFORMED_CREDENTIALS_HINT}`);
|
|
850
827
|
return raw;
|
|
851
828
|
}
|
|
829
|
+
function readStoredApiBaseUrl(raw) {
|
|
830
|
+
const value = raw.api_base_url ?? raw.api_base_url_2 ?? raw.api_base_url_1;
|
|
831
|
+
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`Stored Primitive CLI credentials are malformed: api_base_url must be a non-empty string. ${MALFORMED_CREDENTIALS_HINT}`);
|
|
832
|
+
return normalizeApiBaseUrl(value);
|
|
833
|
+
}
|
|
852
834
|
/**
|
|
853
835
|
* Sentinel returned by parseCredentials when the on-disk credentials were
|
|
854
836
|
* written by an API-key-based CLI. The caller treats this as "not logged in"
|
|
@@ -880,7 +862,7 @@ function parseCredentials(raw) {
|
|
|
880
862
|
oauth_client_id: requireString(raw, "oauth_client_id"),
|
|
881
863
|
org_id: requireString(raw, "org_id"),
|
|
882
864
|
org_name: orgName,
|
|
883
|
-
|
|
865
|
+
api_base_url: readStoredApiBaseUrl(raw),
|
|
884
866
|
created_at: requireString(raw, "created_at")
|
|
885
867
|
};
|
|
886
868
|
}
|
|
@@ -895,11 +877,28 @@ function normalize(url, fallback) {
|
|
|
895
877
|
if (!trimmed) return fallback;
|
|
896
878
|
return trimmed.replace(/\/+$/, "");
|
|
897
879
|
}
|
|
898
|
-
function
|
|
899
|
-
|
|
880
|
+
function canonicalizeKnownApiBaseUrl(url) {
|
|
881
|
+
let parsed;
|
|
882
|
+
try {
|
|
883
|
+
parsed = new URL(url);
|
|
884
|
+
} catch {
|
|
885
|
+
return url;
|
|
886
|
+
}
|
|
887
|
+
if (parsed.pathname.replace(/\/+$/, "") !== "/api/v1") return url;
|
|
888
|
+
if (parsed.hostname === "primitive.dev" || parsed.hostname === "www.primitive.dev") {
|
|
889
|
+
parsed.hostname = "api.primitive.dev";
|
|
890
|
+
parsed.pathname = "/v1";
|
|
891
|
+
return parsed.toString().replace(/\/+$/, "");
|
|
892
|
+
}
|
|
893
|
+
if (parsed.hostname === "primitive-staging-1.com") {
|
|
894
|
+
parsed.hostname = "api.primitive-staging-1.com";
|
|
895
|
+
parsed.pathname = "/v1";
|
|
896
|
+
return parsed.toString().replace(/\/+$/, "");
|
|
897
|
+
}
|
|
898
|
+
return url;
|
|
900
899
|
}
|
|
901
|
-
function
|
|
902
|
-
return normalize(url,
|
|
900
|
+
function normalizeApiBaseUrl(url) {
|
|
901
|
+
return canonicalizeKnownApiBaseUrl(normalize(url, DEFAULT_API_BASE_URL));
|
|
903
902
|
}
|
|
904
903
|
function cliAccessTokenExpiresAt(expiresInSeconds, now = Date.now) {
|
|
905
904
|
return new Date(now() + expiresInSeconds * 1e3).toISOString();
|
|
@@ -1091,28 +1090,43 @@ function acquireCliCredentialsLock(configDir, options = {}) {
|
|
|
1091
1090
|
});
|
|
1092
1091
|
};
|
|
1093
1092
|
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Detect the PRIMITIVE_KEY vs PRIMITIVE_API_KEY rename trap.
|
|
1095
|
+
*
|
|
1096
|
+
* AGX feedback: users on older docs (or coming from other tools) set
|
|
1097
|
+
* `PRIMITIVE_KEY` and then cannot figure out why the CLI reports no
|
|
1098
|
+
* API key. The CLI reads `PRIMITIVE_API_KEY` only. Returns a stderr
|
|
1099
|
+
* hint when `PRIMITIVE_KEY` is set but `PRIMITIVE_API_KEY` is not,
|
|
1100
|
+
* otherwise null. Exported as a helper so both `doctor` and the
|
|
1101
|
+
* general auth-resolution path surface the same guidance from the
|
|
1102
|
+
* first command the user runs, instead of forcing them to discover
|
|
1103
|
+
* the rename via `doctor` after the fact.
|
|
1104
|
+
*/
|
|
1105
|
+
function detectPrimitiveKeyEnvMisname(env = process.env) {
|
|
1106
|
+
const primitiveKey = env.PRIMITIVE_KEY;
|
|
1107
|
+
const primitiveApiKey = env.PRIMITIVE_API_KEY;
|
|
1108
|
+
if ((primitiveKey?.length ?? 0) > 0 && (primitiveApiKey?.length ?? 0) === 0) return "PRIMITIVE_KEY is set but the CLI reads PRIMITIVE_API_KEY. Rename your env var, or re-run with PRIMITIVE_API_KEY=$PRIMITIVE_KEY.";
|
|
1109
|
+
return null;
|
|
1110
|
+
}
|
|
1094
1111
|
function resolveCliAuth(params) {
|
|
1095
1112
|
const apiKey = params.apiKey?.trim();
|
|
1096
|
-
const
|
|
1113
|
+
const apiBaseUrl = normalizeApiBaseUrl(params.apiBaseUrl);
|
|
1097
1114
|
if (apiKey) return {
|
|
1098
1115
|
apiKey,
|
|
1099
|
-
|
|
1100
|
-
apiBaseUrl2,
|
|
1116
|
+
apiBaseUrl,
|
|
1101
1117
|
credentials: null,
|
|
1102
1118
|
source: "flag-or-env"
|
|
1103
1119
|
};
|
|
1104
1120
|
const credentials = loadCliCredentials(params.configDir);
|
|
1105
1121
|
if (credentials) return {
|
|
1106
1122
|
apiKey: credentials.access_token,
|
|
1107
|
-
|
|
1108
|
-
apiBaseUrl2,
|
|
1123
|
+
apiBaseUrl: credentials.api_base_url,
|
|
1109
1124
|
credentials,
|
|
1110
1125
|
source: "stored"
|
|
1111
1126
|
};
|
|
1112
1127
|
return {
|
|
1113
1128
|
apiKey: void 0,
|
|
1114
|
-
|
|
1115
|
-
apiBaseUrl2,
|
|
1129
|
+
apiBaseUrl,
|
|
1116
1130
|
credentials: null,
|
|
1117
1131
|
source: "none"
|
|
1118
1132
|
};
|
|
@@ -1169,13 +1183,10 @@ function parseHeaders(raw, context) {
|
|
|
1169
1183
|
function parseEnvironmentConfig(raw, context) {
|
|
1170
1184
|
if (!isRecord(raw)) throw cliConfigError(`${context} must be a JSON object.`);
|
|
1171
1185
|
const env = {};
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
if (raw.api_base_url_2 !== void 0) {
|
|
1177
|
-
if (typeof raw.api_base_url_2 !== "string") throw cliConfigError(`${context}.api_base_url_2 must be a string.`);
|
|
1178
|
-
env.api_base_url_2 = normalizeApiBaseUrl2(raw.api_base_url_2);
|
|
1186
|
+
const rawApiBaseUrl = raw.api_base_url ?? raw.api_base_url_2 ?? raw.api_base_url_1;
|
|
1187
|
+
if (rawApiBaseUrl !== void 0) {
|
|
1188
|
+
if (typeof rawApiBaseUrl !== "string") throw cliConfigError(`${context}.api_base_url must be a string.`);
|
|
1189
|
+
env.api_base_url = normalizeApiBaseUrl(rawApiBaseUrl);
|
|
1179
1190
|
}
|
|
1180
1191
|
const headers = parseHeaders(raw.headers, context);
|
|
1181
1192
|
if (Object.keys(headers).length > 0) env.headers = headers;
|
|
@@ -1259,7 +1270,7 @@ function resolveConfigEnvironment(config) {
|
|
|
1259
1270
|
} : null;
|
|
1260
1271
|
}
|
|
1261
1272
|
function upsertCliEnvironment(params) {
|
|
1262
|
-
const name = normalizeCliEnvironmentName(params.environmentName ?? "default");
|
|
1273
|
+
const name = normalizeCliEnvironmentName(params.environmentName ?? resolveConfigEnvironment(params.config)?.name ?? "default");
|
|
1263
1274
|
const existing = params.config.environments[name] ?? {};
|
|
1264
1275
|
const nextHeaders = { ...existing.headers ?? {} };
|
|
1265
1276
|
for (const assignment of params.headers ?? []) {
|
|
@@ -1269,8 +1280,7 @@ function upsertCliEnvironment(params) {
|
|
|
1269
1280
|
for (const rawName of params.unsetHeaders ?? []) delete nextHeaders[validateCliHeaderName(rawName)];
|
|
1270
1281
|
const nextEnvironment = {
|
|
1271
1282
|
...existing,
|
|
1272
|
-
...params.
|
|
1273
|
-
...params.apiBaseUrl2 !== void 0 ? { api_base_url_2: normalizeApiBaseUrl2(params.apiBaseUrl2) } : {},
|
|
1283
|
+
...params.apiBaseUrl !== void 0 ? { api_base_url: normalizeApiBaseUrl(params.apiBaseUrl) } : {},
|
|
1274
1284
|
...Object.keys(nextHeaders).length > 0 ? { headers: nextHeaders } : {}
|
|
1275
1285
|
};
|
|
1276
1286
|
if (Object.keys(nextHeaders).length === 0) delete nextEnvironment.headers;
|
|
@@ -1301,4 +1311,4 @@ function redactCliEnvironment(environment) {
|
|
|
1301
1311
|
};
|
|
1302
1312
|
}
|
|
1303
1313
|
//#endregion
|
|
1304
|
-
export { createClient as A, saveCliCredentials as C, loadChatConversationByLocalId as D, loadActiveChatState as E, saveActiveChatState as O, resolveCliAuth as S, deleteChatState as T, deleteCliCredentials as _, normalizeCliEnvironmentName as a,
|
|
1314
|
+
export { createClient as A, saveCliCredentials as C, loadChatConversationByLocalId as D, loadActiveChatState as E, saveActiveChatState as O, resolveCliAuth as S, deleteChatState as T, deleteCliCredentials as _, normalizeCliEnvironmentName as a, loadCliCredentials as b, resolveConfigEnvironment as c, validateCliHeaderName as d, validateCliHeaderValue as f, credentialsPath as g, credentialsLockPath as h, loadCliConfig as i, createConfig as j, PrimitiveApiClient as k, saveCliConfig as l, cliAccessTokenExpiresAt as m, deleteCliConfig as n, redactCliEnvironment as o, acquireCliCredentialsLock as p, emptyCliConfig as r, removeCliEnvironment as s, DEFAULT_ENVIRONMENT as t, upsertCliEnvironment as u, deleteCliCredentialsLock as v, chatStatePath as w, normalizeApiBaseUrl as x, detectPrimitiveKeyEnvMisname as y };
|