@siglume/api-sdk 0.10.8 → 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/README.md +148 -99
- package/dist/bin/siglume.cjs +232 -334
- package/dist/bin/siglume.cjs.map +1 -1
- package/dist/bin/siglume.js +232 -334
- package/dist/bin/siglume.js.map +1 -1
- package/dist/cli/index.cjs +232 -334
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +24 -67
- package/dist/cli/index.d.ts +24 -67
- package/dist/cli/index.js +232 -334
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +214 -202
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -112
- package/dist/index.d.ts +27 -112
- package/dist/index.js +214 -202
- package/dist/index.js.map +1 -1
- package/package.json +58 -58
package/dist/bin/siglume.js
CHANGED
|
@@ -155,6 +155,61 @@ var init_utils = __esm({
|
|
|
155
155
|
}
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
+
// src/types.ts
|
|
159
|
+
var PermissionClass, ApprovalMode, Environment, PriceModel, AppCategory, MINIMUM_JPY_OPERATION_PRICE_MINOR, ToolManualPermissionClass, SettlementMode;
|
|
160
|
+
var init_types = __esm({
|
|
161
|
+
"src/types.ts"() {
|
|
162
|
+
"use strict";
|
|
163
|
+
PermissionClass = {
|
|
164
|
+
READ_ONLY: "read-only",
|
|
165
|
+
ACTION: "action",
|
|
166
|
+
PAYMENT: "payment",
|
|
167
|
+
/** @deprecated Use READ_ONLY. Behaves identically. */
|
|
168
|
+
RECOMMENDATION: "recommendation"
|
|
169
|
+
};
|
|
170
|
+
ApprovalMode = {
|
|
171
|
+
AUTO: "auto",
|
|
172
|
+
BUDGET_BOUNDED: "budget-bounded",
|
|
173
|
+
ALWAYS_ASK: "always-ask",
|
|
174
|
+
DENY: "deny"
|
|
175
|
+
};
|
|
176
|
+
Environment = {
|
|
177
|
+
SANDBOX: "sandbox",
|
|
178
|
+
LIVE: "live"
|
|
179
|
+
};
|
|
180
|
+
PriceModel = {
|
|
181
|
+
FREE: "free",
|
|
182
|
+
SUBSCRIPTION: "subscription",
|
|
183
|
+
ONE_TIME: "one_time",
|
|
184
|
+
BUNDLE: "bundle",
|
|
185
|
+
USAGE_BASED: "usage_based",
|
|
186
|
+
PER_ACTION: "per_action"
|
|
187
|
+
};
|
|
188
|
+
AppCategory = {
|
|
189
|
+
COMMERCE: "commerce",
|
|
190
|
+
BOOKING: "booking",
|
|
191
|
+
CRM: "crm",
|
|
192
|
+
FINANCE: "finance",
|
|
193
|
+
DOCUMENT: "document",
|
|
194
|
+
COMMUNICATION: "communication",
|
|
195
|
+
MONITORING: "monitoring",
|
|
196
|
+
OTHER: "other"
|
|
197
|
+
};
|
|
198
|
+
MINIMUM_JPY_OPERATION_PRICE_MINOR = 15;
|
|
199
|
+
ToolManualPermissionClass = {
|
|
200
|
+
READ_ONLY: "read_only",
|
|
201
|
+
ACTION: "action",
|
|
202
|
+
PAYMENT: "payment"
|
|
203
|
+
};
|
|
204
|
+
SettlementMode = {
|
|
205
|
+
STRIPE_CHECKOUT: "stripe_checkout",
|
|
206
|
+
STRIPE_PAYMENT_INTENT: "stripe_payment_intent",
|
|
207
|
+
POLYGON_MANDATE: "polygon_mandate",
|
|
208
|
+
EMBEDDED_WALLET_CHARGE: "embedded_wallet_charge"
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
158
213
|
// src/webhooks.ts
|
|
159
214
|
function isRecord2(value) {
|
|
160
215
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -1276,6 +1331,58 @@ function validateSaveDataSchema(schema, fieldName) {
|
|
|
1276
1331
|
}
|
|
1277
1332
|
}
|
|
1278
1333
|
}
|
|
1334
|
+
function validatePricingPlanFloor(plan, defaultCurrency) {
|
|
1335
|
+
if (plan === void 0 || plan === null) {
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
if (!isRecord(plan)) {
|
|
1339
|
+
throw new SiglumeClientError("AppManifest.pricing_plan must be an object when provided.");
|
|
1340
|
+
}
|
|
1341
|
+
const items = plan.items;
|
|
1342
|
+
if (items === void 0 || items === null) {
|
|
1343
|
+
return;
|
|
1344
|
+
}
|
|
1345
|
+
if (!Array.isArray(items)) {
|
|
1346
|
+
throw new SiglumeClientError("AppManifest.pricing_plan.items must be an array when provided.");
|
|
1347
|
+
}
|
|
1348
|
+
const planCurrency = String(plan.currency ?? defaultCurrency ?? "").trim().toUpperCase();
|
|
1349
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
1350
|
+
items.forEach((item, index) => {
|
|
1351
|
+
if (!isRecord(item)) {
|
|
1352
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}] must be an object.`);
|
|
1353
|
+
}
|
|
1354
|
+
const itemKey = String(
|
|
1355
|
+
item.key ?? item.operation ?? item.operation_key ?? item.request_type ?? item.receipt_code ?? item.action ?? ""
|
|
1356
|
+
).trim();
|
|
1357
|
+
if (!itemKey) {
|
|
1358
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].key is required.`);
|
|
1359
|
+
}
|
|
1360
|
+
if (seenKeys.has(itemKey)) {
|
|
1361
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].key duplicates ${itemKey}.`);
|
|
1362
|
+
}
|
|
1363
|
+
seenKeys.add(itemKey);
|
|
1364
|
+
const amountRaw = item.price_minor ?? item.amount_minor ?? item.cost_minor ?? item.value_minor;
|
|
1365
|
+
if (amountRaw === void 0 || amountRaw === null) {
|
|
1366
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].price_minor is required.`);
|
|
1367
|
+
}
|
|
1368
|
+
const amountMinor = typeof amountRaw === "number" ? amountRaw : typeof amountRaw === "string" && amountRaw.trim() ? Number(amountRaw) : NaN;
|
|
1369
|
+
if (!Number.isInteger(amountMinor)) {
|
|
1370
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].price_minor must be an integer.`);
|
|
1371
|
+
}
|
|
1372
|
+
if (amountMinor < 0) {
|
|
1373
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].price_minor must be zero or positive.`);
|
|
1374
|
+
}
|
|
1375
|
+
const currency = String(item.currency ?? planCurrency ?? defaultCurrency ?? "").trim().toUpperCase();
|
|
1376
|
+
if (MINIMUM_JPY_OPERATION_PRICE_CURRENCIES.has(currency) && amountMinor > 0 && amountMinor < MINIMUM_JPY_OPERATION_PRICE_MINOR) {
|
|
1377
|
+
throw new SiglumeClientError(
|
|
1378
|
+
`AppManifest.pricing_plan.items[${index}].price_minor must be 0 or at least ${MINIMUM_JPY_OPERATION_PRICE_MINOR} for JPY/JPYC operation billing.`
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1383
|
+
function pricingPlanHasItems(plan) {
|
|
1384
|
+
return isRecord(plan) && Array.isArray(plan.items) && plan.items.length > 0;
|
|
1385
|
+
}
|
|
1279
1386
|
function buildToolManualQualityReport(payload) {
|
|
1280
1387
|
const qualityBlock = isRecord(payload.quality) ? payload.quality : payload;
|
|
1281
1388
|
const issues = [];
|
|
@@ -1351,6 +1458,7 @@ function buildUrl(baseUrl, path, params) {
|
|
|
1351
1458
|
}
|
|
1352
1459
|
function parseListing(data) {
|
|
1353
1460
|
const metadata = isRecord(data.metadata) ? data.metadata : {};
|
|
1461
|
+
const pricing_plan = isRecord(data.pricing_plan) ? data.pricing_plan : isRecord(metadata.pricing_plan) ? metadata.pricing_plan : null;
|
|
1354
1462
|
const persistence = isRecord(data.persistence) ? data.persistence : isRecord(metadata.persistence) ? metadata.persistence : {};
|
|
1355
1463
|
return {
|
|
1356
1464
|
listing_id: String(data.listing_id ?? data.id ?? ""),
|
|
@@ -1364,6 +1472,7 @@ function parseListing(data) {
|
|
|
1364
1472
|
dry_run_supported: Boolean(data.dry_run_supported ?? false),
|
|
1365
1473
|
price_model: stringOrNull(data.price_model),
|
|
1366
1474
|
price_value_minor: Number(data.price_value_minor ?? 0),
|
|
1475
|
+
pricing_plan,
|
|
1367
1476
|
currency: String(data.currency ?? "USD"),
|
|
1368
1477
|
allow_free_trial: Boolean(data.allow_free_trial ?? false),
|
|
1369
1478
|
free_trial_duration_days: Number(data.free_trial_duration_days ?? 30),
|
|
@@ -1438,18 +1547,6 @@ function parseBundleMember(data) {
|
|
|
1438
1547
|
link_id: stringOrNull(data.link_id)
|
|
1439
1548
|
};
|
|
1440
1549
|
}
|
|
1441
|
-
function parseConnectedAccountLifecycle(data) {
|
|
1442
|
-
return {
|
|
1443
|
-
connected_account_id: String(data.connected_account_id ?? ""),
|
|
1444
|
-
provider_key: String(data.provider_key ?? ""),
|
|
1445
|
-
expires_at: stringOrNull(data.expires_at),
|
|
1446
|
-
scopes: Array.isArray(data.scopes) ? data.scopes.filter((s) => typeof s === "string") : [],
|
|
1447
|
-
refreshed_at: stringOrNull(data.refreshed_at),
|
|
1448
|
-
connection_status: stringOrNull(data.connection_status),
|
|
1449
|
-
provider_revoked: typeof data.provider_revoked === "boolean" ? data.provider_revoked : null,
|
|
1450
|
-
revoked_at: stringOrNull(data.revoked_at)
|
|
1451
|
-
};
|
|
1452
|
-
}
|
|
1453
1550
|
function parseBundle(data) {
|
|
1454
1551
|
const membersRaw = Array.isArray(data.members) ? data.members : [];
|
|
1455
1552
|
return {
|
|
@@ -1528,21 +1625,6 @@ function parseBinding(data) {
|
|
|
1528
1625
|
raw: { ...data }
|
|
1529
1626
|
};
|
|
1530
1627
|
}
|
|
1531
|
-
function parseConnectedAccount(data) {
|
|
1532
|
-
return {
|
|
1533
|
-
connected_account_id: String(data.connected_account_id ?? data.id ?? ""),
|
|
1534
|
-
provider_key: String(data.provider_key ?? ""),
|
|
1535
|
-
account_role: String(data.account_role ?? ""),
|
|
1536
|
-
display_name: stringOrNull(data.display_name),
|
|
1537
|
-
environment: stringOrNull(data.environment),
|
|
1538
|
-
connection_status: stringOrNull(data.connection_status),
|
|
1539
|
-
scopes: Array.isArray(data.scopes) ? data.scopes.filter((item) => typeof item === "string") : [],
|
|
1540
|
-
metadata: toRecord(data.metadata),
|
|
1541
|
-
created_at: stringOrNull(data.created_at),
|
|
1542
|
-
updated_at: stringOrNull(data.updated_at),
|
|
1543
|
-
raw: { ...data }
|
|
1544
|
-
};
|
|
1545
|
-
}
|
|
1546
1628
|
function parseSupportCase(data) {
|
|
1547
1629
|
return {
|
|
1548
1630
|
support_case_id: String(data.support_case_id ?? data.id ?? ""),
|
|
@@ -2488,10 +2570,11 @@ function cloneJsonLike(value) {
|
|
|
2488
2570
|
}
|
|
2489
2571
|
return value;
|
|
2490
2572
|
}
|
|
2491
|
-
var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, CursorPageResult, SiglumeClient;
|
|
2573
|
+
var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, MINIMUM_JPY_OPERATION_PRICE_CURRENCIES, CursorPageResult, SiglumeClient;
|
|
2492
2574
|
var init_client = __esm({
|
|
2493
2575
|
"src/client.ts"() {
|
|
2494
2576
|
"use strict";
|
|
2577
|
+
init_types();
|
|
2495
2578
|
init_errors();
|
|
2496
2579
|
init_webhooks();
|
|
2497
2580
|
init_web3();
|
|
@@ -2499,6 +2582,7 @@ var init_client = __esm({
|
|
|
2499
2582
|
init_utils();
|
|
2500
2583
|
DEFAULT_SIGLUME_API_BASE = "https://siglume.com/v1";
|
|
2501
2584
|
RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
2585
|
+
MINIMUM_JPY_OPERATION_PRICE_CURRENCIES = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
|
|
2502
2586
|
CursorPageResult = class {
|
|
2503
2587
|
items;
|
|
2504
2588
|
next_cursor;
|
|
@@ -2581,13 +2665,6 @@ var init_client = __esm({
|
|
|
2581
2665
|
if (options.runtime_validation) {
|
|
2582
2666
|
payload.runtime_validation = coerceMapping(options.runtime_validation, "runtime_validation");
|
|
2583
2667
|
}
|
|
2584
|
-
if (options.oauth_credentials) {
|
|
2585
|
-
payload.oauth_credentials = Array.isArray(options.oauth_credentials) ? {
|
|
2586
|
-
items: options.oauth_credentials.map(
|
|
2587
|
-
(item, index) => coerceMapping(item, `oauth_credentials[${index}]`)
|
|
2588
|
-
)
|
|
2589
|
-
} : coerceMapping(options.oauth_credentials, "oauth_credentials");
|
|
2590
|
-
}
|
|
2591
2668
|
if (options.source_context) {
|
|
2592
2669
|
payload.source_context = coerceMapping(options.source_context, "source_context");
|
|
2593
2670
|
}
|
|
@@ -2613,6 +2690,7 @@ var init_client = __esm({
|
|
|
2613
2690
|
"jurisdiction",
|
|
2614
2691
|
"price_model",
|
|
2615
2692
|
"price_value_minor",
|
|
2693
|
+
"pricing_plan",
|
|
2616
2694
|
"currency",
|
|
2617
2695
|
"allow_free_trial",
|
|
2618
2696
|
"free_trial_duration_days",
|
|
@@ -2629,6 +2707,9 @@ var init_client = __esm({
|
|
|
2629
2707
|
payload[fieldName] = value;
|
|
2630
2708
|
}
|
|
2631
2709
|
}
|
|
2710
|
+
if (payload.pricing_plan !== void 0 && (typeof payload.pricing_plan !== "object" || Array.isArray(payload.pricing_plan))) {
|
|
2711
|
+
throw new SiglumeClientError("AppManifest.pricing_plan must be an object when provided.");
|
|
2712
|
+
}
|
|
2632
2713
|
if (payload.store_vertical === void 0 || payload.store_vertical === null) {
|
|
2633
2714
|
throw new SiglumeClientError(
|
|
2634
2715
|
"AppManifest.store_vertical is required. Choose 'api' for normal API Store listings or 'game' for API games."
|
|
@@ -2644,6 +2725,13 @@ var init_client = __esm({
|
|
|
2644
2725
|
throw new SiglumeClientError(`AppManifest.currency must be 'USD' or 'JPY'. Got ${String(payload.currency)}.`);
|
|
2645
2726
|
}
|
|
2646
2727
|
payload.currency = currency;
|
|
2728
|
+
if (payload.pricing_plan !== void 0) {
|
|
2729
|
+
validatePricingPlanFloor(payload.pricing_plan, currency);
|
|
2730
|
+
}
|
|
2731
|
+
const priceModel = String(payload.price_model ?? "free").trim().toLowerCase();
|
|
2732
|
+
if ((priceModel === "usage_based" || priceModel === "per_action") && !pricingPlanHasItems(payload.pricing_plan)) {
|
|
2733
|
+
throw new SiglumeClientError("AppManifest.pricing_plan.items is required for usage_based/per_action pricing.");
|
|
2734
|
+
}
|
|
2647
2735
|
if (payload.allow_free_trial === void 0 || payload.allow_free_trial === null) {
|
|
2648
2736
|
throw new SiglumeClientError(
|
|
2649
2737
|
"AppManifest.allow_free_trial is required. Pass true to offer a Plus/Pro buyer free trial or false to disable trials."
|
|
@@ -2717,7 +2805,6 @@ var init_client = __esm({
|
|
|
2717
2805
|
auto_manifest: toRecord(data.auto_manifest),
|
|
2718
2806
|
confidence: toRecord(data.confidence),
|
|
2719
2807
|
validation_report: toRecord(data.validation_report),
|
|
2720
|
-
oauth_status: toRecord(data.oauth_status),
|
|
2721
2808
|
review_url: stringOrNull(data.review_url),
|
|
2722
2809
|
trace_id: meta.trace_id,
|
|
2723
2810
|
request_id: meta.request_id
|
|
@@ -2893,66 +2980,9 @@ var init_client = __esm({
|
|
|
2893
2980
|
return parseBundle(data);
|
|
2894
2981
|
}
|
|
2895
2982
|
// ----- end bundles -------------------------------------------------------
|
|
2896
|
-
// ----- Connected accounts
|
|
2897
|
-
//
|
|
2898
|
-
|
|
2899
|
-
const body = {
|
|
2900
|
-
listing_id: input.listing_id,
|
|
2901
|
-
redirect_uri: input.redirect_uri
|
|
2902
|
-
};
|
|
2903
|
-
if (input.scopes !== void 0) body.scopes = input.scopes;
|
|
2904
|
-
if (input.account_role !== void 0) body.account_role = input.account_role;
|
|
2905
|
-
const [data] = await this.request("POST", "/me/connected-accounts/oauth/authorize", {
|
|
2906
|
-
json_body: body
|
|
2907
|
-
});
|
|
2908
|
-
return {
|
|
2909
|
-
authorize_url: String(data.authorize_url ?? ""),
|
|
2910
|
-
state: String(data.state ?? ""),
|
|
2911
|
-
provider_key: String(data.provider_key ?? ""),
|
|
2912
|
-
scopes: Array.isArray(data.scopes) ? data.scopes.filter((s) => typeof s === "string") : [],
|
|
2913
|
-
pkce_method: stringOrNull(data.pkce_method)
|
|
2914
|
-
};
|
|
2915
|
-
}
|
|
2916
|
-
async complete_connected_account_oauth(input) {
|
|
2917
|
-
const [data] = await this.request("POST", "/me/connected-accounts/oauth/callback", {
|
|
2918
|
-
json_body: { state: input.state, code: input.code }
|
|
2919
|
-
});
|
|
2920
|
-
return { ...data };
|
|
2921
|
-
}
|
|
2922
|
-
async refresh_connected_account(account_id) {
|
|
2923
|
-
const [data] = await this.request("POST", `/me/connected-accounts/${account_id}/refresh`);
|
|
2924
|
-
return parseConnectedAccountLifecycle(data);
|
|
2925
|
-
}
|
|
2926
|
-
async revoke_connected_account(account_id) {
|
|
2927
|
-
const [data] = await this.request("POST", `/me/connected-accounts/${account_id}/revoke`);
|
|
2928
|
-
return parseConnectedAccountLifecycle(data);
|
|
2929
|
-
}
|
|
2930
|
-
async set_listing_oauth_credentials(listing_id, input) {
|
|
2931
|
-
const body = {
|
|
2932
|
-
provider_key: input.provider_key,
|
|
2933
|
-
client_id: input.client_id,
|
|
2934
|
-
client_secret: input.client_secret,
|
|
2935
|
-
authorize_url: input.authorize_url,
|
|
2936
|
-
token_url: input.token_url
|
|
2937
|
-
};
|
|
2938
|
-
if (input.revoke_url !== void 0) body.revoke_url = input.revoke_url;
|
|
2939
|
-
if (input.display_name !== void 0) body.display_name = input.display_name;
|
|
2940
|
-
if (input.scope_separator !== void 0) body.scope_separator = input.scope_separator;
|
|
2941
|
-
if (input.token_endpoint_auth !== void 0) body.token_endpoint_auth = input.token_endpoint_auth;
|
|
2942
|
-
if (input.pkce_required !== void 0) body.pkce_required = input.pkce_required;
|
|
2943
|
-
if (input.refresh_supported !== void 0) body.refresh_supported = input.refresh_supported;
|
|
2944
|
-
if (input.available_scopes !== void 0) body.available_scopes = input.available_scopes;
|
|
2945
|
-
if (input.required_scopes !== void 0) body.required_scopes = input.required_scopes;
|
|
2946
|
-
const [data] = await this.request("PUT", `/market/capabilities/${listing_id}/oauth-credentials`, {
|
|
2947
|
-
json_body: body
|
|
2948
|
-
});
|
|
2949
|
-
return { ...data };
|
|
2950
|
-
}
|
|
2951
|
-
async get_listing_oauth_credentials_status(listing_id) {
|
|
2952
|
-
const [data] = await this.request("GET", `/market/capabilities/${listing_id}/oauth-credentials`);
|
|
2953
|
-
return { ...data };
|
|
2954
|
-
}
|
|
2955
|
-
// ----- end connected accounts --------------------------------------------
|
|
2983
|
+
// ----- Connected accounts ------------------------------------------------
|
|
2984
|
+
// Architecture B: publisher APIs own external OAuth and token storage.
|
|
2985
|
+
// The SDK no longer exposes platform OAuth or listing credential APIs.
|
|
2956
2986
|
async get_developer_portal() {
|
|
2957
2987
|
const [data, meta] = await this.request("GET", "/market/developer/portal");
|
|
2958
2988
|
return {
|
|
@@ -2985,7 +3015,6 @@ var init_client = __esm({
|
|
|
2985
3015
|
dry_run_supported: Boolean(data.dry_run_supported ?? false),
|
|
2986
3016
|
approval_mode: stringOrNull(data.approval_mode),
|
|
2987
3017
|
required_connected_accounts: Array.isArray(data.required_connected_accounts) ? data.required_connected_accounts : [],
|
|
2988
|
-
connected_accounts: Array.isArray(data.connected_accounts) ? data.connected_accounts.filter((item) => isRecord(item)).map((item) => ({ ...item })) : [],
|
|
2989
3018
|
stub_providers_enabled: Boolean(data.stub_providers_enabled ?? false),
|
|
2990
3019
|
simulated_receipts: Boolean(data.simulated_receipts ?? false),
|
|
2991
3020
|
approval_simulator: Boolean(data.approval_simulator ?? false),
|
|
@@ -4283,25 +4312,6 @@ var init_client = __esm({
|
|
|
4283
4312
|
raw: { ...data }
|
|
4284
4313
|
};
|
|
4285
4314
|
}
|
|
4286
|
-
async list_connected_accounts(options = {}) {
|
|
4287
|
-
const params = {
|
|
4288
|
-
provider_key: options.provider_key,
|
|
4289
|
-
environment: options.environment,
|
|
4290
|
-
limit: Math.max(1, Math.min(Math.trunc(options.limit ?? 50), 100)),
|
|
4291
|
-
cursor: options.cursor
|
|
4292
|
-
};
|
|
4293
|
-
const [data, meta] = await this.request("GET", "/market/connected-accounts", { params });
|
|
4294
|
-
const items = Array.isArray(data.items) ? data.items.filter((item) => isRecord(item)).map(parseConnectedAccount) : [];
|
|
4295
|
-
const next_cursor = stringOrNull(data.next_cursor);
|
|
4296
|
-
return new CursorPageResult({
|
|
4297
|
-
items,
|
|
4298
|
-
next_cursor,
|
|
4299
|
-
limit: typeof data.limit === "number" ? data.limit : params.limit,
|
|
4300
|
-
offset: typeof data.offset === "number" ? data.offset : null,
|
|
4301
|
-
meta,
|
|
4302
|
-
fetchNext: next_cursor ? (cursor) => this.list_connected_accounts({ ...options, cursor }) : void 0
|
|
4303
|
-
});
|
|
4304
|
-
}
|
|
4305
4315
|
async create_support_case(subject, body, options = {}) {
|
|
4306
4316
|
const summary = subject.trim();
|
|
4307
4317
|
const details = body.trim();
|
|
@@ -5396,53 +5406,8 @@ function stableValue(value) {
|
|
|
5396
5406
|
return value;
|
|
5397
5407
|
}
|
|
5398
5408
|
|
|
5399
|
-
// src/
|
|
5400
|
-
|
|
5401
|
-
READ_ONLY: "read-only",
|
|
5402
|
-
ACTION: "action",
|
|
5403
|
-
PAYMENT: "payment",
|
|
5404
|
-
/** @deprecated Use READ_ONLY. Behaves identically. */
|
|
5405
|
-
RECOMMENDATION: "recommendation"
|
|
5406
|
-
};
|
|
5407
|
-
var ApprovalMode = {
|
|
5408
|
-
AUTO: "auto",
|
|
5409
|
-
BUDGET_BOUNDED: "budget-bounded",
|
|
5410
|
-
ALWAYS_ASK: "always-ask",
|
|
5411
|
-
DENY: "deny"
|
|
5412
|
-
};
|
|
5413
|
-
var Environment = {
|
|
5414
|
-
SANDBOX: "sandbox",
|
|
5415
|
-
LIVE: "live"
|
|
5416
|
-
};
|
|
5417
|
-
var PriceModel = {
|
|
5418
|
-
FREE: "free",
|
|
5419
|
-
SUBSCRIPTION: "subscription",
|
|
5420
|
-
ONE_TIME: "one_time",
|
|
5421
|
-
BUNDLE: "bundle",
|
|
5422
|
-
USAGE_BASED: "usage_based",
|
|
5423
|
-
PER_ACTION: "per_action"
|
|
5424
|
-
};
|
|
5425
|
-
var AppCategory = {
|
|
5426
|
-
COMMERCE: "commerce",
|
|
5427
|
-
BOOKING: "booking",
|
|
5428
|
-
CRM: "crm",
|
|
5429
|
-
FINANCE: "finance",
|
|
5430
|
-
DOCUMENT: "document",
|
|
5431
|
-
COMMUNICATION: "communication",
|
|
5432
|
-
MONITORING: "monitoring",
|
|
5433
|
-
OTHER: "other"
|
|
5434
|
-
};
|
|
5435
|
-
var ToolManualPermissionClass = {
|
|
5436
|
-
READ_ONLY: "read_only",
|
|
5437
|
-
ACTION: "action",
|
|
5438
|
-
PAYMENT: "payment"
|
|
5439
|
-
};
|
|
5440
|
-
var SettlementMode = {
|
|
5441
|
-
STRIPE_CHECKOUT: "stripe_checkout",
|
|
5442
|
-
STRIPE_PAYMENT_INTENT: "stripe_payment_intent",
|
|
5443
|
-
POLYGON_MANDATE: "polygon_mandate",
|
|
5444
|
-
EMBEDDED_WALLET_CHARGE: "embedded_wallet_charge"
|
|
5445
|
-
};
|
|
5409
|
+
// src/runtime.ts
|
|
5410
|
+
init_types();
|
|
5446
5411
|
|
|
5447
5412
|
// src/testing/recorder.ts
|
|
5448
5413
|
var CASSETTE_VERSION = 1;
|
|
@@ -5834,6 +5799,7 @@ Actual: ${requestSignature(requestRecord, ignoreBodyFields)}`
|
|
|
5834
5799
|
};
|
|
5835
5800
|
|
|
5836
5801
|
// src/tool-manual-validator.ts
|
|
5802
|
+
init_types();
|
|
5837
5803
|
init_utils();
|
|
5838
5804
|
var JURISDICTION_PATTERN = /^[A-Z]{2}(-[A-Z0-9]{1,3})?$/;
|
|
5839
5805
|
var TOOL_NAME_RE = /^[A-Za-z0-9_]{3,64}$/;
|
|
@@ -6105,6 +6071,64 @@ function validate_tool_manual(manualInput) {
|
|
|
6105
6071
|
// src/runtime.ts
|
|
6106
6072
|
init_web3();
|
|
6107
6073
|
var CAPABILITY_KEY_RE = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
|
|
6074
|
+
var MINIMUM_JPY_OPERATION_PRICE_CURRENCIES2 = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
|
|
6075
|
+
function pricingPlanFloorIssues(plan, defaultCurrency) {
|
|
6076
|
+
const issues = [];
|
|
6077
|
+
if (plan === void 0 || plan === null) {
|
|
6078
|
+
return issues;
|
|
6079
|
+
}
|
|
6080
|
+
if (typeof plan !== "object" || Array.isArray(plan)) {
|
|
6081
|
+
return ["pricing_plan must be an object when provided"];
|
|
6082
|
+
}
|
|
6083
|
+
const record = plan;
|
|
6084
|
+
const items = record.items;
|
|
6085
|
+
if (items === void 0 || items === null) {
|
|
6086
|
+
return issues;
|
|
6087
|
+
}
|
|
6088
|
+
if (!Array.isArray(items)) {
|
|
6089
|
+
return ["pricing_plan.items must be an array when provided"];
|
|
6090
|
+
}
|
|
6091
|
+
const planCurrency = String(record.currency ?? defaultCurrency ?? "").trim().toUpperCase();
|
|
6092
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
6093
|
+
items.forEach((item, index) => {
|
|
6094
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) {
|
|
6095
|
+
issues.push(`pricing_plan.items[${index}] must be an object`);
|
|
6096
|
+
return;
|
|
6097
|
+
}
|
|
6098
|
+
const itemRecord = item;
|
|
6099
|
+
const itemKey = String(
|
|
6100
|
+
itemRecord.key ?? itemRecord.operation ?? itemRecord.operation_key ?? itemRecord.request_type ?? itemRecord.receipt_code ?? itemRecord.action ?? ""
|
|
6101
|
+
).trim();
|
|
6102
|
+
if (!itemKey) {
|
|
6103
|
+
issues.push(`pricing_plan.items[${index}].key is required`);
|
|
6104
|
+
} else if (seenKeys.has(itemKey)) {
|
|
6105
|
+
issues.push(`pricing_plan.items[${index}].key duplicates ${itemKey}`);
|
|
6106
|
+
} else {
|
|
6107
|
+
seenKeys.add(itemKey);
|
|
6108
|
+
}
|
|
6109
|
+
const amountRaw = itemRecord.price_minor ?? itemRecord.amount_minor ?? itemRecord.cost_minor ?? itemRecord.value_minor;
|
|
6110
|
+
if (amountRaw === void 0 || amountRaw === null) {
|
|
6111
|
+
issues.push(`pricing_plan.items[${index}].price_minor is required`);
|
|
6112
|
+
return;
|
|
6113
|
+
}
|
|
6114
|
+
const amountMinor = typeof amountRaw === "number" ? amountRaw : typeof amountRaw === "string" && amountRaw.trim() ? Number(amountRaw) : NaN;
|
|
6115
|
+
if (!Number.isInteger(amountMinor)) {
|
|
6116
|
+
issues.push(`pricing_plan.items[${index}].price_minor must be an integer`);
|
|
6117
|
+
return;
|
|
6118
|
+
}
|
|
6119
|
+
if (amountMinor < 0) {
|
|
6120
|
+
issues.push(`pricing_plan.items[${index}].price_minor must be zero or positive`);
|
|
6121
|
+
return;
|
|
6122
|
+
}
|
|
6123
|
+
const currency = String(itemRecord.currency ?? planCurrency ?? defaultCurrency ?? "").trim().toUpperCase();
|
|
6124
|
+
if (MINIMUM_JPY_OPERATION_PRICE_CURRENCIES2.has(currency) && amountMinor > 0 && amountMinor < MINIMUM_JPY_OPERATION_PRICE_MINOR) {
|
|
6125
|
+
issues.push(
|
|
6126
|
+
`pricing_plan.items[${index}].price_minor must be 0 or at least ${MINIMUM_JPY_OPERATION_PRICE_MINOR} for JPY/JPYC operation billing`
|
|
6127
|
+
);
|
|
6128
|
+
}
|
|
6129
|
+
});
|
|
6130
|
+
return issues;
|
|
6131
|
+
}
|
|
6108
6132
|
function normalizeExecutionResult(result, executionKind) {
|
|
6109
6133
|
return {
|
|
6110
6134
|
success: Boolean(result.success),
|
|
@@ -6145,24 +6169,12 @@ var AppTestHarness = class {
|
|
|
6145
6169
|
this.stubs = stubs;
|
|
6146
6170
|
}
|
|
6147
6171
|
async executeWithKind(execution_kind, task_type = "default", options = {}) {
|
|
6148
|
-
const connected_accounts = options.connected_accounts ?? Object.fromEntries(
|
|
6149
|
-
Object.keys(this.stubs).map((key) => [
|
|
6150
|
-
key,
|
|
6151
|
-
{
|
|
6152
|
-
provider_key: key,
|
|
6153
|
-
session_token: `stub-token-${key}`,
|
|
6154
|
-
environment: Environment.SANDBOX,
|
|
6155
|
-
scopes: []
|
|
6156
|
-
}
|
|
6157
|
-
])
|
|
6158
|
-
);
|
|
6159
6172
|
const ctx = {
|
|
6160
6173
|
agent_id: "test-agent-001",
|
|
6161
6174
|
owner_user_id: "test-owner-001",
|
|
6162
6175
|
task_type,
|
|
6163
6176
|
environment: Environment.SANDBOX,
|
|
6164
6177
|
execution_kind,
|
|
6165
|
-
connected_accounts,
|
|
6166
6178
|
input_params: options.input_params ?? {},
|
|
6167
6179
|
trace_id: options.trace_id,
|
|
6168
6180
|
idempotency_key: options.idempotency_key,
|
|
@@ -6204,6 +6216,10 @@ var AppTestHarness = class {
|
|
|
6204
6216
|
if (!manifest.example_prompts || manifest.example_prompts.length === 0) {
|
|
6205
6217
|
issues.push("at least one example_prompt is recommended");
|
|
6206
6218
|
}
|
|
6219
|
+
issues.push(...pricingPlanFloorIssues(manifest.pricing_plan, String(manifest.currency ?? "USD")));
|
|
6220
|
+
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)) {
|
|
6221
|
+
issues.push("pricing_plan.items is required for usage_based/per_action pricing");
|
|
6222
|
+
}
|
|
6207
6223
|
if (manifest.permission_class === PermissionClass.ACTION || manifest.permission_class === PermissionClass.PAYMENT) {
|
|
6208
6224
|
if (!manifest.dry_run_supported) {
|
|
6209
6225
|
issues.push("action/payment apps should support dry_run");
|
|
@@ -6252,12 +6268,6 @@ var AppTestHarness = class {
|
|
|
6252
6268
|
}
|
|
6253
6269
|
return issues;
|
|
6254
6270
|
}
|
|
6255
|
-
async simulate_connected_account_missing(task_type = "default", options = {}) {
|
|
6256
|
-
return this.executeWithKind("dry_run", task_type, {
|
|
6257
|
-
...options,
|
|
6258
|
-
connected_accounts: {}
|
|
6259
|
-
});
|
|
6260
|
-
}
|
|
6261
6271
|
async simulate_metering(record, options = {}) {
|
|
6262
6272
|
const { normalizeUsageRecord: normalizeUsageRecord2 } = await Promise.resolve().then(() => (init_metering(), metering_exports));
|
|
6263
6273
|
const manifest = await this.app.manifest();
|
|
@@ -6285,7 +6295,7 @@ var AppTestHarness = class {
|
|
|
6285
6295
|
};
|
|
6286
6296
|
}
|
|
6287
6297
|
return {
|
|
6288
|
-
experimental:
|
|
6298
|
+
experimental: false,
|
|
6289
6299
|
usage_record,
|
|
6290
6300
|
invoice_line_preview
|
|
6291
6301
|
};
|
|
@@ -7220,15 +7230,6 @@ async function loadProject(path = ".") {
|
|
|
7220
7230
|
const tool_manual = tool_manual_path ? JSON.parse(await readFile(tool_manual_path, "utf8")) : buildToolManualTemplate(manifest);
|
|
7221
7231
|
const runtime_validation_path = await findRuntimeValidationPath(root_dir);
|
|
7222
7232
|
const runtime_validation = runtime_validation_path ? await loadJsonObject(runtime_validation_path, "runtime_validation") : void 0;
|
|
7223
|
-
const oauth_credentials_path = await findOauthCredentialsPath(root_dir);
|
|
7224
|
-
let oauth_credentials;
|
|
7225
|
-
if (oauth_credentials_path) {
|
|
7226
|
-
const parsed = JSON.parse(await readFile(oauth_credentials_path, "utf8"));
|
|
7227
|
-
if (!isRecord(parsed) && !Array.isArray(parsed)) {
|
|
7228
|
-
throw new SiglumeProjectError("oauth_credentials must be a JSON object or array");
|
|
7229
|
-
}
|
|
7230
|
-
oauth_credentials = parsed;
|
|
7231
|
-
}
|
|
7232
7233
|
return {
|
|
7233
7234
|
root_dir,
|
|
7234
7235
|
adapter_path,
|
|
@@ -7237,9 +7238,7 @@ async function loadProject(path = ".") {
|
|
|
7237
7238
|
tool_manual_path: tool_manual_path ?? void 0,
|
|
7238
7239
|
tool_manual,
|
|
7239
7240
|
runtime_validation_path: runtime_validation_path ?? void 0,
|
|
7240
|
-
runtime_validation
|
|
7241
|
-
oauth_credentials_path: oauth_credentials_path ?? void 0,
|
|
7242
|
-
oauth_credentials
|
|
7241
|
+
runtime_validation
|
|
7243
7242
|
};
|
|
7244
7243
|
}
|
|
7245
7244
|
function isPlatformManagedRequirement(value) {
|
|
@@ -7277,6 +7276,21 @@ function requiredOauthProviders(requirements) {
|
|
|
7277
7276
|
}
|
|
7278
7277
|
return providers;
|
|
7279
7278
|
}
|
|
7279
|
+
function apiManagedRequirementsMissingConnectUrl(requirements) {
|
|
7280
|
+
const missing = [];
|
|
7281
|
+
for (const item of requirements ?? []) {
|
|
7282
|
+
if (!isRecord(item)) continue;
|
|
7283
|
+
const managedBy = String(item.managed_by ?? "").trim().toLowerCase().replaceAll("_", "-");
|
|
7284
|
+
if (managedBy !== "api") continue;
|
|
7285
|
+
const connectUrl = String(item.connect_url ?? "").trim();
|
|
7286
|
+
if (connectUrl) continue;
|
|
7287
|
+
const label = oauthProviderKeyFromRequirement(item) ?? "(missing provider_key)";
|
|
7288
|
+
if (!missing.includes(label)) {
|
|
7289
|
+
missing.push(label);
|
|
7290
|
+
}
|
|
7291
|
+
}
|
|
7292
|
+
return missing;
|
|
7293
|
+
}
|
|
7280
7294
|
function connectedAccountRequirementLabel(value) {
|
|
7281
7295
|
if (isRecord(value)) {
|
|
7282
7296
|
for (const key of ["provider_key", "provider", "account_type", "name"]) {
|
|
@@ -7287,102 +7301,6 @@ function connectedAccountRequirementLabel(value) {
|
|
|
7287
7301
|
}
|
|
7288
7302
|
return String(value ?? "").trim();
|
|
7289
7303
|
}
|
|
7290
|
-
function oauthProviderRecordsMap(payload) {
|
|
7291
|
-
if (!payload) {
|
|
7292
|
-
return {};
|
|
7293
|
-
}
|
|
7294
|
-
const items = Array.isArray(payload) ? payload : Array.isArray(payload.items) ? payload.items : [payload];
|
|
7295
|
-
const resolved = {};
|
|
7296
|
-
for (const [index, item] of items.entries()) {
|
|
7297
|
-
if (!isRecord(item)) {
|
|
7298
|
-
throw new SiglumeProjectError(`oauth_credentials[${index}] must be a JSON object.`);
|
|
7299
|
-
}
|
|
7300
|
-
const providerKey = oauthProviderKeyFromRequirement(item.provider_key ?? item.provider);
|
|
7301
|
-
if (!providerKey) {
|
|
7302
|
-
throw new SiglumeProjectError(`oauth_credentials[${index}].provider_key is required.`);
|
|
7303
|
-
}
|
|
7304
|
-
const authorizeUrl = String(item.authorize_url ?? item.authorization_url ?? item.auth_url ?? "").trim();
|
|
7305
|
-
const tokenUrl = String(item.token_url ?? "").trim();
|
|
7306
|
-
if (!authorizeUrl || !tokenUrl) {
|
|
7307
|
-
throw new SiglumeProjectError(
|
|
7308
|
-
`oauth_credentials[${index}] must include authorize_url and token_url.`
|
|
7309
|
-
);
|
|
7310
|
-
}
|
|
7311
|
-
for (const [urlKey, urlValue] of Object.entries({
|
|
7312
|
-
authorize_url: authorizeUrl,
|
|
7313
|
-
token_url: tokenUrl,
|
|
7314
|
-
revoke_url: String(item.revoke_url ?? "").trim()
|
|
7315
|
-
})) {
|
|
7316
|
-
if (urlValue && !urlValue.startsWith("https://")) {
|
|
7317
|
-
throw new SiglumeProjectError(`oauth_credentials[${index}].${urlKey} must be an https URL.`);
|
|
7318
|
-
}
|
|
7319
|
-
}
|
|
7320
|
-
const clientId = String(item.client_id ?? "").trim();
|
|
7321
|
-
const clientSecret = String(item.client_secret ?? "").trim();
|
|
7322
|
-
if (!clientId || !clientSecret) {
|
|
7323
|
-
throw new SiglumeProjectError(`oauth_credentials[${index}] must include client_id and client_secret.`);
|
|
7324
|
-
}
|
|
7325
|
-
const rawScopes = item.required_scopes ?? item.scopes;
|
|
7326
|
-
let scopes = [];
|
|
7327
|
-
if (rawScopes == null) {
|
|
7328
|
-
scopes = [];
|
|
7329
|
-
} else if (!Array.isArray(rawScopes)) {
|
|
7330
|
-
throw new SiglumeProjectError(`oauth_credentials[${index}].required_scopes must be a JSON array.`);
|
|
7331
|
-
} else {
|
|
7332
|
-
scopes = rawScopes.map((scope) => String(scope ?? "").trim()).filter(Boolean);
|
|
7333
|
-
}
|
|
7334
|
-
const record = {
|
|
7335
|
-
provider_key: providerKey,
|
|
7336
|
-
client_id: clientId,
|
|
7337
|
-
client_secret: clientSecret,
|
|
7338
|
-
required_scopes: scopes
|
|
7339
|
-
};
|
|
7340
|
-
for (const [key, value] of Object.entries({
|
|
7341
|
-
authorize_url: authorizeUrl,
|
|
7342
|
-
token_url: tokenUrl,
|
|
7343
|
-
revoke_url: String(item.revoke_url ?? "").trim(),
|
|
7344
|
-
display_name: String(item.display_name ?? "").trim(),
|
|
7345
|
-
scope_separator: String(item.scope_separator ?? "").trim(),
|
|
7346
|
-
token_endpoint_auth: String(item.token_endpoint_auth ?? "").trim()
|
|
7347
|
-
})) {
|
|
7348
|
-
if (value) record[key] = value;
|
|
7349
|
-
}
|
|
7350
|
-
for (const key of ["pkce_required", "refresh_supported"]) {
|
|
7351
|
-
if (typeof item[key] === "boolean") record[key] = item[key];
|
|
7352
|
-
}
|
|
7353
|
-
if (Array.isArray(item.available_scopes)) {
|
|
7354
|
-
const availableScopes = item.available_scopes.map((scope) => String(scope ?? "").trim()).filter(Boolean);
|
|
7355
|
-
if (availableScopes.length > 0) record.available_scopes = availableScopes;
|
|
7356
|
-
}
|
|
7357
|
-
resolved[providerKey] = record;
|
|
7358
|
-
}
|
|
7359
|
-
return resolved;
|
|
7360
|
-
}
|
|
7361
|
-
function canonicalOauthCredentialsPayload(payload) {
|
|
7362
|
-
const records = oauthProviderRecordsMap(payload);
|
|
7363
|
-
const providerKeys = Object.keys(records).sort();
|
|
7364
|
-
if (providerKeys.length === 0) {
|
|
7365
|
-
return void 0;
|
|
7366
|
-
}
|
|
7367
|
-
return {
|
|
7368
|
-
items: providerKeys.map((providerKey) => records[providerKey])
|
|
7369
|
-
};
|
|
7370
|
-
}
|
|
7371
|
-
function ensureRequiredOauthCredentials(project) {
|
|
7372
|
-
const requiredProviders = requiredOauthProviders(project.manifest.required_connected_accounts ?? []);
|
|
7373
|
-
if (requiredProviders.length === 0) {
|
|
7374
|
-
return;
|
|
7375
|
-
}
|
|
7376
|
-
const provided = new Set(Object.keys(oauthProviderRecordsMap(project.oauth_credentials)));
|
|
7377
|
-
const missing = requiredProviders.filter((provider) => !provided.has(provider));
|
|
7378
|
-
if (missing.length === 0) {
|
|
7379
|
-
return;
|
|
7380
|
-
}
|
|
7381
|
-
const path = project.oauth_credentials_path ?? join(project.root_dir, "oauth_credentials.json");
|
|
7382
|
-
throw new SiglumeProjectError(
|
|
7383
|
-
`${path} is required for platform-managed OAuth APIs. Missing provider seeds: ${missing.join(", ")}`
|
|
7384
|
-
);
|
|
7385
|
-
}
|
|
7386
7304
|
async function validateProject(path = ".", deps = {}) {
|
|
7387
7305
|
const project = await loadProject(path);
|
|
7388
7306
|
const manifest_issues = await projectValidationIssues(project);
|
|
@@ -7537,10 +7455,21 @@ function ensureExplicitToolManual(project) {
|
|
|
7537
7455
|
async function registrationPreflight(project, client) {
|
|
7538
7456
|
const manifestIssues = await projectValidationIssues(project);
|
|
7539
7457
|
const [toolManualValid, toolManualIssues] = validate_tool_manual(project.tool_manual);
|
|
7458
|
+
const retiredPlatformOauthProviders = requiredOauthProviders(project.manifest.required_connected_accounts ?? []);
|
|
7459
|
+
if (retiredPlatformOauthProviders.length > 0) {
|
|
7460
|
+
throw new SiglumeProjectError(
|
|
7461
|
+
`Registration preflight failed. Fix these before calling auto-register:
|
|
7462
|
+
- platform-managed OAuth is retired. Use managed_by="api" with connect_url: ${retiredPlatformOauthProviders.join(", ")}`
|
|
7463
|
+
);
|
|
7464
|
+
}
|
|
7465
|
+
const apiManagedMissingConnectUrl = apiManagedRequirementsMissingConnectUrl(project.manifest.required_connected_accounts ?? []);
|
|
7466
|
+
if (apiManagedMissingConnectUrl.length > 0) {
|
|
7467
|
+
throw new SiglumeProjectError(
|
|
7468
|
+
`Registration preflight failed. Fix these before calling auto-register:
|
|
7469
|
+
- API-managed OAuth requirements must include connect_url: ${apiManagedMissingConnectUrl.join(", ")}`
|
|
7470
|
+
);
|
|
7471
|
+
}
|
|
7540
7472
|
const remoteQuality = await client.preview_quality_score(project.tool_manual);
|
|
7541
|
-
const requiredOauthProvidersList = requiredOauthProviders(project.manifest.required_connected_accounts ?? []);
|
|
7542
|
-
const oauthProviderRecords = oauthProviderRecordsMap(project.oauth_credentials);
|
|
7543
|
-
const missingOauthProviders = requiredOauthProvidersList.filter((provider) => !oauthProviderRecords[provider]);
|
|
7544
7473
|
const blockingToolManualIssues = toolManualIssues.filter((issue2) => issue2.severity === "error");
|
|
7545
7474
|
const errors = [
|
|
7546
7475
|
...manifestIssues.map((issue2) => String(issue2)),
|
|
@@ -7552,17 +7481,12 @@ async function registrationPreflight(project, client) {
|
|
|
7552
7481
|
if (!remoteQualityOk(remoteQuality)) {
|
|
7553
7482
|
errors.push(`remote Tool Manual quality is not publishable: ${remoteQuality.grade} (${remoteQuality.overall_score}/100)`);
|
|
7554
7483
|
}
|
|
7555
|
-
if (missingOauthProviders.length > 0) {
|
|
7556
|
-
errors.push(`oauth_credentials.json is required for platform-managed OAuth APIs: ${missingOauthProviders.join(", ")}`);
|
|
7557
|
-
}
|
|
7558
7484
|
const preflight = {
|
|
7559
7485
|
manifest_issues: manifestIssues,
|
|
7560
7486
|
tool_manual_valid: toolManualValid,
|
|
7561
7487
|
tool_manual_issues: toolManualIssues.map((issue2) => toJsonable(issue2)),
|
|
7562
7488
|
remote_quality: toJsonable(remoteQuality),
|
|
7563
|
-
|
|
7564
|
-
oauth_credentials_path: project.oauth_credentials_path ?? null,
|
|
7565
|
-
oauth_missing_providers: missingOauthProviders,
|
|
7489
|
+
retired_platform_oauth_providers: retiredPlatformOauthProviders,
|
|
7566
7490
|
ok: errors.length === 0
|
|
7567
7491
|
};
|
|
7568
7492
|
if (errors.length > 0) {
|
|
@@ -7601,8 +7525,6 @@ async function runRegistration(path = ".", options = {}, deps = {}) {
|
|
|
7601
7525
|
ensureExplicitToolManual(project);
|
|
7602
7526
|
ensureManifestPublisherIdentity(project);
|
|
7603
7527
|
ensureRuntimeValidationReady(project);
|
|
7604
|
-
ensureRequiredOauthCredentials(project);
|
|
7605
|
-
const canonicalOauthCredentials = canonicalOauthCredentialsPayload(project.oauth_credentials);
|
|
7606
7528
|
const client = await createClient(deps);
|
|
7607
7529
|
if (requestedCompanySlug) {
|
|
7608
7530
|
const slug = companyNameSlug(requestedCompanySlug);
|
|
@@ -7679,14 +7601,12 @@ async function runRegistration(path = ".", options = {}, deps = {}) {
|
|
|
7679
7601
|
}
|
|
7680
7602
|
}
|
|
7681
7603
|
const receipt = await client.auto_register(project.manifest, project.tool_manual, {
|
|
7682
|
-
runtime_validation: project.runtime_validation
|
|
7683
|
-
oauth_credentials: canonicalOauthCredentials
|
|
7604
|
+
runtime_validation: project.runtime_validation
|
|
7684
7605
|
});
|
|
7685
7606
|
const result = {
|
|
7686
7607
|
receipt: toJsonable(receipt),
|
|
7687
7608
|
registration_preflight: preflight,
|
|
7688
|
-
runtime_validation_path: project.runtime_validation_path ?? null
|
|
7689
|
-
oauth_credentials_path: project.oauth_credentials_path ?? null
|
|
7609
|
+
runtime_validation_path: project.runtime_validation_path ?? null
|
|
7690
7610
|
};
|
|
7691
7611
|
if (developerPortalPreflight) {
|
|
7692
7612
|
result.developer_portal_preflight = developerPortalPreflight;
|
|
@@ -7707,7 +7627,6 @@ async function runPreflight(path = ".", deps = {}) {
|
|
|
7707
7627
|
ensureExplicitToolManual(project);
|
|
7708
7628
|
ensureManifestPublisherIdentity(project);
|
|
7709
7629
|
ensureRuntimeValidationReady(project);
|
|
7710
|
-
ensureRequiredOauthCredentials(project);
|
|
7711
7630
|
const client = await createClient(deps);
|
|
7712
7631
|
const preflight = await registrationPreflight(project, client);
|
|
7713
7632
|
let developerPortalPreflight = null;
|
|
@@ -7725,8 +7644,7 @@ async function runPreflight(path = ".", deps = {}) {
|
|
|
7725
7644
|
ok: true,
|
|
7726
7645
|
adapter_path: project.adapter_path,
|
|
7727
7646
|
registration_preflight: preflight,
|
|
7728
|
-
runtime_validation_path: project.runtime_validation_path ?? null
|
|
7729
|
-
oauth_credentials_path: project.oauth_credentials_path ?? null
|
|
7647
|
+
runtime_validation_path: project.runtime_validation_path ?? null
|
|
7730
7648
|
};
|
|
7731
7649
|
if (developerPortalPreflight) {
|
|
7732
7650
|
result.developer_portal_preflight = developerPortalPreflight;
|
|
@@ -8208,7 +8126,7 @@ function operationReadmeTemplate(operation, manifest, warning) {
|
|
|
8208
8126
|
"- `tool_manual.json`: machine-generated ToolManual scaffold",
|
|
8209
8127
|
"- `runtime_validation.json`: local public endpoint and review-key checks used by auto-register",
|
|
8210
8128
|
"- `docs/api-usage.md`: publishable API usage guide template for `docs_url`",
|
|
8211
|
-
"- `.gitignore`: keeps runtime review keys
|
|
8129
|
+
"- `.gitignore`: keeps runtime review keys out of Git",
|
|
8212
8130
|
"- `tests/test_adapter.ts`: smoke test for `AppTestHarness`",
|
|
8213
8131
|
"",
|
|
8214
8132
|
"Before registering, replace all generated placeholders:",
|
|
@@ -8216,8 +8134,8 @@ function operationReadmeTemplate(operation, manifest, warning) {
|
|
|
8216
8134
|
"- Replace `support_contact` with a real support email address or public support URL.",
|
|
8217
8135
|
"- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
|
|
8218
8136
|
"- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
|
|
8219
|
-
"- If the API uses
|
|
8220
|
-
"- Do not commit real review keys or
|
|
8137
|
+
"- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
|
|
8138
|
+
"- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
|
|
8221
8139
|
"- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
|
|
8222
8140
|
"",
|
|
8223
8141
|
"## Commands",
|
|
@@ -8293,8 +8211,6 @@ function generatedGitignore() {
|
|
|
8293
8211
|
"!.env.example",
|
|
8294
8212
|
"runtime_validation.json",
|
|
8295
8213
|
"runtime-validation.json",
|
|
8296
|
-
"oauth_credentials.json",
|
|
8297
|
-
"oauth-credentials.json",
|
|
8298
8214
|
"",
|
|
8299
8215
|
"# Python / test artifacts.",
|
|
8300
8216
|
"__pycache__/",
|
|
@@ -8440,13 +8356,6 @@ async function runHarnessForProject(project) {
|
|
|
8440
8356
|
checks.push(executionCheck("quote", await harness.execute_quote(task_type, { input_params: sample_input }), harness));
|
|
8441
8357
|
checks.push(executionCheck("payment", await harness.execute_payment(task_type, { input_params: sample_input }), harness));
|
|
8442
8358
|
}
|
|
8443
|
-
checks.push(
|
|
8444
|
-
executionCheck(
|
|
8445
|
-
"missing_account_simulation",
|
|
8446
|
-
await harness.simulate_connected_account_missing(task_type, { input_params: sample_input }),
|
|
8447
|
-
harness
|
|
8448
|
-
)
|
|
8449
|
-
);
|
|
8450
8359
|
return {
|
|
8451
8360
|
adapter_path: project.adapter_path,
|
|
8452
8361
|
task_type,
|
|
@@ -8549,15 +8458,6 @@ async function findRuntimeValidationPath(root_dir) {
|
|
|
8549
8458
|
}
|
|
8550
8459
|
return null;
|
|
8551
8460
|
}
|
|
8552
|
-
async function findOauthCredentialsPath(root_dir) {
|
|
8553
|
-
for (const name of ["oauth_credentials.json", "oauth-credentials.json"]) {
|
|
8554
|
-
const candidate = join(root_dir, name);
|
|
8555
|
-
if (existsSync(candidate)) {
|
|
8556
|
-
return candidate;
|
|
8557
|
-
}
|
|
8558
|
-
}
|
|
8559
|
-
return null;
|
|
8560
|
-
}
|
|
8561
8461
|
async function loadJsonObject(path, label) {
|
|
8562
8462
|
let payload;
|
|
8563
8463
|
try {
|
|
@@ -8789,15 +8689,15 @@ function readmeTemplate(template) {
|
|
|
8789
8689
|
"- `tool_manual.json`: editable ToolManual draft for validation and registration",
|
|
8790
8690
|
"- `runtime_validation.json`: local live API smoke-test contract used during registration",
|
|
8791
8691
|
"- `docs/api-usage.md`: publish this page and use its public URL as `docs_url`",
|
|
8792
|
-
"- `.gitignore`: keeps runtime review keys
|
|
8692
|
+
"- `.gitignore`: keeps runtime review keys out of Git",
|
|
8793
8693
|
"",
|
|
8794
8694
|
"Before registering, replace all generated placeholders:",
|
|
8795
8695
|
"- In `adapter.ts` and `manifest.json`, replace `docs_url` with a dedicated public API usage guide, not a homepage.",
|
|
8796
8696
|
"- Replace `support_contact` with a real support email address or public support URL.",
|
|
8797
8697
|
"- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
|
|
8798
8698
|
"- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
|
|
8799
|
-
"- If the API uses
|
|
8800
|
-
"- Do not commit real review keys or
|
|
8699
|
+
"- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
|
|
8700
|
+
"- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
|
|
8801
8701
|
"- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
|
|
8802
8702
|
"",
|
|
8803
8703
|
"Suggested workflow:",
|
|
@@ -9015,7 +8915,6 @@ async function runCli(argv, deps = {}) {
|
|
|
9015
8915
|
emit(stdout, `preflight_quality: ${preflight.remote_quality.grade} (${preflight.remote_quality.overall_score}/100)`);
|
|
9016
8916
|
}
|
|
9017
8917
|
if (report.runtime_validation_path) emit(stdout, `runtime_validation_path: ${String(report.runtime_validation_path)}`);
|
|
9018
|
-
if (report.oauth_credentials_path) emit(stdout, `oauth_credentials_path: ${String(report.oauth_credentials_path)}`);
|
|
9019
8918
|
});
|
|
9020
8919
|
program.command("companies").description("List Siglume companies available for company-name publishing.").option("--json", "emit machine-readable JSON", false).action(async (options) => {
|
|
9021
8920
|
const report = await listCompanyPublishersReport(deps);
|
|
@@ -9066,7 +8965,6 @@ async function runCli(argv, deps = {}) {
|
|
|
9066
8965
|
emit(stdout, `listing_id: ${receipt.listing_id}`);
|
|
9067
8966
|
emit(stdout, `receipt_status: ${receipt.status}`);
|
|
9068
8967
|
if (receipt.listing_status) emit(stdout, `listing_status: ${receipt.listing_status}`);
|
|
9069
|
-
if (receipt.oauth_status) emit(stdout, `oauth_configured: ${Boolean(receipt.oauth_status.configured)}`);
|
|
9070
8968
|
if (receipt.review_url) emit(stdout, `review_url: ${receipt.review_url}`);
|
|
9071
8969
|
if (receipt.trace_id) emit(stdout, `trace_id: ${receipt.trace_id}`);
|
|
9072
8970
|
if (receipt.request_id) emit(stdout, `request_id: ${receipt.request_id}`);
|