@primitivedotdev/cli 1.2.1 → 1.4.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/oclif/index.js +1060 -12
- package/package.json +7 -1
package/dist/oclif/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import { Args, Command, Errors, Flags, ux } from "@oclif/core";
|
|
|
3
3
|
import { chmodSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import path, { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
6
|
-
import { hostname } from "node:os";
|
|
7
6
|
import process$1 from "node:process";
|
|
8
7
|
import { createInterface } from "node:readline/promises";
|
|
8
|
+
import { hostname } from "node:os";
|
|
9
9
|
import { spawn } from "node:child_process";
|
|
10
10
|
//#region \0rolldown/runtime.js
|
|
11
11
|
var __defProp = Object.defineProperty;
|
|
@@ -26,6 +26,8 @@ const client = createClient(createConfig({ baseUrl: "https://api.primitive.dev/v
|
|
|
26
26
|
var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
27
27
|
addDomain: () => addDomain,
|
|
28
28
|
cliLogout: () => cliLogout,
|
|
29
|
+
createAgentAccount: () => createAgentAccount,
|
|
30
|
+
createAgentClaimLink: () => createAgentClaimLink,
|
|
29
31
|
createEndpoint: () => createEndpoint,
|
|
30
32
|
createFilter: () => createFilter,
|
|
31
33
|
createFunction: () => createFunction,
|
|
@@ -74,6 +76,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
74
76
|
sendEmail: () => sendEmail,
|
|
75
77
|
setFunctionRoute: () => setFunctionRoute,
|
|
76
78
|
setFunctionSecret: () => setFunctionSecret,
|
|
79
|
+
startAgentClaim: () => startAgentClaim,
|
|
77
80
|
startAgentSignup: () => startAgentSignup,
|
|
78
81
|
startCliLogin: () => startCliLogin,
|
|
79
82
|
startCliSignup: () => startCliSignup,
|
|
@@ -85,6 +88,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
85
88
|
updateEndpoint: () => updateEndpoint,
|
|
86
89
|
updateFilter: () => updateFilter,
|
|
87
90
|
updateFunction: () => updateFunction,
|
|
91
|
+
verifyAgentClaim: () => verifyAgentClaim,
|
|
88
92
|
verifyAgentSignup: () => verifyAgentSignup,
|
|
89
93
|
verifyCliSignup: () => verifyCliSignup,
|
|
90
94
|
verifyDomain: () => verifyDomain
|
|
@@ -229,6 +233,92 @@ const verifyAgentSignup = (options) => (options.client ?? client).post({
|
|
|
229
233
|
}
|
|
230
234
|
});
|
|
231
235
|
/**
|
|
236
|
+
* Create an emailless agent account
|
|
237
|
+
*
|
|
238
|
+
* Creates an emailless agent account without authentication and returns a
|
|
239
|
+
* one-time API key (prefixed `prim_`) plus a provisioned managed inbox.
|
|
240
|
+
* The account is on the `agent` plan: reply-only (it can send only to
|
|
241
|
+
* addresses that have already sent it authenticated mail) with tight send
|
|
242
|
+
* limits. Use the returned `api_key` as a Bearer token on later calls. The
|
|
243
|
+
* account can be upgraded to a full developer account by confirming an
|
|
244
|
+
* email through the claim flow. This endpoint does not require an API key.
|
|
245
|
+
*
|
|
246
|
+
*/
|
|
247
|
+
const createAgentAccount = (options) => (options.client ?? client).post({
|
|
248
|
+
url: "/agent/accounts",
|
|
249
|
+
...options,
|
|
250
|
+
headers: {
|
|
251
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
252
|
+
...options.headers
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
/**
|
|
256
|
+
* Start an agent account email claim
|
|
257
|
+
*
|
|
258
|
+
* Begins upgrading an emailless `agent` account into a full `developer`
|
|
259
|
+
* account by confirming an email address. Authenticated by the agent's own
|
|
260
|
+
* API key (the org is taken from the credential). Sends a verification
|
|
261
|
+
* code to the supplied email and returns the claim session id plus resend
|
|
262
|
+
* timing. Submit the code to `/agent/claim/verify` to complete the
|
|
263
|
+
* upgrade. Confirming an email that already belongs to a Primitive account
|
|
264
|
+
* is rejected.
|
|
265
|
+
*
|
|
266
|
+
*/
|
|
267
|
+
const startAgentClaim = (options) => (options.client ?? client).post({
|
|
268
|
+
security: [{
|
|
269
|
+
scheme: "bearer",
|
|
270
|
+
type: "http"
|
|
271
|
+
}],
|
|
272
|
+
url: "/agent/claim/start",
|
|
273
|
+
...options,
|
|
274
|
+
headers: {
|
|
275
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
276
|
+
...options.headers
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
/**
|
|
280
|
+
* Verify an agent account email claim
|
|
281
|
+
*
|
|
282
|
+
* Confirms the verification code emailed by `/agent/claim/start` and
|
|
283
|
+
* upgrades the account to the `developer` plan. The org id, API key, and
|
|
284
|
+
* managed inbox all carry over; the send cap lifts. Authenticated by the
|
|
285
|
+
* agent's own API key.
|
|
286
|
+
*
|
|
287
|
+
*/
|
|
288
|
+
const verifyAgentClaim = (options) => (options.client ?? client).post({
|
|
289
|
+
security: [{
|
|
290
|
+
scheme: "bearer",
|
|
291
|
+
type: "http"
|
|
292
|
+
}],
|
|
293
|
+
url: "/agent/claim/verify",
|
|
294
|
+
...options,
|
|
295
|
+
headers: {
|
|
296
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
297
|
+
...options.headers
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
/**
|
|
301
|
+
* Create a browser claim link
|
|
302
|
+
*
|
|
303
|
+
* Mints an opaque, single-use link an agent can hand to a human to
|
|
304
|
+
* complete the email-confirmation upgrade in a browser. Authenticated by
|
|
305
|
+
* the agent's own API key. `claim_url` is null when the API host cannot
|
|
306
|
+
* resolve a web origin to build the link.
|
|
307
|
+
*
|
|
308
|
+
*/
|
|
309
|
+
const createAgentClaimLink = (options) => (options?.client ?? client).post({
|
|
310
|
+
security: [{
|
|
311
|
+
scheme: "bearer",
|
|
312
|
+
type: "http"
|
|
313
|
+
}],
|
|
314
|
+
url: "/agent/claim/link",
|
|
315
|
+
...options,
|
|
316
|
+
headers: {
|
|
317
|
+
"Content-Type": "application/json",
|
|
318
|
+
...options?.headers
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
/**
|
|
232
322
|
* Revoke the current CLI OAuth session
|
|
233
323
|
*
|
|
234
324
|
* Revokes the OAuth grant used to authenticate the request. API-key
|
|
@@ -1104,10 +1194,12 @@ const listFunctions = (options) => (options?.client ?? client).get({
|
|
|
1104
1194
|
* each delivery and forwards the `Primitive-Signature` header to
|
|
1105
1195
|
* the handler. Verify the raw request body with
|
|
1106
1196
|
* `PRIMITIVE_WEBHOOK_SECRET` before parsing JSON; after verification
|
|
1107
|
-
* the request body parses to
|
|
1108
|
-
* `
|
|
1109
|
-
*
|
|
1110
|
-
*
|
|
1197
|
+
* the request body parses to a webhook event whose `event` field is
|
|
1198
|
+
* `email.received` for normal inbound mail, or a machine-mail type
|
|
1199
|
+
* (`email.bounced`, `email.tls_report`, `email.dmarc_report`,
|
|
1200
|
+
* `email.dmarc_failure`) for bounces and reports. Code is bundled
|
|
1201
|
+
* before being uploaded; ship a single self-contained file rather
|
|
1202
|
+
* than relying on external imports.
|
|
1111
1203
|
*
|
|
1112
1204
|
* **Code limits.** `code` is capped at 1 MiB UTF-8. `sourceMap`
|
|
1113
1205
|
* (optional) is capped at 5 MiB UTF-8, stored with each deployment
|
|
@@ -1528,7 +1620,7 @@ const openapiDocument = {
|
|
|
1528
1620
|
},
|
|
1529
1621
|
{
|
|
1530
1622
|
"name": "Functions",
|
|
1531
|
-
"description": "Deploy JavaScript handlers that run on inbound mail. Each function\nis a single ESM module whose default export is an object with an\nasync `fetch(request, env)` method, in the shape of a Workers-style\nhandler. Primitive signs each delivery and forwards the\n`Primitive-Signature` header to the handler; verify the raw request\nbody with `PRIMITIVE_WEBHOOK_SECRET` before trusting the parsed
|
|
1623
|
+
"description": "Deploy JavaScript handlers that run on inbound mail. Each function\nis a single ESM module whose default export is an object with an\nasync `fetch(request, env)` method, in the shape of a Workers-style\nhandler. Primitive signs each delivery and forwards the\n`Primitive-Signature` header to the handler; verify the raw request\nbody with `PRIMITIVE_WEBHOOK_SECRET` before trusting the parsed event.\nThe `event` field is `email.received` for normal inbound mail, or a\nmachine-mail type (`email.bounced`, `email.tls_report`,\n`email.dmarc_report`, `email.dmarc_failure`) for bounces and reports;\nthe payload shape is otherwise identical. Code runs on\nPrimitive's edge runtime; there is no infrastructure to manage.\nSecrets land in `env` as encrypted bindings and are refreshed on\nevery redeploy.\n"
|
|
1532
1624
|
}
|
|
1533
1625
|
],
|
|
1534
1626
|
"paths": {
|
|
@@ -1834,6 +1926,128 @@ const openapiDocument = {
|
|
|
1834
1926
|
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
1835
1927
|
}
|
|
1836
1928
|
} },
|
|
1929
|
+
"/agent/accounts": { "post": {
|
|
1930
|
+
"operationId": "createAgentAccount",
|
|
1931
|
+
"summary": "Create an emailless agent account",
|
|
1932
|
+
"description": "Creates an emailless agent account without authentication and returns a\none-time API key (prefixed `prim_`) plus a provisioned managed inbox.\nThe account is on the `agent` plan: reply-only (it can send only to\naddresses that have already sent it authenticated mail) with tight send\nlimits. Use the returned `api_key` as a Bearer token on later calls. The\naccount can be upgraded to a full developer account by confirming an\nemail through the claim flow. This endpoint does not require an API key.\n",
|
|
1933
|
+
"tags": ["Agent"],
|
|
1934
|
+
"security": [],
|
|
1935
|
+
"requestBody": {
|
|
1936
|
+
"required": true,
|
|
1937
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAgentAccountInput" } } }
|
|
1938
|
+
},
|
|
1939
|
+
"responses": {
|
|
1940
|
+
"200": {
|
|
1941
|
+
"description": "Agent account created; the API key is returned once",
|
|
1942
|
+
"headers": { "Cache-Control": {
|
|
1943
|
+
"schema": { "type": "string" },
|
|
1944
|
+
"description": "Always `no-store`"
|
|
1945
|
+
} },
|
|
1946
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
1947
|
+
"type": "object",
|
|
1948
|
+
"properties": { "data": { "$ref": "#/components/schemas/AgentAccountResult" } }
|
|
1949
|
+
}] } } }
|
|
1950
|
+
},
|
|
1951
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
1952
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
1953
|
+
}
|
|
1954
|
+
} },
|
|
1955
|
+
"/agent/claim/start": { "post": {
|
|
1956
|
+
"operationId": "startAgentClaim",
|
|
1957
|
+
"summary": "Start an agent account email claim",
|
|
1958
|
+
"description": "Begins upgrading an emailless `agent` account into a full `developer`\naccount by confirming an email address. Authenticated by the agent's own\nAPI key (the org is taken from the credential). Sends a verification\ncode to the supplied email and returns the claim session id plus resend\ntiming. Submit the code to `/agent/claim/verify` to complete the\nupgrade. Confirming an email that already belongs to a Primitive account\nis rejected.\n",
|
|
1959
|
+
"tags": ["Agent"],
|
|
1960
|
+
"requestBody": {
|
|
1961
|
+
"required": true,
|
|
1962
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/StartAgentClaimInput" } } }
|
|
1963
|
+
},
|
|
1964
|
+
"responses": {
|
|
1965
|
+
"200": {
|
|
1966
|
+
"description": "Claim started and verification email sent",
|
|
1967
|
+
"headers": { "Cache-Control": {
|
|
1968
|
+
"schema": { "type": "string" },
|
|
1969
|
+
"description": "Always `no-store`"
|
|
1970
|
+
} },
|
|
1971
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
1972
|
+
"type": "object",
|
|
1973
|
+
"properties": { "data": { "$ref": "#/components/schemas/AgentClaimStartResult" } }
|
|
1974
|
+
}] } } }
|
|
1975
|
+
},
|
|
1976
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
1977
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
1978
|
+
"404": { "$ref": "#/components/responses/NotFound" },
|
|
1979
|
+
"409": {
|
|
1980
|
+
"description": "The email is already in use, or the account is not claimable",
|
|
1981
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
|
|
1982
|
+
},
|
|
1983
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
1984
|
+
}
|
|
1985
|
+
} },
|
|
1986
|
+
"/agent/claim/verify": { "post": {
|
|
1987
|
+
"operationId": "verifyAgentClaim",
|
|
1988
|
+
"summary": "Verify an agent account email claim",
|
|
1989
|
+
"description": "Confirms the verification code emailed by `/agent/claim/start` and\nupgrades the account to the `developer` plan. The org id, API key, and\nmanaged inbox all carry over; the send cap lifts. Authenticated by the\nagent's own API key.\n",
|
|
1990
|
+
"tags": ["Agent"],
|
|
1991
|
+
"requestBody": {
|
|
1992
|
+
"required": true,
|
|
1993
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifyAgentClaimInput" } } }
|
|
1994
|
+
},
|
|
1995
|
+
"responses": {
|
|
1996
|
+
"200": {
|
|
1997
|
+
"description": "Claim verified; account upgraded to developer",
|
|
1998
|
+
"headers": { "Cache-Control": {
|
|
1999
|
+
"schema": { "type": "string" },
|
|
2000
|
+
"description": "Always `no-store`"
|
|
2001
|
+
} },
|
|
2002
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
2003
|
+
"type": "object",
|
|
2004
|
+
"properties": { "data": { "$ref": "#/components/schemas/AgentClaimResult" } }
|
|
2005
|
+
}] } } }
|
|
2006
|
+
},
|
|
2007
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
2008
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
2009
|
+
"404": { "$ref": "#/components/responses/NotFound" },
|
|
2010
|
+
"409": {
|
|
2011
|
+
"description": "The account is already claimed, or the email is in use",
|
|
2012
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
|
|
2013
|
+
},
|
|
2014
|
+
"410": {
|
|
2015
|
+
"description": "The claim or its verification code has expired",
|
|
2016
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
|
|
2017
|
+
},
|
|
2018
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
2019
|
+
}
|
|
2020
|
+
} },
|
|
2021
|
+
"/agent/claim/link": { "post": {
|
|
2022
|
+
"operationId": "createAgentClaimLink",
|
|
2023
|
+
"summary": "Create a browser claim link",
|
|
2024
|
+
"description": "Mints an opaque, single-use link an agent can hand to a human to\ncomplete the email-confirmation upgrade in a browser. Authenticated by\nthe agent's own API key. `claim_url` is null when the API host cannot\nresolve a web origin to build the link.\n",
|
|
2025
|
+
"tags": ["Agent"],
|
|
2026
|
+
"requestBody": {
|
|
2027
|
+
"required": false,
|
|
2028
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAgentClaimLinkInput" } } }
|
|
2029
|
+
},
|
|
2030
|
+
"responses": {
|
|
2031
|
+
"200": {
|
|
2032
|
+
"description": "Claim link created",
|
|
2033
|
+
"headers": { "Cache-Control": {
|
|
2034
|
+
"schema": { "type": "string" },
|
|
2035
|
+
"description": "Always `no-store`"
|
|
2036
|
+
} },
|
|
2037
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
2038
|
+
"type": "object",
|
|
2039
|
+
"properties": { "data": { "$ref": "#/components/schemas/AgentClaimLinkResult" } }
|
|
2040
|
+
}] } } }
|
|
2041
|
+
},
|
|
2042
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
2043
|
+
"404": { "$ref": "#/components/responses/NotFound" },
|
|
2044
|
+
"409": {
|
|
2045
|
+
"description": "The account is not claimable (not an agent account, or already claimed)",
|
|
2046
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
|
|
2047
|
+
},
|
|
2048
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
2049
|
+
}
|
|
2050
|
+
} },
|
|
1837
2051
|
"/cli/logout": { "post": {
|
|
1838
2052
|
"operationId": "cliLogout",
|
|
1839
2053
|
"summary": "Revoke the current CLI OAuth session",
|
|
@@ -2178,6 +2392,25 @@ const openapiDocument = {
|
|
|
2178
2392
|
"format": "date-time"
|
|
2179
2393
|
},
|
|
2180
2394
|
"description": "Filter emails created on or before this timestamp"
|
|
2395
|
+
},
|
|
2396
|
+
{
|
|
2397
|
+
"name": "since",
|
|
2398
|
+
"in": "query",
|
|
2399
|
+
"schema": {
|
|
2400
|
+
"type": "string",
|
|
2401
|
+
"maxLength": 200
|
|
2402
|
+
},
|
|
2403
|
+
"description": "Forward-tail cursor. Returns rows that became visible AFTER this\ncursor, oldest-first, so a caller can stream new inbound mail by\nre-passing the cursor from each response. Mutually exclusive with\n`cursor` (which pages history newest-first). Pass the `meta.cursor`\nfrom the previous `since` response; an empty page means caught up.\n"
|
|
2404
|
+
},
|
|
2405
|
+
{
|
|
2406
|
+
"name": "wait",
|
|
2407
|
+
"in": "query",
|
|
2408
|
+
"schema": {
|
|
2409
|
+
"type": "integer",
|
|
2410
|
+
"minimum": 0,
|
|
2411
|
+
"maximum": 30
|
|
2412
|
+
},
|
|
2413
|
+
"description": "Long-poll: hold the request up to this many seconds waiting for new\nmail past `since`, returning as soon as any arrives (or an empty\npage when the wait elapses). Requires `since`. Omitted means no wait\n(returns immediately); the server treats an absent value as 0. NOT\ngiven an OpenAPI `default` on purpose: a default makes some\ngenerators (e.g. openapi-python-client) send `wait=0` on every call,\nwhich then fails the `wait` requires `since` check for plain history\nlistings.\n"
|
|
2181
2414
|
}
|
|
2182
2415
|
],
|
|
2183
2416
|
"responses": {
|
|
@@ -3117,7 +3350,7 @@ const openapiDocument = {
|
|
|
3117
3350
|
"post": {
|
|
3118
3351
|
"operationId": "createFunction",
|
|
3119
3352
|
"summary": "Deploy a function",
|
|
3120
|
-
"description": "Creates and deploys a new function. The handler must be a single\nESM module whose default export is an object with an async\n`fetch(request, env)` method (Workers-style). Primitive signs\neach delivery and forwards the `Primitive-Signature` header to\nthe handler. Verify the raw request body with\n`PRIMITIVE_WEBHOOK_SECRET` before parsing JSON; after verification\nthe request body parses to
|
|
3353
|
+
"description": "Creates and deploys a new function. The handler must be a single\nESM module whose default export is an object with an async\n`fetch(request, env)` method (Workers-style). Primitive signs\neach delivery and forwards the `Primitive-Signature` header to\nthe handler. Verify the raw request body with\n`PRIMITIVE_WEBHOOK_SECRET` before parsing JSON; after verification\nthe request body parses to a webhook event whose `event` field is\n`email.received` for normal inbound mail, or a machine-mail type\n(`email.bounced`, `email.tls_report`, `email.dmarc_report`,\n`email.dmarc_failure`) for bounces and reports. Code is bundled\nbefore being uploaded; ship a single self-contained file rather\nthan relying on external imports.\n\n**Code limits.** `code` is capped at 1 MiB UTF-8. `sourceMap`\n(optional) is capped at 5 MiB UTF-8, stored with each deployment\nattempt, and sent to the runtime so stack traces can resolve to\noriginal source files.\n\n**Routing.** On successful deploy, the function code is live\nin the runtime, but inbound mail will not reach it until at\nleast one route is bound. Routes are managed from the Primitive\ndashboard. A `deploy_status` of `deployed` means the script is\ninstalled, not that the function is receiving mail. The\ninternal runtime URL is not returned by the API and is not a\ncustomer-facing integration surface.\n\n**Secrets.** New functions ship with the managed secrets\n(`PRIMITIVE_WEBHOOK_SECRET`, `PRIMITIVE_API_KEY`,\n`PRIMITIVE_API_BASE_URL`) already bound. Add user-set secrets via\n`POST /functions/{id}/secrets`; secret writes only land in the\nrunning handler on the next redeploy.\n",
|
|
3121
3354
|
"tags": ["Functions"],
|
|
3122
3355
|
"requestBody": {
|
|
3123
3356
|
"required": true,
|
|
@@ -4428,6 +4661,177 @@ const openapiDocument = {
|
|
|
4428
4661
|
"orgs"
|
|
4429
4662
|
]
|
|
4430
4663
|
},
|
|
4664
|
+
"PlanLimits": {
|
|
4665
|
+
"type": "object",
|
|
4666
|
+
"description": "Plan-derived quota limits for an account.",
|
|
4667
|
+
"properties": {
|
|
4668
|
+
"storage_mb": { "type": "number" },
|
|
4669
|
+
"send_per_hour": { "type": "number" },
|
|
4670
|
+
"send_per_day": { "type": "number" },
|
|
4671
|
+
"api_per_minute": { "type": "number" },
|
|
4672
|
+
"webhooks_max_global": { "type": ["number", "null"] },
|
|
4673
|
+
"webhooks_per_domain": { "type": "boolean" },
|
|
4674
|
+
"filters_per_domain": { "type": "boolean" },
|
|
4675
|
+
"spam_thresholds_per_domain": { "type": "boolean" }
|
|
4676
|
+
},
|
|
4677
|
+
"required": [
|
|
4678
|
+
"storage_mb",
|
|
4679
|
+
"send_per_hour",
|
|
4680
|
+
"send_per_day",
|
|
4681
|
+
"api_per_minute",
|
|
4682
|
+
"webhooks_max_global",
|
|
4683
|
+
"webhooks_per_domain",
|
|
4684
|
+
"filters_per_domain",
|
|
4685
|
+
"spam_thresholds_per_domain"
|
|
4686
|
+
]
|
|
4687
|
+
},
|
|
4688
|
+
"CreateAgentAccountInput": {
|
|
4689
|
+
"type": "object",
|
|
4690
|
+
"additionalProperties": false,
|
|
4691
|
+
"properties": {
|
|
4692
|
+
"terms_accepted": {
|
|
4693
|
+
"type": "boolean",
|
|
4694
|
+
"enum": [true],
|
|
4695
|
+
"description": "Must be true to accept the Terms of Service and Privacy Policy."
|
|
4696
|
+
},
|
|
4697
|
+
"device_name": {
|
|
4698
|
+
"type": "string",
|
|
4699
|
+
"minLength": 1,
|
|
4700
|
+
"maxLength": 80,
|
|
4701
|
+
"description": "Optional label for the device or agent creating the account."
|
|
4702
|
+
}
|
|
4703
|
+
},
|
|
4704
|
+
"required": ["terms_accepted"]
|
|
4705
|
+
},
|
|
4706
|
+
"AgentAccountUpgradeHint": {
|
|
4707
|
+
"type": "object",
|
|
4708
|
+
"description": "In-band pointer to the upgrade path for an agent account.",
|
|
4709
|
+
"properties": {
|
|
4710
|
+
"plan": {
|
|
4711
|
+
"type": "string",
|
|
4712
|
+
"enum": ["developer"]
|
|
4713
|
+
},
|
|
4714
|
+
"description": { "type": "string" },
|
|
4715
|
+
"claim_path": { "type": "string" }
|
|
4716
|
+
},
|
|
4717
|
+
"required": [
|
|
4718
|
+
"plan",
|
|
4719
|
+
"description",
|
|
4720
|
+
"claim_path"
|
|
4721
|
+
]
|
|
4722
|
+
},
|
|
4723
|
+
"AgentAccountResult": {
|
|
4724
|
+
"type": "object",
|
|
4725
|
+
"properties": {
|
|
4726
|
+
"api_key": {
|
|
4727
|
+
"type": "string",
|
|
4728
|
+
"description": "One-time API key (prefixed `prim_`). Shown once; store it securely."
|
|
4729
|
+
},
|
|
4730
|
+
"org_id": {
|
|
4731
|
+
"type": "string",
|
|
4732
|
+
"format": "uuid"
|
|
4733
|
+
},
|
|
4734
|
+
"address": {
|
|
4735
|
+
"type": ["string", "null"],
|
|
4736
|
+
"description": "Provisioned managed inbox FQDN, or null if the inbox publish was deferred."
|
|
4737
|
+
},
|
|
4738
|
+
"plan": {
|
|
4739
|
+
"type": "string",
|
|
4740
|
+
"enum": ["agent"]
|
|
4741
|
+
},
|
|
4742
|
+
"limits": { "$ref": "#/components/schemas/PlanLimits" },
|
|
4743
|
+
"upgrade": { "$ref": "#/components/schemas/AgentAccountUpgradeHint" }
|
|
4744
|
+
},
|
|
4745
|
+
"required": [
|
|
4746
|
+
"api_key",
|
|
4747
|
+
"org_id",
|
|
4748
|
+
"address",
|
|
4749
|
+
"plan",
|
|
4750
|
+
"limits",
|
|
4751
|
+
"upgrade"
|
|
4752
|
+
]
|
|
4753
|
+
},
|
|
4754
|
+
"StartAgentClaimInput": {
|
|
4755
|
+
"type": "object",
|
|
4756
|
+
"additionalProperties": false,
|
|
4757
|
+
"properties": { "email": {
|
|
4758
|
+
"type": "string",
|
|
4759
|
+
"format": "email",
|
|
4760
|
+
"maxLength": 254,
|
|
4761
|
+
"description": "Email to confirm. Must not already belong to a Primitive account."
|
|
4762
|
+
} },
|
|
4763
|
+
"required": ["email"]
|
|
4764
|
+
},
|
|
4765
|
+
"AgentClaimStartResult": {
|
|
4766
|
+
"type": "object",
|
|
4767
|
+
"properties": {
|
|
4768
|
+
"claim_session_id": { "type": "string" },
|
|
4769
|
+
"resend_after_seconds": { "type": "integer" },
|
|
4770
|
+
"expires_in_seconds": { "type": "integer" }
|
|
4771
|
+
},
|
|
4772
|
+
"required": [
|
|
4773
|
+
"claim_session_id",
|
|
4774
|
+
"resend_after_seconds",
|
|
4775
|
+
"expires_in_seconds"
|
|
4776
|
+
]
|
|
4777
|
+
},
|
|
4778
|
+
"VerifyAgentClaimInput": {
|
|
4779
|
+
"type": "object",
|
|
4780
|
+
"additionalProperties": false,
|
|
4781
|
+
"properties": { "verification_code": {
|
|
4782
|
+
"type": "string",
|
|
4783
|
+
"minLength": 1,
|
|
4784
|
+
"maxLength": 32,
|
|
4785
|
+
"description": "The verification code emailed by the claim start step."
|
|
4786
|
+
} },
|
|
4787
|
+
"required": ["verification_code"]
|
|
4788
|
+
},
|
|
4789
|
+
"AgentClaimResult": {
|
|
4790
|
+
"type": "object",
|
|
4791
|
+
"properties": {
|
|
4792
|
+
"org_id": {
|
|
4793
|
+
"type": "string",
|
|
4794
|
+
"format": "uuid"
|
|
4795
|
+
},
|
|
4796
|
+
"plan": {
|
|
4797
|
+
"type": "string",
|
|
4798
|
+
"enum": ["developer"]
|
|
4799
|
+
},
|
|
4800
|
+
"email": {
|
|
4801
|
+
"type": "string",
|
|
4802
|
+
"format": "email"
|
|
4803
|
+
},
|
|
4804
|
+
"limits": { "$ref": "#/components/schemas/PlanLimits" }
|
|
4805
|
+
},
|
|
4806
|
+
"required": [
|
|
4807
|
+
"org_id",
|
|
4808
|
+
"plan",
|
|
4809
|
+
"email",
|
|
4810
|
+
"limits"
|
|
4811
|
+
]
|
|
4812
|
+
},
|
|
4813
|
+
"CreateAgentClaimLinkInput": {
|
|
4814
|
+
"type": "object",
|
|
4815
|
+
"additionalProperties": false,
|
|
4816
|
+
"description": "No fields; an empty object is accepted.",
|
|
4817
|
+
"properties": {}
|
|
4818
|
+
},
|
|
4819
|
+
"AgentClaimLinkResult": {
|
|
4820
|
+
"type": "object",
|
|
4821
|
+
"properties": {
|
|
4822
|
+
"claim_token": { "type": "string" },
|
|
4823
|
+
"claim_url": {
|
|
4824
|
+
"type": ["string", "null"],
|
|
4825
|
+
"description": "Browser URL to hand to a human, or null if no web origin is configured."
|
|
4826
|
+
},
|
|
4827
|
+
"expires_in_seconds": { "type": "integer" }
|
|
4828
|
+
},
|
|
4829
|
+
"required": [
|
|
4830
|
+
"claim_token",
|
|
4831
|
+
"claim_url",
|
|
4832
|
+
"expires_in_seconds"
|
|
4833
|
+
]
|
|
4834
|
+
},
|
|
4431
4835
|
"CliLogoutInput": {
|
|
4432
4836
|
"type": "object",
|
|
4433
4837
|
"additionalProperties": false,
|
|
@@ -4466,6 +4870,16 @@ const openapiDocument = {
|
|
|
4466
4870
|
},
|
|
4467
4871
|
"email": { "type": "string" },
|
|
4468
4872
|
"plan": { "type": "string" },
|
|
4873
|
+
"limits": { "$ref": "#/components/schemas/PlanLimits" },
|
|
4874
|
+
"entitlements": {
|
|
4875
|
+
"type": "array",
|
|
4876
|
+
"items": { "type": "string" },
|
|
4877
|
+
"description": "Granted org entitlement keys (sorted). A headless caller reads its\ncapabilities here — e.g. an emailless agent seeing only\n[\"send_mail\", \"send_to_known_addresses\"] knows it is reply-only.\n"
|
|
4878
|
+
},
|
|
4879
|
+
"managed_inbox_address": {
|
|
4880
|
+
"type": ["string", "null"],
|
|
4881
|
+
"description": "The managed inbox FQDN to reply as, or null if the org has no managed inbox."
|
|
4882
|
+
},
|
|
4469
4883
|
"created_at": {
|
|
4470
4884
|
"type": "string",
|
|
4471
4885
|
"format": "date-time"
|
|
@@ -4493,6 +4907,9 @@ const openapiDocument = {
|
|
|
4493
4907
|
"id",
|
|
4494
4908
|
"email",
|
|
4495
4909
|
"plan",
|
|
4910
|
+
"limits",
|
|
4911
|
+
"entitlements",
|
|
4912
|
+
"managed_inbox_address",
|
|
4496
4913
|
"created_at",
|
|
4497
4914
|
"discard_content_on_webhook_confirmed"
|
|
4498
4915
|
]
|
|
@@ -7531,6 +7948,39 @@ const operationManifest = [
|
|
|
7531
7948
|
},
|
|
7532
7949
|
"email": { "type": "string" },
|
|
7533
7950
|
"plan": { "type": "string" },
|
|
7951
|
+
"limits": {
|
|
7952
|
+
"type": "object",
|
|
7953
|
+
"description": "Plan-derived quota limits for an account.",
|
|
7954
|
+
"properties": {
|
|
7955
|
+
"storage_mb": { "type": "number" },
|
|
7956
|
+
"send_per_hour": { "type": "number" },
|
|
7957
|
+
"send_per_day": { "type": "number" },
|
|
7958
|
+
"api_per_minute": { "type": "number" },
|
|
7959
|
+
"webhooks_max_global": { "type": ["number", "null"] },
|
|
7960
|
+
"webhooks_per_domain": { "type": "boolean" },
|
|
7961
|
+
"filters_per_domain": { "type": "boolean" },
|
|
7962
|
+
"spam_thresholds_per_domain": { "type": "boolean" }
|
|
7963
|
+
},
|
|
7964
|
+
"required": [
|
|
7965
|
+
"storage_mb",
|
|
7966
|
+
"send_per_hour",
|
|
7967
|
+
"send_per_day",
|
|
7968
|
+
"api_per_minute",
|
|
7969
|
+
"webhooks_max_global",
|
|
7970
|
+
"webhooks_per_domain",
|
|
7971
|
+
"filters_per_domain",
|
|
7972
|
+
"spam_thresholds_per_domain"
|
|
7973
|
+
]
|
|
7974
|
+
},
|
|
7975
|
+
"entitlements": {
|
|
7976
|
+
"type": "array",
|
|
7977
|
+
"items": { "type": "string" },
|
|
7978
|
+
"description": "Granted org entitlement keys (sorted). A headless caller reads its\ncapabilities here — e.g. an emailless agent seeing only\n[\"send_mail\", \"send_to_known_addresses\"] knows it is reply-only.\n"
|
|
7979
|
+
},
|
|
7980
|
+
"managed_inbox_address": {
|
|
7981
|
+
"type": ["string", "null"],
|
|
7982
|
+
"description": "The managed inbox FQDN to reply as, or null if the org has no managed inbox."
|
|
7983
|
+
},
|
|
7534
7984
|
"created_at": {
|
|
7535
7985
|
"type": "string",
|
|
7536
7986
|
"format": "date-time"
|
|
@@ -7558,6 +8008,9 @@ const operationManifest = [
|
|
|
7558
8008
|
"id",
|
|
7559
8009
|
"email",
|
|
7560
8010
|
"plan",
|
|
8011
|
+
"limits",
|
|
8012
|
+
"entitlements",
|
|
8013
|
+
"managed_inbox_address",
|
|
7561
8014
|
"created_at",
|
|
7562
8015
|
"discard_content_on_webhook_confirmed"
|
|
7563
8016
|
]
|
|
@@ -7727,6 +8180,148 @@ const operationManifest = [
|
|
|
7727
8180
|
"tag": "Account",
|
|
7728
8181
|
"tagCommand": "account"
|
|
7729
8182
|
},
|
|
8183
|
+
{
|
|
8184
|
+
"binaryResponse": false,
|
|
8185
|
+
"bodyRequired": true,
|
|
8186
|
+
"command": "create-agent-account",
|
|
8187
|
+
"description": "Creates an emailless agent account without authentication and returns a\none-time API key (prefixed `prim_`) plus a provisioned managed inbox.\nThe account is on the `agent` plan: reply-only (it can send only to\naddresses that have already sent it authenticated mail) with tight send\nlimits. Use the returned `api_key` as a Bearer token on later calls. The\naccount can be upgraded to a full developer account by confirming an\nemail through the claim flow. This endpoint does not require an API key.\n",
|
|
8188
|
+
"hasJsonBody": true,
|
|
8189
|
+
"method": "POST",
|
|
8190
|
+
"operationId": "createAgentAccount",
|
|
8191
|
+
"path": "/agent/accounts",
|
|
8192
|
+
"pathParams": [],
|
|
8193
|
+
"queryParams": [],
|
|
8194
|
+
"requestSchema": {
|
|
8195
|
+
"type": "object",
|
|
8196
|
+
"additionalProperties": false,
|
|
8197
|
+
"properties": {
|
|
8198
|
+
"terms_accepted": {
|
|
8199
|
+
"type": "boolean",
|
|
8200
|
+
"enum": [true],
|
|
8201
|
+
"description": "Must be true to accept the Terms of Service and Privacy Policy."
|
|
8202
|
+
},
|
|
8203
|
+
"device_name": {
|
|
8204
|
+
"type": "string",
|
|
8205
|
+
"minLength": 1,
|
|
8206
|
+
"maxLength": 80,
|
|
8207
|
+
"description": "Optional label for the device or agent creating the account."
|
|
8208
|
+
}
|
|
8209
|
+
},
|
|
8210
|
+
"required": ["terms_accepted"]
|
|
8211
|
+
},
|
|
8212
|
+
"responseSchema": {
|
|
8213
|
+
"type": "object",
|
|
8214
|
+
"properties": {
|
|
8215
|
+
"api_key": {
|
|
8216
|
+
"type": "string",
|
|
8217
|
+
"description": "One-time API key (prefixed `prim_`). Shown once; store it securely."
|
|
8218
|
+
},
|
|
8219
|
+
"org_id": {
|
|
8220
|
+
"type": "string",
|
|
8221
|
+
"format": "uuid"
|
|
8222
|
+
},
|
|
8223
|
+
"address": {
|
|
8224
|
+
"type": ["string", "null"],
|
|
8225
|
+
"description": "Provisioned managed inbox FQDN, or null if the inbox publish was deferred."
|
|
8226
|
+
},
|
|
8227
|
+
"plan": {
|
|
8228
|
+
"type": "string",
|
|
8229
|
+
"enum": ["agent"]
|
|
8230
|
+
},
|
|
8231
|
+
"limits": {
|
|
8232
|
+
"type": "object",
|
|
8233
|
+
"description": "Plan-derived quota limits for an account.",
|
|
8234
|
+
"properties": {
|
|
8235
|
+
"storage_mb": { "type": "number" },
|
|
8236
|
+
"send_per_hour": { "type": "number" },
|
|
8237
|
+
"send_per_day": { "type": "number" },
|
|
8238
|
+
"api_per_minute": { "type": "number" },
|
|
8239
|
+
"webhooks_max_global": { "type": ["number", "null"] },
|
|
8240
|
+
"webhooks_per_domain": { "type": "boolean" },
|
|
8241
|
+
"filters_per_domain": { "type": "boolean" },
|
|
8242
|
+
"spam_thresholds_per_domain": { "type": "boolean" }
|
|
8243
|
+
},
|
|
8244
|
+
"required": [
|
|
8245
|
+
"storage_mb",
|
|
8246
|
+
"send_per_hour",
|
|
8247
|
+
"send_per_day",
|
|
8248
|
+
"api_per_minute",
|
|
8249
|
+
"webhooks_max_global",
|
|
8250
|
+
"webhooks_per_domain",
|
|
8251
|
+
"filters_per_domain",
|
|
8252
|
+
"spam_thresholds_per_domain"
|
|
8253
|
+
]
|
|
8254
|
+
},
|
|
8255
|
+
"upgrade": {
|
|
8256
|
+
"type": "object",
|
|
8257
|
+
"description": "In-band pointer to the upgrade path for an agent account.",
|
|
8258
|
+
"properties": {
|
|
8259
|
+
"plan": {
|
|
8260
|
+
"type": "string",
|
|
8261
|
+
"enum": ["developer"]
|
|
8262
|
+
},
|
|
8263
|
+
"description": { "type": "string" },
|
|
8264
|
+
"claim_path": { "type": "string" }
|
|
8265
|
+
},
|
|
8266
|
+
"required": [
|
|
8267
|
+
"plan",
|
|
8268
|
+
"description",
|
|
8269
|
+
"claim_path"
|
|
8270
|
+
]
|
|
8271
|
+
}
|
|
8272
|
+
},
|
|
8273
|
+
"required": [
|
|
8274
|
+
"api_key",
|
|
8275
|
+
"org_id",
|
|
8276
|
+
"address",
|
|
8277
|
+
"plan",
|
|
8278
|
+
"limits",
|
|
8279
|
+
"upgrade"
|
|
8280
|
+
]
|
|
8281
|
+
},
|
|
8282
|
+
"sdkName": "createAgentAccount",
|
|
8283
|
+
"summary": "Create an emailless agent account",
|
|
8284
|
+
"tag": "Agent",
|
|
8285
|
+
"tagCommand": "agent"
|
|
8286
|
+
},
|
|
8287
|
+
{
|
|
8288
|
+
"binaryResponse": false,
|
|
8289
|
+
"bodyRequired": false,
|
|
8290
|
+
"command": "create-agent-claim-link",
|
|
8291
|
+
"description": "Mints an opaque, single-use link an agent can hand to a human to\ncomplete the email-confirmation upgrade in a browser. Authenticated by\nthe agent's own API key. `claim_url` is null when the API host cannot\nresolve a web origin to build the link.\n",
|
|
8292
|
+
"hasJsonBody": true,
|
|
8293
|
+
"method": "POST",
|
|
8294
|
+
"operationId": "createAgentClaimLink",
|
|
8295
|
+
"path": "/agent/claim/link",
|
|
8296
|
+
"pathParams": [],
|
|
8297
|
+
"queryParams": [],
|
|
8298
|
+
"requestSchema": {
|
|
8299
|
+
"type": "object",
|
|
8300
|
+
"additionalProperties": false,
|
|
8301
|
+
"description": "No fields; an empty object is accepted.",
|
|
8302
|
+
"properties": {}
|
|
8303
|
+
},
|
|
8304
|
+
"responseSchema": {
|
|
8305
|
+
"type": "object",
|
|
8306
|
+
"properties": {
|
|
8307
|
+
"claim_token": { "type": "string" },
|
|
8308
|
+
"claim_url": {
|
|
8309
|
+
"type": ["string", "null"],
|
|
8310
|
+
"description": "Browser URL to hand to a human, or null if no web origin is configured."
|
|
8311
|
+
},
|
|
8312
|
+
"expires_in_seconds": { "type": "integer" }
|
|
8313
|
+
},
|
|
8314
|
+
"required": [
|
|
8315
|
+
"claim_token",
|
|
8316
|
+
"claim_url",
|
|
8317
|
+
"expires_in_seconds"
|
|
8318
|
+
]
|
|
8319
|
+
},
|
|
8320
|
+
"sdkName": "createAgentClaimLink",
|
|
8321
|
+
"summary": "Create a browser claim link",
|
|
8322
|
+
"tag": "Agent",
|
|
8323
|
+
"tagCommand": "agent"
|
|
8324
|
+
},
|
|
7730
8325
|
{
|
|
7731
8326
|
"binaryResponse": false,
|
|
7732
8327
|
"bodyRequired": true,
|
|
@@ -7774,8 +8369,48 @@ const operationManifest = [
|
|
|
7774
8369
|
"verification_code_length"
|
|
7775
8370
|
]
|
|
7776
8371
|
},
|
|
7777
|
-
"sdkName": "resendAgentSignupVerification",
|
|
7778
|
-
"summary": "Resend agent signup verification code",
|
|
8372
|
+
"sdkName": "resendAgentSignupVerification",
|
|
8373
|
+
"summary": "Resend agent signup verification code",
|
|
8374
|
+
"tag": "Agent",
|
|
8375
|
+
"tagCommand": "agent"
|
|
8376
|
+
},
|
|
8377
|
+
{
|
|
8378
|
+
"binaryResponse": false,
|
|
8379
|
+
"bodyRequired": true,
|
|
8380
|
+
"command": "start-agent-claim",
|
|
8381
|
+
"description": "Begins upgrading an emailless `agent` account into a full `developer`\naccount by confirming an email address. Authenticated by the agent's own\nAPI key (the org is taken from the credential). Sends a verification\ncode to the supplied email and returns the claim session id plus resend\ntiming. Submit the code to `/agent/claim/verify` to complete the\nupgrade. Confirming an email that already belongs to a Primitive account\nis rejected.\n",
|
|
8382
|
+
"hasJsonBody": true,
|
|
8383
|
+
"method": "POST",
|
|
8384
|
+
"operationId": "startAgentClaim",
|
|
8385
|
+
"path": "/agent/claim/start",
|
|
8386
|
+
"pathParams": [],
|
|
8387
|
+
"queryParams": [],
|
|
8388
|
+
"requestSchema": {
|
|
8389
|
+
"type": "object",
|
|
8390
|
+
"additionalProperties": false,
|
|
8391
|
+
"properties": { "email": {
|
|
8392
|
+
"type": "string",
|
|
8393
|
+
"format": "email",
|
|
8394
|
+
"maxLength": 254,
|
|
8395
|
+
"description": "Email to confirm. Must not already belong to a Primitive account."
|
|
8396
|
+
} },
|
|
8397
|
+
"required": ["email"]
|
|
8398
|
+
},
|
|
8399
|
+
"responseSchema": {
|
|
8400
|
+
"type": "object",
|
|
8401
|
+
"properties": {
|
|
8402
|
+
"claim_session_id": { "type": "string" },
|
|
8403
|
+
"resend_after_seconds": { "type": "integer" },
|
|
8404
|
+
"expires_in_seconds": { "type": "integer" }
|
|
8405
|
+
},
|
|
8406
|
+
"required": [
|
|
8407
|
+
"claim_session_id",
|
|
8408
|
+
"resend_after_seconds",
|
|
8409
|
+
"expires_in_seconds"
|
|
8410
|
+
]
|
|
8411
|
+
},
|
|
8412
|
+
"sdkName": "startAgentClaim",
|
|
8413
|
+
"summary": "Start an agent account email claim",
|
|
7779
8414
|
"tag": "Agent",
|
|
7780
8415
|
"tagCommand": "agent"
|
|
7781
8416
|
},
|
|
@@ -7861,6 +8496,80 @@ const operationManifest = [
|
|
|
7861
8496
|
"tag": "Agent",
|
|
7862
8497
|
"tagCommand": "agent"
|
|
7863
8498
|
},
|
|
8499
|
+
{
|
|
8500
|
+
"binaryResponse": false,
|
|
8501
|
+
"bodyRequired": true,
|
|
8502
|
+
"command": "verify-agent-claim",
|
|
8503
|
+
"description": "Confirms the verification code emailed by `/agent/claim/start` and\nupgrades the account to the `developer` plan. The org id, API key, and\nmanaged inbox all carry over; the send cap lifts. Authenticated by the\nagent's own API key.\n",
|
|
8504
|
+
"hasJsonBody": true,
|
|
8505
|
+
"method": "POST",
|
|
8506
|
+
"operationId": "verifyAgentClaim",
|
|
8507
|
+
"path": "/agent/claim/verify",
|
|
8508
|
+
"pathParams": [],
|
|
8509
|
+
"queryParams": [],
|
|
8510
|
+
"requestSchema": {
|
|
8511
|
+
"type": "object",
|
|
8512
|
+
"additionalProperties": false,
|
|
8513
|
+
"properties": { "verification_code": {
|
|
8514
|
+
"type": "string",
|
|
8515
|
+
"minLength": 1,
|
|
8516
|
+
"maxLength": 32,
|
|
8517
|
+
"description": "The verification code emailed by the claim start step."
|
|
8518
|
+
} },
|
|
8519
|
+
"required": ["verification_code"]
|
|
8520
|
+
},
|
|
8521
|
+
"responseSchema": {
|
|
8522
|
+
"type": "object",
|
|
8523
|
+
"properties": {
|
|
8524
|
+
"org_id": {
|
|
8525
|
+
"type": "string",
|
|
8526
|
+
"format": "uuid"
|
|
8527
|
+
},
|
|
8528
|
+
"plan": {
|
|
8529
|
+
"type": "string",
|
|
8530
|
+
"enum": ["developer"]
|
|
8531
|
+
},
|
|
8532
|
+
"email": {
|
|
8533
|
+
"type": "string",
|
|
8534
|
+
"format": "email"
|
|
8535
|
+
},
|
|
8536
|
+
"limits": {
|
|
8537
|
+
"type": "object",
|
|
8538
|
+
"description": "Plan-derived quota limits for an account.",
|
|
8539
|
+
"properties": {
|
|
8540
|
+
"storage_mb": { "type": "number" },
|
|
8541
|
+
"send_per_hour": { "type": "number" },
|
|
8542
|
+
"send_per_day": { "type": "number" },
|
|
8543
|
+
"api_per_minute": { "type": "number" },
|
|
8544
|
+
"webhooks_max_global": { "type": ["number", "null"] },
|
|
8545
|
+
"webhooks_per_domain": { "type": "boolean" },
|
|
8546
|
+
"filters_per_domain": { "type": "boolean" },
|
|
8547
|
+
"spam_thresholds_per_domain": { "type": "boolean" }
|
|
8548
|
+
},
|
|
8549
|
+
"required": [
|
|
8550
|
+
"storage_mb",
|
|
8551
|
+
"send_per_hour",
|
|
8552
|
+
"send_per_day",
|
|
8553
|
+
"api_per_minute",
|
|
8554
|
+
"webhooks_max_global",
|
|
8555
|
+
"webhooks_per_domain",
|
|
8556
|
+
"filters_per_domain",
|
|
8557
|
+
"spam_thresholds_per_domain"
|
|
8558
|
+
]
|
|
8559
|
+
}
|
|
8560
|
+
},
|
|
8561
|
+
"required": [
|
|
8562
|
+
"org_id",
|
|
8563
|
+
"plan",
|
|
8564
|
+
"email",
|
|
8565
|
+
"limits"
|
|
8566
|
+
]
|
|
8567
|
+
},
|
|
8568
|
+
"sdkName": "verifyAgentClaim",
|
|
8569
|
+
"summary": "Verify an agent account email claim",
|
|
8570
|
+
"tag": "Agent",
|
|
8571
|
+
"tagCommand": "agent"
|
|
8572
|
+
},
|
|
7864
8573
|
{
|
|
7865
8574
|
"binaryResponse": false,
|
|
7866
8575
|
"bodyRequired": true,
|
|
@@ -9758,6 +10467,22 @@ const operationManifest = [
|
|
|
9758
10467
|
"name": "date_to",
|
|
9759
10468
|
"required": false,
|
|
9760
10469
|
"type": "string"
|
|
10470
|
+
},
|
|
10471
|
+
{
|
|
10472
|
+
"description": "Forward-tail cursor. Returns rows that became visible AFTER this\ncursor, oldest-first, so a caller can stream new inbound mail by\nre-passing the cursor from each response. Mutually exclusive with\n`cursor` (which pages history newest-first). Pass the `meta.cursor`\nfrom the previous `since` response; an empty page means caught up.\n",
|
|
10473
|
+
"enum": null,
|
|
10474
|
+
"name": "since",
|
|
10475
|
+
"required": false,
|
|
10476
|
+
"type": "string"
|
|
10477
|
+
},
|
|
10478
|
+
{
|
|
10479
|
+
"description": "Long-poll: hold the request up to this many seconds waiting for new\nmail past `since`, returning as soon as any arrives (or an empty\npage when the wait elapses). Requires `since`. Omitted means no wait\n(returns immediately); the server treats an absent value as 0. NOT\ngiven an OpenAPI `default` on purpose: a default makes some\ngenerators (e.g. openapi-python-client) send `wait=0` on every call,\nwhich then fails the `wait` requires `since` check for plain history\nlistings.\n",
|
|
10480
|
+
"enum": null,
|
|
10481
|
+
"maximum": 30,
|
|
10482
|
+
"minimum": 0,
|
|
10483
|
+
"name": "wait",
|
|
10484
|
+
"required": false,
|
|
10485
|
+
"type": "integer"
|
|
9761
10486
|
}
|
|
9762
10487
|
],
|
|
9763
10488
|
"requestSchema": null,
|
|
@@ -10767,7 +11492,7 @@ const operationManifest = [
|
|
|
10767
11492
|
"binaryResponse": false,
|
|
10768
11493
|
"bodyRequired": true,
|
|
10769
11494
|
"command": "create-function",
|
|
10770
|
-
"description": "Creates and deploys a new function. The handler must be a single\nESM module whose default export is an object with an async\n`fetch(request, env)` method (Workers-style). Primitive signs\neach delivery and forwards the `Primitive-Signature` header to\nthe handler. Verify the raw request body with\n`PRIMITIVE_WEBHOOK_SECRET` before parsing JSON; after verification\nthe request body parses to
|
|
11495
|
+
"description": "Creates and deploys a new function. The handler must be a single\nESM module whose default export is an object with an async\n`fetch(request, env)` method (Workers-style). Primitive signs\neach delivery and forwards the `Primitive-Signature` header to\nthe handler. Verify the raw request body with\n`PRIMITIVE_WEBHOOK_SECRET` before parsing JSON; after verification\nthe request body parses to a webhook event whose `event` field is\n`email.received` for normal inbound mail, or a machine-mail type\n(`email.bounced`, `email.tls_report`, `email.dmarc_report`,\n`email.dmarc_failure`) for bounces and reports. Code is bundled\nbefore being uploaded; ship a single self-contained file rather\nthan relying on external imports.\n\n**Code limits.** `code` is capped at 1 MiB UTF-8. `sourceMap`\n(optional) is capped at 5 MiB UTF-8, stored with each deployment\nattempt, and sent to the runtime so stack traces can resolve to\noriginal source files.\n\n**Routing.** On successful deploy, the function code is live\nin the runtime, but inbound mail will not reach it until at\nleast one route is bound. Routes are managed from the Primitive\ndashboard. A `deploy_status` of `deployed` means the script is\ninstalled, not that the function is receiving mail. The\ninternal runtime URL is not returned by the API and is not a\ncustomer-facing integration surface.\n\n**Secrets.** New functions ship with the managed secrets\n(`PRIMITIVE_WEBHOOK_SECRET`, `PRIMITIVE_API_KEY`,\n`PRIMITIVE_API_BASE_URL`) already bound. Add user-set secrets via\n`POST /functions/{id}/secrets`; secret writes only land in the\nrunning handler on the next redeploy.\n",
|
|
10771
11496
|
"hasJsonBody": true,
|
|
10772
11497
|
"method": "POST",
|
|
10773
11498
|
"operationId": "createFunction",
|
|
@@ -14705,6 +15430,76 @@ function canonicalizeCliReferences(description) {
|
|
|
14705
15430
|
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'`");
|
|
14706
15431
|
}
|
|
14707
15432
|
//#endregion
|
|
15433
|
+
//#region src/oclif/commands/agent-upgrade.ts
|
|
15434
|
+
/**
|
|
15435
|
+
* Interactive upgrade of an emailless agent account to a full developer
|
|
15436
|
+
* account: starts the email claim, prompts for the emailed code, and verifies
|
|
15437
|
+
* it. Combines the generated `agent:claim` (start) and `agent:claim-verify`
|
|
15438
|
+
* into one flow with a prompt, mirroring the `signup` interactive command.
|
|
15439
|
+
* Authenticated by the agent's own API key (the org is taken from the key).
|
|
15440
|
+
*/
|
|
15441
|
+
var AgentUpgradeCommand = class AgentUpgradeCommand extends Command {
|
|
15442
|
+
static description = "Upgrade an emailless agent account to a full developer account by confirming an email. Authenticated by the agent's own API key (PRIMITIVE_API_KEY).";
|
|
15443
|
+
static summary = "Upgrade an agent account to developer (email confirmation)";
|
|
15444
|
+
static examples = ["<%= config.bin %> agent upgrade --email you@example.com"];
|
|
15445
|
+
static flags = {
|
|
15446
|
+
email: Flags.string({ description: "Email to confirm. Prompted if omitted." }),
|
|
15447
|
+
code: Flags.string({ description: "Verification code from the email. Prompted if omitted." }),
|
|
15448
|
+
"api-key": Flags.string({
|
|
15449
|
+
env: "PRIMITIVE_API_KEY",
|
|
15450
|
+
description: "Agent API key (defaults to PRIMITIVE_API_KEY or saved credentials)."
|
|
15451
|
+
}),
|
|
15452
|
+
"api-base-url": Flags.string({ description: "Override the API base URL." })
|
|
15453
|
+
};
|
|
15454
|
+
async run() {
|
|
15455
|
+
const { flags } = await this.parse(AgentUpgradeCommand);
|
|
15456
|
+
const { apiClient } = await createAuthenticatedCliApiClient({
|
|
15457
|
+
apiKey: flags["api-key"],
|
|
15458
|
+
apiBaseUrl: flags["api-base-url"],
|
|
15459
|
+
configDir: this.config.configDir
|
|
15460
|
+
});
|
|
15461
|
+
const email = flags.email ?? await promptRequired$1("Email to confirm: ");
|
|
15462
|
+
const started = await startAgentClaim({
|
|
15463
|
+
body: { email },
|
|
15464
|
+
client: apiClient.client,
|
|
15465
|
+
responseStyle: "fields"
|
|
15466
|
+
});
|
|
15467
|
+
if (!started.data) {
|
|
15468
|
+
writeErrorWithHints(extractErrorPayload(started.error));
|
|
15469
|
+
this.exit(1);
|
|
15470
|
+
return;
|
|
15471
|
+
}
|
|
15472
|
+
process$1.stderr.write(`Verification code sent to ${email}.\n`);
|
|
15473
|
+
const verified = await verifyAgentClaim({
|
|
15474
|
+
body: { verification_code: flags.code ?? await promptRequired$1("Verification code: ") },
|
|
15475
|
+
client: apiClient.client,
|
|
15476
|
+
responseStyle: "fields"
|
|
15477
|
+
});
|
|
15478
|
+
const result = verified.data?.data;
|
|
15479
|
+
if (result) {
|
|
15480
|
+
this.log(JSON.stringify(result, null, 2));
|
|
15481
|
+
process$1.stderr.write(`Upgraded to ${result.plan}. Your API key and managed inbox carry over; the send cap is lifted.\n`);
|
|
15482
|
+
return;
|
|
15483
|
+
}
|
|
15484
|
+
writeErrorWithHints(extractErrorPayload(verified.error));
|
|
15485
|
+
this.exit(1);
|
|
15486
|
+
}
|
|
15487
|
+
};
|
|
15488
|
+
async function promptRequired$1(question) {
|
|
15489
|
+
const rl = createInterface({
|
|
15490
|
+
input: process$1.stdin,
|
|
15491
|
+
output: process$1.stderr
|
|
15492
|
+
});
|
|
15493
|
+
try {
|
|
15494
|
+
for (;;) {
|
|
15495
|
+
const answer = (await rl.question(question)).trim();
|
|
15496
|
+
if (answer) return answer;
|
|
15497
|
+
}
|
|
15498
|
+
} finally {
|
|
15499
|
+
rl.close();
|
|
15500
|
+
}
|
|
15501
|
+
}
|
|
15502
|
+
//#endregion
|
|
14708
15503
|
//#region src/oclif/attachments.ts
|
|
14709
15504
|
function readAttachmentBytes(path, readFile) {
|
|
14710
15505
|
try {
|
|
@@ -18138,8 +18933,8 @@ const PRIMITIVE_TEAM_AUTHOR = {
|
|
|
18138
18933
|
name: "Primitive Team",
|
|
18139
18934
|
url: "https://primitive.dev"
|
|
18140
18935
|
};
|
|
18141
|
-
const SDK_VERSION_RANGE = "^1.
|
|
18142
|
-
const CLI_VERSION_RANGE = "^1.
|
|
18936
|
+
const SDK_VERSION_RANGE = "^1.4.0";
|
|
18937
|
+
const CLI_VERSION_RANGE = "^1.4.0";
|
|
18143
18938
|
const ESBUILD_VERSION_RANGE = "^0.27.0";
|
|
18144
18939
|
function renderHandler() {
|
|
18145
18940
|
return `// env.PRIMITIVE_API_KEY, env.PRIMITIVE_WEBHOOK_SECRET, and
|
|
@@ -21284,6 +22079,251 @@ var LogoutCommand = class LogoutCommand extends Command {
|
|
|
21284
22079
|
}
|
|
21285
22080
|
};
|
|
21286
22081
|
//#endregion
|
|
22082
|
+
//#region src/oclif/commands/org-secrets-shared.ts
|
|
22083
|
+
function orgSecretsUrl(baseUrl, key) {
|
|
22084
|
+
const base = `${baseUrl.replace(/\/$/, "")}/org/secrets`;
|
|
22085
|
+
return key ? `${base}/${encodeURIComponent(key)}` : base;
|
|
22086
|
+
}
|
|
22087
|
+
function orgSecretsAuthHeaders(requestHeaders, apiKey) {
|
|
22088
|
+
return {
|
|
22089
|
+
...requestHeaders ?? {},
|
|
22090
|
+
...apiKey ? { authorization: `Bearer ${apiKey}` } : {}
|
|
22091
|
+
};
|
|
22092
|
+
}
|
|
22093
|
+
async function orgSecretsErrorPayload(response) {
|
|
22094
|
+
if ((response.headers.get("content-type")?.toLowerCase() ?? "").includes("application/json")) return response.json().catch(() => ({
|
|
22095
|
+
code: "http_error",
|
|
22096
|
+
message: `HTTP ${response.status} ${response.statusText}`.trim()
|
|
22097
|
+
}));
|
|
22098
|
+
return {
|
|
22099
|
+
code: "http_error",
|
|
22100
|
+
message: (await response.text().catch(() => "")).trim() || `HTTP ${response.status} ${response.statusText}`.trim()
|
|
22101
|
+
};
|
|
22102
|
+
}
|
|
22103
|
+
async function runOrgSecretsRequest(fetchImpl, baseUrl, headers, op) {
|
|
22104
|
+
const url = op.kind === "remove" ? orgSecretsUrl(baseUrl, op.key) : orgSecretsUrl(baseUrl);
|
|
22105
|
+
const init = op.kind === "set" ? {
|
|
22106
|
+
method: "POST",
|
|
22107
|
+
headers: {
|
|
22108
|
+
...headers,
|
|
22109
|
+
"content-type": "application/json"
|
|
22110
|
+
},
|
|
22111
|
+
body: JSON.stringify({
|
|
22112
|
+
key: op.key,
|
|
22113
|
+
value: op.value
|
|
22114
|
+
})
|
|
22115
|
+
} : op.kind === "remove" ? {
|
|
22116
|
+
method: "DELETE",
|
|
22117
|
+
headers
|
|
22118
|
+
} : { headers };
|
|
22119
|
+
let response;
|
|
22120
|
+
try {
|
|
22121
|
+
response = await fetchImpl(url, init);
|
|
22122
|
+
} catch (error) {
|
|
22123
|
+
return {
|
|
22124
|
+
kind: "error",
|
|
22125
|
+
payload: extractErrorPayload(error)
|
|
22126
|
+
};
|
|
22127
|
+
}
|
|
22128
|
+
if (!response.ok) return {
|
|
22129
|
+
kind: "error",
|
|
22130
|
+
payload: extractErrorPayload(await orgSecretsErrorPayload(response))
|
|
22131
|
+
};
|
|
22132
|
+
if (op.kind === "remove") return {
|
|
22133
|
+
kind: "ok",
|
|
22134
|
+
data: null
|
|
22135
|
+
};
|
|
22136
|
+
const body = await response.json().catch(() => ({}));
|
|
22137
|
+
if (op.kind === "list") return {
|
|
22138
|
+
kind: "ok",
|
|
22139
|
+
data: body.data?.items ?? []
|
|
22140
|
+
};
|
|
22141
|
+
return {
|
|
22142
|
+
kind: "ok",
|
|
22143
|
+
data: body.data ?? {}
|
|
22144
|
+
};
|
|
22145
|
+
}
|
|
22146
|
+
//#endregion
|
|
22147
|
+
//#region src/oclif/commands/org-secrets-list.ts
|
|
22148
|
+
var OrgSecretsListCommand = class OrgSecretsListCommand extends Command {
|
|
22149
|
+
static description = `List your organization's global secrets.
|
|
22150
|
+
|
|
22151
|
+
Global secrets apply to every function in the org and are read as
|
|
22152
|
+
\`env.<KEY>\` in handlers. Only the keys and timestamps are returned;
|
|
22153
|
+
the values are encrypted at rest and never surfaced.`;
|
|
22154
|
+
static summary = "List global secrets (keys only; values never returned)";
|
|
22155
|
+
static examples = ["<%= config.bin %> org secrets list"];
|
|
22156
|
+
static flags = {
|
|
22157
|
+
"api-key": Flags.string({
|
|
22158
|
+
description: "Primitive API key override (defaults to PRIMITIVE_API_KEY or saved OAuth login credentials)",
|
|
22159
|
+
env: "PRIMITIVE_API_KEY"
|
|
22160
|
+
}),
|
|
22161
|
+
"api-base-url": Flags.string({
|
|
22162
|
+
description: "Override the primary API base URL. Internal testing only; not documented to customers.",
|
|
22163
|
+
env: "PRIMITIVE_API_BASE_URL",
|
|
22164
|
+
hidden: true
|
|
22165
|
+
}),
|
|
22166
|
+
time: Flags.boolean({ description: TIME_FLAG_DESCRIPTION })
|
|
22167
|
+
};
|
|
22168
|
+
async run() {
|
|
22169
|
+
const { flags } = await this.parse(OrgSecretsListCommand);
|
|
22170
|
+
await runWithTiming(flags.time, async () => {
|
|
22171
|
+
const { auth, baseUrlOverridden, requestConfig } = await createAuthenticatedCliApiClient({
|
|
22172
|
+
apiKey: flags["api-key"],
|
|
22173
|
+
apiBaseUrl: flags["api-base-url"],
|
|
22174
|
+
configDir: this.config.configDir
|
|
22175
|
+
});
|
|
22176
|
+
const outcome = await runOrgSecretsRequest(fetch, requestConfig.resolvedApiBaseUrl, orgSecretsAuthHeaders(requestConfig.headers, auth.apiKey), { kind: "list" });
|
|
22177
|
+
if (outcome.kind === "error") {
|
|
22178
|
+
writeErrorWithHints(outcome.payload);
|
|
22179
|
+
surfaceUnauthorizedHint({
|
|
22180
|
+
auth,
|
|
22181
|
+
baseUrlOverridden,
|
|
22182
|
+
configDir: this.config.configDir,
|
|
22183
|
+
payload: outcome.payload
|
|
22184
|
+
});
|
|
22185
|
+
process.exitCode = 1;
|
|
22186
|
+
return;
|
|
22187
|
+
}
|
|
22188
|
+
this.log(JSON.stringify(outcome.data, null, 2));
|
|
22189
|
+
});
|
|
22190
|
+
}
|
|
22191
|
+
};
|
|
22192
|
+
//#endregion
|
|
22193
|
+
//#region src/oclif/commands/org-secrets-remove.ts
|
|
22194
|
+
var OrgSecretsRemoveCommand = class OrgSecretsRemoveCommand extends Command {
|
|
22195
|
+
static description = `Delete a global secret.
|
|
22196
|
+
|
|
22197
|
+
Deployed functions keep the previous value until each is redeployed. A
|
|
22198
|
+
function that defines its own secret of the same name is unaffected.`;
|
|
22199
|
+
static summary = "Delete a global secret";
|
|
22200
|
+
static aliases = ["org:secrets:delete"];
|
|
22201
|
+
static examples = ["<%= config.bin %> org secrets remove --key STRIPE_KEY"];
|
|
22202
|
+
static flags = {
|
|
22203
|
+
"api-key": Flags.string({
|
|
22204
|
+
description: "Primitive API key override (defaults to PRIMITIVE_API_KEY or saved OAuth login credentials)",
|
|
22205
|
+
env: "PRIMITIVE_API_KEY"
|
|
22206
|
+
}),
|
|
22207
|
+
"api-base-url": Flags.string({
|
|
22208
|
+
description: "Override the primary API base URL. Internal testing only; not documented to customers.",
|
|
22209
|
+
env: "PRIMITIVE_API_BASE_URL",
|
|
22210
|
+
hidden: true
|
|
22211
|
+
}),
|
|
22212
|
+
key: Flags.string({
|
|
22213
|
+
description: "Global secret key to delete.",
|
|
22214
|
+
required: true
|
|
22215
|
+
}),
|
|
22216
|
+
time: Flags.boolean({ description: TIME_FLAG_DESCRIPTION })
|
|
22217
|
+
};
|
|
22218
|
+
async run() {
|
|
22219
|
+
const { flags } = await this.parse(OrgSecretsRemoveCommand);
|
|
22220
|
+
await runWithTiming(flags.time, async () => {
|
|
22221
|
+
const { auth, baseUrlOverridden, requestConfig } = await createAuthenticatedCliApiClient({
|
|
22222
|
+
apiKey: flags["api-key"],
|
|
22223
|
+
apiBaseUrl: flags["api-base-url"],
|
|
22224
|
+
configDir: this.config.configDir
|
|
22225
|
+
});
|
|
22226
|
+
const outcome = await runOrgSecretsRequest(fetch, requestConfig.resolvedApiBaseUrl, orgSecretsAuthHeaders(requestConfig.headers, auth.apiKey), {
|
|
22227
|
+
kind: "remove",
|
|
22228
|
+
key: flags.key
|
|
22229
|
+
});
|
|
22230
|
+
if (outcome.kind === "error") {
|
|
22231
|
+
writeErrorWithHints(outcome.payload);
|
|
22232
|
+
surfaceUnauthorizedHint({
|
|
22233
|
+
auth,
|
|
22234
|
+
baseUrlOverridden,
|
|
22235
|
+
configDir: this.config.configDir,
|
|
22236
|
+
payload: outcome.payload
|
|
22237
|
+
});
|
|
22238
|
+
process.exitCode = 1;
|
|
22239
|
+
return;
|
|
22240
|
+
}
|
|
22241
|
+
process.stderr.write(`Global secret ${flags.key} deleted. Deployed functions keep the previous value until each is redeployed.\n`);
|
|
22242
|
+
});
|
|
22243
|
+
}
|
|
22244
|
+
};
|
|
22245
|
+
//#endregion
|
|
22246
|
+
//#region src/oclif/commands/org-secrets-set.ts
|
|
22247
|
+
var OrgSecretsSetCommand = class OrgSecretsSetCommand extends Command {
|
|
22248
|
+
static description = `Set a global secret available to every function as \`env.<KEY>\`.
|
|
22249
|
+
|
|
22250
|
+
Global secrets are read into each function at deploy time, so a new or
|
|
22251
|
+
changed value lands in a function only on its next redeploy. A function
|
|
22252
|
+
secret with the same key overrides the global value for that function.
|
|
22253
|
+
|
|
22254
|
+
Keys must match \`^[A-Z_][A-Z0-9_]*$\` (uppercase letters, digits,
|
|
22255
|
+
underscores; first character a letter or underscore). System-managed keys
|
|
22256
|
+
are reserved and rejected. ${SINGLE_SECRET_VALUE_SOURCE_DESCRIPTION}`;
|
|
22257
|
+
static summary = "Set a global secret shared across all functions";
|
|
22258
|
+
static examples = [
|
|
22259
|
+
"<%= config.bin %> org secrets set --key STRIPE_KEY --value sk_live_...",
|
|
22260
|
+
"<%= config.bin %> org secrets set --key OPENAI_KEY --value-from-env OPENAI_KEY",
|
|
22261
|
+
"printf '%s' \"$OPENAI_KEY\" | <%= config.bin %> org secrets set --key OPENAI_KEY --stdin"
|
|
22262
|
+
];
|
|
22263
|
+
static flags = {
|
|
22264
|
+
"api-key": Flags.string({
|
|
22265
|
+
description: "Primitive API key override (defaults to PRIMITIVE_API_KEY or saved OAuth login credentials)",
|
|
22266
|
+
env: "PRIMITIVE_API_KEY"
|
|
22267
|
+
}),
|
|
22268
|
+
"api-base-url": Flags.string({
|
|
22269
|
+
description: "Override the primary API base URL. Internal testing only; not documented to customers.",
|
|
22270
|
+
env: "PRIMITIVE_API_BASE_URL",
|
|
22271
|
+
hidden: true
|
|
22272
|
+
}),
|
|
22273
|
+
key: Flags.string({
|
|
22274
|
+
description: "Secret key. Uppercase letters, digits, underscores; must start with a letter or underscore. System-managed keys are reserved.",
|
|
22275
|
+
required: true
|
|
22276
|
+
}),
|
|
22277
|
+
value: Flags.string({ description: "Secret value (up to 4096 UTF-8 bytes). Encrypted at rest. Visible in shell history and process argv; prefer a non-argv source for sensitive values." }),
|
|
22278
|
+
"value-from-env": Flags.string({ description: "Environment variable to read as the secret value. Example: --value-from-env OPENAI_KEY reads process.env.OPENAI_KEY." }),
|
|
22279
|
+
"value-file": Flags.string({ description: "UTF-8 file to read as the secret value. The full file contents become the value." }),
|
|
22280
|
+
"value-from-env-file": Flags.string({ description: "Dotenv-style file to read as the secret value. Use FILE to read --key from that file, or FILE:KEY to read a different key." }),
|
|
22281
|
+
stdin: Flags.boolean({ description: "Read the secret value from stdin. A single trailing line ending is stripped." }),
|
|
22282
|
+
time: Flags.boolean({ description: TIME_FLAG_DESCRIPTION })
|
|
22283
|
+
};
|
|
22284
|
+
async run() {
|
|
22285
|
+
const { flags } = await this.parse(OrgSecretsSetCommand);
|
|
22286
|
+
await runWithTiming(flags.time, async () => {
|
|
22287
|
+
const { auth, baseUrlOverridden, requestConfig } = await createAuthenticatedCliApiClient({
|
|
22288
|
+
apiKey: flags["api-key"],
|
|
22289
|
+
apiBaseUrl: flags["api-base-url"],
|
|
22290
|
+
configDir: this.config.configDir
|
|
22291
|
+
});
|
|
22292
|
+
const resolved = resolveSingleSecretValue({
|
|
22293
|
+
key: flags.key,
|
|
22294
|
+
value: flags.value,
|
|
22295
|
+
valueFile: flags["value-file"],
|
|
22296
|
+
valueFromEnv: flags["value-from-env"],
|
|
22297
|
+
valueFromEnvFile: flags["value-from-env-file"],
|
|
22298
|
+
stdin: flags.stdin
|
|
22299
|
+
});
|
|
22300
|
+
if (resolved.kind === "error") {
|
|
22301
|
+
process.stderr.write(`${resolved.message}\n`);
|
|
22302
|
+
process.exitCode = 1;
|
|
22303
|
+
return;
|
|
22304
|
+
}
|
|
22305
|
+
const outcome = await runOrgSecretsRequest(fetch, requestConfig.resolvedApiBaseUrl, orgSecretsAuthHeaders(requestConfig.headers, auth.apiKey), {
|
|
22306
|
+
kind: "set",
|
|
22307
|
+
key: flags.key,
|
|
22308
|
+
value: resolved.value
|
|
22309
|
+
});
|
|
22310
|
+
if (outcome.kind === "error") {
|
|
22311
|
+
writeErrorWithHints(outcome.payload);
|
|
22312
|
+
surfaceUnauthorizedHint({
|
|
22313
|
+
auth,
|
|
22314
|
+
baseUrlOverridden,
|
|
22315
|
+
configDir: this.config.configDir,
|
|
22316
|
+
payload: outcome.payload
|
|
22317
|
+
});
|
|
22318
|
+
process.exitCode = 1;
|
|
22319
|
+
return;
|
|
22320
|
+
}
|
|
22321
|
+
this.log(JSON.stringify(outcome.data, null, 2));
|
|
22322
|
+
process.stderr.write(`Global secret ${flags.key} saved. Deployed functions pick it up on their next redeploy; a function secret of the same name overrides it.\n`);
|
|
22323
|
+
});
|
|
22324
|
+
}
|
|
22325
|
+
};
|
|
22326
|
+
//#endregion
|
|
21287
22327
|
//#region src/oclif/message-body-sources.ts
|
|
21288
22328
|
function defaultReadFile(path) {
|
|
21289
22329
|
return readFileSync(path, "utf8");
|
|
@@ -22657,6 +23697,10 @@ const CANONICAL_OPERATION_ALIASES = {
|
|
|
22657
23697
|
"account:show": "account:get-account",
|
|
22658
23698
|
"account:storage": "account:get-storage-stats",
|
|
22659
23699
|
"account:webhook-secret": "account:get-webhook-secret",
|
|
23700
|
+
"agent:claim": "agent:start-agent-claim",
|
|
23701
|
+
"agent:claim-link": "agent:create-agent-claim-link",
|
|
23702
|
+
"agent:claim-verify": "agent:verify-agent-claim",
|
|
23703
|
+
"agent:create": "agent:create-agent-account",
|
|
22660
23704
|
"deliveries:list": "webhook-deliveries:list-deliveries",
|
|
22661
23705
|
"deliveries:replay": "webhook-deliveries:replay-delivery",
|
|
22662
23706
|
"domains:add": "domains:add-domain",
|
|
@@ -22715,6 +23759,7 @@ const OVERRIDDEN_OPERATION_IDS = new Set([
|
|
|
22715
23759
|
const generatedCommands = Object.fromEntries(operationManifest.filter((operation) => !OVERRIDDEN_OPERATION_IDS.has(operationId(operation))).map((operation) => [operationId(operation), createOperationCommand(operation)]));
|
|
22716
23760
|
const COMMANDS = {
|
|
22717
23761
|
completion: CompletionCommand,
|
|
23762
|
+
"agent:upgrade": AgentUpgradeCommand,
|
|
22718
23763
|
"list-operations": ListOperationsCommand,
|
|
22719
23764
|
config: ConfigCommand,
|
|
22720
23765
|
"config:list": ConfigListCommand,
|
|
@@ -22767,6 +23812,9 @@ const COMMANDS = {
|
|
|
22767
23812
|
"functions:deploy": FunctionsDeployCommand,
|
|
22768
23813
|
"functions:redeploy": FunctionsRedeployCommand,
|
|
22769
23814
|
"functions:set-secret": FunctionsSetSecretCommand,
|
|
23815
|
+
"org:secrets:list": OrgSecretsListCommand,
|
|
23816
|
+
"org:secrets:set": OrgSecretsSetCommand,
|
|
23817
|
+
"org:secrets:remove": OrgSecretsRemoveCommand,
|
|
22770
23818
|
"functions:test": FunctionsTestFunctionCommand,
|
|
22771
23819
|
"functions:test-function": FunctionsTestFunctionCommand,
|
|
22772
23820
|
"functions:route-set": FunctionsRouteSetCommand,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primitivedotdev/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Official Primitive CLI: deploy Primitive Functions, send and inspect mail, manage endpoints, all from the terminal. Wraps the @primitivedotdev/sdk runtime client with one-shot commands.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -97,6 +97,12 @@
|
|
|
97
97
|
},
|
|
98
98
|
"functions": {
|
|
99
99
|
"description": "Deploy JavaScript handlers that run on inbound mail. Prefer `primitive functions templates`, `primitive functions init`, `primitive functions deploy`, `primitive functions redeploy`, `primitive functions list`, `primitive functions get`, `primitive functions logs`, and `primitive functions set-secret`; generated API names remain available for compatibility."
|
|
100
|
+
},
|
|
101
|
+
"org": {
|
|
102
|
+
"description": "Manage org-level (global) resources shared across functions"
|
|
103
|
+
},
|
|
104
|
+
"org:secrets": {
|
|
105
|
+
"description": "Global secrets shared across every function. Use `primitive org secrets list|set|remove`. Changes land in a function on its next redeploy; a function secret of the same name overrides the global."
|
|
100
106
|
}
|
|
101
107
|
},
|
|
102
108
|
"topicSeparator": " "
|