primcli 1.70.0 → 1.72.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/README.md +115 -2
- package/dist/{api-command-C58Oh38I.js → api-command-BrwPbyPP.js} +286 -19
- package/dist/{cli-config-DMszFbGn.js → cli-config--YTRdJ3t.js} +15 -4
- package/dist/{json-output-CEskSQJi.js → json-output-Ce10AsSb.js} +71 -3
- package/dist/{machine-session-CKmn5bvB.js → machine-session-Be6j29GE.js} +8 -6
- package/dist/{notify-session-CVZtEboh.js → notify-session-Byt5sPWW.js} +2 -2
- package/dist/oclif/auto-signal-worker.js +2 -2
- package/dist/oclif/auto-signals.js +1 -1
- package/dist/oclif/index.js +5266 -112
- package/dist/oclif/listen-supervisor.js +1 -2
- package/dist/oclif/proxy-auto-detect.js +1 -1
- package/dist/oclif/receiver-heal.js +2 -2
- package/dist/oclif/root-signup-hint.js +1 -1
- package/dist/{repeats-BL7ZC-_6-BZ-MphTV.js → repeats-BL7ZC-_6-CKMKBlx7.js} +1 -1
- package/dist/{scoped-chat-Dsark9hm.js → scoped-chat-DTFkP360.js} +1 -1
- package/dist/{signal-command-Dy_oub7_.js → signal-command-DeEEZPbQ.js} +4 -4
- package/dist/skills/primitive-connect/SKILL.md +162 -355
- package/dist/skills/primitive-connect/references/collaboration.md +39 -2
- package/dist/skills/primitive-connect/references/communication.md +2 -2
- package/dist/skills/primitive-connect/references/connect.md +234 -0
- package/dist/skills/primitive-connect/references/contact-requests.md +3 -3
- package/dist/skills/primitive-connect/references/contacts.md +4 -4
- package/dist/skills/primitive-connect/references/conversations.md +4 -4
- package/dist/skills/primitive-connect/references/external-services.md +86 -0
- package/dist/skills/primitive-connect/references/manual-setup.md +2 -2
- package/dist/skills/primitive-connect/references/presence-and-receiving.md +5 -5
- package/dist/skills/primitive-connect/scripts/check-cli-capabilities.mjs +13 -4
- package/dist/skills/primitive-connect.json +13 -11
- package/man/primitive.1 +17 -3
- package/package.json +11 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as __exportAll, _ as WEBHOOK_EVENT_TYPES, g as SENT_EMAIL_EVENT_TYPES } from "./repeats-BL7ZC-_6-
|
|
2
|
-
import { C as resolveCliAuth,
|
|
1
|
+
import { S as __exportAll, _ as WEBHOOK_EVENT_TYPES, g as SENT_EMAIL_EVENT_TYPES } from "./repeats-BL7ZC-_6-CKMKBlx7.js";
|
|
2
|
+
import { C as resolveCliAuth, G as PrimitiveApiClient, I as agentProfilesDirectory, K as createClient, M as AGENT_PROFILE_ENV, P as agentProfileDirectory, S as normalizeApiBaseUrl, T as saveSignupCredentials, U as requireDefaultLoginProfile, _ as deleteCliCredentials, c as resolveConfigEnvironment, d as validateCliHeaderName, f as validateCliHeaderValue, i as loadCliConfig, m as cliAccessTokenExpiresAt, p as acquireCliCredentialsLock, q as createConfig, w as saveCliCredentials, x as loadCliCredentials, y as detectPrimitiveKeyEnvMisname, z as loadConnectedAgentProfile } from "./cli-config--YTRdJ3t.js";
|
|
3
3
|
import { h as writeMailJson, m as withMailLock, p as syncMailDirectory, u as privateMailPermissions } from "./shared-mail-files-MwlVE90c.js";
|
|
4
4
|
import { Command, Errors, Flags } from "@oclif/core";
|
|
5
5
|
import { existsSync, lstatSync, readFileSync, readdirSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
@@ -15,6 +15,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
15
15
|
agentConnectionSetup: () => agentConnectionSetup,
|
|
16
16
|
awaitReply: () => awaitReply,
|
|
17
17
|
cancelSentEmail: () => cancelSentEmail,
|
|
18
|
+
cancelSentEmailByIdempotencyKey: () => cancelSentEmailByIdempotencyKey,
|
|
18
19
|
checkDefaultNetworkContactAdmission: () => checkDefaultNetworkContactAdmission,
|
|
19
20
|
checkDomainDns: () => checkDomainDns,
|
|
20
21
|
claimAgentConnection: () => claimAgentConnection,
|
|
@@ -55,8 +56,12 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
55
56
|
discardEmailContent: () => discardEmailContent,
|
|
56
57
|
downloadAttachments: () => downloadAttachments,
|
|
57
58
|
downloadDomainZoneFile: () => downloadDomainZoneFile,
|
|
59
|
+
downloadEmailAttachmentArchiveMember: () => downloadEmailAttachmentArchiveMember,
|
|
60
|
+
downloadEmailAttachmentByFilename: () => downloadEmailAttachmentByFilename,
|
|
58
61
|
downloadEmailAttachmentPart: () => downloadEmailAttachmentPart,
|
|
59
62
|
downloadRawEmail: () => downloadRawEmail,
|
|
63
|
+
downloadSentAttachmentArchiveMember: () => downloadSentAttachmentArchiveMember,
|
|
64
|
+
downloadSentAttachmentByFilename: () => downloadSentAttachmentByFilename,
|
|
60
65
|
downloadSentAttachmentPart: () => downloadSentAttachmentPart,
|
|
61
66
|
getAccount: () => getAccount,
|
|
62
67
|
getAgent: () => getAgent,
|
|
@@ -91,12 +96,14 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
91
96
|
listAgentConnections: () => listAgentConnections,
|
|
92
97
|
listAgentContacts: () => listAgentContacts,
|
|
93
98
|
listAgentNetworks: () => listAgentNetworks,
|
|
99
|
+
listChanges: () => listChanges,
|
|
94
100
|
listContacts: () => listContacts,
|
|
95
101
|
listDeclinedPayments: () => listDeclinedPayments,
|
|
96
102
|
listDefaultNetworkAgents: () => listDefaultNetworkAgents,
|
|
97
103
|
listDefaultNetworkMembers: () => listDefaultNetworkMembers,
|
|
98
104
|
listDeliveries: () => listDeliveries,
|
|
99
105
|
listDomains: () => listDomains,
|
|
106
|
+
listEmailAttachmentArchiveMembers: () => listEmailAttachmentArchiveMembers,
|
|
100
107
|
listEmails: () => listEmails,
|
|
101
108
|
listEndpoints: () => listEndpoints,
|
|
102
109
|
listFilters: () => listFilters,
|
|
@@ -110,6 +117,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
110
117
|
listRegistryRequests: () => listRegistryRequests,
|
|
111
118
|
listRepeatingSends: () => listRepeatingSends,
|
|
112
119
|
listRoutes: () => listRoutes,
|
|
120
|
+
listSentAttachmentArchiveMembers: () => listSentAttachmentArchiveMembers,
|
|
113
121
|
listSentEmails: () => listSentEmails,
|
|
114
122
|
listTemplates: () => listTemplates,
|
|
115
123
|
listWakeAuthorizations: () => listWakeAuthorizations,
|
|
@@ -887,6 +895,45 @@ const downloadEmailAttachmentPart = (options) => (options.client ?? client).get(
|
|
|
887
895
|
...options
|
|
888
896
|
});
|
|
889
897
|
/**
|
|
898
|
+
* Download one received email attachment by filename
|
|
899
|
+
*
|
|
900
|
+
* Returns the same bytes as downloadEmailAttachmentPart, selecting the attachment by its exact filename. The path form `/emails/{id}/attachments/{filename}` also works for any name that is not digits only, which that form reads as a part_index. When several attachments share the filename the response is 409 attachment_name_ambiguous with every matching part_index, and nothing is returned. Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail received at its own address. Function credentials are not supported. Discarded content is unavailable.
|
|
901
|
+
*/
|
|
902
|
+
const downloadEmailAttachmentByFilename = (options) => (options.client ?? client).get({
|
|
903
|
+
security: [{
|
|
904
|
+
scheme: "bearer",
|
|
905
|
+
type: "http"
|
|
906
|
+
}],
|
|
907
|
+
url: "/emails/{id}/attachments",
|
|
908
|
+
...options
|
|
909
|
+
});
|
|
910
|
+
/**
|
|
911
|
+
* List the files inside a received zip or tar attachment
|
|
912
|
+
*
|
|
913
|
+
* Lists the regular files inside a zip, tar or tar.gz attachment with each one's path, decoded size and SHA-256. The format is detected from the content. Unsafe paths refuse the whole archive, and resource limits bound the work (see the 413 and 422 responses). Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail received at its own address. Function credentials are not supported. Discarded content is unavailable.
|
|
914
|
+
*/
|
|
915
|
+
const listEmailAttachmentArchiveMembers = (options) => (options.client ?? client).get({
|
|
916
|
+
security: [{
|
|
917
|
+
scheme: "bearer",
|
|
918
|
+
type: "http"
|
|
919
|
+
}],
|
|
920
|
+
url: "/emails/{id}/attachments/{attachment}/members",
|
|
921
|
+
...options
|
|
922
|
+
});
|
|
923
|
+
/**
|
|
924
|
+
* Download one file from inside a received zip or tar attachment
|
|
925
|
+
*
|
|
926
|
+
* Returns the decoded bytes of one regular file inside a zip, tar or tar.gz attachment, by its listed path. The archive's structure, every member path and every limit are checked as for the listing, but only the requested file is decoded and verified (its zip CRC-32, and X-Content-SHA256 of the bytes returned); list the archive to have every file decoded. Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail received at its own address. Function credentials are not supported. Discarded content is unavailable.
|
|
927
|
+
*/
|
|
928
|
+
const downloadEmailAttachmentArchiveMember = (options) => (options.client ?? client).get({
|
|
929
|
+
security: [{
|
|
930
|
+
scheme: "bearer",
|
|
931
|
+
type: "http"
|
|
932
|
+
}],
|
|
933
|
+
url: "/emails/{id}/attachments/{attachment}/members/{path}",
|
|
934
|
+
...options
|
|
935
|
+
});
|
|
936
|
+
/**
|
|
890
937
|
* Download one sent email attachment
|
|
891
938
|
*
|
|
892
939
|
* Pending service release. This contract does not establish live availability.
|
|
@@ -909,6 +956,45 @@ const downloadSentAttachmentPart = (options) => (options.client ?? client).get({
|
|
|
909
956
|
...options
|
|
910
957
|
});
|
|
911
958
|
/**
|
|
959
|
+
* Download one sent email attachment by filename
|
|
960
|
+
*
|
|
961
|
+
* Returns the same bytes as downloadSentAttachmentPart, selecting the attachment by its exact filename. The path form `/sent-emails/{id}/attachments/{filename}` also works for any name that is not digits only, which that form reads as a part_index. When several attachments share the filename the response is 409 attachment_name_ambiguous with every matching part_index, and nothing is returned. Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail sent from its own address. Function credentials are not supported. Discarded content is unavailable.
|
|
962
|
+
*/
|
|
963
|
+
const downloadSentAttachmentByFilename = (options) => (options.client ?? client).get({
|
|
964
|
+
security: [{
|
|
965
|
+
scheme: "bearer",
|
|
966
|
+
type: "http"
|
|
967
|
+
}],
|
|
968
|
+
url: "/sent-emails/{id}/attachments",
|
|
969
|
+
...options
|
|
970
|
+
});
|
|
971
|
+
/**
|
|
972
|
+
* List the files inside a sent zip or tar attachment
|
|
973
|
+
*
|
|
974
|
+
* Lists the regular files inside a zip, tar or tar.gz attachment with each one's path, decoded size and SHA-256. The format is detected from the content. Unsafe paths refuse the whole archive, and resource limits bound the work (see the 413 and 422 responses). Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail sent from its own address. Function credentials are not supported. Discarded content is unavailable.
|
|
975
|
+
*/
|
|
976
|
+
const listSentAttachmentArchiveMembers = (options) => (options.client ?? client).get({
|
|
977
|
+
security: [{
|
|
978
|
+
scheme: "bearer",
|
|
979
|
+
type: "http"
|
|
980
|
+
}],
|
|
981
|
+
url: "/sent-emails/{id}/attachments/{attachment}/members",
|
|
982
|
+
...options
|
|
983
|
+
});
|
|
984
|
+
/**
|
|
985
|
+
* Download one file from inside a sent zip or tar attachment
|
|
986
|
+
*
|
|
987
|
+
* Returns the decoded bytes of one regular file inside a zip, tar or tar.gz attachment, by its listed path. The archive's structure, every member path and every limit are checked as for the listing, but only the requested file is decoded and verified (its zip CRC-32, and X-Content-SHA256 of the bytes returned); list the archive to have every file decoded. Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail sent from its own address. Function credentials are not supported. Discarded content is unavailable.
|
|
988
|
+
*/
|
|
989
|
+
const downloadSentAttachmentArchiveMember = (options) => (options.client ?? client).get({
|
|
990
|
+
security: [{
|
|
991
|
+
scheme: "bearer",
|
|
992
|
+
type: "http"
|
|
993
|
+
}],
|
|
994
|
+
url: "/sent-emails/{id}/attachments/{attachment}/members/{path}",
|
|
995
|
+
...options
|
|
996
|
+
});
|
|
997
|
+
/**
|
|
912
998
|
* Stop the repeat behind a received message
|
|
913
999
|
*
|
|
914
1000
|
* Called by the recipient of a repeating send: the connected agent's own
|
|
@@ -1990,6 +2076,42 @@ const agentConnectionSetup = (options) => (options?.client ?? client).get({
|
|
|
1990
2076
|
...options
|
|
1991
2077
|
});
|
|
1992
2078
|
/**
|
|
2079
|
+
* Long-poll what changed
|
|
2080
|
+
*
|
|
2081
|
+
* One feed of small invalidations (ids and kinds) for everything an app keeps a snapshot of: inbound mail, sent mail, the member's conversation read state, the agent directory and presence, and the credential's own access. Non-consumptive and replayable: any number of devices can read the same cursor independently.
|
|
2082
|
+
*
|
|
2083
|
+
* Start with `since=start` (or no `since`): it returns an empty page whose `next_cursor` is a baseline. Take it BEFORE the initial list reads; every change that commits after it is delivered, including ones those reads already reflect. Then call with `since=<next_cursor>&wait=20` in a loop. Changes come oldest first in commit order, at least once: a write that commits late is never skipped, because positions are assigned at commit.
|
|
2084
|
+
*
|
|
2085
|
+
* Every change is scoped to what this credential's full reads would show: a connected agent sees only its own mail, its own sends and sends it provably received; mail held for sender authentication is announced only when released; read state reaches only the member it belongs to; agent changes reach members and agents allowed to view the network; organization API keys receive no agent changes. Function credentials cannot call this.
|
|
2086
|
+
*
|
|
2087
|
+
* Changes are kept 7 days. A cursor answers 410 `cursor_expired` only when changes after it were pruned (an idle cursor stays valid); rebuild the snapshots from `since=start`.
|
|
2088
|
+
*/
|
|
2089
|
+
const listChanges = (options) => (options?.client ?? client).get({
|
|
2090
|
+
security: [{
|
|
2091
|
+
scheme: "bearer",
|
|
2092
|
+
type: "http"
|
|
2093
|
+
}],
|
|
2094
|
+
url: "/changes",
|
|
2095
|
+
...options
|
|
2096
|
+
});
|
|
2097
|
+
/**
|
|
2098
|
+
* Cancel a scheduled send by idempotency key
|
|
2099
|
+
*
|
|
2100
|
+
* Cancels the still-scheduled send created with this `Idempotency-Key` (matched exactly), as `POST /sent-emails/{id}/cancel` does, and releases the key. 404 `not_found`: no send this credential can act on was created with the key. 409 `not_scheduled`: the send holding the key is no longer scheduled; `error.details` names its `sent_email_id` and `status` (`canceled` if already canceled). Pass `created_before` on a retry so it cannot reach a newer send that reused the released key. A connected agent can cancel any scheduled send from its own address, whoever created it, and no other.
|
|
2101
|
+
*/
|
|
2102
|
+
const cancelSentEmailByIdempotencyKey = (options) => (options.client ?? client).post({
|
|
2103
|
+
security: [{
|
|
2104
|
+
scheme: "bearer",
|
|
2105
|
+
type: "http"
|
|
2106
|
+
}],
|
|
2107
|
+
url: "/sent-emails/cancel",
|
|
2108
|
+
...options,
|
|
2109
|
+
headers: {
|
|
2110
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
2111
|
+
...options.headers
|
|
2112
|
+
}
|
|
2113
|
+
});
|
|
2114
|
+
/**
|
|
1993
2115
|
* Cancel a scheduled send
|
|
1994
2116
|
*
|
|
1995
2117
|
* Cancels a STILL-SCHEDULED send (status `scheduled`), moving it
|
|
@@ -3517,7 +3639,13 @@ async function createAuthenticatedCliApiClient(params) {
|
|
|
3517
3639
|
const ATTACHMENT_WAIT_OPERATIONS = /* @__PURE__ */ new Set([
|
|
3518
3640
|
"downloadAttachments",
|
|
3519
3641
|
"downloadEmailAttachmentPart",
|
|
3520
|
-
"downloadSentAttachmentPart"
|
|
3642
|
+
"downloadSentAttachmentPart",
|
|
3643
|
+
"downloadEmailAttachmentByFilename",
|
|
3644
|
+
"downloadSentAttachmentByFilename",
|
|
3645
|
+
"downloadEmailAttachmentArchiveMember",
|
|
3646
|
+
"downloadSentAttachmentArchiveMember",
|
|
3647
|
+
"listEmailAttachmentArchiveMembers",
|
|
3648
|
+
"listSentAttachmentArchiveMembers"
|
|
3521
3649
|
]);
|
|
3522
3650
|
/** Longest a download command waits for attachment content, in total. */
|
|
3523
3651
|
const ATTACHMENT_WAIT_MAX_MS = 6e4;
|
|
@@ -3891,6 +4019,63 @@ function withFlagSuggestion(error, valid) {
|
|
|
3891
4019
|
return error;
|
|
3892
4020
|
}
|
|
3893
4021
|
//#endregion
|
|
4022
|
+
//#region src/oclif/from-verified-filter.ts
|
|
4023
|
+
/**
|
|
4024
|
+
* The `from_verified` filter on GET /emails and GET /emails/search: the
|
|
4025
|
+
* `from_verified=true|false` parameter (`--from-verified`) and the
|
|
4026
|
+
* `from_verified:` search term.
|
|
4027
|
+
*
|
|
4028
|
+
* `from_verified` says whether the From domain was authenticated when the
|
|
4029
|
+
* email arrived. A filter on it is a trust decision, so a server that does
|
|
4030
|
+
* not apply it must fail loudly: rows returned for `--from-verified true`
|
|
4031
|
+
* that do not all carry `from_verified: true` are refused instead of being
|
|
4032
|
+
* printed as if they were authenticated mail.
|
|
4033
|
+
*/
|
|
4034
|
+
const FROM_VERIFIED_FILTER_UNSUPPORTED_CODE = "from_verified_filter_unsupported";
|
|
4035
|
+
var FromVerifiedFilterUnsupportedError = class extends Error {
|
|
4036
|
+
code = FROM_VERIFIED_FILTER_UNSUPPORTED_CODE;
|
|
4037
|
+
constructor(detail) {
|
|
4038
|
+
super(`The server did not apply the \`from_verified\` filter: ${detail} Nothing was printed. Upgrade to a server that returns \`from_verified\`, or drop the filter.`);
|
|
4039
|
+
this.name = "FromVerifiedFilterUnsupportedError";
|
|
4040
|
+
}
|
|
4041
|
+
};
|
|
4042
|
+
const FROM_VERIFIED_SURFACES = {
|
|
4043
|
+
listEmails: "GET /emails",
|
|
4044
|
+
searchEmails: "GET /emails/search"
|
|
4045
|
+
};
|
|
4046
|
+
const TERM = /(?:^|\s)from_verified:("?)(true|false)\1(?=\s|$)/gi;
|
|
4047
|
+
const PHRASE = /(^|\s)(?:(?!from_verified:)[A-Za-z_][\w.-]*:)?"(?:[^"\\]|\\.)*"/gi;
|
|
4048
|
+
/** The `from_verified:` values a search query asks for, in order. */
|
|
4049
|
+
function fromVerifiedTermsInQuery(q) {
|
|
4050
|
+
if (typeof q !== "string") return [];
|
|
4051
|
+
return [...q.replace(PHRASE, "$1 ").matchAll(TERM)].map((match) => match[2]?.toLowerCase() === "true");
|
|
4052
|
+
}
|
|
4053
|
+
/**
|
|
4054
|
+
* For the generated `emails list` / `emails search` commands: the surface
|
|
4055
|
+
* name and the values every row must have when this call filtered on
|
|
4056
|
+
* `from_verified`, else null.
|
|
4057
|
+
*/
|
|
4058
|
+
function fromVerifiedExpectation(sdkName, query) {
|
|
4059
|
+
const surface = FROM_VERIFIED_SURFACES[sdkName];
|
|
4060
|
+
if (!surface || !query) return null;
|
|
4061
|
+
const expected = fromVerifiedTermsInQuery(typeof query.q === "string" ? query.q : void 0);
|
|
4062
|
+
if (query.from_verified === "true") expected.push(true);
|
|
4063
|
+
if (query.from_verified === "false") expected.push(false);
|
|
4064
|
+
return expected.length > 0 ? {
|
|
4065
|
+
surface,
|
|
4066
|
+
expected
|
|
4067
|
+
} : null;
|
|
4068
|
+
}
|
|
4069
|
+
/** Throw unless every row carries `from_verified` with every expected value. */
|
|
4070
|
+
function assertFromVerifiedRows(rows, expectation) {
|
|
4071
|
+
const wrong = rows.filter((row) => {
|
|
4072
|
+
if (row === null || typeof row !== "object") return true;
|
|
4073
|
+
const value = row.from_verified;
|
|
4074
|
+
return typeof value !== "boolean" || expectation.expected.some((expected) => expected !== value);
|
|
4075
|
+
}).length;
|
|
4076
|
+
if (wrong > 0) throw new FromVerifiedFilterUnsupportedError(`${expectation.surface} returned ${wrong} of ${rows.length} email${rows.length === 1 ? "" : "s"} without the requested \`from_verified\` value.`);
|
|
4077
|
+
}
|
|
4078
|
+
//#endregion
|
|
3894
4079
|
//#region src/oclif/idempotent-replay-banner.ts
|
|
3895
4080
|
/**
|
|
3896
4081
|
* If `data` carries `idempotent_replay: true`, write a stderr notice
|
|
@@ -4107,7 +4292,7 @@ const SEND_OUTCOME_HELP = `Outcomes and exit codes, shared by chat, chat reply,
|
|
|
4107
4292
|
- exit 0 replied: chat only. The message was sent and a reply arrived.
|
|
4108
4293
|
- exit 0 sent: accepted for delivery. A queued status counts as sent.
|
|
4109
4294
|
- exit 0 already_sent: an identical earlier send exists (or was deleted: HTTP 410 sent_email_deleted). Nothing new went out. Do not resend.
|
|
4110
|
-
- exit 1 not_sent: the API rejected the request (HTTP 400, 401, 402, 403, 404, 413, 422 or 429), the command failed before sending, or the send record has status agent_failed, gate_denied or canceled. Nothing went out.
|
|
4295
|
+
- exit 1 not_sent: the API rejected the request (HTTP 400, 401, 402, 403, 404, 413, 422 or 429, or, from --if-latest-message-id, 409 latest_message_mismatch, 422 latest_message_thread_unresolved or 503 thread_busy), the command failed before sending, or the send record has status agent_failed, gate_denied or canceled. Nothing went out.
|
|
4111
4296
|
- exit 2: invalid flags or arguments. Nothing went out.
|
|
4112
4297
|
- exit 3 sent_awaiting_reply: chat only. Sent, but no reply before the timeout. Wait; do not resend.
|
|
4113
4298
|
- exit 4 uncertain: transport error, conflict, server error, or a send record with status unknown. It may or may not have gone out. Reconcile with primitive sent get --idempotency-key <key> (the key is in the --json envelope) before retrying.`;
|
|
@@ -4118,6 +4303,8 @@ function sendFailureOutcome(httpStatus) {
|
|
|
4118
4303
|
return httpStatus !== void 0 && DEFINITIVE_SEND_REJECTION_STATUSES.includes(httpStatus) ? "not_sent" : "uncertain";
|
|
4119
4304
|
}
|
|
4120
4305
|
const SENT_EMAIL_DELETED_CODE = "sent_email_deleted";
|
|
4306
|
+
const LATEST_MESSAGE_MISMATCH_CODE = "latest_message_mismatch";
|
|
4307
|
+
const THREAD_BUSY_CODE = "thread_busy";
|
|
4121
4308
|
function errorPayloadCode(payload) {
|
|
4122
4309
|
if (payload === null || typeof payload !== "object") return void 0;
|
|
4123
4310
|
const code = payload.code;
|
|
@@ -4128,7 +4315,10 @@ function isDeletedEarlierSend(httpStatus, errorPayload) {
|
|
|
4128
4315
|
}
|
|
4129
4316
|
/** Classify an API error from a send request. */
|
|
4130
4317
|
function classifySendError(httpStatus, errorPayload) {
|
|
4131
|
-
|
|
4318
|
+
if (isDeletedEarlierSend(httpStatus, errorPayload)) return "already_sent";
|
|
4319
|
+
if (httpStatus === 409 && errorPayloadCode(errorPayload) === LATEST_MESSAGE_MISMATCH_CODE) return "not_sent";
|
|
4320
|
+
if (httpStatus === 503 && errorPayloadCode(errorPayload) === THREAD_BUSY_CODE) return "not_sent";
|
|
4321
|
+
return sendFailureOutcome(httpStatus);
|
|
4132
4322
|
}
|
|
4133
4323
|
function formatDeletedEarlierSendNotice() {
|
|
4134
4324
|
return "Already sent: an earlier send matching this request went out and its record was later deleted, so the API refused this one (HTTP 410 sent_email_deleted). Nothing new was sent. Do not resend or change the idempotency key to get around this.";
|
|
@@ -4175,6 +4365,16 @@ function describeSentStatus(status) {
|
|
|
4175
4365
|
function formatSentSummary(noun, sent) {
|
|
4176
4366
|
return `${noun} sent (${describeSentStatus(sent.status)}, id ${sent.id}). Do not resend.`;
|
|
4177
4367
|
}
|
|
4368
|
+
/**
|
|
4369
|
+
* Summary for a send the API accepted with status `scheduled`: nothing
|
|
4370
|
+
* has gone out yet, and it can still be canceled.
|
|
4371
|
+
*/
|
|
4372
|
+
function formatScheduledSummary(noun, sent, idempotencyKey) {
|
|
4373
|
+
const when = sent.scheduled_at ? ` for ${sent.scheduled_at}` : "";
|
|
4374
|
+
const verb = sent.idempotent_replay === true ? "already scheduled" : "scheduled";
|
|
4375
|
+
const byKey = idempotencyKey ? ` or \`primitive sent cancel --idempotency-key ${shellQuote(idempotencyKey)}\`` : "";
|
|
4376
|
+
return `${noun} ${verb}${when} (id ${sent.id}). Nothing has gone out yet. Do not resend. To cancel it before then, run \`primitive sent cancel --id ${sent.id}\`${byKey}.`;
|
|
4377
|
+
}
|
|
4178
4378
|
function formatSendFailureSummary(noun, outcome, httpStatus) {
|
|
4179
4379
|
if (outcome === "not_sent") return `${noun} not sent: ${httpStatus === void 0 ? "the request failed before sending" : `the API rejected the request (HTTP ${httpStatus})`}. Nothing went out; fix the problem before retrying.`;
|
|
4180
4380
|
return `${noun} send outcome uncertain (${httpStatus === void 0 ? "no response from the API" : `HTTP ${httpStatus}`}): it may or may not have gone out. Do not resend blindly; check sent history first.`;
|
|
@@ -4392,8 +4592,9 @@ function sendIdentityFields(params) {
|
|
|
4392
4592
|
};
|
|
4393
4593
|
}
|
|
4394
4594
|
/**
|
|
4395
|
-
* Commands that inspect an existing send
|
|
4396
|
-
* a caller that follows them after
|
|
4595
|
+
* Commands that inspect an existing send, or cancel one still
|
|
4596
|
+
* scheduled. None of them send again: a caller that follows them after
|
|
4597
|
+
* a failure cannot double-send.
|
|
4397
4598
|
*/
|
|
4398
4599
|
function buildSendCommandFollowUps(params) {
|
|
4399
4600
|
const commands = [];
|
|
@@ -4404,13 +4605,22 @@ function buildSendCommandFollowUps(params) {
|
|
|
4404
4605
|
"--idempotency-key",
|
|
4405
4606
|
params.idempotencyKey
|
|
4406
4607
|
]));
|
|
4407
|
-
if (params.sentId !== null)
|
|
4408
|
-
"
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4608
|
+
if (params.sentId !== null) {
|
|
4609
|
+
commands.push(buildFollowUpCommand("inspect_sent_email", "Inspect the send and its delivery status", [
|
|
4610
|
+
"primitive",
|
|
4611
|
+
"sent",
|
|
4612
|
+
"get",
|
|
4613
|
+
"--id",
|
|
4614
|
+
params.sentId
|
|
4615
|
+
]));
|
|
4616
|
+
if (params.scheduled === true) commands.push(buildFollowUpCommand("cancel_scheduled_send", "Cancel this scheduled send before it goes out", [
|
|
4617
|
+
"primitive",
|
|
4618
|
+
"sent",
|
|
4619
|
+
"cancel",
|
|
4620
|
+
"--id",
|
|
4621
|
+
params.sentId
|
|
4622
|
+
]));
|
|
4623
|
+
}
|
|
4414
4624
|
if (params.outcome === "uncertain") commands.push(buildFollowUpCommand("list_recent_sent_emails", "Check sent history for this attempt before retrying", [
|
|
4415
4625
|
"primitive",
|
|
4416
4626
|
"sent",
|
|
@@ -4449,7 +4659,7 @@ function reportSendCommandResult(params) {
|
|
|
4449
4659
|
errorPayload = { message: "The API returned no send record." };
|
|
4450
4660
|
} else {
|
|
4451
4661
|
outcome = successfulSendOutcome(sent);
|
|
4452
|
-
outcomeMessage = outcome === "not_sent" || outcome === "uncertain" ? formatSendRecordFailureSummary(params.noun, outcome, sent) : outcome === "already_sent" ? formatAlreadySentNotice(sent, {
|
|
4662
|
+
outcomeMessage = outcome === "not_sent" || outcome === "uncertain" ? formatSendRecordFailureSummary(params.noun, outcome, sent) : sent.status === "scheduled" ? formatScheduledSummary(params.noun, sent, params.idempotencyKey ?? sent.client_idempotency_key) : outcome === "already_sent" ? formatAlreadySentNotice(sent, {
|
|
4453
4663
|
keyOrigin: params.idempotencyKeyOrigin ?? "caller",
|
|
4454
4664
|
keyHint: "--idempotency-key with a new key"
|
|
4455
4665
|
}) : formatSentSummary(params.noun, sent);
|
|
@@ -4472,6 +4682,7 @@ function reportSendCommandResult(params) {
|
|
|
4472
4682
|
attemptStartedAtIso: params.attemptStartedAtIso,
|
|
4473
4683
|
idempotencyKey: params.idempotencyKey,
|
|
4474
4684
|
outcome,
|
|
4685
|
+
scheduled: sent?.status === "scheduled",
|
|
4475
4686
|
sentId: sent?.id ?? null
|
|
4476
4687
|
}),
|
|
4477
4688
|
...params.extraEnvelopeFields
|
|
@@ -5361,7 +5572,7 @@ function savedConnectedProfiles(configDir, exclude) {
|
|
|
5361
5572
|
*/
|
|
5362
5573
|
async function otherProfiles(configDir, session, current) {
|
|
5363
5574
|
if (session) try {
|
|
5364
|
-
const { connectedProfilesForSession } = await import("./machine-session-
|
|
5575
|
+
const { connectedProfilesForSession } = await import("./machine-session-Be6j29GE.js").then((n) => n.s);
|
|
5365
5576
|
return {
|
|
5366
5577
|
inSession: true,
|
|
5367
5578
|
profiles: connectedProfilesForSession(configDir, session, current)
|
|
@@ -5628,6 +5839,42 @@ const API_ERROR_CODES = {
|
|
|
5628
5839
|
function flagName(parameterName) {
|
|
5629
5840
|
return parameterName.replace(/_/g, "-");
|
|
5630
5841
|
}
|
|
5842
|
+
/**
|
|
5843
|
+
* Flag name for a request header an operation declares, such as
|
|
5844
|
+
* `--idempotency-key` for `Idempotency-Key`.
|
|
5845
|
+
*/
|
|
5846
|
+
function headerFlagName(headerName) {
|
|
5847
|
+
return headerName.toLowerCase().replace(/_/g, "-");
|
|
5848
|
+
}
|
|
5849
|
+
/**
|
|
5850
|
+
* True when `text` holds an ASCII control character. Header values
|
|
5851
|
+
* travel on the wire as given, so one (a line break above all) could
|
|
5852
|
+
* never be sent and is refused before the request.
|
|
5853
|
+
*/
|
|
5854
|
+
function hasControlCharacter(text) {
|
|
5855
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
5856
|
+
const code = text.charCodeAt(index);
|
|
5857
|
+
if (code < 32 || code === 127) return true;
|
|
5858
|
+
}
|
|
5859
|
+
return false;
|
|
5860
|
+
}
|
|
5861
|
+
/**
|
|
5862
|
+
* Read the declared-header flags the caller passed into a header map
|
|
5863
|
+
* keyed by the header name the spec declares. Only flags `buildFlags`
|
|
5864
|
+
* registered for a header are read.
|
|
5865
|
+
*/
|
|
5866
|
+
function collectHeaderFlags(parsedFlags, headerFlagToName) {
|
|
5867
|
+
const headers = {};
|
|
5868
|
+
for (const [flag, header] of headerFlagToName) {
|
|
5869
|
+
const value = parsedFlags[flag];
|
|
5870
|
+
if (value === void 0) continue;
|
|
5871
|
+
const text = String(value);
|
|
5872
|
+
if (text.trim() === "") throw new Errors.CLIError(`--${flag} must not be empty.`, { exit: 2 });
|
|
5873
|
+
if (hasControlCharacter(text)) throw new Errors.CLIError(`--${flag} must not contain control characters such as line breaks.`, { exit: 2 });
|
|
5874
|
+
headers[header] = text;
|
|
5875
|
+
}
|
|
5876
|
+
return headers;
|
|
5877
|
+
}
|
|
5631
5878
|
function flagDescription(parameter) {
|
|
5632
5879
|
return parameter.description ?? parameter.name;
|
|
5633
5880
|
}
|
|
@@ -5976,6 +6223,14 @@ function buildFlags(operation) {
|
|
|
5976
6223
|
bodyFieldFlagToProperty.set(name, extra.property);
|
|
5977
6224
|
}
|
|
5978
6225
|
}
|
|
6226
|
+
const headerFlagToName = /* @__PURE__ */ new Map();
|
|
6227
|
+
for (const parameter of operation.headerParams) {
|
|
6228
|
+
const name = headerFlagName(parameter.name);
|
|
6229
|
+
if (RESERVED_FLAG_NAMES.has(name)) continue;
|
|
6230
|
+
if (flags[name] !== void 0) continue;
|
|
6231
|
+
flags[name] = flagForParameter(parameter);
|
|
6232
|
+
headerFlagToName.set(name, parameter.name);
|
|
6233
|
+
}
|
|
5979
6234
|
if (EVENT_TYPES_FLAG_OPERATIONS.has(operation.sdkName)) flags["event-types"] = Flags.string({
|
|
5980
6235
|
description: EVENT_TYPES_FLAG_DESCRIPTION,
|
|
5981
6236
|
multiple: true
|
|
@@ -5988,7 +6243,8 @@ function buildFlags(operation) {
|
|
|
5988
6243
|
});
|
|
5989
6244
|
return {
|
|
5990
6245
|
flags,
|
|
5991
|
-
bodyFieldFlagToProperty
|
|
6246
|
+
bodyFieldFlagToProperty,
|
|
6247
|
+
headerFlagToName
|
|
5992
6248
|
};
|
|
5993
6249
|
}
|
|
5994
6250
|
function collectBodyFieldFlags(parsedFlags, bodyFieldFlagToProperty) {
|
|
@@ -6083,7 +6339,7 @@ const OPERATION_SUCCESS_HOOKS = { verifyAgentSignup: ({ envelope, configDir, api
|
|
|
6083
6339
|
writeStderr("Credentials saved to the CLI config; `primitive whoami` will work on the next call.\n");
|
|
6084
6340
|
} };
|
|
6085
6341
|
function createOperationCommand(operation) {
|
|
6086
|
-
const { flags, bodyFieldFlagToProperty } = buildFlags(operation);
|
|
6342
|
+
const { flags, bodyFieldFlagToProperty, headerFlagToName } = buildFlags(operation);
|
|
6087
6343
|
const baseDescription = operation.description !== null && operation.description !== void 0 ? canonicalizeCliReferences(operation.description) : `${operation.method} ${operation.path}`;
|
|
6088
6344
|
const schemaSummary = operation.hasJsonBody ? renderRequestSchemaSummary(operation.requestSchema) : null;
|
|
6089
6345
|
const hint = OPERATION_HINTS[operation.sdkName];
|
|
@@ -6099,6 +6355,7 @@ function createOperationCommand(operation) {
|
|
|
6099
6355
|
throw withFlagSuggestion(error, flagNames);
|
|
6100
6356
|
});
|
|
6101
6357
|
const parsedFlags = flags;
|
|
6358
|
+
const headers = collectHeaderFlags(parsedFlags, headerFlagToName);
|
|
6102
6359
|
if ([
|
|
6103
6360
|
"startAgentSignup",
|
|
6104
6361
|
"verifyAgentSignup",
|
|
@@ -6142,9 +6399,11 @@ function createOperationCommand(operation) {
|
|
|
6142
6399
|
const query = collectValues(operation.queryParams, parsedFlags);
|
|
6143
6400
|
const replyStateSurface = replyStateSurfaceForOperation(operation.sdkName, query);
|
|
6144
6401
|
const automatedSurface = automatedSurfaceForOperation(operation.sdkName, query);
|
|
6402
|
+
const fromVerified = fromVerifiedExpectation(operation.sdkName, query);
|
|
6145
6403
|
const callOperation = () => operationFn({
|
|
6146
6404
|
body,
|
|
6147
6405
|
client: apiClient.client,
|
|
6406
|
+
...Object.keys(headers).length > 0 ? { headers } : {},
|
|
6148
6407
|
parseAs: operation.binaryResponse ? "blob" : "auto",
|
|
6149
6408
|
path: collectValues(operation.pathParams, parsedFlags),
|
|
6150
6409
|
query,
|
|
@@ -6220,6 +6479,14 @@ function createOperationCommand(operation) {
|
|
|
6220
6479
|
process.exitCode = 1;
|
|
6221
6480
|
return;
|
|
6222
6481
|
}
|
|
6482
|
+
if (fromVerified) try {
|
|
6483
|
+
assertFromVerifiedRows(Array.isArray(envelope?.data) ? envelope.data : [], fromVerified);
|
|
6484
|
+
} catch (error) {
|
|
6485
|
+
if (!(error instanceof FromVerifiedFilterUnsupportedError)) throw error;
|
|
6486
|
+
process.stderr.write(`${error.message}\n`);
|
|
6487
|
+
process.exitCode = 1;
|
|
6488
|
+
return;
|
|
6489
|
+
}
|
|
6223
6490
|
const jsonOutput = parsedFlags.json === true;
|
|
6224
6491
|
const withEnvelope = parsedFlags.envelope === true;
|
|
6225
6492
|
const cursor = envelope?.meta?.cursor;
|
|
@@ -6276,4 +6543,4 @@ function canonicalizeCliReferences(description) {
|
|
|
6276
6543
|
return description.replaceAll("`primitive emails:latest`", "`primitive emails latest`").replaceAll("`primitive describe emails:get-email | jq '.responseSchema.properties'`", "`primitive describe emails:get | jq '.responseSchema.properties'`");
|
|
6277
6544
|
}
|
|
6278
6545
|
//#endregion
|
|
6279
|
-
export {
|
|
6546
|
+
export { MAX_SEND_WAIT_TIMEOUT_MS as $, listSentAttachmentArchiveMembers as $n, refreshStoredCliCredentials as $t, formatMailWakeLine as A, getFunction as An, updateFunction as Ar, loadSkillLine as At, clearConsumedPendingMail as B, listAgentContacts as Bn, automatedRejectedError as Bt, hasReplyState as C, getAccount as Cn, startAgentClaim as Cr, thrownErrorExitCode as Ct, bareAddress$1 as D, getCreditBalance as Dn, testFunction as Dr, defaultConnectionName as Dt, explainPendingMailNotFound as E, getConversation as En, stopRepeatFromEmail as Er, connectNextSteps as Et, serverRelationship as F, getOrgRoutingTopology as Fn, verifyAgentClaim as Fr, AUTOMATED_FILTER_UNSUPPORTED_CODE as Ft, removePendingMail as G, listDomains as Gn, queryUsesAutomated as Gt, pendingMailPath as H, listContacts as Hn, expectedAutomatedVerdicts as Ht, skillFirstLine as I, getRepeatingSend as In, verifyAgentSignup as Ir, AUTOMATED_FLAG_DESCRIPTION as It, readEmailInteraction as J, listEndpoints as Jn, withAttachmentWait as Jt, interactionHumanLine as K, listEmailAttachmentArchiveMembers as Kn, ATTACHMENT_WAIT_FLAG_DESCRIPTION as Kt, wakeReadCommand as L, getSentEmail as Ln, AUTOMATED_VALUES as Lt, readThreadContext as M, getFunctionTestRunTrace as Mn, updateRoute as Mr, formatAlreadySentNotice as Mt, sentInThread as N, getInboxStatus as Nn, updateWakeAuthorization as Nr, writeIdempotentReplayBannerIfReplay as Nt, describeWake as O, getDefaultNetworkAgent as On, unsetFunctionRoute as Or, generatedAgentName as Ot, serverMuted as P, getMemory as Pn, updateWakeSchedule as Pr, withFlagSuggestion as Pt, IDEMPOTENCY_KEY_FLAG_DESCRIPTION as Q, listRoutes as Qn, createCliApiClient as Qt, wakeRecipientField as R, getThread as Rn, AutomatedFilterUnsupportedError as Rt, formatRepliesCell as S, downloadSentAttachmentByFilename as Sn, simulateRoute as Sr, successfulSendOutcome as St, queryUsesAwaiting as T, getContact as Tn, startCliLogin as Tr, cliInvocation as Tt, readPendingMail as U, listDefaultNetworkAgents as Un, hasAutomatedVerdict as Ut, clearReadPendingMail as V, listAgentNetworks as Vn, ensureSearchReportsAutomated as Vt, recordPendingMail as W, listDefaultNetworkMembers as Wn, isAutomatedRejectedError as Wt, replyInteractionWarning as X, listFunctions as Xn, SAVED_CLI_OAUTH_SESSION_EXPIRED_MESSAGE as Xt, replyExpectation as Y, listFunctionLogs as Yn, ConnectedAgentKeyRequiredError as Yt, wakeInteractionSentence as Z, listRepeatingSends as Zn, createAuthenticatedCliApiClient as Zt, ReplyStateUnsupportedError as _, deleteWakeSchedule as _n, semanticSearch as _r, sendIdentityFields as _t, extractErrorCode as a, cliLogout as an, pullWebhookEvent as ar, checkPriorReplies as at, ensureSearchReportsReplyState as b, downloadEmailAttachmentPart as bn, setFunctionSecret as br, sentHistoryWindowStart as bt, hasControlCharacter as c, createFunction as cn, putContact as cr, excludeSignalReplies as ct, runWithTiming as d, createWakeSchedule as dn, reorderRoutes as dr, formatPriorRepliesCheckSkipped as dt, resolveCliApiRequestConfig as en, listSentEmails as er, SEND_OUTCOME_HELP as et, surfaceUnauthorizedHint as f, deleteAgentContact as fn, replyToEmail as fr, formatPriorRepliesWarning as ft, REPLY_STATE_UNSUPPORTED_CODE as g, deleteWakeAuthorization as gn, searchMemories as gr, reportSendCommandResult as gt, AWAITING_VALUES as h, deleteRoute as hn, searchEmails as hr, priorRepliesThatWentOut as ht, createOperationCommand as i, checkDefaultNetworkContactAdmission as in, pollCliLogin as ir, buildThrownSendFailureEnvelope as it, latestOwnOutbound as j, getFunctionRouting as jn, updateRepeatingSend as jr, currentMailSessionKey as jt, displayAddress as k, getEmail as kn, updateDefaultNetworkMember as kr, identitySuggestions as kt, headerFlagName as l, createRoute as ln, redeemCreditCode as lr, followUpCommandPrefix as lt, AWAITING_FLAG_DESCRIPTION as m, deleteMemory as mn, runWakeSchedule as mr, formatSendRecordFailureSummary as mt, API_ERROR_CODES as n, cancelSentEmail as nn, listWakeDispatches as nr, assertValidIdempotencyKey as nt, extractErrorPayload as o, completeWebhookEvent as on, putAgentContact as or, classifySendError as ot, writeErrorWithHints as p, deleteContact as pn, resendAgentSignupVerification as pr, formatSendFailureSummary as pt, interactionNextActions as q, listEmails as qn, ATTACHMENT_WAIT_MAX_MS as qt, TIME_FLAG_DESCRIPTION as r, cancelSentEmailByIdempotencyKey as rn, listWakeSchedules as rr, buildFollowUpCommand as rt, formatErrorPayload as s, createEndpoint as sn, putAgentContactPolicy as sr, deriveSendIdempotencyKey as st, API_BASE_URL_FLAG_DESCRIPTION as t, addDefaultNetworkMember as tn, listWakeAuthorizations as tr, apiResultHttpStatus as tt, readTextFileFlag as u, createWakeAuthorization as un, removeDefaultNetworkMember as ur, formatDeletedEarlierSendNotice as ut, assertAwaitingFilterRows as v, downloadEmailAttachmentArchiveMember as vn, sendEmail as vr, sendOutcomeExitCode as vt, isAwaitingRejectedError as w, getAgentContactPolicy as wn, startAgentSignup as wr, DEFAULT_ENROLL_NAME as wt, formatAwaitingCell as x, downloadSentAttachmentArchiveMember as xn, setMemory as xr, serializeErrorPayload as xt, awaitingRejectedError as y, downloadEmailAttachmentByFilename as yn, setFunctionRoute as yr, sendWaitClampNotice as yt, wakeRelationship as z, getWakeSchedule as zn, assertAutomatedVerdict as zt };
|
|
@@ -636,6 +636,17 @@ var PrimitiveApiClient = class {
|
|
|
636
636
|
//#endregion
|
|
637
637
|
//#region src/oclif/connected-agent-profile.ts
|
|
638
638
|
const AGENT_PROFILE_ENV = "PRIMITIVE_AGENT_PROFILE";
|
|
639
|
+
/**
|
|
640
|
+
* The selected agent's email address, exported next to AGENT_PROFILE_ENV for
|
|
641
|
+
* a registered session so other tools can read it without running the CLI.
|
|
642
|
+
*/
|
|
643
|
+
const AGENT_ADDRESS_ENV = "PRIMITIVE_AGENT_ADDRESS";
|
|
644
|
+
/**
|
|
645
|
+
* One sentence telling a session whose agent is selected how to run a command
|
|
646
|
+
* as the member login instead. An empty PRIMITIVE_AGENT_PROFILE selects no
|
|
647
|
+
* profile everywhere in the CLI.
|
|
648
|
+
*/
|
|
649
|
+
const MEMBER_LOGIN_OPT_OUT = "rerun the same command with `PRIMITIVE_AGENT_PROFILE=` in front of it (or under `env -u PRIMITIVE_AGENT_PROFILE`) to run it as the member login";
|
|
639
650
|
function parsePresenceProfile(value, owner) {
|
|
640
651
|
const row = mailObject(value, [
|
|
641
652
|
"protocol",
|
|
@@ -661,7 +672,7 @@ function supportedPresenceProfile(value, owner) {
|
|
|
661
672
|
}
|
|
662
673
|
var AgentConnectionSetupError = class extends Error {};
|
|
663
674
|
function requireDefaultLoginProfile() {
|
|
664
|
-
if (process.env["PRIMITIVE_AGENT_PROFILE"]?.trim()) throw new AgentConnectionSetupError(
|
|
675
|
+
if (process.env["PRIMITIVE_AGENT_PROFILE"]?.trim()) throw new AgentConnectionSetupError(`This command manages the member login, so it does not run as the agent selected by PRIMITIVE_AGENT_PROFILE; ${MEMBER_LOGIN_OPT_OUT}, and the agent profile is unchanged.`);
|
|
665
676
|
}
|
|
666
677
|
function agentProfileName(value) {
|
|
667
678
|
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/.test(value)) throw new AgentConnectionSetupError("Agent profile must start with a letter or number and contain only letters, numbers, dots, underscores or hyphens (at most 63 characters).");
|
|
@@ -1282,8 +1293,8 @@ function resolveCliAuth(params) {
|
|
|
1282
1293
|
const profileName = (params.env ?? process.env)["PRIMITIVE_AGENT_PROFILE"]?.trim() || void 0;
|
|
1283
1294
|
if (profileName !== void 0) {
|
|
1284
1295
|
const profile = loadConnectedAgentProfile(params.configDir, profileName);
|
|
1285
|
-
if (!profile) throw new AgentConnectionSetupError(
|
|
1286
|
-
if (apiKey && apiKey !== profile.api_key || params.apiBaseUrl !== void 0 && apiBaseUrl !== profile.api_base_url) throw new AgentConnectionSetupError(
|
|
1296
|
+
if (!profile) throw new AgentConnectionSetupError(`Agent profile ${profileName} selected by PRIMITIVE_AGENT_PROFILE is not saved on this machine, so no login is used; run \`primitive agent status --profile ${profileName}\` to see what happened to it, or ${MEMBER_LOGIN_OPT_OUT}.`);
|
|
1297
|
+
if (apiKey && apiKey !== profile.api_key || params.apiBaseUrl !== void 0 && apiBaseUrl !== profile.api_base_url) throw new AgentConnectionSetupError(`An explicit API key or API origin conflicts with agent profile ${profileName} selected by PRIMITIVE_AGENT_PROFILE; drop the override to act as that agent, or rerun the same command with \`PRIMITIVE_AGENT_PROFILE=\` in front of it to use the override.`);
|
|
1287
1298
|
return {
|
|
1288
1299
|
apiKey: profile.api_key,
|
|
1289
1300
|
apiBaseUrl: profile.api_base_url,
|
|
@@ -1492,4 +1503,4 @@ function redactCliEnvironment(environment) {
|
|
|
1492
1503
|
};
|
|
1493
1504
|
}
|
|
1494
1505
|
//#endregion
|
|
1495
|
-
export { saveActiveChatState as A,
|
|
1506
|
+
export { saveActiveChatState as A, parseConnectedAgentProfile as B, resolveCliAuth as C, deleteChatState as D, chatStatePath as E, agentProfileName as F, PrimitiveApiClient as G, profileAlreadyConnectedMessage as H, agentProfilesDirectory as I, createClient as K, connectedAgentIdentity as L, AGENT_PROFILE_ENV as M, AgentConnectionSetupError as N, loadActiveChatState as O, agentProfileDirectory as P, connectedApiBaseUrl as R, normalizeApiBaseUrl as S, saveSignupCredentials as T, requireDefaultLoginProfile as U, parseOwnerMemberAddress as V, saveConnectedAgentProfile as W, deleteCliCredentials as _, normalizeCliEnvironmentName as a, hasStoredCliLogin as b, resolveConfigEnvironment as c, validateCliHeaderName as d, validateCliHeaderValue as f, credentialsPath as g, credentialsLockPath as h, loadCliConfig as i, AGENT_ADDRESS_ENV as j, loadChatConversationByLocalId as k, saveCliConfig as l, cliAccessTokenExpiresAt as m, deleteCliConfig as n, redactCliEnvironment as o, acquireCliCredentialsLock as p, createConfig as q, emptyCliConfig as r, removeCliEnvironment as s, DEFAULT_ENVIRONMENT as t, upsertCliEnvironment as u, deleteCliCredentialsLock as v, saveCliCredentials as w, loadCliCredentials as x, detectPrimitiveKeyEnvMisname as y, loadConnectedAgentProfile as z };
|