@siglume/api-sdk 1.0.0 → 1.1.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
@@ -30,6 +30,81 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
+ // src/types.ts
34
+ var PermissionClass, ApprovalMode, ExecutionKind, Environment, PriceModel, AppCategory, StoreVertical, ListingCurrency, MINIMUM_JPY_OPERATION_PRICE_MINOR, PersistenceMode, ToolManualPermissionClass, SettlementMode;
35
+ var init_types = __esm({
36
+ "src/types.ts"() {
37
+ "use strict";
38
+ PermissionClass = {
39
+ READ_ONLY: "read-only",
40
+ ACTION: "action",
41
+ PAYMENT: "payment",
42
+ /** @deprecated Use READ_ONLY. Behaves identically. */
43
+ RECOMMENDATION: "recommendation"
44
+ };
45
+ ApprovalMode = {
46
+ AUTO: "auto",
47
+ BUDGET_BOUNDED: "budget-bounded",
48
+ ALWAYS_ASK: "always-ask",
49
+ DENY: "deny"
50
+ };
51
+ ExecutionKind = {
52
+ DRY_RUN: "dry_run",
53
+ QUOTE: "quote",
54
+ ACTION: "action",
55
+ PAYMENT: "payment"
56
+ };
57
+ Environment = {
58
+ SANDBOX: "sandbox",
59
+ LIVE: "live"
60
+ };
61
+ PriceModel = {
62
+ FREE: "free",
63
+ SUBSCRIPTION: "subscription",
64
+ ONE_TIME: "one_time",
65
+ BUNDLE: "bundle",
66
+ USAGE_BASED: "usage_based",
67
+ PER_ACTION: "per_action"
68
+ };
69
+ AppCategory = {
70
+ COMMERCE: "commerce",
71
+ BOOKING: "booking",
72
+ CRM: "crm",
73
+ FINANCE: "finance",
74
+ DOCUMENT: "document",
75
+ COMMUNICATION: "communication",
76
+ MONITORING: "monitoring",
77
+ OTHER: "other"
78
+ };
79
+ StoreVertical = {
80
+ API: "api",
81
+ GAME: "game"
82
+ };
83
+ ListingCurrency = {
84
+ USD: "USD",
85
+ JPY: "JPY"
86
+ };
87
+ MINIMUM_JPY_OPERATION_PRICE_MINOR = 15;
88
+ PersistenceMode = {
89
+ NONE: "none",
90
+ LOCAL: "local",
91
+ PLATFORM: "platform",
92
+ DEVELOPER_SERVER: "developer_server"
93
+ };
94
+ ToolManualPermissionClass = {
95
+ READ_ONLY: "read_only",
96
+ ACTION: "action",
97
+ PAYMENT: "payment"
98
+ };
99
+ SettlementMode = {
100
+ STRIPE_CHECKOUT: "stripe_checkout",
101
+ STRIPE_PAYMENT_INTENT: "stripe_payment_intent",
102
+ POLYGON_MANDATE: "polygon_mandate",
103
+ EMBEDDED_WALLET_CHARGE: "embedded_wallet_charge"
104
+ };
105
+ }
106
+ });
107
+
33
108
  // src/errors.ts
34
109
  var SiglumeError, SiglumeClientError, SiglumeProjectError, SiglumeValidationError, SiglumeAssistError, SiglumeNotFoundError, SiglumeWebhookError, SiglumeWebhookSignatureError, SiglumeWebhookPayloadError, SiglumeWebhookReplayError, SiglumeAPIError;
35
110
  var init_errors = __esm({
@@ -1609,6 +1684,58 @@ function validateSaveDataSchema(schema, fieldName) {
1609
1684
  }
1610
1685
  }
1611
1686
  }
1687
+ function validatePricingPlanFloor(plan, defaultCurrency) {
1688
+ if (plan === void 0 || plan === null) {
1689
+ return;
1690
+ }
1691
+ if (!isRecord2(plan)) {
1692
+ throw new SiglumeClientError("AppManifest.pricing_plan must be an object when provided.");
1693
+ }
1694
+ const items = plan.items;
1695
+ if (items === void 0 || items === null) {
1696
+ return;
1697
+ }
1698
+ if (!Array.isArray(items)) {
1699
+ throw new SiglumeClientError("AppManifest.pricing_plan.items must be an array when provided.");
1700
+ }
1701
+ const planCurrency = String(plan.currency ?? defaultCurrency ?? "").trim().toUpperCase();
1702
+ const seenKeys = /* @__PURE__ */ new Set();
1703
+ items.forEach((item, index) => {
1704
+ if (!isRecord2(item)) {
1705
+ throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}] must be an object.`);
1706
+ }
1707
+ const itemKey = String(
1708
+ item.key ?? item.operation ?? item.operation_key ?? item.request_type ?? item.receipt_code ?? item.action ?? ""
1709
+ ).trim();
1710
+ if (!itemKey) {
1711
+ throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].key is required.`);
1712
+ }
1713
+ if (seenKeys.has(itemKey)) {
1714
+ throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].key duplicates ${itemKey}.`);
1715
+ }
1716
+ seenKeys.add(itemKey);
1717
+ const amountRaw = item.price_minor ?? item.amount_minor ?? item.cost_minor ?? item.value_minor;
1718
+ if (amountRaw === void 0 || amountRaw === null) {
1719
+ throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].price_minor is required.`);
1720
+ }
1721
+ const amountMinor = typeof amountRaw === "number" ? amountRaw : typeof amountRaw === "string" && amountRaw.trim() ? Number(amountRaw) : NaN;
1722
+ if (!Number.isInteger(amountMinor)) {
1723
+ throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].price_minor must be an integer.`);
1724
+ }
1725
+ if (amountMinor < 0) {
1726
+ throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].price_minor must be zero or positive.`);
1727
+ }
1728
+ const currency = String(item.currency ?? planCurrency ?? defaultCurrency ?? "").trim().toUpperCase();
1729
+ if (MINIMUM_JPY_OPERATION_PRICE_CURRENCIES.has(currency) && amountMinor > 0 && amountMinor < MINIMUM_JPY_OPERATION_PRICE_MINOR) {
1730
+ throw new SiglumeClientError(
1731
+ `AppManifest.pricing_plan.items[${index}].price_minor must be 0 or at least ${MINIMUM_JPY_OPERATION_PRICE_MINOR} for JPY/JPYC operation billing.`
1732
+ );
1733
+ }
1734
+ });
1735
+ }
1736
+ function pricingPlanHasItems(plan) {
1737
+ return isRecord2(plan) && Array.isArray(plan.items) && plan.items.length > 0;
1738
+ }
1612
1739
  function buildToolManualQualityReport(payload) {
1613
1740
  const qualityBlock = isRecord2(payload.quality) ? payload.quality : payload;
1614
1741
  const issues = [];
@@ -1684,6 +1811,7 @@ function buildUrl(baseUrl, path, params) {
1684
1811
  }
1685
1812
  function parseListing(data) {
1686
1813
  const metadata = isRecord2(data.metadata) ? data.metadata : {};
1814
+ const pricing_plan = isRecord2(data.pricing_plan) ? data.pricing_plan : isRecord2(metadata.pricing_plan) ? metadata.pricing_plan : null;
1687
1815
  const persistence = isRecord2(data.persistence) ? data.persistence : isRecord2(metadata.persistence) ? metadata.persistence : {};
1688
1816
  return {
1689
1817
  listing_id: String(data.listing_id ?? data.id ?? ""),
@@ -1697,6 +1825,7 @@ function parseListing(data) {
1697
1825
  dry_run_supported: Boolean(data.dry_run_supported ?? false),
1698
1826
  price_model: stringOrNull2(data.price_model),
1699
1827
  price_value_minor: Number(data.price_value_minor ?? 0),
1828
+ pricing_plan,
1700
1829
  currency: String(data.currency ?? "USD"),
1701
1830
  allow_free_trial: Boolean(data.allow_free_trial ?? false),
1702
1831
  free_trial_duration_days: Number(data.free_trial_duration_days ?? 30),
@@ -2794,10 +2923,11 @@ function cloneJsonLike(value) {
2794
2923
  }
2795
2924
  return value;
2796
2925
  }
2797
- var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, CursorPageResult, SiglumeClient;
2926
+ var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, MINIMUM_JPY_OPERATION_PRICE_CURRENCIES, CursorPageResult, SiglumeClient;
2798
2927
  var init_client = __esm({
2799
2928
  "src/client.ts"() {
2800
2929
  "use strict";
2930
+ init_types();
2801
2931
  init_errors();
2802
2932
  init_webhooks();
2803
2933
  init_web3();
@@ -2805,6 +2935,7 @@ var init_client = __esm({
2805
2935
  init_utils();
2806
2936
  DEFAULT_SIGLUME_API_BASE = "https://siglume.com/v1";
2807
2937
  RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
2938
+ MINIMUM_JPY_OPERATION_PRICE_CURRENCIES = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
2808
2939
  CursorPageResult = class {
2809
2940
  items;
2810
2941
  next_cursor;
@@ -2912,6 +3043,7 @@ var init_client = __esm({
2912
3043
  "jurisdiction",
2913
3044
  "price_model",
2914
3045
  "price_value_minor",
3046
+ "pricing_plan",
2915
3047
  "currency",
2916
3048
  "allow_free_trial",
2917
3049
  "free_trial_duration_days",
@@ -2928,6 +3060,9 @@ var init_client = __esm({
2928
3060
  payload[fieldName] = value;
2929
3061
  }
2930
3062
  }
3063
+ if (payload.pricing_plan !== void 0 && (typeof payload.pricing_plan !== "object" || Array.isArray(payload.pricing_plan))) {
3064
+ throw new SiglumeClientError("AppManifest.pricing_plan must be an object when provided.");
3065
+ }
2931
3066
  if (payload.store_vertical === void 0 || payload.store_vertical === null) {
2932
3067
  throw new SiglumeClientError(
2933
3068
  "AppManifest.store_vertical is required. Choose 'api' for normal API Store listings or 'game' for API games."
@@ -2943,6 +3078,13 @@ var init_client = __esm({
2943
3078
  throw new SiglumeClientError(`AppManifest.currency must be 'USD' or 'JPY'. Got ${String(payload.currency)}.`);
2944
3079
  }
2945
3080
  payload.currency = currency;
3081
+ if (payload.pricing_plan !== void 0) {
3082
+ validatePricingPlanFloor(payload.pricing_plan, currency);
3083
+ }
3084
+ const priceModel = String(payload.price_model ?? "free").trim().toLowerCase();
3085
+ if ((priceModel === "usage_based" || priceModel === "per_action") && !pricingPlanHasItems(payload.pricing_plan)) {
3086
+ throw new SiglumeClientError("AppManifest.pricing_plan.items is required for usage_based/per_action pricing.");
3087
+ }
2946
3088
  if (payload.allow_free_trial === void 0 || payload.allow_free_trial === null) {
2947
3089
  throw new SiglumeClientError(
2948
3090
  "AppManifest.allow_free_trial is required. Pass true to offer a Plus/Pro buyer free trial or false to disable trials."
@@ -5205,6 +5347,7 @@ __export(src_exports, {
5205
5347
  InMemoryWebhookDedupe: () => InMemoryWebhookDedupe,
5206
5348
  LLMProvider: () => LLMProvider,
5207
5349
  ListingCurrency: () => ListingCurrency,
5350
+ MINIMUM_JPY_OPERATION_PRICE_MINOR: () => MINIMUM_JPY_OPERATION_PRICE_MINOR,
5208
5351
  MeterClient: () => MeterClient,
5209
5352
  OpenAIProvider: () => OpenAIProvider,
5210
5353
  PermissionClass: () => PermissionClass,
@@ -6569,73 +6712,8 @@ function toRecord3(value) {
6569
6712
  init_metering();
6570
6713
  init_operations();
6571
6714
 
6572
- // src/types.ts
6573
- var PermissionClass = {
6574
- READ_ONLY: "read-only",
6575
- ACTION: "action",
6576
- PAYMENT: "payment",
6577
- /** @deprecated Use READ_ONLY. Behaves identically. */
6578
- RECOMMENDATION: "recommendation"
6579
- };
6580
- var ApprovalMode = {
6581
- AUTO: "auto",
6582
- BUDGET_BOUNDED: "budget-bounded",
6583
- ALWAYS_ASK: "always-ask",
6584
- DENY: "deny"
6585
- };
6586
- var ExecutionKind = {
6587
- DRY_RUN: "dry_run",
6588
- QUOTE: "quote",
6589
- ACTION: "action",
6590
- PAYMENT: "payment"
6591
- };
6592
- var Environment = {
6593
- SANDBOX: "sandbox",
6594
- LIVE: "live"
6595
- };
6596
- var PriceModel = {
6597
- FREE: "free",
6598
- SUBSCRIPTION: "subscription",
6599
- ONE_TIME: "one_time",
6600
- BUNDLE: "bundle",
6601
- USAGE_BASED: "usage_based",
6602
- PER_ACTION: "per_action"
6603
- };
6604
- var AppCategory = {
6605
- COMMERCE: "commerce",
6606
- BOOKING: "booking",
6607
- CRM: "crm",
6608
- FINANCE: "finance",
6609
- DOCUMENT: "document",
6610
- COMMUNICATION: "communication",
6611
- MONITORING: "monitoring",
6612
- OTHER: "other"
6613
- };
6614
- var StoreVertical = {
6615
- API: "api",
6616
- GAME: "game"
6617
- };
6618
- var ListingCurrency = {
6619
- USD: "USD",
6620
- JPY: "JPY"
6621
- };
6622
- var PersistenceMode = {
6623
- NONE: "none",
6624
- LOCAL: "local",
6625
- PLATFORM: "platform",
6626
- DEVELOPER_SERVER: "developer_server"
6627
- };
6628
- var ToolManualPermissionClass = {
6629
- READ_ONLY: "read_only",
6630
- ACTION: "action",
6631
- PAYMENT: "payment"
6632
- };
6633
- var SettlementMode = {
6634
- STRIPE_CHECKOUT: "stripe_checkout",
6635
- STRIPE_PAYMENT_INTENT: "stripe_payment_intent",
6636
- POLYGON_MANDATE: "polygon_mandate",
6637
- EMBEDDED_WALLET_CHARGE: "embedded_wallet_charge"
6638
- };
6715
+ // src/runtime.ts
6716
+ init_types();
6639
6717
 
6640
6718
  // src/testing/recorder.ts
6641
6719
  var CASSETTE_VERSION = 1;
@@ -7033,6 +7111,7 @@ Actual: ${requestSignature(requestRecord, ignoreBodyFields)}`
7033
7111
  };
7034
7112
 
7035
7113
  // src/tool-manual-validator.ts
7114
+ init_types();
7036
7115
  init_utils();
7037
7116
  var JURISDICTION_PATTERN = /^[A-Z]{2}(-[A-Z0-9]{1,3})?$/;
7038
7117
  var TOOL_NAME_RE = /^[A-Za-z0-9_]{3,64}$/;
@@ -7307,6 +7386,64 @@ function validate_tool_manual(manualInput) {
7307
7386
  // src/runtime.ts
7308
7387
  init_web3();
7309
7388
  var CAPABILITY_KEY_RE = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
7389
+ var MINIMUM_JPY_OPERATION_PRICE_CURRENCIES2 = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
7390
+ function pricingPlanFloorIssues(plan, defaultCurrency) {
7391
+ const issues = [];
7392
+ if (plan === void 0 || plan === null) {
7393
+ return issues;
7394
+ }
7395
+ if (typeof plan !== "object" || Array.isArray(plan)) {
7396
+ return ["pricing_plan must be an object when provided"];
7397
+ }
7398
+ const record = plan;
7399
+ const items = record.items;
7400
+ if (items === void 0 || items === null) {
7401
+ return issues;
7402
+ }
7403
+ if (!Array.isArray(items)) {
7404
+ return ["pricing_plan.items must be an array when provided"];
7405
+ }
7406
+ const planCurrency = String(record.currency ?? defaultCurrency ?? "").trim().toUpperCase();
7407
+ const seenKeys = /* @__PURE__ */ new Set();
7408
+ items.forEach((item, index) => {
7409
+ if (typeof item !== "object" || item === null || Array.isArray(item)) {
7410
+ issues.push(`pricing_plan.items[${index}] must be an object`);
7411
+ return;
7412
+ }
7413
+ const itemRecord = item;
7414
+ const itemKey = String(
7415
+ itemRecord.key ?? itemRecord.operation ?? itemRecord.operation_key ?? itemRecord.request_type ?? itemRecord.receipt_code ?? itemRecord.action ?? ""
7416
+ ).trim();
7417
+ if (!itemKey) {
7418
+ issues.push(`pricing_plan.items[${index}].key is required`);
7419
+ } else if (seenKeys.has(itemKey)) {
7420
+ issues.push(`pricing_plan.items[${index}].key duplicates ${itemKey}`);
7421
+ } else {
7422
+ seenKeys.add(itemKey);
7423
+ }
7424
+ const amountRaw = itemRecord.price_minor ?? itemRecord.amount_minor ?? itemRecord.cost_minor ?? itemRecord.value_minor;
7425
+ if (amountRaw === void 0 || amountRaw === null) {
7426
+ issues.push(`pricing_plan.items[${index}].price_minor is required`);
7427
+ return;
7428
+ }
7429
+ const amountMinor = typeof amountRaw === "number" ? amountRaw : typeof amountRaw === "string" && amountRaw.trim() ? Number(amountRaw) : NaN;
7430
+ if (!Number.isInteger(amountMinor)) {
7431
+ issues.push(`pricing_plan.items[${index}].price_minor must be an integer`);
7432
+ return;
7433
+ }
7434
+ if (amountMinor < 0) {
7435
+ issues.push(`pricing_plan.items[${index}].price_minor must be zero or positive`);
7436
+ return;
7437
+ }
7438
+ const currency = String(itemRecord.currency ?? planCurrency ?? defaultCurrency ?? "").trim().toUpperCase();
7439
+ if (MINIMUM_JPY_OPERATION_PRICE_CURRENCIES2.has(currency) && amountMinor > 0 && amountMinor < MINIMUM_JPY_OPERATION_PRICE_MINOR) {
7440
+ issues.push(
7441
+ `pricing_plan.items[${index}].price_minor must be 0 or at least ${MINIMUM_JPY_OPERATION_PRICE_MINOR} for JPY/JPYC operation billing`
7442
+ );
7443
+ }
7444
+ });
7445
+ return issues;
7446
+ }
7310
7447
  function normalizeExecutionResult(result, executionKind) {
7311
7448
  return {
7312
7449
  success: Boolean(result.success),
@@ -7408,6 +7545,10 @@ var AppTestHarness = class {
7408
7545
  if (!manifest.example_prompts || manifest.example_prompts.length === 0) {
7409
7546
  issues.push("at least one example_prompt is recommended");
7410
7547
  }
7548
+ issues.push(...pricingPlanFloorIssues(manifest.pricing_plan, String(manifest.currency ?? "USD")));
7549
+ if ((manifest.price_model === PriceModel.USAGE_BASED || manifest.price_model === PriceModel.PER_ACTION) && (!manifest.pricing_plan || !Array.isArray(manifest.pricing_plan.items) || manifest.pricing_plan.items.length === 0)) {
7550
+ issues.push("pricing_plan.items is required for usage_based/per_action pricing");
7551
+ }
7411
7552
  if (manifest.permission_class === PermissionClass.ACTION || manifest.permission_class === PermissionClass.PAYMENT) {
7412
7553
  if (!manifest.dry_run_supported) {
7413
7554
  issues.push("action/payment apps should support dry_run");
@@ -7483,7 +7624,7 @@ var AppTestHarness = class {
7483
7624
  };
7484
7625
  }
7485
7626
  return {
7486
- experimental: manifest.price_model === PriceModel.USAGE_BASED || manifest.price_model === PriceModel.PER_ACTION,
7627
+ experimental: false,
7487
7628
  usage_record,
7488
7629
  invoice_line_preview
7489
7630
  };
@@ -8909,6 +9050,7 @@ function readEnv(name) {
8909
9050
  }
8910
9051
 
8911
9052
  // src/index.ts
9053
+ init_types();
8912
9054
  init_web3();
8913
9055
  init_webhooks();
8914
9056
  init_utils();