primcli 1.19.0 → 1.20.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.
Files changed (2) hide show
  1. package/dist/oclif/index.js +1578 -209
  2. package/package.json +4 -1
@@ -76,9 +76,12 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
76
76
  getSentEmail: () => getSentEmail,
77
77
  getSpendPolicy: () => getSpendPolicy,
78
78
  getStorageStats: () => getStorageStats,
79
+ getTemplate: () => getTemplate,
80
+ getTemplateInstall: () => getTemplateInstall,
79
81
  getThread: () => getThread,
80
82
  getWakeSchedule: () => getWakeSchedule,
81
83
  getWebhookSecret: () => getWebhookSecret,
84
+ installTemplate: () => installTemplate,
82
85
  listDeclinedPayments: () => listDeclinedPayments,
83
86
  listDeliveries: () => listDeliveries,
84
87
  listDomains: () => listDomains,
@@ -95,6 +98,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
95
98
  listRegistryRequests: () => listRegistryRequests,
96
99
  listRoutes: () => listRoutes,
97
100
  listSentEmails: () => listSentEmails,
101
+ listTemplates: () => listTemplates,
98
102
  listWakeAuthorizations: () => listWakeAuthorizations,
99
103
  listWakeDispatches: () => listWakeDispatches,
100
104
  listWakeSchedules: () => listWakeSchedules,
@@ -2025,6 +2029,65 @@ const searchMemories = (options) => (options?.client ?? client).get({
2025
2029
  ...options
2026
2030
  });
2027
2031
  /**
2032
+ * List function templates
2033
+ *
2034
+ * List approved Function templates available for browsing and
2035
+ * installation. Results are cacheable and paginated with
2036
+ * `data.next_cursor`.
2037
+ *
2038
+ */
2039
+ const listTemplates = (options) => (options?.client ?? client).get({
2040
+ url: "/templates",
2041
+ ...options
2042
+ });
2043
+ /**
2044
+ * Get a function template
2045
+ *
2046
+ * Fetch one approved Function template by slug, including its manifest
2047
+ * snapshot and README. The stored source files used for install are not
2048
+ * returned.
2049
+ *
2050
+ */
2051
+ const getTemplate = (options) => (options.client ?? client).get({
2052
+ url: "/templates/{id}",
2053
+ ...options
2054
+ });
2055
+ /**
2056
+ * Install a function template
2057
+ *
2058
+ * Start a one-shot deploy of an approved deploy-mode Function template.
2059
+ * The response returns an install record immediately; poll
2060
+ * `GET /templates/installs/{id}` for progress.
2061
+ *
2062
+ */
2063
+ const installTemplate = (options) => (options.client ?? client).post({
2064
+ security: [{
2065
+ scheme: "bearer",
2066
+ type: "http"
2067
+ }],
2068
+ url: "/templates/{id}/install",
2069
+ ...options,
2070
+ headers: {
2071
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2072
+ ...options.headers
2073
+ }
2074
+ });
2075
+ /**
2076
+ * Get template install status
2077
+ *
2078
+ * Fetch the current state of a template install. Reads may advance the
2079
+ * self-test phase when a reply effect has been observed.
2080
+ *
2081
+ */
2082
+ const getTemplateInstall = (options) => (options.client ?? client).get({
2083
+ security: [{
2084
+ scheme: "bearer",
2085
+ type: "http"
2086
+ }],
2087
+ url: "/templates/installs/{id}",
2088
+ ...options
2089
+ });
2090
+ /**
2028
2091
  * List payout addresses
2029
2092
  *
2030
2093
  * List your org's registered payout addresses, newest first.
@@ -2460,6 +2523,10 @@ const openapiDocument = {
2460
2523
  "name": "Memories",
2461
2524
  "description": "Durable org-scoped or function-scoped JSON key-value storage for\nagents and functions. Keys are caller-defined. Function scope is\nalways addressed by the function id UUID, not by function name.\n"
2462
2525
  },
2526
+ {
2527
+ "name": "Templates",
2528
+ "description": "Browse approved Function templates, install deploy-mode templates, and\npoll install progress.\n"
2529
+ },
2463
2530
  {
2464
2531
  "name": "Registries",
2465
2532
  "description": "The Agent Registry: ownable directories of agents, addressable by a\nregistry-scoped handle. A registry's publish policy (owner_only, request,\nor open) decides whether a publish lists immediately or pends owner\napproval. An agent is defined once with a globally unique,\nreachability-verified address, then published into any registry under a\nhandle. Discovery reads (list, resolve, get) are public for public\nregistries; managing a registry and moderating requests use the owner's\nAPI key.\n"
@@ -5285,6 +5352,167 @@ const openapiDocument = {
5285
5352
  "429": { "$ref": "#/components/responses/RateLimited" }
5286
5353
  }
5287
5354
  } },
5355
+ "/templates": { "get": {
5356
+ "operationId": "listTemplates",
5357
+ "summary": "List function templates",
5358
+ "description": "List approved Function templates available for browsing and\ninstallation. Results are cacheable and paginated with\n`data.next_cursor`.\n",
5359
+ "tags": ["Templates"],
5360
+ "security": [],
5361
+ "parameters": [
5362
+ {
5363
+ "name": "q",
5364
+ "in": "query",
5365
+ "required": false,
5366
+ "description": "Search templates by title, summary, or slug.",
5367
+ "schema": {
5368
+ "type": "string",
5369
+ "minLength": 1
5370
+ }
5371
+ },
5372
+ {
5373
+ "name": "tag",
5374
+ "in": "query",
5375
+ "required": false,
5376
+ "description": "Filter templates by an exact tag.",
5377
+ "schema": {
5378
+ "type": "string",
5379
+ "minLength": 1
5380
+ }
5381
+ },
5382
+ {
5383
+ "name": "cursor",
5384
+ "in": "query",
5385
+ "required": false,
5386
+ "description": "Cursor from a previous response `data.next_cursor` value.",
5387
+ "schema": { "type": "string" }
5388
+ },
5389
+ {
5390
+ "name": "limit",
5391
+ "in": "query",
5392
+ "required": false,
5393
+ "description": "Maximum number of templates to return. The server caps this at 100.",
5394
+ "schema": {
5395
+ "type": "integer",
5396
+ "minimum": 1,
5397
+ "maximum": 100,
5398
+ "default": 50
5399
+ }
5400
+ }
5401
+ ],
5402
+ "responses": {
5403
+ "200": {
5404
+ "description": "Paginated template registry summaries",
5405
+ "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
5406
+ "type": "object",
5407
+ "properties": { "data": { "$ref": "#/components/schemas/TemplateRegistryPage" } },
5408
+ "required": ["data"]
5409
+ }] } } }
5410
+ },
5411
+ "400": { "$ref": "#/components/responses/ValidationError" },
5412
+ "429": { "$ref": "#/components/responses/RateLimited" }
5413
+ }
5414
+ } },
5415
+ "/templates/{id}": { "get": {
5416
+ "operationId": "getTemplate",
5417
+ "summary": "Get a function template",
5418
+ "description": "Fetch one approved Function template by slug, including its manifest\nsnapshot and README. The stored source files used for install are not\nreturned.\n",
5419
+ "tags": ["Templates"],
5420
+ "security": [],
5421
+ "parameters": [{
5422
+ "name": "id",
5423
+ "in": "path",
5424
+ "required": true,
5425
+ "description": "Template slug from the template manifest.",
5426
+ "schema": {
5427
+ "type": "string",
5428
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$"
5429
+ }
5430
+ }],
5431
+ "responses": {
5432
+ "200": {
5433
+ "description": "Template registry detail",
5434
+ "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
5435
+ "type": "object",
5436
+ "properties": { "data": { "$ref": "#/components/schemas/TemplateRegistryDetail" } },
5437
+ "required": ["data"]
5438
+ }] } } }
5439
+ },
5440
+ "400": { "$ref": "#/components/responses/ValidationError" },
5441
+ "404": { "$ref": "#/components/responses/NotFound" },
5442
+ "429": { "$ref": "#/components/responses/RateLimited" }
5443
+ }
5444
+ } },
5445
+ "/templates/{id}/install": { "post": {
5446
+ "operationId": "installTemplate",
5447
+ "summary": "Install a function template",
5448
+ "description": "Start a one-shot deploy of an approved deploy-mode Function template.\nThe response returns an install record immediately; poll\n`GET /templates/installs/{id}` for progress.\n",
5449
+ "tags": ["Templates"],
5450
+ "security": [{ "BearerAuth": [] }],
5451
+ "parameters": [{
5452
+ "name": "id",
5453
+ "in": "path",
5454
+ "required": true,
5455
+ "description": "Template slug from the template manifest.",
5456
+ "schema": {
5457
+ "type": "string",
5458
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$"
5459
+ }
5460
+ }],
5461
+ "requestBody": {
5462
+ "required": true,
5463
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InstallTemplateBody" } } }
5464
+ },
5465
+ "responses": {
5466
+ "201": {
5467
+ "description": "Template install started",
5468
+ "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
5469
+ "type": "object",
5470
+ "properties": { "data": { "$ref": "#/components/schemas/TemplateInstallStatus" } },
5471
+ "required": ["data"]
5472
+ }] } } }
5473
+ },
5474
+ "400": { "$ref": "#/components/responses/ValidationError" },
5475
+ "401": { "$ref": "#/components/responses/Unauthorized" },
5476
+ "403": { "$ref": "#/components/responses/Forbidden" },
5477
+ "404": { "$ref": "#/components/responses/NotFound" },
5478
+ "409": { "$ref": "#/components/responses/Conflict" },
5479
+ "422": { "$ref": "#/components/responses/UnprocessableEntity" },
5480
+ "429": { "$ref": "#/components/responses/RateLimited" }
5481
+ }
5482
+ } },
5483
+ "/templates/installs/{id}": { "get": {
5484
+ "operationId": "getTemplateInstall",
5485
+ "summary": "Get template install status",
5486
+ "description": "Fetch the current state of a template install. Reads may advance the\nself-test phase when a reply effect has been observed.\n",
5487
+ "tags": ["Templates"],
5488
+ "security": [{ "BearerAuth": [] }],
5489
+ "parameters": [{
5490
+ "name": "id",
5491
+ "in": "path",
5492
+ "required": true,
5493
+ "description": "Template install UUID.",
5494
+ "schema": {
5495
+ "type": "string",
5496
+ "format": "uuid",
5497
+ "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
5498
+ }
5499
+ }],
5500
+ "responses": {
5501
+ "200": {
5502
+ "description": "Current template install status",
5503
+ "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
5504
+ "type": "object",
5505
+ "properties": { "data": { "$ref": "#/components/schemas/TemplateInstallStatus" } },
5506
+ "required": ["data"]
5507
+ }] } } }
5508
+ },
5509
+ "400": { "$ref": "#/components/responses/ValidationError" },
5510
+ "401": { "$ref": "#/components/responses/Unauthorized" },
5511
+ "403": { "$ref": "#/components/responses/Forbidden" },
5512
+ "404": { "$ref": "#/components/responses/NotFound" },
5513
+ "429": { "$ref": "#/components/responses/RateLimited" }
5514
+ }
5515
+ } },
5288
5516
  "/x402/payout-addresses": {
5289
5517
  "post": {
5290
5518
  "operationId": "registerPayoutAddress",
@@ -6955,6 +7183,16 @@ const openapiDocument = {
6955
7183
  "org_not_accessible",
6956
7184
  "feature_disabled",
6957
7185
  "memory_conflict",
7186
+ "template_not_installable",
7187
+ "scaffold_only",
7188
+ "invalid_variables",
7189
+ "unknown_secrets",
7190
+ "missing_secrets",
7191
+ "no_inbound_domain",
7192
+ "domain_cannot_send",
7193
+ "address_taken",
7194
+ "route_cap_reached",
7195
+ "name_exhausted",
6958
7196
  "developer_usage_credit_exhausted",
6959
7197
  "no_payout_address",
6960
7198
  "ownership_proof_failed",
@@ -11697,75 +11935,545 @@ const openapiDocument = {
11697
11935
  "key",
11698
11936
  "scope"
11699
11937
  ]
11700
- }
11701
- }
11702
- }
11703
- };
11704
- //#endregion
11705
- //#region ../packages/api-core/src/openapi/operations.generated.ts
11706
- const operationManifest = [
11707
- {
11708
- "binaryResponse": false,
11709
- "bodyRequired": false,
11710
- "command": "get-account",
11711
- "description": null,
11712
- "hasJsonBody": false,
11713
- "method": "GET",
11714
- "operationId": "getAccount",
11715
- "path": "/account",
11716
- "pathParams": [],
11717
- "queryParams": [],
11718
- "requestSchema": null,
11719
- "responseSchema": {
11720
- "type": "object",
11721
- "properties": {
11722
- "id": {
11723
- "type": "string",
11724
- "format": "uuid"
11725
- },
11726
- "email": { "type": "string" },
11727
- "plan": { "type": "string" },
11728
- "limits": {
11729
- "type": "object",
11730
- "description": "Plan-derived quota limits for an account.",
11731
- "properties": {
11732
- "storage_mb": { "type": "number" },
11733
- "send_per_hour": { "type": "number" },
11734
- "send_per_day": { "type": "number" },
11735
- "api_per_minute": { "type": "number" },
11736
- "webhooks_max_global": { "type": ["number", "null"] },
11737
- "webhooks_per_domain": { "type": "boolean" },
11738
- "filters_per_domain": { "type": "boolean" },
11739
- "spam_thresholds_per_domain": { "type": "boolean" }
11938
+ },
11939
+ "TemplateAuthor": {
11940
+ "type": "object",
11941
+ "additionalProperties": false,
11942
+ "properties": {
11943
+ "id": {
11944
+ "type": "string",
11945
+ "minLength": 1
11740
11946
  },
11741
- "required": [
11742
- "storage_mb",
11743
- "send_per_hour",
11744
- "send_per_day",
11745
- "api_per_minute",
11746
- "webhooks_max_global",
11747
- "webhooks_per_domain",
11748
- "filters_per_domain",
11749
- "spam_thresholds_per_domain"
11750
- ]
11751
- },
11752
- "entitlements": {
11753
- "type": "array",
11754
- "items": { "type": "string" },
11755
- "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"
11947
+ "name": {
11948
+ "type": "string",
11949
+ "minLength": 1
11950
+ },
11951
+ "url": {
11952
+ "type": "string",
11953
+ "format": "uri"
11954
+ }
11756
11955
  },
11757
- "managed_inbox_address": {
11758
- "type": ["string", "null"],
11759
- "description": "The managed inbox FQDN to reply as, or null if the org has no managed inbox."
11956
+ "required": ["id", "name"]
11957
+ },
11958
+ "TemplateSource": { "oneOf": [{
11959
+ "type": "object",
11960
+ "additionalProperties": false,
11961
+ "properties": {
11962
+ "mode": {
11963
+ "type": "string",
11964
+ "const": "managed-build"
11965
+ },
11966
+ "dir": {
11967
+ "type": "string",
11968
+ "minLength": 1,
11969
+ "default": "."
11970
+ }
11760
11971
  },
11761
- "created_at": {
11762
- "type": "string",
11763
- "format": "date-time"
11972
+ "required": ["mode", "dir"]
11973
+ }, {
11974
+ "type": "object",
11975
+ "additionalProperties": false,
11976
+ "properties": {
11977
+ "mode": {
11978
+ "type": "string",
11979
+ "const": "bundle"
11980
+ },
11981
+ "file": {
11982
+ "type": "string",
11983
+ "minLength": 1
11984
+ }
11764
11985
  },
11765
- "onboarding_completed": { "type": "boolean" },
11766
- "onboarding_step": { "type": ["string", "null"] },
11767
- "stripe_subscription_status": { "type": ["string", "null"] },
11768
- "subscription_current_period_end": {
11986
+ "required": ["mode", "file"]
11987
+ }] },
11988
+ "TemplateInstall": {
11989
+ "type": "object",
11990
+ "additionalProperties": false,
11991
+ "properties": {
11992
+ "mode": {
11993
+ "type": "string",
11994
+ "enum": ["deploy", "scaffold"]
11995
+ },
11996
+ "editFiles": {
11997
+ "type": "array",
11998
+ "items": {
11999
+ "type": "string",
12000
+ "minLength": 1
12001
+ }
12002
+ },
12003
+ "reason": {
12004
+ "type": "string",
12005
+ "default": ""
12006
+ }
12007
+ },
12008
+ "required": [
12009
+ "mode",
12010
+ "editFiles",
12011
+ "reason"
12012
+ ]
12013
+ },
12014
+ "TemplateSecret": {
12015
+ "type": "object",
12016
+ "additionalProperties": false,
12017
+ "properties": {
12018
+ "key": {
12019
+ "type": "string",
12020
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
12021
+ },
12022
+ "required": {
12023
+ "type": "boolean",
12024
+ "default": true
12025
+ },
12026
+ "description": { "type": "string" }
12027
+ },
12028
+ "required": ["key", "required"]
12029
+ },
12030
+ "TemplateSecretGroup": {
12031
+ "type": "object",
12032
+ "additionalProperties": false,
12033
+ "properties": {
12034
+ "keys": {
12035
+ "type": "array",
12036
+ "minItems": 2,
12037
+ "items": {
12038
+ "type": "string",
12039
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
12040
+ }
12041
+ },
12042
+ "min": {
12043
+ "type": "integer",
12044
+ "minimum": 1,
12045
+ "default": 1
12046
+ },
12047
+ "description": { "type": "string" }
12048
+ },
12049
+ "required": ["keys", "min"]
12050
+ },
12051
+ "TemplateVariableValidation": {
12052
+ "type": "object",
12053
+ "additionalProperties": false,
12054
+ "properties": {
12055
+ "pattern": {
12056
+ "type": "string",
12057
+ "minLength": 1
12058
+ },
12059
+ "maxLength": {
12060
+ "type": "integer",
12061
+ "minimum": 1
12062
+ }
12063
+ }
12064
+ },
12065
+ "TemplateVariable": {
12066
+ "type": "object",
12067
+ "additionalProperties": false,
12068
+ "properties": {
12069
+ "key": {
12070
+ "type": "string",
12071
+ "minLength": 1
12072
+ },
12073
+ "prompt": {
12074
+ "type": "string",
12075
+ "minLength": 1
12076
+ },
12077
+ "default": { "type": "string" },
12078
+ "file": {
12079
+ "type": "string",
12080
+ "minLength": 1
12081
+ },
12082
+ "type": {
12083
+ "type": "string",
12084
+ "enum": [
12085
+ "string",
12086
+ "select",
12087
+ "url",
12088
+ "email"
12089
+ ],
12090
+ "default": "string"
12091
+ },
12092
+ "options": {
12093
+ "type": "array",
12094
+ "items": {
12095
+ "type": "string",
12096
+ "minLength": 1
12097
+ }
12098
+ },
12099
+ "validation": { "$ref": "#/components/schemas/TemplateVariableValidation" }
12100
+ },
12101
+ "required": [
12102
+ "key",
12103
+ "prompt",
12104
+ "type"
12105
+ ]
12106
+ },
12107
+ "TemplateSetup": {
12108
+ "type": "object",
12109
+ "additionalProperties": false,
12110
+ "properties": {
12111
+ "agent": {
12112
+ "type": "string",
12113
+ "minLength": 1
12114
+ },
12115
+ "prompt": {
12116
+ "type": "string",
12117
+ "minLength": 1
12118
+ },
12119
+ "produces": {
12120
+ "type": "array",
12121
+ "items": {
12122
+ "type": "string",
12123
+ "minLength": 1
12124
+ }
12125
+ }
12126
+ },
12127
+ "required": [
12128
+ "agent",
12129
+ "prompt",
12130
+ "produces"
12131
+ ]
12132
+ },
12133
+ "TemplateManifest": {
12134
+ "type": "object",
12135
+ "additionalProperties": false,
12136
+ "properties": {
12137
+ "schemaVersion": {
12138
+ "type": "integer",
12139
+ "const": 1
12140
+ },
12141
+ "id": {
12142
+ "type": "string",
12143
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
12144
+ "description": "Stable template slug from the manifest."
12145
+ },
12146
+ "title": {
12147
+ "type": "string",
12148
+ "minLength": 1
12149
+ },
12150
+ "summary": {
12151
+ "type": "string",
12152
+ "minLength": 1
12153
+ },
12154
+ "description": { "type": "string" },
12155
+ "author": { "$ref": "#/components/schemas/TemplateAuthor" },
12156
+ "tags": {
12157
+ "type": "array",
12158
+ "items": {
12159
+ "type": "string",
12160
+ "minLength": 1
12161
+ }
12162
+ },
12163
+ "source": { "$ref": "#/components/schemas/TemplateSource" },
12164
+ "install": { "$ref": "#/components/schemas/TemplateInstall" },
12165
+ "secrets": {
12166
+ "type": "array",
12167
+ "items": { "$ref": "#/components/schemas/TemplateSecret" }
12168
+ },
12169
+ "secretGroups": {
12170
+ "type": "array",
12171
+ "items": { "$ref": "#/components/schemas/TemplateSecretGroup" }
12172
+ },
12173
+ "variables": {
12174
+ "type": "array",
12175
+ "items": { "$ref": "#/components/schemas/TemplateVariable" }
12176
+ },
12177
+ "setup": { "$ref": "#/components/schemas/TemplateSetup" },
12178
+ "postInstall": { "type": "string" }
12179
+ },
12180
+ "required": [
12181
+ "schemaVersion",
12182
+ "id",
12183
+ "title",
12184
+ "summary",
12185
+ "author",
12186
+ "tags",
12187
+ "source",
12188
+ "install",
12189
+ "secrets",
12190
+ "secretGroups",
12191
+ "variables"
12192
+ ]
12193
+ },
12194
+ "TemplateRegistryStatus": {
12195
+ "type": "string",
12196
+ "enum": [
12197
+ "pending",
12198
+ "approved",
12199
+ "rejected"
12200
+ ]
12201
+ },
12202
+ "TemplateRegistrySummary": {
12203
+ "type": "object",
12204
+ "properties": {
12205
+ "id": {
12206
+ "type": "string",
12207
+ "format": "uuid"
12208
+ },
12209
+ "slug": {
12210
+ "type": "string",
12211
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
12212
+ "description": "Stable template slug used in template URLs and install commands."
12213
+ },
12214
+ "title": { "type": "string" },
12215
+ "summary": { "type": "string" },
12216
+ "author": { "$ref": "#/components/schemas/TemplateAuthor" },
12217
+ "tags": {
12218
+ "type": "array",
12219
+ "items": { "type": "string" }
12220
+ },
12221
+ "verified": { "type": "boolean" },
12222
+ "install_count": {
12223
+ "type": "integer",
12224
+ "minimum": 0
12225
+ },
12226
+ "github_repo": {
12227
+ "type": "string",
12228
+ "pattern": "^[A-Za-z0-9-]+/[A-Za-z0-9_.-]+$",
12229
+ "description": "GitHub repository in owner/repo form."
12230
+ },
12231
+ "created_at": {
12232
+ "type": "string",
12233
+ "format": "date-time"
12234
+ },
12235
+ "updated_at": {
12236
+ "type": "string",
12237
+ "format": "date-time"
12238
+ }
12239
+ },
12240
+ "required": [
12241
+ "id",
12242
+ "slug",
12243
+ "title",
12244
+ "summary",
12245
+ "author",
12246
+ "tags",
12247
+ "verified",
12248
+ "install_count",
12249
+ "github_repo",
12250
+ "created_at",
12251
+ "updated_at"
12252
+ ]
12253
+ },
12254
+ "TemplateRegistryDetail": {
12255
+ "type": "object",
12256
+ "properties": {
12257
+ "id": {
12258
+ "type": "string",
12259
+ "format": "uuid"
12260
+ },
12261
+ "slug": {
12262
+ "type": "string",
12263
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
12264
+ "description": "Stable template slug used in template URLs and install commands."
12265
+ },
12266
+ "title": { "type": "string" },
12267
+ "summary": { "type": "string" },
12268
+ "author": { "$ref": "#/components/schemas/TemplateAuthor" },
12269
+ "tags": {
12270
+ "type": "array",
12271
+ "items": { "type": "string" }
12272
+ },
12273
+ "verified": { "type": "boolean" },
12274
+ "install_count": {
12275
+ "type": "integer",
12276
+ "minimum": 0
12277
+ },
12278
+ "github_repo": {
12279
+ "type": "string",
12280
+ "pattern": "^[A-Za-z0-9-]+/[A-Za-z0-9_.-]+$",
12281
+ "description": "GitHub repository in owner/repo form."
12282
+ },
12283
+ "created_at": {
12284
+ "type": "string",
12285
+ "format": "date-time"
12286
+ },
12287
+ "updated_at": {
12288
+ "type": "string",
12289
+ "format": "date-time"
12290
+ },
12291
+ "description": { "type": ["string", "null"] },
12292
+ "github_sha": { "type": "string" },
12293
+ "github_path": { "type": ["string", "null"] },
12294
+ "manifest": { "$ref": "#/components/schemas/TemplateManifest" },
12295
+ "readme": { "type": ["string", "null"] },
12296
+ "status": { "$ref": "#/components/schemas/TemplateRegistryStatus" }
12297
+ },
12298
+ "required": [
12299
+ "id",
12300
+ "slug",
12301
+ "title",
12302
+ "summary",
12303
+ "author",
12304
+ "tags",
12305
+ "verified",
12306
+ "install_count",
12307
+ "github_repo",
12308
+ "created_at",
12309
+ "updated_at",
12310
+ "description",
12311
+ "github_sha",
12312
+ "github_path",
12313
+ "manifest",
12314
+ "readme",
12315
+ "status"
12316
+ ]
12317
+ },
12318
+ "TemplateRegistryPage": {
12319
+ "type": "object",
12320
+ "properties": {
12321
+ "items": {
12322
+ "type": "array",
12323
+ "items": { "$ref": "#/components/schemas/TemplateRegistrySummary" }
12324
+ },
12325
+ "next_cursor": {
12326
+ "type": ["string", "null"],
12327
+ "description": "Cursor to pass as the next `cursor` query value, or null when there are no more templates."
12328
+ }
12329
+ },
12330
+ "required": ["items", "next_cursor"]
12331
+ },
12332
+ "InstallTemplateBody": {
12333
+ "type": "object",
12334
+ "additionalProperties": false,
12335
+ "properties": {
12336
+ "address": {
12337
+ "type": "string",
12338
+ "pattern": "^[a-z0-9][a-z0-9._-]{0,63}$",
12339
+ "description": "Localpart to claim on the selected inbound domain. Defaults to the template slug."
12340
+ },
12341
+ "domain": {
12342
+ "type": "string",
12343
+ "minLength": 3,
12344
+ "description": "Org domain name to claim the address on. Defaults to the org's newest active domain."
12345
+ },
12346
+ "variables": {
12347
+ "type": "object",
12348
+ "additionalProperties": { "type": "string" },
12349
+ "description": "Template variable values keyed by manifest variable key."
12350
+ },
12351
+ "secrets": {
12352
+ "type": "object",
12353
+ "additionalProperties": { "type": "string" },
12354
+ "description": "Secret values keyed by manifest secret key."
12355
+ }
12356
+ }
12357
+ },
12358
+ "TemplateInstallState": {
12359
+ "type": "string",
12360
+ "enum": [
12361
+ "deploying",
12362
+ "connecting",
12363
+ "bound",
12364
+ "tested",
12365
+ "deploy_failed",
12366
+ "bind_failed",
12367
+ "test_failed"
12368
+ ]
12369
+ },
12370
+ "TemplateInstallStatus": {
12371
+ "type": "object",
12372
+ "properties": {
12373
+ "id": {
12374
+ "type": "string",
12375
+ "format": "uuid"
12376
+ },
12377
+ "template_slug": {
12378
+ "type": "string",
12379
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
12380
+ "description": "Template slug for this install."
12381
+ },
12382
+ "state": { "$ref": "#/components/schemas/TemplateInstallState" },
12383
+ "address": { "type": ["string", "null"] },
12384
+ "function_id": {
12385
+ "type": ["string", "null"],
12386
+ "format": "uuid"
12387
+ },
12388
+ "error": { "type": ["string", "null"] },
12389
+ "created_at": {
12390
+ "type": "string",
12391
+ "format": "date-time"
12392
+ },
12393
+ "updated_at": {
12394
+ "type": "string",
12395
+ "format": "date-time"
12396
+ }
12397
+ },
12398
+ "required": [
12399
+ "id",
12400
+ "template_slug",
12401
+ "state",
12402
+ "address",
12403
+ "function_id",
12404
+ "error",
12405
+ "created_at",
12406
+ "updated_at"
12407
+ ]
12408
+ }
12409
+ }
12410
+ }
12411
+ };
12412
+ //#endregion
12413
+ //#region ../packages/api-core/src/openapi/operations.generated.ts
12414
+ const operationManifest = [
12415
+ {
12416
+ "binaryResponse": false,
12417
+ "bodyRequired": false,
12418
+ "command": "get-account",
12419
+ "description": null,
12420
+ "hasJsonBody": false,
12421
+ "method": "GET",
12422
+ "operationId": "getAccount",
12423
+ "path": "/account",
12424
+ "pathParams": [],
12425
+ "queryParams": [],
12426
+ "requestSchema": null,
12427
+ "responseSchema": {
12428
+ "type": "object",
12429
+ "properties": {
12430
+ "id": {
12431
+ "type": "string",
12432
+ "format": "uuid"
12433
+ },
12434
+ "email": { "type": "string" },
12435
+ "plan": { "type": "string" },
12436
+ "limits": {
12437
+ "type": "object",
12438
+ "description": "Plan-derived quota limits for an account.",
12439
+ "properties": {
12440
+ "storage_mb": { "type": "number" },
12441
+ "send_per_hour": { "type": "number" },
12442
+ "send_per_day": { "type": "number" },
12443
+ "api_per_minute": { "type": "number" },
12444
+ "webhooks_max_global": { "type": ["number", "null"] },
12445
+ "webhooks_per_domain": { "type": "boolean" },
12446
+ "filters_per_domain": { "type": "boolean" },
12447
+ "spam_thresholds_per_domain": { "type": "boolean" }
12448
+ },
12449
+ "required": [
12450
+ "storage_mb",
12451
+ "send_per_hour",
12452
+ "send_per_day",
12453
+ "api_per_minute",
12454
+ "webhooks_max_global",
12455
+ "webhooks_per_domain",
12456
+ "filters_per_domain",
12457
+ "spam_thresholds_per_domain"
12458
+ ]
12459
+ },
12460
+ "entitlements": {
12461
+ "type": "array",
12462
+ "items": { "type": "string" },
12463
+ "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"
12464
+ },
12465
+ "managed_inbox_address": {
12466
+ "type": ["string", "null"],
12467
+ "description": "The managed inbox FQDN to reply as, or null if the org has no managed inbox."
12468
+ },
12469
+ "created_at": {
12470
+ "type": "string",
12471
+ "format": "date-time"
12472
+ },
12473
+ "onboarding_completed": { "type": "boolean" },
12474
+ "onboarding_step": { "type": ["string", "null"] },
12475
+ "stripe_subscription_status": { "type": ["string", "null"] },
12476
+ "subscription_current_period_end": {
11769
12477
  "type": ["string", "null"],
11770
12478
  "format": "date-time"
11771
12479
  },
@@ -20940,7 +21648,206 @@ const operationManifest = [
20940
21648
  "required": ["filename", "content_base64"]
20941
21649
  }
20942
21650
  }
20943
- }
21651
+ }
21652
+ },
21653
+ "responseSchema": {
21654
+ "type": "object",
21655
+ "properties": {
21656
+ "id": {
21657
+ "type": "string",
21658
+ "description": "Persisted sent-email attempt ID."
21659
+ },
21660
+ "status": {
21661
+ "type": "string",
21662
+ "description": "Lifecycle status of a sent_emails row. Possible values:\n\n - `queued`: pre-call INSERT; the outbound agent has not\n yet replied.\n - `submitted_to_agent`: agent accepted; `queue_id` is set.\n - `agent_failed`: agent rejected; `error_code` and\n `error_message` carry the reason.\n - `gate_denied`: a recipient-scope gate denied the send;\n the agent was never called. The `gates` array carries\n the denial detail. /send-mail returns 403 in this case\n so callers see the denial synchronously; /sent-emails\n additionally records the row for historical lookup,\n which is when this status appears in a listing.\n - `unknown`: terminal indeterminate; the on-box log\n poller couldn't classify the receiver's response.\n - `delivered` / `bounced` / `deferred` / `wait_timeout`:\n terminal delivery outcomes (see DeliveryStatus).\n",
21663
+ "enum": [
21664
+ "queued",
21665
+ "submitted_to_agent",
21666
+ "agent_failed",
21667
+ "gate_denied",
21668
+ "unknown",
21669
+ "delivered",
21670
+ "bounced",
21671
+ "deferred",
21672
+ "wait_timeout"
21673
+ ]
21674
+ },
21675
+ "from": {
21676
+ "type": "string",
21677
+ "description": "Bare from-address actually written on the wire. Echoed\non every success branch so callers can confirm what\nwent out, particularly useful for the /emails/{id}/reply\npath where `from` is server-derived from the inbound's\nrecipient when the caller doesn't override.\n\nFor sends where the caller passed a from-header that\nincluded a display name (e.g. `\"Acme Support\" <support@acme.test>`),\nthis field is the parsed bare address (`support@acme.test`).\nThe display name was sent on the wire intact; this field\njust makes the address easy to compare against allowlists.\n"
21678
+ },
21679
+ "queue_id": {
21680
+ "type": ["string", "null"],
21681
+ "description": "Message identifier assigned by Primitive's OUTBOUND relay\n(the box that signs your mail and submits it to the\nreceiving MTA). NOT the receiver's queue id.\n\nThe receiver may also report its own queue id in\n`smtp_response_text` (e.g. `\"250 2.0.0 Ok: queued as\n99D111927CDA\"` from a Postfix receiver). Those two ids\nrefer to different mail systems and are NOT comparable.\nTreat `queue_id` as Primitive-internal and the\nreceiver's id as remote-system-internal.\n\nNull on rows that never reached the relay (queued,\ngate_denied, agent_failed before signing).\n"
21682
+ },
21683
+ "accepted": {
21684
+ "type": "array",
21685
+ "items": { "type": "string" },
21686
+ "description": "Recipient addresses accepted by the relay."
21687
+ },
21688
+ "rejected": {
21689
+ "type": "array",
21690
+ "items": { "type": "string" },
21691
+ "description": "Recipient addresses rejected by the relay."
21692
+ },
21693
+ "client_idempotency_key": {
21694
+ "type": "string",
21695
+ "description": "Effective idempotency key used for this send."
21696
+ },
21697
+ "request_id": {
21698
+ "type": "string",
21699
+ "description": "Server-issued request identifier for support and tracing."
21700
+ },
21701
+ "content_hash": {
21702
+ "type": "string",
21703
+ "description": "Stable hash of the canonical send payload."
21704
+ },
21705
+ "delivery_status": {
21706
+ "type": "string",
21707
+ "description": "Narrower enum covering only the four terminal delivery\noutcomes returned to a synchronous `wait: true` send.\n\nOn the SendMailResult shape, `delivery_status` is always\nequal to `status` whenever both are present (i.e. on\nterminal-state replays and live wait=true responses).\nThe two fields exist so callers that want to type-narrow\non \"this is a delivery outcome\" can pattern-match against\nthe four-value enum without handling the broader\nSentEmailStatus value set (which also covers `queued`,\n`submitted_to_agent`, `agent_failed`, `gate_denied`,\n`unknown`).\n\nOn async-mode and pre-terminal responses, `delivery_status`\nis absent and only `status` is populated. Use `status` if\nyou want a single field that's always present.\n",
21708
+ "enum": [
21709
+ "delivered",
21710
+ "bounced",
21711
+ "deferred",
21712
+ "wait_timeout"
21713
+ ]
21714
+ },
21715
+ "smtp_response_code": {
21716
+ "type": ["integer", "null"],
21717
+ "description": "SMTP response code from the first downstream delivery outcome when wait is true."
21718
+ },
21719
+ "smtp_response_text": {
21720
+ "type": "string",
21721
+ "description": "SMTP response text from the first downstream delivery outcome when wait is true."
21722
+ },
21723
+ "idempotent_replay": {
21724
+ "type": "boolean",
21725
+ "description": "True when the response replays a previously-recorded send\nkeyed by `client_idempotency_key` (same key, same canonical\npayload). False on a fresh send and on gate-denied\nresponses. Lets callers branch on cache state without\ndiffing fields.\n"
21726
+ }
21727
+ },
21728
+ "required": [
21729
+ "id",
21730
+ "status",
21731
+ "from",
21732
+ "queue_id",
21733
+ "accepted",
21734
+ "rejected",
21735
+ "client_idempotency_key",
21736
+ "request_id",
21737
+ "content_hash",
21738
+ "idempotent_replay"
21739
+ ]
21740
+ },
21741
+ "sdkName": "replyToEmail",
21742
+ "summary": "Reply to an inbound email",
21743
+ "tag": "Sending",
21744
+ "tagCommand": "sending"
21745
+ },
21746
+ {
21747
+ "binaryResponse": false,
21748
+ "bodyRequired": true,
21749
+ "command": "send-email",
21750
+ "description": "Sends an outbound email through Primitive's outbound relay. By default\nthe request returns once the relay accepts the message for delivery.\nSet `wait: true` to wait for the first downstream SMTP delivery outcome.\n\n**Host routing.** /send-mail is served by the canonical API host\n(`https://api.primitive.dev/v1`) so the request body can carry\ninline attachments up to ~30 MiB raw. The legacy dashboard\ncompatibility host (`https://www.primitive.dev/api/v1`) also accepts\n/send-mail, but Vercel request body limits apply before proxying.\nThe typed SDKs route /send-mail to the canonical API host\nautomatically.\n",
21751
+ "hasJsonBody": true,
21752
+ "method": "POST",
21753
+ "operationId": "sendEmail",
21754
+ "path": "/send-mail",
21755
+ "pathParams": [],
21756
+ "queryParams": [],
21757
+ "requestSchema": {
21758
+ "type": "object",
21759
+ "additionalProperties": false,
21760
+ "properties": {
21761
+ "from": {
21762
+ "type": "string",
21763
+ "minLength": 3,
21764
+ "maxLength": 998,
21765
+ "description": "RFC 5322 From header. The sender domain must be a verified outbound domain for your organization."
21766
+ },
21767
+ "to": {
21768
+ "type": "string",
21769
+ "minLength": 3,
21770
+ "maxLength": 320,
21771
+ "description": "Recipient address. Recipient eligibility depends on your account's outbound entitlements."
21772
+ },
21773
+ "subject": {
21774
+ "type": "string",
21775
+ "minLength": 1,
21776
+ "maxLength": 998,
21777
+ "description": "Subject line for the outbound message"
21778
+ },
21779
+ "body_text": {
21780
+ "type": "string",
21781
+ "description": "Plain-text message body. At least one of body_text or body_html is required. The combined UTF-8 byte length of body_text and body_html must be at most 262144 bytes."
21782
+ },
21783
+ "body_html": {
21784
+ "type": "string",
21785
+ "description": "HTML message body. At least one of body_text or body_html is required. The combined UTF-8 byte length of body_text and body_html must be at most 262144 bytes."
21786
+ },
21787
+ "in_reply_to": {
21788
+ "type": "string",
21789
+ "minLength": 1,
21790
+ "maxLength": 998,
21791
+ "pattern": "^[^\\x00-\\x1F\\x7F]+$",
21792
+ "description": "Message-ID of the direct parent email when sending a threaded reply."
21793
+ },
21794
+ "references": {
21795
+ "type": "array",
21796
+ "maxItems": 100,
21797
+ "description": "Full ordered message-id chain for the thread.",
21798
+ "items": {
21799
+ "type": "string",
21800
+ "minLength": 1,
21801
+ "maxLength": 998,
21802
+ "pattern": "^[^\\x00-\\x1F\\x7F]+$"
21803
+ }
21804
+ },
21805
+ "attachments": {
21806
+ "type": "array",
21807
+ "maxItems": 100,
21808
+ "description": "Inline attachments. Send requests with attachments to https://api.primitive.dev/v1/send-mail. Combined raw decoded attachment bytes must be at most 31457280.",
21809
+ "items": {
21810
+ "type": "object",
21811
+ "additionalProperties": false,
21812
+ "properties": {
21813
+ "filename": {
21814
+ "type": "string",
21815
+ "minLength": 1,
21816
+ "maxLength": 255,
21817
+ "description": "Attachment filename. Control characters are rejected."
21818
+ },
21819
+ "content_type": {
21820
+ "type": "string",
21821
+ "minLength": 1,
21822
+ "maxLength": 255,
21823
+ "description": "Optional MIME content type. Control characters are rejected."
21824
+ },
21825
+ "content_base64": {
21826
+ "type": "string",
21827
+ "minLength": 1,
21828
+ "maxLength": 44040192,
21829
+ "description": "Base64-encoded attachment bytes."
21830
+ }
21831
+ },
21832
+ "required": ["filename", "content_base64"]
21833
+ }
21834
+ },
21835
+ "wait": {
21836
+ "type": "boolean",
21837
+ "description": "When true, wait for the first downstream SMTP delivery outcome before returning."
21838
+ },
21839
+ "wait_timeout_ms": {
21840
+ "type": "integer",
21841
+ "minimum": 1e3,
21842
+ "maximum": 3e4,
21843
+ "description": "Maximum time to wait for a delivery outcome when wait is true. Defaults to 30000."
21844
+ }
21845
+ },
21846
+ "required": [
21847
+ "from",
21848
+ "to",
21849
+ "subject"
21850
+ ]
20944
21851
  },
20945
21852
  "responseSchema": {
20946
21853
  "type": "object",
@@ -21030,209 +21937,671 @@ const operationManifest = [
21030
21937
  "idempotent_replay"
21031
21938
  ]
21032
21939
  },
21033
- "sdkName": "replyToEmail",
21034
- "summary": "Reply to an inbound email",
21940
+ "sdkName": "sendEmail",
21941
+ "summary": "Send outbound email",
21035
21942
  "tag": "Sending",
21036
21943
  "tagCommand": "sending"
21037
21944
  },
21038
21945
  {
21039
21946
  "binaryResponse": false,
21040
- "bodyRequired": true,
21041
- "command": "send-email",
21042
- "description": "Sends an outbound email through Primitive's outbound relay. By default\nthe request returns once the relay accepts the message for delivery.\nSet `wait: true` to wait for the first downstream SMTP delivery outcome.\n\n**Host routing.** /send-mail is served by the canonical API host\n(`https://api.primitive.dev/v1`) so the request body can carry\ninline attachments up to ~30 MiB raw. The legacy dashboard\ncompatibility host (`https://www.primitive.dev/api/v1`) also accepts\n/send-mail, but Vercel request body limits apply before proxying.\nThe typed SDKs route /send-mail to the canonical API host\nautomatically.\n",
21043
- "hasJsonBody": true,
21044
- "method": "POST",
21045
- "operationId": "sendEmail",
21046
- "path": "/send-mail",
21047
- "pathParams": [],
21947
+ "bodyRequired": false,
21948
+ "command": "get-template",
21949
+ "description": "Fetch one approved Function template by slug, including its manifest\nsnapshot and README. The stored source files used for install are not\nreturned.\n",
21950
+ "hasJsonBody": false,
21951
+ "method": "GET",
21952
+ "operationId": "getTemplate",
21953
+ "path": "/templates/{id}",
21954
+ "pathParams": [{
21955
+ "description": "Template slug from the template manifest.",
21956
+ "enum": null,
21957
+ "name": "id",
21958
+ "required": true,
21959
+ "type": "string"
21960
+ }],
21048
21961
  "queryParams": [],
21049
- "requestSchema": {
21962
+ "requestSchema": null,
21963
+ "responseSchema": {
21050
21964
  "type": "object",
21051
- "additionalProperties": false,
21052
21965
  "properties": {
21053
- "from": {
21966
+ "id": {
21054
21967
  "type": "string",
21055
- "minLength": 3,
21056
- "maxLength": 998,
21057
- "description": "RFC 5322 From header. The sender domain must be a verified outbound domain for your organization."
21968
+ "format": "uuid"
21058
21969
  },
21059
- "to": {
21970
+ "slug": {
21060
21971
  "type": "string",
21061
- "minLength": 3,
21062
- "maxLength": 320,
21063
- "description": "Recipient address. Recipient eligibility depends on your account's outbound entitlements."
21972
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
21973
+ "description": "Stable template slug used in template URLs and install commands."
21064
21974
  },
21065
- "subject": {
21066
- "type": "string",
21067
- "minLength": 1,
21068
- "maxLength": 998,
21069
- "description": "Subject line for the outbound message"
21975
+ "title": { "type": "string" },
21976
+ "summary": { "type": "string" },
21977
+ "author": {
21978
+ "type": "object",
21979
+ "additionalProperties": false,
21980
+ "properties": {
21981
+ "id": {
21982
+ "type": "string",
21983
+ "minLength": 1
21984
+ },
21985
+ "name": {
21986
+ "type": "string",
21987
+ "minLength": 1
21988
+ },
21989
+ "url": {
21990
+ "type": "string",
21991
+ "format": "uri"
21992
+ }
21993
+ },
21994
+ "required": ["id", "name"]
21070
21995
  },
21071
- "body_text": {
21072
- "type": "string",
21073
- "description": "Plain-text message body. At least one of body_text or body_html is required. The combined UTF-8 byte length of body_text and body_html must be at most 262144 bytes."
21996
+ "tags": {
21997
+ "type": "array",
21998
+ "items": { "type": "string" }
21074
21999
  },
21075
- "body_html": {
22000
+ "verified": { "type": "boolean" },
22001
+ "install_count": {
22002
+ "type": "integer",
22003
+ "minimum": 0
22004
+ },
22005
+ "github_repo": {
21076
22006
  "type": "string",
21077
- "description": "HTML message body. At least one of body_text or body_html is required. The combined UTF-8 byte length of body_text and body_html must be at most 262144 bytes."
22007
+ "pattern": "^[A-Za-z0-9-]+/[A-Za-z0-9_.-]+$",
22008
+ "description": "GitHub repository in owner/repo form."
21078
22009
  },
21079
- "in_reply_to": {
22010
+ "created_at": {
21080
22011
  "type": "string",
21081
- "minLength": 1,
21082
- "maxLength": 998,
21083
- "pattern": "^[^\\x00-\\x1F\\x7F]+$",
21084
- "description": "Message-ID of the direct parent email when sending a threaded reply."
22012
+ "format": "date-time"
21085
22013
  },
21086
- "references": {
21087
- "type": "array",
21088
- "maxItems": 100,
21089
- "description": "Full ordered message-id chain for the thread.",
21090
- "items": {
21091
- "type": "string",
21092
- "minLength": 1,
21093
- "maxLength": 998,
21094
- "pattern": "^[^\\x00-\\x1F\\x7F]+$"
21095
- }
22014
+ "updated_at": {
22015
+ "type": "string",
22016
+ "format": "date-time"
21096
22017
  },
21097
- "attachments": {
21098
- "type": "array",
21099
- "maxItems": 100,
21100
- "description": "Inline attachments. Send requests with attachments to https://api.primitive.dev/v1/send-mail. Combined raw decoded attachment bytes must be at most 31457280.",
21101
- "items": {
21102
- "type": "object",
21103
- "additionalProperties": false,
21104
- "properties": {
21105
- "filename": {
21106
- "type": "string",
21107
- "minLength": 1,
21108
- "maxLength": 255,
21109
- "description": "Attachment filename. Control characters are rejected."
22018
+ "description": { "type": ["string", "null"] },
22019
+ "github_sha": { "type": "string" },
22020
+ "github_path": { "type": ["string", "null"] },
22021
+ "manifest": {
22022
+ "type": "object",
22023
+ "additionalProperties": false,
22024
+ "properties": {
22025
+ "schemaVersion": {
22026
+ "type": "integer",
22027
+ "const": 1
22028
+ },
22029
+ "id": {
22030
+ "type": "string",
22031
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
22032
+ "description": "Stable template slug from the manifest."
22033
+ },
22034
+ "title": {
22035
+ "type": "string",
22036
+ "minLength": 1
22037
+ },
22038
+ "summary": {
22039
+ "type": "string",
22040
+ "minLength": 1
22041
+ },
22042
+ "description": { "type": "string" },
22043
+ "author": {
22044
+ "type": "object",
22045
+ "additionalProperties": false,
22046
+ "properties": {
22047
+ "id": {
22048
+ "type": "string",
22049
+ "minLength": 1
22050
+ },
22051
+ "name": {
22052
+ "type": "string",
22053
+ "minLength": 1
22054
+ },
22055
+ "url": {
22056
+ "type": "string",
22057
+ "format": "uri"
22058
+ }
21110
22059
  },
21111
- "content_type": {
22060
+ "required": ["id", "name"]
22061
+ },
22062
+ "tags": {
22063
+ "type": "array",
22064
+ "items": {
21112
22065
  "type": "string",
21113
- "minLength": 1,
21114
- "maxLength": 255,
21115
- "description": "Optional MIME content type. Control characters are rejected."
22066
+ "minLength": 1
22067
+ }
22068
+ },
22069
+ "source": { "oneOf": [{
22070
+ "type": "object",
22071
+ "additionalProperties": false,
22072
+ "properties": {
22073
+ "mode": {
22074
+ "type": "string",
22075
+ "const": "managed-build"
22076
+ },
22077
+ "dir": {
22078
+ "type": "string",
22079
+ "minLength": 1,
22080
+ "default": "."
22081
+ }
21116
22082
  },
21117
- "content_base64": {
21118
- "type": "string",
21119
- "minLength": 1,
21120
- "maxLength": 44040192,
21121
- "description": "Base64-encoded attachment bytes."
22083
+ "required": ["mode", "dir"]
22084
+ }, {
22085
+ "type": "object",
22086
+ "additionalProperties": false,
22087
+ "properties": {
22088
+ "mode": {
22089
+ "type": "string",
22090
+ "const": "bundle"
22091
+ },
22092
+ "file": {
22093
+ "type": "string",
22094
+ "minLength": 1
22095
+ }
22096
+ },
22097
+ "required": ["mode", "file"]
22098
+ }] },
22099
+ "install": {
22100
+ "type": "object",
22101
+ "additionalProperties": false,
22102
+ "properties": {
22103
+ "mode": {
22104
+ "type": "string",
22105
+ "enum": ["deploy", "scaffold"]
22106
+ },
22107
+ "editFiles": {
22108
+ "type": "array",
22109
+ "items": {
22110
+ "type": "string",
22111
+ "minLength": 1
22112
+ }
22113
+ },
22114
+ "reason": {
22115
+ "type": "string",
22116
+ "default": ""
22117
+ }
22118
+ },
22119
+ "required": [
22120
+ "mode",
22121
+ "editFiles",
22122
+ "reason"
22123
+ ]
22124
+ },
22125
+ "secrets": {
22126
+ "type": "array",
22127
+ "items": {
22128
+ "type": "object",
22129
+ "additionalProperties": false,
22130
+ "properties": {
22131
+ "key": {
22132
+ "type": "string",
22133
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
22134
+ },
22135
+ "required": {
22136
+ "type": "boolean",
22137
+ "default": true
22138
+ },
22139
+ "description": { "type": "string" }
22140
+ },
22141
+ "required": ["key", "required"]
21122
22142
  }
21123
22143
  },
21124
- "required": ["filename", "content_base64"]
21125
- }
21126
- },
21127
- "wait": {
21128
- "type": "boolean",
21129
- "description": "When true, wait for the first downstream SMTP delivery outcome before returning."
21130
- },
21131
- "wait_timeout_ms": {
21132
- "type": "integer",
21133
- "minimum": 1e3,
21134
- "maximum": 3e4,
21135
- "description": "Maximum time to wait for a delivery outcome when wait is true. Defaults to 30000."
22144
+ "secretGroups": {
22145
+ "type": "array",
22146
+ "items": {
22147
+ "type": "object",
22148
+ "additionalProperties": false,
22149
+ "properties": {
22150
+ "keys": {
22151
+ "type": "array",
22152
+ "minItems": 2,
22153
+ "items": {
22154
+ "type": "string",
22155
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
22156
+ }
22157
+ },
22158
+ "min": {
22159
+ "type": "integer",
22160
+ "minimum": 1,
22161
+ "default": 1
22162
+ },
22163
+ "description": { "type": "string" }
22164
+ },
22165
+ "required": ["keys", "min"]
22166
+ }
22167
+ },
22168
+ "variables": {
22169
+ "type": "array",
22170
+ "items": {
22171
+ "type": "object",
22172
+ "additionalProperties": false,
22173
+ "properties": {
22174
+ "key": {
22175
+ "type": "string",
22176
+ "minLength": 1
22177
+ },
22178
+ "prompt": {
22179
+ "type": "string",
22180
+ "minLength": 1
22181
+ },
22182
+ "default": { "type": "string" },
22183
+ "file": {
22184
+ "type": "string",
22185
+ "minLength": 1
22186
+ },
22187
+ "type": {
22188
+ "type": "string",
22189
+ "enum": [
22190
+ "string",
22191
+ "select",
22192
+ "url",
22193
+ "email"
22194
+ ],
22195
+ "default": "string"
22196
+ },
22197
+ "options": {
22198
+ "type": "array",
22199
+ "items": {
22200
+ "type": "string",
22201
+ "minLength": 1
22202
+ }
22203
+ },
22204
+ "validation": {
22205
+ "type": "object",
22206
+ "additionalProperties": false,
22207
+ "properties": {
22208
+ "pattern": {
22209
+ "type": "string",
22210
+ "minLength": 1
22211
+ },
22212
+ "maxLength": {
22213
+ "type": "integer",
22214
+ "minimum": 1
22215
+ }
22216
+ }
22217
+ }
22218
+ },
22219
+ "required": [
22220
+ "key",
22221
+ "prompt",
22222
+ "type"
22223
+ ]
22224
+ }
22225
+ },
22226
+ "setup": {
22227
+ "type": "object",
22228
+ "additionalProperties": false,
22229
+ "properties": {
22230
+ "agent": {
22231
+ "type": "string",
22232
+ "minLength": 1
22233
+ },
22234
+ "prompt": {
22235
+ "type": "string",
22236
+ "minLength": 1
22237
+ },
22238
+ "produces": {
22239
+ "type": "array",
22240
+ "items": {
22241
+ "type": "string",
22242
+ "minLength": 1
22243
+ }
22244
+ }
22245
+ },
22246
+ "required": [
22247
+ "agent",
22248
+ "prompt",
22249
+ "produces"
22250
+ ]
22251
+ },
22252
+ "postInstall": { "type": "string" }
22253
+ },
22254
+ "required": [
22255
+ "schemaVersion",
22256
+ "id",
22257
+ "title",
22258
+ "summary",
22259
+ "author",
22260
+ "tags",
22261
+ "source",
22262
+ "install",
22263
+ "secrets",
22264
+ "secretGroups",
22265
+ "variables"
22266
+ ]
22267
+ },
22268
+ "readme": { "type": ["string", "null"] },
22269
+ "status": {
22270
+ "type": "string",
22271
+ "enum": [
22272
+ "pending",
22273
+ "approved",
22274
+ "rejected"
22275
+ ]
21136
22276
  }
21137
22277
  },
21138
22278
  "required": [
21139
- "from",
21140
- "to",
21141
- "subject"
22279
+ "id",
22280
+ "slug",
22281
+ "title",
22282
+ "summary",
22283
+ "author",
22284
+ "tags",
22285
+ "verified",
22286
+ "install_count",
22287
+ "github_repo",
22288
+ "created_at",
22289
+ "updated_at",
22290
+ "description",
22291
+ "github_sha",
22292
+ "github_path",
22293
+ "manifest",
22294
+ "readme",
22295
+ "status"
21142
22296
  ]
21143
22297
  },
22298
+ "sdkName": "getTemplate",
22299
+ "summary": "Get a function template",
22300
+ "tag": "Templates",
22301
+ "tagCommand": "templates"
22302
+ },
22303
+ {
22304
+ "binaryResponse": false,
22305
+ "bodyRequired": false,
22306
+ "command": "get-template-install",
22307
+ "description": "Fetch the current state of a template install. Reads may advance the\nself-test phase when a reply effect has been observed.\n",
22308
+ "hasJsonBody": false,
22309
+ "method": "GET",
22310
+ "operationId": "getTemplateInstall",
22311
+ "path": "/templates/installs/{id}",
22312
+ "pathParams": [{
22313
+ "description": "Template install UUID.",
22314
+ "enum": null,
22315
+ "name": "id",
22316
+ "required": true,
22317
+ "type": "string"
22318
+ }],
22319
+ "queryParams": [],
22320
+ "requestSchema": null,
21144
22321
  "responseSchema": {
21145
22322
  "type": "object",
21146
22323
  "properties": {
21147
22324
  "id": {
21148
22325
  "type": "string",
21149
- "description": "Persisted sent-email attempt ID."
22326
+ "format": "uuid"
21150
22327
  },
21151
- "status": {
22328
+ "template_slug": {
21152
22329
  "type": "string",
21153
- "description": "Lifecycle status of a sent_emails row. Possible values:\n\n - `queued`: pre-call INSERT; the outbound agent has not\n yet replied.\n - `submitted_to_agent`: agent accepted; `queue_id` is set.\n - `agent_failed`: agent rejected; `error_code` and\n `error_message` carry the reason.\n - `gate_denied`: a recipient-scope gate denied the send;\n the agent was never called. The `gates` array carries\n the denial detail. /send-mail returns 403 in this case\n so callers see the denial synchronously; /sent-emails\n additionally records the row for historical lookup,\n which is when this status appears in a listing.\n - `unknown`: terminal indeterminate; the on-box log\n poller couldn't classify the receiver's response.\n - `delivered` / `bounced` / `deferred` / `wait_timeout`:\n terminal delivery outcomes (see DeliveryStatus).\n",
21154
- "enum": [
21155
- "queued",
21156
- "submitted_to_agent",
21157
- "agent_failed",
21158
- "gate_denied",
21159
- "unknown",
21160
- "delivered",
21161
- "bounced",
21162
- "deferred",
21163
- "wait_timeout"
21164
- ]
22330
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
22331
+ "description": "Template slug for this install."
21165
22332
  },
21166
- "from": {
22333
+ "state": {
21167
22334
  "type": "string",
21168
- "description": "Bare from-address actually written on the wire. Echoed\non every success branch so callers can confirm what\nwent out, particularly useful for the /emails/{id}/reply\npath where `from` is server-derived from the inbound's\nrecipient when the caller doesn't override.\n\nFor sends where the caller passed a from-header that\nincluded a display name (e.g. `\"Acme Support\" <support@acme.test>`),\nthis field is the parsed bare address (`support@acme.test`).\nThe display name was sent on the wire intact; this field\njust makes the address easy to compare against allowlists.\n"
22335
+ "enum": [
22336
+ "deploying",
22337
+ "connecting",
22338
+ "bound",
22339
+ "tested",
22340
+ "deploy_failed",
22341
+ "bind_failed",
22342
+ "test_failed"
22343
+ ]
21169
22344
  },
21170
- "queue_id": {
22345
+ "address": { "type": ["string", "null"] },
22346
+ "function_id": {
21171
22347
  "type": ["string", "null"],
21172
- "description": "Message identifier assigned by Primitive's OUTBOUND relay\n(the box that signs your mail and submits it to the\nreceiving MTA). NOT the receiver's queue id.\n\nThe receiver may also report its own queue id in\n`smtp_response_text` (e.g. `\"250 2.0.0 Ok: queued as\n99D111927CDA\"` from a Postfix receiver). Those two ids\nrefer to different mail systems and are NOT comparable.\nTreat `queue_id` as Primitive-internal and the\nreceiver's id as remote-system-internal.\n\nNull on rows that never reached the relay (queued,\ngate_denied, agent_failed before signing).\n"
22348
+ "format": "uuid"
21173
22349
  },
21174
- "accepted": {
21175
- "type": "array",
21176
- "items": { "type": "string" },
21177
- "description": "Recipient addresses accepted by the relay."
22350
+ "error": { "type": ["string", "null"] },
22351
+ "created_at": {
22352
+ "type": "string",
22353
+ "format": "date-time"
21178
22354
  },
21179
- "rejected": {
21180
- "type": "array",
21181
- "items": { "type": "string" },
21182
- "description": "Recipient addresses rejected by the relay."
22355
+ "updated_at": {
22356
+ "type": "string",
22357
+ "format": "date-time"
22358
+ }
22359
+ },
22360
+ "required": [
22361
+ "id",
22362
+ "template_slug",
22363
+ "state",
22364
+ "address",
22365
+ "function_id",
22366
+ "error",
22367
+ "created_at",
22368
+ "updated_at"
22369
+ ]
22370
+ },
22371
+ "sdkName": "getTemplateInstall",
22372
+ "summary": "Get template install status",
22373
+ "tag": "Templates",
22374
+ "tagCommand": "templates"
22375
+ },
22376
+ {
22377
+ "binaryResponse": false,
22378
+ "bodyRequired": true,
22379
+ "command": "install-template",
22380
+ "description": "Start a one-shot deploy of an approved deploy-mode Function template.\nThe response returns an install record immediately; poll\n`GET /templates/installs/{id}` for progress.\n",
22381
+ "hasJsonBody": true,
22382
+ "method": "POST",
22383
+ "operationId": "installTemplate",
22384
+ "path": "/templates/{id}/install",
22385
+ "pathParams": [{
22386
+ "description": "Template slug from the template manifest.",
22387
+ "enum": null,
22388
+ "name": "id",
22389
+ "required": true,
22390
+ "type": "string"
22391
+ }],
22392
+ "queryParams": [],
22393
+ "requestSchema": {
22394
+ "type": "object",
22395
+ "additionalProperties": false,
22396
+ "properties": {
22397
+ "address": {
22398
+ "type": "string",
22399
+ "pattern": "^[a-z0-9][a-z0-9._-]{0,63}$",
22400
+ "description": "Localpart to claim on the selected inbound domain. Defaults to the template slug."
21183
22401
  },
21184
- "client_idempotency_key": {
22402
+ "domain": {
21185
22403
  "type": "string",
21186
- "description": "Effective idempotency key used for this send."
22404
+ "minLength": 3,
22405
+ "description": "Org domain name to claim the address on. Defaults to the org's newest active domain."
21187
22406
  },
21188
- "request_id": {
22407
+ "variables": {
22408
+ "type": "object",
22409
+ "additionalProperties": { "type": "string" },
22410
+ "description": "Template variable values keyed by manifest variable key."
22411
+ },
22412
+ "secrets": {
22413
+ "type": "object",
22414
+ "additionalProperties": { "type": "string" },
22415
+ "description": "Secret values keyed by manifest secret key."
22416
+ }
22417
+ }
22418
+ },
22419
+ "responseSchema": {
22420
+ "type": "object",
22421
+ "properties": {
22422
+ "id": {
21189
22423
  "type": "string",
21190
- "description": "Server-issued request identifier for support and tracing."
22424
+ "format": "uuid"
21191
22425
  },
21192
- "content_hash": {
22426
+ "template_slug": {
21193
22427
  "type": "string",
21194
- "description": "Stable hash of the canonical send payload."
22428
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
22429
+ "description": "Template slug for this install."
21195
22430
  },
21196
- "delivery_status": {
22431
+ "state": {
21197
22432
  "type": "string",
21198
- "description": "Narrower enum covering only the four terminal delivery\noutcomes returned to a synchronous `wait: true` send.\n\nOn the SendMailResult shape, `delivery_status` is always\nequal to `status` whenever both are present (i.e. on\nterminal-state replays and live wait=true responses).\nThe two fields exist so callers that want to type-narrow\non \"this is a delivery outcome\" can pattern-match against\nthe four-value enum without handling the broader\nSentEmailStatus value set (which also covers `queued`,\n`submitted_to_agent`, `agent_failed`, `gate_denied`,\n`unknown`).\n\nOn async-mode and pre-terminal responses, `delivery_status`\nis absent and only `status` is populated. Use `status` if\nyou want a single field that's always present.\n",
21199
22433
  "enum": [
21200
- "delivered",
21201
- "bounced",
21202
- "deferred",
21203
- "wait_timeout"
22434
+ "deploying",
22435
+ "connecting",
22436
+ "bound",
22437
+ "tested",
22438
+ "deploy_failed",
22439
+ "bind_failed",
22440
+ "test_failed"
21204
22441
  ]
21205
22442
  },
21206
- "smtp_response_code": {
21207
- "type": ["integer", "null"],
21208
- "description": "SMTP response code from the first downstream delivery outcome when wait is true."
22443
+ "address": { "type": ["string", "null"] },
22444
+ "function_id": {
22445
+ "type": ["string", "null"],
22446
+ "format": "uuid"
21209
22447
  },
21210
- "smtp_response_text": {
22448
+ "error": { "type": ["string", "null"] },
22449
+ "created_at": {
21211
22450
  "type": "string",
21212
- "description": "SMTP response text from the first downstream delivery outcome when wait is true."
22451
+ "format": "date-time"
21213
22452
  },
21214
- "idempotent_replay": {
21215
- "type": "boolean",
21216
- "description": "True when the response replays a previously-recorded send\nkeyed by `client_idempotency_key` (same key, same canonical\npayload). False on a fresh send and on gate-denied\nresponses. Lets callers branch on cache state without\ndiffing fields.\n"
22453
+ "updated_at": {
22454
+ "type": "string",
22455
+ "format": "date-time"
21217
22456
  }
21218
22457
  },
21219
22458
  "required": [
21220
22459
  "id",
21221
- "status",
21222
- "from",
21223
- "queue_id",
21224
- "accepted",
21225
- "rejected",
21226
- "client_idempotency_key",
21227
- "request_id",
21228
- "content_hash",
21229
- "idempotent_replay"
22460
+ "template_slug",
22461
+ "state",
22462
+ "address",
22463
+ "function_id",
22464
+ "error",
22465
+ "created_at",
22466
+ "updated_at"
21230
22467
  ]
21231
22468
  },
21232
- "sdkName": "sendEmail",
21233
- "summary": "Send outbound email",
21234
- "tag": "Sending",
21235
- "tagCommand": "sending"
22469
+ "sdkName": "installTemplate",
22470
+ "summary": "Install a function template",
22471
+ "tag": "Templates",
22472
+ "tagCommand": "templates"
22473
+ },
22474
+ {
22475
+ "binaryResponse": false,
22476
+ "bodyRequired": false,
22477
+ "command": "list-templates",
22478
+ "description": "List approved Function templates available for browsing and\ninstallation. Results are cacheable and paginated with\n`data.next_cursor`.\n",
22479
+ "hasJsonBody": false,
22480
+ "method": "GET",
22481
+ "operationId": "listTemplates",
22482
+ "path": "/templates",
22483
+ "pathParams": [],
22484
+ "queryParams": [
22485
+ {
22486
+ "description": "Search templates by title, summary, or slug.",
22487
+ "enum": null,
22488
+ "name": "q",
22489
+ "required": false,
22490
+ "type": "string"
22491
+ },
22492
+ {
22493
+ "description": "Filter templates by an exact tag.",
22494
+ "enum": null,
22495
+ "name": "tag",
22496
+ "required": false,
22497
+ "type": "string"
22498
+ },
22499
+ {
22500
+ "description": "Cursor from a previous response `data.next_cursor` value.",
22501
+ "enum": null,
22502
+ "name": "cursor",
22503
+ "required": false,
22504
+ "type": "string"
22505
+ },
22506
+ {
22507
+ "default": 50,
22508
+ "description": "Maximum number of templates to return. The server caps this at 100.",
22509
+ "enum": null,
22510
+ "maximum": 100,
22511
+ "minimum": 1,
22512
+ "name": "limit",
22513
+ "required": false,
22514
+ "type": "integer"
22515
+ }
22516
+ ],
22517
+ "requestSchema": null,
22518
+ "responseSchema": {
22519
+ "type": "object",
22520
+ "properties": {
22521
+ "items": {
22522
+ "type": "array",
22523
+ "items": {
22524
+ "type": "object",
22525
+ "properties": {
22526
+ "id": {
22527
+ "type": "string",
22528
+ "format": "uuid"
22529
+ },
22530
+ "slug": {
22531
+ "type": "string",
22532
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
22533
+ "description": "Stable template slug used in template URLs and install commands."
22534
+ },
22535
+ "title": { "type": "string" },
22536
+ "summary": { "type": "string" },
22537
+ "author": {
22538
+ "type": "object",
22539
+ "additionalProperties": false,
22540
+ "properties": {
22541
+ "id": {
22542
+ "type": "string",
22543
+ "minLength": 1
22544
+ },
22545
+ "name": {
22546
+ "type": "string",
22547
+ "minLength": 1
22548
+ },
22549
+ "url": {
22550
+ "type": "string",
22551
+ "format": "uri"
22552
+ }
22553
+ },
22554
+ "required": ["id", "name"]
22555
+ },
22556
+ "tags": {
22557
+ "type": "array",
22558
+ "items": { "type": "string" }
22559
+ },
22560
+ "verified": { "type": "boolean" },
22561
+ "install_count": {
22562
+ "type": "integer",
22563
+ "minimum": 0
22564
+ },
22565
+ "github_repo": {
22566
+ "type": "string",
22567
+ "pattern": "^[A-Za-z0-9-]+/[A-Za-z0-9_.-]+$",
22568
+ "description": "GitHub repository in owner/repo form."
22569
+ },
22570
+ "created_at": {
22571
+ "type": "string",
22572
+ "format": "date-time"
22573
+ },
22574
+ "updated_at": {
22575
+ "type": "string",
22576
+ "format": "date-time"
22577
+ }
22578
+ },
22579
+ "required": [
22580
+ "id",
22581
+ "slug",
22582
+ "title",
22583
+ "summary",
22584
+ "author",
22585
+ "tags",
22586
+ "verified",
22587
+ "install_count",
22588
+ "github_repo",
22589
+ "created_at",
22590
+ "updated_at"
22591
+ ]
22592
+ }
22593
+ },
22594
+ "next_cursor": {
22595
+ "type": ["string", "null"],
22596
+ "description": "Cursor to pass as the next `cursor` query value, or null when there are no more templates."
22597
+ }
22598
+ },
22599
+ "required": ["items", "next_cursor"]
22600
+ },
22601
+ "sdkName": "listTemplates",
22602
+ "summary": "List function templates",
22603
+ "tag": "Templates",
22604
+ "tagCommand": "templates"
21236
22605
  },
21237
22606
  {
21238
22607
  "binaryResponse": false,
@@ -26567,8 +27936,8 @@ const PRIMITIVE_TEAM_AUTHOR = {
26567
27936
  name: "Primitive Team",
26568
27937
  url: "https://primitive.dev"
26569
27938
  };
26570
- const SDK_VERSION_RANGE = "^1.19.0";
26571
- const CLI_VERSION_RANGE = "^1.19.0";
27939
+ const SDK_VERSION_RANGE = "^1.20.0";
27940
+ const CLI_VERSION_RANGE = "^1.20.0";
26572
27941
  const ESBUILD_VERSION_RANGE = "^0.27.0";
26573
27942
  function renderHandler() {
26574
27943
  return `// env.PRIMITIVE_API_KEY, env.PRIMITIVE_WEBHOOK_SECRET, and