@primitivedotdev/cli 0.34.0 → 0.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/{cli-config-D9nB6fOW.js → cli-config-DREZ2BxT.js} +41 -48
- package/dist/oclif/index.js +1341 -416
- package/dist/oclif/root-signup-hint.js +12 -11
- package/man/primitive.1 +2 -5
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ Or with npm:
|
|
|
12
12
|
```bash
|
|
13
13
|
npm install -g @primitivedotdev/cli
|
|
14
14
|
primitive whoami
|
|
15
|
+
# `prim` is installed as a short alias for the same CLI.
|
|
16
|
+
prim whoami
|
|
15
17
|
```
|
|
16
18
|
|
|
17
19
|
Or with no install:
|
|
@@ -55,6 +57,8 @@ Use task-oriented commands for normal workflows:
|
|
|
55
57
|
```bash
|
|
56
58
|
primitive send --to alice@example.com --body "Hello"
|
|
57
59
|
primitive reply --id <inbound-email-id> --body "Thanks"
|
|
60
|
+
primitive reply --id <inbound-email-id> --body "See attached" --attachment ./report.pdf
|
|
61
|
+
primitive chat reply "See attached" --attachment ./report.pdf
|
|
58
62
|
primitive emails list
|
|
59
63
|
primitive emails get --id <inbound-email-id>
|
|
60
64
|
primitive sent list
|
|
@@ -620,43 +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 /send-mail. The hand-written
|
|
635
|
-
* PrimitiveClient.send / .reply / .forward methods on the subclass
|
|
636
|
-
* route /send-mail 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() under the
|
|
642
|
-
* hood. Exposed for the CLI's hand-rolled send command, which calls
|
|
643
|
-
* the generated sendEmail directly; not part of the publicly-
|
|
644
|
-
* documented SDK surface. Customer code should call .send() on the
|
|
645
|
-
* subclass instead.
|
|
646
|
-
*/
|
|
647
|
-
_sendClient;
|
|
648
631
|
constructor(options = {}) {
|
|
649
|
-
const { apiKey, auth,
|
|
632
|
+
const { apiKey, auth, apiBaseUrl = DEFAULT_API_BASE_URL, ...config } = options;
|
|
650
633
|
const resolvedAuth = auth ?? createDefaultAuth(apiKey);
|
|
651
634
|
this.client = createClient(createConfig({
|
|
652
635
|
...config,
|
|
653
636
|
auth: resolvedAuth,
|
|
654
|
-
baseUrl:
|
|
655
|
-
}));
|
|
656
|
-
this._sendClient = createClient(createConfig({
|
|
657
|
-
...config,
|
|
658
|
-
auth: resolvedAuth,
|
|
659
|
-
baseUrl: apiBaseUrl2
|
|
637
|
+
baseUrl: apiBaseUrl
|
|
660
638
|
}));
|
|
661
639
|
}
|
|
662
640
|
getConfig() {
|
|
@@ -848,6 +826,11 @@ function requireString(value, key) {
|
|
|
848
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}`);
|
|
849
827
|
return raw;
|
|
850
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
|
+
}
|
|
851
834
|
/**
|
|
852
835
|
* Sentinel returned by parseCredentials when the on-disk credentials were
|
|
853
836
|
* written by an API-key-based CLI. The caller treats this as "not logged in"
|
|
@@ -879,7 +862,7 @@ function parseCredentials(raw) {
|
|
|
879
862
|
oauth_client_id: requireString(raw, "oauth_client_id"),
|
|
880
863
|
org_id: requireString(raw, "org_id"),
|
|
881
864
|
org_name: orgName,
|
|
882
|
-
|
|
865
|
+
api_base_url: readStoredApiBaseUrl(raw),
|
|
883
866
|
created_at: requireString(raw, "created_at")
|
|
884
867
|
};
|
|
885
868
|
}
|
|
@@ -894,11 +877,28 @@ function normalize(url, fallback) {
|
|
|
894
877
|
if (!trimmed) return fallback;
|
|
895
878
|
return trimmed.replace(/\/+$/, "");
|
|
896
879
|
}
|
|
897
|
-
function
|
|
898
|
-
|
|
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;
|
|
899
899
|
}
|
|
900
|
-
function
|
|
901
|
-
return normalize(url,
|
|
900
|
+
function normalizeApiBaseUrl(url) {
|
|
901
|
+
return canonicalizeKnownApiBaseUrl(normalize(url, DEFAULT_API_BASE_URL));
|
|
902
902
|
}
|
|
903
903
|
function cliAccessTokenExpiresAt(expiresInSeconds, now = Date.now) {
|
|
904
904
|
return new Date(now() + expiresInSeconds * 1e3).toISOString();
|
|
@@ -1092,26 +1092,23 @@ function acquireCliCredentialsLock(configDir, options = {}) {
|
|
|
1092
1092
|
}
|
|
1093
1093
|
function resolveCliAuth(params) {
|
|
1094
1094
|
const apiKey = params.apiKey?.trim();
|
|
1095
|
-
const
|
|
1095
|
+
const apiBaseUrl = normalizeApiBaseUrl(params.apiBaseUrl);
|
|
1096
1096
|
if (apiKey) return {
|
|
1097
1097
|
apiKey,
|
|
1098
|
-
|
|
1099
|
-
apiBaseUrl2,
|
|
1098
|
+
apiBaseUrl,
|
|
1100
1099
|
credentials: null,
|
|
1101
1100
|
source: "flag-or-env"
|
|
1102
1101
|
};
|
|
1103
1102
|
const credentials = loadCliCredentials(params.configDir);
|
|
1104
1103
|
if (credentials) return {
|
|
1105
1104
|
apiKey: credentials.access_token,
|
|
1106
|
-
|
|
1107
|
-
apiBaseUrl2,
|
|
1105
|
+
apiBaseUrl: credentials.api_base_url,
|
|
1108
1106
|
credentials,
|
|
1109
1107
|
source: "stored"
|
|
1110
1108
|
};
|
|
1111
1109
|
return {
|
|
1112
1110
|
apiKey: void 0,
|
|
1113
|
-
|
|
1114
|
-
apiBaseUrl2,
|
|
1111
|
+
apiBaseUrl,
|
|
1115
1112
|
credentials: null,
|
|
1116
1113
|
source: "none"
|
|
1117
1114
|
};
|
|
@@ -1168,13 +1165,10 @@ function parseHeaders(raw, context) {
|
|
|
1168
1165
|
function parseEnvironmentConfig(raw, context) {
|
|
1169
1166
|
if (!isRecord(raw)) throw cliConfigError(`${context} must be a JSON object.`);
|
|
1170
1167
|
const env = {};
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
if (raw.api_base_url_2 !== void 0) {
|
|
1176
|
-
if (typeof raw.api_base_url_2 !== "string") throw cliConfigError(`${context}.api_base_url_2 must be a string.`);
|
|
1177
|
-
env.api_base_url_2 = normalizeApiBaseUrl2(raw.api_base_url_2);
|
|
1168
|
+
const rawApiBaseUrl = raw.api_base_url ?? raw.api_base_url_2 ?? raw.api_base_url_1;
|
|
1169
|
+
if (rawApiBaseUrl !== void 0) {
|
|
1170
|
+
if (typeof rawApiBaseUrl !== "string") throw cliConfigError(`${context}.api_base_url must be a string.`);
|
|
1171
|
+
env.api_base_url = normalizeApiBaseUrl(rawApiBaseUrl);
|
|
1178
1172
|
}
|
|
1179
1173
|
const headers = parseHeaders(raw.headers, context);
|
|
1180
1174
|
if (Object.keys(headers).length > 0) env.headers = headers;
|
|
@@ -1258,7 +1252,7 @@ function resolveConfigEnvironment(config) {
|
|
|
1258
1252
|
} : null;
|
|
1259
1253
|
}
|
|
1260
1254
|
function upsertCliEnvironment(params) {
|
|
1261
|
-
const name = normalizeCliEnvironmentName(params.environmentName ?? "default");
|
|
1255
|
+
const name = normalizeCliEnvironmentName(params.environmentName ?? resolveConfigEnvironment(params.config)?.name ?? "default");
|
|
1262
1256
|
const existing = params.config.environments[name] ?? {};
|
|
1263
1257
|
const nextHeaders = { ...existing.headers ?? {} };
|
|
1264
1258
|
for (const assignment of params.headers ?? []) {
|
|
@@ -1268,8 +1262,7 @@ function upsertCliEnvironment(params) {
|
|
|
1268
1262
|
for (const rawName of params.unsetHeaders ?? []) delete nextHeaders[validateCliHeaderName(rawName)];
|
|
1269
1263
|
const nextEnvironment = {
|
|
1270
1264
|
...existing,
|
|
1271
|
-
...params.
|
|
1272
|
-
...params.apiBaseUrl2 !== void 0 ? { api_base_url_2: normalizeApiBaseUrl2(params.apiBaseUrl2) } : {},
|
|
1265
|
+
...params.apiBaseUrl !== void 0 ? { api_base_url: normalizeApiBaseUrl(params.apiBaseUrl) } : {},
|
|
1273
1266
|
...Object.keys(nextHeaders).length > 0 ? { headers: nextHeaders } : {}
|
|
1274
1267
|
};
|
|
1275
1268
|
if (Object.keys(nextHeaders).length === 0) delete nextEnvironment.headers;
|
|
@@ -1300,4 +1293,4 @@ function redactCliEnvironment(environment) {
|
|
|
1300
1293
|
};
|
|
1301
1294
|
}
|
|
1302
1295
|
//#endregion
|
|
1303
|
-
export {
|
|
1296
|
+
export { createConfig as A, chatStatePath as C, saveActiveChatState as D, loadChatConversationByLocalId as E, PrimitiveApiClient as O, saveCliCredentials as S, loadActiveChatState as T, deleteCliCredentials as _, normalizeCliEnvironmentName as a, normalizeApiBaseUrl as b, resolveConfigEnvironment as c, validateCliHeaderName as d, validateCliHeaderValue as f, credentialsPath as g, credentialsLockPath as h, loadCliConfig as i, createClient 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, deleteChatState as w, resolveCliAuth as x, loadCliCredentials as y };
|