@siglume/api-sdk 0.10.7 → 1.0.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.cjs CHANGED
@@ -1559,6 +1559,56 @@ var init_operations = __esm({
1559
1559
  });
1560
1560
 
1561
1561
  // src/client.ts
1562
+ function validateManifestPersistenceContract(payload) {
1563
+ const vertical = String(payload.store_vertical ?? "").trim().toLowerCase();
1564
+ const persistence = payload.persistence;
1565
+ if (persistence === void 0 || persistence === null) {
1566
+ return;
1567
+ }
1568
+ if (!isRecord2(persistence)) {
1569
+ throw new SiglumeClientError("AppManifest.persistence must be an object.");
1570
+ }
1571
+ const mode = String(persistence.mode ?? (vertical === "game" ? "platform" : "none")).trim().toLowerCase();
1572
+ if (!["none", "local", "platform", "developer_server"].includes(mode)) {
1573
+ throw new SiglumeClientError(
1574
+ "AppManifest.persistence.mode must be one of: none, local, platform, developer_server."
1575
+ );
1576
+ }
1577
+ const schema = persistence.save_data_schema;
1578
+ if (vertical === "game" && mode !== "none" && schema === void 0) {
1579
+ throw new SiglumeClientError(
1580
+ "AppManifest.persistence.save_data_schema is required when store_vertical='game' and persistence.mode is not 'none'."
1581
+ );
1582
+ }
1583
+ if (schema !== void 0) {
1584
+ validateSaveDataSchema(schema, "AppManifest.persistence.save_data_schema");
1585
+ }
1586
+ }
1587
+ function validateSaveDataSchema(schema, fieldName) {
1588
+ if (!isRecord2(schema)) {
1589
+ throw new SiglumeClientError(`${fieldName} must be a JSON Schema object.`);
1590
+ }
1591
+ const schemaSize = new TextEncoder().encode(JSON.stringify(schema)).length;
1592
+ if (schemaSize > 8192) {
1593
+ throw new SiglumeClientError(`${fieldName} must be at most 8192 bytes.`);
1594
+ }
1595
+ if (schema.type !== "object") {
1596
+ throw new SiglumeClientError(`${fieldName}.type must be 'object'.`);
1597
+ }
1598
+ const properties = schema.properties;
1599
+ if (!isRecord2(properties) || Object.keys(properties).length === 0) {
1600
+ throw new SiglumeClientError(`${fieldName}.properties must be a non-empty object.`);
1601
+ }
1602
+ if (schema.required !== void 0) {
1603
+ if (!Array.isArray(schema.required) || !schema.required.every((item) => typeof item === "string")) {
1604
+ throw new SiglumeClientError(`${fieldName}.required must be an array of strings when provided.`);
1605
+ }
1606
+ const missing = schema.required.filter((item) => !(item in properties));
1607
+ if (missing.length > 0) {
1608
+ throw new SiglumeClientError(`${fieldName}.required references undefined properties: ${missing.join(", ")}.`);
1609
+ }
1610
+ }
1611
+ }
1562
1612
  function buildToolManualQualityReport(payload) {
1563
1613
  const qualityBlock = isRecord2(payload.quality) ? payload.quality : payload;
1564
1614
  const issues = [];
@@ -1633,6 +1683,8 @@ function buildUrl(baseUrl, path, params) {
1633
1683
  return url.toString();
1634
1684
  }
1635
1685
  function parseListing(data) {
1686
+ const metadata = isRecord2(data.metadata) ? data.metadata : {};
1687
+ const persistence = isRecord2(data.persistence) ? data.persistence : isRecord2(metadata.persistence) ? metadata.persistence : {};
1636
1688
  return {
1637
1689
  listing_id: String(data.listing_id ?? data.id ?? ""),
1638
1690
  capability_key: String(data.capability_key ?? ""),
@@ -1655,14 +1707,59 @@ function parseListing(data) {
1655
1707
  seller_display_name: stringOrNull2(data.seller_display_name),
1656
1708
  seller_homepage_url: stringOrNull2(data.seller_homepage_url),
1657
1709
  seller_social_url: stringOrNull2(data.seller_social_url),
1710
+ publisher_type: stringOrNull2(data.publisher_type),
1711
+ publisher_company_id: stringOrNull2(data.publisher_company_id),
1712
+ company_id: stringOrNull2(data.company_id),
1713
+ company_name: stringOrNull2(data.company_name),
1714
+ company_publish_status: stringOrNull2(data.company_publish_status),
1715
+ company_terms_version: stringOrNull2(data.company_terms_version),
1658
1716
  review_status: stringOrNull2(data.review_status),
1659
1717
  review_note: stringOrNull2(data.review_note),
1660
1718
  submission_blockers: Array.isArray(data.submission_blockers) ? data.submission_blockers.filter((item) => typeof item === "string") : [],
1719
+ persistence: { ...persistence },
1661
1720
  created_at: stringOrNull2(data.created_at),
1662
1721
  updated_at: stringOrNull2(data.updated_at),
1663
1722
  raw: { ...data }
1664
1723
  };
1665
1724
  }
1725
+ function parseCompanyPublisher(data) {
1726
+ const wallets = Array.isArray(data.settlement_wallets) ? data.settlement_wallets.filter((item) => isRecord2(item)) : [];
1727
+ return {
1728
+ company_id: String(data.company_id ?? data.id ?? ""),
1729
+ name: String(data.name ?? ""),
1730
+ status: String(data.status ?? ""),
1731
+ description: stringOrNull2(data.description),
1732
+ is_founder: Boolean(data.is_founder ?? false),
1733
+ membership_role: stringOrNull2(data.membership_role),
1734
+ membership_status: stringOrNull2(data.membership_status),
1735
+ can_publish: Boolean(data.can_publish ?? true),
1736
+ can_approve: Boolean(data.can_approve ?? false),
1737
+ approval_required: Boolean(data.approval_required ?? false),
1738
+ paid_listing_allowed: Boolean(data.paid_listing_allowed ?? false),
1739
+ disabled_reasons: Array.isArray(data.disabled_reasons) ? data.disabled_reasons.filter((item) => typeof item === "string") : [],
1740
+ company_terms_version: stringOrNull2(data.company_terms_version),
1741
+ active_listing_count: Number(data.active_listing_count ?? 0),
1742
+ pending_approval_count: Number(data.pending_approval_count ?? 0),
1743
+ settlement_wallet_ready: Boolean(data.settlement_wallet_ready ?? false),
1744
+ settlement_wallets: wallets.map((item) => ({ ...item })),
1745
+ raw: { ...data }
1746
+ };
1747
+ }
1748
+ function parseCapabilitySaveState(data) {
1749
+ return {
1750
+ capability_key: String(data.capability_key ?? ""),
1751
+ save_key: String(data.save_key ?? ""),
1752
+ schema_version: String(data.schema_version ?? "1"),
1753
+ revision: Number(data.revision ?? 0),
1754
+ payload: toRecord2(data.payload),
1755
+ metadata: toRecord2(data.metadata),
1756
+ checksum: stringOrNull2(data.checksum),
1757
+ updated_at: stringOrNull2(data.updated_at),
1758
+ created_at: stringOrNull2(data.created_at),
1759
+ exists: Boolean(data.exists ?? false),
1760
+ raw: { ...data }
1761
+ };
1762
+ }
1666
1763
  function parseBundleMember(data) {
1667
1764
  return {
1668
1765
  capability_listing_id: String(data.capability_listing_id ?? ""),
@@ -1674,18 +1771,6 @@ function parseBundleMember(data) {
1674
1771
  link_id: stringOrNull2(data.link_id)
1675
1772
  };
1676
1773
  }
1677
- function parseConnectedAccountLifecycle(data) {
1678
- return {
1679
- connected_account_id: String(data.connected_account_id ?? ""),
1680
- provider_key: String(data.provider_key ?? ""),
1681
- expires_at: stringOrNull2(data.expires_at),
1682
- scopes: Array.isArray(data.scopes) ? data.scopes.filter((s) => typeof s === "string") : [],
1683
- refreshed_at: stringOrNull2(data.refreshed_at),
1684
- connection_status: stringOrNull2(data.connection_status),
1685
- provider_revoked: typeof data.provider_revoked === "boolean" ? data.provider_revoked : null,
1686
- revoked_at: stringOrNull2(data.revoked_at)
1687
- };
1688
- }
1689
1774
  function parseBundle(data) {
1690
1775
  const membersRaw = Array.isArray(data.members) ? data.members : [];
1691
1776
  return {
@@ -1764,21 +1849,6 @@ function parseBinding(data) {
1764
1849
  raw: { ...data }
1765
1850
  };
1766
1851
  }
1767
- function parseConnectedAccount(data) {
1768
- return {
1769
- connected_account_id: String(data.connected_account_id ?? data.id ?? ""),
1770
- provider_key: String(data.provider_key ?? ""),
1771
- account_role: String(data.account_role ?? ""),
1772
- display_name: stringOrNull2(data.display_name),
1773
- environment: stringOrNull2(data.environment),
1774
- connection_status: stringOrNull2(data.connection_status),
1775
- scopes: Array.isArray(data.scopes) ? data.scopes.filter((item) => typeof item === "string") : [],
1776
- metadata: toRecord2(data.metadata),
1777
- created_at: stringOrNull2(data.created_at),
1778
- updated_at: stringOrNull2(data.updated_at),
1779
- raw: { ...data }
1780
- };
1781
- }
1782
1852
  function parseSupportCase(data) {
1783
1853
  return {
1784
1854
  support_case_id: String(data.support_case_id ?? data.id ?? ""),
@@ -2817,13 +2887,6 @@ var init_client = __esm({
2817
2887
  if (options.runtime_validation) {
2818
2888
  payload.runtime_validation = coerceMapping(options.runtime_validation, "runtime_validation");
2819
2889
  }
2820
- if (options.oauth_credentials) {
2821
- payload.oauth_credentials = Array.isArray(options.oauth_credentials) ? {
2822
- items: options.oauth_credentials.map(
2823
- (item, index) => coerceMapping(item, `oauth_credentials[${index}]`)
2824
- )
2825
- } : coerceMapping(options.oauth_credentials, "oauth_credentials");
2826
- }
2827
2890
  if (options.source_context) {
2828
2891
  payload.source_context = coerceMapping(options.source_context, "source_context");
2829
2892
  }
@@ -2842,6 +2905,9 @@ var init_client = __esm({
2842
2905
  "support_contact",
2843
2906
  "seller_homepage_url",
2844
2907
  "seller_social_url",
2908
+ "publisher_type",
2909
+ "company_id",
2910
+ "publisher_company_id",
2845
2911
  "store_vertical",
2846
2912
  "jurisdiction",
2847
2913
  "price_model",
@@ -2854,7 +2920,8 @@ var init_client = __esm({
2854
2920
  "dry_run_supported",
2855
2921
  "required_connected_accounts",
2856
2922
  "permission_scopes",
2857
- "compatibility_tags"
2923
+ "compatibility_tags",
2924
+ "persistence"
2858
2925
  ]) {
2859
2926
  const value = manifestPayload[fieldName];
2860
2927
  if (value !== void 0 && value !== null) {
@@ -2894,6 +2961,26 @@ var init_client = __esm({
2894
2961
  );
2895
2962
  }
2896
2963
  }
2964
+ const explicitPublisherType = payload.publisher_type !== void 0 && payload.publisher_type !== null;
2965
+ const companyId = String(payload.company_id ?? "").trim() || String(payload.publisher_company_id ?? "").trim();
2966
+ const publisherType = String(payload.publisher_type ?? "user").trim().toLowerCase();
2967
+ if (publisherType !== "user" && publisherType !== "company") {
2968
+ throw new SiglumeClientError("AppManifest.publisher_type must be 'user' or 'company'.");
2969
+ }
2970
+ if (publisherType === "company" && !companyId) {
2971
+ throw new SiglumeClientError("AppManifest.company_id is required when publisher_type='company'.");
2972
+ }
2973
+ if (publisherType === "user" && companyId) {
2974
+ throw new SiglumeClientError("AppManifest.company_id cannot be combined with publisher_type='user'.");
2975
+ }
2976
+ if (explicitPublisherType || companyId) {
2977
+ payload.publisher_type = publisherType;
2978
+ }
2979
+ if (companyId) {
2980
+ payload.company_id = companyId;
2981
+ payload.publisher_company_id = companyId;
2982
+ }
2983
+ validateManifestPersistenceContract(payload);
2897
2984
  if (payload.manifest && typeof payload.manifest === "object") {
2898
2985
  delete payload.manifest.version;
2899
2986
  }
@@ -2929,7 +3016,6 @@ var init_client = __esm({
2929
3016
  auto_manifest: toRecord2(data.auto_manifest),
2930
3017
  confidence: toRecord2(data.confidence),
2931
3018
  validation_report: toRecord2(data.validation_report),
2932
- oauth_status: toRecord2(data.oauth_status),
2933
3019
  review_url: stringOrNull2(data.review_url),
2934
3020
  trace_id: meta.trace_id,
2935
3021
  request_id: meta.request_id
@@ -3001,6 +3087,45 @@ var init_client = __esm({
3001
3087
  const [data] = await this.request("GET", `/market/capabilities/${listing_id}`);
3002
3088
  return parseListing(data);
3003
3089
  }
3090
+ async list_company_publishers() {
3091
+ const [data] = await this.request("GET", "/market/company-publishers");
3092
+ return Array.isArray(data.items) ? data.items.filter((item) => isRecord2(item)).map(parseCompanyPublisher) : [];
3093
+ }
3094
+ async request_company_publish_approval(listing_id, note) {
3095
+ const [data] = await this.request("POST", `/market/capabilities/${listing_id}/company-publish-approval`, {
3096
+ json_body: note ? { note } : {}
3097
+ });
3098
+ return parseListing(data);
3099
+ }
3100
+ async decide_company_publish_approval(listing_id, options) {
3101
+ const [data] = await this.request("POST", `/market/capabilities/${listing_id}/company-publish-approval/decision`, {
3102
+ json_body: {
3103
+ decision: options.decision,
3104
+ ...options.reason ? { reason: options.reason } : {}
3105
+ }
3106
+ });
3107
+ return parseListing(data);
3108
+ }
3109
+ async get_capability_state(capability_key, save_key = "default") {
3110
+ const [data] = await this.request("GET", `/market/capability-state/${capability_key}/${save_key}`);
3111
+ return parseCapabilitySaveState(data);
3112
+ }
3113
+ async put_capability_state(capability_key, save_key = "default", payload = {}, options = {}) {
3114
+ const body = {
3115
+ payload: toRecord2(payload),
3116
+ schema_version: options.schema_version ?? "1",
3117
+ metadata: toRecord2(options.metadata)
3118
+ };
3119
+ if (options.expected_revision !== void 0 && options.expected_revision !== null) {
3120
+ body.expected_revision = Math.trunc(options.expected_revision);
3121
+ }
3122
+ const [data] = await this.request("PUT", `/market/capability-state/${capability_key}/${save_key}`, { json_body: body });
3123
+ return parseCapabilitySaveState(data);
3124
+ }
3125
+ async delete_capability_state(capability_key, save_key = "default") {
3126
+ const [data] = await this.request("DELETE", `/market/capability-state/${capability_key}/${save_key}`);
3127
+ return parseCapabilitySaveState(data);
3128
+ }
3004
3129
  // ----- Capability bundles (v0.7 track 2) ---------------------------------
3005
3130
  async list_bundles(options = {}) {
3006
3131
  const params = {
@@ -3066,66 +3191,9 @@ var init_client = __esm({
3066
3191
  return parseBundle(data);
3067
3192
  }
3068
3193
  // ----- end bundles -------------------------------------------------------
3069
- // ----- Connected accounts (v0.7 track 3) ---------------------------------
3070
- // `resolve()` is intentionally NOT wrapped: runtime-only, never over the wire.
3071
- async start_connected_account_oauth(input) {
3072
- const body = {
3073
- listing_id: input.listing_id,
3074
- redirect_uri: input.redirect_uri
3075
- };
3076
- if (input.scopes !== void 0) body.scopes = input.scopes;
3077
- if (input.account_role !== void 0) body.account_role = input.account_role;
3078
- const [data] = await this.request("POST", "/me/connected-accounts/oauth/authorize", {
3079
- json_body: body
3080
- });
3081
- return {
3082
- authorize_url: String(data.authorize_url ?? ""),
3083
- state: String(data.state ?? ""),
3084
- provider_key: String(data.provider_key ?? ""),
3085
- scopes: Array.isArray(data.scopes) ? data.scopes.filter((s) => typeof s === "string") : [],
3086
- pkce_method: stringOrNull2(data.pkce_method)
3087
- };
3088
- }
3089
- async complete_connected_account_oauth(input) {
3090
- const [data] = await this.request("POST", "/me/connected-accounts/oauth/callback", {
3091
- json_body: { state: input.state, code: input.code }
3092
- });
3093
- return { ...data };
3094
- }
3095
- async refresh_connected_account(account_id) {
3096
- const [data] = await this.request("POST", `/me/connected-accounts/${account_id}/refresh`);
3097
- return parseConnectedAccountLifecycle(data);
3098
- }
3099
- async revoke_connected_account(account_id) {
3100
- const [data] = await this.request("POST", `/me/connected-accounts/${account_id}/revoke`);
3101
- return parseConnectedAccountLifecycle(data);
3102
- }
3103
- async set_listing_oauth_credentials(listing_id, input) {
3104
- const body = {
3105
- provider_key: input.provider_key,
3106
- client_id: input.client_id,
3107
- client_secret: input.client_secret,
3108
- authorize_url: input.authorize_url,
3109
- token_url: input.token_url
3110
- };
3111
- if (input.revoke_url !== void 0) body.revoke_url = input.revoke_url;
3112
- if (input.display_name !== void 0) body.display_name = input.display_name;
3113
- if (input.scope_separator !== void 0) body.scope_separator = input.scope_separator;
3114
- if (input.token_endpoint_auth !== void 0) body.token_endpoint_auth = input.token_endpoint_auth;
3115
- if (input.pkce_required !== void 0) body.pkce_required = input.pkce_required;
3116
- if (input.refresh_supported !== void 0) body.refresh_supported = input.refresh_supported;
3117
- if (input.available_scopes !== void 0) body.available_scopes = input.available_scopes;
3118
- if (input.required_scopes !== void 0) body.required_scopes = input.required_scopes;
3119
- const [data] = await this.request("PUT", `/market/capabilities/${listing_id}/oauth-credentials`, {
3120
- json_body: body
3121
- });
3122
- return { ...data };
3123
- }
3124
- async get_listing_oauth_credentials_status(listing_id) {
3125
- const [data] = await this.request("GET", `/market/capabilities/${listing_id}/oauth-credentials`);
3126
- return { ...data };
3127
- }
3128
- // ----- end connected accounts --------------------------------------------
3194
+ // ----- Connected accounts ------------------------------------------------
3195
+ // Architecture B: publisher APIs own external OAuth and token storage.
3196
+ // The SDK no longer exposes platform OAuth or listing credential APIs.
3129
3197
  async get_developer_portal() {
3130
3198
  const [data, meta] = await this.request("GET", "/market/developer/portal");
3131
3199
  return {
@@ -3158,7 +3226,6 @@ var init_client = __esm({
3158
3226
  dry_run_supported: Boolean(data.dry_run_supported ?? false),
3159
3227
  approval_mode: stringOrNull2(data.approval_mode),
3160
3228
  required_connected_accounts: Array.isArray(data.required_connected_accounts) ? data.required_connected_accounts : [],
3161
- connected_accounts: Array.isArray(data.connected_accounts) ? data.connected_accounts.filter((item) => isRecord2(item)).map((item) => ({ ...item })) : [],
3162
3229
  stub_providers_enabled: Boolean(data.stub_providers_enabled ?? false),
3163
3230
  simulated_receipts: Boolean(data.simulated_receipts ?? false),
3164
3231
  approval_simulator: Boolean(data.approval_simulator ?? false),
@@ -4456,25 +4523,6 @@ var init_client = __esm({
4456
4523
  raw: { ...data }
4457
4524
  };
4458
4525
  }
4459
- async list_connected_accounts(options = {}) {
4460
- const params = {
4461
- provider_key: options.provider_key,
4462
- environment: options.environment,
4463
- limit: Math.max(1, Math.min(Math.trunc(options.limit ?? 50), 100)),
4464
- cursor: options.cursor
4465
- };
4466
- const [data, meta] = await this.request("GET", "/market/connected-accounts", { params });
4467
- const items = Array.isArray(data.items) ? data.items.filter((item) => isRecord2(item)).map(parseConnectedAccount) : [];
4468
- const next_cursor = stringOrNull2(data.next_cursor);
4469
- return new CursorPageResult({
4470
- items,
4471
- next_cursor,
4472
- limit: typeof data.limit === "number" ? data.limit : params.limit,
4473
- offset: typeof data.offset === "number" ? data.offset : null,
4474
- meta,
4475
- fetchNext: next_cursor ? (cursor) => this.list_connected_accounts({ ...options, cursor }) : void 0
4476
- });
4477
- }
4478
4526
  async create_support_case(subject, body, options = {}) {
4479
4527
  const summary = subject.trim();
4480
4528
  const details = body.trim();
@@ -5160,6 +5208,7 @@ __export(src_exports, {
5160
5208
  MeterClient: () => MeterClient,
5161
5209
  OpenAIProvider: () => OpenAIProvider,
5162
5210
  PermissionClass: () => PermissionClass,
5211
+ PersistenceMode: () => PersistenceMode,
5163
5212
  PriceModel: () => PriceModel,
5164
5213
  RecordMode: () => RecordMode,
5165
5214
  Recorder: () => Recorder,
@@ -6570,6 +6619,12 @@ var ListingCurrency = {
6570
6619
  USD: "USD",
6571
6620
  JPY: "JPY"
6572
6621
  };
6622
+ var PersistenceMode = {
6623
+ NONE: "none",
6624
+ LOCAL: "local",
6625
+ PLATFORM: "platform",
6626
+ DEVELOPER_SERVER: "developer_server"
6627
+ };
6573
6628
  var ToolManualPermissionClass = {
6574
6629
  READ_ONLY: "read_only",
6575
6630
  ACTION: "action",
@@ -7306,24 +7361,12 @@ var AppTestHarness = class {
7306
7361
  this.stubs = stubs;
7307
7362
  }
7308
7363
  async executeWithKind(execution_kind, task_type = "default", options = {}) {
7309
- const connected_accounts = options.connected_accounts ?? Object.fromEntries(
7310
- Object.keys(this.stubs).map((key) => [
7311
- key,
7312
- {
7313
- provider_key: key,
7314
- session_token: `stub-token-${key}`,
7315
- environment: Environment.SANDBOX,
7316
- scopes: []
7317
- }
7318
- ])
7319
- );
7320
7364
  const ctx = {
7321
7365
  agent_id: "test-agent-001",
7322
7366
  owner_user_id: "test-owner-001",
7323
7367
  task_type,
7324
7368
  environment: Environment.SANDBOX,
7325
7369
  execution_kind,
7326
- connected_accounts,
7327
7370
  input_params: options.input_params ?? {},
7328
7371
  trace_id: options.trace_id,
7329
7372
  idempotency_key: options.idempotency_key,
@@ -7413,12 +7456,6 @@ var AppTestHarness = class {
7413
7456
  }
7414
7457
  return issues;
7415
7458
  }
7416
- async simulate_connected_account_missing(task_type = "default", options = {}) {
7417
- return this.executeWithKind("dry_run", task_type, {
7418
- ...options,
7419
- connected_accounts: {}
7420
- });
7421
- }
7422
7459
  async simulate_metering(record, options = {}) {
7423
7460
  const { normalizeUsageRecord: normalizeUsageRecord2 } = await Promise.resolve().then(() => (init_metering(), metering_exports));
7424
7461
  const manifest = await this.app.manifest();