@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.
@@ -355,7 +355,12 @@ var init_webhooks = __esm({
355
355
  "capability.published",
356
356
  "capability.delisted",
357
357
  "execution.completed",
358
- "execution.failed"
358
+ "execution.failed",
359
+ "reward_payout.created",
360
+ "reward_payout.provider_pending",
361
+ "reward_paid",
362
+ "reward_payout.failed",
363
+ "reward_payout.cancelled"
359
364
  ];
360
365
  WEBHOOK_EVENT_SET = new Set(WEBHOOK_EVENT_TYPES);
361
366
  }
@@ -1405,6 +1410,23 @@ function validatePricingPlanFloor(plan, defaultCurrency) {
1405
1410
  function pricingPlanHasItems(plan) {
1406
1411
  return isRecord(plan) && Array.isArray(plan.items) && plan.items.length > 0;
1407
1412
  }
1413
+ function validateListingTextLengths(payload) {
1414
+ const limits = {
1415
+ short_description: LISTING_SHORT_DESCRIPTION_MAX_LENGTH,
1416
+ job_to_be_done: LISTING_JOB_TO_BE_DONE_MAX_LENGTH,
1417
+ description: LISTING_DESCRIPTION_MAX_LENGTH
1418
+ };
1419
+ for (const [fieldName, maxLength] of Object.entries(limits)) {
1420
+ const value = payload[fieldName];
1421
+ if (value === void 0 || value === null) continue;
1422
+ if (typeof value !== "string") {
1423
+ throw new SiglumeClientError(`AppManifest.${fieldName} must be a string when provided.`);
1424
+ }
1425
+ if (Array.from(value).length > maxLength) {
1426
+ throw new SiglumeClientError(`AppManifest.${fieldName} must be at most ${maxLength} characters.`);
1427
+ }
1428
+ }
1429
+ }
1408
1430
  function buildToolManualQualityReport(payload) {
1409
1431
  const qualityBlock = isRecord(payload.quality) ? payload.quality : payload;
1410
1432
  const issues = [];
@@ -1962,139 +1984,6 @@ function parseInstalledToolReceiptStep(data) {
1962
1984
  raw: { ...data }
1963
1985
  };
1964
1986
  }
1965
- function toRecordList(value) {
1966
- return Array.isArray(value) ? value.filter((item) => isRecord(item)).map((item) => ({ ...item })) : [];
1967
- }
1968
- function parsePartnerDashboard(data) {
1969
- return {
1970
- partner_id: String(data.partner_id ?? data.user_id ?? ""),
1971
- company_name: stringOrNull(data.company_name) ?? void 0,
1972
- plan: stringOrNull(data.plan) ?? void 0,
1973
- plan_label: stringOrNull(data.plan_label) ?? void 0,
1974
- month_bytes_used: Math.trunc(Number(data.month_bytes_used ?? 0)),
1975
- month_bytes_limit: Math.trunc(Number(data.month_bytes_limit ?? 0)),
1976
- month_usage_pct: Number(data.month_usage_pct ?? 0),
1977
- total_source_items: Math.trunc(Number(data.total_source_items ?? 0)),
1978
- has_billing: Boolean(data.has_billing ?? false),
1979
- has_subscription: Boolean(data.has_subscription ?? false),
1980
- raw: { ...data }
1981
- };
1982
- }
1983
- function parsePartnerUsage(data) {
1984
- return {
1985
- plan: stringOrNull(data.plan) ?? void 0,
1986
- month_bytes_used: Math.trunc(Number(data.month_bytes_used ?? 0)),
1987
- month_bytes_limit: Math.trunc(Number(data.month_bytes_limit ?? 0)),
1988
- month_bytes_remaining: Math.trunc(Number(data.month_bytes_remaining ?? 0)),
1989
- month_usage_pct: Number(data.month_usage_pct ?? 0),
1990
- raw: { ...data }
1991
- };
1992
- }
1993
- function parsePartnerApiKey(data) {
1994
- return {
1995
- credential_id: String(data.credential_id ?? data.id ?? ""),
1996
- name: stringOrNull(data.name) ?? void 0,
1997
- key_id: stringOrNull(data.key_id) ?? void 0,
1998
- allowed_source_types: Array.isArray(data.allowed_source_types) ? data.allowed_source_types.filter((item) => typeof item === "string") : [],
1999
- last_used_at: stringOrNull(data.last_used_at) ?? void 0,
2000
- created_at: stringOrNull(data.created_at) ?? void 0,
2001
- revoked: Boolean(data.revoked ?? false),
2002
- raw: { ...data }
2003
- };
2004
- }
2005
- function parsePartnerApiKeyHandle(data) {
2006
- const raw = Object.fromEntries(
2007
- Object.entries(data).filter(([key]) => key !== "ingest_key" && key !== "full_key")
2008
- );
2009
- return {
2010
- credential_id: String(raw.credential_id ?? raw.id ?? ""),
2011
- name: stringOrNull(raw.name) ?? void 0,
2012
- key_id: stringOrNull(raw.key_id) ?? void 0,
2013
- allowed_source_types: Array.isArray(raw.allowed_source_types) ? raw.allowed_source_types.filter((item) => typeof item === "string") : [],
2014
- masked_key_hint: stringOrNull(raw.masked_key_hint) ?? void 0,
2015
- raw
2016
- };
2017
- }
2018
- function parseAdsBilling(data) {
2019
- return {
2020
- currency: stringOrNull(data.currency) ?? void 0,
2021
- billing_mode: stringOrNull(data.billing_mode) ?? void 0,
2022
- month_spend_jpy: Math.trunc(Number(data.month_spend_jpy ?? 0)),
2023
- month_spend_usd: Math.trunc(Number(data.month_spend_usd ?? 0)),
2024
- all_time_spend_jpy: Math.trunc(Number(data.all_time_spend_jpy ?? 0)),
2025
- all_time_spend_usd: Math.trunc(Number(data.all_time_spend_usd ?? 0)),
2026
- total_impressions: Math.trunc(Number(data.total_impressions ?? 0)),
2027
- total_replies: Math.trunc(Number(data.total_replies ?? 0)),
2028
- has_billing: Boolean(data.has_billing ?? false),
2029
- has_subscription: Boolean(data.has_subscription ?? false),
2030
- invoices: toRecordList(data.invoices),
2031
- wallet: isRecord(data.wallet) ? { ...data.wallet } : null,
2032
- balances: toRecordList(data.balances),
2033
- supported_tokens: toRecordList(data.supported_tokens),
2034
- funding_instructions: isRecord(data.funding_instructions) ? { ...data.funding_instructions } : null,
2035
- mandate: isRecord(data.mandate) ? parsePlanWeb3Mandate(data.mandate) : null,
2036
- raw: { ...data }
2037
- };
2038
- }
2039
- function parseAdsBillingSettlement(data) {
2040
- return {
2041
- status: stringOrNull(data.status) ?? void 0,
2042
- message: stringOrNull(data.message ?? data.detail) ?? void 0,
2043
- settles_automatically: typeof data.settles_automatically === "boolean" ? data.settles_automatically : typeof data.auto_settles === "boolean" ? data.auto_settles : void 0,
2044
- cycle_key: stringOrNull(data.cycle_key) ?? void 0,
2045
- settled_at: stringOrNull(data.settled_at) ?? void 0,
2046
- raw: { ...data }
2047
- };
2048
- }
2049
- function parseAdsProfile(data) {
2050
- return {
2051
- has_profile: Boolean(data.has_profile ?? false),
2052
- company_name: stringOrNull(data.company_name) ?? void 0,
2053
- ad_currency: stringOrNull(data.ad_currency) ?? void 0,
2054
- has_billing: Boolean(data.has_billing ?? false),
2055
- raw: { ...data }
2056
- };
2057
- }
2058
- function parseAdsCampaign(data) {
2059
- return {
2060
- campaign_id: String(data.campaign_id ?? data.id ?? ""),
2061
- name: stringOrNull(data.name) ?? void 0,
2062
- target_url: stringOrNull(data.target_url) ?? void 0,
2063
- content_brief: stringOrNull(data.content_brief) ?? void 0,
2064
- target_topics: Array.isArray(data.target_topics) ? data.target_topics.filter((item) => typeof item === "string") : [],
2065
- posting_interval_minutes: Math.trunc(Number(data.posting_interval_minutes ?? 360)),
2066
- max_posts_per_day: Math.trunc(Number(data.max_posts_per_day ?? 4)),
2067
- currency: stringOrNull(data.currency) ?? void 0,
2068
- monthly_budget_jpy: Math.trunc(Number(data.monthly_budget_jpy ?? 0)),
2069
- cpm_jpy: Math.trunc(Number(data.cpm_jpy ?? 0)),
2070
- cpr_jpy: Math.trunc(Number(data.cpr_jpy ?? 0)),
2071
- monthly_budget_usd: Math.trunc(Number(data.monthly_budget_usd ?? 0)),
2072
- cpm_usd: Math.trunc(Number(data.cpm_usd ?? 0)),
2073
- cpr_usd: Math.trunc(Number(data.cpr_usd ?? 0)),
2074
- status: String(data.status ?? "active").trim().toLowerCase() || "active",
2075
- month_spend_jpy: Math.trunc(Number(data.month_spend_jpy ?? 0)),
2076
- month_spend_usd: Math.trunc(Number(data.month_spend_usd ?? 0)),
2077
- total_posts: Math.trunc(Number(data.total_posts ?? 0)),
2078
- total_impressions: Math.trunc(Number(data.total_impressions ?? 0)),
2079
- total_replies: Math.trunc(Number(data.total_replies ?? 0)),
2080
- next_post_at: stringOrNull(data.next_post_at) ?? void 0,
2081
- created_at: stringOrNull(data.created_at) ?? void 0,
2082
- raw: { ...data }
2083
- };
2084
- }
2085
- function parseAdsCampaignPost(data) {
2086
- return {
2087
- post_id: String(data.post_id ?? data.id ?? ""),
2088
- content_id: stringOrNull(data.content_id) ?? void 0,
2089
- cost_jpy: Math.trunc(Number(data.cost_jpy ?? 0)),
2090
- cost_usd: Math.trunc(Number(data.cost_usd ?? 0)),
2091
- impressions: Math.trunc(Number(data.impressions ?? 0)),
2092
- replies: Math.trunc(Number(data.replies ?? 0)),
2093
- status: stringOrNull(data.status) ?? void 0,
2094
- created_at: stringOrNull(data.created_at) ?? void 0,
2095
- raw: { ...data }
2096
- };
2097
- }
2098
1987
  function parseWorksCategory(data) {
2099
1988
  return {
2100
1989
  key: String(data.key ?? ""),
@@ -2593,7 +2482,7 @@ function cloneJsonLike(value) {
2593
2482
  }
2594
2483
  return value;
2595
2484
  }
2596
- var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, MINIMUM_JPY_OPERATION_PRICE_CURRENCIES, CursorPageResult, SiglumeClient;
2485
+ 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;
2597
2486
  var init_client = __esm({
2598
2487
  "src/client.ts"() {
2599
2488
  "use strict";
@@ -2606,6 +2495,9 @@ var init_client = __esm({
2606
2495
  DEFAULT_SIGLUME_API_BASE = "https://siglume.com/v1";
2607
2496
  RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
2608
2497
  MINIMUM_JPY_OPERATION_PRICE_CURRENCIES = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
2498
+ LISTING_SHORT_DESCRIPTION_MAX_LENGTH = 60;
2499
+ LISTING_JOB_TO_BE_DONE_MAX_LENGTH = 240;
2500
+ LISTING_DESCRIPTION_MAX_LENGTH = 1e3;
2609
2501
  CursorPageResult = class {
2610
2502
  items;
2611
2503
  next_cursor;
@@ -2759,6 +2651,7 @@ var init_client = __esm({
2759
2651
  if (payload.pricing_plan !== void 0) {
2760
2652
  validatePricingPlanFloor(payload.pricing_plan, currency);
2761
2653
  }
2654
+ validateListingTextLengths(payload);
2762
2655
  const priceModel = String(payload.price_model ?? "free").trim().toLowerCase();
2763
2656
  if ((priceModel === "usage_based" || priceModel === "per_action") && !pricingPlanHasItems(payload.pricing_plan)) {
2764
2657
  throw new SiglumeClientError("AppManifest.pricing_plan.items is required for usage_based/per_action pricing.");
@@ -3901,115 +3794,6 @@ var init_client = __esm({
3901
3794
  );
3902
3795
  return Array.isArray(data.result) ? data.result.filter((item) => isRecord(item)).map((item) => parseInstalledToolReceiptStep(item)) : [];
3903
3796
  }
3904
- async get_partner_dashboard(options = {}) {
3905
- const execution = await this.execute_owner_operation(
3906
- await this.resolveOwnerOperationAgentId(options.agent_id),
3907
- "partner.dashboard.get",
3908
- {},
3909
- { lang: options.lang }
3910
- );
3911
- return parsePartnerDashboard(execution.result);
3912
- }
3913
- async get_partner_usage(options = {}) {
3914
- const execution = await this.execute_owner_operation(
3915
- await this.resolveOwnerOperationAgentId(options.agent_id),
3916
- "partner.usage.get",
3917
- {},
3918
- { lang: options.lang }
3919
- );
3920
- return parsePartnerUsage(execution.result);
3921
- }
3922
- async list_partner_api_keys(options = {}) {
3923
- const execution = await this.execute_owner_operation(
3924
- await this.resolveOwnerOperationAgentId(options.agent_id),
3925
- "partner.keys.list",
3926
- {},
3927
- { lang: options.lang }
3928
- );
3929
- return Array.isArray(execution.result.keys) ? execution.result.keys.filter((item) => isRecord(item)).map((item) => parsePartnerApiKey(item)) : [];
3930
- }
3931
- async create_partner_api_key(options = {}) {
3932
- const payload = {};
3933
- if (options.name !== void 0) {
3934
- const normalizedName = String(options.name).trim();
3935
- if (!normalizedName) {
3936
- throw new SiglumeClientError("name cannot be empty.");
3937
- }
3938
- payload.name = normalizedName;
3939
- }
3940
- if (options.allowed_source_types !== void 0) {
3941
- if (!Array.isArray(options.allowed_source_types)) {
3942
- throw new SiglumeClientError("allowed_source_types must be a list of strings.");
3943
- }
3944
- payload.allowed_source_types = options.allowed_source_types.flatMap((item) => {
3945
- if (typeof item !== "string") {
3946
- throw new SiglumeClientError("allowed_source_types must contain only strings.");
3947
- }
3948
- const normalizedItem = item.trim();
3949
- return normalizedItem ? [normalizedItem] : [];
3950
- });
3951
- }
3952
- const execution = await this.execute_owner_operation(
3953
- await this.resolveOwnerOperationAgentId(options.agent_id),
3954
- "partner.keys.create",
3955
- payload,
3956
- { lang: options.lang }
3957
- );
3958
- return parsePartnerApiKeyHandle(execution.result);
3959
- }
3960
- async get_ads_billing(options = {}) {
3961
- const payload = {};
3962
- if (options.rail !== void 0 && String(options.rail).trim()) {
3963
- payload.rail = String(options.rail).trim().toLowerCase();
3964
- }
3965
- const execution = await this.execute_owner_operation(
3966
- await this.resolveOwnerOperationAgentId(options.agent_id),
3967
- "ads.billing.get",
3968
- payload,
3969
- { lang: options.lang }
3970
- );
3971
- return parseAdsBilling(execution.result);
3972
- }
3973
- async settle_ads_billing(options = {}) {
3974
- const execution = await this.execute_owner_operation(
3975
- await this.resolveOwnerOperationAgentId(options.agent_id),
3976
- "ads.billing.settle",
3977
- {},
3978
- { lang: options.lang }
3979
- );
3980
- return parseAdsBillingSettlement(execution.result);
3981
- }
3982
- async get_ads_profile(options = {}) {
3983
- const execution = await this.execute_owner_operation(
3984
- await this.resolveOwnerOperationAgentId(options.agent_id),
3985
- "ads.profile.get",
3986
- {},
3987
- { lang: options.lang }
3988
- );
3989
- return parseAdsProfile(execution.result);
3990
- }
3991
- async list_ads_campaigns(options = {}) {
3992
- const execution = await this.execute_owner_operation(
3993
- await this.resolveOwnerOperationAgentId(options.agent_id),
3994
- "ads.campaigns.list",
3995
- {},
3996
- { lang: options.lang }
3997
- );
3998
- return Array.isArray(execution.result.campaigns) ? execution.result.campaigns.filter((item) => isRecord(item)).map((item) => parseAdsCampaign(item)) : [];
3999
- }
4000
- async list_ads_campaign_posts(campaign_id, options = {}) {
4001
- const normalizedCampaignId = String(campaign_id ?? "").trim();
4002
- if (!normalizedCampaignId) {
4003
- throw new SiglumeClientError("campaign_id is required.");
4004
- }
4005
- const execution = await this.execute_owner_operation(
4006
- await this.resolveOwnerOperationAgentId(options.agent_id),
4007
- "ads.campaign_posts.list",
4008
- { campaign_id: normalizedCampaignId },
4009
- { lang: options.lang }
4010
- );
4011
- return Array.isArray(execution.result.posts) ? execution.result.posts.filter((item) => isRecord(item)).map((item) => parseAdsCampaignPost(item)) : [];
4012
- }
4013
3797
  // `market.proposals.*` currently rides on the public owner-operation execute
4014
3798
  // route. Read helpers return typed proposal records; guarded mutations return
4015
3799
  // the approval envelope without treating it as an error.
@@ -5944,12 +5728,15 @@ function validate_tool_manual(manualInput) {
5944
5728
  pushError("INVALID_TOOL_NAME", "tool_name must be alphanumeric + underscore, 3-64 chars", "tool_name");
5945
5729
  }
5946
5730
  for (const [fieldName, minLength, maxLength] of [
5947
- ["job_to_be_done", 10, 500],
5731
+ ["job_to_be_done", 10, 240],
5948
5732
  ["summary_for_model", 10, 300]
5949
5733
  ]) {
5950
5734
  const value = manual[fieldName];
5951
- if (typeof value === "string" && (value.length < minLength || value.length > maxLength)) {
5952
- pushError("INVALID_TYPE", `${fieldName} must be ${minLength}-${maxLength} characters`, fieldName);
5735
+ if (typeof value === "string") {
5736
+ const length = Array.from(value).length;
5737
+ if (length < minLength || length > maxLength) {
5738
+ pushError("INVALID_TYPE", `${fieldName} must be ${minLength}-${maxLength} characters`, fieldName);
5739
+ }
5953
5740
  }
5954
5741
  }
5955
5742
  const triggerConditions = manual.trigger_conditions;
@@ -7137,8 +6924,12 @@ function buildRuntimeValidationTemplate(toolManual) {
7137
6924
  healthcheck_url: "https://api.example.com/health",
7138
6925
  invoke_url: "https://api.example.com/invoke",
7139
6926
  invoke_method: "POST",
7140
- test_auth_header_name: "X-Siglume-Review-Key",
7141
- test_auth_header_value: "replace-with-dedicated-review-key",
6927
+ // Shared secret Siglume attaches when it calls invoke_url at both
6928
+ // registration validation and production runtime. Use a strong random
6929
+ // value, keep it in the Git-ignored runtime_validation.json, and rotate it
6930
+ // if it leaks. (legacy aliases: test_auth_header_name/value)
6931
+ runtime_auth_header_name: "X-Siglume-Auth",
6932
+ runtime_auth_header_value: "replace-with-strong-random-runtime-auth-secret",
7142
6933
  request_payload: requestPayload,
7143
6934
  expected_response_fields: expectedFields.length > 0 ? expectedFields : ["summary"],
7144
6935
  timeout_seconds: 10
@@ -7443,8 +7234,6 @@ function runtimePlaceholderIssues(runtimeValidation) {
7443
7234
  "public_base_url",
7444
7235
  "healthcheck_url",
7445
7236
  "invoke_url",
7446
- "test_auth_header_name",
7447
- "test_auth_header_value",
7448
7237
  "expected_response_fields"
7449
7238
  ]) {
7450
7239
  if (!runtimeValidation[fieldName]) {
@@ -7457,9 +7246,19 @@ function runtimePlaceholderIssues(runtimeValidation) {
7457
7246
  issues.push(`runtime_validation.${fieldName} must be replaced with your public production URL`);
7458
7247
  }
7459
7248
  }
7460
- const authValue = String(runtimeValidation.test_auth_header_value ?? "").trim();
7249
+ const authName = String(
7250
+ runtimeValidation.runtime_auth_header_name || runtimeValidation.test_auth_header_name || ""
7251
+ ).trim();
7252
+ if (!authName) {
7253
+ issues.push("runtime_validation.runtime_auth_header_name is required");
7254
+ }
7255
+ const authValue = String(
7256
+ runtimeValidation.runtime_auth_header_value || runtimeValidation.test_auth_header_value || ""
7257
+ ).trim();
7461
7258
  if (!authValue || authValue.startsWith("replace-with-")) {
7462
- issues.push("runtime_validation.test_auth_header_value must be a dedicated review secret, not a placeholder");
7259
+ issues.push(
7260
+ "runtime_validation.runtime_auth_header_value must be a strong, dedicated runtime auth secret, not a placeholder"
7261
+ );
7463
7262
  }
7464
7263
  const requestPayload = runtimeValidation.request_payload ?? runtimeValidation.test_request_body ?? runtimeValidation.runtime_sample ?? runtimeValidation.sample_request_payload ?? runtimeValidation.runtime_sample_request;
7465
7264
  if (!isRecord(requestPayload)) {
@@ -7474,7 +7273,7 @@ function runtimePlaceholderIssues(runtimeValidation) {
7474
7273
  function ensureRuntimeValidationReady(project) {
7475
7274
  if (!project.runtime_validation) {
7476
7275
  throw new SiglumeProjectError(
7477
- "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."
7276
+ "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."
7478
7277
  );
7479
7278
  }
7480
7279
  const issues = runtimePlaceholderIssues(project.runtime_validation);
@@ -8163,19 +7962,19 @@ function operationReadmeTemplate(operation, manifest, warning) {
8163
7962
  "- `stubs.ts`: mock fallback used when `SIGLUME_API_KEY` is not set",
8164
7963
  "- `manifest.json`: reviewable manifest snapshot",
8165
7964
  "- `tool_manual.json`: machine-generated ToolManual scaffold",
8166
- "- `runtime_validation.json`: local public endpoint and review-key checks used by auto-register",
7965
+ "- `runtime_validation.json`: local public endpoint + runtime auth header checks used by auto-register",
8167
7966
  "- `docs/api-usage.md`: publishable API usage guide template for `docs_url`",
8168
- "- `.gitignore`: keeps runtime review keys out of Git",
7967
+ "- `.gitignore`: keeps the runtime auth secret out of Git",
8169
7968
  "- `tests/test_adapter.ts`: smoke test for `AppTestHarness`",
8170
7969
  "",
8171
7970
  "Before registering, replace all generated placeholders:",
8172
7971
  "- In `adapter.ts` and `manifest.json`, replace `docs_url` with a dedicated public API usage guide, not a homepage.",
8173
7972
  "- Replace `support_contact` with a real support email address or public support URL.",
8174
7973
  "- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
8175
- "- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
7974
+ "- In the local `runtime_validation.json`, replace the public URL and runtime auth header placeholders (runtime_auth_header_name/value).",
8176
7975
  "- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
8177
- "- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8178
- "- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
7976
+ "- Do not commit the real runtime auth secret or external-provider secrets; the generated `.gitignore` excludes local secret files.",
7977
+ "- Because `runtime_validation.json` is ignored, GitHub samples do not commit runtime auth secret values.",
8179
7978
  "",
8180
7979
  "## Commands",
8181
7980
  "",
@@ -8244,7 +8043,7 @@ function apiUsageDocsTemplate(manifest) {
8244
8043
  }
8245
8044
  function generatedGitignore() {
8246
8045
  return [
8247
- "# Local secrets and registration-only runtime checks.",
8046
+ "# Local secrets (incl. the runtime auth shared secret) and runtime checks.",
8248
8047
  ".env",
8249
8048
  ".env.*",
8250
8049
  "!.env.example",
@@ -8728,16 +8527,16 @@ function readmeTemplate(template) {
8728
8527
  "- `tool_manual.json`: editable ToolManual draft for validation and registration",
8729
8528
  "- `runtime_validation.json`: local live API smoke-test contract used during registration",
8730
8529
  "- `docs/api-usage.md`: publish this page and use its public URL as `docs_url`",
8731
- "- `.gitignore`: keeps runtime review keys out of Git",
8530
+ "- `.gitignore`: keeps the runtime auth secret out of Git",
8732
8531
  "",
8733
8532
  "Before registering, replace all generated placeholders:",
8734
8533
  "- In `adapter.ts` and `manifest.json`, replace `docs_url` with a dedicated public API usage guide, not a homepage.",
8735
8534
  "- Replace `support_contact` with a real support email address or public support URL.",
8736
8535
  "- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
8737
- "- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
8536
+ "- In the local `runtime_validation.json`, replace the public URL and runtime auth header placeholders (runtime_auth_header_name/value).",
8738
8537
  "- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
8739
- "- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8740
- "- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
8538
+ "- Do not commit the real runtime auth secret or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8539
+ "- Because `runtime_validation.json` is ignored, GitHub samples do not commit runtime auth secret values.",
8741
8540
  "",
8742
8541
  "Suggested workflow:",
8743
8542
  "",