@siglume/api-sdk 1.2.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -333,7 +333,12 @@ var init_webhooks = __esm({
333
333
  "capability.published",
334
334
  "capability.delisted",
335
335
  "execution.completed",
336
- "execution.failed"
336
+ "execution.failed",
337
+ "reward_payout.created",
338
+ "reward_payout.provider_pending",
339
+ "reward_paid",
340
+ "reward_payout.failed",
341
+ "reward_payout.cancelled"
337
342
  ];
338
343
  WEBHOOK_EVENT_SET = new Set(WEBHOOK_EVENT_TYPES);
339
344
  }
@@ -1383,6 +1388,23 @@ function validatePricingPlanFloor(plan, defaultCurrency) {
1383
1388
  function pricingPlanHasItems(plan) {
1384
1389
  return isRecord(plan) && Array.isArray(plan.items) && plan.items.length > 0;
1385
1390
  }
1391
+ function validateListingTextLengths(payload) {
1392
+ const limits = {
1393
+ short_description: LISTING_SHORT_DESCRIPTION_MAX_LENGTH,
1394
+ job_to_be_done: LISTING_JOB_TO_BE_DONE_MAX_LENGTH,
1395
+ description: LISTING_DESCRIPTION_MAX_LENGTH
1396
+ };
1397
+ for (const [fieldName, maxLength] of Object.entries(limits)) {
1398
+ const value = payload[fieldName];
1399
+ if (value === void 0 || value === null) continue;
1400
+ if (typeof value !== "string") {
1401
+ throw new SiglumeClientError(`AppManifest.${fieldName} must be a string when provided.`);
1402
+ }
1403
+ if (Array.from(value).length > maxLength) {
1404
+ throw new SiglumeClientError(`AppManifest.${fieldName} must be at most ${maxLength} characters.`);
1405
+ }
1406
+ }
1407
+ }
1386
1408
  function buildToolManualQualityReport(payload) {
1387
1409
  const qualityBlock = isRecord(payload.quality) ? payload.quality : payload;
1388
1410
  const issues = [];
@@ -1940,139 +1962,6 @@ function parseInstalledToolReceiptStep(data) {
1940
1962
  raw: { ...data }
1941
1963
  };
1942
1964
  }
1943
- function toRecordList(value) {
1944
- return Array.isArray(value) ? value.filter((item) => isRecord(item)).map((item) => ({ ...item })) : [];
1945
- }
1946
- function parsePartnerDashboard(data) {
1947
- return {
1948
- partner_id: String(data.partner_id ?? data.user_id ?? ""),
1949
- company_name: stringOrNull(data.company_name) ?? void 0,
1950
- plan: stringOrNull(data.plan) ?? void 0,
1951
- plan_label: stringOrNull(data.plan_label) ?? void 0,
1952
- month_bytes_used: Math.trunc(Number(data.month_bytes_used ?? 0)),
1953
- month_bytes_limit: Math.trunc(Number(data.month_bytes_limit ?? 0)),
1954
- month_usage_pct: Number(data.month_usage_pct ?? 0),
1955
- total_source_items: Math.trunc(Number(data.total_source_items ?? 0)),
1956
- has_billing: Boolean(data.has_billing ?? false),
1957
- has_subscription: Boolean(data.has_subscription ?? false),
1958
- raw: { ...data }
1959
- };
1960
- }
1961
- function parsePartnerUsage(data) {
1962
- return {
1963
- plan: stringOrNull(data.plan) ?? void 0,
1964
- month_bytes_used: Math.trunc(Number(data.month_bytes_used ?? 0)),
1965
- month_bytes_limit: Math.trunc(Number(data.month_bytes_limit ?? 0)),
1966
- month_bytes_remaining: Math.trunc(Number(data.month_bytes_remaining ?? 0)),
1967
- month_usage_pct: Number(data.month_usage_pct ?? 0),
1968
- raw: { ...data }
1969
- };
1970
- }
1971
- function parsePartnerApiKey(data) {
1972
- return {
1973
- credential_id: String(data.credential_id ?? data.id ?? ""),
1974
- name: stringOrNull(data.name) ?? void 0,
1975
- key_id: stringOrNull(data.key_id) ?? void 0,
1976
- allowed_source_types: Array.isArray(data.allowed_source_types) ? data.allowed_source_types.filter((item) => typeof item === "string") : [],
1977
- last_used_at: stringOrNull(data.last_used_at) ?? void 0,
1978
- created_at: stringOrNull(data.created_at) ?? void 0,
1979
- revoked: Boolean(data.revoked ?? false),
1980
- raw: { ...data }
1981
- };
1982
- }
1983
- function parsePartnerApiKeyHandle(data) {
1984
- const raw = Object.fromEntries(
1985
- Object.entries(data).filter(([key]) => key !== "ingest_key" && key !== "full_key")
1986
- );
1987
- return {
1988
- credential_id: String(raw.credential_id ?? raw.id ?? ""),
1989
- name: stringOrNull(raw.name) ?? void 0,
1990
- key_id: stringOrNull(raw.key_id) ?? void 0,
1991
- allowed_source_types: Array.isArray(raw.allowed_source_types) ? raw.allowed_source_types.filter((item) => typeof item === "string") : [],
1992
- masked_key_hint: stringOrNull(raw.masked_key_hint) ?? void 0,
1993
- raw
1994
- };
1995
- }
1996
- function parseAdsBilling(data) {
1997
- return {
1998
- currency: stringOrNull(data.currency) ?? void 0,
1999
- billing_mode: stringOrNull(data.billing_mode) ?? void 0,
2000
- month_spend_jpy: Math.trunc(Number(data.month_spend_jpy ?? 0)),
2001
- month_spend_usd: Math.trunc(Number(data.month_spend_usd ?? 0)),
2002
- all_time_spend_jpy: Math.trunc(Number(data.all_time_spend_jpy ?? 0)),
2003
- all_time_spend_usd: Math.trunc(Number(data.all_time_spend_usd ?? 0)),
2004
- total_impressions: Math.trunc(Number(data.total_impressions ?? 0)),
2005
- total_replies: Math.trunc(Number(data.total_replies ?? 0)),
2006
- has_billing: Boolean(data.has_billing ?? false),
2007
- has_subscription: Boolean(data.has_subscription ?? false),
2008
- invoices: toRecordList(data.invoices),
2009
- wallet: isRecord(data.wallet) ? { ...data.wallet } : null,
2010
- balances: toRecordList(data.balances),
2011
- supported_tokens: toRecordList(data.supported_tokens),
2012
- funding_instructions: isRecord(data.funding_instructions) ? { ...data.funding_instructions } : null,
2013
- mandate: isRecord(data.mandate) ? parsePlanWeb3Mandate(data.mandate) : null,
2014
- raw: { ...data }
2015
- };
2016
- }
2017
- function parseAdsBillingSettlement(data) {
2018
- return {
2019
- status: stringOrNull(data.status) ?? void 0,
2020
- message: stringOrNull(data.message ?? data.detail) ?? void 0,
2021
- settles_automatically: typeof data.settles_automatically === "boolean" ? data.settles_automatically : typeof data.auto_settles === "boolean" ? data.auto_settles : void 0,
2022
- cycle_key: stringOrNull(data.cycle_key) ?? void 0,
2023
- settled_at: stringOrNull(data.settled_at) ?? void 0,
2024
- raw: { ...data }
2025
- };
2026
- }
2027
- function parseAdsProfile(data) {
2028
- return {
2029
- has_profile: Boolean(data.has_profile ?? false),
2030
- company_name: stringOrNull(data.company_name) ?? void 0,
2031
- ad_currency: stringOrNull(data.ad_currency) ?? void 0,
2032
- has_billing: Boolean(data.has_billing ?? false),
2033
- raw: { ...data }
2034
- };
2035
- }
2036
- function parseAdsCampaign(data) {
2037
- return {
2038
- campaign_id: String(data.campaign_id ?? data.id ?? ""),
2039
- name: stringOrNull(data.name) ?? void 0,
2040
- target_url: stringOrNull(data.target_url) ?? void 0,
2041
- content_brief: stringOrNull(data.content_brief) ?? void 0,
2042
- target_topics: Array.isArray(data.target_topics) ? data.target_topics.filter((item) => typeof item === "string") : [],
2043
- posting_interval_minutes: Math.trunc(Number(data.posting_interval_minutes ?? 360)),
2044
- max_posts_per_day: Math.trunc(Number(data.max_posts_per_day ?? 4)),
2045
- currency: stringOrNull(data.currency) ?? void 0,
2046
- monthly_budget_jpy: Math.trunc(Number(data.monthly_budget_jpy ?? 0)),
2047
- cpm_jpy: Math.trunc(Number(data.cpm_jpy ?? 0)),
2048
- cpr_jpy: Math.trunc(Number(data.cpr_jpy ?? 0)),
2049
- monthly_budget_usd: Math.trunc(Number(data.monthly_budget_usd ?? 0)),
2050
- cpm_usd: Math.trunc(Number(data.cpm_usd ?? 0)),
2051
- cpr_usd: Math.trunc(Number(data.cpr_usd ?? 0)),
2052
- status: String(data.status ?? "active").trim().toLowerCase() || "active",
2053
- month_spend_jpy: Math.trunc(Number(data.month_spend_jpy ?? 0)),
2054
- month_spend_usd: Math.trunc(Number(data.month_spend_usd ?? 0)),
2055
- total_posts: Math.trunc(Number(data.total_posts ?? 0)),
2056
- total_impressions: Math.trunc(Number(data.total_impressions ?? 0)),
2057
- total_replies: Math.trunc(Number(data.total_replies ?? 0)),
2058
- next_post_at: stringOrNull(data.next_post_at) ?? void 0,
2059
- created_at: stringOrNull(data.created_at) ?? void 0,
2060
- raw: { ...data }
2061
- };
2062
- }
2063
- function parseAdsCampaignPost(data) {
2064
- return {
2065
- post_id: String(data.post_id ?? data.id ?? ""),
2066
- content_id: stringOrNull(data.content_id) ?? void 0,
2067
- cost_jpy: Math.trunc(Number(data.cost_jpy ?? 0)),
2068
- cost_usd: Math.trunc(Number(data.cost_usd ?? 0)),
2069
- impressions: Math.trunc(Number(data.impressions ?? 0)),
2070
- replies: Math.trunc(Number(data.replies ?? 0)),
2071
- status: stringOrNull(data.status) ?? void 0,
2072
- created_at: stringOrNull(data.created_at) ?? void 0,
2073
- raw: { ...data }
2074
- };
2075
- }
2076
1965
  function parseWorksCategory(data) {
2077
1966
  return {
2078
1967
  key: String(data.key ?? ""),
@@ -2571,7 +2460,7 @@ function cloneJsonLike(value) {
2571
2460
  }
2572
2461
  return value;
2573
2462
  }
2574
- var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, MINIMUM_JPY_OPERATION_PRICE_CURRENCIES, CursorPageResult, SiglumeClient;
2463
+ var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, MINIMUM_JPY_OPERATION_PRICE_CURRENCIES, LISTING_SHORT_DESCRIPTION_MAX_LENGTH, LISTING_JOB_TO_BE_DONE_MAX_LENGTH, LISTING_DESCRIPTION_MAX_LENGTH, CursorPageResult, SiglumeClient;
2575
2464
  var init_client = __esm({
2576
2465
  "src/client.ts"() {
2577
2466
  "use strict";
@@ -2584,6 +2473,9 @@ var init_client = __esm({
2584
2473
  DEFAULT_SIGLUME_API_BASE = "https://siglume.com/v1";
2585
2474
  RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
2586
2475
  MINIMUM_JPY_OPERATION_PRICE_CURRENCIES = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
2476
+ LISTING_SHORT_DESCRIPTION_MAX_LENGTH = 60;
2477
+ LISTING_JOB_TO_BE_DONE_MAX_LENGTH = 240;
2478
+ LISTING_DESCRIPTION_MAX_LENGTH = 1e3;
2587
2479
  CursorPageResult = class {
2588
2480
  items;
2589
2481
  next_cursor;
@@ -2737,6 +2629,7 @@ var init_client = __esm({
2737
2629
  if (payload.pricing_plan !== void 0) {
2738
2630
  validatePricingPlanFloor(payload.pricing_plan, currency);
2739
2631
  }
2632
+ validateListingTextLengths(payload);
2740
2633
  const priceModel = String(payload.price_model ?? "free").trim().toLowerCase();
2741
2634
  if ((priceModel === "usage_based" || priceModel === "per_action") && !pricingPlanHasItems(payload.pricing_plan)) {
2742
2635
  throw new SiglumeClientError("AppManifest.pricing_plan.items is required for usage_based/per_action pricing.");
@@ -3879,115 +3772,6 @@ var init_client = __esm({
3879
3772
  );
3880
3773
  return Array.isArray(data.result) ? data.result.filter((item) => isRecord(item)).map((item) => parseInstalledToolReceiptStep(item)) : [];
3881
3774
  }
3882
- async get_partner_dashboard(options = {}) {
3883
- const execution = await this.execute_owner_operation(
3884
- await this.resolveOwnerOperationAgentId(options.agent_id),
3885
- "partner.dashboard.get",
3886
- {},
3887
- { lang: options.lang }
3888
- );
3889
- return parsePartnerDashboard(execution.result);
3890
- }
3891
- async get_partner_usage(options = {}) {
3892
- const execution = await this.execute_owner_operation(
3893
- await this.resolveOwnerOperationAgentId(options.agent_id),
3894
- "partner.usage.get",
3895
- {},
3896
- { lang: options.lang }
3897
- );
3898
- return parsePartnerUsage(execution.result);
3899
- }
3900
- async list_partner_api_keys(options = {}) {
3901
- const execution = await this.execute_owner_operation(
3902
- await this.resolveOwnerOperationAgentId(options.agent_id),
3903
- "partner.keys.list",
3904
- {},
3905
- { lang: options.lang }
3906
- );
3907
- return Array.isArray(execution.result.keys) ? execution.result.keys.filter((item) => isRecord(item)).map((item) => parsePartnerApiKey(item)) : [];
3908
- }
3909
- async create_partner_api_key(options = {}) {
3910
- const payload = {};
3911
- if (options.name !== void 0) {
3912
- const normalizedName = String(options.name).trim();
3913
- if (!normalizedName) {
3914
- throw new SiglumeClientError("name cannot be empty.");
3915
- }
3916
- payload.name = normalizedName;
3917
- }
3918
- if (options.allowed_source_types !== void 0) {
3919
- if (!Array.isArray(options.allowed_source_types)) {
3920
- throw new SiglumeClientError("allowed_source_types must be a list of strings.");
3921
- }
3922
- payload.allowed_source_types = options.allowed_source_types.flatMap((item) => {
3923
- if (typeof item !== "string") {
3924
- throw new SiglumeClientError("allowed_source_types must contain only strings.");
3925
- }
3926
- const normalizedItem = item.trim();
3927
- return normalizedItem ? [normalizedItem] : [];
3928
- });
3929
- }
3930
- const execution = await this.execute_owner_operation(
3931
- await this.resolveOwnerOperationAgentId(options.agent_id),
3932
- "partner.keys.create",
3933
- payload,
3934
- { lang: options.lang }
3935
- );
3936
- return parsePartnerApiKeyHandle(execution.result);
3937
- }
3938
- async get_ads_billing(options = {}) {
3939
- const payload = {};
3940
- if (options.rail !== void 0 && String(options.rail).trim()) {
3941
- payload.rail = String(options.rail).trim().toLowerCase();
3942
- }
3943
- const execution = await this.execute_owner_operation(
3944
- await this.resolveOwnerOperationAgentId(options.agent_id),
3945
- "ads.billing.get",
3946
- payload,
3947
- { lang: options.lang }
3948
- );
3949
- return parseAdsBilling(execution.result);
3950
- }
3951
- async settle_ads_billing(options = {}) {
3952
- const execution = await this.execute_owner_operation(
3953
- await this.resolveOwnerOperationAgentId(options.agent_id),
3954
- "ads.billing.settle",
3955
- {},
3956
- { lang: options.lang }
3957
- );
3958
- return parseAdsBillingSettlement(execution.result);
3959
- }
3960
- async get_ads_profile(options = {}) {
3961
- const execution = await this.execute_owner_operation(
3962
- await this.resolveOwnerOperationAgentId(options.agent_id),
3963
- "ads.profile.get",
3964
- {},
3965
- { lang: options.lang }
3966
- );
3967
- return parseAdsProfile(execution.result);
3968
- }
3969
- async list_ads_campaigns(options = {}) {
3970
- const execution = await this.execute_owner_operation(
3971
- await this.resolveOwnerOperationAgentId(options.agent_id),
3972
- "ads.campaigns.list",
3973
- {},
3974
- { lang: options.lang }
3975
- );
3976
- return Array.isArray(execution.result.campaigns) ? execution.result.campaigns.filter((item) => isRecord(item)).map((item) => parseAdsCampaign(item)) : [];
3977
- }
3978
- async list_ads_campaign_posts(campaign_id, options = {}) {
3979
- const normalizedCampaignId = String(campaign_id ?? "").trim();
3980
- if (!normalizedCampaignId) {
3981
- throw new SiglumeClientError("campaign_id is required.");
3982
- }
3983
- const execution = await this.execute_owner_operation(
3984
- await this.resolveOwnerOperationAgentId(options.agent_id),
3985
- "ads.campaign_posts.list",
3986
- { campaign_id: normalizedCampaignId },
3987
- { lang: options.lang }
3988
- );
3989
- return Array.isArray(execution.result.posts) ? execution.result.posts.filter((item) => isRecord(item)).map((item) => parseAdsCampaignPost(item)) : [];
3990
- }
3991
3775
  // `market.proposals.*` currently rides on the public owner-operation execute
3992
3776
  // route. Read helpers return typed proposal records; guarded mutations return
3993
3777
  // the approval envelope without treating it as an error.
@@ -5917,12 +5701,15 @@ function validate_tool_manual(manualInput) {
5917
5701
  pushError("INVALID_TOOL_NAME", "tool_name must be alphanumeric + underscore, 3-64 chars", "tool_name");
5918
5702
  }
5919
5703
  for (const [fieldName, minLength, maxLength] of [
5920
- ["job_to_be_done", 10, 500],
5704
+ ["job_to_be_done", 10, 240],
5921
5705
  ["summary_for_model", 10, 300]
5922
5706
  ]) {
5923
5707
  const value = manual[fieldName];
5924
- if (typeof value === "string" && (value.length < minLength || value.length > maxLength)) {
5925
- pushError("INVALID_TYPE", `${fieldName} must be ${minLength}-${maxLength} characters`, fieldName);
5708
+ if (typeof value === "string") {
5709
+ const length = Array.from(value).length;
5710
+ if (length < minLength || length > maxLength) {
5711
+ pushError("INVALID_TYPE", `${fieldName} must be ${minLength}-${maxLength} characters`, fieldName);
5712
+ }
5926
5713
  }
5927
5714
  }
5928
5715
  const triggerConditions = manual.trigger_conditions;
@@ -7110,8 +6897,12 @@ function buildRuntimeValidationTemplate(toolManual) {
7110
6897
  healthcheck_url: "https://api.example.com/health",
7111
6898
  invoke_url: "https://api.example.com/invoke",
7112
6899
  invoke_method: "POST",
7113
- test_auth_header_name: "X-Siglume-Review-Key",
7114
- test_auth_header_value: "replace-with-dedicated-review-key",
6900
+ // Shared secret Siglume attaches when it calls invoke_url at both
6901
+ // registration validation and production runtime. Use a strong random
6902
+ // value, keep it in the Git-ignored runtime_validation.json, and rotate it
6903
+ // if it leaks. (legacy aliases: test_auth_header_name/value)
6904
+ runtime_auth_header_name: "X-Siglume-Auth",
6905
+ runtime_auth_header_value: "replace-with-strong-random-runtime-auth-secret",
7115
6906
  request_payload: requestPayload,
7116
6907
  expected_response_fields: expectedFields.length > 0 ? expectedFields : ["summary"],
7117
6908
  timeout_seconds: 10
@@ -7416,8 +7207,6 @@ function runtimePlaceholderIssues(runtimeValidation) {
7416
7207
  "public_base_url",
7417
7208
  "healthcheck_url",
7418
7209
  "invoke_url",
7419
- "test_auth_header_name",
7420
- "test_auth_header_value",
7421
7210
  "expected_response_fields"
7422
7211
  ]) {
7423
7212
  if (!runtimeValidation[fieldName]) {
@@ -7430,9 +7219,19 @@ function runtimePlaceholderIssues(runtimeValidation) {
7430
7219
  issues.push(`runtime_validation.${fieldName} must be replaced with your public production URL`);
7431
7220
  }
7432
7221
  }
7433
- const authValue = String(runtimeValidation.test_auth_header_value ?? "").trim();
7222
+ const authName = String(
7223
+ runtimeValidation.runtime_auth_header_name || runtimeValidation.test_auth_header_name || ""
7224
+ ).trim();
7225
+ if (!authName) {
7226
+ issues.push("runtime_validation.runtime_auth_header_name is required");
7227
+ }
7228
+ const authValue = String(
7229
+ runtimeValidation.runtime_auth_header_value || runtimeValidation.test_auth_header_value || ""
7230
+ ).trim();
7434
7231
  if (!authValue || authValue.startsWith("replace-with-")) {
7435
- issues.push("runtime_validation.test_auth_header_value must be a dedicated review secret, not a placeholder");
7232
+ issues.push(
7233
+ "runtime_validation.runtime_auth_header_value must be a strong, dedicated runtime auth secret, not a placeholder"
7234
+ );
7436
7235
  }
7437
7236
  const requestPayload = runtimeValidation.request_payload ?? runtimeValidation.test_request_body ?? runtimeValidation.runtime_sample ?? runtimeValidation.sample_request_payload ?? runtimeValidation.runtime_sample_request;
7438
7237
  if (!isRecord(requestPayload)) {
@@ -7447,7 +7246,7 @@ function runtimePlaceholderIssues(runtimeValidation) {
7447
7246
  function ensureRuntimeValidationReady(project) {
7448
7247
  if (!project.runtime_validation) {
7449
7248
  throw new SiglumeProjectError(
7450
- "runtime_validation.json is required for `siglume register`. Create it with public_base_url, healthcheck_url, invoke_url, dedicated review auth header, request_payload, and expected_response_fields."
7249
+ "runtime_validation.json is required for `siglume register`. Create it with public_base_url, healthcheck_url, invoke_url, runtime auth header (runtime_auth_header_name/value), request_payload, and expected_response_fields."
7451
7250
  );
7452
7251
  }
7453
7252
  const issues = runtimePlaceholderIssues(project.runtime_validation);
@@ -8136,19 +7935,19 @@ function operationReadmeTemplate(operation, manifest, warning) {
8136
7935
  "- `stubs.ts`: mock fallback used when `SIGLUME_API_KEY` is not set",
8137
7936
  "- `manifest.json`: reviewable manifest snapshot",
8138
7937
  "- `tool_manual.json`: machine-generated ToolManual scaffold",
8139
- "- `runtime_validation.json`: local public endpoint and review-key checks used by auto-register",
7938
+ "- `runtime_validation.json`: local public endpoint + runtime auth header checks used by auto-register",
8140
7939
  "- `docs/api-usage.md`: publishable API usage guide template for `docs_url`",
8141
- "- `.gitignore`: keeps runtime review keys out of Git",
7940
+ "- `.gitignore`: keeps the runtime auth secret out of Git",
8142
7941
  "- `tests/test_adapter.ts`: smoke test for `AppTestHarness`",
8143
7942
  "",
8144
7943
  "Before registering, replace all generated placeholders:",
8145
7944
  "- In `adapter.ts` and `manifest.json`, replace `docs_url` with a dedicated public API usage guide, not a homepage.",
8146
7945
  "- Replace `support_contact` with a real support email address or public support URL.",
8147
7946
  "- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
8148
- "- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
7947
+ "- In the local `runtime_validation.json`, replace the public URL and runtime auth header placeholders (runtime_auth_header_name/value).",
8149
7948
  "- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
8150
- "- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8151
- "- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
7949
+ "- Do not commit the real runtime auth secret or external-provider secrets; the generated `.gitignore` excludes local secret files.",
7950
+ "- Because `runtime_validation.json` is ignored, GitHub samples do not commit runtime auth secret values.",
8152
7951
  "",
8153
7952
  "## Commands",
8154
7953
  "",
@@ -8217,7 +8016,7 @@ function apiUsageDocsTemplate(manifest) {
8217
8016
  }
8218
8017
  function generatedGitignore() {
8219
8018
  return [
8220
- "# Local secrets and registration-only runtime checks.",
8019
+ "# Local secrets (incl. the runtime auth shared secret) and runtime checks.",
8221
8020
  ".env",
8222
8021
  ".env.*",
8223
8022
  "!.env.example",
@@ -8701,16 +8500,16 @@ function readmeTemplate(template) {
8701
8500
  "- `tool_manual.json`: editable ToolManual draft for validation and registration",
8702
8501
  "- `runtime_validation.json`: local live API smoke-test contract used during registration",
8703
8502
  "- `docs/api-usage.md`: publish this page and use its public URL as `docs_url`",
8704
- "- `.gitignore`: keeps runtime review keys out of Git",
8503
+ "- `.gitignore`: keeps the runtime auth secret out of Git",
8705
8504
  "",
8706
8505
  "Before registering, replace all generated placeholders:",
8707
8506
  "- In `adapter.ts` and `manifest.json`, replace `docs_url` with a dedicated public API usage guide, not a homepage.",
8708
8507
  "- Replace `support_contact` with a real support email address or public support URL.",
8709
8508
  "- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
8710
- "- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
8509
+ "- In the local `runtime_validation.json`, replace the public URL and runtime auth header placeholders (runtime_auth_header_name/value).",
8711
8510
  "- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
8712
- "- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8713
- "- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
8511
+ "- Do not commit the real runtime auth secret or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8512
+ "- Because `runtime_validation.json` is ignored, GitHub samples do not commit runtime auth secret values.",
8714
8513
  "",
8715
8514
  "Suggested workflow:",
8716
8515
  "",