@graph8/sdk 0.13.0 → 0.14.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/index.js CHANGED
@@ -23,9 +23,12 @@ __export(index_exports, {
23
23
  DEFAULT_APP_API: () => DEFAULT_APP_API,
24
24
  G8Error: () => G8Error,
25
25
  KNOWN_WEBHOOK_EVENTS: () => KNOWN_WEBHOOK_EVENTS,
26
+ MAX_TAIL_LINES: () => MAX_TAIL_LINES,
27
+ MIN_TAIL_LINES: () => MIN_TAIL_LINES,
26
28
  WebhookSignatureError: () => WebhookSignatureError,
27
29
  backoffDelayMs: () => backoffDelayMs,
28
30
  constructEvent: () => constructEvent,
31
+ createAppPlatformClient: () => createAppPlatformClient,
29
32
  createAppRequester: () => createAppRequester,
30
33
  createGraph8AppClient: () => createGraph8AppClient,
31
34
  createGraph8ServiceClient: () => createGraph8ServiceClient,
@@ -1258,10 +1261,284 @@ var createAppsClient = (apiKey, apiUrl) => {
1258
1261
  };
1259
1262
  };
1260
1263
 
1261
- // src/fields.ts
1264
+ // src/appPlatform.ts
1262
1265
  var DEFAULT_API18 = "https://be.graph8.com";
1263
- var createFieldsClient = (apiKey, apiUrl) => {
1266
+ var MIN_TAIL_LINES = 1;
1267
+ var MAX_TAIL_LINES = 2e3;
1268
+ var createAppPlatformClient = (apiKey, apiUrl) => {
1264
1269
  const baseUrl = apiUrl || DEFAULT_API18;
1270
+ const unwrap = (resp) => resp.data ?? resp;
1271
+ return {
1272
+ // ---- source binding -------------------------------------------------
1273
+ /**
1274
+ * Bind the repository an app builds from.
1275
+ *
1276
+ * `repo_url` must be fetchable -- `https://`, `ssh://` or `git@`, with no
1277
+ * whitespace. A `file://` or bare path is refused with 422, because a build
1278
+ * that can read the builder's filesystem is a build that can read ours.
1279
+ *
1280
+ * `credential_ref` is a POINTER into your secret manager, not a token.
1281
+ */
1282
+ async setSource(appId, params) {
1283
+ const resp = await request(
1284
+ baseUrl,
1285
+ `/api/v1/apps/${appId}/source`,
1286
+ apiKey,
1287
+ {
1288
+ method: "PUT",
1289
+ body: {
1290
+ repo_url: params.repo_url,
1291
+ provider: params.provider,
1292
+ default_branch: params.default_branch ?? null,
1293
+ credential_ref: params.credential_ref ?? null
1294
+ }
1295
+ }
1296
+ );
1297
+ return unwrap(resp);
1298
+ },
1299
+ /** Unbind the source. Returns the full app with every source field null. */
1300
+ async clearSource(appId) {
1301
+ const resp = await request(
1302
+ baseUrl,
1303
+ `/api/v1/apps/${appId}/source`,
1304
+ apiKey,
1305
+ { method: "DELETE" }
1306
+ );
1307
+ return unwrap(resp);
1308
+ },
1309
+ // ---- deployments ----------------------------------------------------
1310
+ /** Every deployment for this app, newest first. Never 404s for an app with none. */
1311
+ async listDeployments(appId) {
1312
+ return request(baseUrl, `/api/v1/apps/${appId}/deployments`, apiKey);
1313
+ },
1314
+ /**
1315
+ * Queue a deployment. Returns `201` with `status: "queued"` -- nothing builds
1316
+ * as a side effect of this call; the build controller picks it up.
1317
+ *
1318
+ * NOT idempotent: two identical calls create two deployments.
1319
+ */
1320
+ async deploy(appId, params) {
1321
+ const body = { source_ref: params.source_ref };
1322
+ if (params.schema_version_id) body.schema_version_id = params.schema_version_id;
1323
+ const resp = await request(
1324
+ baseUrl,
1325
+ `/api/v1/apps/${appId}/deployments`,
1326
+ apiKey,
1327
+ { method: "POST", body }
1328
+ );
1329
+ return unwrap(resp);
1330
+ },
1331
+ /** Fetch one deployment. The polling endpoint for a build loop. */
1332
+ async getDeployment(appId, deploymentId) {
1333
+ const resp = await request(
1334
+ baseUrl,
1335
+ `/api/v1/apps/${appId}/deployments/${deploymentId}`,
1336
+ apiKey
1337
+ );
1338
+ return unwrap(resp);
1339
+ },
1340
+ /**
1341
+ * The deployment currently serving traffic, or `null`.
1342
+ *
1343
+ * `null` is a real answer with a 200, not a 404: "this app has never shipped"
1344
+ * is information, while a 404 would read as "no such app".
1345
+ */
1346
+ async activeDeployment(appId) {
1347
+ const resp = await request(
1348
+ baseUrl,
1349
+ `/api/v1/apps/${appId}/deployments/active`,
1350
+ apiKey
1351
+ );
1352
+ return resp.data ?? null;
1353
+ },
1354
+ /**
1355
+ * Promote a built deployment to serve traffic. Anything it displaces moves to
1356
+ * `rolled_back` in the same transaction, so there is never a moment with two
1357
+ * live deployments.
1358
+ *
1359
+ * `409` when the state machine forbids it -- a deployment cannot become
1360
+ * `deployed` without having been built, and a `failed` one cannot be revived.
1361
+ * A retry is a new deployment, not a resurrection.
1362
+ */
1363
+ async promote(appId, deploymentId, imageDigest) {
1364
+ const resp = await request(
1365
+ baseUrl,
1366
+ `/api/v1/apps/${appId}/deployments/${deploymentId}/promote`,
1367
+ apiKey,
1368
+ { method: "POST", body: { image_digest: imageDigest } }
1369
+ );
1370
+ return unwrap(resp);
1371
+ },
1372
+ /** Roll back a deployment that is currently serving. Only a `deployed` one may be. */
1373
+ async rollback(appId, deploymentId) {
1374
+ const resp = await request(
1375
+ baseUrl,
1376
+ `/api/v1/apps/${appId}/deployments/${deploymentId}/rollback`,
1377
+ apiKey,
1378
+ { method: "POST", body: {} }
1379
+ );
1380
+ return unwrap(resp);
1381
+ },
1382
+ // ---- logs -----------------------------------------------------------
1383
+ /**
1384
+ * Why a build failed. Returns every step of the build pod in the order
1385
+ * Kubernetes runs them; a step that has not started yet is omitted rather
1386
+ * than returned empty.
1387
+ *
1388
+ * An empty `containers` list is not an error -- build pods are reaped an hour
1389
+ * after they finish, so logs for an older deployment are genuinely gone.
1390
+ * `last_error_sanitized` on the deployment is what survives.
1391
+ *
1392
+ * `503` means graph8 could not reach the cluster, which is deliberately
1393
+ * different from an empty `200`: one means we could not look, the other means
1394
+ * your build produced no output.
1395
+ */
1396
+ async deploymentLogs(appId, deploymentId, tailLines) {
1397
+ const resp = await request(
1398
+ baseUrl,
1399
+ `/api/v1/apps/${appId}/deployments/${deploymentId}/logs`,
1400
+ apiKey,
1401
+ { query: tailLines === void 0 ? void 0 : { tail_lines: tailLines } }
1402
+ );
1403
+ return unwrap(resp);
1404
+ },
1405
+ /**
1406
+ * What the running app is printing. The app's own pods only -- the per-app
1407
+ * egress proxy shares the namespace and is deliberately excluded.
1408
+ *
1409
+ * Empty until a deployment reaches `deployed`.
1410
+ */
1411
+ async logs(appId, tailLines) {
1412
+ const resp = await request(
1413
+ baseUrl,
1414
+ `/api/v1/apps/${appId}/logs`,
1415
+ apiKey,
1416
+ { query: tailLines === void 0 ? void 0 : { tail_lines: tailLines } }
1417
+ );
1418
+ return unwrap(resp);
1419
+ },
1420
+ // ---- domains --------------------------------------------------------
1421
+ /** Every hostname claimed for this app, whatever its verification state. */
1422
+ async listDomains(appId) {
1423
+ return request(baseUrl, `/api/v1/apps/${appId}/domains`, apiKey);
1424
+ },
1425
+ /**
1426
+ * Claim a hostname and get the TXT record that proves you own it.
1427
+ *
1428
+ * Returns `201`, and the domain is NESTED at `data.domain` -- this is the one
1429
+ * route on the surface whose payload is not the record itself. Hostnames are
1430
+ * globally unique, so a host another app holds is refused.
1431
+ */
1432
+ async claimDomain(appId, hostname) {
1433
+ const resp = await request(
1434
+ baseUrl,
1435
+ `/api/v1/apps/${appId}/domains`,
1436
+ apiKey,
1437
+ { method: "POST", body: { hostname } }
1438
+ );
1439
+ return unwrap(resp);
1440
+ },
1441
+ /**
1442
+ * Check DNS for the TXT record and advance the domain to `verified`.
1443
+ *
1444
+ * Idempotent: verifying an already-verified domain re-checks and stays
1445
+ * verified, so it is safe to re-run after a DNS change. Send no body -- the
1446
+ * record in DNS is the payload.
1447
+ */
1448
+ async verifyDomain(appId, hostname) {
1449
+ const resp = await request(
1450
+ baseUrl,
1451
+ `/api/v1/apps/${appId}/domains/${encodeURIComponent(hostname)}/verify`,
1452
+ apiKey,
1453
+ { method: "POST", body: {} }
1454
+ );
1455
+ return unwrap(resp);
1456
+ },
1457
+ /**
1458
+ * Release a claimed hostname.
1459
+ *
1460
+ * A HARD delete. Hostnames are globally unique, so a row left behind in any
1461
+ * status keeps the host burned for every other builder. Releasing one you
1462
+ * already released is a `404`, because after the first call the claim
1463
+ * genuinely does not exist.
1464
+ *
1465
+ * Returns the NORMALIZED hostname, which may differ from what you passed.
1466
+ */
1467
+ async releaseDomain(appId, hostname) {
1468
+ const resp = await request(
1469
+ baseUrl,
1470
+ `/api/v1/apps/${appId}/domains/${encodeURIComponent(hostname)}`,
1471
+ apiKey,
1472
+ { method: "DELETE" }
1473
+ );
1474
+ return unwrap(resp);
1475
+ },
1476
+ // ---- secrets --------------------------------------------------------
1477
+ /**
1478
+ * Which secrets this app declares, and when each was last rotated.
1479
+ *
1480
+ * NEVER returns a value. graph8 stores a POINTER into your secret manager and
1481
+ * has no column for the secret itself.
1482
+ */
1483
+ async listSecrets(appId) {
1484
+ return request(baseUrl, `/api/v1/apps/${appId}/secrets`, apiKey);
1485
+ },
1486
+ /**
1487
+ * Declare a secret, or rotate the pointer to it.
1488
+ *
1489
+ * `providerRef` is a REFERENCE, and the server rejects anything that looks
1490
+ * like a credential -- a value starting `bearer `, `sk-`, `ghp_`, `xox` and
1491
+ * friends is a 422. That refusal is the feature: it catches the mistake of
1492
+ * pasting the secret where its address belongs.
1493
+ */
1494
+ async putSecret(appId, secretKey, providerRef) {
1495
+ const resp = await request(
1496
+ baseUrl,
1497
+ `/api/v1/apps/${appId}/secrets/${encodeURIComponent(secretKey)}`,
1498
+ apiKey,
1499
+ { method: "PUT", body: { provider_ref: providerRef ?? null } }
1500
+ );
1501
+ return unwrap(resp);
1502
+ },
1503
+ /** Undeclare a secret. A key the app never declared is a 404, so a typo is
1504
+ * never reported as a successful removal. */
1505
+ async deleteSecret(appId, secretKey) {
1506
+ const resp = await request(
1507
+ baseUrl,
1508
+ `/api/v1/apps/${appId}/secrets/${encodeURIComponent(secretKey)}`,
1509
+ apiKey,
1510
+ { method: "DELETE" }
1511
+ );
1512
+ return unwrap(resp);
1513
+ },
1514
+ // ---- schema versions ------------------------------------------------
1515
+ /**
1516
+ * Publish a custom-object schema version. Returns `201`.
1517
+ *
1518
+ * Takes only the `objects` list, not a whole `graph8.app.yaml`: the rest of
1519
+ * that file is app metadata the control plane already holds, and accepting it
1520
+ * here would create a second place for it to disagree.
1521
+ */
1522
+ async publishSchemaVersion(appId, objects) {
1523
+ const resp = await request(
1524
+ baseUrl,
1525
+ `/api/v1/apps/${appId}/schema-versions`,
1526
+ apiKey,
1527
+ { method: "POST", body: { objects } }
1528
+ );
1529
+ return unwrap(resp);
1530
+ },
1531
+ /** Every schema version this app has published. Empty array, never 404. */
1532
+ async listSchemaVersions(appId) {
1533
+ return request(baseUrl, `/api/v1/apps/${appId}/schema-versions`, apiKey);
1534
+ }
1535
+ };
1536
+ };
1537
+
1538
+ // src/fields.ts
1539
+ var DEFAULT_API19 = "https://be.graph8.com";
1540
+ var createFieldsClient = (apiKey, apiUrl) => {
1541
+ const baseUrl = apiUrl || DEFAULT_API19;
1265
1542
  return {
1266
1543
  /** List contact fields (base + custom). Pass listId to include list-specific custom fields. */
1267
1544
  async listContactFields(listId) {
@@ -1303,9 +1580,9 @@ var createFieldsClient = (apiKey, apiUrl) => {
1303
1580
  };
1304
1581
 
1305
1582
  // src/objects.ts
1306
- var DEFAULT_API19 = "https://be.graph8.com";
1583
+ var DEFAULT_API20 = "https://be.graph8.com";
1307
1584
  var createObjectsClient = (apiKey, apiUrl) => {
1308
- const baseUrl = apiUrl || DEFAULT_API19;
1585
+ const baseUrl = apiUrl || DEFAULT_API20;
1309
1586
  const encode = (value) => encodeURIComponent(value);
1310
1587
  return {
1311
1588
  /** List the custom object types in your workspace. */
@@ -1366,12 +1643,12 @@ var createObjectsClient = (apiKey, apiUrl) => {
1366
1643
  * Values are versioned rather than overwritten, so the previous value stays
1367
1644
  * readable through `history`.
1368
1645
  */
1369
- async updateRecord(objectSlug, recordId, values) {
1646
+ async updateRecord(objectSlug, recordId, values, options) {
1370
1647
  const resp = await request(
1371
1648
  baseUrl,
1372
1649
  `/api/v1/objects/${encode(objectSlug)}/records/${encode(recordId)}`,
1373
1650
  apiKey,
1374
- { method: "PATCH", body: { values } }
1651
+ { method: "PATCH", body: { values, ...options?.expectedRevision === void 0 ? {} : { expected_revision: options.expectedRevision } } }
1375
1652
  );
1376
1653
  return resp.data ?? resp;
1377
1654
  },
@@ -1388,6 +1665,16 @@ var createObjectsClient = (apiKey, apiUrl) => {
1388
1665
  );
1389
1666
  return resp.data ?? resp;
1390
1667
  },
1668
+ /** Restore archived values under current constraints. Conflicts leave the record archived. */
1669
+ async restoreRecord(objectSlug, recordId) {
1670
+ const resp = await request(
1671
+ baseUrl,
1672
+ `/api/v1/objects/${encode(objectSlug)}/records/${encode(recordId)}/restore`,
1673
+ apiKey,
1674
+ { method: "POST" }
1675
+ );
1676
+ return resp.data ?? resp;
1677
+ },
1391
1678
  /**
1392
1679
  * A record's value timeline, newest first. An entry whose `active_until` is
1393
1680
  * null is the value currently in force.
@@ -1405,9 +1692,9 @@ var createObjectsClient = (apiKey, apiUrl) => {
1405
1692
  };
1406
1693
 
1407
1694
  // src/deals.ts
1408
- var DEFAULT_API20 = "https://be.graph8.com";
1695
+ var DEFAULT_API21 = "https://be.graph8.com";
1409
1696
  var createDealsClient = (apiKey, apiUrl) => {
1410
- const baseUrl = apiUrl || DEFAULT_API20;
1697
+ const baseUrl = apiUrl || DEFAULT_API21;
1411
1698
  return {
1412
1699
  /** List all deal pipelines and their stages. */
1413
1700
  async pipelines() {
@@ -1451,9 +1738,9 @@ var createDealsClient = (apiKey, apiUrl) => {
1451
1738
  };
1452
1739
 
1453
1740
  // src/inbox.ts
1454
- var DEFAULT_API21 = "https://be.graph8.com";
1741
+ var DEFAULT_API22 = "https://be.graph8.com";
1455
1742
  var createInboxClient = (apiKey, apiUrl) => {
1456
- const baseUrl = apiUrl || DEFAULT_API21;
1743
+ const baseUrl = apiUrl || DEFAULT_API22;
1457
1744
  return {
1458
1745
  /** List inbox threads across email, SMS, and LinkedIn. */
1459
1746
  async list(params = {}) {
@@ -1506,9 +1793,9 @@ var createInboxClient = (apiKey, apiUrl) => {
1506
1793
  };
1507
1794
 
1508
1795
  // src/quotes.ts
1509
- var DEFAULT_API22 = "https://be.graph8.com";
1796
+ var DEFAULT_API23 = "https://be.graph8.com";
1510
1797
  var createQuotesClient = (apiKey, apiUrl) => {
1511
- const baseUrl = apiUrl || DEFAULT_API22;
1798
+ const baseUrl = apiUrl || DEFAULT_API23;
1512
1799
  return {
1513
1800
  /** List quotes org-wide with optional filters and pagination. */
1514
1801
  async list(params = {}) {
@@ -1580,9 +1867,9 @@ var createQuotesClient = (apiKey, apiUrl) => {
1580
1867
  };
1581
1868
 
1582
1869
  // src/pipelines.ts
1583
- var DEFAULT_API23 = "https://be.graph8.com";
1870
+ var DEFAULT_API24 = "https://be.graph8.com";
1584
1871
  var createPipelinesClient = (apiKey, apiUrl) => {
1585
- const baseUrl = apiUrl || DEFAULT_API23;
1872
+ const baseUrl = apiUrl || DEFAULT_API24;
1586
1873
  return {
1587
1874
  /** List all stage-checklist pipelines with stages, evidence, scripts. */
1588
1875
  async list() {
@@ -1664,9 +1951,9 @@ var createPipelinesClient = (apiKey, apiUrl) => {
1664
1951
  };
1665
1952
 
1666
1953
  // src/workflows.ts
1667
- var DEFAULT_API24 = "https://be.graph8.com";
1954
+ var DEFAULT_API25 = "https://be.graph8.com";
1668
1955
  var createWorkflowsClient = (apiKey, apiUrl) => {
1669
- const baseUrl = apiUrl || DEFAULT_API24;
1956
+ const baseUrl = apiUrl || DEFAULT_API25;
1670
1957
  return {
1671
1958
  /** List workflows org-wide. */
1672
1959
  async list(params = {}) {
@@ -1782,9 +2069,9 @@ var createWorkflowsClient = (apiKey, apiUrl) => {
1782
2069
  };
1783
2070
 
1784
2071
  // src/skills.ts
1785
- var DEFAULT_API25 = "https://be.graph8.com";
2072
+ var DEFAULT_API26 = "https://be.graph8.com";
1786
2073
  var createSkillsClient = (apiKey, apiUrl) => {
1787
- const baseUrl = apiUrl || DEFAULT_API25;
2074
+ const baseUrl = apiUrl || DEFAULT_API26;
1788
2075
  return {
1789
2076
  /** List skills. */
1790
2077
  async list(params = {}) {
@@ -1871,9 +2158,9 @@ var createSkillsClient = (apiKey, apiUrl) => {
1871
2158
  };
1872
2159
 
1873
2160
  // src/intent.ts
1874
- var DEFAULT_API26 = "https://be.graph8.com";
2161
+ var DEFAULT_API27 = "https://be.graph8.com";
1875
2162
  var createIntentClient = (apiKey, apiUrl) => {
1876
- const baseUrl = apiUrl || DEFAULT_API26;
2163
+ const baseUrl = apiUrl || DEFAULT_API27;
1877
2164
  const get = (path) => request(baseUrl, `/api/v1${path}`, apiKey);
1878
2165
  const post = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "POST", body });
1879
2166
  const del = (path) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "DELETE" });
@@ -1948,9 +2235,9 @@ var createIntentClient = (apiKey, apiUrl) => {
1948
2235
  };
1949
2236
 
1950
2237
  // src/studio.ts
1951
- var DEFAULT_API27 = "https://be.graph8.com";
2238
+ var DEFAULT_API28 = "https://be.graph8.com";
1952
2239
  var createStudioClient = (apiKey, apiUrl) => {
1953
- const baseUrl = apiUrl || DEFAULT_API27;
2240
+ const baseUrl = apiUrl || DEFAULT_API28;
1954
2241
  const get = (path, params = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { query: params });
1955
2242
  const post = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "POST", body });
1956
2243
  const patch = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "PATCH", body });
@@ -2005,9 +2292,9 @@ var createStudioClient = (apiKey, apiUrl) => {
2005
2292
  };
2006
2293
 
2007
2294
  // src/meetings.ts
2008
- var DEFAULT_API28 = "https://be.graph8.com";
2295
+ var DEFAULT_API29 = "https://be.graph8.com";
2009
2296
  var createMeetingsClient = (apiKey, apiUrl) => {
2010
- const baseUrl = apiUrl || DEFAULT_API28;
2297
+ const baseUrl = apiUrl || DEFAULT_API29;
2011
2298
  return {
2012
2299
  /** List meetings with optional filters. Returns summary rows without transcript / analysis. */
2013
2300
  async list(params = {}) {
@@ -2022,9 +2309,9 @@ var createMeetingsClient = (apiKey, apiUrl) => {
2022
2309
  };
2023
2310
 
2024
2311
  // src/audiences.ts
2025
- var DEFAULT_API29 = "https://be.graph8.com";
2312
+ var DEFAULT_API30 = "https://be.graph8.com";
2026
2313
  var createAudiencesClient = (apiKey, apiUrl) => {
2027
- const baseUrl = apiUrl || DEFAULT_API29;
2314
+ const baseUrl = apiUrl || DEFAULT_API30;
2028
2315
  const base = "/api/v1/audience-syncs";
2029
2316
  return {
2030
2317
  /** List all audience syncs for the organization. */
@@ -2072,9 +2359,9 @@ var createAudiencesClient = (apiKey, apiUrl) => {
2072
2359
  };
2073
2360
 
2074
2361
  // src/search.ts
2075
- var DEFAULT_API30 = "https://be.graph8.com";
2362
+ var DEFAULT_API31 = "https://be.graph8.com";
2076
2363
  var createSearchClient = (apiKey, apiUrl) => {
2077
- const baseUrl = apiUrl || DEFAULT_API30;
2364
+ const baseUrl = apiUrl || DEFAULT_API31;
2078
2365
  const body = (p) => ({ filters: [], page: 1, limit: 25, ...p });
2079
2366
  return {
2080
2367
  /** Search open-data contacts by filter. */
@@ -2105,9 +2392,9 @@ var createSearchClient = (apiKey, apiUrl) => {
2105
2392
  };
2106
2393
 
2107
2394
  // src/agency.ts
2108
- var DEFAULT_API31 = "https://be.graph8.com";
2395
+ var DEFAULT_API32 = "https://be.graph8.com";
2109
2396
  var createAgencyClient = (apiKey, apiUrl) => {
2110
- const baseUrl = apiUrl || DEFAULT_API31;
2397
+ const baseUrl = apiUrl || DEFAULT_API32;
2111
2398
  return {
2112
2399
  /** Describe the agency credential: agency org + authorized client count. */
2113
2400
  async me() {
@@ -2122,9 +2409,9 @@ var createAgencyClient = (apiKey, apiUrl) => {
2122
2409
  };
2123
2410
 
2124
2411
  // src/marketplace.ts
2125
- var DEFAULT_API32 = "https://be.graph8.com";
2412
+ var DEFAULT_API33 = "https://be.graph8.com";
2126
2413
  var createMarketplaceClient = (apiKey, apiUrl) => {
2127
- const baseUrl = apiUrl || DEFAULT_API32;
2414
+ const baseUrl = apiUrl || DEFAULT_API33;
2128
2415
  const base = "/api/v1/marketplace";
2129
2416
  return {
2130
2417
  /** Your own marketplace SDR profile. */
@@ -2174,9 +2461,9 @@ var createMarketplaceClient = (apiKey, apiUrl) => {
2174
2461
  };
2175
2462
 
2176
2463
  // src/snippet.ts
2177
- var DEFAULT_API33 = "https://be.graph8.com";
2464
+ var DEFAULT_API34 = "https://be.graph8.com";
2178
2465
  var createSnippetClient = (apiKey, apiUrl) => {
2179
- const baseUrl = apiUrl || DEFAULT_API33;
2466
+ const baseUrl = apiUrl || DEFAULT_API34;
2180
2467
  return {
2181
2468
  /** Get your org's tracking snippet (write key + React/script-tag embeds + config). */
2182
2469
  async get() {
@@ -2188,7 +2475,7 @@ var createSnippetClient = (apiKey, apiUrl) => {
2188
2475
 
2189
2476
  // src/core.ts
2190
2477
  var DEFAULT_HOST = "https://t.graph8.com";
2191
- var DEFAULT_API34 = "https://be.graph8.com";
2478
+ var DEFAULT_API35 = "https://be.graph8.com";
2192
2479
  var G8 = class {
2193
2480
  constructor() {
2194
2481
  /** @internal */
@@ -2232,6 +2519,8 @@ var G8 = class {
2232
2519
  /** @internal */
2233
2520
  this._apps = null;
2234
2521
  /** @internal */
2522
+ this._appPlatform = null;
2523
+ /** @internal */
2235
2524
  this._objects = null;
2236
2525
  /** @internal */
2237
2526
  this._deals = null;
@@ -2275,7 +2564,7 @@ var G8 = class {
2275
2564
  debug: config.debug
2276
2565
  });
2277
2566
  }
2278
- const apiUrl = config.apiUrl || DEFAULT_API34;
2567
+ const apiUrl = config.apiUrl || DEFAULT_API35;
2279
2568
  const writeKey = config.writeKey || "";
2280
2569
  const apiKey = config.apiKey || "";
2281
2570
  if (writeKey) {
@@ -2299,6 +2588,7 @@ var G8 = class {
2299
2588
  this._tasks = createTasksClient(apiKey, apiUrl);
2300
2589
  this._fields = createFieldsClient(apiKey, apiUrl);
2301
2590
  this._apps = createAppsClient(apiKey, apiUrl);
2591
+ this._appPlatform = createAppPlatformClient(apiKey, apiUrl);
2302
2592
  this._objects = createObjectsClient(apiKey, apiUrl);
2303
2593
  this._deals = createDealsClient(apiKey, apiUrl);
2304
2594
  this._inbox = createInboxClient(apiKey, apiUrl);
@@ -2425,6 +2715,18 @@ var G8 = class {
2425
2715
  this._assertKey("apps");
2426
2716
  return this._apps;
2427
2717
  }
2718
+ /**
2719
+ * Ship a hosted app: bind a source, deploy, promote, attach a hostname, read
2720
+ * build logs (requires API key). PREVIEW.
2721
+ *
2722
+ * Separate from `apps` on purpose. `apps` is the app's IDENTITY -- create it,
2723
+ * see who installed it, what it cost. This is its LIFECYCLE, and the two have
2724
+ * different blast radii: a mistake here takes a customer's app down.
2725
+ */
2726
+ get appPlatform() {
2727
+ this._assertKey("appPlatform");
2728
+ return this._appPlatform;
2729
+ }
2428
2730
  /** Custom object types, their schema, and their records (requires API key). PREVIEW. */
2429
2731
  get objects() {
2430
2732
  this._assertKey("objects");
@@ -2682,9 +2984,12 @@ function createGraph8ServiceClient(config) {
2682
2984
  DEFAULT_APP_API,
2683
2985
  G8Error,
2684
2986
  KNOWN_WEBHOOK_EVENTS,
2987
+ MAX_TAIL_LINES,
2988
+ MIN_TAIL_LINES,
2685
2989
  WebhookSignatureError,
2686
2990
  backoffDelayMs,
2687
2991
  constructEvent,
2992
+ createAppPlatformClient,
2688
2993
  createAppRequester,
2689
2994
  createGraph8AppClient,
2690
2995
  createGraph8ServiceClient,