@siglume/api-sdk 0.10.0 → 0.10.2
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 +6 -5
- package/dist/bin/siglume.cjs +135 -233
- package/dist/bin/siglume.cjs.map +1 -1
- package/dist/bin/siglume.js +135 -233
- package/dist/bin/siglume.js.map +1 -1
- package/dist/cli/index.cjs +135 -233
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +13 -129
- package/dist/cli/index.d.ts +13 -129
- package/dist/cli/index.js +135 -233
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +40 -254
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -216
- package/dist/index.d.ts +23 -216
- package/dist/index.js +40 -254
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/siglume.js
CHANGED
|
@@ -119,18 +119,6 @@ function camelCaseFromCapabilityKey(capabilityKey) {
|
|
|
119
119
|
}
|
|
120
120
|
return `${words.map((word) => word[0].toUpperCase() + word.slice(1)).join("")}App`;
|
|
121
121
|
}
|
|
122
|
-
function buildDefaultI18n(manifestPayload) {
|
|
123
|
-
const job = String(manifestPayload.job_to_be_done ?? "").trim();
|
|
124
|
-
const shortDescription = String(
|
|
125
|
-
manifestPayload.short_description ?? manifestPayload.job_to_be_done ?? manifestPayload.name ?? ""
|
|
126
|
-
).trim();
|
|
127
|
-
return {
|
|
128
|
-
job_to_be_done_en: job,
|
|
129
|
-
job_to_be_done_ja: job,
|
|
130
|
-
short_description_en: shortDescription,
|
|
131
|
-
short_description_ja: shortDescription
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
122
|
function buildRegistrationStubSource(manifestPayload, toolManualPayload) {
|
|
135
123
|
const capabilityKey = String(manifestPayload.capability_key ?? "generated-registration");
|
|
136
124
|
const jobToBeDone = String(
|
|
@@ -285,10 +273,8 @@ var init_webhooks = __esm({
|
|
|
285
273
|
"subscription.cancelled",
|
|
286
274
|
"subscription.paused",
|
|
287
275
|
"subscription.reinstated",
|
|
288
|
-
"refund.issued",
|
|
289
276
|
"payment.succeeded",
|
|
290
277
|
"payment.failed",
|
|
291
|
-
"payment.disputed",
|
|
292
278
|
"capability.published",
|
|
293
279
|
"capability.delisted",
|
|
294
280
|
"execution.completed",
|
|
@@ -1328,6 +1314,7 @@ function parseListing(data) {
|
|
|
1328
1314
|
price_value_minor: Number(data.price_value_minor ?? 0),
|
|
1329
1315
|
currency: String(data.currency ?? "USD"),
|
|
1330
1316
|
short_description: stringOrNull(data.short_description),
|
|
1317
|
+
description: stringOrNull(data.description),
|
|
1331
1318
|
docs_url: stringOrNull(data.docs_url),
|
|
1332
1319
|
support_contact: stringOrNull(data.support_contact),
|
|
1333
1320
|
seller_display_name: stringOrNull(data.seller_display_name),
|
|
@@ -1352,19 +1339,6 @@ function parseBundleMember(data) {
|
|
|
1352
1339
|
link_id: stringOrNull(data.link_id)
|
|
1353
1340
|
};
|
|
1354
1341
|
}
|
|
1355
|
-
function parseConnectedAccountProvider(data) {
|
|
1356
|
-
return {
|
|
1357
|
-
provider_key: String(data.provider_key ?? ""),
|
|
1358
|
-
display_name: String(data.display_name ?? ""),
|
|
1359
|
-
auth_type: String(data.auth_type ?? "oauth2"),
|
|
1360
|
-
refresh_supported: Boolean(data.refresh_supported ?? false),
|
|
1361
|
-
pkce_required: Boolean(data.pkce_required ?? false),
|
|
1362
|
-
default_scopes: Array.isArray(data.default_scopes) ? data.default_scopes.filter((s) => typeof s === "string") : [],
|
|
1363
|
-
available_scopes: Array.isArray(data.available_scopes) ? data.available_scopes.filter((s) => typeof s === "string") : [],
|
|
1364
|
-
scope_separator: String(data.scope_separator ?? " "),
|
|
1365
|
-
notes: stringOrNull(data.notes)
|
|
1366
|
-
};
|
|
1367
|
-
}
|
|
1368
1342
|
function parseConnectedAccountLifecycle(data) {
|
|
1369
1343
|
return {
|
|
1370
1344
|
connected_account_id: String(data.connected_account_id ?? ""),
|
|
@@ -2406,50 +2380,6 @@ function parseMarketProposalActionResult(execution) {
|
|
|
2406
2380
|
raw: { ...execution.raw }
|
|
2407
2381
|
};
|
|
2408
2382
|
}
|
|
2409
|
-
function parseRefund(data) {
|
|
2410
|
-
return {
|
|
2411
|
-
refund_id: String(data.refund_id ?? data.id ?? ""),
|
|
2412
|
-
receipt_id: String(data.receipt_id ?? ""),
|
|
2413
|
-
owner_user_id: stringOrNull(data.owner_user_id) ?? void 0,
|
|
2414
|
-
payment_mandate_id: stringOrNull(data.payment_mandate_id) ?? void 0,
|
|
2415
|
-
usage_event_id: stringOrNull(data.usage_event_id) ?? void 0,
|
|
2416
|
-
chain_receipt_id: stringOrNull(data.chain_receipt_id) ?? void 0,
|
|
2417
|
-
amount_minor: Number(data.amount_minor ?? 0),
|
|
2418
|
-
currency: String(data.currency ?? "USD"),
|
|
2419
|
-
status: String(data.status ?? "issued"),
|
|
2420
|
-
reason_code: String(data.reason_code ?? "customer-request"),
|
|
2421
|
-
note: stringOrNull(data.note) ?? void 0,
|
|
2422
|
-
idempotency_key: stringOrNull(data.idempotency_key) ?? void 0,
|
|
2423
|
-
on_chain_tx_hash: stringOrNull(data.on_chain_tx_hash) ?? void 0,
|
|
2424
|
-
metadata: toRecord(data.metadata),
|
|
2425
|
-
idempotent_replay: Boolean(data.idempotent_replay ?? false),
|
|
2426
|
-
created_at: stringOrNull(data.created_at) ?? void 0,
|
|
2427
|
-
updated_at: stringOrNull(data.updated_at) ?? void 0,
|
|
2428
|
-
raw: { ...data }
|
|
2429
|
-
};
|
|
2430
|
-
}
|
|
2431
|
-
function parseDispute(data) {
|
|
2432
|
-
return {
|
|
2433
|
-
dispute_id: String(data.dispute_id ?? data.id ?? ""),
|
|
2434
|
-
receipt_id: String(data.receipt_id ?? ""),
|
|
2435
|
-
owner_user_id: stringOrNull(data.owner_user_id) ?? void 0,
|
|
2436
|
-
payment_mandate_id: stringOrNull(data.payment_mandate_id) ?? void 0,
|
|
2437
|
-
usage_event_id: stringOrNull(data.usage_event_id) ?? void 0,
|
|
2438
|
-
external_dispute_id: stringOrNull(data.external_dispute_id) ?? void 0,
|
|
2439
|
-
status: String(data.status ?? "open"),
|
|
2440
|
-
reason_code: String(data.reason_code ?? "manual-review"),
|
|
2441
|
-
description: stringOrNull(data.description) ?? void 0,
|
|
2442
|
-
evidence: toRecord(data.evidence),
|
|
2443
|
-
response_decision: stringOrNull(data.response_decision) ?? void 0,
|
|
2444
|
-
response_note: stringOrNull(data.response_note) ?? void 0,
|
|
2445
|
-
responded_at: stringOrNull(data.responded_at) ?? void 0,
|
|
2446
|
-
metadata: toRecord(data.metadata),
|
|
2447
|
-
idempotent_replay: Boolean(data.idempotent_replay ?? false),
|
|
2448
|
-
created_at: stringOrNull(data.created_at) ?? void 0,
|
|
2449
|
-
updated_at: stringOrNull(data.updated_at) ?? void 0,
|
|
2450
|
-
raw: { ...data }
|
|
2451
|
-
};
|
|
2452
|
-
}
|
|
2453
2383
|
function cloneJsonLike(value) {
|
|
2454
2384
|
if (Array.isArray(value)) {
|
|
2455
2385
|
return value.map((item) => cloneJsonLike(item));
|
|
@@ -2534,10 +2464,13 @@ var init_client = __esm({
|
|
|
2534
2464
|
async auto_register(manifest, tool_manual, options = {}) {
|
|
2535
2465
|
const manifestPayload = coerceMapping(manifest, "manifest");
|
|
2536
2466
|
const toolManualPayload = coerceMapping(tool_manual, "tool_manual");
|
|
2467
|
+
const toolManualForRequest = { ...toolManualPayload };
|
|
2468
|
+
const embeddedInputFormSpec = toolManualForRequest.input_form_spec;
|
|
2469
|
+
delete toolManualForRequest.input_form_spec;
|
|
2470
|
+
const inputFormSpec = options.input_form_spec ?? embeddedInputFormSpec;
|
|
2537
2471
|
const payload = {
|
|
2538
|
-
i18n: buildDefaultI18n(manifestPayload),
|
|
2539
2472
|
manifest: { ...manifestPayload },
|
|
2540
|
-
tool_manual:
|
|
2473
|
+
tool_manual: toolManualForRequest
|
|
2541
2474
|
};
|
|
2542
2475
|
if (options.source_url) {
|
|
2543
2476
|
payload.source_url = options.source_url;
|
|
@@ -2556,14 +2489,11 @@ var init_client = __esm({
|
|
|
2556
2489
|
)
|
|
2557
2490
|
} : coerceMapping(options.oauth_credentials, "oauth_credentials");
|
|
2558
2491
|
}
|
|
2559
|
-
if (options.metadata) {
|
|
2560
|
-
payload.metadata = coerceMapping(options.metadata, "metadata");
|
|
2561
|
-
}
|
|
2562
2492
|
if (options.source_context) {
|
|
2563
2493
|
payload.source_context = coerceMapping(options.source_context, "source_context");
|
|
2564
2494
|
}
|
|
2565
|
-
if (
|
|
2566
|
-
payload.input_form_spec = coerceMapping(
|
|
2495
|
+
if (inputFormSpec !== void 0 && inputFormSpec !== null) {
|
|
2496
|
+
payload.input_form_spec = coerceMapping(inputFormSpec, "input_form_spec");
|
|
2567
2497
|
}
|
|
2568
2498
|
for (const fieldName of [
|
|
2569
2499
|
"capability_key",
|
|
@@ -2614,7 +2544,11 @@ var init_client = __esm({
|
|
|
2614
2544
|
if (!listing_id) {
|
|
2615
2545
|
throw new SiglumeClientError("Siglume auto-register response did not include listing_id.");
|
|
2616
2546
|
}
|
|
2617
|
-
this.pendingConfirmations.set(listing_id, {
|
|
2547
|
+
this.pendingConfirmations.set(listing_id, {
|
|
2548
|
+
manifest: manifestPayload,
|
|
2549
|
+
tool_manual: toRecord(payload.tool_manual),
|
|
2550
|
+
input_form_spec: toRecord(payload.input_form_spec)
|
|
2551
|
+
});
|
|
2618
2552
|
return {
|
|
2619
2553
|
listing_id,
|
|
2620
2554
|
status: String(data.status ?? "draft"),
|
|
@@ -2762,11 +2696,6 @@ var init_client = __esm({
|
|
|
2762
2696
|
// ----- end bundles -------------------------------------------------------
|
|
2763
2697
|
// ----- Connected accounts (v0.7 track 3) ---------------------------------
|
|
2764
2698
|
// `resolve()` is intentionally NOT wrapped: runtime-only, never over the wire.
|
|
2765
|
-
async list_connected_account_providers() {
|
|
2766
|
-
const [data] = await this.request("GET", "/me/connected-accounts/providers");
|
|
2767
|
-
const items = Array.isArray(data.items) ? data.items : [];
|
|
2768
|
-
return items.filter((item) => isRecord(item)).map(parseConnectedAccountProvider);
|
|
2769
|
-
}
|
|
2770
2699
|
async start_connected_account_oauth(input) {
|
|
2771
2700
|
const body = {
|
|
2772
2701
|
listing_id: input.listing_id,
|
|
@@ -2803,8 +2732,17 @@ var init_client = __esm({
|
|
|
2803
2732
|
const body = {
|
|
2804
2733
|
provider_key: input.provider_key,
|
|
2805
2734
|
client_id: input.client_id,
|
|
2806
|
-
client_secret: input.client_secret
|
|
2735
|
+
client_secret: input.client_secret,
|
|
2736
|
+
authorize_url: input.authorize_url,
|
|
2737
|
+
token_url: input.token_url
|
|
2807
2738
|
};
|
|
2739
|
+
if (input.revoke_url !== void 0) body.revoke_url = input.revoke_url;
|
|
2740
|
+
if (input.display_name !== void 0) body.display_name = input.display_name;
|
|
2741
|
+
if (input.scope_separator !== void 0) body.scope_separator = input.scope_separator;
|
|
2742
|
+
if (input.token_endpoint_auth !== void 0) body.token_endpoint_auth = input.token_endpoint_auth;
|
|
2743
|
+
if (input.pkce_required !== void 0) body.pkce_required = input.pkce_required;
|
|
2744
|
+
if (input.refresh_supported !== void 0) body.refresh_supported = input.refresh_supported;
|
|
2745
|
+
if (input.available_scopes !== void 0) body.available_scopes = input.available_scopes;
|
|
2808
2746
|
if (input.required_scopes !== void 0) body.required_scopes = input.required_scopes;
|
|
2809
2747
|
const [data] = await this.request("PUT", `/market/capabilities/${listing_id}/oauth-credentials`, {
|
|
2810
2748
|
json_body: body
|
|
@@ -4209,105 +4147,6 @@ ${details}` : summary;
|
|
|
4209
4147
|
fetchNext: next_cursor ? (cursor) => this.list_support_cases({ ...options, cursor }) : void 0
|
|
4210
4148
|
});
|
|
4211
4149
|
}
|
|
4212
|
-
async issue_partial_refund(options) {
|
|
4213
|
-
const receipt_id = String(options.receipt_id ?? "").trim();
|
|
4214
|
-
const idempotency_key = String(options.idempotency_key ?? "").trim();
|
|
4215
|
-
if (!receipt_id) {
|
|
4216
|
-
throw new SiglumeClientError("receipt_id is required.");
|
|
4217
|
-
}
|
|
4218
|
-
if (!idempotency_key) {
|
|
4219
|
-
throw new SiglumeClientError("idempotency_key is required.");
|
|
4220
|
-
}
|
|
4221
|
-
if (!Number.isFinite(options.amount_minor)) {
|
|
4222
|
-
throw new SiglumeClientError("amount_minor must be a finite number.");
|
|
4223
|
-
}
|
|
4224
|
-
const amount_minor = Math.trunc(options.amount_minor);
|
|
4225
|
-
if (amount_minor <= 0) {
|
|
4226
|
-
throw new SiglumeClientError("amount_minor must be positive.");
|
|
4227
|
-
}
|
|
4228
|
-
if (typeof options.original_amount_minor === "number" && amount_minor > Math.trunc(options.original_amount_minor)) {
|
|
4229
|
-
throw new SiglumeClientError("amount_minor cannot exceed the original receipt amount.");
|
|
4230
|
-
}
|
|
4231
|
-
const [data] = await this.request("POST", "/market/refunds", {
|
|
4232
|
-
json_body: {
|
|
4233
|
-
receipt_id,
|
|
4234
|
-
amount_minor,
|
|
4235
|
-
reason_code: options.reason ?? "customer-request",
|
|
4236
|
-
note: options.note,
|
|
4237
|
-
idempotency_key
|
|
4238
|
-
}
|
|
4239
|
-
});
|
|
4240
|
-
return parseRefund(data);
|
|
4241
|
-
}
|
|
4242
|
-
async issue_full_refund(options) {
|
|
4243
|
-
const receipt_id = String(options.receipt_id ?? "").trim();
|
|
4244
|
-
if (!receipt_id) {
|
|
4245
|
-
throw new SiglumeClientError("receipt_id is required.");
|
|
4246
|
-
}
|
|
4247
|
-
const provided_key = String(options.idempotency_key ?? "").trim();
|
|
4248
|
-
const idempotency_key = provided_key || `full-refund:${receipt_id}`;
|
|
4249
|
-
const [data] = await this.request("POST", "/market/refunds", {
|
|
4250
|
-
json_body: {
|
|
4251
|
-
receipt_id,
|
|
4252
|
-
reason_code: options.reason ?? "customer-request",
|
|
4253
|
-
note: options.note,
|
|
4254
|
-
idempotency_key
|
|
4255
|
-
}
|
|
4256
|
-
});
|
|
4257
|
-
return parseRefund(data);
|
|
4258
|
-
}
|
|
4259
|
-
async list_refunds(options = {}) {
|
|
4260
|
-
const [data] = await this.requestAny("GET", "/market/refunds", {
|
|
4261
|
-
params: {
|
|
4262
|
-
receipt_id: options.receipt_id,
|
|
4263
|
-
limit: Math.max(1, Math.min(Math.trunc(options.limit ?? 50), 100))
|
|
4264
|
-
}
|
|
4265
|
-
});
|
|
4266
|
-
if (!Array.isArray(data)) {
|
|
4267
|
-
throw new SiglumeClientError("Expected refunds to be returned as an array.");
|
|
4268
|
-
}
|
|
4269
|
-
return data.filter((item) => isRecord(item)).map(parseRefund);
|
|
4270
|
-
}
|
|
4271
|
-
async get_refund(refund_id) {
|
|
4272
|
-
const [data] = await this.request("GET", `/market/refunds/${refund_id}`);
|
|
4273
|
-
return parseRefund(data);
|
|
4274
|
-
}
|
|
4275
|
-
async get_refunds_for_receipt(receipt_id, options = {}) {
|
|
4276
|
-
return this.list_refunds({ receipt_id, limit: options.limit });
|
|
4277
|
-
}
|
|
4278
|
-
async list_disputes(options = {}) {
|
|
4279
|
-
const [data] = await this.requestAny("GET", "/market/disputes", {
|
|
4280
|
-
params: {
|
|
4281
|
-
receipt_id: options.receipt_id,
|
|
4282
|
-
limit: Math.max(1, Math.min(Math.trunc(options.limit ?? 50), 100))
|
|
4283
|
-
}
|
|
4284
|
-
});
|
|
4285
|
-
if (!Array.isArray(data)) {
|
|
4286
|
-
throw new SiglumeClientError("Expected disputes to be returned as an array.");
|
|
4287
|
-
}
|
|
4288
|
-
return data.filter((item) => isRecord(item)).map(parseDispute);
|
|
4289
|
-
}
|
|
4290
|
-
async get_dispute(dispute_id) {
|
|
4291
|
-
const [data] = await this.request("GET", `/market/disputes/${dispute_id}`);
|
|
4292
|
-
return parseDispute(data);
|
|
4293
|
-
}
|
|
4294
|
-
async respond_to_dispute(options) {
|
|
4295
|
-
const dispute_id = String(options.dispute_id ?? "").trim();
|
|
4296
|
-
if (!dispute_id) {
|
|
4297
|
-
throw new SiglumeClientError("dispute_id is required.");
|
|
4298
|
-
}
|
|
4299
|
-
if (!isRecord(options.evidence)) {
|
|
4300
|
-
throw new SiglumeClientError("evidence must be an object.");
|
|
4301
|
-
}
|
|
4302
|
-
const [data] = await this.request("POST", `/market/disputes/${dispute_id}/respond`, {
|
|
4303
|
-
json_body: {
|
|
4304
|
-
response: options.response,
|
|
4305
|
-
evidence: toRecord(options.evidence),
|
|
4306
|
-
note: options.note
|
|
4307
|
-
}
|
|
4308
|
-
});
|
|
4309
|
-
return parseDispute(data);
|
|
4310
|
-
}
|
|
4311
4150
|
async create_webhook_subscription(options) {
|
|
4312
4151
|
const normalizedEventTypes = options.event_types.map((item) => String(item).trim()).filter((item) => item.length > 0);
|
|
4313
4152
|
if (normalizedEventTypes.length === 0) {
|
|
@@ -5816,16 +5655,24 @@ function coerceToolManual(manual) {
|
|
|
5816
5655
|
}
|
|
5817
5656
|
function checkSchemaForbiddenRecursive(schema, rootField, pushIssue, path = "") {
|
|
5818
5657
|
for (const keyword of COMPOSITION_KEYWORDS) {
|
|
5819
|
-
if (keyword in schema) {
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
);
|
|
5658
|
+
if (!(keyword in schema)) {
|
|
5659
|
+
continue;
|
|
5660
|
+
}
|
|
5661
|
+
const branches = schema[keyword];
|
|
5662
|
+
const location = path ? `${rootField}.${path}.${keyword}` : `${rootField}.${keyword}`;
|
|
5663
|
+
if (!Array.isArray(branches) || branches.length === 0) {
|
|
5664
|
+
pushIssue(issue("INPUT_SCHEMA", `${keyword} must be a non-empty array`, location));
|
|
5665
|
+
continue;
|
|
5828
5666
|
}
|
|
5667
|
+
branches.forEach((branch, index) => {
|
|
5668
|
+
const branchPath = path ? `${path}.${keyword}[${index}]` : `${keyword}[${index}]`;
|
|
5669
|
+
const branchLocation = `${rootField}.${branchPath}`;
|
|
5670
|
+
if (!isRecord(branch)) {
|
|
5671
|
+
pushIssue(issue("INPUT_SCHEMA", `${keyword}[${index}] must be an object`, branchLocation));
|
|
5672
|
+
return;
|
|
5673
|
+
}
|
|
5674
|
+
checkSchemaForbiddenRecursive(branch, rootField, pushIssue, branchPath);
|
|
5675
|
+
});
|
|
5829
5676
|
}
|
|
5830
5677
|
for (const forbidden of INPUT_SCHEMA_FORBIDDEN_KEYS) {
|
|
5831
5678
|
if (forbidden in schema) {
|
|
@@ -7192,43 +7039,51 @@ async function loadProject(path = ".") {
|
|
|
7192
7039
|
oauth_credentials
|
|
7193
7040
|
};
|
|
7194
7041
|
}
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
"google-calendar": "google",
|
|
7204
|
-
github: "github",
|
|
7205
|
-
linear: "linear",
|
|
7206
|
-
notion: "notion"
|
|
7207
|
-
};
|
|
7042
|
+
function isPlatformManagedRequirement(value) {
|
|
7043
|
+
if (!isRecord(value)) return false;
|
|
7044
|
+
if (value.platform_managed === true) return true;
|
|
7045
|
+
const owner = String(
|
|
7046
|
+
value.managed_by ?? value.auth_managed_by ?? value.connection_owner ?? ""
|
|
7047
|
+
).trim().toLowerCase().replaceAll("_", "-");
|
|
7048
|
+
return owner === "platform" || owner === "siglume" || owner === "siglume-platform";
|
|
7049
|
+
}
|
|
7208
7050
|
function oauthProviderKeyFromRequirement(value) {
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
}
|
|
7214
|
-
for (const token of raw.replaceAll("/", "-").replaceAll(":", "-").split("-")) {
|
|
7215
|
-
const next = token.trim();
|
|
7216
|
-
if (OAUTH_PROVIDER_ALIASES[next]) {
|
|
7217
|
-
return OAUTH_PROVIDER_ALIASES[next];
|
|
7051
|
+
if (isRecord(value)) {
|
|
7052
|
+
for (const key of ["provider_key", "provider", "account_type", "name"]) {
|
|
7053
|
+
const providerKey = oauthProviderKeyFromRequirement(value[key]);
|
|
7054
|
+
if (providerKey) return providerKey;
|
|
7218
7055
|
}
|
|
7056
|
+
return null;
|
|
7219
7057
|
}
|
|
7220
|
-
|
|
7058
|
+
const raw = String(value ?? "").trim();
|
|
7059
|
+
return raw || null;
|
|
7221
7060
|
}
|
|
7222
7061
|
function requiredOauthProviders(requirements) {
|
|
7223
7062
|
const providers = [];
|
|
7224
7063
|
for (const item of requirements ?? []) {
|
|
7064
|
+
if (!isPlatformManagedRequirement(item)) continue;
|
|
7225
7065
|
const providerKey = oauthProviderKeyFromRequirement(item);
|
|
7066
|
+
if (!providerKey) {
|
|
7067
|
+
throw new SiglumeProjectError(
|
|
7068
|
+
"required_connected_accounts platform-managed entries must include a provider_key"
|
|
7069
|
+
);
|
|
7070
|
+
}
|
|
7226
7071
|
if (providerKey && !providers.includes(providerKey)) {
|
|
7227
7072
|
providers.push(providerKey);
|
|
7228
7073
|
}
|
|
7229
7074
|
}
|
|
7230
7075
|
return providers;
|
|
7231
7076
|
}
|
|
7077
|
+
function connectedAccountRequirementLabel(value) {
|
|
7078
|
+
if (isRecord(value)) {
|
|
7079
|
+
for (const key of ["provider_key", "provider", "account_type", "name"]) {
|
|
7080
|
+
const label = String(value[key] ?? "").trim();
|
|
7081
|
+
if (label) return label;
|
|
7082
|
+
}
|
|
7083
|
+
return "";
|
|
7084
|
+
}
|
|
7085
|
+
return String(value ?? "").trim();
|
|
7086
|
+
}
|
|
7232
7087
|
function oauthProviderRecordsMap(payload) {
|
|
7233
7088
|
if (!payload) {
|
|
7234
7089
|
return {};
|
|
@@ -7241,7 +7096,23 @@ function oauthProviderRecordsMap(payload) {
|
|
|
7241
7096
|
}
|
|
7242
7097
|
const providerKey = oauthProviderKeyFromRequirement(item.provider_key ?? item.provider);
|
|
7243
7098
|
if (!providerKey) {
|
|
7244
|
-
throw new SiglumeProjectError(`oauth_credentials[${index}].provider_key is
|
|
7099
|
+
throw new SiglumeProjectError(`oauth_credentials[${index}].provider_key is required.`);
|
|
7100
|
+
}
|
|
7101
|
+
const authorizeUrl = String(item.authorize_url ?? item.authorization_url ?? item.auth_url ?? "").trim();
|
|
7102
|
+
const tokenUrl = String(item.token_url ?? "").trim();
|
|
7103
|
+
if (!authorizeUrl || !tokenUrl) {
|
|
7104
|
+
throw new SiglumeProjectError(
|
|
7105
|
+
`oauth_credentials[${index}] must include authorize_url and token_url.`
|
|
7106
|
+
);
|
|
7107
|
+
}
|
|
7108
|
+
for (const [urlKey, urlValue] of Object.entries({
|
|
7109
|
+
authorize_url: authorizeUrl,
|
|
7110
|
+
token_url: tokenUrl,
|
|
7111
|
+
revoke_url: String(item.revoke_url ?? "").trim()
|
|
7112
|
+
})) {
|
|
7113
|
+
if (urlValue && !urlValue.startsWith("https://")) {
|
|
7114
|
+
throw new SiglumeProjectError(`oauth_credentials[${index}].${urlKey} must be an https URL.`);
|
|
7115
|
+
}
|
|
7245
7116
|
}
|
|
7246
7117
|
const clientId = String(item.client_id ?? "").trim();
|
|
7247
7118
|
const clientSecret = String(item.client_secret ?? "").trim();
|
|
@@ -7257,12 +7128,30 @@ function oauthProviderRecordsMap(payload) {
|
|
|
7257
7128
|
} else {
|
|
7258
7129
|
scopes = rawScopes.map((scope) => String(scope ?? "").trim()).filter(Boolean);
|
|
7259
7130
|
}
|
|
7260
|
-
|
|
7131
|
+
const record = {
|
|
7261
7132
|
provider_key: providerKey,
|
|
7262
7133
|
client_id: clientId,
|
|
7263
7134
|
client_secret: clientSecret,
|
|
7264
7135
|
required_scopes: scopes
|
|
7265
7136
|
};
|
|
7137
|
+
for (const [key, value] of Object.entries({
|
|
7138
|
+
authorize_url: authorizeUrl,
|
|
7139
|
+
token_url: tokenUrl,
|
|
7140
|
+
revoke_url: String(item.revoke_url ?? "").trim(),
|
|
7141
|
+
display_name: String(item.display_name ?? "").trim(),
|
|
7142
|
+
scope_separator: String(item.scope_separator ?? "").trim(),
|
|
7143
|
+
token_endpoint_auth: String(item.token_endpoint_auth ?? "").trim()
|
|
7144
|
+
})) {
|
|
7145
|
+
if (value) record[key] = value;
|
|
7146
|
+
}
|
|
7147
|
+
for (const key of ["pkce_required", "refresh_supported"]) {
|
|
7148
|
+
if (typeof item[key] === "boolean") record[key] = item[key];
|
|
7149
|
+
}
|
|
7150
|
+
if (Array.isArray(item.available_scopes)) {
|
|
7151
|
+
const availableScopes = item.available_scopes.map((scope) => String(scope ?? "").trim()).filter(Boolean);
|
|
7152
|
+
if (availableScopes.length > 0) record.available_scopes = availableScopes;
|
|
7153
|
+
}
|
|
7154
|
+
resolved[providerKey] = record;
|
|
7266
7155
|
}
|
|
7267
7156
|
return resolved;
|
|
7268
7157
|
}
|
|
@@ -7288,7 +7177,7 @@ function ensureRequiredOauthCredentials(project) {
|
|
|
7288
7177
|
}
|
|
7289
7178
|
const path = project.oauth_credentials_path ?? join(project.root_dir, "oauth_credentials.json");
|
|
7290
7179
|
throw new SiglumeProjectError(
|
|
7291
|
-
`${path} is required for
|
|
7180
|
+
`${path} is required for platform-managed OAuth APIs. Missing provider seeds: ${missing.join(", ")}`
|
|
7292
7181
|
);
|
|
7293
7182
|
}
|
|
7294
7183
|
async function validateProject(path = ".", deps = {}) {
|
|
@@ -7456,7 +7345,7 @@ async function registrationPreflight(project, client) {
|
|
|
7456
7345
|
errors.push(`remote Tool Manual quality is not publishable: ${remoteQuality.grade} (${remoteQuality.overall_score}/100)`);
|
|
7457
7346
|
}
|
|
7458
7347
|
if (missingOauthProviders.length > 0) {
|
|
7459
|
-
errors.push(`oauth_credentials.json is required for
|
|
7348
|
+
errors.push(`oauth_credentials.json is required for platform-managed OAuth APIs: ${missingOauthProviders.join(", ")}`);
|
|
7460
7349
|
}
|
|
7461
7350
|
const preflight = {
|
|
7462
7351
|
manifest_issues: manifestIssues,
|
|
@@ -7482,6 +7371,7 @@ async function runRegistration(path = ".", options = {}, deps = {}) {
|
|
|
7482
7371
|
ensureManifestPublisherIdentity(project);
|
|
7483
7372
|
ensureRuntimeValidationReady(project);
|
|
7484
7373
|
ensureRequiredOauthCredentials(project);
|
|
7374
|
+
const canonicalOauthCredentials = canonicalOauthCredentialsPayload(project.oauth_credentials);
|
|
7485
7375
|
const client = await createClient(deps);
|
|
7486
7376
|
const preflight = await registrationPreflight(project, client);
|
|
7487
7377
|
let developerPortalPreflight = null;
|
|
@@ -7497,7 +7387,7 @@ async function runRegistration(path = ".", options = {}, deps = {}) {
|
|
|
7497
7387
|
}
|
|
7498
7388
|
const receipt = await client.auto_register(project.manifest, project.tool_manual, {
|
|
7499
7389
|
runtime_validation: project.runtime_validation,
|
|
7500
|
-
oauth_credentials:
|
|
7390
|
+
oauth_credentials: canonicalOauthCredentials
|
|
7501
7391
|
});
|
|
7502
7392
|
const result = {
|
|
7503
7393
|
receipt: toJsonable(receipt),
|
|
@@ -7508,7 +7398,8 @@ async function runRegistration(path = ".", options = {}, deps = {}) {
|
|
|
7508
7398
|
if (developerPortalPreflight) {
|
|
7509
7399
|
result.developer_portal_preflight = developerPortalPreflight;
|
|
7510
7400
|
}
|
|
7511
|
-
|
|
7401
|
+
const shouldConfirm = Boolean(options.confirm) || options.confirm === void 0 && !options.draft_only && !options.submit_review;
|
|
7402
|
+
if (shouldConfirm) {
|
|
7512
7403
|
result.confirmation = toJsonable(await client.confirm_registration(receipt.listing_id));
|
|
7513
7404
|
if (options.submit_review) {
|
|
7514
7405
|
result.submit_review_skipped = true;
|
|
@@ -8039,8 +7930,8 @@ function operationReadmeTemplate(operation, manifest, warning) {
|
|
|
8039
7930
|
"siglume score . --remote",
|
|
8040
7931
|
"siglume preflight .",
|
|
8041
7932
|
"siglume register .",
|
|
8042
|
-
"#
|
|
8043
|
-
"siglume register . --
|
|
7933
|
+
"# review-only staging path:",
|
|
7934
|
+
"siglume register . --draft-only",
|
|
8044
7935
|
"```",
|
|
8045
7936
|
""
|
|
8046
7937
|
].join("\n");
|
|
@@ -8051,7 +7942,7 @@ function apiUsageDocsTemplate(manifest) {
|
|
|
8051
7942
|
const jobToBeDone = String(manifest.job_to_be_done ?? "Describe what this API lets an agent do.");
|
|
8052
7943
|
const permissionClass = String(manifest.permission_class ?? "read-only");
|
|
8053
7944
|
const priceModel = String(manifest.price_model ?? "free");
|
|
8054
|
-
const requiredAccounts = (manifest.required_connected_accounts ?? []).join(", ") || "none";
|
|
7945
|
+
const requiredAccounts = (manifest.required_connected_accounts ?? []).map((item) => connectedAccountRequirementLabel(item)).filter(Boolean).join(", ") || "none";
|
|
8055
7946
|
const supportContact = String(manifest.support_contact ?? "replace-with-support-contact");
|
|
8056
7947
|
return [
|
|
8057
7948
|
`# ${name} API Usage Guide`,
|
|
@@ -8612,8 +8503,8 @@ function readmeTemplate(template) {
|
|
|
8612
8503
|
"siglume score . --remote",
|
|
8613
8504
|
"siglume preflight .",
|
|
8614
8505
|
"siglume register .",
|
|
8615
|
-
"#
|
|
8616
|
-
"siglume register . --
|
|
8506
|
+
"# review-only staging path:",
|
|
8507
|
+
"siglume register . --draft-only",
|
|
8617
8508
|
"```",
|
|
8618
8509
|
""
|
|
8619
8510
|
].join("\n");
|
|
@@ -8795,16 +8686,25 @@ async function runCli(argv, deps = {}) {
|
|
|
8795
8686
|
if (report.runtime_validation_path) emit(stdout, `runtime_validation_path: ${String(report.runtime_validation_path)}`);
|
|
8796
8687
|
if (report.oauth_credentials_path) emit(stdout, `oauth_credentials_path: ${String(report.oauth_credentials_path)}`);
|
|
8797
8688
|
});
|
|
8798
|
-
program.command("register").option("--confirm", "confirm the draft
|
|
8799
|
-
const
|
|
8689
|
+
program.command("register").option("--confirm", "explicitly confirm the registration; this is the default unless --draft-only is set", false).option("--draft-only", "create or refresh the draft without confirming publication", false).option("--submit-review", "legacy alias: publish immediately if your environment still routes through submit-review", false).option("--json", "emit machine-readable JSON", false).argument("[path]", ".", "project path").action(async (path, options) => {
|
|
8690
|
+
const draftOnly = Boolean(options.draftOnly);
|
|
8691
|
+
if (draftOnly && options.confirm) {
|
|
8692
|
+
throw new SiglumeProjectError("--draft-only cannot be combined with --confirm.");
|
|
8693
|
+
}
|
|
8694
|
+
if (draftOnly && options.submitReview) {
|
|
8695
|
+
throw new SiglumeProjectError("--draft-only cannot be combined with --submit-review.");
|
|
8696
|
+
}
|
|
8697
|
+
const shouldConfirm = Boolean(options.confirm) || !draftOnly && !options.submitReview;
|
|
8698
|
+
const report = await runRegistration(path, { confirm: shouldConfirm, draft_only: draftOnly, submit_review: options.submitReview }, deps);
|
|
8800
8699
|
if (options.json) {
|
|
8801
8700
|
emit(stdout, renderJson(report));
|
|
8802
8701
|
} else {
|
|
8803
8702
|
const receipt = report.receipt;
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8703
|
+
const published = Boolean(report.confirmation || report.review);
|
|
8704
|
+
if (published && receipt.registration_mode === "upgrade") {
|
|
8705
|
+
emit(stdout, "Upgrade registered.");
|
|
8706
|
+
} else if (published) {
|
|
8707
|
+
emit(stdout, "Registration accepted.");
|
|
8808
8708
|
} else if (receipt.registration_mode === "upgrade") {
|
|
8809
8709
|
emit(stdout, "Upgrade staged.");
|
|
8810
8710
|
} else if (receipt.registration_mode === "refresh") {
|
|
@@ -8821,10 +8721,12 @@ async function runCli(argv, deps = {}) {
|
|
|
8821
8721
|
if (receipt.request_id) emit(stdout, `request_id: ${receipt.request_id}`);
|
|
8822
8722
|
if (report.confirmation) {
|
|
8823
8723
|
const confirmation = report.confirmation;
|
|
8724
|
+
emit(stdout, "Listing published.");
|
|
8824
8725
|
if (confirmation.status) emit(stdout, `confirmation_status: ${confirmation.status}`);
|
|
8825
8726
|
if (confirmation.release?.release_status) emit(stdout, `release_status: ${confirmation.release.release_status}`);
|
|
8826
8727
|
} else if (report.review) {
|
|
8827
8728
|
const review = report.review;
|
|
8729
|
+
emit(stdout, "Listing published via legacy submit-review alias.");
|
|
8828
8730
|
if (review.status) emit(stdout, `publish_status: ${review.status}`);
|
|
8829
8731
|
}
|
|
8830
8732
|
const preflight = report.registration_preflight;
|