@graph8/sdk 0.13.1 → 0.15.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/react.mjs CHANGED
@@ -841,6 +841,8 @@ var KNOWN_WEBHOOK_EVENTS = [
841
841
  "engagement.email_bounced",
842
842
  "engagement.email_skipped",
843
843
  "engagement.call_dispatched",
844
+ "engagement.call_connected",
845
+ "engagement.call_graded",
844
846
  "engagement.sms_sent",
845
847
  "engagement.sms_replied",
846
848
  "engagement.whatsapp_sent",
@@ -851,7 +853,12 @@ var KNOWN_WEBHOOK_EVENTS = [
851
853
  "engagement.linkedin_connection_accepted",
852
854
  "meeting.booked",
853
855
  "meeting.cancelled",
854
- "meeting.rescheduled"
856
+ "meeting.rescheduled",
857
+ "deal.won",
858
+ "crm.record.created",
859
+ "crm.record.updated",
860
+ "crm.record.archived",
861
+ "crm.record.restored"
855
862
  ];
856
863
  var WebhookSignatureError = class extends Error {
857
864
  constructor(message) {
@@ -1211,10 +1218,282 @@ var createAppsClient = (apiKey, apiUrl) => {
1211
1218
  };
1212
1219
  };
1213
1220
 
1214
- // src/fields.ts
1221
+ // src/appPlatform.ts
1215
1222
  var DEFAULT_API18 = "https://be.graph8.com";
1216
- var createFieldsClient = (apiKey, apiUrl) => {
1223
+ var createAppPlatformClient = (apiKey, apiUrl) => {
1217
1224
  const baseUrl = apiUrl || DEFAULT_API18;
1225
+ const unwrap = (resp) => resp.data ?? resp;
1226
+ return {
1227
+ // ---- source binding -------------------------------------------------
1228
+ /**
1229
+ * Bind the repository an app builds from.
1230
+ *
1231
+ * `repo_url` must be fetchable -- `https://`, `ssh://` or `git@`, with no
1232
+ * whitespace. A `file://` or bare path is refused with 422, because a build
1233
+ * that can read the builder's filesystem is a build that can read ours.
1234
+ *
1235
+ * `credential_ref` is a POINTER into your secret manager, not a token.
1236
+ */
1237
+ async setSource(appId, params) {
1238
+ const resp = await request(
1239
+ baseUrl,
1240
+ `/api/v1/apps/${appId}/source`,
1241
+ apiKey,
1242
+ {
1243
+ method: "PUT",
1244
+ body: {
1245
+ repo_url: params.repo_url,
1246
+ provider: params.provider,
1247
+ default_branch: params.default_branch ?? null,
1248
+ credential_ref: params.credential_ref ?? null
1249
+ }
1250
+ }
1251
+ );
1252
+ return unwrap(resp);
1253
+ },
1254
+ /** Unbind the source. Returns the full app with every source field null. */
1255
+ async clearSource(appId) {
1256
+ const resp = await request(
1257
+ baseUrl,
1258
+ `/api/v1/apps/${appId}/source`,
1259
+ apiKey,
1260
+ { method: "DELETE" }
1261
+ );
1262
+ return unwrap(resp);
1263
+ },
1264
+ // ---- deployments ----------------------------------------------------
1265
+ /** Every deployment for this app, newest first. Never 404s for an app with none. */
1266
+ async listDeployments(appId) {
1267
+ return request(baseUrl, `/api/v1/apps/${appId}/deployments`, apiKey);
1268
+ },
1269
+ /**
1270
+ * Queue a deployment. Returns `201` with `status: "queued"` -- nothing builds
1271
+ * as a side effect of this call; the build controller picks it up.
1272
+ *
1273
+ * NOT idempotent: two identical calls create two deployments.
1274
+ */
1275
+ async deploy(appId, params) {
1276
+ const body = { source_ref: params.source_ref };
1277
+ if (params.schema_version_id) body.schema_version_id = params.schema_version_id;
1278
+ const resp = await request(
1279
+ baseUrl,
1280
+ `/api/v1/apps/${appId}/deployments`,
1281
+ apiKey,
1282
+ { method: "POST", body }
1283
+ );
1284
+ return unwrap(resp);
1285
+ },
1286
+ /** Fetch one deployment. The polling endpoint for a build loop. */
1287
+ async getDeployment(appId, deploymentId) {
1288
+ const resp = await request(
1289
+ baseUrl,
1290
+ `/api/v1/apps/${appId}/deployments/${deploymentId}`,
1291
+ apiKey
1292
+ );
1293
+ return unwrap(resp);
1294
+ },
1295
+ /**
1296
+ * The deployment currently serving traffic, or `null`.
1297
+ *
1298
+ * `null` is a real answer with a 200, not a 404: "this app has never shipped"
1299
+ * is information, while a 404 would read as "no such app".
1300
+ */
1301
+ async activeDeployment(appId) {
1302
+ const resp = await request(
1303
+ baseUrl,
1304
+ `/api/v1/apps/${appId}/deployments/active`,
1305
+ apiKey
1306
+ );
1307
+ return resp.data ?? null;
1308
+ },
1309
+ /**
1310
+ * Promote a built deployment to serve traffic. Anything it displaces moves to
1311
+ * `rolled_back` in the same transaction, so there is never a moment with two
1312
+ * live deployments.
1313
+ *
1314
+ * `409` when the state machine forbids it -- a deployment cannot become
1315
+ * `deployed` without having been built, and a `failed` one cannot be revived.
1316
+ * A retry is a new deployment, not a resurrection.
1317
+ */
1318
+ async promote(appId, deploymentId, imageDigest) {
1319
+ const resp = await request(
1320
+ baseUrl,
1321
+ `/api/v1/apps/${appId}/deployments/${deploymentId}/promote`,
1322
+ apiKey,
1323
+ { method: "POST", body: { image_digest: imageDigest } }
1324
+ );
1325
+ return unwrap(resp);
1326
+ },
1327
+ /** Roll back a deployment that is currently serving. Only a `deployed` one may be. */
1328
+ async rollback(appId, deploymentId) {
1329
+ const resp = await request(
1330
+ baseUrl,
1331
+ `/api/v1/apps/${appId}/deployments/${deploymentId}/rollback`,
1332
+ apiKey,
1333
+ { method: "POST", body: {} }
1334
+ );
1335
+ return unwrap(resp);
1336
+ },
1337
+ // ---- logs -----------------------------------------------------------
1338
+ /**
1339
+ * Why a build failed. Returns every step of the build pod in the order
1340
+ * Kubernetes runs them; a step that has not started yet is omitted rather
1341
+ * than returned empty.
1342
+ *
1343
+ * An empty `containers` list is not an error -- build pods are reaped an hour
1344
+ * after they finish, so logs for an older deployment are genuinely gone.
1345
+ * `last_error_sanitized` on the deployment is what survives.
1346
+ *
1347
+ * `503` means graph8 could not reach the cluster, which is deliberately
1348
+ * different from an empty `200`: one means we could not look, the other means
1349
+ * your build produced no output.
1350
+ */
1351
+ async deploymentLogs(appId, deploymentId, tailLines) {
1352
+ const resp = await request(
1353
+ baseUrl,
1354
+ `/api/v1/apps/${appId}/deployments/${deploymentId}/logs`,
1355
+ apiKey,
1356
+ { query: tailLines === void 0 ? void 0 : { tail_lines: tailLines } }
1357
+ );
1358
+ return unwrap(resp);
1359
+ },
1360
+ /**
1361
+ * What the running app is printing. The app's own pods only -- the per-app
1362
+ * egress proxy shares the namespace and is deliberately excluded.
1363
+ *
1364
+ * Empty until a deployment reaches `deployed`.
1365
+ */
1366
+ async logs(appId, tailLines) {
1367
+ const resp = await request(
1368
+ baseUrl,
1369
+ `/api/v1/apps/${appId}/logs`,
1370
+ apiKey,
1371
+ { query: tailLines === void 0 ? void 0 : { tail_lines: tailLines } }
1372
+ );
1373
+ return unwrap(resp);
1374
+ },
1375
+ // ---- domains --------------------------------------------------------
1376
+ /** Every hostname claimed for this app, whatever its verification state. */
1377
+ async listDomains(appId) {
1378
+ return request(baseUrl, `/api/v1/apps/${appId}/domains`, apiKey);
1379
+ },
1380
+ /**
1381
+ * Claim a hostname and get the TXT record that proves you own it.
1382
+ *
1383
+ * Returns `201`, and the domain is NESTED at `data.domain` -- this is the one
1384
+ * route on the surface whose payload is not the record itself. Hostnames are
1385
+ * globally unique, so a host another app holds is refused.
1386
+ */
1387
+ async claimDomain(appId, hostname) {
1388
+ const resp = await request(
1389
+ baseUrl,
1390
+ `/api/v1/apps/${appId}/domains`,
1391
+ apiKey,
1392
+ { method: "POST", body: { hostname } }
1393
+ );
1394
+ return unwrap(resp);
1395
+ },
1396
+ /**
1397
+ * Check DNS for the TXT record and advance the domain to `verified`.
1398
+ *
1399
+ * Idempotent: verifying an already-verified domain re-checks and stays
1400
+ * verified, so it is safe to re-run after a DNS change. Send no body -- the
1401
+ * record in DNS is the payload.
1402
+ */
1403
+ async verifyDomain(appId, hostname) {
1404
+ const resp = await request(
1405
+ baseUrl,
1406
+ `/api/v1/apps/${appId}/domains/${encodeURIComponent(hostname)}/verify`,
1407
+ apiKey,
1408
+ { method: "POST", body: {} }
1409
+ );
1410
+ return unwrap(resp);
1411
+ },
1412
+ /**
1413
+ * Release a claimed hostname.
1414
+ *
1415
+ * A HARD delete. Hostnames are globally unique, so a row left behind in any
1416
+ * status keeps the host burned for every other builder. Releasing one you
1417
+ * already released is a `404`, because after the first call the claim
1418
+ * genuinely does not exist.
1419
+ *
1420
+ * Returns the NORMALIZED hostname, which may differ from what you passed.
1421
+ */
1422
+ async releaseDomain(appId, hostname) {
1423
+ const resp = await request(
1424
+ baseUrl,
1425
+ `/api/v1/apps/${appId}/domains/${encodeURIComponent(hostname)}`,
1426
+ apiKey,
1427
+ { method: "DELETE" }
1428
+ );
1429
+ return unwrap(resp);
1430
+ },
1431
+ // ---- secrets --------------------------------------------------------
1432
+ /**
1433
+ * Which secrets this app declares, and when each was last rotated.
1434
+ *
1435
+ * NEVER returns a value. graph8 stores a POINTER into your secret manager and
1436
+ * has no column for the secret itself.
1437
+ */
1438
+ async listSecrets(appId) {
1439
+ return request(baseUrl, `/api/v1/apps/${appId}/secrets`, apiKey);
1440
+ },
1441
+ /**
1442
+ * Declare a secret, or rotate the pointer to it.
1443
+ *
1444
+ * `providerRef` is a REFERENCE, and the server rejects anything that looks
1445
+ * like a credential -- a value starting `bearer `, `sk-`, `ghp_`, `xox` and
1446
+ * friends is a 422. That refusal is the feature: it catches the mistake of
1447
+ * pasting the secret where its address belongs.
1448
+ */
1449
+ async putSecret(appId, secretKey, providerRef) {
1450
+ const resp = await request(
1451
+ baseUrl,
1452
+ `/api/v1/apps/${appId}/secrets/${encodeURIComponent(secretKey)}`,
1453
+ apiKey,
1454
+ { method: "PUT", body: { provider_ref: providerRef ?? null } }
1455
+ );
1456
+ return unwrap(resp);
1457
+ },
1458
+ /** Undeclare a secret. A key the app never declared is a 404, so a typo is
1459
+ * never reported as a successful removal. */
1460
+ async deleteSecret(appId, secretKey) {
1461
+ const resp = await request(
1462
+ baseUrl,
1463
+ `/api/v1/apps/${appId}/secrets/${encodeURIComponent(secretKey)}`,
1464
+ apiKey,
1465
+ { method: "DELETE" }
1466
+ );
1467
+ return unwrap(resp);
1468
+ },
1469
+ // ---- schema versions ------------------------------------------------
1470
+ /**
1471
+ * Publish a custom-object schema version. Returns `201`.
1472
+ *
1473
+ * Takes only the `objects` list, not a whole `graph8.app.yaml`: the rest of
1474
+ * that file is app metadata the control plane already holds, and accepting it
1475
+ * here would create a second place for it to disagree.
1476
+ */
1477
+ async publishSchemaVersion(appId, objects) {
1478
+ const resp = await request(
1479
+ baseUrl,
1480
+ `/api/v1/apps/${appId}/schema-versions`,
1481
+ apiKey,
1482
+ { method: "POST", body: { objects } }
1483
+ );
1484
+ return unwrap(resp);
1485
+ },
1486
+ /** Every schema version this app has published. Empty array, never 404. */
1487
+ async listSchemaVersions(appId) {
1488
+ return request(baseUrl, `/api/v1/apps/${appId}/schema-versions`, apiKey);
1489
+ }
1490
+ };
1491
+ };
1492
+
1493
+ // src/fields.ts
1494
+ var DEFAULT_API19 = "https://be.graph8.com";
1495
+ var createFieldsClient = (apiKey, apiUrl) => {
1496
+ const baseUrl = apiUrl || DEFAULT_API19;
1218
1497
  return {
1219
1498
  /** List contact fields (base + custom). Pass listId to include list-specific custom fields. */
1220
1499
  async listContactFields(listId) {
@@ -1256,14 +1535,38 @@ var createFieldsClient = (apiKey, apiUrl) => {
1256
1535
  };
1257
1536
 
1258
1537
  // src/objects.ts
1259
- var DEFAULT_API19 = "https://be.graph8.com";
1538
+ var DEFAULT_API20 = "https://be.graph8.com";
1260
1539
  var createObjectsClient = (apiKey, apiUrl) => {
1261
- const baseUrl = apiUrl || DEFAULT_API19;
1540
+ const baseUrl = apiUrl || DEFAULT_API20;
1262
1541
  const encode = (value) => encodeURIComponent(value);
1263
1542
  return {
1264
1543
  /** List the custom object types in your workspace. */
1265
- async list() {
1266
- return request(baseUrl, "/api/v1/objects", apiKey);
1544
+ async list(params = {}) {
1545
+ const query = params.include_archived ? "?include_archived=true" : "";
1546
+ return request(baseUrl, `/api/v1/objects${query}`, apiKey);
1547
+ },
1548
+ /** Create a native custom object. Requires objects:manage and Admin access. */
1549
+ async create(input) {
1550
+ const resp = await request(baseUrl, "/api/v1/objects", apiKey, {
1551
+ method: "POST",
1552
+ body: input
1553
+ });
1554
+ return resp.data;
1555
+ },
1556
+ /** Rename, archive or restore an object while preserving its slug and data. */
1557
+ async update(objectSlug, input) {
1558
+ const resp = await request(baseUrl, `/api/v1/objects/${encode(objectSlug)}`, apiKey, {
1559
+ method: "PATCH",
1560
+ body: input
1561
+ });
1562
+ return resp.data;
1563
+ },
1564
+ /** Archive the object without deleting records; restore with update({ is_archived: false }). */
1565
+ async archive(objectSlug) {
1566
+ const resp = await request(baseUrl, `/api/v1/objects/${encode(objectSlug)}`, apiKey, {
1567
+ method: "DELETE"
1568
+ });
1569
+ return resp.data;
1267
1570
  },
1268
1571
  /** Fetch one object type by slug. */
1269
1572
  async get(objectSlug) {
@@ -1275,10 +1578,35 @@ var createObjectsClient = (apiKey, apiUrl) => {
1275
1578
  return resp.data ?? resp;
1276
1579
  },
1277
1580
  /** The object's attributes — the schema its records must satisfy. */
1278
- async listAttributes(objectSlug) {
1279
- return request(baseUrl, `/api/v1/objects/${encode(objectSlug)}/attributes`, apiKey);
1581
+ async listAttributes(objectSlug, params = {}) {
1582
+ const query = params.include_archived ? "?include_archived=true" : "";
1583
+ return request(baseUrl, `/api/v1/objects/${encode(objectSlug)}/attributes${query}`, apiKey);
1584
+ },
1585
+ /** Create a field using the same schema rules as the customer UI. */
1586
+ async createAttribute(objectSlug, input) {
1587
+ const resp = await request(baseUrl, `/api/v1/objects/${encode(objectSlug)}/attributes`, apiKey, {
1588
+ method: "POST",
1589
+ body: input
1590
+ });
1591
+ return resp.data;
1280
1592
  },
1281
- /** Paginated records with their current values. Archived records are excluded. */
1593
+ /** Edit or restore a field; its type and slug are immutable. */
1594
+ async updateAttribute(objectSlug, attributeSlug, input) {
1595
+ const resp = await request(baseUrl, `/api/v1/objects/${encode(objectSlug)}/attributes/${encode(attributeSlug)}`, apiKey, {
1596
+ method: "PATCH",
1597
+ body: input
1598
+ });
1599
+ return resp.data;
1600
+ },
1601
+ /** Archive without deleting values; restore with updateAttribute({ is_archived: false }). */
1602
+ async archiveAttribute(objectSlug, attributeSlug) {
1603
+ const resp = await request(baseUrl, `/api/v1/objects/${encode(objectSlug)}/attributes/${encode(attributeSlug)}`, apiKey, {
1604
+ method: "DELETE"
1605
+ });
1606
+ return resp.data;
1607
+ },
1608
+ /** Paginated custom records or canonical deals with current values and revisions.
1609
+ * Deal totals and related references respect current record access. */
1282
1610
  async listRecords(objectSlug, params = {}) {
1283
1611
  const query = {};
1284
1612
  if (params.page != null) query.page = params.page;
@@ -1302,7 +1630,24 @@ var createObjectsClient = (apiKey, apiUrl) => {
1302
1630
  );
1303
1631
  return resp.data ?? resp;
1304
1632
  },
1305
- /** Fetch one record with its currently active values. */
1633
+ /** Match a unique single-value key, creating or updating while preserving omitted fields. */
1634
+ async upsertRecord(objectSlug, matchingAttribute, values, options = {}) {
1635
+ const resp = await request(
1636
+ baseUrl,
1637
+ `/api/v1/objects/${encode(objectSlug)}/records/upsert`,
1638
+ apiKey,
1639
+ { method: "POST", body: {
1640
+ matching_attribute: matchingAttribute,
1641
+ values,
1642
+ ...options.expectedRevision !== void 0 ? { expected_revision: options.expectedRevision } : {}
1643
+ } }
1644
+ );
1645
+ return resp.data;
1646
+ },
1647
+ /** Fetch one custom record, canonical contact/company, or deal by its stable graph8 ID.
1648
+ * Deals retain their UUIDs and expose company, primary-contact and contact_ids references only
1649
+ * when permitted. Generic deal mutations are not yet supported.
1650
+ */
1306
1651
  async getRecord(objectSlug, recordId) {
1307
1652
  const resp = await request(
1308
1653
  baseUrl,
@@ -1316,15 +1661,24 @@ var createObjectsClient = (apiKey, apiUrl) => {
1316
1661
  * required attributes you omit are left alone rather than reported missing.
1317
1662
  * Sending an explicit `null` CLEARS that attribute.
1318
1663
  *
1319
- * Values are versioned rather than overwritten, so the previous value stays
1320
- * readable through `history`.
1664
+ * Custom values retain generations through `history`. Canonical contacts and
1665
+ * companies require expectedRevision from a fresh read and expose recorded
1666
+ * mutations through `changes`. They do not yet support appendValues/removeValues.
1321
1667
  */
1322
1668
  async updateRecord(objectSlug, recordId, values, options) {
1323
1669
  const resp = await request(
1324
1670
  baseUrl,
1325
1671
  `/api/v1/objects/${encode(objectSlug)}/records/${encode(recordId)}`,
1326
1672
  apiKey,
1327
- { method: "PATCH", body: { values, ...options?.expectedRevision === void 0 ? {} : { expected_revision: options.expectedRevision } } }
1673
+ {
1674
+ method: "PATCH",
1675
+ body: {
1676
+ values,
1677
+ ...options?.expectedRevision === void 0 ? {} : { expected_revision: options.expectedRevision },
1678
+ ...options?.appendValues === void 0 ? {} : { append_values: options.appendValues },
1679
+ ...options?.removeValues === void 0 ? {} : { remove_values: options.removeValues }
1680
+ }
1681
+ }
1328
1682
  );
1329
1683
  return resp.data ?? resp;
1330
1684
  },
@@ -1363,14 +1717,27 @@ var createObjectsClient = (apiKey, apiUrl) => {
1363
1717
  { query: limit != null ? { limit } : void 0 }
1364
1718
  );
1365
1719
  return resp.data ?? resp;
1720
+ },
1721
+ /** Recorded custom-record or canonical contact/company mutations. Pass next_cursor to continue.
1722
+ * Canonical history respects current access/privacy; archived records and older
1723
+ * unrecorded writes are not reconstructed. Store unavailability returns 503.
1724
+ */
1725
+ async changes(objectSlug, recordId, options = {}) {
1726
+ const resp = await request(
1727
+ baseUrl,
1728
+ `/api/v1/objects/${encode(objectSlug)}/records/${encode(recordId)}/changes`,
1729
+ apiKey,
1730
+ { query: options }
1731
+ );
1732
+ return resp.data ?? resp;
1366
1733
  }
1367
1734
  };
1368
1735
  };
1369
1736
 
1370
1737
  // src/deals.ts
1371
- var DEFAULT_API20 = "https://be.graph8.com";
1738
+ var DEFAULT_API21 = "https://be.graph8.com";
1372
1739
  var createDealsClient = (apiKey, apiUrl) => {
1373
- const baseUrl = apiUrl || DEFAULT_API20;
1740
+ const baseUrl = apiUrl || DEFAULT_API21;
1374
1741
  return {
1375
1742
  /** List all deal pipelines and their stages. */
1376
1743
  async pipelines() {
@@ -1414,9 +1781,9 @@ var createDealsClient = (apiKey, apiUrl) => {
1414
1781
  };
1415
1782
 
1416
1783
  // src/inbox.ts
1417
- var DEFAULT_API21 = "https://be.graph8.com";
1784
+ var DEFAULT_API22 = "https://be.graph8.com";
1418
1785
  var createInboxClient = (apiKey, apiUrl) => {
1419
- const baseUrl = apiUrl || DEFAULT_API21;
1786
+ const baseUrl = apiUrl || DEFAULT_API22;
1420
1787
  return {
1421
1788
  /** List inbox threads across email, SMS, and LinkedIn. */
1422
1789
  async list(params = {}) {
@@ -1469,9 +1836,9 @@ var createInboxClient = (apiKey, apiUrl) => {
1469
1836
  };
1470
1837
 
1471
1838
  // src/quotes.ts
1472
- var DEFAULT_API22 = "https://be.graph8.com";
1839
+ var DEFAULT_API23 = "https://be.graph8.com";
1473
1840
  var createQuotesClient = (apiKey, apiUrl) => {
1474
- const baseUrl = apiUrl || DEFAULT_API22;
1841
+ const baseUrl = apiUrl || DEFAULT_API23;
1475
1842
  return {
1476
1843
  /** List quotes org-wide with optional filters and pagination. */
1477
1844
  async list(params = {}) {
@@ -1543,9 +1910,9 @@ var createQuotesClient = (apiKey, apiUrl) => {
1543
1910
  };
1544
1911
 
1545
1912
  // src/pipelines.ts
1546
- var DEFAULT_API23 = "https://be.graph8.com";
1913
+ var DEFAULT_API24 = "https://be.graph8.com";
1547
1914
  var createPipelinesClient = (apiKey, apiUrl) => {
1548
- const baseUrl = apiUrl || DEFAULT_API23;
1915
+ const baseUrl = apiUrl || DEFAULT_API24;
1549
1916
  return {
1550
1917
  /** List all stage-checklist pipelines with stages, evidence, scripts. */
1551
1918
  async list() {
@@ -1627,9 +1994,9 @@ var createPipelinesClient = (apiKey, apiUrl) => {
1627
1994
  };
1628
1995
 
1629
1996
  // src/workflows.ts
1630
- var DEFAULT_API24 = "https://be.graph8.com";
1997
+ var DEFAULT_API25 = "https://be.graph8.com";
1631
1998
  var createWorkflowsClient = (apiKey, apiUrl) => {
1632
- const baseUrl = apiUrl || DEFAULT_API24;
1999
+ const baseUrl = apiUrl || DEFAULT_API25;
1633
2000
  return {
1634
2001
  /** List workflows org-wide. */
1635
2002
  async list(params = {}) {
@@ -1745,9 +2112,9 @@ var createWorkflowsClient = (apiKey, apiUrl) => {
1745
2112
  };
1746
2113
 
1747
2114
  // src/skills.ts
1748
- var DEFAULT_API25 = "https://be.graph8.com";
2115
+ var DEFAULT_API26 = "https://be.graph8.com";
1749
2116
  var createSkillsClient = (apiKey, apiUrl) => {
1750
- const baseUrl = apiUrl || DEFAULT_API25;
2117
+ const baseUrl = apiUrl || DEFAULT_API26;
1751
2118
  return {
1752
2119
  /** List skills. */
1753
2120
  async list(params = {}) {
@@ -1834,9 +2201,9 @@ var createSkillsClient = (apiKey, apiUrl) => {
1834
2201
  };
1835
2202
 
1836
2203
  // src/intent.ts
1837
- var DEFAULT_API26 = "https://be.graph8.com";
2204
+ var DEFAULT_API27 = "https://be.graph8.com";
1838
2205
  var createIntentClient = (apiKey, apiUrl) => {
1839
- const baseUrl = apiUrl || DEFAULT_API26;
2206
+ const baseUrl = apiUrl || DEFAULT_API27;
1840
2207
  const get = (path) => request(baseUrl, `/api/v1${path}`, apiKey);
1841
2208
  const post = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "POST", body });
1842
2209
  const del = (path) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "DELETE" });
@@ -1911,9 +2278,9 @@ var createIntentClient = (apiKey, apiUrl) => {
1911
2278
  };
1912
2279
 
1913
2280
  // src/studio.ts
1914
- var DEFAULT_API27 = "https://be.graph8.com";
2281
+ var DEFAULT_API28 = "https://be.graph8.com";
1915
2282
  var createStudioClient = (apiKey, apiUrl) => {
1916
- const baseUrl = apiUrl || DEFAULT_API27;
2283
+ const baseUrl = apiUrl || DEFAULT_API28;
1917
2284
  const get = (path, params = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { query: params });
1918
2285
  const post = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "POST", body });
1919
2286
  const patch = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "PATCH", body });
@@ -1968,9 +2335,9 @@ var createStudioClient = (apiKey, apiUrl) => {
1968
2335
  };
1969
2336
 
1970
2337
  // src/meetings.ts
1971
- var DEFAULT_API28 = "https://be.graph8.com";
2338
+ var DEFAULT_API29 = "https://be.graph8.com";
1972
2339
  var createMeetingsClient = (apiKey, apiUrl) => {
1973
- const baseUrl = apiUrl || DEFAULT_API28;
2340
+ const baseUrl = apiUrl || DEFAULT_API29;
1974
2341
  return {
1975
2342
  /** List meetings with optional filters. Returns summary rows without transcript / analysis. */
1976
2343
  async list(params = {}) {
@@ -1985,9 +2352,9 @@ var createMeetingsClient = (apiKey, apiUrl) => {
1985
2352
  };
1986
2353
 
1987
2354
  // src/audiences.ts
1988
- var DEFAULT_API29 = "https://be.graph8.com";
2355
+ var DEFAULT_API30 = "https://be.graph8.com";
1989
2356
  var createAudiencesClient = (apiKey, apiUrl) => {
1990
- const baseUrl = apiUrl || DEFAULT_API29;
2357
+ const baseUrl = apiUrl || DEFAULT_API30;
1991
2358
  const base = "/api/v1/audience-syncs";
1992
2359
  return {
1993
2360
  /** List all audience syncs for the organization. */
@@ -2035,9 +2402,9 @@ var createAudiencesClient = (apiKey, apiUrl) => {
2035
2402
  };
2036
2403
 
2037
2404
  // src/search.ts
2038
- var DEFAULT_API30 = "https://be.graph8.com";
2405
+ var DEFAULT_API31 = "https://be.graph8.com";
2039
2406
  var createSearchClient = (apiKey, apiUrl) => {
2040
- const baseUrl = apiUrl || DEFAULT_API30;
2407
+ const baseUrl = apiUrl || DEFAULT_API31;
2041
2408
  const body = (p) => ({ filters: [], page: 1, limit: 25, ...p });
2042
2409
  return {
2043
2410
  /** Search open-data contacts by filter. */
@@ -2068,9 +2435,9 @@ var createSearchClient = (apiKey, apiUrl) => {
2068
2435
  };
2069
2436
 
2070
2437
  // src/agency.ts
2071
- var DEFAULT_API31 = "https://be.graph8.com";
2438
+ var DEFAULT_API32 = "https://be.graph8.com";
2072
2439
  var createAgencyClient = (apiKey, apiUrl) => {
2073
- const baseUrl = apiUrl || DEFAULT_API31;
2440
+ const baseUrl = apiUrl || DEFAULT_API32;
2074
2441
  return {
2075
2442
  /** Describe the agency credential: agency org + authorized client count. */
2076
2443
  async me() {
@@ -2085,9 +2452,9 @@ var createAgencyClient = (apiKey, apiUrl) => {
2085
2452
  };
2086
2453
 
2087
2454
  // src/marketplace.ts
2088
- var DEFAULT_API32 = "https://be.graph8.com";
2455
+ var DEFAULT_API33 = "https://be.graph8.com";
2089
2456
  var createMarketplaceClient = (apiKey, apiUrl) => {
2090
- const baseUrl = apiUrl || DEFAULT_API32;
2457
+ const baseUrl = apiUrl || DEFAULT_API33;
2091
2458
  const base = "/api/v1/marketplace";
2092
2459
  return {
2093
2460
  /** Your own marketplace SDR profile. */
@@ -2137,9 +2504,9 @@ var createMarketplaceClient = (apiKey, apiUrl) => {
2137
2504
  };
2138
2505
 
2139
2506
  // src/snippet.ts
2140
- var DEFAULT_API33 = "https://be.graph8.com";
2507
+ var DEFAULT_API34 = "https://be.graph8.com";
2141
2508
  var createSnippetClient = (apiKey, apiUrl) => {
2142
- const baseUrl = apiUrl || DEFAULT_API33;
2509
+ const baseUrl = apiUrl || DEFAULT_API34;
2143
2510
  return {
2144
2511
  /** Get your org's tracking snippet (write key + React/script-tag embeds + config). */
2145
2512
  async get() {
@@ -2151,7 +2518,7 @@ var createSnippetClient = (apiKey, apiUrl) => {
2151
2518
 
2152
2519
  // src/core.ts
2153
2520
  var DEFAULT_HOST = "https://t.graph8.com";
2154
- var DEFAULT_API34 = "https://be.graph8.com";
2521
+ var DEFAULT_API35 = "https://be.graph8.com";
2155
2522
  var G8 = class {
2156
2523
  constructor() {
2157
2524
  /** @internal */
@@ -2195,6 +2562,8 @@ var G8 = class {
2195
2562
  /** @internal */
2196
2563
  this._apps = null;
2197
2564
  /** @internal */
2565
+ this._appPlatform = null;
2566
+ /** @internal */
2198
2567
  this._objects = null;
2199
2568
  /** @internal */
2200
2569
  this._deals = null;
@@ -2238,7 +2607,7 @@ var G8 = class {
2238
2607
  debug: config.debug
2239
2608
  });
2240
2609
  }
2241
- const apiUrl = config.apiUrl || DEFAULT_API34;
2610
+ const apiUrl = config.apiUrl || DEFAULT_API35;
2242
2611
  const writeKey = config.writeKey || "";
2243
2612
  const apiKey = config.apiKey || "";
2244
2613
  if (writeKey) {
@@ -2262,6 +2631,7 @@ var G8 = class {
2262
2631
  this._tasks = createTasksClient(apiKey, apiUrl);
2263
2632
  this._fields = createFieldsClient(apiKey, apiUrl);
2264
2633
  this._apps = createAppsClient(apiKey, apiUrl);
2634
+ this._appPlatform = createAppPlatformClient(apiKey, apiUrl);
2265
2635
  this._objects = createObjectsClient(apiKey, apiUrl);
2266
2636
  this._deals = createDealsClient(apiKey, apiUrl);
2267
2637
  this._inbox = createInboxClient(apiKey, apiUrl);
@@ -2388,6 +2758,18 @@ var G8 = class {
2388
2758
  this._assertKey("apps");
2389
2759
  return this._apps;
2390
2760
  }
2761
+ /**
2762
+ * Ship a hosted app: bind a source, deploy, promote, attach a hostname, read
2763
+ * build logs (requires API key). PREVIEW.
2764
+ *
2765
+ * Separate from `apps` on purpose. `apps` is the app's IDENTITY -- create it,
2766
+ * see who installed it, what it cost. This is its LIFECYCLE, and the two have
2767
+ * different blast radii: a mistake here takes a customer's app down.
2768
+ */
2769
+ get appPlatform() {
2770
+ this._assertKey("appPlatform");
2771
+ return this._appPlatform;
2772
+ }
2391
2773
  /** Custom object types, their schema, and their records (requires API key). PREVIEW. */
2392
2774
  get objects() {
2393
2775
  this._assertKey("objects");