@tool-bridge/server 0.16.0 → 0.17.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.
Files changed (115) hide show
  1. package/dist/{airtable-S3T4TAN7.js → airtable-NOSOMOVB.js} +106 -114
  2. package/dist/{alt_text_generator_ai-4DIRIDKL.js → alt_text_generator_ai-BHIJ4LW5.js} +25 -16
  3. package/dist/{amap-LGVGNPML.js → amap-QRLP4TWZ.js} +114 -123
  4. package/dist/{anthropic-27RFZO35.js → anthropic-IEOI36EV.js} +34 -56
  5. package/dist/{apify-6WLYAIAS.js → apify-3CCYTQVK.js} +31 -49
  6. package/dist/{brave_search-K2SVJ66F.js → brave_search-PZNYDQG7.js} +52 -77
  7. package/dist/chunk-JXHMDBAY.js +45 -0
  8. package/dist/chunk-LMLX3DJF.js +50 -0
  9. package/dist/{chunk-YB2FLNWI.js → chunk-RVWZN3CI.js} +2103 -1775
  10. package/dist/{chunk-BB6ZLMTU.js → chunk-TLNUIPFZ.js} +492 -300
  11. package/dist/chunk-U5UHT7CX.js +977 -0
  12. package/dist/chunk-U67V476Y.js +35 -0
  13. package/dist/chunk-WW2IMPQK.js +283 -0
  14. package/dist/{chunk-VK3V2WTY.js → chunk-YASUMV2K.js} +4 -6
  15. package/dist/{circleci-WV3ITU7Q.js → circleci-VSJ4O5FC.js} +36 -55
  16. package/dist/{clerk-NFQEFKS4.js → clerk-CC2JZBZI.js} +60 -80
  17. package/dist/{cloudflare_dns-2RK5ASBJ.js → cloudflare_dns-PJEBSEYQ.js} +90 -113
  18. package/dist/{cohere-5KEW7LWT.js → cohere-KBACYSPF.js} +33 -49
  19. package/dist/{confluence-SZE63S46.js → confluence-2PX3O7G5.js} +79 -115
  20. package/dist/{convertapi-QPG2JC5K.js → convertapi-BVOTD2PJ.js} +13 -16
  21. package/dist/{currencyapi-UO2APQRY.js → currencyapi-6ZQ2VNQ7.js} +30 -53
  22. package/dist/{deepseek-LJELIMM3.js → deepseek-MB3WVVTB.js} +30 -38
  23. package/dist/{docker_hub-2MFXSBOF.js → docker_hub-7CLQL2IJ.js} +141 -157
  24. package/dist/{dropbox-GQYNTTVA.js → dropbox-VFYDVUNK.js} +134 -141
  25. package/dist/{dub-KI2LHXST.js → dub-QN3EETJY.js} +61 -93
  26. package/dist/{e2b-WO6ISY3C.js → e2b-NKC3Y776.js} +39 -69
  27. package/dist/{exa-IZ7B3BPT.js → exa-KKZ6F25K.js} +49 -77
  28. package/dist/{fal_ai-LTMF36GJ.js → fal_ai-25LYJD2O.js} +37 -44
  29. package/dist/{feishu-WM7SLSFD.js → feishu-NRT55B3Q.js} +4 -6
  30. package/dist/{feishu_custom_bot-66W3MXH2.js → feishu_custom_bot-3W3XXUG4.js} +4 -5
  31. package/dist/{figma-2Z274VQZ.js → figma-4FLP35TC.js} +56 -81
  32. package/dist/{firehydrant-IFI4R65V.js → firehydrant-BLXPLZ3X.js} +40 -53
  33. package/dist/{fixer-BCCZEB3D.js → fixer-4OR62TGE.js} +31 -43
  34. package/dist/{fly-755FXYB5.js → fly-MYCKOZZK.js} +50 -66
  35. package/dist/{front-4FZKKXXK.js → front-3DFYVMF3.js} +43 -66
  36. package/dist/{geocodio-WYKDJ3DP.js → geocodio-CXMD6VKA.js} +37 -63
  37. package/dist/{ghost-5BNQTCOH.js → ghost-4UUE737W.js} +51 -57
  38. package/dist/{github-ULELF5VX.js → github-WFS2ON2N.js} +48 -41
  39. package/dist/{gmail-G34WT64J.js → gmail-KW7FXA7A.js} +26 -36
  40. package/dist/{googlecalendar-BQU255SC.js → googlecalendar-AMH5JQMC.js} +57 -78
  41. package/dist/{googledocs-HPCNQXYJ.js → googledocs-R5VA6CKD.js} +14 -22
  42. package/dist/{grafana-VOV24FIC.js → grafana-IT6DWIVB.js} +95 -122
  43. package/dist/{graphhopper-D5RXW6AP.js → graphhopper-TYFDJZWC.js} +32 -46
  44. package/dist/index.d.ts +57 -50
  45. package/dist/index.js +4 -3
  46. package/dist/{ip2proxy-DAYO7EKZ.js → ip2proxy-GJ4HXVXO.js} +35 -42
  47. package/dist/{ipgeolocation_io-XD4PSLII.js → ipgeolocation_io-OAGR6PRF.js} +40 -60
  48. package/dist/{ipqualityscore-K27QEAWK.js → ipqualityscore-BCKAMDGL.js} +30 -42
  49. package/dist/{jina_ai-E6UXFV2P.js → jina_ai-N3NXRVIZ.js} +32 -58
  50. package/dist/{jira-ZDSXGQ6W.js → jira-CHLBKWLO.js} +116 -126
  51. package/dist/{langsmith-TIFJRREW.js → langsmith-OIKOTPY3.js} +101 -121
  52. package/dist/{lemlist-DASEMJMA.js → lemlist-VAKYPKS3.js} +57 -68
  53. package/dist/{linear-KE6UP4SP.js → linear-Q6QTPJ5R.js} +109 -118
  54. package/dist/{logsnag-IMNDN4R5.js → logsnag-SQOQBTES.js} +31 -48
  55. package/dist/main.js +103 -102
  56. package/dist/{mattermost-HHHMUXQA.js → mattermost-G2KBEICM.js} +45 -62
  57. package/dist/{mem0-D2FGGOIY.js → mem0-D2FPLYDX.js} +72 -98
  58. package/dist/{memos-4OVIGFPH.js → memos-76PTWV5V.js} +68 -122
  59. package/dist/{metabase-33WCX5YD.js → metabase-TWSIDVBM.js} +47 -60
  60. package/dist/{mistral_ai-QIMZ2JYL.js → mistral_ai-TP7TQUEJ.js} +35 -40
  61. package/dist/{mother_duck-M6VWS2VH.js → mother_duck-UXY5THYU.js} +42 -62
  62. package/dist/{ngrok-Z2PKQBHH.js → ngrok-RZW2ISJK.js} +42 -58
  63. package/dist/{notes-SS4RPC4K.js → notes-B2I6FWK2.js} +3 -5
  64. package/dist/{notion-FJCNQ6I7.js → notion-QOKRUE6M.js} +83 -97
  65. package/dist/{open_exchange_rates-WU57WTT5.js → open_exchange_rates-ODLFWEJ7.js} +35 -39
  66. package/dist/{openai-JODZ4GKT.js → openai-ZPBPPPGT.js} +51 -55
  67. package/dist/{opengraph_io-SQRAUSV5.js → opengraph_io-EOI5UJKT.js} +61 -79
  68. package/dist/{openrouter-Q5XXEJZ7.js → openrouter-BUWLF3BG.js} +41 -55
  69. package/dist/{outline-RT2EHJ2X.js → outline-NXS3QRXO.js} +89 -104
  70. package/dist/{paddle-OF2V7GAC.js → paddle-T4MSKQ76.js} +34 -49
  71. package/dist/{perplexity-LNZEWLHG.js → perplexity-WW5N2LW7.js} +33 -50
  72. package/dist/{pinecone-JSJIXZYN.js → pinecone-RY5AZPQM.js} +65 -91
  73. package/dist/{pipedrive-D4CKVUXR.js → pipedrive-OHYQNZTU.js} +37 -59
  74. package/dist/{polar-M7ZYP6UR.js → polar-XZIAHXS5.js} +43 -53
  75. package/dist/{posthog-YV7CZOH4.js → posthog-DTPTWORY.js} +58 -77
  76. package/dist/{postmark-KYHLECRG.js → postmark-F4UCQKC3.js} +52 -71
  77. package/dist/{prerender-HCMHBKV2.js → prerender-P3Y2MLIC.js} +32 -50
  78. package/dist/{pubmed-WYVLCCN3.js → pubmed-RHU3GXFB.js} +28 -60
  79. package/dist/{railway-TWIRD5KR.js → railway-VB6SRLI6.js} +32 -39
  80. package/dist/{readwise-UZ467IQ7.js → readwise-DIMSKJZR.js} +62 -78
  81. package/dist/{render-MECUC5CC.js → render-XCCDCEEK.js} +48 -64
  82. package/dist/{replicate-A5MEK3SW.js → replicate-IUEOQ4JC.js} +41 -58
  83. package/dist/{resend-BC6EAWJQ.js → resend-N5MJZH5E.js} +27 -37
  84. package/dist/{rootly-ZM3QDUIS.js → rootly-25T4NBTU.js} +64 -76
  85. package/dist/{scrapfly-WAML42QJ.js → scrapfly-PK4XFXUA.js} +45 -51
  86. package/dist/{scrapingbee-DG7PET3V.js → scrapingbee-ITPBMWQU.js} +25 -33
  87. package/dist/{screenshot_fyi-HY6WTHIO.js → screenshot_fyi-5U6ZYPKR.js} +29 -47
  88. package/dist/{semantic_scholar-C5IZA7IP.js → semantic_scholar-BJGCI2MU.js} +37 -56
  89. package/dist/{sentry-OKBPSTDM.js → sentry-63IC263P.js} +66 -85
  90. package/dist/{shodan-PPC6DYU4.js → shodan-2WBIFHFN.js} +42 -53
  91. package/dist/{shopify-EWGUHBXO.js → shopify-XLLJRAGM.js} +32 -49
  92. package/dist/{stripe-6RPDPC5W.js → stripe-WLVCY3UN.js} +4 -5
  93. package/dist/{supabase-SK7DQ42N.js → supabase-BKNZ35ER.js} +69 -88
  94. package/dist/{tavily-YCG5VQMH.js → tavily-YFSDEUTL.js} +37 -62
  95. package/dist/{telegram-2OES5FYB.js → telegram-FC35W74G.js} +168 -177
  96. package/dist/{telnyx-POOSBBR4.js → telnyx-MI32XZUG.js} +30 -50
  97. package/dist/{todoist-M7YD6YSS.js → todoist-4ZFJKZC6.js} +77 -89
  98. package/dist/{trello-IS6V5W3E.js → trello-UOGFNMK4.js} +108 -122
  99. package/dist/{turso-RCFHUFVH.js → turso-YTSTW3ZS.js} +52 -64
  100. package/dist/{twilio-OS2RXFGO.js → twilio-XAJDFUQH.js} +48 -55
  101. package/dist/{umami-PQ2SJ2LN.js → umami-ZVIUBPAI.js} +49 -69
  102. package/dist/{unsplash-C6BPZO4E.js → unsplash-IU3PLDNS.js} +35 -52
  103. package/dist/{upstash_redis-WH6UER7H.js → upstash_redis-3EYJW7SY.js} +28 -40
  104. package/dist/{uptimerobot-M3YZGS6Z.js → uptimerobot-PJG2ASRU.js} +11 -12
  105. package/dist/{v2ex-R4JWTEHN.js → v2ex-KFQWWGFC.js} +36 -61
  106. package/dist/{vercel-FZVYUOQD.js → vercel-I2ZDOQRL.js} +124 -150
  107. package/dist/{webapi-VLM4IKVB.js → webapi-GW5QXWXE.js} +1 -1
  108. package/dist/{wolfram_alpha_api-2KOLO5DC.js → wolfram_alpha_api-BNXOJMB6.js} +26 -34
  109. package/dist/{wordpress-XRWGO6LG.js → wordpress-36D7BSMP.js} +87 -104
  110. package/dist/{workos-WR4NKOYL.js → workos-6X4JJRRC.js} +37 -56
  111. package/dist/{zhihu-BKZIB3WA.js → zhihu-CIXKCHIU.js} +35 -57
  112. package/package.json +5 -5
  113. package/dist/chunk-2O27H4Y2.js +0 -183
  114. package/dist/chunk-GKX72JMJ.js +0 -378
  115. package/dist/chunk-MLKGABMK.js +0 -9
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  __export
3
- } from "./chunk-MLKGABMK.js";
3
+ } from "./chunk-U67V476Y.js";
4
4
 
5
5
  // ../core/src/errors.ts
6
6
  var TB_ERROR_CODES = [
@@ -11851,29 +11851,29 @@ var formatMap = {
11851
11851
  // do not set
11852
11852
  };
11853
11853
  var stringProcessor = (schema, ctx, _json, _params) => {
11854
- const json2 = _json;
11855
- json2.type = "string";
11854
+ const json3 = _json;
11855
+ json3.type = "string";
11856
11856
  const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag;
11857
11857
  if (typeof minimum === "number")
11858
- json2.minLength = minimum;
11858
+ json3.minLength = minimum;
11859
11859
  if (typeof maximum === "number")
11860
- json2.maxLength = maximum;
11860
+ json3.maxLength = maximum;
11861
11861
  if (format) {
11862
- json2.format = formatMap[format] ?? format;
11863
- if (json2.format === "")
11864
- delete json2.format;
11862
+ json3.format = formatMap[format] ?? format;
11863
+ if (json3.format === "")
11864
+ delete json3.format;
11865
11865
  if (format === "time") {
11866
- delete json2.format;
11866
+ delete json3.format;
11867
11867
  }
11868
11868
  }
11869
11869
  if (contentEncoding)
11870
- json2.contentEncoding = contentEncoding;
11870
+ json3.contentEncoding = contentEncoding;
11871
11871
  if (patterns && patterns.size > 0) {
11872
11872
  const regexes = [...patterns];
11873
11873
  if (regexes.length === 1)
11874
- json2.pattern = regexes[0].source;
11874
+ json3.pattern = regexes[0].source;
11875
11875
  else if (regexes.length > 1) {
11876
- json2.allOf = [
11876
+ json3.allOf = [
11877
11877
  ...regexes.map((regex) => ({
11878
11878
  ...ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0" ? { type: "string" } : {},
11879
11879
  pattern: regex.source
@@ -11883,40 +11883,40 @@ var stringProcessor = (schema, ctx, _json, _params) => {
11883
11883
  }
11884
11884
  };
11885
11885
  var numberProcessor = (schema, ctx, _json, _params) => {
11886
- const json2 = _json;
11886
+ const json3 = _json;
11887
11887
  const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
11888
11888
  if (typeof format === "string" && format.includes("int"))
11889
- json2.type = "integer";
11889
+ json3.type = "integer";
11890
11890
  else
11891
- json2.type = "number";
11891
+ json3.type = "number";
11892
11892
  const exMin = typeof exclusiveMinimum === "number" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY);
11893
11893
  const exMax = typeof exclusiveMaximum === "number" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY);
11894
11894
  const legacy = ctx.target === "draft-04" || ctx.target === "openapi-3.0";
11895
11895
  if (exMin) {
11896
11896
  if (legacy) {
11897
- json2.minimum = exclusiveMinimum;
11898
- json2.exclusiveMinimum = true;
11897
+ json3.minimum = exclusiveMinimum;
11898
+ json3.exclusiveMinimum = true;
11899
11899
  } else {
11900
- json2.exclusiveMinimum = exclusiveMinimum;
11900
+ json3.exclusiveMinimum = exclusiveMinimum;
11901
11901
  }
11902
11902
  } else if (typeof minimum === "number") {
11903
- json2.minimum = minimum;
11903
+ json3.minimum = minimum;
11904
11904
  }
11905
11905
  if (exMax) {
11906
11906
  if (legacy) {
11907
- json2.maximum = exclusiveMaximum;
11908
- json2.exclusiveMaximum = true;
11907
+ json3.maximum = exclusiveMaximum;
11908
+ json3.exclusiveMaximum = true;
11909
11909
  } else {
11910
- json2.exclusiveMaximum = exclusiveMaximum;
11910
+ json3.exclusiveMaximum = exclusiveMaximum;
11911
11911
  }
11912
11912
  } else if (typeof maximum === "number") {
11913
- json2.maximum = maximum;
11913
+ json3.maximum = maximum;
11914
11914
  }
11915
11915
  if (typeof multipleOf === "number")
11916
- json2.multipleOf = multipleOf;
11916
+ json3.multipleOf = multipleOf;
11917
11917
  };
11918
- var booleanProcessor = (_schema, _ctx, json2, _params) => {
11919
- json2.type = "boolean";
11918
+ var booleanProcessor = (_schema, _ctx, json3, _params) => {
11919
+ json3.type = "boolean";
11920
11920
  };
11921
11921
  var bigintProcessor = (_schema, ctx, _json, _params) => {
11922
11922
  if (ctx.unrepresentable === "throw") {
@@ -11928,13 +11928,13 @@ var symbolProcessor = (_schema, ctx, _json, _params) => {
11928
11928
  throw new Error("Symbols cannot be represented in JSON Schema");
11929
11929
  }
11930
11930
  };
11931
- var nullProcessor = (_schema, ctx, json2, _params) => {
11931
+ var nullProcessor = (_schema, ctx, json3, _params) => {
11932
11932
  if (ctx.target === "openapi-3.0") {
11933
- json2.type = "string";
11934
- json2.nullable = true;
11935
- json2.enum = [null];
11933
+ json3.type = "string";
11934
+ json3.nullable = true;
11935
+ json3.enum = [null];
11936
11936
  } else {
11937
- json2.type = "null";
11937
+ json3.type = "null";
11938
11938
  }
11939
11939
  };
11940
11940
  var undefinedProcessor = (_schema, ctx, _json, _params) => {
@@ -11947,8 +11947,8 @@ var voidProcessor = (_schema, ctx, _json, _params) => {
11947
11947
  throw new Error("Void cannot be represented in JSON Schema");
11948
11948
  }
11949
11949
  };
11950
- var neverProcessor = (_schema, _ctx, json2, _params) => {
11951
- json2.not = {};
11950
+ var neverProcessor = (_schema, _ctx, json3, _params) => {
11951
+ json3.not = {};
11952
11952
  };
11953
11953
  var anyProcessor = (_schema, _ctx, _json, _params) => {
11954
11954
  };
@@ -11959,16 +11959,16 @@ var dateProcessor = (_schema, ctx, _json, _params) => {
11959
11959
  throw new Error("Date cannot be represented in JSON Schema");
11960
11960
  }
11961
11961
  };
11962
- var enumProcessor = (schema, _ctx, json2, _params) => {
11962
+ var enumProcessor = (schema, _ctx, json3, _params) => {
11963
11963
  const def = schema._zod.def;
11964
11964
  const values = getEnumValues(def.entries);
11965
11965
  if (values.every((v) => typeof v === "number"))
11966
- json2.type = "number";
11966
+ json3.type = "number";
11967
11967
  if (values.every((v) => typeof v === "string"))
11968
- json2.type = "string";
11969
- json2.enum = values;
11968
+ json3.type = "string";
11969
+ json3.enum = values;
11970
11970
  };
11971
- var literalProcessor = (schema, ctx, json2, _params) => {
11971
+ var literalProcessor = (schema, ctx, json3, _params) => {
11972
11972
  const def = schema._zod.def;
11973
11973
  const vals = [];
11974
11974
  for (const val of def.values) {
@@ -11990,22 +11990,22 @@ var literalProcessor = (schema, ctx, json2, _params) => {
11990
11990
  if (vals.length === 0) {
11991
11991
  } else if (vals.length === 1) {
11992
11992
  const val = vals[0];
11993
- json2.type = val === null ? "null" : typeof val;
11993
+ json3.type = val === null ? "null" : typeof val;
11994
11994
  if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") {
11995
- json2.enum = [val];
11995
+ json3.enum = [val];
11996
11996
  } else {
11997
- json2.const = val;
11997
+ json3.const = val;
11998
11998
  }
11999
11999
  } else {
12000
12000
  if (vals.every((v) => typeof v === "number"))
12001
- json2.type = "number";
12001
+ json3.type = "number";
12002
12002
  if (vals.every((v) => typeof v === "string"))
12003
- json2.type = "string";
12003
+ json3.type = "string";
12004
12004
  if (vals.every((v) => typeof v === "boolean"))
12005
- json2.type = "boolean";
12005
+ json3.type = "boolean";
12006
12006
  if (vals.every((v) => v === null))
12007
- json2.type = "null";
12008
- json2.enum = vals;
12007
+ json3.type = "null";
12008
+ json3.enum = vals;
12009
12009
  }
12010
12010
  };
12011
12011
  var nanProcessor = (_schema, ctx, _json, _params) => {
@@ -12013,16 +12013,16 @@ var nanProcessor = (_schema, ctx, _json, _params) => {
12013
12013
  throw new Error("NaN cannot be represented in JSON Schema");
12014
12014
  }
12015
12015
  };
12016
- var templateLiteralProcessor = (schema, _ctx, json2, _params) => {
12017
- const _json = json2;
12016
+ var templateLiteralProcessor = (schema, _ctx, json3, _params) => {
12017
+ const _json = json3;
12018
12018
  const pattern = schema._zod.pattern;
12019
12019
  if (!pattern)
12020
12020
  throw new Error("Pattern not found in template literal");
12021
12021
  _json.type = "string";
12022
12022
  _json.pattern = pattern.source;
12023
12023
  };
12024
- var fileProcessor = (schema, _ctx, json2, _params) => {
12025
- const _json = json2;
12024
+ var fileProcessor = (schema, _ctx, json3, _params) => {
12025
+ const _json = json3;
12026
12026
  const file2 = {
12027
12027
  type: "string",
12028
12028
  format: "binary",
@@ -12045,8 +12045,8 @@ var fileProcessor = (schema, _ctx, json2, _params) => {
12045
12045
  Object.assign(_json, file2);
12046
12046
  }
12047
12047
  };
12048
- var successProcessor = (_schema, _ctx, json2, _params) => {
12049
- json2.type = "boolean";
12048
+ var successProcessor = (_schema, _ctx, json3, _params) => {
12049
+ json3.type = "boolean";
12050
12050
  };
12051
12051
  var customProcessor = (_schema, ctx, _json, _params) => {
12052
12052
  if (ctx.unrepresentable === "throw") {
@@ -12074,27 +12074,27 @@ var setProcessor = (_schema, ctx, _json, _params) => {
12074
12074
  }
12075
12075
  };
12076
12076
  var arrayProcessor = (schema, ctx, _json, params) => {
12077
- const json2 = _json;
12077
+ const json3 = _json;
12078
12078
  const def = schema._zod.def;
12079
12079
  const { minimum, maximum } = schema._zod.bag;
12080
12080
  if (typeof minimum === "number")
12081
- json2.minItems = minimum;
12081
+ json3.minItems = minimum;
12082
12082
  if (typeof maximum === "number")
12083
- json2.maxItems = maximum;
12084
- json2.type = "array";
12085
- json2.items = process(def.element, ctx, {
12083
+ json3.maxItems = maximum;
12084
+ json3.type = "array";
12085
+ json3.items = process(def.element, ctx, {
12086
12086
  ...params,
12087
12087
  path: [...params.path, "items"]
12088
12088
  });
12089
12089
  };
12090
12090
  var objectProcessor = (schema, ctx, _json, params) => {
12091
- const json2 = _json;
12091
+ const json3 = _json;
12092
12092
  const def = schema._zod.def;
12093
- json2.type = "object";
12094
- json2.properties = {};
12093
+ json3.type = "object";
12094
+ json3.properties = {};
12095
12095
  const shape = def.shape;
12096
12096
  for (const key in shape) {
12097
- json2.properties[key] = process(shape[key], ctx, {
12097
+ json3.properties[key] = process(shape[key], ctx, {
12098
12098
  ...params,
12099
12099
  path: [...params.path, "properties", key]
12100
12100
  });
@@ -12109,21 +12109,21 @@ var objectProcessor = (schema, ctx, _json, params) => {
12109
12109
  }
12110
12110
  }));
12111
12111
  if (requiredKeys.size > 0) {
12112
- json2.required = Array.from(requiredKeys);
12112
+ json3.required = Array.from(requiredKeys);
12113
12113
  }
12114
12114
  if (def.catchall?._zod.def.type === "never") {
12115
- json2.additionalProperties = false;
12115
+ json3.additionalProperties = false;
12116
12116
  } else if (!def.catchall) {
12117
12117
  if (ctx.io === "output")
12118
- json2.additionalProperties = false;
12118
+ json3.additionalProperties = false;
12119
12119
  } else if (def.catchall) {
12120
- json2.additionalProperties = process(def.catchall, ctx, {
12120
+ json3.additionalProperties = process(def.catchall, ctx, {
12121
12121
  ...params,
12122
12122
  path: [...params.path, "additionalProperties"]
12123
12123
  });
12124
12124
  }
12125
12125
  };
12126
- var unionProcessor = (schema, ctx, json2, params) => {
12126
+ var unionProcessor = (schema, ctx, json3, params) => {
12127
12127
  const def = schema._zod.def;
12128
12128
  const isExclusive = def.inclusive === false;
12129
12129
  const options = def.options.map((x, i) => process(x, ctx, {
@@ -12131,12 +12131,12 @@ var unionProcessor = (schema, ctx, json2, params) => {
12131
12131
  path: [...params.path, isExclusive ? "oneOf" : "anyOf", i]
12132
12132
  }));
12133
12133
  if (isExclusive) {
12134
- json2.oneOf = options;
12134
+ json3.oneOf = options;
12135
12135
  } else {
12136
- json2.anyOf = options;
12136
+ json3.anyOf = options;
12137
12137
  }
12138
12138
  };
12139
- var intersectionProcessor = (schema, ctx, json2, params) => {
12139
+ var intersectionProcessor = (schema, ctx, json3, params) => {
12140
12140
  const def = schema._zod.def;
12141
12141
  const a = process(def.left, ctx, {
12142
12142
  ...params,
@@ -12151,12 +12151,12 @@ var intersectionProcessor = (schema, ctx, json2, params) => {
12151
12151
  ...isSimpleIntersection(a) ? a.allOf : [a],
12152
12152
  ...isSimpleIntersection(b) ? b.allOf : [b]
12153
12153
  ];
12154
- json2.allOf = allOf;
12154
+ json3.allOf = allOf;
12155
12155
  };
12156
12156
  var tupleProcessor = (schema, ctx, _json, params) => {
12157
- const json2 = _json;
12157
+ const json3 = _json;
12158
12158
  const def = schema._zod.def;
12159
- json2.type = "array";
12159
+ json3.type = "array";
12160
12160
  const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
12161
12161
  const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
12162
12162
  const prefixItems = def.items.map((x, i) => process(x, ctx, {
@@ -12168,37 +12168,37 @@ var tupleProcessor = (schema, ctx, _json, params) => {
12168
12168
  path: [...params.path, restPath, ...ctx.target === "openapi-3.0" ? [def.items.length] : []]
12169
12169
  }) : null;
12170
12170
  if (ctx.target === "draft-2020-12") {
12171
- json2.prefixItems = prefixItems;
12171
+ json3.prefixItems = prefixItems;
12172
12172
  if (rest) {
12173
- json2.items = rest;
12173
+ json3.items = rest;
12174
12174
  }
12175
12175
  } else if (ctx.target === "openapi-3.0") {
12176
- json2.items = {
12176
+ json3.items = {
12177
12177
  anyOf: prefixItems
12178
12178
  };
12179
12179
  if (rest) {
12180
- json2.items.anyOf.push(rest);
12180
+ json3.items.anyOf.push(rest);
12181
12181
  }
12182
- json2.minItems = prefixItems.length;
12182
+ json3.minItems = prefixItems.length;
12183
12183
  if (!rest) {
12184
- json2.maxItems = prefixItems.length;
12184
+ json3.maxItems = prefixItems.length;
12185
12185
  }
12186
12186
  } else {
12187
- json2.items = prefixItems;
12187
+ json3.items = prefixItems;
12188
12188
  if (rest) {
12189
- json2.additionalItems = rest;
12189
+ json3.additionalItems = rest;
12190
12190
  }
12191
12191
  }
12192
12192
  const { minimum, maximum } = schema._zod.bag;
12193
12193
  if (typeof minimum === "number")
12194
- json2.minItems = minimum;
12194
+ json3.minItems = minimum;
12195
12195
  if (typeof maximum === "number")
12196
- json2.maxItems = maximum;
12196
+ json3.maxItems = maximum;
12197
12197
  };
12198
12198
  var recordProcessor = (schema, ctx, _json, params) => {
12199
- const json2 = _json;
12199
+ const json3 = _json;
12200
12200
  const def = schema._zod.def;
12201
- json2.type = "object";
12201
+ json3.type = "object";
12202
12202
  const keyType = def.keyType;
12203
12203
  const keyBag = keyType._zod.bag;
12204
12204
  const patterns = keyBag?.patterns;
@@ -12207,18 +12207,18 @@ var recordProcessor = (schema, ctx, _json, params) => {
12207
12207
  ...params,
12208
12208
  path: [...params.path, "patternProperties", "*"]
12209
12209
  });
12210
- json2.patternProperties = {};
12210
+ json3.patternProperties = {};
12211
12211
  for (const pattern of patterns) {
12212
- json2.patternProperties[pattern.source] = valueSchema;
12212
+ json3.patternProperties[pattern.source] = valueSchema;
12213
12213
  }
12214
12214
  } else {
12215
12215
  if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
12216
- json2.propertyNames = process(def.keyType, ctx, {
12216
+ json3.propertyNames = process(def.keyType, ctx, {
12217
12217
  ...params,
12218
12218
  path: [...params.path, "propertyNames"]
12219
12219
  });
12220
12220
  }
12221
- json2.additionalProperties = process(def.valueType, ctx, {
12221
+ json3.additionalProperties = process(def.valueType, ctx, {
12222
12222
  ...params,
12223
12223
  path: [...params.path, "additionalProperties"]
12224
12224
  });
@@ -12227,19 +12227,19 @@ var recordProcessor = (schema, ctx, _json, params) => {
12227
12227
  if (keyValues) {
12228
12228
  const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
12229
12229
  if (validKeyValues.length > 0) {
12230
- json2.required = validKeyValues;
12230
+ json3.required = validKeyValues;
12231
12231
  }
12232
12232
  }
12233
12233
  };
12234
- var nullableProcessor = (schema, ctx, json2, params) => {
12234
+ var nullableProcessor = (schema, ctx, json3, params) => {
12235
12235
  const def = schema._zod.def;
12236
12236
  const inner = process(def.innerType, ctx, params);
12237
12237
  const seen = ctx.seen.get(schema);
12238
12238
  if (ctx.target === "openapi-3.0") {
12239
12239
  seen.ref = def.innerType;
12240
- json2.nullable = true;
12240
+ json3.nullable = true;
12241
12241
  } else {
12242
- json2.anyOf = [inner, { type: "null" }];
12242
+ json3.anyOf = [inner, { type: "null" }];
12243
12243
  }
12244
12244
  };
12245
12245
  var nonoptionalProcessor = (schema, ctx, _json, params) => {
@@ -12248,22 +12248,22 @@ var nonoptionalProcessor = (schema, ctx, _json, params) => {
12248
12248
  const seen = ctx.seen.get(schema);
12249
12249
  seen.ref = def.innerType;
12250
12250
  };
12251
- var defaultProcessor = (schema, ctx, json2, params) => {
12251
+ var defaultProcessor = (schema, ctx, json3, params) => {
12252
12252
  const def = schema._zod.def;
12253
12253
  process(def.innerType, ctx, params);
12254
12254
  const seen = ctx.seen.get(schema);
12255
12255
  seen.ref = def.innerType;
12256
- json2.default = JSON.parse(JSON.stringify(def.defaultValue));
12256
+ json3.default = JSON.parse(JSON.stringify(def.defaultValue));
12257
12257
  };
12258
- var prefaultProcessor = (schema, ctx, json2, params) => {
12258
+ var prefaultProcessor = (schema, ctx, json3, params) => {
12259
12259
  const def = schema._zod.def;
12260
12260
  process(def.innerType, ctx, params);
12261
12261
  const seen = ctx.seen.get(schema);
12262
12262
  seen.ref = def.innerType;
12263
12263
  if (ctx.io === "input")
12264
- json2._prefault = JSON.parse(JSON.stringify(def.defaultValue));
12264
+ json3._prefault = JSON.parse(JSON.stringify(def.defaultValue));
12265
12265
  };
12266
- var catchProcessor = (schema, ctx, json2, params) => {
12266
+ var catchProcessor = (schema, ctx, json3, params) => {
12267
12267
  const def = schema._zod.def;
12268
12268
  process(def.innerType, ctx, params);
12269
12269
  const seen = ctx.seen.get(schema);
@@ -12274,7 +12274,7 @@ var catchProcessor = (schema, ctx, json2, params) => {
12274
12274
  } catch {
12275
12275
  throw new Error("Dynamic catch values are not supported in JSON Schema");
12276
12276
  }
12277
- json2.default = catchValue;
12277
+ json3.default = catchValue;
12278
12278
  };
12279
12279
  var pipeProcessor = (schema, ctx, _json, params) => {
12280
12280
  const def = schema._zod.def;
@@ -12284,12 +12284,12 @@ var pipeProcessor = (schema, ctx, _json, params) => {
12284
12284
  const seen = ctx.seen.get(schema);
12285
12285
  seen.ref = innerType;
12286
12286
  };
12287
- var readonlyProcessor = (schema, ctx, json2, params) => {
12287
+ var readonlyProcessor = (schema, ctx, json3, params) => {
12288
12288
  const def = schema._zod.def;
12289
12289
  process(def.innerType, ctx, params);
12290
12290
  const seen = ctx.seen.get(schema);
12291
12291
  seen.ref = def.innerType;
12292
- json2.readOnly = true;
12292
+ json3.readOnly = true;
12293
12293
  };
12294
12294
  var promiseProcessor = (schema, ctx, _json, params) => {
12295
12295
  const def = schema._zod.def;
@@ -12933,7 +12933,7 @@ var ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
12933
12933
  var _ZodString = /* @__PURE__ */ $constructor("_ZodString", (inst, def) => {
12934
12934
  $ZodString.init(inst, def);
12935
12935
  ZodType.init(inst, def);
12936
- inst._zod.processJSONSchema = (ctx, json2, params) => stringProcessor(inst, ctx, json2, params);
12936
+ inst._zod.processJSONSchema = (ctx, json3, params) => stringProcessor(inst, ctx, json3, params);
12937
12937
  const bag = inst._zod.bag;
12938
12938
  inst.format = bag.format ?? null;
12939
12939
  inst.minLength = bag.minimum ?? null;
@@ -13204,7 +13204,7 @@ function hash(alg, params) {
13204
13204
  var ZodNumber = /* @__PURE__ */ $constructor("ZodNumber", (inst, def) => {
13205
13205
  $ZodNumber.init(inst, def);
13206
13206
  ZodType.init(inst, def);
13207
- inst._zod.processJSONSchema = (ctx, json2, params) => numberProcessor(inst, ctx, json2, params);
13207
+ inst._zod.processJSONSchema = (ctx, json3, params) => numberProcessor(inst, ctx, json3, params);
13208
13208
  _installLazyMethods(inst, "ZodNumber", {
13209
13209
  gt(value, params) {
13210
13210
  return this.check(_gt(value, params));
@@ -13284,7 +13284,7 @@ function uint32(params) {
13284
13284
  var ZodBoolean = /* @__PURE__ */ $constructor("ZodBoolean", (inst, def) => {
13285
13285
  $ZodBoolean.init(inst, def);
13286
13286
  ZodType.init(inst, def);
13287
- inst._zod.processJSONSchema = (ctx, json2, params) => booleanProcessor(inst, ctx, json2, params);
13287
+ inst._zod.processJSONSchema = (ctx, json3, params) => booleanProcessor(inst, ctx, json3, params);
13288
13288
  });
13289
13289
  function boolean2(params) {
13290
13290
  return _boolean(ZodBoolean, params);
@@ -13292,7 +13292,7 @@ function boolean2(params) {
13292
13292
  var ZodBigInt = /* @__PURE__ */ $constructor("ZodBigInt", (inst, def) => {
13293
13293
  $ZodBigInt.init(inst, def);
13294
13294
  ZodType.init(inst, def);
13295
- inst._zod.processJSONSchema = (ctx, json2, params) => bigintProcessor(inst, ctx, json2, params);
13295
+ inst._zod.processJSONSchema = (ctx, json3, params) => bigintProcessor(inst, ctx, json3, params);
13296
13296
  inst.gte = (value, params) => inst.check(_gte(value, params));
13297
13297
  inst.min = (value, params) => inst.check(_gte(value, params));
13298
13298
  inst.gt = (value, params) => inst.check(_gt(value, params));
@@ -13327,7 +13327,7 @@ function uint64(params) {
13327
13327
  var ZodSymbol = /* @__PURE__ */ $constructor("ZodSymbol", (inst, def) => {
13328
13328
  $ZodSymbol.init(inst, def);
13329
13329
  ZodType.init(inst, def);
13330
- inst._zod.processJSONSchema = (ctx, json2, params) => symbolProcessor(inst, ctx, json2, params);
13330
+ inst._zod.processJSONSchema = (ctx, json3, params) => symbolProcessor(inst, ctx, json3, params);
13331
13331
  });
13332
13332
  function symbol(params) {
13333
13333
  return _symbol(ZodSymbol, params);
@@ -13335,7 +13335,7 @@ function symbol(params) {
13335
13335
  var ZodUndefined = /* @__PURE__ */ $constructor("ZodUndefined", (inst, def) => {
13336
13336
  $ZodUndefined.init(inst, def);
13337
13337
  ZodType.init(inst, def);
13338
- inst._zod.processJSONSchema = (ctx, json2, params) => undefinedProcessor(inst, ctx, json2, params);
13338
+ inst._zod.processJSONSchema = (ctx, json3, params) => undefinedProcessor(inst, ctx, json3, params);
13339
13339
  });
13340
13340
  function _undefined3(params) {
13341
13341
  return _undefined2(ZodUndefined, params);
@@ -13343,7 +13343,7 @@ function _undefined3(params) {
13343
13343
  var ZodNull = /* @__PURE__ */ $constructor("ZodNull", (inst, def) => {
13344
13344
  $ZodNull.init(inst, def);
13345
13345
  ZodType.init(inst, def);
13346
- inst._zod.processJSONSchema = (ctx, json2, params) => nullProcessor(inst, ctx, json2, params);
13346
+ inst._zod.processJSONSchema = (ctx, json3, params) => nullProcessor(inst, ctx, json3, params);
13347
13347
  });
13348
13348
  function _null3(params) {
13349
13349
  return _null2(ZodNull, params);
@@ -13351,7 +13351,7 @@ function _null3(params) {
13351
13351
  var ZodAny = /* @__PURE__ */ $constructor("ZodAny", (inst, def) => {
13352
13352
  $ZodAny.init(inst, def);
13353
13353
  ZodType.init(inst, def);
13354
- inst._zod.processJSONSchema = (ctx, json2, params) => anyProcessor(inst, ctx, json2, params);
13354
+ inst._zod.processJSONSchema = (ctx, json3, params) => anyProcessor(inst, ctx, json3, params);
13355
13355
  });
13356
13356
  function any() {
13357
13357
  return _any(ZodAny);
@@ -13359,7 +13359,7 @@ function any() {
13359
13359
  var ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
13360
13360
  $ZodUnknown.init(inst, def);
13361
13361
  ZodType.init(inst, def);
13362
- inst._zod.processJSONSchema = (ctx, json2, params) => unknownProcessor(inst, ctx, json2, params);
13362
+ inst._zod.processJSONSchema = (ctx, json3, params) => unknownProcessor(inst, ctx, json3, params);
13363
13363
  });
13364
13364
  function unknown() {
13365
13365
  return _unknown(ZodUnknown);
@@ -13367,7 +13367,7 @@ function unknown() {
13367
13367
  var ZodNever = /* @__PURE__ */ $constructor("ZodNever", (inst, def) => {
13368
13368
  $ZodNever.init(inst, def);
13369
13369
  ZodType.init(inst, def);
13370
- inst._zod.processJSONSchema = (ctx, json2, params) => neverProcessor(inst, ctx, json2, params);
13370
+ inst._zod.processJSONSchema = (ctx, json3, params) => neverProcessor(inst, ctx, json3, params);
13371
13371
  });
13372
13372
  function never(params) {
13373
13373
  return _never(ZodNever, params);
@@ -13375,7 +13375,7 @@ function never(params) {
13375
13375
  var ZodVoid = /* @__PURE__ */ $constructor("ZodVoid", (inst, def) => {
13376
13376
  $ZodVoid.init(inst, def);
13377
13377
  ZodType.init(inst, def);
13378
- inst._zod.processJSONSchema = (ctx, json2, params) => voidProcessor(inst, ctx, json2, params);
13378
+ inst._zod.processJSONSchema = (ctx, json3, params) => voidProcessor(inst, ctx, json3, params);
13379
13379
  });
13380
13380
  function _void2(params) {
13381
13381
  return _void(ZodVoid, params);
@@ -13383,7 +13383,7 @@ function _void2(params) {
13383
13383
  var ZodDate = /* @__PURE__ */ $constructor("ZodDate", (inst, def) => {
13384
13384
  $ZodDate.init(inst, def);
13385
13385
  ZodType.init(inst, def);
13386
- inst._zod.processJSONSchema = (ctx, json2, params) => dateProcessor(inst, ctx, json2, params);
13386
+ inst._zod.processJSONSchema = (ctx, json3, params) => dateProcessor(inst, ctx, json3, params);
13387
13387
  inst.min = (value, params) => inst.check(_gte(value, params));
13388
13388
  inst.max = (value, params) => inst.check(_lte(value, params));
13389
13389
  const c = inst._zod.bag;
@@ -13396,7 +13396,7 @@ function date3(params) {
13396
13396
  var ZodArray = /* @__PURE__ */ $constructor("ZodArray", (inst, def) => {
13397
13397
  $ZodArray.init(inst, def);
13398
13398
  ZodType.init(inst, def);
13399
- inst._zod.processJSONSchema = (ctx, json2, params) => arrayProcessor(inst, ctx, json2, params);
13399
+ inst._zod.processJSONSchema = (ctx, json3, params) => arrayProcessor(inst, ctx, json3, params);
13400
13400
  inst.element = def.element;
13401
13401
  _installLazyMethods(inst, "ZodArray", {
13402
13402
  min(n, params) {
@@ -13426,7 +13426,7 @@ function keyof(schema) {
13426
13426
  var ZodObject = /* @__PURE__ */ $constructor("ZodObject", (inst, def) => {
13427
13427
  $ZodObjectJIT.init(inst, def);
13428
13428
  ZodType.init(inst, def);
13429
- inst._zod.processJSONSchema = (ctx, json2, params) => objectProcessor(inst, ctx, json2, params);
13429
+ inst._zod.processJSONSchema = (ctx, json3, params) => objectProcessor(inst, ctx, json3, params);
13430
13430
  util_exports.defineLazy(inst, "shape", () => {
13431
13431
  return def.shape;
13432
13432
  });
@@ -13499,7 +13499,7 @@ function looseObject(shape, params) {
13499
13499
  var ZodUnion = /* @__PURE__ */ $constructor("ZodUnion", (inst, def) => {
13500
13500
  $ZodUnion.init(inst, def);
13501
13501
  ZodType.init(inst, def);
13502
- inst._zod.processJSONSchema = (ctx, json2, params) => unionProcessor(inst, ctx, json2, params);
13502
+ inst._zod.processJSONSchema = (ctx, json3, params) => unionProcessor(inst, ctx, json3, params);
13503
13503
  inst.options = def.options;
13504
13504
  });
13505
13505
  function union(options, params) {
@@ -13512,7 +13512,7 @@ function union(options, params) {
13512
13512
  var ZodXor = /* @__PURE__ */ $constructor("ZodXor", (inst, def) => {
13513
13513
  ZodUnion.init(inst, def);
13514
13514
  $ZodXor.init(inst, def);
13515
- inst._zod.processJSONSchema = (ctx, json2, params) => unionProcessor(inst, ctx, json2, params);
13515
+ inst._zod.processJSONSchema = (ctx, json3, params) => unionProcessor(inst, ctx, json3, params);
13516
13516
  inst.options = def.options;
13517
13517
  });
13518
13518
  function xor(options, params) {
@@ -13538,7 +13538,7 @@ function discriminatedUnion(discriminator, options, params) {
13538
13538
  var ZodIntersection = /* @__PURE__ */ $constructor("ZodIntersection", (inst, def) => {
13539
13539
  $ZodIntersection.init(inst, def);
13540
13540
  ZodType.init(inst, def);
13541
- inst._zod.processJSONSchema = (ctx, json2, params) => intersectionProcessor(inst, ctx, json2, params);
13541
+ inst._zod.processJSONSchema = (ctx, json3, params) => intersectionProcessor(inst, ctx, json3, params);
13542
13542
  });
13543
13543
  function intersection(left, right) {
13544
13544
  return new ZodIntersection({
@@ -13550,7 +13550,7 @@ function intersection(left, right) {
13550
13550
  var ZodTuple = /* @__PURE__ */ $constructor("ZodTuple", (inst, def) => {
13551
13551
  $ZodTuple.init(inst, def);
13552
13552
  ZodType.init(inst, def);
13553
- inst._zod.processJSONSchema = (ctx, json2, params) => tupleProcessor(inst, ctx, json2, params);
13553
+ inst._zod.processJSONSchema = (ctx, json3, params) => tupleProcessor(inst, ctx, json3, params);
13554
13554
  inst.rest = (rest) => inst.clone({
13555
13555
  ...inst._zod.def,
13556
13556
  rest
@@ -13570,7 +13570,7 @@ function tuple(items, _paramsOrRest, _params) {
13570
13570
  var ZodRecord = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
13571
13571
  $ZodRecord.init(inst, def);
13572
13572
  ZodType.init(inst, def);
13573
- inst._zod.processJSONSchema = (ctx, json2, params) => recordProcessor(inst, ctx, json2, params);
13573
+ inst._zod.processJSONSchema = (ctx, json3, params) => recordProcessor(inst, ctx, json3, params);
13574
13574
  inst.keyType = def.keyType;
13575
13575
  inst.valueType = def.valueType;
13576
13576
  });
@@ -13612,7 +13612,7 @@ function looseRecord(keyType, valueType, params) {
13612
13612
  var ZodMap = /* @__PURE__ */ $constructor("ZodMap", (inst, def) => {
13613
13613
  $ZodMap.init(inst, def);
13614
13614
  ZodType.init(inst, def);
13615
- inst._zod.processJSONSchema = (ctx, json2, params) => mapProcessor(inst, ctx, json2, params);
13615
+ inst._zod.processJSONSchema = (ctx, json3, params) => mapProcessor(inst, ctx, json3, params);
13616
13616
  inst.keyType = def.keyType;
13617
13617
  inst.valueType = def.valueType;
13618
13618
  inst.min = (...args) => inst.check(_minSize(...args));
@@ -13631,7 +13631,7 @@ function map(keyType, valueType, params) {
13631
13631
  var ZodSet = /* @__PURE__ */ $constructor("ZodSet", (inst, def) => {
13632
13632
  $ZodSet.init(inst, def);
13633
13633
  ZodType.init(inst, def);
13634
- inst._zod.processJSONSchema = (ctx, json2, params) => setProcessor(inst, ctx, json2, params);
13634
+ inst._zod.processJSONSchema = (ctx, json3, params) => setProcessor(inst, ctx, json3, params);
13635
13635
  inst.min = (...args) => inst.check(_minSize(...args));
13636
13636
  inst.nonempty = (params) => inst.check(_minSize(1, params));
13637
13637
  inst.max = (...args) => inst.check(_maxSize(...args));
@@ -13647,7 +13647,7 @@ function set(valueType, params) {
13647
13647
  var ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
13648
13648
  $ZodEnum.init(inst, def);
13649
13649
  ZodType.init(inst, def);
13650
- inst._zod.processJSONSchema = (ctx, json2, params) => enumProcessor(inst, ctx, json2, params);
13650
+ inst._zod.processJSONSchema = (ctx, json3, params) => enumProcessor(inst, ctx, json3, params);
13651
13651
  inst.enum = def.entries;
13652
13652
  inst.options = Object.values(def.entries);
13653
13653
  const keys = new Set(Object.keys(def.entries));
@@ -13700,7 +13700,7 @@ function nativeEnum(entries, params) {
13700
13700
  var ZodLiteral = /* @__PURE__ */ $constructor("ZodLiteral", (inst, def) => {
13701
13701
  $ZodLiteral.init(inst, def);
13702
13702
  ZodType.init(inst, def);
13703
- inst._zod.processJSONSchema = (ctx, json2, params) => literalProcessor(inst, ctx, json2, params);
13703
+ inst._zod.processJSONSchema = (ctx, json3, params) => literalProcessor(inst, ctx, json3, params);
13704
13704
  inst.values = new Set(def.values);
13705
13705
  Object.defineProperty(inst, "value", {
13706
13706
  get() {
@@ -13721,7 +13721,7 @@ function literal(value, params) {
13721
13721
  var ZodFile = /* @__PURE__ */ $constructor("ZodFile", (inst, def) => {
13722
13722
  $ZodFile.init(inst, def);
13723
13723
  ZodType.init(inst, def);
13724
- inst._zod.processJSONSchema = (ctx, json2, params) => fileProcessor(inst, ctx, json2, params);
13724
+ inst._zod.processJSONSchema = (ctx, json3, params) => fileProcessor(inst, ctx, json3, params);
13725
13725
  inst.min = (size, params) => inst.check(_minSize(size, params));
13726
13726
  inst.max = (size, params) => inst.check(_maxSize(size, params));
13727
13727
  inst.mime = (types, params) => inst.check(_mime(Array.isArray(types) ? types : [types], params));
@@ -13732,7 +13732,7 @@ function file(params) {
13732
13732
  var ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
13733
13733
  $ZodTransform.init(inst, def);
13734
13734
  ZodType.init(inst, def);
13735
- inst._zod.processJSONSchema = (ctx, json2, params) => transformProcessor(inst, ctx, json2, params);
13735
+ inst._zod.processJSONSchema = (ctx, json3, params) => transformProcessor(inst, ctx, json3, params);
13736
13736
  inst._zod.parse = (payload, _ctx) => {
13737
13737
  if (_ctx.direction === "backward") {
13738
13738
  throw new $ZodEncodeError(inst.constructor.name);
@@ -13772,7 +13772,7 @@ function transform(fn) {
13772
13772
  var ZodOptional = /* @__PURE__ */ $constructor("ZodOptional", (inst, def) => {
13773
13773
  $ZodOptional.init(inst, def);
13774
13774
  ZodType.init(inst, def);
13775
- inst._zod.processJSONSchema = (ctx, json2, params) => optionalProcessor(inst, ctx, json2, params);
13775
+ inst._zod.processJSONSchema = (ctx, json3, params) => optionalProcessor(inst, ctx, json3, params);
13776
13776
  inst.unwrap = () => inst._zod.def.innerType;
13777
13777
  });
13778
13778
  function optional(innerType) {
@@ -13784,7 +13784,7 @@ function optional(innerType) {
13784
13784
  var ZodExactOptional = /* @__PURE__ */ $constructor("ZodExactOptional", (inst, def) => {
13785
13785
  $ZodExactOptional.init(inst, def);
13786
13786
  ZodType.init(inst, def);
13787
- inst._zod.processJSONSchema = (ctx, json2, params) => optionalProcessor(inst, ctx, json2, params);
13787
+ inst._zod.processJSONSchema = (ctx, json3, params) => optionalProcessor(inst, ctx, json3, params);
13788
13788
  inst.unwrap = () => inst._zod.def.innerType;
13789
13789
  });
13790
13790
  function exactOptional(innerType) {
@@ -13796,7 +13796,7 @@ function exactOptional(innerType) {
13796
13796
  var ZodNullable = /* @__PURE__ */ $constructor("ZodNullable", (inst, def) => {
13797
13797
  $ZodNullable.init(inst, def);
13798
13798
  ZodType.init(inst, def);
13799
- inst._zod.processJSONSchema = (ctx, json2, params) => nullableProcessor(inst, ctx, json2, params);
13799
+ inst._zod.processJSONSchema = (ctx, json3, params) => nullableProcessor(inst, ctx, json3, params);
13800
13800
  inst.unwrap = () => inst._zod.def.innerType;
13801
13801
  });
13802
13802
  function nullable(innerType) {
@@ -13811,7 +13811,7 @@ function nullish2(innerType) {
13811
13811
  var ZodDefault = /* @__PURE__ */ $constructor("ZodDefault", (inst, def) => {
13812
13812
  $ZodDefault.init(inst, def);
13813
13813
  ZodType.init(inst, def);
13814
- inst._zod.processJSONSchema = (ctx, json2, params) => defaultProcessor(inst, ctx, json2, params);
13814
+ inst._zod.processJSONSchema = (ctx, json3, params) => defaultProcessor(inst, ctx, json3, params);
13815
13815
  inst.unwrap = () => inst._zod.def.innerType;
13816
13816
  inst.removeDefault = inst.unwrap;
13817
13817
  });
@@ -13827,7 +13827,7 @@ function _default2(innerType, defaultValue) {
13827
13827
  var ZodPrefault = /* @__PURE__ */ $constructor("ZodPrefault", (inst, def) => {
13828
13828
  $ZodPrefault.init(inst, def);
13829
13829
  ZodType.init(inst, def);
13830
- inst._zod.processJSONSchema = (ctx, json2, params) => prefaultProcessor(inst, ctx, json2, params);
13830
+ inst._zod.processJSONSchema = (ctx, json3, params) => prefaultProcessor(inst, ctx, json3, params);
13831
13831
  inst.unwrap = () => inst._zod.def.innerType;
13832
13832
  });
13833
13833
  function prefault(innerType, defaultValue) {
@@ -13842,7 +13842,7 @@ function prefault(innerType, defaultValue) {
13842
13842
  var ZodNonOptional = /* @__PURE__ */ $constructor("ZodNonOptional", (inst, def) => {
13843
13843
  $ZodNonOptional.init(inst, def);
13844
13844
  ZodType.init(inst, def);
13845
- inst._zod.processJSONSchema = (ctx, json2, params) => nonoptionalProcessor(inst, ctx, json2, params);
13845
+ inst._zod.processJSONSchema = (ctx, json3, params) => nonoptionalProcessor(inst, ctx, json3, params);
13846
13846
  inst.unwrap = () => inst._zod.def.innerType;
13847
13847
  });
13848
13848
  function nonoptional(innerType, params) {
@@ -13855,7 +13855,7 @@ function nonoptional(innerType, params) {
13855
13855
  var ZodSuccess = /* @__PURE__ */ $constructor("ZodSuccess", (inst, def) => {
13856
13856
  $ZodSuccess.init(inst, def);
13857
13857
  ZodType.init(inst, def);
13858
- inst._zod.processJSONSchema = (ctx, json2, params) => successProcessor(inst, ctx, json2, params);
13858
+ inst._zod.processJSONSchema = (ctx, json3, params) => successProcessor(inst, ctx, json3, params);
13859
13859
  inst.unwrap = () => inst._zod.def.innerType;
13860
13860
  });
13861
13861
  function success(innerType) {
@@ -13867,7 +13867,7 @@ function success(innerType) {
13867
13867
  var ZodCatch = /* @__PURE__ */ $constructor("ZodCatch", (inst, def) => {
13868
13868
  $ZodCatch.init(inst, def);
13869
13869
  ZodType.init(inst, def);
13870
- inst._zod.processJSONSchema = (ctx, json2, params) => catchProcessor(inst, ctx, json2, params);
13870
+ inst._zod.processJSONSchema = (ctx, json3, params) => catchProcessor(inst, ctx, json3, params);
13871
13871
  inst.unwrap = () => inst._zod.def.innerType;
13872
13872
  inst.removeCatch = inst.unwrap;
13873
13873
  });
@@ -13881,7 +13881,7 @@ function _catch2(innerType, catchValue) {
13881
13881
  var ZodNaN = /* @__PURE__ */ $constructor("ZodNaN", (inst, def) => {
13882
13882
  $ZodNaN.init(inst, def);
13883
13883
  ZodType.init(inst, def);
13884
- inst._zod.processJSONSchema = (ctx, json2, params) => nanProcessor(inst, ctx, json2, params);
13884
+ inst._zod.processJSONSchema = (ctx, json3, params) => nanProcessor(inst, ctx, json3, params);
13885
13885
  });
13886
13886
  function nan(params) {
13887
13887
  return _nan(ZodNaN, params);
@@ -13889,7 +13889,7 @@ function nan(params) {
13889
13889
  var ZodPipe = /* @__PURE__ */ $constructor("ZodPipe", (inst, def) => {
13890
13890
  $ZodPipe.init(inst, def);
13891
13891
  ZodType.init(inst, def);
13892
- inst._zod.processJSONSchema = (ctx, json2, params) => pipeProcessor(inst, ctx, json2, params);
13892
+ inst._zod.processJSONSchema = (ctx, json3, params) => pipeProcessor(inst, ctx, json3, params);
13893
13893
  inst.in = def.in;
13894
13894
  inst.out = def.out;
13895
13895
  });
@@ -13931,7 +13931,7 @@ var ZodPreprocess = /* @__PURE__ */ $constructor("ZodPreprocess", (inst, def) =>
13931
13931
  var ZodReadonly = /* @__PURE__ */ $constructor("ZodReadonly", (inst, def) => {
13932
13932
  $ZodReadonly.init(inst, def);
13933
13933
  ZodType.init(inst, def);
13934
- inst._zod.processJSONSchema = (ctx, json2, params) => readonlyProcessor(inst, ctx, json2, params);
13934
+ inst._zod.processJSONSchema = (ctx, json3, params) => readonlyProcessor(inst, ctx, json3, params);
13935
13935
  inst.unwrap = () => inst._zod.def.innerType;
13936
13936
  });
13937
13937
  function readonly(innerType) {
@@ -13943,7 +13943,7 @@ function readonly(innerType) {
13943
13943
  var ZodTemplateLiteral = /* @__PURE__ */ $constructor("ZodTemplateLiteral", (inst, def) => {
13944
13944
  $ZodTemplateLiteral.init(inst, def);
13945
13945
  ZodType.init(inst, def);
13946
- inst._zod.processJSONSchema = (ctx, json2, params) => templateLiteralProcessor(inst, ctx, json2, params);
13946
+ inst._zod.processJSONSchema = (ctx, json3, params) => templateLiteralProcessor(inst, ctx, json3, params);
13947
13947
  });
13948
13948
  function templateLiteral(parts, params) {
13949
13949
  return new ZodTemplateLiteral({
@@ -13955,7 +13955,7 @@ function templateLiteral(parts, params) {
13955
13955
  var ZodLazy = /* @__PURE__ */ $constructor("ZodLazy", (inst, def) => {
13956
13956
  $ZodLazy.init(inst, def);
13957
13957
  ZodType.init(inst, def);
13958
- inst._zod.processJSONSchema = (ctx, json2, params) => lazyProcessor(inst, ctx, json2, params);
13958
+ inst._zod.processJSONSchema = (ctx, json3, params) => lazyProcessor(inst, ctx, json3, params);
13959
13959
  inst.unwrap = () => inst._zod.def.getter();
13960
13960
  });
13961
13961
  function lazy(getter) {
@@ -13967,7 +13967,7 @@ function lazy(getter) {
13967
13967
  var ZodPromise = /* @__PURE__ */ $constructor("ZodPromise", (inst, def) => {
13968
13968
  $ZodPromise.init(inst, def);
13969
13969
  ZodType.init(inst, def);
13970
- inst._zod.processJSONSchema = (ctx, json2, params) => promiseProcessor(inst, ctx, json2, params);
13970
+ inst._zod.processJSONSchema = (ctx, json3, params) => promiseProcessor(inst, ctx, json3, params);
13971
13971
  inst.unwrap = () => inst._zod.def.innerType;
13972
13972
  });
13973
13973
  function promise(innerType) {
@@ -13979,7 +13979,7 @@ function promise(innerType) {
13979
13979
  var ZodFunction = /* @__PURE__ */ $constructor("ZodFunction", (inst, def) => {
13980
13980
  $ZodFunction.init(inst, def);
13981
13981
  ZodType.init(inst, def);
13982
- inst._zod.processJSONSchema = (ctx, json2, params) => functionProcessor(inst, ctx, json2, params);
13982
+ inst._zod.processJSONSchema = (ctx, json3, params) => functionProcessor(inst, ctx, json3, params);
13983
13983
  });
13984
13984
  function _function(params) {
13985
13985
  return new ZodFunction({
@@ -13991,7 +13991,7 @@ function _function(params) {
13991
13991
  var ZodCustom = /* @__PURE__ */ $constructor("ZodCustom", (inst, def) => {
13992
13992
  $ZodCustom.init(inst, def);
13993
13993
  ZodType.init(inst, def);
13994
- inst._zod.processJSONSchema = (ctx, json2, params) => customProcessor(inst, ctx, json2, params);
13994
+ inst._zod.processJSONSchema = (ctx, json3, params) => customProcessor(inst, ctx, json3, params);
13995
13995
  });
13996
13996
  function check(fn) {
13997
13997
  const ch = new $ZodCheck({
@@ -15069,51 +15069,221 @@ async function identify(store, bearer, now) {
15069
15069
  };
15070
15070
  }
15071
15071
 
15072
- // ../core/src/builtin/util.ts
15073
- var VOID_ACK = { ok: true };
15074
- function withCommandPaths(nodePath, cmds) {
15075
- return cmds.map((cmd) => ({ ...cmd, path: `/${nodePath}/${cmd.name}` }));
15072
+ // ../core/src/operation/registry.ts
15073
+ function normalizeSchema(input) {
15074
+ return input instanceof external_exports.ZodType ? input : external_exports.strictObject(input);
15076
15075
  }
15077
- var LIST_OPTS_SCHEMA = {
15078
- type: "object",
15079
- description: "pagination options",
15080
- properties: {
15081
- cursor: { type: "string", description: "opaque cursor returned by the previous page" },
15082
- limit: { type: "number", description: "page size (default 50, max 200)" }
15083
- }
15084
- };
15085
- function cmdPath(nodePath) {
15086
- return `/${nodePath}`;
15076
+ function toJsonSchema(schema) {
15077
+ const json3 = external_exports.toJSONSchema(schema);
15078
+ return omit2(json3, "$schema");
15087
15079
  }
15088
- function requireString(args, field) {
15089
- const v = args[field];
15090
- if (typeof v !== "string" || v.length === 0) {
15091
- throw new TBError("invalid_argument", `field '${field}' must be a non-empty string`);
15092
- }
15093
- return v;
15080
+ function invalidArgument(name, error51) {
15081
+ const detail = error51.issues.map((issue2) => {
15082
+ const path = issue2.path.join(".");
15083
+ return path.length > 0 ? `${path}: ${issue2.message}` : issue2.message;
15084
+ }).join("; ");
15085
+ return new TBError("invalid_argument", `invalid arguments for '${name}': ${detail}`);
15094
15086
  }
15095
- function optString(args, field) {
15096
- const v = args[field];
15097
- if (v === void 0) return void 0;
15098
- if (typeof v !== "string") {
15099
- throw new TBError("invalid_argument", `field '${field}' must be a string`);
15087
+ var TOOL_RESULT_KEYS = /* @__PURE__ */ new Set(["content", "contentBlocks", "isError", "structuredContent"]);
15088
+ function toToolResult(value) {
15089
+ if (typeof value === "object" && value !== null && "content" in value) {
15090
+ const keys = Object.keys(value);
15091
+ if (keys.every((key) => TOOL_RESULT_KEYS.has(key))) return value;
15100
15092
  }
15101
- return v;
15093
+ return { content: value };
15102
15094
  }
15103
- function optListOptions(args) {
15104
- const opts = args.opts;
15105
- if (opts === void 0) return void 0;
15106
- if (typeof opts !== "object" || opts === null) {
15107
- throw new TBError("invalid_argument", "field 'opts' must be an object");
15095
+ var OperationRegistry = class {
15096
+ ops = /* @__PURE__ */ new Map();
15097
+ /** 注册一个操作。同名重复注册 invalid_argument(配置错误,快速失败) */
15098
+ register(name, spec, handler) {
15099
+ if (name.length === 0) {
15100
+ throw new TBError("invalid_argument", "operation name must be non-empty");
15101
+ }
15102
+ if (this.ops.has(name)) {
15103
+ throw new TBError("invalid_argument", `operation '${name}' is already registered`);
15104
+ }
15105
+ if (spec.inputSchema !== void 0 && spec.rawInputSchema !== void 0) {
15106
+ throw new TBError(
15107
+ "invalid_argument",
15108
+ `operation '${name}': inputSchema and rawInputSchema are mutually exclusive`
15109
+ );
15110
+ }
15111
+ const schema = spec.inputSchema !== void 0 ? normalizeSchema(spec.inputSchema) : void 0;
15112
+ const toolSpec = { name };
15113
+ if (spec.description !== void 0) toolSpec.description = spec.description;
15114
+ if (spec.effect !== void 0) toolSpec.effect = spec.effect;
15115
+ if (spec.confirm !== void 0) toolSpec.confirm = spec.confirm;
15116
+ if (schema !== void 0) toolSpec.inputSchema = toJsonSchema(schema);
15117
+ else if (spec.rawInputSchema !== void 0) toolSpec.inputSchema = spec.rawInputSchema;
15118
+ if (spec.outputSchema !== void 0) toolSpec.outputSchema = spec.outputSchema;
15119
+ this.ops.set(name, {
15120
+ schema,
15121
+ spec: toolSpec,
15122
+ handler
15123
+ });
15124
+ return this;
15108
15125
  }
15109
- return opts;
15110
- }
15111
- function requireObject(args, field) {
15112
- const v = args[field];
15113
- if (typeof v !== "object" || v === null) {
15114
- throw new TBError("invalid_argument", `field '${field}' must be an object`);
15126
+ /** 已注册的操作名(注册顺序)。 */
15127
+ names() {
15128
+ return [...this.ops.keys()];
15129
+ }
15130
+ has(name) {
15131
+ return this.ops.has(name);
15132
+ }
15133
+ /** 全部 ToolSpec(工具源天然小,豁免分页)。 */
15134
+ list() {
15135
+ return [...this.ops.values()].map((op) => op.spec);
15136
+ }
15137
+ /** 单个 ToolSpec;不存在 → not_found。 */
15138
+ get(name) {
15139
+ const op = this.ops.get(name);
15140
+ if (op === void 0) throw TBError.notFound(`unknown operation: '${name}'`);
15141
+ return op.spec;
15142
+ }
15143
+ /**
15144
+ * 只执行入参解析,不调用 handler。
15145
+ *
15146
+ * 少数 HTBP 命令由宿主转发到另一执行通道(例如设备 context);它们仍需复用注册
15147
+ * 真源的 strict schema,但不能在当前进程执行 provider handler。
15148
+ */
15149
+ parse(name, args) {
15150
+ const op = this.ops.get(name);
15151
+ if (op === void 0) throw TBError.notFound(`unknown operation: '${name}'`);
15152
+ if (op.schema === void 0) return args;
15153
+ const parsed = op.schema.safeParse(args);
15154
+ if (!parsed.success) throw invalidArgument(name, parsed.error);
15155
+ return parsed.data;
15156
+ }
15157
+ /**
15158
+ * 校验后调用 handler,保留 handler 的原始返回值。
15159
+ *
15160
+ * builtin 等内部适配层已有自己的 wire 形状,不应被套上 ToolResult;
15161
+ * 它们复用本方法的 Zod 校验和 handler 调度。工具源继续用 {@link call}。
15162
+ */
15163
+ async invoke(name, args, ctx) {
15164
+ const op = this.ops.get(name);
15165
+ if (op === void 0) throw TBError.notFound(`unknown operation: '${name}'`);
15166
+ return await op.handler(this.parse(name, args), ctx);
15167
+ }
15168
+ /**
15169
+ * 调用:safeParse 入参(失败 → invalid_argument)、执行 handler、把裸返回值包成 ToolResult。
15170
+ * 未声明 schema 的操作原样透传 args。
15171
+ */
15172
+ async call(name, args, ctx) {
15173
+ return toToolResult(await this.invoke(name, args, ctx));
15174
+ }
15175
+ };
15176
+
15177
+ // ../core/src/operation/htbpCommandRegistry.ts
15178
+ var HTBP_LIST_OPTIONS_SCHEMA = external_exports.strictObject({
15179
+ cursor: external_exports.string().optional().describe("opaque cursor returned by the previous page"),
15180
+ limit: external_exports.number().optional().describe("page size (default 50, max 200)")
15181
+ }).describe("pagination options");
15182
+ var HtbpCommandRegistry = class {
15183
+ metadata = /* @__PURE__ */ new Map();
15184
+ operations = new OperationRegistry();
15185
+ register(name, spec, handler) {
15186
+ const { h, returns, scope, ...operationSpec } = spec;
15187
+ this.operations.register(
15188
+ name,
15189
+ { ...operationSpec, description: h },
15190
+ handler
15191
+ );
15192
+ this.metadata.set(name, {
15193
+ scope,
15194
+ ...returns !== void 0 ? { returns } : {}
15195
+ });
15196
+ return this;
15197
+ }
15198
+ names() {
15199
+ return this.operations.names();
15200
+ }
15201
+ has(name) {
15202
+ return this.operations.has(name);
15203
+ }
15204
+ scopeFor(name) {
15205
+ return this.metadata.get(name)?.scope;
15206
+ }
15207
+ commandSpecs(nodePath) {
15208
+ return this.operations.list().map((operation) => {
15209
+ const metadata = this.metadata.get(operation.name);
15210
+ if (metadata === void 0) {
15211
+ throw new TBError("internal", `HTBP command metadata missing: '${operation.name}'`);
15212
+ }
15213
+ return {
15214
+ name: operation.name,
15215
+ method: "POST",
15216
+ path: `/${nodePath}/${operation.name}`,
15217
+ scope: metadata.scope,
15218
+ ...operation.description !== void 0 ? { h: operation.description } : {},
15219
+ ...operation.inputSchema !== void 0 ? { inputSchema: operation.inputSchema } : {},
15220
+ ...operation.outputSchema !== void 0 ? { outputSchema: operation.outputSchema } : {},
15221
+ ...operation.effect !== void 0 ? { effect: operation.effect } : {},
15222
+ ...operation.confirm !== void 0 ? { confirm: operation.confirm } : {},
15223
+ ...metadata.returns !== void 0 ? { returns: metadata.returns } : {}
15224
+ };
15225
+ });
15226
+ }
15227
+ command(name, nodePath) {
15228
+ return this.commandSpecs(nodePath).find((command) => command.name === name);
15229
+ }
15230
+ helpModel(node, include = () => true) {
15231
+ return {
15232
+ node,
15233
+ cmds: this.commandSpecs(node.path).filter(include)
15234
+ };
15235
+ }
15236
+ async invoke(name, args, context) {
15237
+ return await this.operations.invoke(name, args, context);
15115
15238
  }
15116
- return v;
15239
+ /** 校验/规范化宿主将转发到另一执行通道的命令入参。 */
15240
+ parse(name, args) {
15241
+ return this.operations.parse(name, args);
15242
+ }
15243
+ };
15244
+
15245
+ // ../core/src/builtin/commandRegistry.ts
15246
+ var BuiltinCommandRegistry = class extends HtbpCommandRegistry {
15247
+ constructor(moduleName, moduleDescription) {
15248
+ super();
15249
+ this.moduleName = moduleName;
15250
+ this.moduleDescription = moduleDescription;
15251
+ }
15252
+ moduleName;
15253
+ moduleDescription;
15254
+ help(nodePath) {
15255
+ return this.helpModel({
15256
+ path: nodePath,
15257
+ kind: "builtin",
15258
+ description: this.moduleDescription
15259
+ });
15260
+ }
15261
+ /** 绑定依赖后生成现有 BuiltinModule 接口。 */
15262
+ module(deps) {
15263
+ return {
15264
+ module: this.moduleName,
15265
+ description: this.moduleDescription,
15266
+ help: (nodePath) => this.help(nodePath),
15267
+ dispatch: async (cmd, args, call, runtime) => {
15268
+ if (!this.has(cmd)) {
15269
+ throw new TBError(
15270
+ "invalid_argument",
15271
+ `unknown cmd '${cmd}' on system/${this.moduleName}`
15272
+ );
15273
+ }
15274
+ return await this.invoke(cmd, args, { deps, call, runtime });
15275
+ }
15276
+ };
15277
+ }
15278
+ };
15279
+
15280
+ // ../core/src/builtin/util.ts
15281
+ var VOID_ACK = { ok: true };
15282
+ function withCommandPaths(nodePath, cmds) {
15283
+ return cmds.map((cmd) => ({ ...cmd, path: `/${nodePath}/${cmd.name}` }));
15284
+ }
15285
+ function cmdPath(nodePath) {
15286
+ return `/${nodePath}`;
15117
15287
  }
15118
15288
 
15119
15289
  // ../core/src/builtin/catalog.ts
@@ -15172,94 +15342,59 @@ function matches2(item, query) {
15172
15342
  const q = query.toLowerCase();
15173
15343
  return item.id.toLowerCase().includes(q) || (item.description?.toLowerCase().includes(q) ?? false);
15174
15344
  }
15175
- function catalogCmds(nodePath) {
15176
- const path = cmdPath(nodePath);
15177
- const cmds = [
15178
- {
15179
- name: "list",
15180
- method: "POST",
15181
- path,
15182
- h: "list built-in integrations available on this host (no credentials, read scope)",
15183
- inputSchema: { type: "object", properties: { opts: LIST_OPTS_SCHEMA } },
15184
- returns: "Page<CatalogListItem> \u2014 id, exports, nodeKinds, exportDetails",
15185
- scope: "read"
15186
- },
15187
- {
15188
- name: "get",
15189
- method: "POST",
15190
- path,
15191
- h: "fetch one catalog entry including its full /~describe descriptor",
15192
- inputSchema: {
15193
- type: "object",
15194
- properties: { id: { type: "string", description: "catalog entry id (= provider id)" } },
15195
- required: ["id"]
15196
- },
15197
- returns: "CatalogEntry \u2014 id, endpoint, digest, describe",
15198
- scope: "read"
15199
- },
15200
- {
15201
- name: "search",
15202
- method: "POST",
15203
- path,
15204
- h: "substring search over catalog id and description",
15205
- inputSchema: {
15206
- type: "object",
15207
- properties: {
15208
- q: { type: "string", description: "case-insensitive substring" },
15209
- opts: LIST_OPTS_SCHEMA
15210
- },
15211
- required: ["q"]
15212
- },
15213
- returns: "Page<CatalogListItem>",
15214
- scope: "read"
15215
- }
15216
- ];
15217
- return withCommandPaths(nodePath, cmds);
15218
- }
15219
15345
  function paginate(items, opts) {
15220
- const o = typeof opts === "object" && opts !== null ? opts : {};
15221
- const limit = typeof o.limit === "number" && o.limit > 0 ? Math.min(o.limit, LIST_LIMIT_MAX) : 50;
15346
+ const limit = typeof opts?.limit === "number" && opts.limit > 0 ? Math.min(opts.limit, LIST_LIMIT_MAX) : 50;
15222
15347
  let start = 0;
15223
- if (typeof o.cursor === "string" && o.cursor !== "") {
15224
- const idx = items.findIndex((i) => i.id === o.cursor);
15348
+ if (opts?.cursor !== void 0 && opts.cursor !== "") {
15349
+ const idx = items.findIndex((i) => i.id === opts.cursor);
15225
15350
  start = idx >= 0 ? idx : 0;
15226
15351
  }
15227
15352
  const page = items.slice(start, start + limit);
15228
15353
  const next = items[start + limit];
15229
15354
  return { items: page, ...next !== void 0 ? { cursor: next.id } : {} };
15230
15355
  }
15356
+ function sortedItems(deps) {
15357
+ return Object.values(deps.catalog()).sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0).map(projectListItem);
15358
+ }
15359
+ var COMMANDS = new BuiltinCommandRegistry("catalog", DESCRIPTION).register(
15360
+ "list",
15361
+ {
15362
+ h: "list built-in integrations available on this host (no credentials, read scope)",
15363
+ inputSchema: external_exports.strictObject({ opts: HTBP_LIST_OPTIONS_SCHEMA.optional() }),
15364
+ returns: "Page<CatalogListItem> \u2014 id, exports, nodeKinds, exportDetails",
15365
+ scope: "read"
15366
+ },
15367
+ ({ opts }, { deps }) => paginate(sortedItems(deps), opts)
15368
+ ).register(
15369
+ "get",
15370
+ {
15371
+ h: "fetch one catalog entry including its full /~describe descriptor",
15372
+ inputSchema: external_exports.strictObject({
15373
+ id: external_exports.string().min(1).describe("catalog entry id (= provider id)")
15374
+ }),
15375
+ returns: "CatalogEntry \u2014 id, endpoint, digest, describe",
15376
+ scope: "read"
15377
+ },
15378
+ ({ id }, { deps }) => {
15379
+ const entry = deps.catalog()[id];
15380
+ if (entry === void 0) throw new TBError("not_found", `no catalog entry '${id}'`);
15381
+ return entry;
15382
+ }
15383
+ ).register(
15384
+ "search",
15385
+ {
15386
+ h: "substring search over catalog id and description",
15387
+ inputSchema: external_exports.strictObject({
15388
+ q: external_exports.string().min(1).describe("case-insensitive substring"),
15389
+ opts: HTBP_LIST_OPTIONS_SCHEMA.optional()
15390
+ }),
15391
+ returns: "Page<CatalogListItem>",
15392
+ scope: "read"
15393
+ },
15394
+ ({ opts, q }, { deps }) => paginate(sortedItems(deps).filter((i) => matches2(i, q)), opts)
15395
+ );
15231
15396
  function createCatalogModule(deps) {
15232
- const sortedItems = () => Object.values(deps.catalog()).sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0).map(projectListItem);
15233
- return {
15234
- module: "catalog",
15235
- description: DESCRIPTION,
15236
- help(nodePath) {
15237
- return {
15238
- node: { path: nodePath, kind: "builtin", description: DESCRIPTION },
15239
- cmds: catalogCmds(nodePath)
15240
- };
15241
- },
15242
- async dispatch(cmd, args) {
15243
- switch (cmd) {
15244
- case "list":
15245
- return paginate(sortedItems(), args.opts);
15246
- case "get": {
15247
- const id = requireString(args, "id");
15248
- const entry = deps.catalog()[id];
15249
- if (entry === void 0) {
15250
- throw new TBError("not_found", `no catalog entry '${id}'`);
15251
- }
15252
- return entry;
15253
- }
15254
- case "search": {
15255
- const q = requireString(args, "q");
15256
- return paginate(sortedItems().filter((i) => matches2(i, q)), args.opts);
15257
- }
15258
- default:
15259
- throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/catalog`);
15260
- }
15261
- }
15262
- };
15397
+ return COMMANDS.module(deps);
15263
15398
  }
15264
15399
 
15265
15400
  // ../core/src/plugin/oauth.ts
@@ -15423,9 +15558,156 @@ function parseTokenResponse(payload, config2, now) {
15423
15558
  };
15424
15559
  }
15425
15560
 
15561
+ // ../core/src/context/commands.ts
15562
+ var metadataSchema = external_exports.record(external_exports.string(), external_exports.string()).optional().describe(
15563
+ "string-to-string metadata map"
15564
+ );
15565
+ var entrySchema = external_exports.strictObject({
15566
+ contentType: external_exports.string().optional().describe(
15567
+ "required when content is a string; defaults to application/json for non-string content"
15568
+ ),
15569
+ content: external_exports.unknown().describe("entry body: string, or any JSON value"),
15570
+ metadata: metadataSchema,
15571
+ ifVersion: external_exports.string().optional().describe("optimistic concurrency: expected current version")
15572
+ });
15573
+ var patchSchema = external_exports.strictObject({
15574
+ content: external_exports.unknown().optional().describe("replacement content"),
15575
+ metadata: metadataSchema,
15576
+ ifVersion: external_exports.string().optional().describe("optimistic concurrency: expected current version")
15577
+ }).describe("partial update; omitted fields keep their current value");
15578
+ var searchOptionsSchema = external_exports.strictObject({
15579
+ cursor: external_exports.string().optional().describe("opaque cursor returned by the previous page"),
15580
+ limit: external_exports.number().optional().describe("page size (default 50, max 200)"),
15581
+ mode: external_exports.enum(["keyword", "semantic"]).optional().describe('default "keyword"')
15582
+ }).describe("pagination + search mode");
15583
+ var contextCommands = new HtbpCommandRegistry().register(
15584
+ "list",
15585
+ {
15586
+ h: "list entries directly under a path (shallow, paginated)",
15587
+ inputSchema: external_exports.strictObject({
15588
+ path: external_exports.string().optional().describe("entry path prefix inside the namespace"),
15589
+ opts: HTBP_LIST_OPTIONS_SCHEMA.optional()
15590
+ }),
15591
+ returns: "Page<ContextEntryMeta>",
15592
+ scope: "read"
15593
+ },
15594
+ ({ opts, path }, { provider }) => provider.list(path ?? "", opts)
15595
+ ).register(
15596
+ "get",
15597
+ {
15598
+ h: "read one entry with content (oversized content comes back as { $ref: <download URL> })",
15599
+ inputSchema: external_exports.strictObject({
15600
+ path: external_exports.string().describe("entry path inside the namespace")
15601
+ }),
15602
+ returns: "ContextEntry",
15603
+ scope: "read"
15604
+ },
15605
+ ({ path }, { provider }) => provider.get(path)
15606
+ ).register(
15607
+ "write",
15608
+ {
15609
+ h: "create or fully replace an entry (idempotent upsert)",
15610
+ inputSchema: external_exports.strictObject({
15611
+ path: external_exports.string().describe("entry path inside the namespace"),
15612
+ entry: entrySchema
15613
+ }),
15614
+ returns: "ContextEntryMeta",
15615
+ scope: "write"
15616
+ },
15617
+ ({ entry, path }, { provider }) => provider.write(path, entry)
15618
+ ).register(
15619
+ "update",
15620
+ {
15621
+ h: "partially update content and/or metadata (shallow merge); not_found if the entry does not exist",
15622
+ inputSchema: external_exports.strictObject({
15623
+ path: external_exports.string().describe("entry path inside the namespace"),
15624
+ patch: patchSchema
15625
+ }),
15626
+ returns: "ContextEntryMeta",
15627
+ scope: "write"
15628
+ },
15629
+ ({ patch, path }, { provider }) => provider.update(path, patch)
15630
+ ).register(
15631
+ "delete",
15632
+ {
15633
+ h: "delete an entry (idempotent)",
15634
+ inputSchema: external_exports.strictObject({
15635
+ path: external_exports.string().describe("entry path inside the namespace")
15636
+ }),
15637
+ scope: "write",
15638
+ effect: "destructive"
15639
+ },
15640
+ ({ path }, { provider }) => provider.delete(path)
15641
+ ).register(
15642
+ "search",
15643
+ {
15644
+ h: "keyword search: substring match on entry paths and metadata values",
15645
+ inputSchema: external_exports.strictObject({
15646
+ query: external_exports.string().describe("substring to match"),
15647
+ opts: searchOptionsSchema.optional()
15648
+ }),
15649
+ returns: "Page<ContextEntryMeta>",
15650
+ scope: "read"
15651
+ },
15652
+ ({ opts, query }, { provider }) => provider.search(query, opts)
15653
+ ).register(
15654
+ "create_upload",
15655
+ {
15656
+ h: "create a short-lived, path-scoped direct-upload grant; persist the returned uri, not url",
15657
+ inputSchema: external_exports.strictObject({
15658
+ path: external_exports.string().describe("target entry path inside the namespace"),
15659
+ contentType: external_exports.string().describe("media type signed into the PUT request"),
15660
+ overwrite: external_exports.boolean().optional().describe(
15661
+ "allow replacing an existing object; default false"
15662
+ )
15663
+ }),
15664
+ returns: "ContextUploadGrant",
15665
+ scope: "write",
15666
+ effect: "write"
15667
+ },
15668
+ ({ contentType, overwrite, path }, { upload }) => upload({
15669
+ path,
15670
+ contentType,
15671
+ ...overwrite !== void 0 ? { overwrite } : {}
15672
+ })
15673
+ );
15674
+ function contextScopeForCmd(command) {
15675
+ const scope = contextCommands.scopeFor(command);
15676
+ return scope === "read" || scope === "write" ? scope : null;
15677
+ }
15678
+ function parseContextCmdArgs(command, args) {
15679
+ const normalized = command.toLowerCase();
15680
+ if (!contextCommands.has(normalized) || normalized === "create_upload") {
15681
+ throw new TBError("invalid_argument", `unknown cmd '${command}'`);
15682
+ }
15683
+ return contextCommands.parse(normalized, args);
15684
+ }
15685
+ async function dispatchContextCmd(provider, command, args) {
15686
+ const normalized = command.toLowerCase();
15687
+ if (!contextCommands.has(normalized) || normalized === "create_upload") {
15688
+ throw new TBError("invalid_argument", `unknown cmd '${command}'`);
15689
+ }
15690
+ const method = normalized;
15691
+ if (typeof provider[method] !== "function") {
15692
+ throw new TBError("invalid_argument", `unknown cmd '${command}'(provider \u672A\u5B9E\u73B0)`);
15693
+ }
15694
+ if (normalized === "write" && (typeof args.entry !== "object" || args.entry === null)) {
15695
+ throw new TBError("invalid_argument", "write \u9700\u8981\u5BF9\u8C61 'entry'");
15696
+ }
15697
+ if (normalized === "update" && (typeof args.patch !== "object" || args.patch === null)) {
15698
+ throw new TBError("invalid_argument", "update \u9700\u8981\u5BF9\u8C61 'patch'");
15699
+ }
15700
+ return await contextCommands.invoke(normalized, args, { provider });
15701
+ }
15702
+ async function dispatchContextUploadCmd(args, upload) {
15703
+ return await contextCommands.invoke("create_upload", args, {
15704
+ upload
15705
+ });
15706
+ }
15707
+
15426
15708
  // ../core/src/context/capabilities.ts
15427
- var CONTEXT_METHODS = ["list", "get", "search", "write", "update", "delete"];
15428
- var CONTEXT_WRITE_METHODS = ["write", "update", "delete"];
15709
+ var CONTEXT_METHODS = contextCommands.names().filter((name) => name !== "create_upload");
15710
+ var CONTEXT_WRITE_METHODS = CONTEXT_METHODS.filter((method) => contextCommands.scopeFor(method) === "write");
15429
15711
  function contextMethodsOf(provider) {
15430
15712
  const methods = /* @__PURE__ */ new Set();
15431
15713
  for (const method of CONTEXT_METHODS) {
@@ -15750,99 +16032,93 @@ function pluginTokenSecretName(id) {
15750
16032
  function projectManifest(record2) {
15751
16033
  return omit2(record2, "tokenSkId");
15752
16034
  }
15753
- function pluginCmds(nodePath) {
15754
- const path = cmdPath(nodePath);
15755
- const idSchema2 = {
15756
- type: "object",
15757
- properties: { id: { type: "string", description: "plugin id" } },
15758
- required: ["id"]
15759
- };
15760
- const cmds = [
15761
- {
15762
- name: "list",
15763
- method: "POST",
15764
- path,
15765
- h: "list registered plugins (pluginToken never returned)",
15766
- inputSchema: { type: "object", properties: { opts: LIST_OPTS_SCHEMA } },
15767
- returns: "Page<PluginView> \u2014 manifest + the exports declared by its /~describe",
15768
- scope: "admin"
15769
- },
15770
- {
15771
- name: "get",
15772
- method: "POST",
15773
- path,
15774
- h: "fetch one plugin manifest by id",
15775
- inputSchema: idSchema2,
15776
- returns: "PluginView \u2014 manifest + the exports declared by its /~describe",
15777
- scope: "admin"
15778
- },
15779
- {
15780
- name: "write",
15781
- method: "POST",
15782
- path,
15783
- h: "register a plugin: probes health and validates its /~describe exports before accepting; then mount an export via system/registry (config.provider = plugin id, config.export = export id)",
15784
- inputSchema: {
15785
- type: "object",
15786
- properties: {
15787
- id: { type: "string", description: "unique plugin id" },
15788
- protocolVersion: {
15789
- type: "string",
15790
- enum: ["plugin/v2"],
15791
- description: "transport protocol version; what the plugin provides is declared by its /~describe exports"
15792
- },
15793
- endpoint: { type: "string", description: "https base URL of the plugin service" },
15794
- auth: {
15795
- type: "object",
15796
- description: '{ kind: "platform-token" } \u2014 gateway mints the token (shown once in the response); or { kind: "bearer", secretRef }'
15797
- },
15798
- healthPath: { type: "string", description: 'GET probe path, e.g. "/healthz"' },
15799
- enabled: { type: "boolean" }
15800
- },
15801
- required: ["id", "endpoint", "auth", "healthPath", "enabled"]
15802
- },
15803
- returns: "PluginView + pluginToken shown once (platform-token only)",
15804
- scope: "admin"
15805
- },
15806
- {
15807
- name: "update",
15808
- method: "POST",
15809
- path,
15810
- h: "patch a registration; endpoint changes re-probe and re-validate the exports before applying",
15811
- inputSchema: {
15812
- type: "object",
15813
- properties: {
15814
- id: { type: "string", description: "plugin id" },
15815
- patch: {
15816
- type: "object",
15817
- description: "fields to change; same shape as write, all optional"
15818
- }
15819
- },
15820
- required: ["id", "patch"]
15821
- },
15822
- returns: "PluginView \u2014 pluginToken shown once if auth switched to platform-token",
15823
- scope: "admin"
15824
- },
15825
- {
15826
- name: "delete",
15827
- method: "POST",
15828
- path,
15829
- h: "unregister a plugin and revoke its platform token; mounted nodes referencing it stop working",
15830
- inputSchema: idSchema2,
15831
- returns: "void",
15832
- scope: "admin"
15833
- },
15834
- {
15835
- name: "health",
15836
- method: "POST",
15837
- path,
15838
- h: "probe the plugin health endpoint now",
15839
- inputSchema: idSchema2,
15840
- returns: "{ id, healthy, checkedAt }",
15841
- scope: "admin"
15842
- }
15843
- ];
15844
- return withCommandPaths(nodePath, cmds);
15845
- }
16035
+ var pluginAuthSchema = external_exports.discriminatedUnion("kind", [
16036
+ external_exports.strictObject({ kind: external_exports.literal("platform-token") }),
16037
+ external_exports.strictObject({ kind: external_exports.literal("bearer"), secretRef: external_exports.string().min(1) })
16038
+ ]).describe(
16039
+ '{ kind: "platform-token" } \u2014 gateway mints the token (shown once in the response); or { kind: "bearer", secretRef }'
16040
+ );
16041
+ var pluginIdSchema = external_exports.string().min(1).describe("plugin id");
16042
+ var manifestFields = {
16043
+ id: external_exports.string().min(1).describe("unique plugin id"),
16044
+ protocolVersion: external_exports.literal("plugin/v2").describe(
16045
+ "transport protocol version; what the plugin provides is declared by its /~describe exports"
16046
+ ),
16047
+ endpoint: external_exports.string().min(1).describe("https base URL of the plugin service"),
16048
+ auth: pluginAuthSchema,
16049
+ healthPath: external_exports.string().min(1).describe('GET probe path, e.g. "/healthz"'),
16050
+ enabled: external_exports.boolean()
16051
+ };
16052
+ var pluginWriteSchema = external_exports.strictObject(manifestFields);
16053
+ var pluginPatchSchema = external_exports.strictObject({
16054
+ id: manifestFields.id.optional(),
16055
+ protocolVersion: manifestFields.protocolVersion.optional(),
16056
+ endpoint: manifestFields.endpoint.optional(),
16057
+ auth: manifestFields.auth.optional(),
16058
+ healthPath: manifestFields.healthPath.optional(),
16059
+ enabled: manifestFields.enabled.optional()
16060
+ }).describe("fields to change; same shape as write, all optional");
16061
+ var COMMANDS2 = new BuiltinCommandRegistry("plugin", DESCRIPTION2).register(
16062
+ "list",
16063
+ {
16064
+ h: "list registered plugins (pluginToken never returned)",
16065
+ inputSchema: external_exports.strictObject({ opts: HTBP_LIST_OPTIONS_SCHEMA.optional() }),
16066
+ returns: "Page<PluginView> \u2014 manifest + the exports declared by its /~describe",
16067
+ scope: "admin"
16068
+ },
16069
+ ({ opts }, { deps }) => deps.list(opts)
16070
+ ).register(
16071
+ "get",
16072
+ {
16073
+ h: "fetch one plugin manifest by id",
16074
+ inputSchema: external_exports.strictObject({ id: pluginIdSchema }),
16075
+ returns: "PluginView \u2014 manifest + the exports declared by its /~describe",
16076
+ scope: "admin"
16077
+ },
16078
+ ({ id }, { deps }) => deps.get(id)
16079
+ ).register(
16080
+ "write",
16081
+ {
16082
+ h: "register a plugin: probes health and validates its /~describe exports before accepting; then mount an export via system/registry (config.provider = plugin id, config.export = export id)",
16083
+ inputSchema: pluginWriteSchema,
16084
+ returns: "PluginView + pluginToken shown once (platform-token only)",
16085
+ scope: "admin"
16086
+ },
16087
+ (input, { deps }) => deps.write(input)
16088
+ ).register(
16089
+ "update",
16090
+ {
16091
+ h: "patch a registration; endpoint changes re-probe and re-validate the exports before applying",
16092
+ inputSchema: external_exports.strictObject({
16093
+ id: pluginIdSchema,
16094
+ patch: pluginPatchSchema
16095
+ }),
16096
+ returns: "PluginView \u2014 pluginToken shown once if auth switched to platform-token",
16097
+ scope: "admin"
16098
+ },
16099
+ ({ id, patch }, { deps }) => deps.update(id, patch)
16100
+ ).register(
16101
+ "delete",
16102
+ {
16103
+ h: "unregister a plugin and revoke its platform token; mounted nodes referencing it stop working",
16104
+ inputSchema: external_exports.strictObject({ id: pluginIdSchema }),
16105
+ returns: "void",
16106
+ scope: "admin"
16107
+ },
16108
+ async ({ id }, { deps }) => {
16109
+ await deps.remove(id);
16110
+ return VOID_ACK;
16111
+ }
16112
+ ).register(
16113
+ "health",
16114
+ {
16115
+ h: "probe the plugin health endpoint now",
16116
+ inputSchema: external_exports.strictObject({ id: pluginIdSchema }),
16117
+ returns: "{ id, healthy, checkedAt }",
16118
+ scope: "admin"
16119
+ },
16120
+ ({ id }, { deps }) => deps.health(id)
16121
+ );
15846
16122
  function clampLimit2(limit) {
15847
16123
  if (limit === void 0 || limit < 1) return LIST_LIMIT_DEFAULT;
15848
16124
  return limit > LIST_LIMIT_MAX ? LIST_LIMIT_MAX : limit;
@@ -15988,394 +16264,216 @@ function createPluginModule(deps) {
15988
16264
  await store.delete(KEY_PLUGIN_HEALTH + id);
15989
16265
  await store.delete(KEY_PLUGIN_META + id);
15990
16266
  }
15991
- return {
15992
- module: "plugin",
15993
- description: DESCRIPTION2,
15994
- help(nodePath) {
15995
- return {
15996
- node: { path: nodePath, kind: "builtin", description: DESCRIPTION2 },
15997
- cmds: pluginCmds(nodePath)
15998
- };
16267
+ return COMMANDS2.module({
16268
+ async list(opts) {
16269
+ const listOpts = { limit: clampLimit2(opts?.limit) };
16270
+ if (opts?.cursor !== void 0) listOpts.cursor = opts.cursor;
16271
+ const page = await store.list(KEY_PLUGIN, listOpts);
16272
+ const items = await Promise.all(
16273
+ page.items.map(({ value }) => view(value))
16274
+ );
16275
+ return page.cursor !== void 0 ? { items, cursor: page.cursor } : { items };
15999
16276
  },
16000
- async dispatch(cmd, args) {
16001
- switch (cmd) {
16002
- case "list": {
16003
- const opts = optListOptions(args);
16004
- const listOpts = { limit: clampLimit2(opts?.limit) };
16005
- if (opts?.cursor !== void 0) listOpts.cursor = opts.cursor;
16006
- const page = await store.list(KEY_PLUGIN, listOpts);
16007
- const items = await Promise.all(
16008
- page.items.map(({ value }) => view(value))
16009
- );
16010
- return page.cursor !== void 0 ? { items, cursor: page.cursor } : { items };
16011
- }
16012
- case "get":
16013
- return await view(await require2(requireString(args, "id")));
16014
- case "write":
16015
- return write(args);
16016
- case "update": {
16017
- const id = requireString(args, "id");
16018
- const patch = args.patch;
16019
- if (typeof patch !== "object" || patch === null) {
16020
- throw new TBError("invalid_argument", "field 'patch' must be an object");
16021
- }
16022
- return update(id, patch);
16023
- }
16024
- case "delete":
16025
- await remove(requireString(args, "id"));
16026
- return VOID_ACK;
16027
- case "health": {
16028
- const id = requireString(args, "id");
16029
- const manifest = projectManifest(await require2(id));
16030
- const record2 = await probeAndRecord(manifest);
16031
- return { id, healthy: record2.healthy, checkedAt: record2.checkedAt };
16032
- }
16033
- default:
16034
- throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/plugin`);
16035
- }
16277
+ async get(id) {
16278
+ return await view(await require2(id));
16279
+ },
16280
+ write,
16281
+ update,
16282
+ remove,
16283
+ async health(id) {
16284
+ const manifest = projectManifest(await require2(id));
16285
+ const record2 = await probeAndRecord(manifest);
16286
+ return { id, healthy: record2.healthy, checkedAt: record2.checkedAt };
16036
16287
  }
16037
- };
16288
+ });
16038
16289
  }
16039
16290
 
16040
16291
  // ../core/src/builtin/store.ts
16041
- var STORE_SCOPE_BY_CMD = {
16042
- create_upload: "write",
16043
- complete_upload: "write",
16044
- abort_upload: "write",
16045
- stat: "read",
16046
- read: "read",
16047
- share: "write",
16048
- revoke_share: "write",
16049
- delete: "write",
16050
- list: "read"
16051
- };
16052
16292
  var DESCRIPTION3 = "Deployment-level private object Store for uploads, reads and short-lived sharing";
16053
- function storeCmds(nodePath) {
16054
- const path = cmdPath(nodePath);
16055
- const objectFields = {
16056
- contentType: { type: "string", description: "object MIME type" },
16057
- filename: { type: "string", description: "display-only filename; never used as a storage key" },
16058
- size: { type: "number", description: "expected byte size" },
16059
- checksum: {
16060
- type: "object",
16061
- description: "optional sha256 checksum declaration",
16062
- properties: {
16063
- algorithm: { type: "string", enum: ["sha256"] },
16064
- value: { type: "string" }
16065
- }
16066
- },
16067
- idempotencyKey: { type: "string", description: "owner-scoped create retry key" }
16068
- };
16069
- const uriField = { uri: { type: "string", description: "store://default/<objectId>" } };
16070
- const specs = [
16071
- {
16072
- name: "create_upload",
16073
- method: "POST",
16074
- path,
16075
- h: "create a new opaque Store object and bounded upload session",
16076
- inputSchema: {
16077
- type: "object",
16078
- properties: objectFields,
16079
- required: ["contentType"]
16080
- },
16081
- returns: "StoreUploadGrant"
16082
- },
16083
- {
16084
- name: "complete_upload",
16085
- method: "POST",
16086
- path,
16087
- h: "verify a direct upload and atomically mark its object ready; idempotent",
16088
- inputSchema: {
16089
- type: "object",
16090
- properties: {
16091
- uploadId: { type: "string" }
16092
- },
16093
- required: ["uploadId"]
16094
- },
16095
- returns: "StoreObject"
16096
- },
16097
- {
16098
- name: "abort_upload",
16099
- method: "POST",
16100
- path,
16101
- h: "abandon an unfinished upload; idempotent until the object is ready",
16102
- inputSchema: {
16103
- type: "object",
16104
- properties: {
16105
- uploadId: { type: "string" }
16106
- },
16107
- required: ["uploadId"]
16108
- },
16109
- returns: "void"
16110
- },
16111
- {
16112
- name: "stat",
16113
- method: "POST",
16114
- path,
16115
- h: "return metadata for a ready object owned by the current principal",
16116
- inputSchema: {
16117
- type: "object",
16118
- properties: uriField,
16119
- required: ["uri"]
16120
- },
16121
- returns: "StoreObject"
16122
- },
16123
- {
16124
- name: "read",
16125
- method: "POST",
16126
- path,
16127
- h: "authorize an object read and return a short-lived $ref",
16128
- inputSchema: {
16129
- type: "object",
16130
- properties: uriField,
16131
- required: ["uri"]
16132
- },
16133
- returns: "{ $ref, contentType, size, expiresAt }"
16134
- },
16135
- {
16136
- name: "share",
16137
- method: "POST",
16138
- path,
16139
- h: "create a short-lived, revocable read share for an owned object",
16140
- inputSchema: {
16141
- type: "object",
16142
- properties: { ...uriField, ttlSec: { type: "number" } },
16143
- required: ["uri"]
16144
- },
16145
- returns: "StoreShare"
16146
- },
16147
- {
16148
- name: "revoke_share",
16149
- method: "POST",
16150
- path,
16151
- h: "revoke a Store share grant",
16152
- inputSchema: {
16153
- type: "object",
16154
- properties: { shareId: { type: "string" } },
16155
- required: ["shareId"]
16156
- },
16157
- returns: "void"
16158
- },
16159
- {
16160
- name: "delete",
16161
- method: "POST",
16162
- path,
16163
- h: "make an owned Store object immediately unreadable and delete its bytes",
16164
- inputSchema: { type: "object", properties: uriField, required: ["uri"] },
16165
- returns: "void"
16166
- },
16167
- {
16168
- name: "list",
16169
- method: "POST",
16170
- path,
16171
- h: "list ready Store objects owned by the current principal",
16172
- inputSchema: { type: "object", properties: { opts: LIST_OPTS_SCHEMA } },
16173
- returns: "Page<StoreObject>"
16174
- }
16175
- ];
16176
- return withCommandPaths(nodePath, specs.map((spec) => ({
16177
- ...spec,
16178
- scope: STORE_SCOPE_BY_CMD[spec.name]
16179
- })));
16180
- }
16181
- function optionalPositiveInt(args, field) {
16182
- const value = args[field];
16183
- if (value === void 0) return void 0;
16184
- if (!Number.isSafeInteger(value) || value < 1) {
16185
- throw new TBError("invalid_argument", `${field} \u5FC5\u987B\u662F\u6B63\u6574\u6570`);
16293
+ var contentTypeSchema = external_exports.string().min(1).describe("object MIME type");
16294
+ var filenameSchema = external_exports.string().optional().describe(
16295
+ "display-only filename; never used as a storage key"
16296
+ );
16297
+ var checksumSchema = external_exports.strictObject({
16298
+ algorithm: external_exports.literal("sha256"),
16299
+ value: external_exports.string()
16300
+ }).optional().describe("optional sha256 checksum declaration");
16301
+ var uriSchema = external_exports.string().describe("store://default/<objectId>");
16302
+ var COMMANDS3 = new BuiltinCommandRegistry("store", DESCRIPTION3).register(
16303
+ "create_upload",
16304
+ {
16305
+ h: "create a new opaque Store object and bounded upload session",
16306
+ inputSchema: external_exports.strictObject({
16307
+ contentType: contentTypeSchema,
16308
+ filename: filenameSchema,
16309
+ size: external_exports.number().optional().describe("expected byte size"),
16310
+ checksum: checksumSchema,
16311
+ idempotencyKey: external_exports.string().optional().describe("owner-scoped create retry key")
16312
+ }),
16313
+ returns: "StoreUploadGrant",
16314
+ scope: "write"
16315
+ },
16316
+ async ({ checksum, contentType, filename, idempotencyKey, size }, { call, deps, runtime }) => {
16317
+ const input = {
16318
+ contentType,
16319
+ ...filename !== void 0 ? { filename } : {},
16320
+ ...size !== void 0 ? { size } : {},
16321
+ ...checksum !== void 0 ? { checksum } : {},
16322
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {}
16323
+ };
16324
+ const start = await deps.service.beginUpload(input, {
16325
+ owner: call.owner,
16326
+ producer: call.owner
16327
+ });
16328
+ return deps.callbacks.createUpload(start, runtime);
16186
16329
  }
16187
- return value;
16188
- }
16189
- function rejectUnknown(args, allowed) {
16190
- const unknown2 = Object.keys(args).filter((key) => !allowed.includes(key));
16191
- if (unknown2.length > 0) {
16192
- throw new TBError("invalid_argument", `\u672A\u77E5\u5B57\u6BB5:${unknown2.join(",")}`);
16330
+ ).register(
16331
+ "complete_upload",
16332
+ {
16333
+ h: "verify a direct upload and atomically mark its object ready; idempotent",
16334
+ inputSchema: external_exports.strictObject({ uploadId: external_exports.string().min(1) }),
16335
+ returns: "StoreObject",
16336
+ scope: "write"
16337
+ },
16338
+ ({ uploadId }, { call, deps }) => deps.service.completeUpload(uploadId, call.owner)
16339
+ ).register(
16340
+ "abort_upload",
16341
+ {
16342
+ h: "abandon an unfinished upload; idempotent until the object is ready",
16343
+ inputSchema: external_exports.strictObject({ uploadId: external_exports.string().min(1) }),
16344
+ returns: "void",
16345
+ scope: "write"
16346
+ },
16347
+ ({ uploadId }, { call, deps }) => deps.service.abortUpload(uploadId, call.owner)
16348
+ ).register(
16349
+ "stat",
16350
+ {
16351
+ h: "return metadata for a ready object owned by the current principal",
16352
+ inputSchema: external_exports.strictObject({ uri: uriSchema }),
16353
+ returns: "StoreObject",
16354
+ scope: "read"
16355
+ },
16356
+ ({ uri }, { call, deps }) => deps.service.stat(uri, { owner: call.owner })
16357
+ ).register(
16358
+ "read",
16359
+ {
16360
+ h: "authorize an object read and return a short-lived $ref",
16361
+ inputSchema: external_exports.strictObject({ uri: uriSchema }),
16362
+ returns: "{ $ref, contentType, size, expiresAt }",
16363
+ scope: "read"
16364
+ },
16365
+ async ({ uri }, { call, deps, runtime }) => {
16366
+ const object2 = await deps.service.authorizeRead(uri, { owner: call.owner });
16367
+ return deps.callbacks.read(object2, runtime);
16193
16368
  }
16194
- }
16369
+ ).register(
16370
+ "share",
16371
+ {
16372
+ h: "create a short-lived, revocable read share for an owned object",
16373
+ inputSchema: external_exports.strictObject({
16374
+ uri: uriSchema,
16375
+ ttlSec: external_exports.number().int().positive().optional()
16376
+ }),
16377
+ returns: "StoreShare",
16378
+ scope: "write"
16379
+ },
16380
+ async ({ ttlSec, uri }, { call, deps, runtime }) => {
16381
+ const result = ttlSec === void 0 ? await deps.service.share(uri, call.owner) : await deps.service.share(uri, call.owner, ttlSec);
16382
+ return deps.callbacks.share(result, runtime);
16383
+ }
16384
+ ).register(
16385
+ "revoke_share",
16386
+ {
16387
+ h: "revoke a Store share grant",
16388
+ inputSchema: external_exports.strictObject({ shareId: external_exports.string().min(1) }),
16389
+ returns: "void",
16390
+ scope: "write"
16391
+ },
16392
+ ({ shareId }, { call, deps }) => deps.service.revokeShare(shareId, call.owner)
16393
+ ).register(
16394
+ "delete",
16395
+ {
16396
+ h: "make an owned Store object immediately unreadable and delete its bytes",
16397
+ inputSchema: external_exports.strictObject({ uri: uriSchema }),
16398
+ returns: "void",
16399
+ scope: "write"
16400
+ },
16401
+ ({ uri }, { call, deps }) => deps.service.delete(uri, { owner: call.owner })
16402
+ ).register(
16403
+ "list",
16404
+ {
16405
+ h: "list ready Store objects owned by the current principal",
16406
+ inputSchema: external_exports.strictObject({ opts: HTBP_LIST_OPTIONS_SCHEMA.optional() }),
16407
+ returns: "Page<StoreObject>",
16408
+ scope: "read"
16409
+ },
16410
+ ({ opts }, { call, deps }) => deps.service.list(call.owner, opts ?? {})
16411
+ );
16195
16412
  function createStoreModule(deps) {
16196
- return {
16197
- module: "store",
16198
- description: DESCRIPTION3,
16199
- help(nodePath) {
16200
- return {
16201
- node: { path: nodePath, kind: "builtin", description: DESCRIPTION3 },
16202
- cmds: storeCmds(nodePath)
16203
- };
16204
- },
16205
- async dispatch(cmd, args, ctx, runtime) {
16206
- switch (cmd) {
16207
- case "create_upload": {
16208
- rejectUnknown(args, ["contentType", "filename", "size", "checksum", "idempotencyKey"]);
16209
- const input = {
16210
- contentType: requireString(args, "contentType"),
16211
- ...args.filename !== void 0 ? { filename: args.filename } : {},
16212
- ...args.size !== void 0 ? { size: args.size } : {},
16213
- ...args.checksum !== void 0 ? { checksum: args.checksum } : {},
16214
- ...args.idempotencyKey !== void 0 ? { idempotencyKey: args.idempotencyKey } : {}
16215
- };
16216
- const start = await deps.service.beginUpload(input, {
16217
- owner: ctx.owner,
16218
- producer: ctx.owner
16219
- });
16220
- return deps.callbacks.createUpload(start, runtime);
16221
- }
16222
- case "complete_upload":
16223
- rejectUnknown(args, ["uploadId"]);
16224
- return deps.service.completeUpload(requireString(args, "uploadId"), ctx.owner);
16225
- case "abort_upload":
16226
- rejectUnknown(args, ["uploadId"]);
16227
- return deps.service.abortUpload(requireString(args, "uploadId"), ctx.owner);
16228
- case "stat":
16229
- rejectUnknown(args, ["uri"]);
16230
- return deps.service.stat(requireString(args, "uri"), { owner: ctx.owner });
16231
- case "read": {
16232
- rejectUnknown(args, ["uri"]);
16233
- const object2 = await deps.service.authorizeRead(requireString(args, "uri"), {
16234
- owner: ctx.owner
16235
- });
16236
- return deps.callbacks.read(object2, runtime);
16237
- }
16238
- case "share": {
16239
- rejectUnknown(args, ["uri", "ttlSec"]);
16240
- const ttlSec = optionalPositiveInt(args, "ttlSec");
16241
- const result = ttlSec === void 0 ? await deps.service.share(requireString(args, "uri"), ctx.owner) : await deps.service.share(requireString(args, "uri"), ctx.owner, ttlSec);
16242
- return deps.callbacks.share(result, runtime);
16243
- }
16244
- case "revoke_share":
16245
- rejectUnknown(args, ["shareId"]);
16246
- return deps.service.revokeShare(requireString(args, "shareId"), ctx.owner);
16247
- case "delete":
16248
- rejectUnknown(args, ["uri"]);
16249
- return deps.service.delete(requireString(args, "uri"), { owner: ctx.owner });
16250
- case "list": {
16251
- rejectUnknown(args, ["opts"]);
16252
- const raw = args.opts;
16253
- if (raw !== void 0 && (typeof raw !== "object" || raw === null || Array.isArray(raw))) {
16254
- throw new TBError("invalid_argument", "opts \u5FC5\u987B\u662F\u5BF9\u8C61");
16255
- }
16256
- return deps.service.list(ctx.owner, raw ?? {});
16257
- }
16258
- default:
16259
- throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/store`);
16260
- }
16261
- }
16262
- };
16413
+ return COMMANDS3.module(deps);
16263
16414
  }
16264
16415
 
16265
16416
  // ../core/src/builtin/annotation.ts
16266
16417
  var DESCRIPTION4 = "Path annotations: admin-curated notes shown in ~help of the annotated path (set / get / remove / list)";
16267
- function annotationCmds(nodePath) {
16268
- const path = cmdPath(nodePath);
16269
- const cmds = [
16270
- {
16271
- name: "set",
16272
- method: "POST",
16273
- path,
16274
- h: "upsert the note shown in ~help of <path>; empty path = tree-wide notice",
16275
- inputSchema: {
16276
- type: "object",
16277
- properties: {
16278
- path: {
16279
- type: "string",
16280
- description: 'tree path (tool sub-paths like "feishu/create-doc" work); "" = tree-wide'
16281
- },
16282
- text: { type: "string", maxLength: 2e3, description: "the note (max 2000 chars)" }
16283
- },
16284
- required: ["path", "text"]
16285
- },
16286
- returns: "{ path, text, updatedAt, updatedBy }",
16287
- scope: "admin"
16288
- },
16289
- {
16290
- name: "get",
16291
- method: "POST",
16292
- path,
16293
- h: "read the note of one path (not_found if none)",
16294
- inputSchema: {
16295
- type: "object",
16296
- properties: { path: { type: "string", description: 'tree path; "" = tree-wide notice' } },
16297
- required: ["path"]
16298
- },
16299
- returns: "{ path, text, updatedAt, updatedBy }",
16300
- scope: "read"
16301
- },
16302
- {
16303
- name: "remove",
16304
- method: "POST",
16305
- path,
16306
- h: "remove the note of a path (idempotent)",
16307
- inputSchema: {
16308
- type: "object",
16309
- properties: { path: { type: "string", description: 'tree path; "" = tree-wide notice' } },
16310
- required: ["path"]
16311
- },
16312
- returns: "void",
16313
- scope: "admin"
16314
- },
16315
- {
16316
- name: "list",
16317
- method: "POST",
16318
- path,
16319
- h: "all annotated paths (optionally under a prefix)",
16320
- inputSchema: {
16321
- type: "object",
16322
- properties: {
16323
- prefix: { type: "string", description: "only paths under this prefix" }
16324
- }
16325
- },
16326
- returns: "{ items: Array<{ path, text, updatedAt, updatedBy }> }",
16327
- scope: "read"
16418
+ var rootablePathSchema = external_exports.string().describe('tree path; "" = tree-wide notice');
16419
+ var COMMANDS4 = new BuiltinCommandRegistry("annotation", DESCRIPTION4).register(
16420
+ "set",
16421
+ {
16422
+ h: "upsert the note shown in ~help of <path>; empty path = tree-wide notice",
16423
+ inputSchema: external_exports.strictObject({
16424
+ path: external_exports.string().describe(
16425
+ 'tree path (tool sub-paths like "feishu/create-doc" work); "" = tree-wide'
16426
+ ),
16427
+ text: external_exports.string().min(1).max(ANNOTATION_TEXT_MAX).describe("the note (max 2000 chars)")
16428
+ }),
16429
+ returns: "{ path, text, updatedAt, updatedBy }",
16430
+ scope: "admin"
16431
+ },
16432
+ async ({ path, text }, { call, deps }) => {
16433
+ if (normalizePath(path) !== "") await deps.registry.resolve(path);
16434
+ return await deps.store.set(path, text, call.keyId, deps.now());
16435
+ }
16436
+ ).register(
16437
+ "get",
16438
+ {
16439
+ h: "read the note of one path (not_found if none)",
16440
+ inputSchema: external_exports.strictObject({ path: rootablePathSchema }),
16441
+ returns: "{ path, text, updatedAt, updatedBy }",
16442
+ scope: "read"
16443
+ },
16444
+ async ({ path }, { deps }) => {
16445
+ const got = await deps.store.get(path);
16446
+ if (got === null) {
16447
+ throw TBError.notFound(`\u8DEF\u5F84\u65E0\u8865\u5145\u8BF4\u660E:'${path === "" ? "/" : path}'`);
16328
16448
  }
16329
- ];
16330
- return withCommandPaths(nodePath, cmds);
16331
- }
16332
- function requireRootablePath(args) {
16333
- const v = args.path;
16334
- if (typeof v !== "string") {
16335
- throw new TBError("invalid_argument", "field 'path' must be a string");
16449
+ return got;
16336
16450
  }
16337
- return v;
16338
- }
16451
+ ).register(
16452
+ "remove",
16453
+ {
16454
+ h: "remove the note of a path (idempotent)",
16455
+ inputSchema: external_exports.strictObject({ path: rootablePathSchema }),
16456
+ returns: "void",
16457
+ scope: "admin"
16458
+ },
16459
+ async ({ path }, { deps }) => {
16460
+ await deps.store.remove(path);
16461
+ return VOID_ACK;
16462
+ }
16463
+ ).register(
16464
+ "list",
16465
+ {
16466
+ h: "all annotated paths (optionally under a prefix)",
16467
+ inputSchema: external_exports.strictObject({
16468
+ prefix: external_exports.string().optional().describe("only paths under this prefix")
16469
+ }),
16470
+ returns: "{ items: Array<{ path, text, updatedAt, updatedBy }> }",
16471
+ scope: "read"
16472
+ },
16473
+ async ({ prefix }, { deps }) => ({ items: await deps.store.list(prefix) })
16474
+ );
16339
16475
  function createAnnotationModule(deps) {
16340
- return {
16341
- module: "annotation",
16342
- description: DESCRIPTION4,
16343
- help(nodePath) {
16344
- return {
16345
- node: { path: nodePath, kind: "builtin", description: DESCRIPTION4 },
16346
- cmds: annotationCmds(nodePath)
16347
- };
16348
- },
16349
- async dispatch(cmd, args, ctx) {
16350
- switch (cmd) {
16351
- case "set": {
16352
- const path = requireRootablePath(args);
16353
- if (normalizePath(path) !== "") {
16354
- await deps.registry.resolve(path);
16355
- }
16356
- return await deps.store.set(path, requireString(args, "text"), ctx.keyId, deps.now());
16357
- }
16358
- case "get": {
16359
- const path = requireRootablePath(args);
16360
- const got = await deps.store.get(path);
16361
- if (got === null) {
16362
- throw TBError.notFound(`\u8DEF\u5F84\u65E0\u8865\u5145\u8BF4\u660E:'${path === "" ? "/" : path}'`);
16363
- }
16364
- return got;
16365
- }
16366
- case "remove": {
16367
- await deps.store.remove(requireRootablePath(args));
16368
- return VOID_ACK;
16369
- }
16370
- case "list": {
16371
- const prefix = optString(args, "prefix");
16372
- return { items: await deps.store.list(prefix) };
16373
- }
16374
- default:
16375
- throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/annotation`);
16376
- }
16377
- }
16378
- };
16476
+ return COMMANDS4.module(deps);
16379
16477
  }
16380
16478
 
16381
16479
  // ../core/src/tool/allowlist.ts
@@ -16443,52 +16541,6 @@ var RemoteAllowlistStore = class {
16443
16541
 
16444
16542
  // ../core/src/builtin/federation.ts
16445
16543
  var DESCRIPTION5 = "Remote federation host allowlist: which hosts kind=remote nodes may connect to (env baseline is read-only; admin only)";
16446
- function federationCmds(nodePath) {
16447
- const path = cmdPath(nodePath);
16448
- const cmds = [
16449
- {
16450
- name: "list",
16451
- method: "POST",
16452
- path,
16453
- h: "merged allowlist view: env baseline entries (removable=false) plus runtime entries",
16454
- inputSchema: { type: "object", properties: {} },
16455
- returns: 'Page<{ host, source: "env"|"store", removable, updatedAt? }>',
16456
- scope: "admin"
16457
- },
16458
- {
16459
- name: "add",
16460
- method: "POST",
16461
- path,
16462
- h: "allow a host (suffix match covers subdomains); takes effect immediately",
16463
- inputSchema: {
16464
- type: "object",
16465
- properties: {
16466
- host: {
16467
- type: "string",
16468
- description: 'bare host suffix, e.g. "example.com" \u2014 no scheme/port/path'
16469
- }
16470
- },
16471
- required: ["host"]
16472
- },
16473
- returns: "{ host, updatedAt } \u2014 bare host suffix; no scheme/port/path",
16474
- scope: "admin"
16475
- },
16476
- {
16477
- name: "remove",
16478
- method: "POST",
16479
- path,
16480
- h: "remove a runtime-added host; env baseline entries cannot be removed here",
16481
- inputSchema: {
16482
- type: "object",
16483
- properties: { host: { type: "string", description: "bare host suffix as listed" } },
16484
- required: ["host"]
16485
- },
16486
- returns: "void \u2014 env baseline entries are not removable",
16487
- scope: "admin"
16488
- }
16489
- ];
16490
- return withCommandPaths(nodePath, cmds);
16491
- }
16492
16544
  function mergedView(base, entries) {
16493
16545
  const byHost = /* @__PURE__ */ new Map();
16494
16546
  for (const raw of base) {
@@ -16502,202 +16554,317 @@ function mergedView(base, entries) {
16502
16554
  }
16503
16555
  return [...byHost.values()].sort((a, b) => a.host.localeCompare(b.host));
16504
16556
  }
16505
- function createFederationModule(deps) {
16506
- return {
16507
- module: "federation",
16508
- description: DESCRIPTION5,
16509
- help(nodePath) {
16510
- return {
16511
- node: { path: nodePath, kind: "builtin", description: DESCRIPTION5 },
16512
- cmds: federationCmds(nodePath)
16513
- };
16514
- },
16515
- async dispatch(cmd, args) {
16516
- switch (cmd) {
16517
- case "list": {
16518
- const items = mergedView(deps.base, await deps.store.list());
16519
- return { items };
16520
- }
16521
- case "add": {
16522
- const host = normalizeAllowHost(requireString(args, "host"));
16523
- if (deps.base.some((b) => b.trim().toLowerCase() === host)) {
16524
- throw new TBError("invalid_argument", `host \u5DF2\u5728\u90E8\u7F72\u57FA\u7EBF(env)\u4E2D,\u65E0\u9700\u6DFB\u52A0:'${host}'`);
16525
- }
16526
- return await deps.store.add(host, deps.now());
16527
- }
16528
- case "remove": {
16529
- const host = normalizeAllowHost(requireString(args, "host"));
16530
- if (deps.base.some((b) => b.trim().toLowerCase() === host)) {
16531
- throw new TBError(
16532
- "invalid_argument",
16533
- `env \u57FA\u7EBF\u6761\u76EE\u4E0D\u53EF\u5220\u9664:'${host}'(\u6539 TB_REMOTE_ALLOWLIST \u5E76\u91CD\u65B0\u90E8\u7F72)`
16534
- );
16535
- }
16536
- await deps.store.remove(host);
16537
- return VOID_ACK;
16538
- }
16539
- default:
16540
- throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/federation`);
16541
- }
16542
- }
16543
- };
16544
- }
16545
-
16546
- // ../core/src/builtin/registry.ts
16547
- var DESCRIPTION6 = "Node registry: the single mount surface \u2014 everything on the tree (mcp/http/context/device/remote nodes) is mounted, listed and unmounted here";
16548
- var NODE_FIELD_SCHEMAS = {
16549
- path: { type: "string", description: 'tree path to mount at, e.g. "docs/context7"' },
16550
- kind: {
16551
- type: "string",
16552
- enum: [...NODE_KINDS],
16553
- description: "node kind; determines the config shape"
16557
+ var COMMANDS5 = new BuiltinCommandRegistry("federation", DESCRIPTION5).register(
16558
+ "list",
16559
+ {
16560
+ h: "merged allowlist view: env baseline entries (removable=false) plus runtime entries",
16561
+ inputSchema: external_exports.strictObject({}),
16562
+ returns: 'Page<{ host, source: "env"|"store", removable, updatedAt? }>',
16563
+ scope: "admin"
16554
16564
  },
16555
- description: { type: "string", description: "one-line description shown in parent ~help" },
16556
- config: {
16557
- type: "object",
16558
- description: "kind-specific config, e.g. mcp: { url, auth?, authRef? } / http: { endpoint, tools } / context: { provider, bucket, \u2026 } / remote: { baseUrl, skRef }; credentials go by authRef/skRef name, never inline"
16565
+ async (_input, { deps }) => ({ items: mergedView(deps.base, await deps.store.list()) })
16566
+ ).register(
16567
+ "add",
16568
+ {
16569
+ h: "allow a host (suffix match covers subdomains); takes effect immediately",
16570
+ inputSchema: external_exports.strictObject({
16571
+ host: external_exports.string().min(1).describe(
16572
+ 'bare host suffix, e.g. "example.com" \u2014 no scheme/port/path'
16573
+ )
16574
+ }),
16575
+ returns: "{ host, updatedAt } \u2014 bare host suffix; no scheme/port/path",
16576
+ scope: "admin"
16559
16577
  },
16560
- virtualize: {
16561
- type: "object",
16562
- description: "optional tool virtualization: { prefix?, rename?: {from:to}, hide?: [name], describe?: {name:text} }"
16578
+ async ({ host }, { deps }) => {
16579
+ const normalized = normalizeAllowHost(host);
16580
+ if (deps.base.some((b) => b.trim().toLowerCase() === normalized)) {
16581
+ throw new TBError("invalid_argument", `host \u5DF2\u5728\u90E8\u7F72\u57FA\u7EBF(env)\u4E2D,\u65E0\u9700\u6DFB\u52A0:'${normalized}'`);
16582
+ }
16583
+ return await deps.store.add(normalized, deps.now());
16563
16584
  }
16564
- };
16565
- function registryCmds(nodePath) {
16566
- const path = cmdPath(nodePath);
16567
- const cmds = [
16568
- {
16569
- name: "list",
16570
- method: "POST",
16571
- path,
16572
- h: "list registered nodes, optionally under a path prefix",
16573
- inputSchema: {
16574
- type: "object",
16575
- properties: {
16576
- prefix: { type: "string", description: "only nodes under this path prefix" },
16577
- opts: LIST_OPTS_SCHEMA
16578
- }
16579
- },
16580
- returns: "Page<Node>",
16581
- scope: "read"
16582
- },
16583
- {
16584
- name: "get",
16585
- method: "POST",
16586
- path,
16587
- h: "fetch one node registration (kind, description, config) by path",
16588
- inputSchema: {
16589
- type: "object",
16590
- properties: { path: { type: "string", description: "exact tree path" } },
16591
- required: ["path"]
16592
- },
16593
- returns: "Node",
16594
- scope: "read"
16595
- },
16596
- {
16597
- name: "write",
16598
- method: "POST",
16599
- path,
16600
- h: "mount (or replace) a node at a path; idempotent upsert, intermediate directories auto-created",
16601
- inputSchema: {
16602
- type: "object",
16603
- properties: NODE_FIELD_SCHEMAS,
16604
- required: ["path", "kind", "description"]
16605
- },
16606
- returns: "Node",
16607
- scope: "register"
16608
- },
16609
- {
16610
- name: "update",
16611
- method: "POST",
16612
- path,
16613
- h: "patch fields of a mounted node (description, config, virtualize, \u2026) without remounting",
16614
- inputSchema: {
16615
- type: "object",
16616
- properties: {
16617
- path: { type: "string", description: "exact tree path" },
16618
- patch: {
16619
- type: "object",
16620
- description: "fields to change; same shape as write, all optional",
16621
- properties: NODE_FIELD_SCHEMAS
16622
- }
16623
- },
16624
- required: ["path", "patch"]
16625
- },
16626
- returns: "Node",
16627
- scope: "register"
16628
- },
16629
- {
16630
- name: "delete",
16631
- method: "POST",
16632
- path,
16633
- h: "unmount a node (and reclaim empty auto-created parents); a node registered by another key can only be removed by its registrar or by a key holding the 'admin' scope on that path",
16634
- inputSchema: {
16635
- type: "object",
16636
- properties: { path: { type: "string", description: "exact tree path" } },
16637
- required: ["path"]
16638
- },
16639
- returns: "void",
16640
- scope: "register"
16585
+ ).register(
16586
+ "remove",
16587
+ {
16588
+ h: "remove a runtime-added host; env baseline entries cannot be removed here",
16589
+ inputSchema: external_exports.strictObject({
16590
+ host: external_exports.string().min(1).describe("bare host suffix as listed")
16591
+ }),
16592
+ returns: "void \u2014 env baseline entries are not removable",
16593
+ scope: "admin"
16594
+ },
16595
+ async ({ host }, { deps }) => {
16596
+ const normalized = normalizeAllowHost(host);
16597
+ if (deps.base.some((b) => b.trim().toLowerCase() === normalized)) {
16598
+ throw new TBError(
16599
+ "invalid_argument",
16600
+ `env \u57FA\u7EBF\u6761\u76EE\u4E0D\u53EF\u5220\u9664:'${normalized}'(\u6539 TB_REMOTE_ALLOWLIST \u5E76\u91CD\u65B0\u90E8\u7F72)`
16601
+ );
16641
16602
  }
16642
- ];
16643
- return withCommandPaths(nodePath, cmds);
16603
+ await deps.store.remove(normalized);
16604
+ return VOID_ACK;
16605
+ }
16606
+ );
16607
+ function createFederationModule(deps) {
16608
+ return COMMANDS5.module(deps);
16609
+ }
16610
+
16611
+ // ../core/src/protocol/errorWire.ts
16612
+ var tbErrorCodeSchema = external_exports.enum(TB_ERROR_CODES);
16613
+ var tbErrorBodySchema = external_exports.object({
16614
+ code: tbErrorCodeSchema,
16615
+ message: external_exports.string(),
16616
+ retryable: external_exports.boolean()
16617
+ });
16618
+
16619
+ // ../core/src/protocol/wire.ts
16620
+ var actionSchema = external_exports.enum(ACTIONS);
16621
+ var nodeKindSchema = external_exports.enum(NODE_KINDS);
16622
+ var nodeInputConfigSchema = external_exports.record(external_exports.string(), external_exports.unknown()).optional().describe(
16623
+ "kind-specific config, e.g. mcp: { url, auth?, authRef? } / http: { endpoint, tools } / context: { provider, bucket, \u2026 } / remote: { baseUrl, skRef }; credentials go by authRef/skRef name, never inline"
16624
+ );
16625
+ var nodeInputVirtualizeSchema = external_exports.strictObject({
16626
+ prefix: external_exports.string().optional(),
16627
+ rename: external_exports.record(external_exports.string(), external_exports.string()).optional(),
16628
+ hide: external_exports.array(external_exports.string()).optional(),
16629
+ describe: external_exports.record(external_exports.string(), external_exports.string()).optional()
16630
+ }).optional().describe(
16631
+ "optional tool virtualization: { prefix?, rename?: {from:to}, hide?: [name], describe?: {name:text} }"
16632
+ );
16633
+ var nodeInputSchema = external_exports.strictObject({
16634
+ path: external_exports.string().min(1).describe('tree path to mount at, e.g. "docs/context7"'),
16635
+ kind: nodeKindSchema.describe("node kind; determines the config shape"),
16636
+ description: external_exports.string().min(1).describe("one-line description shown in parent ~help"),
16637
+ config: nodeInputConfigSchema,
16638
+ virtualize: nodeInputVirtualizeSchema
16639
+ });
16640
+ var presenceStateSchema = external_exports.enum(["online", "stale", "offline"]);
16641
+ var presenceSchema = external_exports.object({
16642
+ lastSeenAt: external_exports.string().optional(),
16643
+ state: presenceStateSchema
16644
+ });
16645
+ var helpFeedbackItemSchema = external_exports.object({
16646
+ id: external_exports.string(),
16647
+ score: external_exports.number(),
16648
+ title: external_exports.string()
16649
+ });
16650
+ var helpChildSchema = external_exports.object({
16651
+ description: external_exports.string(),
16652
+ kind: nodeKindSchema,
16653
+ path: external_exports.string()
16654
+ });
16655
+ var helpCommandSchema = external_exports.object({
16656
+ confirm: external_exports.boolean().optional(),
16657
+ effect: external_exports.string().optional(),
16658
+ h: external_exports.string().optional(),
16659
+ inputSchema: external_exports.unknown().optional(),
16660
+ method: external_exports.literal("POST"),
16661
+ name: external_exports.string(),
16662
+ outputSchema: external_exports.unknown().optional(),
16663
+ path: external_exports.string(),
16664
+ returns: external_exports.string().optional(),
16665
+ scope: actionSchema
16666
+ });
16667
+ var helpJsonSchema = external_exports.object({
16668
+ children: external_exports.array(helpChildSchema).optional(),
16669
+ cmds: external_exports.array(helpCommandSchema),
16670
+ feedback: external_exports.array(helpFeedbackItemSchema).optional(),
16671
+ hint: external_exports.string().optional(),
16672
+ htbp: external_exports.string(),
16673
+ node: external_exports.object({
16674
+ description: external_exports.string(),
16675
+ kind: nodeKindSchema,
16676
+ path: external_exports.string()
16677
+ }),
16678
+ note: external_exports.string().optional()
16679
+ });
16680
+ var treeJsonSchema = external_exports.lazy(() => external_exports.object({
16681
+ children: external_exports.array(treeJsonSchema).optional(),
16682
+ description: external_exports.string(),
16683
+ kind: nodeKindSchema,
16684
+ path: external_exports.string(),
16685
+ presence: presenceSchema.optional(),
16686
+ truncated: external_exports.boolean().optional()
16687
+ }));
16688
+ var toolSpecSchema = external_exports.object({
16689
+ confirm: external_exports.boolean().optional(),
16690
+ description: external_exports.string().optional(),
16691
+ effect: external_exports.string().optional(),
16692
+ inputSchema: external_exports.unknown().optional(),
16693
+ name: external_exports.string(),
16694
+ outputSchema: external_exports.unknown().optional()
16695
+ });
16696
+ var toolSearchItemSchema = external_exports.object({
16697
+ path: external_exports.string(),
16698
+ tool: toolSpecSchema
16699
+ });
16700
+ function pageSchema(itemSchema) {
16701
+ return external_exports.object({
16702
+ cursor: external_exports.string().optional(),
16703
+ items: external_exports.array(itemSchema)
16704
+ });
16644
16705
  }
16706
+ var toolSearchPageSchema = pageSchema(toolSearchItemSchema);
16707
+ var toolSearchRequestSchema = external_exports.strictObject({
16708
+ opts: external_exports.strictObject({
16709
+ cursor: external_exports.string().optional(),
16710
+ limit: external_exports.number().int().optional(),
16711
+ mode: external_exports.enum(["keyword", "semantic"]).optional()
16712
+ }).optional(),
16713
+ query: external_exports.string().trim().min(1)
16714
+ });
16715
+ var registryNodeSchema = external_exports.object({
16716
+ config: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
16717
+ createdAt: external_exports.string().optional(),
16718
+ description: external_exports.string(),
16719
+ kind: nodeKindSchema,
16720
+ lastSeenAt: external_exports.string().optional(),
16721
+ online: external_exports.boolean().optional(),
16722
+ path: external_exports.string(),
16723
+ registeredBy: external_exports.string().optional(),
16724
+ updatedAt: external_exports.string().optional(),
16725
+ virtualize: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
16726
+ });
16727
+ var feedbackViewShape = {
16728
+ at: external_exports.string(),
16729
+ by: external_exports.string(),
16730
+ down: external_exports.number().int().nonnegative(),
16731
+ id: external_exports.string(),
16732
+ score: external_exports.number().int(),
16733
+ title: external_exports.string(),
16734
+ up: external_exports.number().int().nonnegative()
16735
+ };
16736
+ var feedbackViewSchema = external_exports.object(feedbackViewShape);
16737
+ var feedbackDetailSchema = external_exports.object({
16738
+ ...feedbackViewShape,
16739
+ detail: external_exports.string(),
16740
+ path: external_exports.string()
16741
+ });
16742
+ var feedbackListSchema = external_exports.object({ items: external_exports.array(feedbackViewSchema) });
16743
+ var feedbackSubmitRequestSchema = external_exports.strictObject({
16744
+ detail: external_exports.string(),
16745
+ title: external_exports.string()
16746
+ });
16747
+ var feedbackSubmitResponseSchema = external_exports.object({
16748
+ at: external_exports.string().optional(),
16749
+ id: external_exports.string(),
16750
+ path: external_exports.string(),
16751
+ title: external_exports.string()
16752
+ });
16753
+ var feedbackVoteRequestSchema = external_exports.strictObject({
16754
+ vote: external_exports.enum(["up", "down", "clear"])
16755
+ });
16756
+ var feedbackRemoveResponseSchema = external_exports.object({ ok: external_exports.literal(true) });
16757
+ var oauthAuthorizeRequestSchema = external_exports.strictObject({
16758
+ redirectUri: external_exports.string().optional()
16759
+ });
16760
+ var oauthAuthorizeResponseSchema = external_exports.discriminatedUnion("status", [
16761
+ external_exports.object({ status: external_exports.literal("authorized") }),
16762
+ external_exports.object({ authorizationUrl: external_exports.url(), status: external_exports.literal("redirect") })
16763
+ ]);
16764
+ var healthResponseSchema = external_exports.object({
16765
+ catalog: external_exports.object({
16766
+ count: external_exports.number().int().nonnegative(),
16767
+ digest: external_exports.string()
16768
+ }).optional(),
16769
+ healthy: external_exports.boolean(),
16770
+ version: external_exports.string()
16771
+ });
16772
+ var livenessResponseSchema = external_exports.object({ live: external_exports.boolean() });
16773
+ var readinessResponseSchema = external_exports.object({
16774
+ checks: external_exports.record(external_exports.string(), external_exports.object({
16775
+ detail: external_exports.string().optional(),
16776
+ ok: external_exports.boolean()
16777
+ })),
16778
+ ready: external_exports.boolean()
16779
+ });
16780
+
16781
+ // ../core/src/builtin/registry.ts
16782
+ var DESCRIPTION6 = "Node registry: the single mount surface \u2014 everything on the tree (mcp/http/context/device/remote nodes) is mounted, listed and unmounted here";
16783
+ var nodePatchSchema = nodeInputSchema.partial().describe(
16784
+ "fields to change; same shape as write, all optional"
16785
+ );
16645
16786
  function parseNodeInput(args) {
16646
- const path = requireString(args, "path");
16647
- const kind = requireString(args, "kind");
16648
- if (!NODE_KINDS.includes(kind)) {
16649
- throw new TBError("invalid_argument", `invalid kind '${kind}'`);
16787
+ const parsed = nodeInputSchema.safeParse(args);
16788
+ if (!parsed.success) {
16789
+ const issue2 = parsed.error.issues[0];
16790
+ throw new TBError(
16791
+ "invalid_argument",
16792
+ `invalid NodeInput${issue2?.path.length ? ` at '${issue2.path.join(".")}'` : ""}: ${issue2?.message ?? "unknown validation error"}`
16793
+ );
16650
16794
  }
16651
- const description = requireString(args, "description");
16652
- const node = { path, kind, description };
16653
- if (args.config !== void 0) node.config = args.config;
16654
- if (args.virtualize !== void 0) node.virtualize = args.virtualize;
16655
- return node;
16795
+ return parsed.data;
16656
16796
  }
16657
- function createRegistryModule(store, now, visibility) {
16658
- return {
16659
- module: "registry",
16660
- description: DESCRIPTION6,
16661
- help(nodePath) {
16662
- return {
16663
- node: { path: nodePath, kind: "builtin", description: DESCRIPTION6 },
16664
- cmds: registryCmds(nodePath)
16665
- };
16666
- },
16667
- async dispatch(cmd, args, ctx) {
16668
- switch (cmd) {
16669
- case "list": {
16670
- const page = await store.list(
16671
- optString(args, "prefix"),
16672
- optListOptions(args)
16673
- );
16674
- if (!visibility) return page;
16675
- const items = page.items.filter((n) => visibility(ctx.scopes, n.path, "read"));
16676
- return page.cursor !== void 0 ? { items, cursor: page.cursor } : { items };
16677
- }
16678
- case "get": {
16679
- const path = requireString(args, "path");
16680
- if (visibility && !visibility(ctx.scopes, path, "read")) {
16681
- throw new TBError("not_found", `\u8282\u70B9\u4E0D\u5B58\u5728:'${path}'`);
16682
- }
16683
- return store.get(path);
16684
- }
16685
- case "write":
16686
- return await store.write(parseNodeInput(args), ctx.keyId, now());
16687
- case "update":
16688
- return await store.update(
16689
- requireString(args, "path"),
16690
- requireObject(args, "patch"),
16691
- now()
16692
- );
16693
- case "delete":
16694
- await store.delete(requireString(args, "path"));
16695
- return VOID_ACK;
16696
- default:
16697
- throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/registry`);
16698
- }
16797
+ var COMMANDS6 = new BuiltinCommandRegistry("registry", DESCRIPTION6).register(
16798
+ "list",
16799
+ {
16800
+ h: "list registered nodes, optionally under a path prefix",
16801
+ inputSchema: external_exports.strictObject({
16802
+ prefix: external_exports.string().optional().describe("only nodes under this path prefix"),
16803
+ opts: HTBP_LIST_OPTIONS_SCHEMA.optional()
16804
+ }),
16805
+ returns: "Page<Node>",
16806
+ scope: "read"
16807
+ },
16808
+ async ({ opts, prefix }, { call, deps }) => {
16809
+ const page = await deps.store.list(prefix, opts);
16810
+ if (!deps.visibility) return page;
16811
+ const items = page.items.filter((n) => deps.visibility?.(call.scopes, n.path, "read") === true);
16812
+ return page.cursor !== void 0 ? { items, cursor: page.cursor } : { items };
16813
+ }
16814
+ ).register(
16815
+ "get",
16816
+ {
16817
+ h: "fetch one node registration (kind, description, config) by path",
16818
+ inputSchema: external_exports.strictObject({
16819
+ path: external_exports.string().min(1).describe("exact tree path")
16820
+ }),
16821
+ returns: "Node",
16822
+ scope: "read"
16823
+ },
16824
+ ({ path }, { call, deps }) => {
16825
+ if (deps.visibility && !deps.visibility(call.scopes, path, "read")) {
16826
+ throw new TBError("not_found", `\u8282\u70B9\u4E0D\u5B58\u5728:'${path}'`);
16699
16827
  }
16700
- };
16828
+ return deps.store.get(path);
16829
+ }
16830
+ ).register(
16831
+ "write",
16832
+ {
16833
+ h: "mount (or replace) a node at a path; idempotent upsert, intermediate directories auto-created",
16834
+ inputSchema: nodeInputSchema,
16835
+ returns: "Node",
16836
+ scope: "register"
16837
+ },
16838
+ (input, { call, deps }) => deps.store.write(input, call.keyId, deps.now())
16839
+ ).register(
16840
+ "update",
16841
+ {
16842
+ h: "patch fields of a mounted node (description, config, virtualize, \u2026) without remounting",
16843
+ inputSchema: external_exports.strictObject({
16844
+ path: external_exports.string().min(1).describe("exact tree path"),
16845
+ patch: nodePatchSchema
16846
+ }),
16847
+ returns: "Node",
16848
+ scope: "register"
16849
+ },
16850
+ ({ patch, path }, { deps }) => deps.store.update(path, patch, deps.now())
16851
+ ).register(
16852
+ "delete",
16853
+ {
16854
+ h: "unmount a node (and reclaim empty auto-created parents); a node registered by another key can only be removed by its registrar or by a key holding the 'admin' scope on that path",
16855
+ inputSchema: external_exports.strictObject({
16856
+ path: external_exports.string().min(1).describe("exact tree path")
16857
+ }),
16858
+ returns: "void",
16859
+ scope: "register"
16860
+ },
16861
+ async ({ path }, { deps }) => {
16862
+ await deps.store.delete(path);
16863
+ return VOID_ACK;
16864
+ }
16865
+ );
16866
+ function createRegistryModule(store, now, visibility) {
16867
+ return COMMANDS6.module({ store, now, ...visibility !== void 0 ? { visibility } : {} });
16701
16868
  }
16702
16869
 
16703
16870
  // ../core/src/builtin/secret.ts
@@ -16710,291 +16877,189 @@ function assertUserSecretName(name) {
16710
16877
  );
16711
16878
  }
16712
16879
  }
16713
- function secretCmds(nodePath) {
16714
- const path = cmdPath(nodePath);
16715
- const cmds = [
16716
- {
16717
- name: "set",
16718
- method: "POST",
16719
- path,
16720
- h: "store or rotate a credential under a name; mount configs reference it as authRef",
16721
- inputSchema: {
16722
- type: "object",
16723
- properties: {
16724
- name: {
16725
- type: "string",
16726
- description: 'reference name used as authRef in mount configs (":" is reserved)'
16727
- },
16728
- value: {
16729
- type: "string",
16730
- description: "the credential (token / key / JSON); encrypted at rest, never echoed"
16731
- }
16732
- },
16733
- required: ["name", "value"]
16734
- },
16735
- returns: "void \u2014 value never echoed",
16736
- scope: "admin"
16737
- },
16738
- {
16739
- name: "list",
16740
- method: "POST",
16741
- path,
16742
- h: "list stored credential names (names and timestamps only, never values)",
16743
- inputSchema: { type: "object", properties: { opts: LIST_OPTS_SCHEMA } },
16744
- returns: "Page<{ name, updatedAt }>",
16745
- scope: "admin"
16746
- },
16747
- {
16748
- name: "delete",
16749
- method: "POST",
16750
- path,
16751
- h: "delete a credential; mounts still referencing it will fail to resolve",
16752
- inputSchema: {
16753
- type: "object",
16754
- properties: { name: { type: "string", description: "reference name" } },
16755
- required: ["name"]
16756
- },
16757
- returns: "void",
16758
- scope: "admin"
16759
- }
16760
- ];
16761
- return withCommandPaths(nodePath, cmds);
16762
- }
16880
+ var COMMANDS7 = new BuiltinCommandRegistry("secret", DESCRIPTION7).register(
16881
+ "set",
16882
+ {
16883
+ h: "store or rotate a credential under a name; mount configs reference it as authRef",
16884
+ inputSchema: external_exports.strictObject({
16885
+ name: external_exports.string().min(1).describe(
16886
+ 'reference name used as authRef in mount configs (":" is reserved)'
16887
+ ),
16888
+ value: external_exports.string().min(1).describe(
16889
+ "the credential (token / key / JSON); encrypted at rest, never echoed"
16890
+ )
16891
+ }),
16892
+ returns: "void \u2014 value never echoed",
16893
+ scope: "admin"
16894
+ },
16895
+ async ({ name, value }, { deps }) => {
16896
+ assertUserSecretName(name);
16897
+ await deps.store.set(name, value, deps.now());
16898
+ return VOID_ACK;
16899
+ }
16900
+ ).register(
16901
+ "list",
16902
+ {
16903
+ h: "list stored credential names (names and timestamps only, never values)",
16904
+ inputSchema: external_exports.strictObject({ opts: HTBP_LIST_OPTIONS_SCHEMA.optional() }),
16905
+ returns: "Page<{ name, updatedAt }>",
16906
+ scope: "admin"
16907
+ },
16908
+ ({ opts }, { deps }) => deps.store.list(opts)
16909
+ ).register(
16910
+ "delete",
16911
+ {
16912
+ h: "delete a credential; mounts still referencing it will fail to resolve",
16913
+ inputSchema: external_exports.strictObject({
16914
+ name: external_exports.string().min(1).describe("reference name")
16915
+ }),
16916
+ returns: "void",
16917
+ scope: "admin"
16918
+ },
16919
+ async ({ name }, { deps }) => {
16920
+ assertUserSecretName(name);
16921
+ await deps.store.delete(name);
16922
+ return VOID_ACK;
16923
+ }
16924
+ );
16763
16925
  function createSecretModule(store, now) {
16764
- return {
16765
- module: "secret",
16766
- description: DESCRIPTION7,
16767
- help(nodePath) {
16768
- return {
16769
- node: { path: nodePath, kind: "builtin", description: DESCRIPTION7 },
16770
- cmds: secretCmds(nodePath)
16771
- };
16772
- },
16773
- async dispatch(cmd, args) {
16774
- switch (cmd) {
16775
- case "set": {
16776
- const name = requireString(args, "name");
16777
- assertUserSecretName(name);
16778
- await store.set(name, requireString(args, "value"), now());
16779
- return VOID_ACK;
16780
- }
16781
- case "list":
16782
- return store.list(optListOptions(args));
16783
- case "delete": {
16784
- const name = requireString(args, "name");
16785
- assertUserSecretName(name);
16786
- await store.delete(name);
16787
- return VOID_ACK;
16788
- }
16789
- default:
16790
- throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/secret`);
16791
- }
16792
- }
16793
- };
16926
+ return COMMANDS7.module({ store, now });
16794
16927
  }
16795
16928
 
16796
16929
  // ../core/src/builtin/status.ts
16797
16930
  var DESCRIPTION8 = "Gateway health and summary (readable without admin)";
16798
- function statusCmds(nodePath) {
16799
- return withCommandPaths(nodePath, [
16800
- {
16801
- name: "get",
16802
- method: "POST",
16803
- path: cmdPath(nodePath),
16804
- h: "health summary: gateway version and node count; no arguments",
16805
- inputSchema: { type: "object", properties: {} },
16806
- returns: "{ healthy, version, nodeCount }",
16807
- scope: "read"
16808
- }
16809
- ]);
16810
- }
16931
+ var COMMANDS8 = new BuiltinCommandRegistry("status", DESCRIPTION8).register(
16932
+ "get",
16933
+ {
16934
+ h: "health summary: gateway version and node count; no arguments",
16935
+ inputSchema: external_exports.strictObject({}),
16936
+ returns: "{ healthy, version, nodeCount }",
16937
+ scope: "read"
16938
+ },
16939
+ async (_input, { deps }) => {
16940
+ const summary = {
16941
+ healthy: true,
16942
+ version: deps.version(),
16943
+ nodeCount: await deps.nodeCount()
16944
+ };
16945
+ return summary;
16946
+ }
16947
+ );
16811
16948
  function createStatusModule(deps) {
16812
- return {
16813
- module: "status",
16814
- description: DESCRIPTION8,
16815
- help(nodePath) {
16816
- return {
16817
- node: { path: nodePath, kind: "builtin", description: DESCRIPTION8 },
16818
- cmds: statusCmds(nodePath)
16819
- };
16820
- },
16821
- async dispatch(cmd) {
16822
- if (cmd !== "get") {
16823
- throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/status`);
16824
- }
16825
- const summary = {
16826
- healthy: true,
16827
- version: deps.version(),
16828
- nodeCount: await deps.nodeCount()
16829
- };
16830
- return summary;
16831
- }
16832
- };
16949
+ return COMMANDS8.module(deps);
16833
16950
  }
16834
16951
 
16835
16952
  // ../core/src/builtin/sk.ts
16836
16953
  var DESCRIPTION9 = "Secret Key registry: issue / list / update / revoke access keys (the only credential form; admin only)";
16837
- var SK_FIELD_SCHEMAS = {
16838
- owner: {
16839
- type: "string",
16840
- description: 'owner ref: "user:<name>" | "agent:<name>" | "device:<id>"'
16954
+ var actionSchema2 = external_exports.enum(["read", "write", "call", "register", "admin"]);
16955
+ var scopeSchema = external_exports.strictObject({
16956
+ pattern: external_exports.string().describe('tree path glob, e.g. "**" (everything) or "docs/**"'),
16957
+ actions: external_exports.array(actionSchema2),
16958
+ effect: external_exports.enum(["allow", "deny"]).optional().describe('default "allow"')
16959
+ });
16960
+ var ownerSchema = external_exports.string().min(1).describe(
16961
+ 'owner ref: "user:<name>" | "agent:<name>" | "device:<id>"'
16962
+ );
16963
+ var descriptionSchema = external_exports.string().optional().describe("what this key is for (shown in list)");
16964
+ var scopesSchema = external_exports.array(scopeSchema).describe(
16965
+ "permission grants; deny wins over allow, no match = denied"
16966
+ );
16967
+ var registerPathsSchema = external_exports.array(external_exports.string()).optional().describe(
16968
+ "path prefixes this key may self-register nodes under (via ~register)"
16969
+ );
16970
+ var expiresAtSchema = external_exports.string().optional().describe(
16971
+ "expiry, ISO 8601 timestamp with timezone; omit = never"
16972
+ );
16973
+ var writeSchema = external_exports.strictObject({
16974
+ owner: ownerSchema,
16975
+ description: descriptionSchema,
16976
+ scopes: scopesSchema,
16977
+ registerPaths: registerPathsSchema,
16978
+ expiresAt: expiresAtSchema
16979
+ });
16980
+ var patchSchema2 = external_exports.strictObject({
16981
+ owner: ownerSchema.optional(),
16982
+ description: descriptionSchema,
16983
+ scopes: scopesSchema.optional(),
16984
+ registerPaths: registerPathsSchema,
16985
+ expiresAt: expiresAtSchema,
16986
+ disabled: external_exports.boolean().optional().describe("true = key rejected until re-enabled")
16987
+ }).describe("fields to change; same shape as write (all optional) plus disabled");
16988
+ function toSecretKeyInput(input) {
16989
+ return {
16990
+ owner: input.owner,
16991
+ scopes: input.scopes,
16992
+ ...input.description !== void 0 ? { description: input.description } : {},
16993
+ ...input.registerPaths !== void 0 ? { registerPaths: input.registerPaths } : {},
16994
+ ...input.expiresAt !== void 0 ? { expiresAt: normalizeExpiresAt(input.expiresAt) } : {}
16995
+ };
16996
+ }
16997
+ function toUpdatePatch(input) {
16998
+ return {
16999
+ ...input.owner !== void 0 ? { owner: input.owner } : {},
17000
+ ...input.description !== void 0 ? { description: input.description } : {},
17001
+ ...input.scopes !== void 0 ? { scopes: input.scopes } : {},
17002
+ ...input.registerPaths !== void 0 ? { registerPaths: input.registerPaths } : {},
17003
+ ...input.expiresAt !== void 0 ? { expiresAt: normalizeExpiresAt(input.expiresAt) } : {},
17004
+ ...input.disabled !== void 0 ? { disabled: input.disabled } : {}
17005
+ };
17006
+ }
17007
+ var COMMANDS9 = new BuiltinCommandRegistry("sk", DESCRIPTION9).register(
17008
+ "list",
17009
+ {
17010
+ h: "list issued keys (id, owner, scopes; the secret itself is never returned)",
17011
+ inputSchema: external_exports.strictObject({ opts: HTBP_LIST_OPTIONS_SCHEMA.optional() }),
17012
+ returns: "Page<SecretKey without hash>",
17013
+ scope: "admin"
16841
17014
  },
16842
- description: { type: "string", description: "what this key is for (shown in list)" },
16843
- scopes: {
16844
- type: "array",
16845
- description: "permission grants; deny wins over allow, no match = denied",
16846
- items: {
16847
- type: "object",
16848
- properties: {
16849
- pattern: {
16850
- type: "string",
16851
- description: 'tree path glob, e.g. "**" (everything) or "docs/**"'
16852
- },
16853
- actions: {
16854
- type: "array",
16855
- items: { type: "string", enum: ["read", "write", "call", "register", "admin"] }
16856
- },
16857
- effect: { type: "string", enum: ["allow", "deny"], description: 'default "allow"' }
16858
- },
16859
- required: ["pattern", "actions"]
16860
- }
17015
+ ({ opts }, { deps }) => deps.store.list(opts)
17016
+ ).register(
17017
+ "get",
17018
+ {
17019
+ h: "fetch one key by id",
17020
+ inputSchema: external_exports.strictObject({
17021
+ id: external_exports.string().min(1).describe("key id (from list or the issue response)")
17022
+ }),
17023
+ returns: "SecretKey without hash",
17024
+ scope: "admin"
16861
17025
  },
16862
- registerPaths: {
16863
- type: "array",
16864
- items: { type: "string" },
16865
- description: "path prefixes this key may self-register nodes under (via ~register)"
17026
+ ({ id }, { deps }) => deps.store.get(id)
17027
+ ).register(
17028
+ "write",
17029
+ {
17030
+ h: "issue a new key \u2014 the response carries the plaintext secret exactly once, store it immediately",
17031
+ inputSchema: writeSchema,
17032
+ returns: "{ key: SecretKey without hash, secret } \u2014 secret shown once",
17033
+ scope: "admin"
16866
17034
  },
16867
- expiresAt: {
16868
- type: "string",
16869
- description: "expiry, ISO 8601 timestamp with timezone; omit = never"
16870
- }
16871
- };
16872
- function skCmds(nodePath) {
16873
- const path = cmdPath(nodePath);
16874
- const cmds = [
16875
- {
16876
- name: "list",
16877
- method: "POST",
16878
- path,
16879
- h: "list issued keys (id, owner, scopes; the secret itself is never returned)",
16880
- inputSchema: { type: "object", properties: { opts: LIST_OPTS_SCHEMA } },
16881
- returns: "Page<SecretKey without hash>",
16882
- scope: "admin"
16883
- },
16884
- {
16885
- name: "get",
16886
- method: "POST",
16887
- path,
16888
- h: "fetch one key by id",
16889
- inputSchema: {
16890
- type: "object",
16891
- properties: {
16892
- id: { type: "string", description: "key id (from list or the issue response)" }
16893
- },
16894
- required: ["id"]
16895
- },
16896
- returns: "SecretKey without hash",
16897
- scope: "admin"
16898
- },
16899
- {
16900
- name: "write",
16901
- method: "POST",
16902
- path,
16903
- h: "issue a new key \u2014 the response carries the plaintext secret exactly once, store it immediately",
16904
- inputSchema: {
16905
- type: "object",
16906
- properties: SK_FIELD_SCHEMAS,
16907
- required: ["owner", "scopes"]
16908
- },
16909
- returns: "{ key: SecretKey without hash, secret } \u2014 secret shown once",
16910
- scope: "admin"
16911
- },
16912
- {
16913
- name: "update",
16914
- method: "POST",
16915
- path,
16916
- h: "patch fields of an issued key (scopes, expiresAt, disabled, \u2026); takes effect immediately",
16917
- inputSchema: {
16918
- type: "object",
16919
- properties: {
16920
- id: { type: "string", description: "key id" },
16921
- patch: {
16922
- type: "object",
16923
- description: "fields to change; same shape as write (all optional) plus disabled",
16924
- properties: {
16925
- ...SK_FIELD_SCHEMAS,
16926
- disabled: { type: "boolean", description: "true = key rejected until re-enabled" }
16927
- }
16928
- }
16929
- },
16930
- required: ["id", "patch"]
16931
- },
16932
- returns: "SecretKey without hash",
16933
- scope: "admin"
16934
- },
16935
- {
16936
- name: "delete",
16937
- method: "POST",
16938
- path,
16939
- h: "revoke a key permanently; takes effect immediately",
16940
- inputSchema: {
16941
- type: "object",
16942
- properties: { id: { type: "string", description: "key id" } },
16943
- required: ["id"]
16944
- },
16945
- returns: "void",
16946
- scope: "admin"
16947
- }
16948
- ];
16949
- return withCommandPaths(nodePath, cmds);
16950
- }
16951
- function asSecretKeyInput(args) {
16952
- const owner = requireString(args, "owner");
16953
- if (!Array.isArray(args.scopes)) {
16954
- throw new TBError("invalid_argument", "field 'scopes' must be an array");
17035
+ (input, { deps }) => deps.store.write(toSecretKeyInput(input), deps.now())
17036
+ ).register(
17037
+ "update",
17038
+ {
17039
+ h: "patch fields of an issued key (scopes, expiresAt, disabled, \u2026); takes effect immediately",
17040
+ inputSchema: external_exports.strictObject({
17041
+ id: external_exports.string().min(1).describe("key id"),
17042
+ patch: patchSchema2
17043
+ }),
17044
+ returns: "SecretKey without hash",
17045
+ scope: "admin"
17046
+ },
17047
+ ({ id, patch }, { deps }) => deps.store.update(id, toUpdatePatch(patch))
17048
+ ).register(
17049
+ "delete",
17050
+ {
17051
+ h: "revoke a key permanently; takes effect immediately",
17052
+ inputSchema: external_exports.strictObject({ id: external_exports.string().min(1).describe("key id") }),
17053
+ returns: "void",
17054
+ scope: "admin"
17055
+ },
17056
+ async ({ id }, { deps }) => {
17057
+ await deps.store.delete(id);
17058
+ return VOID_ACK;
16955
17059
  }
16956
- const input = { owner, scopes: args.scopes };
16957
- if (typeof args.description === "string") input.description = args.description;
16958
- if (Array.isArray(args.registerPaths)) input.registerPaths = args.registerPaths;
16959
- if ("expiresAt" in args) input.expiresAt = normalizeExpiresAt(args.expiresAt);
16960
- return input;
16961
- }
16962
- function asSkUpdatePatch(args) {
16963
- const patch = { ...args };
16964
- if ("expiresAt" in args) patch.expiresAt = normalizeExpiresAt(args.expiresAt);
16965
- return patch;
16966
- }
17060
+ );
16967
17061
  function createSkModule(store, now) {
16968
- return {
16969
- module: "sk",
16970
- description: DESCRIPTION9,
16971
- help(nodePath) {
16972
- return {
16973
- node: { path: nodePath, kind: "builtin", description: DESCRIPTION9 },
16974
- cmds: skCmds(nodePath)
16975
- };
16976
- },
16977
- async dispatch(cmd, args) {
16978
- switch (cmd) {
16979
- case "list":
16980
- return store.list(optListOptions(args));
16981
- case "get":
16982
- return store.get(requireString(args, "id"));
16983
- case "write":
16984
- return store.write(asSecretKeyInput(args), now());
16985
- case "update":
16986
- return store.update(
16987
- requireString(args, "id"),
16988
- asSkUpdatePatch(requireObject(args, "patch"))
16989
- );
16990
- case "delete":
16991
- await store.delete(requireString(args, "id"));
16992
- return VOID_ACK;
16993
- default:
16994
- throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/sk`);
16995
- }
16996
- }
16997
- };
17062
+ return COMMANDS9.module({ store, now });
16998
17063
  }
16999
17064
 
17000
17065
  // ../core/src/builtin/index.ts
@@ -17051,191 +17116,18 @@ function createBuiltins(deps) {
17051
17116
  // ../core/src/context/help.ts
17052
17117
  var CONTEXT_CAPABILITIES = ["search", "delete"];
17053
17118
  var CONTEXT_DIRECT_UPLOAD_CAPABILITY = "direct-upload";
17054
- var SCOPE_BY_CMD = {
17055
- list: "read",
17056
- get: "read",
17057
- search: "read",
17058
- write: "write",
17059
- update: "write",
17060
- delete: "write",
17061
- create_upload: "write"
17062
- };
17063
- function contextScopeForCmd(command) {
17064
- return SCOPE_BY_CMD[command] ?? null;
17065
- }
17066
- var OPTS_SCHEMA = {
17067
- type: "object",
17068
- description: "pagination options",
17069
- properties: {
17070
- cursor: { type: "string", description: "opaque cursor returned by the previous page" },
17071
- limit: { type: "number", description: "page size (default 50, max 200)" }
17072
- }
17073
- };
17074
- var SEARCH_OPTS_SCHEMA = {
17075
- type: "object",
17076
- description: "pagination + search mode",
17077
- properties: {
17078
- cursor: { type: "string", description: "opaque cursor returned by the previous page" },
17079
- limit: { type: "number", description: "page size (default 50, max 200)" },
17080
- mode: { type: "string", enum: ["keyword", "semantic"], description: 'default "keyword"' }
17081
- }
17082
- };
17083
- var METADATA_SCHEMA = {
17084
- type: "object",
17085
- description: "string-to-string metadata map",
17086
- additionalProperties: { type: "string" }
17087
- };
17088
- var ENTRY_SCHEMA = {
17089
- type: "object",
17090
- required: ["content"],
17091
- properties: {
17092
- contentType: {
17093
- type: "string",
17094
- description: "required when content is a string; defaults to application/json for non-string content"
17095
- },
17096
- content: { description: "entry body: string, or any JSON value" },
17097
- metadata: METADATA_SCHEMA,
17098
- ifVersion: { type: "string", description: "optimistic concurrency: expected current version" }
17099
- }
17100
- };
17101
- var PATCH_SCHEMA = {
17102
- type: "object",
17103
- description: "partial update; omitted fields keep their current value",
17104
- properties: {
17105
- content: { description: "replacement content" },
17106
- metadata: METADATA_SCHEMA,
17107
- ifVersion: { type: "string", description: "optimistic concurrency: expected current version" }
17108
- }
17109
- };
17110
- function contextCmds(nodePath) {
17111
- const path = cmdPath(nodePath);
17112
- const cmds = [
17113
- {
17114
- name: "list",
17115
- method: "POST",
17116
- path,
17117
- h: "list entries directly under a path (shallow, paginated)",
17118
- inputSchema: {
17119
- type: "object",
17120
- properties: {
17121
- path: { type: "string", description: "entry path prefix inside the namespace" },
17122
- opts: OPTS_SCHEMA
17123
- }
17124
- },
17125
- returns: "Page<ContextEntryMeta>",
17126
- scope: "read"
17127
- },
17128
- {
17129
- name: "get",
17130
- method: "POST",
17131
- path,
17132
- h: "read one entry with content (oversized content comes back as { $ref: <download URL> })",
17133
- inputSchema: {
17134
- type: "object",
17135
- required: ["path"],
17136
- properties: {
17137
- path: { type: "string", description: "entry path inside the namespace" }
17138
- }
17139
- },
17140
- returns: "ContextEntry",
17141
- scope: "read"
17142
- },
17143
- {
17144
- name: "write",
17145
- method: "POST",
17146
- path,
17147
- h: "create or fully replace an entry (idempotent upsert)",
17148
- inputSchema: {
17149
- type: "object",
17150
- required: ["path", "entry"],
17151
- properties: {
17152
- path: { type: "string", description: "entry path inside the namespace" },
17153
- entry: ENTRY_SCHEMA
17154
- }
17155
- },
17156
- returns: "ContextEntryMeta",
17157
- scope: "write"
17158
- },
17159
- {
17160
- name: "update",
17161
- method: "POST",
17162
- path,
17163
- h: "partially update content and/or metadata (shallow merge); not_found if the entry does not exist",
17164
- inputSchema: {
17165
- type: "object",
17166
- required: ["path", "patch"],
17167
- properties: {
17168
- path: { type: "string", description: "entry path inside the namespace" },
17169
- patch: PATCH_SCHEMA
17170
- }
17171
- },
17172
- returns: "ContextEntryMeta",
17173
- scope: "write"
17174
- },
17175
- {
17176
- name: "delete",
17177
- method: "POST",
17178
- path,
17179
- h: "delete an entry (idempotent)",
17180
- inputSchema: {
17181
- type: "object",
17182
- required: ["path"],
17183
- properties: {
17184
- path: { type: "string", description: "entry path inside the namespace" }
17185
- }
17186
- },
17187
- scope: "write",
17188
- effect: "destructive"
17189
- },
17190
- {
17191
- name: "search",
17192
- method: "POST",
17193
- path,
17194
- h: "keyword search: substring match on entry paths and metadata values",
17195
- inputSchema: {
17196
- type: "object",
17197
- required: ["query"],
17198
- properties: {
17199
- query: { type: "string", description: "substring to match" },
17200
- opts: SEARCH_OPTS_SCHEMA
17201
- }
17202
- },
17203
- returns: "Page<ContextEntryMeta>",
17204
- scope: "read"
17205
- }
17206
- ];
17207
- return withCommandPaths(nodePath, cmds);
17208
- }
17209
17119
  function contextUploadCmd(nodePath) {
17210
- return withCommandPaths(nodePath, [{
17211
- name: "create_upload",
17212
- method: "POST",
17213
- path: cmdPath(nodePath),
17214
- h: "create a short-lived, path-scoped direct-upload grant; persist the returned uri, not url",
17215
- inputSchema: {
17216
- type: "object",
17217
- required: ["path", "contentType"],
17218
- properties: {
17219
- path: { type: "string", description: "target entry path inside the namespace" },
17220
- contentType: { type: "string", description: "media type signed into the PUT request" },
17221
- overwrite: {
17222
- type: "boolean",
17223
- description: "allow replacing an existing object; default false"
17224
- }
17225
- }
17226
- },
17227
- returns: "ContextUploadGrant",
17228
- scope: "write",
17229
- effect: "write"
17230
- }])[0];
17120
+ return contextCommands.command("create_upload", nodePath);
17231
17121
  }
17232
17122
  function contextHelpModel(node, opts = {}) {
17233
- const all = contextCmds(node.path);
17234
- const present = opts.methods === void 0 ? all : all.filter((c) => opts.methods?.has(c.name));
17235
- return {
17236
- node: { path: node.path, kind: "context", description: node.description },
17237
- cmds: opts.readOnly ? present.filter((c) => c.scope === "read") : present
17238
- };
17123
+ return contextCommands.helpModel(
17124
+ { path: node.path, kind: "context", description: node.description },
17125
+ (command) => {
17126
+ if (command.name === "create_upload") return false;
17127
+ if (opts.methods !== void 0 && !opts.methods.has(command.name)) return false;
17128
+ return opts.readOnly !== true || command.scope === "read";
17129
+ }
17130
+ );
17239
17131
  }
17240
17132
 
17241
17133
  // ../core/src/context/objectStore.ts
@@ -17644,11 +17536,6 @@ function isContextExpired(createdAt, ttlSec, now) {
17644
17536
  }
17645
17537
 
17646
17538
  // ../core/src/device/frames.ts
17647
- var tbErrorBodySchema = external_exports.object({
17648
- code: external_exports.enum(TB_ERROR_CODES),
17649
- message: external_exports.string(),
17650
- retryable: external_exports.boolean()
17651
- });
17652
17539
  var deviceNodeCmdSchema = external_exports.object({
17653
17540
  name: external_exports.string().min(1),
17654
17541
  description: external_exports.string().optional(),
@@ -17657,7 +17544,7 @@ var deviceNodeCmdSchema = external_exports.object({
17657
17544
  effect: external_exports.string().optional(),
17658
17545
  confirm: external_exports.boolean().optional()
17659
17546
  }).passthrough();
17660
- var nodeInputSchema = external_exports.object({
17547
+ var nodeInputSchema2 = external_exports.object({
17661
17548
  path: external_exports.string().min(1),
17662
17549
  kind: external_exports.enum(NODE_KINDS),
17663
17550
  description: external_exports.string(),
@@ -17672,7 +17559,7 @@ var deviceExposeSchema = external_exports.object({
17672
17559
  roots: external_exports.array(external_exports.string().min(1)).min(1),
17673
17560
  readOnly: external_exports.boolean().optional()
17674
17561
  }).optional(),
17675
- nodes: external_exports.array(nodeInputSchema).optional()
17562
+ nodes: external_exports.array(nodeInputSchema2).optional()
17676
17563
  });
17677
17564
  var idSchema = external_exports.string().min(1);
17678
17565
  var deviceCallContextSchema = external_exports.object({
@@ -18076,12 +17963,12 @@ function requireShort(value, field, max) {
18076
17963
  return trimmed;
18077
17964
  }
18078
17965
  var FeedbackStore = class {
17966
+ onMutation;
17967
+ store;
18079
17968
  constructor(store, onMutation) {
18080
- this.store = store;
18081
17969
  this.onMutation = onMutation;
17970
+ this.store = store;
18082
17971
  }
18083
- store;
18084
- onMutation;
18085
17972
  keyOf(path) {
18086
17973
  return KEY_FEEDBACK + path;
18087
17974
  }
@@ -18243,24 +18130,24 @@ function renderHelpJson(model) {
18243
18130
  if (cmd.confirm) out.confirm = cmd.confirm;
18244
18131
  return out;
18245
18132
  });
18246
- const json2 = {
18133
+ const json3 = {
18247
18134
  htbp: HTBP_VERSION,
18248
18135
  node: { path: model.node.path, kind: model.node.kind, description: model.node.description },
18249
18136
  cmds
18250
18137
  };
18251
- if (model.hint !== void 0) json2.hint = model.hint;
18252
- if (model.note !== void 0) json2.note = model.note;
18138
+ if (model.hint !== void 0) json3.hint = model.hint;
18139
+ if (model.note !== void 0) json3.note = model.note;
18253
18140
  if (model.feedback !== void 0 && model.feedback.length > 0) {
18254
- json2.feedback = model.feedback.map((f) => ({ id: f.id, title: f.title, score: f.score }));
18141
+ json3.feedback = model.feedback.map((f) => ({ id: f.id, title: f.title, score: f.score }));
18255
18142
  }
18256
18143
  if (model.children) {
18257
- json2.children = model.children.map((child) => ({
18144
+ json3.children = model.children.map((child) => ({
18258
18145
  path: child.path,
18259
18146
  kind: child.kind,
18260
18147
  description: child.description
18261
18148
  }));
18262
18149
  }
18263
- return json2;
18150
+ return json3;
18264
18151
  }
18265
18152
 
18266
18153
  // ../core/src/htbp/helpMarkdown.ts
@@ -18505,43 +18392,116 @@ var TOKEN_PREFIX = {
18505
18392
  function stateCorrupt(kind) {
18506
18393
  return new TBError("internal", `Store ${kind} \u72B6\u6001\u635F\u574F`, { retryable: false });
18507
18394
  }
18508
- function asRecord2(value, kind) {
18509
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
18510
- throw stateCorrupt(kind);
18511
- }
18512
- return value;
18513
- }
18514
- function assertRevisioned(value, kind) {
18515
- const record2 = asRecord2(value, kind);
18516
- if (!Number.isInteger(record2.revision) || record2.revision < 1) {
18517
- throw stateCorrupt(kind);
18518
- }
18519
- return record2;
18520
- }
18521
- function parseObject(value) {
18522
- const record2 = assertRevisioned(value, "object");
18523
- if (typeof record2.id !== "string" || record2.store !== DEFAULT_STORE_NAME || typeof record2.driverKey !== "string" || typeof record2.owner !== "string" || typeof record2.contentType !== "string" || typeof record2.uploadId !== "string" || typeof record2.status !== "string") throw stateCorrupt("object");
18524
- return value;
18525
- }
18395
+ var persistedId = external_exports.string().min(1);
18396
+ var persistedOwner = external_exports.string().min(1).refine((value) => !/[\r\n\0]/.test(value));
18397
+ var persistedTimestamp = external_exports.string().refine((value) => Number.isFinite(Date.parse(value)));
18398
+ var persistedNonNegativeInt = external_exports.number().int().nonnegative().refine(Number.isSafeInteger);
18399
+ var persistedPositiveInt = persistedNonNegativeInt.refine((value) => value > 0);
18400
+ var persistedHash = external_exports.string().regex(/^[0-9a-f]{64}$/);
18401
+ var persistedChecksum = external_exports.looseObject({
18402
+ algorithm: external_exports.literal("sha256"),
18403
+ value: external_exports.string().min(1)
18404
+ });
18405
+ function stateParser(kind, shape) {
18406
+ const schema = external_exports.looseObject({ revision: persistedPositiveInt, ...shape });
18407
+ return (value) => {
18408
+ const parsed = schema.safeParse(value);
18409
+ if (!parsed.success) throw stateCorrupt(kind);
18410
+ return parsed.data;
18411
+ };
18412
+ }
18413
+ var parseObject = stateParser("object", {
18414
+ bytesDeletedAt: persistedTimestamp.optional(),
18415
+ checksum: persistedChecksum.optional(),
18416
+ contentType: external_exports.string().min(1),
18417
+ createdAt: persistedTimestamp,
18418
+ driverKey: persistedId,
18419
+ etag: external_exports.string().optional(),
18420
+ expectedChecksum: persistedChecksum.optional(),
18421
+ expectedSize: persistedNonNegativeInt.optional(),
18422
+ expiresAt: persistedTimestamp.optional(),
18423
+ filename: external_exports.string().optional(),
18424
+ id: persistedId,
18425
+ originCallId: persistedId.optional(),
18426
+ owner: persistedOwner,
18427
+ producer: persistedOwner.optional(),
18428
+ readyAt: persistedTimestamp.optional(),
18429
+ size: persistedNonNegativeInt.optional(),
18430
+ status: external_exports.enum(["pending", "ready", "failed", "abandoned", "deleted"]),
18431
+ store: external_exports.literal(DEFAULT_STORE_NAME),
18432
+ updatedAt: persistedTimestamp,
18433
+ uploadId: persistedId
18434
+ });
18435
+ var parseSessionRecord = stateParser("upload session", {
18436
+ capabilityHash: persistedHash,
18437
+ completedAt: persistedTimestamp.optional(),
18438
+ contentType: external_exports.string().min(1),
18439
+ createdAt: persistedTimestamp,
18440
+ expectedChecksum: persistedChecksum.optional(),
18441
+ expectedSize: persistedNonNegativeInt.optional(),
18442
+ expiresAt: persistedTimestamp,
18443
+ id: persistedId,
18444
+ maxBytes: persistedPositiveInt,
18445
+ objectId: persistedId,
18446
+ status: external_exports.enum(["created", "completed", "aborted", "expired", "failed"]),
18447
+ terminalAt: persistedTimestamp.optional(),
18448
+ transport: external_exports.enum(["relay", "presigned-put"])
18449
+ });
18450
+ var parseCallCapabilityRecord = stateParser("call capability", {
18451
+ allowedContentTypes: external_exports.array(external_exports.string().min(1)).min(1),
18452
+ callId: persistedId,
18453
+ createdAt: persistedTimestamp,
18454
+ expiresAt: persistedTimestamp,
18455
+ id: persistedId,
18456
+ maxBytes: persistedPositiveInt,
18457
+ maxObjectBytes: persistedPositiveInt,
18458
+ maxObjects: persistedPositiveInt,
18459
+ owner: persistedOwner,
18460
+ producer: persistedOwner,
18461
+ reservations: external_exports.array(external_exports.looseObject({
18462
+ maxBytes: persistedPositiveInt,
18463
+ objectId: persistedId
18464
+ })),
18465
+ reservedBytes: persistedNonNegativeInt,
18466
+ status: external_exports.enum(["active", "exhausted", "revoked", "expired"]),
18467
+ terminalAt: persistedTimestamp.optional(),
18468
+ tokenHash: persistedHash
18469
+ });
18470
+ var parseShare = stateParser("share grant", {
18471
+ createdAt: persistedTimestamp,
18472
+ createdBy: persistedOwner,
18473
+ expiresAt: persistedTimestamp,
18474
+ id: persistedId,
18475
+ objectId: persistedId,
18476
+ status: external_exports.enum(["active", "revoked", "expired"]),
18477
+ terminalAt: persistedTimestamp.optional(),
18478
+ tokenHash: persistedHash
18479
+ });
18480
+ var parseIdempotencyBinding = stateParser("idempotency binding", {
18481
+ createdAt: persistedTimestamp,
18482
+ domain: external_exports.enum(["owner", "call"]),
18483
+ expiresAt: persistedTimestamp,
18484
+ fingerprint: persistedHash,
18485
+ objectId: persistedId,
18486
+ originCallId: persistedId.optional(),
18487
+ owner: persistedOwner,
18488
+ producer: persistedOwner,
18489
+ uploadId: persistedId
18490
+ });
18526
18491
  function parseSession(value) {
18527
- const record2 = assertRevisioned(value, "upload session");
18528
- if (typeof record2.id !== "string" || typeof record2.objectId !== "string" || typeof record2.capabilityHash !== "string" || typeof record2.status !== "string") throw stateCorrupt("upload session");
18529
- return value;
18492
+ const session = parseSessionRecord(value);
18493
+ if (session.expectedSize !== void 0 && session.expectedSize > session.maxBytes || session.transport === "presigned-put" && session.expectedSize === void 0) throw stateCorrupt("upload session");
18494
+ return session;
18530
18495
  }
18531
18496
  function parseCallCapability(value) {
18532
- const record2 = assertRevisioned(value, "call capability");
18533
- if (typeof record2.id !== "string" || typeof record2.tokenHash !== "string" || typeof record2.owner !== "string" || typeof record2.producer !== "string" || typeof record2.callId !== "string" || !Array.isArray(record2.reservations)) throw stateCorrupt("call capability");
18534
- return value;
18535
- }
18536
- function parseShare(value) {
18537
- const record2 = assertRevisioned(value, "share grant");
18538
- if (typeof record2.id !== "string" || typeof record2.objectId !== "string" || typeof record2.tokenHash !== "string" || typeof record2.createdBy !== "string") throw stateCorrupt("share grant");
18539
- return value;
18540
- }
18541
- function parseIdempotencyBinding(value) {
18542
- const record2 = assertRevisioned(value, "idempotency binding");
18543
- if (typeof record2.owner !== "string" || record2.domain !== "owner" && record2.domain !== "call" || typeof record2.producer !== "string" || typeof record2.fingerprint !== "string" || typeof record2.objectId !== "string" || typeof record2.uploadId !== "string") throw stateCorrupt("idempotency binding");
18544
- return value;
18497
+ const capability = parseCallCapabilityRecord(value);
18498
+ const reservedBytes = capability.reservations.reduce(
18499
+ (total, reservation) => total + reservation.maxBytes,
18500
+ 0
18501
+ );
18502
+ const ids = new Set(capability.reservations.map((reservation) => reservation.objectId));
18503
+ if (capability.maxObjectBytes > capability.maxBytes || capability.reservations.length > capability.maxObjects || ids.size !== capability.reservations.length || capability.reservations.some((reservation) => reservation.maxBytes > capability.maxObjectBytes) || !Number.isSafeInteger(reservedBytes) || reservedBytes !== capability.reservedBytes || reservedBytes > capability.maxBytes) throw stateCorrupt("call capability");
18504
+ return capability;
18545
18505
  }
18546
18506
  function requireOwner(owner, field = "owner") {
18547
18507
  if (typeof owner !== "string" || owner.trim() === "" || /[\r\n\0]/.test(owner)) {
@@ -18580,7 +18540,10 @@ function normalizeContentType(value) {
18580
18540
  }
18581
18541
  function normalizeChecksum(value) {
18582
18542
  if (value === void 0) return void 0;
18583
- const record2 = asRecord2(value, "checksum");
18543
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
18544
+ throw new TBError("invalid_argument", "checksum \u4EC5\u652F\u6301 sha256");
18545
+ }
18546
+ const record2 = value;
18584
18547
  if (record2.algorithm !== "sha256" || typeof record2.value !== "string") {
18585
18548
  throw new TBError("invalid_argument", "checksum \u4EC5\u652F\u6301 sha256");
18586
18549
  }
@@ -18702,6 +18665,12 @@ var StoreService = class {
18702
18665
  tokenSecret;
18703
18666
  uploadTtlSec;
18704
18667
  cas;
18668
+ /** 所有已存在记录的 CAS 共用 revision 期望,并拒绝错误的版本跃迁。 */
18669
+ async compareRecord(key, current, next) {
18670
+ if (next !== null && next.revision !== current.revision + 1)
18671
+ throw stateCorrupt("revision transition");
18672
+ return await this.cas(key, current.revision, next);
18673
+ }
18705
18674
  async issueCallUploadCapability(input) {
18706
18675
  const now = this.nowIso();
18707
18676
  const expiresAt = normalizeTimestamp(input.expiresAt, "expiresAt");
@@ -18775,7 +18744,7 @@ var StoreService = class {
18775
18744
  terminalAt: this.nowIso(),
18776
18745
  revision: capability.revision + 1
18777
18746
  };
18778
- if (await this.cas(`${KEY_STORE_CALL_CAPABILITY}${capability.id}`, capability.revision, next)) {
18747
+ if (await this.compareRecord(`${KEY_STORE_CALL_CAPABILITY}${capability.id}`, capability, next)) {
18779
18748
  return;
18780
18749
  }
18781
18750
  }
@@ -18813,7 +18782,7 @@ var StoreService = class {
18813
18782
  /** relay PUT 成功即在同一调用内把对象推进 ready;后续 complete 仅作幂等确认。 */
18814
18783
  async commitRelayUpload(input) {
18815
18784
  const session = await this.verifyUploadToken(input.uploadToken);
18816
- if (session.status === "completed") return this.readyDescriptor(session.objectId);
18785
+ if (session.status === "completed") return descriptorOf(await this.requireObject(session.objectId));
18817
18786
  if (session.transport !== "relay") {
18818
18787
  throw new TBError("invalid_argument", "\u8BE5 upload session \u4E0D\u662F relay transport");
18819
18788
  }
@@ -18851,7 +18820,7 @@ var StoreService = class {
18851
18820
  await this.failUpload(session, object2);
18852
18821
  throw error51;
18853
18822
  }
18854
- return this.markReady(session, object2, meta3);
18823
+ return this.markReady(session, meta3);
18855
18824
  }
18856
18825
  /** 普通管理面 complete:只接受稳定 owner,不接受 capability body 字段。 */
18857
18826
  async completeUpload(uploadId, actor) {
@@ -18868,7 +18837,7 @@ var StoreService = class {
18868
18837
  }
18869
18838
  async completeAuthorizedUpload(session, object2) {
18870
18839
  if (session.status === "completed" || object2.status === "ready") {
18871
- if (object2.status !== "ready") return this.readyDescriptor(object2.id);
18840
+ if (object2.status !== "ready") return descriptorOf(await this.requireObject(object2.id));
18872
18841
  await this.completeSessionBestEffort(session);
18873
18842
  return descriptorOf(object2);
18874
18843
  }
@@ -18891,7 +18860,7 @@ var StoreService = class {
18891
18860
  await this.failUpload(session, object2);
18892
18861
  throw error51;
18893
18862
  }
18894
- return this.markReady(session, object2, meta3);
18863
+ return this.markReady(session, meta3);
18895
18864
  }
18896
18865
  /** 普通管理面 abort:owner 路径。 */
18897
18866
  async abortUpload(uploadId, actor) {
@@ -18900,9 +18869,7 @@ var StoreService = class {
18900
18869
  }
18901
18870
  /** capability-only abort:token 只应来自 Authorization header。 */
18902
18871
  async abortUploadWithToken(uploadId, uploadToken) {
18903
- const id = this.tokenId(uploadToken, "upload");
18904
- const session = await this.requireSession(id);
18905
- await this.assertTokenHash(uploadToken, session.capabilityHash, "upload capability \u65E0\u6548");
18872
+ const session = await this.verifyUploadToken(uploadToken);
18906
18873
  if (session.id !== uploadId) {
18907
18874
  throw new TBError("permission_denied", "upload capability \u4E0E session \u4E0D\u5339\u914D");
18908
18875
  }
@@ -18921,7 +18888,7 @@ var StoreService = class {
18921
18888
  updatedAt: this.nowIso(),
18922
18889
  revision: object2.revision + 1
18923
18890
  };
18924
- if (await this.cas(`${KEY_STORE_OBJECT}${object2.id}`, object2.revision, next)) object2 = next;
18891
+ if (await this.compareRecord(`${KEY_STORE_OBJECT}${object2.id}`, object2, next)) object2 = next;
18925
18892
  else object2 = await this.requireObject(object2.id);
18926
18893
  }
18927
18894
  if (object2.status === "ready") throw new TBError("conflict", "ready \u5BF9\u8C61\u4E0D\u80FD abort");
@@ -18933,7 +18900,7 @@ var StoreService = class {
18933
18900
  terminalAt,
18934
18901
  revision: session.revision + 1
18935
18902
  };
18936
- if (await this.cas(`${KEY_STORE_UPLOAD}${session.id}`, session.revision, next)) session = next;
18903
+ if (await this.compareRecord(`${KEY_STORE_UPLOAD}${session.id}`, session, next)) session = next;
18937
18904
  else session = await this.requireSession(session.id);
18938
18905
  }
18939
18906
  if (session.status === "completed") throw new TBError("conflict", "ready \u5BF9\u8C61\u4E0D\u80FD abort");
@@ -18991,7 +18958,7 @@ var StoreService = class {
18991
18958
  updatedAt: this.nowIso(),
18992
18959
  revision: object2.revision + 1
18993
18960
  };
18994
- if (!await this.cas(`${KEY_STORE_OBJECT}${object2.id}`, object2.revision, next)) continue;
18961
+ if (!await this.compareRecord(`${KEY_STORE_OBJECT}${object2.id}`, object2, next)) continue;
18995
18962
  await this.objects.delete(object2.driverKey);
18996
18963
  await this.markBytesDeleted(object2.id, object2.driverKey);
18997
18964
  return { ok: true };
@@ -19056,7 +19023,7 @@ var StoreService = class {
19056
19023
  terminalAt: this.nowIso(),
19057
19024
  revision: grant.revision + 1
19058
19025
  };
19059
- if (await this.cas(`${KEY_STORE_SHARE}${grant.id}`, grant.revision, next)) {
19026
+ if (await this.compareRecord(`${KEY_STORE_SHARE}${grant.id}`, grant, next)) {
19060
19027
  return { ok: true };
19061
19028
  }
19062
19029
  }
@@ -19073,7 +19040,6 @@ var StoreService = class {
19073
19040
  expiredUploads: 0,
19074
19041
  abandonedObjects: 0,
19075
19042
  deletedBytes: 0,
19076
- deletedOrphans: 0,
19077
19043
  deletedStaging: 0,
19078
19044
  expiredCallCapabilities: 0,
19079
19045
  expiredIdempotencyBindings: 0,
@@ -19102,7 +19068,7 @@ var StoreService = class {
19102
19068
  if (session.status === "expired") result.expiredUploads++;
19103
19069
  }
19104
19070
  if (this.uploadSessionIsTerminal(session) && this.retentionElapsed(this.uploadSessionTerminalAt(session), this.uploadTtlSec, nowMs)) {
19105
- await this.cas(item.key, session.revision, null);
19071
+ await this.compareRecord(item.key, session, null);
19106
19072
  }
19107
19073
  }
19108
19074
  const shares = opts.cursors?.shares === null ? { items: [] } : await this.state.list(KEY_STORE_SHARE, {
@@ -19119,7 +19085,7 @@ var StoreService = class {
19119
19085
  if (grant.status === "expired") result.expiredShares++;
19120
19086
  }
19121
19087
  if (grant.status !== "active" && this.retentionElapsed(grant.terminalAt ?? grant.expiresAt, this.shareTtlSec, nowMs)) {
19122
- await this.cas(item.key, grant.revision, null);
19088
+ await this.compareRecord(item.key, grant, null);
19123
19089
  }
19124
19090
  }
19125
19091
  const capabilities = opts.cursors?.callCapabilities === null ? { items: [] } : await this.state.list(KEY_STORE_CALL_CAPABILITY, {
@@ -19140,7 +19106,7 @@ var StoreService = class {
19140
19106
  this.uploadTtlSec,
19141
19107
  nowMs
19142
19108
  )) {
19143
- await this.cas(item.key, capability.revision, null);
19109
+ await this.compareRecord(item.key, capability, null);
19144
19110
  }
19145
19111
  }
19146
19112
  const idempotencyBindings = opts.cursors?.idempotencyBindings === null ? { items: [] } : await this.state.list(KEY_STORE_IDEMPOTENCY, {
@@ -19150,7 +19116,7 @@ var StoreService = class {
19150
19116
  for (const item of idempotencyBindings.items) {
19151
19117
  const binding = parseIdempotencyBinding(item.value);
19152
19118
  if (Date.parse(binding.expiresAt) > nowMs) continue;
19153
- if (await this.cas(item.key, binding.revision, null)) {
19119
+ if (await this.compareRecord(item.key, binding, null)) {
19154
19120
  result.expiredIdempotencyBindings++;
19155
19121
  }
19156
19122
  }
@@ -19167,7 +19133,7 @@ var StoreService = class {
19167
19133
  updatedAt: now,
19168
19134
  revision: object2.revision + 1
19169
19135
  };
19170
- if (await this.cas(`${KEY_STORE_OBJECT}${object2.id}`, object2.revision, deleted)) {
19136
+ if (await this.compareRecord(`${KEY_STORE_OBJECT}${object2.id}`, object2, deleted)) {
19171
19137
  object2 = deleted;
19172
19138
  } else {
19173
19139
  const currentRaw = await this.state.get(item.key);
@@ -19185,7 +19151,7 @@ var StoreService = class {
19185
19151
  updatedAt: now,
19186
19152
  revision: object2.revision + 1
19187
19153
  };
19188
- if (await this.cas(`${KEY_STORE_OBJECT}${object2.id}`, object2.revision, abandoned)) {
19154
+ if (await this.compareRecord(`${KEY_STORE_OBJECT}${object2.id}`, object2, abandoned)) {
19189
19155
  object2 = abandoned;
19190
19156
  result.abandonedObjects++;
19191
19157
  } else {
@@ -19204,7 +19170,7 @@ var StoreService = class {
19204
19170
  object2 = parseObject(currentRaw);
19205
19171
  }
19206
19172
  if (this.objectIsTerminal(object2) && object2.bytesDeletedAt !== void 0 && this.retentionElapsed(object2.bytesDeletedAt, this.uploadTtlSec, nowMs)) {
19207
- await this.cas(item.key, object2.revision, null);
19173
+ await this.compareRecord(item.key, object2, null);
19208
19174
  }
19209
19175
  }
19210
19176
  const cursors = {
@@ -19212,8 +19178,7 @@ var StoreService = class {
19212
19178
  shares: shares.cursor ?? null,
19213
19179
  callCapabilities: capabilities.cursor ?? null,
19214
19180
  idempotencyBindings: idempotencyBindings.cursor ?? null,
19215
- objects: objectRecords.cursor ?? null,
19216
- driverObjects: null
19181
+ objects: objectRecords.cursor ?? null
19217
19182
  };
19218
19183
  return Object.values(cursors).some((cursor) => cursor !== null) ? { ...result, cursors } : result;
19219
19184
  }
@@ -19292,12 +19257,10 @@ var StoreService = class {
19292
19257
  contentType: input.contentType,
19293
19258
  maxBytes,
19294
19259
  expiresAt: this.afterSeconds(now, this.uploadTtlSec),
19295
- attempts: 0,
19296
19260
  createdAt: now,
19297
19261
  revision: 1,
19298
19262
  ...input.size !== void 0 ? { expectedSize: input.size } : {},
19299
- ...input.checksum !== void 0 ? { expectedChecksum: input.checksum } : {},
19300
- ...input.idempotencyKey !== void 0 ? { idempotencyKeyHash: await sha256Hex(input.idempotencyKey) } : {}
19263
+ ...input.checksum !== void 0 ? { expectedChecksum: input.checksum } : {}
19301
19264
  };
19302
19265
  const objectCreated = await this.cas(`${KEY_STORE_OBJECT}${object2.id}`, null, object2);
19303
19266
  if (!objectCreated) {
@@ -19368,13 +19331,22 @@ var StoreService = class {
19368
19331
  async releaseFreshBinding(resolved) {
19369
19332
  if (!resolved.created || resolved.key === void 0) return;
19370
19333
  if (await this.state.get(`${KEY_STORE_UPLOAD}${resolved.binding.uploadId}`) !== null) return;
19371
- await this.cas(resolved.key, resolved.binding.revision, null);
19334
+ await this.compareRecord(resolved.key, resolved.binding, null);
19372
19335
  }
19373
19336
  async reserveCallCapability(token, objectId, input, transportMaxBytes) {
19374
19337
  for (let attempt = 0; attempt < MAX_CAS_ATTEMPTS; attempt++) {
19375
19338
  const capability = await this.verifyCallUploadCapability(token);
19376
19339
  const previous = capability.reservations.find((r) => r.objectId === objectId);
19377
- if (previous !== void 0) return previous.maxBytes;
19340
+ if (previous !== void 0) {
19341
+ const replayMaxBytes = Math.min(previous.maxBytes, transportMaxBytes);
19342
+ if (input.size !== void 0 && input.size > replayMaxBytes) {
19343
+ throw new TBError(
19344
+ "rate_limited",
19345
+ `\u5BF9\u8C61\u8D85\u8FC7\u672C\u6B21\u4E0A\u4F20\u4E0A\u9650 ${replayMaxBytes} bytes`
19346
+ );
19347
+ }
19348
+ return replayMaxBytes;
19349
+ }
19378
19350
  if (capability.status !== "active") {
19379
19351
  throw new TBError("rate_limited", "call upload capability \u914D\u989D\u5DF2\u8017\u5C3D");
19380
19352
  }
@@ -19404,18 +19376,16 @@ var StoreService = class {
19404
19376
  status: exhausted ? "exhausted" : "active",
19405
19377
  revision: capability.revision + 1
19406
19378
  };
19407
- if (await this.cas(
19408
- `${KEY_STORE_CALL_CAPABILITY}${capability.id}`,
19409
- capability.revision,
19410
- next
19411
- )) return maxBytes;
19379
+ if (await this.compareRecord(`${KEY_STORE_CALL_CAPABILITY}${capability.id}`, capability, next))
19380
+ return maxBytes;
19412
19381
  }
19413
19382
  throw new TBError("conflict", "call upload capability \u5E76\u53D1\u6D88\u8D39\u51B2\u7A81");
19414
19383
  }
19415
19384
  async startFor(session) {
19416
19385
  const object2 = await this.requireObject(session.objectId);
19417
19386
  const uploadToken = await this.tokenFor("upload", session.id);
19418
- if (session.status === "completed" && object2.status === "ready") {
19387
+ if (object2.status === "ready") {
19388
+ await this.completeSessionBestEffort(session);
19419
19389
  return {
19420
19390
  uploadId: session.id,
19421
19391
  objectUri: storeUri(object2.id),
@@ -19436,7 +19406,11 @@ var StoreService = class {
19436
19406
  throw new TBError("conflict", "upload session \u5DF2\u8FC7\u671F");
19437
19407
  }
19438
19408
  let signedRequest;
19439
- if (session.transport === "presigned-put" && session.expectedSize !== void 0 && this.objects.presignPutExact !== void 0) {
19409
+ if (session.transport === "presigned-put") {
19410
+ if (session.expectedSize === void 0) throw stateCorrupt("direct upload size");
19411
+ if (this.objects.presignPutExact === void 0) {
19412
+ throw new TBError("unavailable", "direct upload signer \u5F53\u524D\u4E0D\u53EF\u7528", { retryable: true });
19413
+ }
19440
19414
  signedRequest = await this.objects.presignPutExact(
19441
19415
  object2.driverKey,
19442
19416
  Math.max(1, Math.floor(remainingMs / 1e3)),
@@ -19493,7 +19467,7 @@ var StoreService = class {
19493
19467
  bytesDeletedAt: this.nowIso(),
19494
19468
  revision: object2.revision + 1
19495
19469
  };
19496
- if (await this.cas(`${KEY_STORE_OBJECT}${object2.id}`, object2.revision, next)) return;
19470
+ if (await this.compareRecord(`${KEY_STORE_OBJECT}${object2.id}`, object2, next)) return;
19497
19471
  }
19498
19472
  throw new TBError("conflict", "Store \u5BF9\u8C61\u5B57\u8282\u5220\u9664\u72B6\u6001\u5E76\u53D1\u66F4\u65B0\u51B2\u7A81");
19499
19473
  }
@@ -19580,56 +19554,51 @@ var StoreService = class {
19580
19554
  };
19581
19555
  return bounded;
19582
19556
  }
19583
- async markReady(sessionInput, objectInput, meta3) {
19584
- let object2 = await this.requireObject(objectInput.id);
19585
- if (object2.status === "ready") {
19586
- const currentSession = await this.requireSession(sessionInput.id);
19587
- await this.completeSessionBestEffort(currentSession);
19588
- return descriptorOf(object2);
19589
- }
19590
- if (object2.status !== "pending") {
19591
- await this.objects.delete(object2.driverKey);
19592
- await this.markBytesDeleted(object2.id, object2.driverKey);
19593
- throw new TBError("conflict", `\u5BF9\u8C61\u72B6\u6001\u4E0D\u5141\u8BB8 ready:${object2.status}`);
19594
- }
19595
- const now = this.nowIso();
19557
+ async markReady(sessionInput, meta3) {
19596
19558
  const actualChecksum = sessionInput.expectedChecksum !== void 0 && meta3.metadata?.["checksum-sha256"]?.toLowerCase() === sessionInput.expectedChecksum.value ? sessionInput.expectedChecksum : void 0;
19597
- const ready = {
19598
- ...object2,
19599
- status: "ready",
19600
- size: meta3.size,
19601
- etag: meta3.etag,
19602
- readyAt: now,
19603
- updatedAt: now,
19604
- revision: object2.revision + 1,
19605
- ...actualChecksum !== void 0 ? { checksum: actualChecksum } : {}
19606
- };
19607
- if (!await this.cas(`${KEY_STORE_OBJECT}${object2.id}`, object2.revision, ready)) {
19608
- object2 = await this.requireObject(object2.id);
19609
- if (object2.status !== "ready") {
19559
+ for (let attempt = 0; attempt < MAX_CAS_ATTEMPTS; attempt++) {
19560
+ const object2 = await this.requireObject(sessionInput.objectId);
19561
+ if (object2.status === "ready") {
19562
+ await this.completeSessionBestEffort(await this.requireSession(sessionInput.id));
19563
+ return descriptorOf(object2);
19564
+ }
19565
+ if (object2.status !== "pending") {
19610
19566
  await this.objects.delete(object2.driverKey);
19611
19567
  await this.markBytesDeleted(object2.id, object2.driverKey);
19612
- throw new TBError("conflict", `\u5BF9\u8C61\u5E76\u53D1\u72B6\u6001\u51B2\u7A81:${object2.status}`);
19568
+ const detail = attempt === 0 ? "\u72B6\u6001\u4E0D\u5141\u8BB8 ready" : "\u5E76\u53D1\u72B6\u6001\u51B2\u7A81";
19569
+ throw new TBError("conflict", `\u5BF9\u8C61${detail}:${object2.status}`);
19613
19570
  }
19614
- } else {
19615
- object2 = ready;
19571
+ const now = this.nowIso();
19572
+ const ready = {
19573
+ ...object2,
19574
+ status: "ready",
19575
+ size: meta3.size,
19576
+ etag: meta3.etag,
19577
+ readyAt: now,
19578
+ updatedAt: now,
19579
+ revision: object2.revision + 1,
19580
+ ...actualChecksum !== void 0 ? { checksum: actualChecksum } : {}
19581
+ };
19582
+ if (!await this.compareRecord(`${KEY_STORE_OBJECT}${object2.id}`, object2, ready)) continue;
19583
+ await this.completeSessionBestEffort(await this.requireSession(sessionInput.id));
19584
+ return descriptorOf(ready);
19616
19585
  }
19617
- const session = await this.requireSession(sessionInput.id);
19618
- await this.completeSessionBestEffort(session);
19619
- return descriptorOf(object2);
19586
+ throw new TBError("conflict", "\u5BF9\u8C61\u5E76\u53D1\u72B6\u6001\u51B2\u7A81:pending");
19620
19587
  }
19621
- async completeSessionBestEffort(session) {
19622
- if (session.status === "completed") return;
19623
- if (session.status !== "created") return;
19624
- const completedAt = this.nowIso();
19625
- const next = {
19626
- ...session,
19627
- status: "completed",
19628
- completedAt,
19629
- terminalAt: completedAt,
19630
- revision: session.revision + 1
19631
- };
19632
- await this.cas(`${KEY_STORE_UPLOAD}${session.id}`, session.revision, next);
19588
+ async completeSessionBestEffort(sessionInput) {
19589
+ for (let attempt = 0; attempt < MAX_CAS_ATTEMPTS; attempt++) {
19590
+ const session = await this.requireSession(sessionInput.id);
19591
+ if (session.status === "completed" || session.status !== "created") return;
19592
+ const completedAt = this.nowIso();
19593
+ const next = {
19594
+ ...session,
19595
+ status: "completed",
19596
+ completedAt,
19597
+ terminalAt: completedAt,
19598
+ revision: session.revision + 1
19599
+ };
19600
+ if (await this.compareRecord(`${KEY_STORE_UPLOAD}${session.id}`, session, next)) return;
19601
+ }
19633
19602
  }
19634
19603
  async failUpload(session, object2) {
19635
19604
  const terminalAt = this.nowIso();
@@ -19641,7 +19610,7 @@ var StoreService = class {
19641
19610
  updatedAt: terminalAt,
19642
19611
  revision: object2.revision + 1
19643
19612
  };
19644
- await this.cas(`${KEY_STORE_OBJECT}${object2.id}`, object2.revision, failed);
19613
+ await this.compareRecord(`${KEY_STORE_OBJECT}${object2.id}`, object2, failed);
19645
19614
  }
19646
19615
  if (session.status === "created") {
19647
19616
  const failed = {
@@ -19650,20 +19619,13 @@ var StoreService = class {
19650
19619
  terminalAt,
19651
19620
  revision: session.revision + 1
19652
19621
  };
19653
- await this.cas(`${KEY_STORE_UPLOAD}${session.id}`, session.revision, failed);
19622
+ await this.compareRecord(`${KEY_STORE_UPLOAD}${session.id}`, session, failed);
19654
19623
  }
19655
19624
  await this.markBytesDeleted(object2.id, object2.driverKey);
19656
19625
  }
19657
19626
  async expireUpload(session) {
19658
19627
  if (session.status !== "created") return;
19659
- const next = {
19660
- ...session,
19661
- status: "expired",
19662
- terminalAt: this.nowIso(),
19663
- revision: session.revision + 1
19664
- };
19665
- if (!await this.cas(`${KEY_STORE_UPLOAD}${session.id}`, session.revision, next)) return;
19666
- const object2 = await this.requireObject(session.objectId);
19628
+ let object2 = await this.requireObject(session.objectId);
19667
19629
  if (object2.status === "pending") {
19668
19630
  const abandoned = {
19669
19631
  ...object2,
@@ -19671,8 +19633,26 @@ var StoreService = class {
19671
19633
  updatedAt: this.nowIso(),
19672
19634
  revision: object2.revision + 1
19673
19635
  };
19674
- await this.cas(`${KEY_STORE_OBJECT}${object2.id}`, object2.revision, abandoned);
19636
+ if (await this.compareRecord(`${KEY_STORE_OBJECT}${object2.id}`, object2, abandoned)) {
19637
+ object2 = abandoned;
19638
+ } else {
19639
+ object2 = await this.requireObject(object2.id);
19640
+ }
19641
+ }
19642
+ if (object2.status === "ready") {
19643
+ await this.completeSessionBestEffort(session);
19644
+ return;
19675
19645
  }
19646
+ if (object2.status === "pending") return;
19647
+ const current = await this.requireSession(session.id);
19648
+ if (current.status !== "created") return;
19649
+ const next = {
19650
+ ...current,
19651
+ status: "expired",
19652
+ terminalAt: this.nowIso(),
19653
+ revision: current.revision + 1
19654
+ };
19655
+ await this.compareRecord(`${KEY_STORE_UPLOAD}${current.id}`, current, next);
19676
19656
  }
19677
19657
  async expireCallCapability(capability) {
19678
19658
  if (capability.status === "expired" || capability.status === "revoked") return;
@@ -19682,7 +19662,7 @@ var StoreService = class {
19682
19662
  terminalAt: this.nowIso(),
19683
19663
  revision: capability.revision + 1
19684
19664
  };
19685
- await this.cas(`${KEY_STORE_CALL_CAPABILITY}${capability.id}`, capability.revision, next);
19665
+ await this.compareRecord(`${KEY_STORE_CALL_CAPABILITY}${capability.id}`, capability, next);
19686
19666
  }
19687
19667
  async expireShare(grant) {
19688
19668
  if (grant.status !== "active") return;
@@ -19692,10 +19672,7 @@ var StoreService = class {
19692
19672
  terminalAt: this.nowIso(),
19693
19673
  revision: grant.revision + 1
19694
19674
  };
19695
- await this.cas(`${KEY_STORE_SHARE}${grant.id}`, grant.revision, next);
19696
- }
19697
- async readyDescriptor(objectId) {
19698
- return descriptorOf(await this.requireObject(objectId));
19675
+ await this.compareRecord(`${KEY_STORE_SHARE}${grant.id}`, grant, next);
19699
19676
  }
19700
19677
  async requireObject(id) {
19701
19678
  const raw = await this.state.get(`${KEY_STORE_OBJECT}${id}`);
@@ -19747,94 +19724,6 @@ var StoreService = class {
19747
19724
  }
19748
19725
  };
19749
19726
 
19750
- // ../core/src/operation/registry.ts
19751
- function normalizeSchema(input) {
19752
- return input instanceof external_exports.ZodType ? input : external_exports.object(input);
19753
- }
19754
- function toJsonSchema(schema) {
19755
- const json2 = external_exports.toJSONSchema(schema);
19756
- return omit2(json2, "$schema");
19757
- }
19758
- function invalidArgument(name, error51) {
19759
- const detail = error51.issues.map((issue2) => {
19760
- const path = issue2.path.join(".");
19761
- return path.length > 0 ? `${path}: ${issue2.message}` : issue2.message;
19762
- }).join("; ");
19763
- return new TBError("invalid_argument", `invalid arguments for '${name}': ${detail}`);
19764
- }
19765
- var TOOL_RESULT_KEYS = /* @__PURE__ */ new Set(["content", "contentBlocks", "isError", "structuredContent"]);
19766
- function toToolResult(value) {
19767
- if (typeof value === "object" && value !== null && "content" in value) {
19768
- const keys = Object.keys(value);
19769
- if (keys.every((key) => TOOL_RESULT_KEYS.has(key))) return value;
19770
- }
19771
- return { content: value };
19772
- }
19773
- var OperationRegistry = class {
19774
- ops = /* @__PURE__ */ new Map();
19775
- /** 注册一个操作。同名重复注册 → invalid_argument(配置错误,快速失败)。 */
19776
- register(name, spec, handler) {
19777
- if (name.length === 0) {
19778
- throw new TBError("invalid_argument", "operation name must be non-empty");
19779
- }
19780
- if (this.ops.has(name)) {
19781
- throw new TBError("invalid_argument", `operation '${name}' is already registered`);
19782
- }
19783
- if (spec.inputSchema !== void 0 && spec.rawInputSchema !== void 0) {
19784
- throw new TBError(
19785
- "invalid_argument",
19786
- `operation '${name}': inputSchema and rawInputSchema are mutually exclusive`
19787
- );
19788
- }
19789
- const schema = spec.inputSchema !== void 0 ? normalizeSchema(spec.inputSchema) : void 0;
19790
- const toolSpec = { name };
19791
- if (spec.description !== void 0) toolSpec.description = spec.description;
19792
- if (spec.effect !== void 0) toolSpec.effect = spec.effect;
19793
- if (spec.confirm !== void 0) toolSpec.confirm = spec.confirm;
19794
- if (schema !== void 0) toolSpec.inputSchema = toJsonSchema(schema);
19795
- else if (spec.rawInputSchema !== void 0) toolSpec.inputSchema = spec.rawInputSchema;
19796
- if (spec.outputSchema !== void 0) toolSpec.outputSchema = spec.outputSchema;
19797
- this.ops.set(name, {
19798
- schema,
19799
- spec: toolSpec,
19800
- handler
19801
- });
19802
- return this;
19803
- }
19804
- /** 已注册的操作名(注册顺序)。 */
19805
- names() {
19806
- return [...this.ops.keys()];
19807
- }
19808
- has(name) {
19809
- return this.ops.has(name);
19810
- }
19811
- /** 全部 ToolSpec(工具源天然小,豁免分页)。 */
19812
- list() {
19813
- return [...this.ops.values()].map((op) => op.spec);
19814
- }
19815
- /** 单个 ToolSpec;不存在 → not_found。 */
19816
- get(name) {
19817
- const op = this.ops.get(name);
19818
- if (op === void 0) throw TBError.notFound(`unknown operation: '${name}'`);
19819
- return op.spec;
19820
- }
19821
- /**
19822
- * 调用:safeParse 入参(失败 → invalid_argument)、执行 handler、把裸返回值包成 ToolResult。
19823
- * 未声明 schema 的操作原样透传 args。
19824
- */
19825
- async call(name, args, ctx) {
19826
- const op = this.ops.get(name);
19827
- if (op === void 0) throw TBError.notFound(`unknown operation: '${name}'`);
19828
- let input = args;
19829
- if (op.schema !== void 0) {
19830
- const parsed = op.schema.safeParse(args);
19831
- if (!parsed.success) throw invalidArgument(name, parsed.error);
19832
- input = parsed.data;
19833
- }
19834
- return toToolResult(await op.handler(input, ctx));
19835
- }
19836
- };
19837
-
19838
19727
  // ../core/src/origin.ts
19839
19728
  function normalizeCanonicalOrigin(value) {
19840
19729
  if (value === void 0) return void 0;
@@ -20100,6 +19989,94 @@ function decodePluginCall(body) {
20100
19989
  return parsed.data;
20101
19990
  }
20102
19991
 
19992
+ // ../core/src/runtimeEnv.ts
19993
+ var DEFAULT_MAX_HOPS = 4;
19994
+ var optionalPositiveIntSchema = external_exports.string().min(1).transform(Number).pipe(external_exports.number().finite().positive()).transform(Math.floor).optional().catch(void 0);
19995
+ var optionalNonNegativeIntSchema = external_exports.string().min(1).transform(Number).pipe(external_exports.number().finite().int().nonnegative()).optional().catch(void 0);
19996
+ var optionalPortSchema = external_exports.string().min(1).transform(Number).pipe(external_exports.number().int().min(0).max(65535)).optional().catch(void 0);
19997
+ var optionalStringSchema = external_exports.string().optional();
19998
+ var positiveEnvKeys = [
19999
+ "TB_DEVICE_RECLAIM_SEC",
20000
+ "TB_MAX_HOPS",
20001
+ "TB_REF_THRESHOLD_BYTES",
20002
+ "TB_REF_TTL_SEC",
20003
+ "TB_STORE_CALL_MAX_BYTES",
20004
+ "TB_STORE_CALL_MAX_OBJECT_BYTES",
20005
+ "TB_STORE_CALL_MAX_OBJECTS",
20006
+ "TB_STORE_CLEANUP_INTERVAL_SEC",
20007
+ "TB_STORE_MAX_OBJECT_BYTES",
20008
+ "TB_STORE_READ_TTL_SEC",
20009
+ "TB_STORE_RELAY_MAX_BYTES",
20010
+ "TB_STORE_SHARE_TTL_SEC",
20011
+ "TB_STORE_UPLOAD_TTL_SEC",
20012
+ "TB_TOOL_CACHE_TTL",
20013
+ "TB_UPLOAD_GRANT_TTL_SEC"
20014
+ ];
20015
+ var positiveEnvShape = Object.fromEntries(
20016
+ positiveEnvKeys.map((key) => [key, optionalPositiveIntSchema])
20017
+ );
20018
+ var runtimeEnvSchema = external_exports.object({
20019
+ ...positiveEnvShape,
20020
+ TB_ALLOW_INSECURE_HTTP: optionalStringSchema,
20021
+ TB_CANONICAL_ORIGIN: optionalStringSchema,
20022
+ TB_INSTANCE_ID: optionalStringSchema,
20023
+ TB_REMOTE_ALLOWLIST: optionalStringSchema,
20024
+ TB_STORE_CALL_ALLOWED_CONTENT_TYPES: optionalStringSchema,
20025
+ TB_STORE_TOKEN_SECRET: external_exports.union([
20026
+ external_exports.literal("").transform(() => void 0),
20027
+ external_exports.string().min(16, "TB_STORE_TOKEN_SECRET \u81F3\u5C11\u9700\u8981 16 \u4E2A\u5B57\u7B26")
20028
+ ]).optional()
20029
+ });
20030
+ function setDefined(target, key, value) {
20031
+ if (value !== void 0) target[key] = value;
20032
+ }
20033
+ function parseNonNegativeIntEnv(value) {
20034
+ return optionalNonNegativeIntSchema.parse(value);
20035
+ }
20036
+ function parsePortEnv(value) {
20037
+ return optionalPortSchema.parse(value);
20038
+ }
20039
+ function parseRuntimeEnv(env) {
20040
+ const parsed = runtimeEnvSchema.parse(env);
20041
+ const allowInsecureHttp = parsed.TB_ALLOW_INSECURE_HTTP === "true";
20042
+ const allowlist = (parsed.TB_REMOTE_ALLOWLIST ?? "").split(",").map((value) => value.trim()).filter(Boolean);
20043
+ const allowedContentTypes = (parsed.TB_STORE_CALL_ALLOWED_CONTENT_TYPES ?? "").split(",").map((value) => value.trim()).filter(Boolean);
20044
+ const presignTtl = (value) => value === void 0 ? void 0 : Math.min(value, PRESIGN_TTL_SEC_MAX);
20045
+ const result = {
20046
+ allowInsecureHttp,
20047
+ remote: {
20048
+ allowInsecure: allowInsecureHttp,
20049
+ allowlist,
20050
+ maxHops: parsed.TB_MAX_HOPS ?? DEFAULT_MAX_HOPS,
20051
+ ...parsed.TB_INSTANCE_ID ? { instanceId: parsed.TB_INSTANCE_ID } : {}
20052
+ }
20053
+ };
20054
+ setDefined(result, "canonicalOrigin", normalizeCanonicalOrigin(parsed.TB_CANONICAL_ORIGIN));
20055
+ const directNumbers = [
20056
+ ["deviceReclaimSec", "TB_DEVICE_RECLAIM_SEC"],
20057
+ ["toolCacheTtlSec", "TB_TOOL_CACHE_TTL"],
20058
+ ["refThresholdBytes", "TB_REF_THRESHOLD_BYTES"],
20059
+ ["storeMaxObjectBytes", "TB_STORE_MAX_OBJECT_BYTES"],
20060
+ ["storeRelayMaxBytes", "TB_STORE_RELAY_MAX_BYTES"],
20061
+ ["storeCallMaxBytes", "TB_STORE_CALL_MAX_BYTES"],
20062
+ ["storeCallMaxObjectBytes", "TB_STORE_CALL_MAX_OBJECT_BYTES"],
20063
+ ["storeCallMaxObjects", "TB_STORE_CALL_MAX_OBJECTS"],
20064
+ ["storeCleanupIntervalSec", "TB_STORE_CLEANUP_INTERVAL_SEC"]
20065
+ ];
20066
+ for (const [output, input] of directNumbers) setDefined(result, output, parsed[input]);
20067
+ const presignTtls = [
20068
+ ["refTtlSec", "TB_REF_TTL_SEC"],
20069
+ ["uploadGrantTtlSec", "TB_UPLOAD_GRANT_TTL_SEC"],
20070
+ ["storeUploadTtlSec", "TB_STORE_UPLOAD_TTL_SEC"],
20071
+ ["storeShareTtlSec", "TB_STORE_SHARE_TTL_SEC"],
20072
+ ["storeReadTtlSec", "TB_STORE_READ_TTL_SEC"]
20073
+ ];
20074
+ for (const [output, input] of presignTtls) setDefined(result, output, presignTtl(parsed[input]));
20075
+ setDefined(result, "storeTokenSecret", parsed.TB_STORE_TOKEN_SECRET);
20076
+ if (allowedContentTypes.length > 0) result.storeCallAllowedContentTypes = allowedContentTypes;
20077
+ return result;
20078
+ }
20079
+
20103
20080
  // ../core/src/search/types.ts
20104
20081
  var TOOL_SEARCH_BATCH_LIMIT = 100;
20105
20082
  var TOOL_SEARCH_WORK_LIMIT = 400;
@@ -20999,133 +20976,103 @@ function parseFrontmatter(text) {
20999
20976
  return { meta: meta3, body };
21000
20977
  }
21001
20978
 
21002
- // ../core/src/skillhub/help.ts
21003
- var SKILLHUB_CAPABILITIES = ["search"];
21004
- var SCOPE_BY_CMD2 = {
21005
- list: "read",
21006
- get: "read",
21007
- search: "read",
21008
- publish: "write",
21009
- remove: "write"
21010
- };
20979
+ // ../core/src/skillhub/commands.ts
20980
+ var publishFileSchema = external_exports.strictObject({
20981
+ path: external_exports.string().describe(
20982
+ "file path relative to the skill root, e.g. 'SKILL.md', 'scripts/run.sh'"
20983
+ ),
20984
+ content: external_exports.string().describe("UTF-8 text content"),
20985
+ contentType: external_exports.string().optional().describe("optional; inferred from extension when omitted")
20986
+ });
20987
+ var skillhubCommands = new HtbpCommandRegistry().register(
20988
+ "list",
20989
+ {
20990
+ h: "list published skills (id / name / description from SKILL.md frontmatter, paginated)",
20991
+ inputSchema: external_exports.strictObject({ opts: HTBP_LIST_OPTIONS_SCHEMA.optional() }),
20992
+ returns: "Page<SkillSummary>",
20993
+ scope: "read"
20994
+ },
20995
+ ({ opts }, provider) => provider.list(opts)
20996
+ ).register(
20997
+ "get",
20998
+ {
20999
+ h: "read a skill: SKILL.md body + file manifest; pass 'file' to fetch one bundled file (oversized/binary as { $ref })",
21000
+ inputSchema: external_exports.strictObject({
21001
+ id: external_exports.string().describe("skill id"),
21002
+ file: external_exports.string().optional().describe(
21003
+ "optional: path of one bundled file to fetch instead of the manifest"
21004
+ )
21005
+ }),
21006
+ returns: "SkillDetail | SkillFile",
21007
+ scope: "read"
21008
+ },
21009
+ ({ file: file2, id }, provider) => file2 === void 0 ? provider.get(id) : provider.get_file(id, file2)
21010
+ ).register(
21011
+ "search",
21012
+ {
21013
+ h: "keyword search over skill id / name / description",
21014
+ inputSchema: external_exports.strictObject({
21015
+ query: external_exports.string().describe("substring to match"),
21016
+ opts: HTBP_LIST_OPTIONS_SCHEMA.optional()
21017
+ }),
21018
+ returns: "Page<SkillSummary>",
21019
+ scope: "read"
21020
+ },
21021
+ ({ opts, query }, provider) => provider.search(query, opts)
21022
+ ).register(
21023
+ "publish",
21024
+ {
21025
+ h: "publish/replace a skill from a set of text files (must include SKILL.md with name+description frontmatter)",
21026
+ inputSchema: external_exports.strictObject({
21027
+ id: external_exports.string().optional().describe(
21028
+ "skill id; defaults to a slug derived from the frontmatter name"
21029
+ ),
21030
+ files: external_exports.array(publishFileSchema).describe(
21031
+ "the skill files; whole-skill replace (files not listed are removed)"
21032
+ )
21033
+ }),
21034
+ returns: "{ id, name, description, fileCount }",
21035
+ scope: "write"
21036
+ },
21037
+ ({ files, id }, provider) => {
21038
+ const input = {
21039
+ files,
21040
+ ...id !== void 0 ? { id } : {}
21041
+ };
21042
+ return provider.publish(input);
21043
+ }
21044
+ ).register(
21045
+ "remove",
21046
+ {
21047
+ h: "delete a skill and all its files (not_found if it does not exist)",
21048
+ inputSchema: external_exports.strictObject({ id: external_exports.string().describe("skill id") }),
21049
+ scope: "write",
21050
+ effect: "destructive"
21051
+ },
21052
+ ({ id }, provider) => provider.remove(id)
21053
+ );
21011
21054
  function skillhubScopeForCmd(command) {
21012
- return SCOPE_BY_CMD2[command] ?? null;
21055
+ const scope = skillhubCommands.scopeFor(command);
21056
+ return scope === "read" || scope === "write" ? scope : null;
21013
21057
  }
21014
- var OPTS_SCHEMA2 = {
21015
- type: "object",
21016
- description: "pagination options",
21017
- properties: {
21018
- cursor: { type: "string", description: "opaque cursor returned by the previous page" },
21019
- limit: { type: "number", description: "page size (default 50, max 200)" }
21058
+ async function dispatchSkillhubCmd(provider, command, args) {
21059
+ const normalized = command.toLowerCase();
21060
+ if (!skillhubCommands.has(normalized)) {
21061
+ throw new TBError("invalid_argument", `unknown cmd '${command}'`);
21020
21062
  }
21021
- };
21022
- var PUBLISH_FILE_SCHEMA = {
21023
- type: "object",
21024
- required: ["path", "content"],
21025
- properties: {
21026
- path: {
21027
- type: "string",
21028
- description: "file path relative to the skill root, e.g. 'SKILL.md', 'scripts/run.sh'"
21029
- },
21030
- content: { type: "string", description: "UTF-8 text content" },
21031
- contentType: { type: "string", description: "optional; inferred from extension when omitted" }
21063
+ if (normalized === "publish" && !Array.isArray(args.files)) {
21064
+ throw new TBError("invalid_argument", "publish \u9700\u8981\u6570\u7EC4 'files'");
21032
21065
  }
21033
- };
21034
- function skillhubCmds(nodePath) {
21035
- const path = cmdPath(nodePath);
21036
- const cmds = [
21037
- {
21038
- name: "list",
21039
- method: "POST",
21040
- path,
21041
- h: "list published skills (id / name / description from SKILL.md frontmatter, paginated)",
21042
- inputSchema: {
21043
- type: "object",
21044
- properties: { opts: OPTS_SCHEMA2 }
21045
- },
21046
- returns: "Page<SkillSummary>",
21047
- scope: "read"
21048
- },
21049
- {
21050
- name: "get",
21051
- method: "POST",
21052
- path,
21053
- h: "read a skill: SKILL.md body + file manifest; pass 'file' to fetch one bundled file (oversized/binary as { $ref })",
21054
- inputSchema: {
21055
- type: "object",
21056
- required: ["id"],
21057
- properties: {
21058
- id: { type: "string", description: "skill id" },
21059
- file: {
21060
- type: "string",
21061
- description: "optional: path of one bundled file to fetch instead of the manifest"
21062
- }
21063
- }
21064
- },
21065
- returns: "SkillDetail | SkillFile",
21066
- scope: "read"
21067
- },
21068
- {
21069
- name: "search",
21070
- method: "POST",
21071
- path,
21072
- h: "keyword search over skill id / name / description",
21073
- inputSchema: {
21074
- type: "object",
21075
- required: ["query"],
21076
- properties: {
21077
- query: { type: "string", description: "substring to match" },
21078
- opts: OPTS_SCHEMA2
21079
- }
21080
- },
21081
- returns: "Page<SkillSummary>",
21082
- scope: "read"
21083
- },
21084
- {
21085
- name: "publish",
21086
- method: "POST",
21087
- path,
21088
- h: "publish/replace a skill from a set of text files (must include SKILL.md with name+description frontmatter)",
21089
- inputSchema: {
21090
- type: "object",
21091
- required: ["files"],
21092
- properties: {
21093
- id: {
21094
- type: "string",
21095
- description: "skill id; defaults to a slug derived from the frontmatter name"
21096
- },
21097
- files: {
21098
- type: "array",
21099
- description: "the skill files; whole-skill replace (files not listed are removed)",
21100
- items: PUBLISH_FILE_SCHEMA
21101
- }
21102
- }
21103
- },
21104
- returns: "{ id, name, description, fileCount }",
21105
- scope: "write"
21106
- },
21107
- {
21108
- name: "remove",
21109
- method: "POST",
21110
- path,
21111
- h: "delete a skill and all its files (not_found if it does not exist)",
21112
- inputSchema: {
21113
- type: "object",
21114
- required: ["id"],
21115
- properties: { id: { type: "string", description: "skill id" } }
21116
- },
21117
- scope: "write",
21118
- effect: "destructive"
21119
- }
21120
- ];
21121
- return withCommandPaths(nodePath, cmds);
21066
+ return await skillhubCommands.invoke(normalized, args, provider);
21122
21067
  }
21068
+
21069
+ // ../core/src/skillhub/help.ts
21070
+ var SKILLHUB_CAPABILITIES = ["search"];
21123
21071
  function skillhubHelpModel(node, opts = {}) {
21124
- const cmds = skillhubCmds(node.path);
21125
- return {
21126
- node: { path: node.path, kind: "skillhub", description: node.description },
21127
- cmds: opts.readOnly ? cmds.filter((c) => c.scope === "read") : cmds
21128
- };
21072
+ return skillhubCommands.helpModel(
21073
+ { path: node.path, kind: "skillhub", description: node.description },
21074
+ (command) => opts.readOnly !== true || command.scope === "read"
21075
+ );
21129
21076
  }
21130
21077
 
21131
21078
  // ../core/src/skillhub/provider.ts
@@ -21871,6 +21818,367 @@ var NodeRegistryStore = class {
21871
21818
  }
21872
21819
  };
21873
21820
 
21821
+ // ../plugin-sdk/src/index.ts
21822
+ var CONTEXT_HANDLER_VERBS = ["list", "get", "write", "update", "delete", "search"];
21823
+ var CAPABILITY_BY_VERB = { search: "search", delete: "delete" };
21824
+ var PROTOCOL_VERSION = "plugin/v2";
21825
+ function json2(value, status = 200) {
21826
+ return new Response(JSON.stringify(value), {
21827
+ status,
21828
+ headers: { "content-type": "application/json; charset=utf-8" }
21829
+ });
21830
+ }
21831
+ function errorResponse(err) {
21832
+ if (isTBError(err)) return json2(err.toJSON(), err.httpStatus);
21833
+ return json2(new TBError("internal", "internal plugin error").toJSON(), 500);
21834
+ }
21835
+ function contextVerbs(handlers) {
21836
+ const verbs = [];
21837
+ for (const verb of CONTEXT_HANDLER_VERBS) {
21838
+ if (typeof handlers[verb] === "function") verbs.push(verb);
21839
+ }
21840
+ return verbs;
21841
+ }
21842
+ function helpCmds(state) {
21843
+ if (state.kind === "tools") return state.registry.list();
21844
+ if (state.kind === "proxyTools") return [];
21845
+ return contextVerbs(state.handlers).map((name) => ({ name }));
21846
+ }
21847
+ function createPlugin(opts = {}) {
21848
+ const healthPath = opts.healthPath ?? "/healthz";
21849
+ const exports = /* @__PURE__ */ new Map();
21850
+ const dedupe = new RequestDedupe();
21851
+ const assertFreshId = (id) => {
21852
+ if (id.length === 0) throw new TBError("invalid_argument", "export id must be non-empty");
21853
+ if (exports.has(id)) {
21854
+ throw new TBError("invalid_argument", `export '${id}' is already declared`);
21855
+ }
21856
+ };
21857
+ function describe3() {
21858
+ return {
21859
+ protocolVersion: PROTOCOL_VERSION,
21860
+ exports: [...exports.values()].map((state) => {
21861
+ if (state.kind === "tools" || state.kind === "proxyTools") {
21862
+ return {
21863
+ id: state.id,
21864
+ profile: "tools/v1",
21865
+ ...state.description !== void 0 ? { description: state.description } : {},
21866
+ ...state.auth !== void 0 ? { auth: state.auth } : {},
21867
+ ...state.kind === "tools" && state.credentialProbe !== void 0 ? { credentialProbe: state.credentialProbe } : {},
21868
+ ...state.credentialFields !== void 0 ? { credentialFields: state.credentialFields } : {},
21869
+ ...state.kind === "tools" && state.mountConfigFields !== void 0 ? { mountConfigFields: state.mountConfigFields } : {},
21870
+ ...state.kind === "tools" && state.oauth !== void 0 ? { oauth: state.oauth } : {}
21871
+ };
21872
+ }
21873
+ const methods = contextVerbs(state.handlers);
21874
+ const capabilities = methods.map((verb) => CAPABILITY_BY_VERB[verb]).filter((c) => c !== void 0);
21875
+ return {
21876
+ id: state.id,
21877
+ profile: "context/v1",
21878
+ ...state.description !== void 0 ? { description: state.description } : {},
21879
+ ...state.auth !== void 0 ? { auth: state.auth } : {},
21880
+ methods,
21881
+ ...capabilities.length > 0 ? { capabilities } : {},
21882
+ ...state.mountConfigFields !== void 0 ? { mountConfigFields: state.mountConfigFields } : {}
21883
+ };
21884
+ })
21885
+ };
21886
+ }
21887
+ function help() {
21888
+ return {
21889
+ protocolVersion: PROTOCOL_VERSION,
21890
+ exports: [...exports.values()].map((state) => ({
21891
+ id: state.id,
21892
+ ...state.kind === "proxyTools" ? { dynamic: true } : {},
21893
+ cmds: helpCmds(state)
21894
+ }))
21895
+ };
21896
+ }
21897
+ function assertAuthorized(request, env) {
21898
+ if (env?.TB_PLUGIN_IN_PROCESS === true) {
21899
+ return;
21900
+ }
21901
+ const header = request.headers.get("authorization") ?? "";
21902
+ const presented = header.startsWith("Bearer ") ? header.slice("Bearer ".length) : "";
21903
+ const expected = opts.token?.(env);
21904
+ if (expected === void 0) {
21905
+ const devBypass = env?.TB_PLUGIN_ALLOW_ANY_TOKEN;
21906
+ if (devBypass !== "true") {
21907
+ throw new TBError(
21908
+ "unavailable",
21909
+ "plugin \u672A\u914D\u7F6E PLUGIN_TOKEN:\u751F\u4EA7\u90E8\u7F72\u5FC5\u987B\u914D\u7F6E;\u672C\u5730\u5F00\u53D1\u53EF\u8BBE TB_PLUGIN_ALLOW_ANY_TOKEN=true",
21910
+ { retryable: false }
21911
+ );
21912
+ }
21913
+ if (presented.length === 0) throw TBError.unauthenticated();
21914
+ return;
21915
+ }
21916
+ if (presented !== expected) throw TBError.unauthenticated();
21917
+ }
21918
+ function decodeUpstreamAuth(request) {
21919
+ const raw = request.headers.get(HEADER_TB_UPSTREAM_AUTH);
21920
+ if (raw === null || raw.length === 0) return void 0;
21921
+ const b64 = raw.replaceAll("-", "+").replaceAll("_", "/");
21922
+ const padded = b64.padEnd(b64.length + (4 - b64.length % 4) % 4, "=");
21923
+ try {
21924
+ const bytes = Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
21925
+ return new TextDecoder().decode(bytes);
21926
+ } catch {
21927
+ throw new TBError("invalid_argument", `${HEADER_TB_UPSTREAM_AUTH} is not valid base64url`);
21928
+ }
21929
+ }
21930
+ async function dispatchTools(state, method, args, ctx) {
21931
+ switch (method.toLowerCase()) {
21932
+ case "list":
21933
+ return state.registry.list();
21934
+ case "call": {
21935
+ const name = args.name;
21936
+ if (typeof name !== "string") {
21937
+ throw new TBError("invalid_argument", "call requires a string 'name'");
21938
+ }
21939
+ const callArgs = args.args ?? {};
21940
+ return await state.registry.call(name, callArgs, ctx);
21941
+ }
21942
+ default:
21943
+ throw new TBError("invalid_argument", `unknown method '${method}' on a tools export`);
21944
+ }
21945
+ }
21946
+ async function dispatchProxyTools(state, method, args, ctx) {
21947
+ switch (method.toLowerCase()) {
21948
+ case "list":
21949
+ return await state.handlers.list(ctx);
21950
+ case "call": {
21951
+ const name = args.name;
21952
+ if (typeof name !== "string" || name === "") {
21953
+ throw new TBError("invalid_argument", "call requires a non-empty string 'name'");
21954
+ }
21955
+ const callArgs = typeof args.args === "object" && args.args !== null ? args.args : {};
21956
+ return toToolResult(await state.handlers.call({ name, args: callArgs }, ctx));
21957
+ }
21958
+ default:
21959
+ throw new TBError("invalid_argument", `unknown method '${method}' on a tools export`);
21960
+ }
21961
+ }
21962
+ async function dispatchContext(state, method, args, ctx) {
21963
+ const handlers = state.handlers;
21964
+ switch (method.toLowerCase()) {
21965
+ case "list":
21966
+ if (handlers.list === void 0) break;
21967
+ return await handlers.list(
21968
+ { path: String(args.path ?? ""), ...args.opts !== void 0 ? { opts: args.opts } : {} },
21969
+ ctx
21970
+ );
21971
+ case "get":
21972
+ if (handlers.get === void 0) break;
21973
+ return await handlers.get({ path: String(args.path ?? "") }, ctx);
21974
+ case "write":
21975
+ if (handlers.write === void 0) break;
21976
+ return await handlers.write(
21977
+ { path: String(args.path ?? ""), entry: args.entry ?? {} },
21978
+ ctx
21979
+ );
21980
+ case "update":
21981
+ if (handlers.update === void 0) break;
21982
+ return await handlers.update(
21983
+ { path: String(args.path ?? ""), patch: args.patch ?? {} },
21984
+ ctx
21985
+ );
21986
+ case "delete":
21987
+ if (handlers.delete === void 0) break;
21988
+ return await handlers.delete({ path: String(args.path ?? "") }, ctx);
21989
+ case "search":
21990
+ if (handlers.search === void 0) break;
21991
+ return await handlers.search(
21992
+ { query: String(args.query ?? ""), ...args.opts !== void 0 ? { opts: args.opts } : {} },
21993
+ ctx
21994
+ );
21995
+ default:
21996
+ throw new TBError("invalid_argument", `unknown method '${method}' on a context export`);
21997
+ }
21998
+ throw new TBError("invalid_argument", `method '${method}' is not implemented by export '${state.id}'`);
21999
+ }
22000
+ async function handleEnvelope(request, env) {
22001
+ assertAuthorized(request, env);
22002
+ const ctxHeader = request.headers.get(HEADER_TB_CONTEXT);
22003
+ if (ctxHeader === null) {
22004
+ throw new TBError("invalid_argument", `missing ${HEADER_TB_CONTEXT}`);
22005
+ }
22006
+ const caller = decodeCallContext(ctxHeader);
22007
+ const call = decodePluginCall(await request.text());
22008
+ const exportId = caller.exportId ?? (exports.size === 1 ? [...exports.keys()][0] : void 0);
22009
+ if (exportId === void 0) {
22010
+ throw new TBError("invalid_argument", "call context carries no exportId and this plugin declares multiple exports");
22011
+ }
22012
+ const state = exports.get(exportId);
22013
+ if (state === void 0) throw new TBError("invalid_argument", `unknown export '${exportId}'`);
22014
+ const upstreamAuth = decodeUpstreamAuth(request);
22015
+ const credentialFields = state.kind === "context" ? void 0 : state.credentialFields;
22016
+ const ctx = {
22017
+ env,
22018
+ caller,
22019
+ exportId,
22020
+ mountPath: caller.mountPath,
22021
+ mountConfig: caller.mountConfig,
22022
+ upstreamAuth,
22023
+ credentials: credentialFields !== void 0 && upstreamAuth !== void 0 ? parseCredentialValues(upstreamAuth, credentialFields) : void 0
22024
+ };
22025
+ const requestId = request.headers.get(HEADER_TB_REQUEST_ID);
22026
+ const run = async () => {
22027
+ if (state.kind === "tools") return await dispatchTools(state, call.tool, call.arguments, ctx);
22028
+ if (state.kind === "proxyTools") {
22029
+ return await dispatchProxyTools(state, call.tool, call.arguments, ctx);
22030
+ }
22031
+ return await dispatchContext(state, call.tool, call.arguments, ctx);
22032
+ };
22033
+ const value = requestId === null ? await run() : await dedupe.run(requestId, run);
22034
+ return json2(value ?? null);
22035
+ }
22036
+ const plugin = {
22037
+ tools(id, meta3) {
22038
+ assertFreshId(id);
22039
+ const state = {
22040
+ auth: void 0,
22041
+ kind: "tools",
22042
+ id,
22043
+ description: meta3?.description,
22044
+ credentialProbe: void 0,
22045
+ credentialFields: void 0,
22046
+ mountConfigFields: void 0,
22047
+ oauth: void 0,
22048
+ registry: new OperationRegistry()
22049
+ };
22050
+ exports.set(id, state);
22051
+ const surface = {
22052
+ auth(config2) {
22053
+ if (state.oauth !== void 0 || state.credentialFields !== void 0) {
22054
+ throw new TBError(
22055
+ "invalid_argument",
22056
+ `export '${id}' \u5DF2\u58F0\u660E oauth/credentials(),\u4E0D\u80FD\u518D\u58F0\u660E auth`
22057
+ );
22058
+ }
22059
+ if (config2.kind === "none" && state.credentialProbe !== void 0) {
22060
+ throw new TBError(
22061
+ "invalid_argument",
22062
+ `export '${id}' \u5DF2\u58F0\u660E credentialProbe,\u4E0D\u80FD\u518D\u58F0\u660E auth:none`
22063
+ );
22064
+ }
22065
+ state.auth = config2;
22066
+ return surface;
22067
+ },
22068
+ register(name, spec, handler) {
22069
+ state.registry.register(name, spec, handler);
22070
+ return surface;
22071
+ },
22072
+ credentials(fields) {
22073
+ if (fields.length === 0) {
22074
+ throw new TBError("invalid_argument", "credentials() \u81F3\u5C11\u8981\u58F0\u660E\u4E00\u4E2A\u5B57\u6BB5");
22075
+ }
22076
+ if (state.oauth !== void 0) {
22077
+ throw new TBError(
22078
+ "invalid_argument",
22079
+ `export '${id}' \u5DF2\u58F0\u660E oauth,\u4E0D\u80FD\u518D\u58F0\u660E credentials()(oauth \u6A21\u5F0F\u4E0B authRef \u6307\u5411\u7684 secret \u56FA\u5B9A\u5B58 clientId/clientSecret)`
22080
+ );
22081
+ }
22082
+ if (state.auth !== void 0) {
22083
+ throw new TBError("invalid_argument", `export '${id}' \u5DF2\u58F0\u660E auth,\u4E0D\u80FD\u518D\u58F0\u660E credentials()`);
22084
+ }
22085
+ state.credentialFields = fields;
22086
+ return surface;
22087
+ },
22088
+ mountConfig(fields) {
22089
+ if (fields.length === 0) {
22090
+ throw new TBError("invalid_argument", "mountConfig() \u81F3\u5C11\u8981\u58F0\u660E\u4E00\u4E2A\u5B57\u6BB5");
22091
+ }
22092
+ state.mountConfigFields = fields;
22093
+ return surface;
22094
+ },
22095
+ oauth(config2) {
22096
+ if (state.credentialFields !== void 0) {
22097
+ throw new TBError(
22098
+ "invalid_argument",
22099
+ `export '${id}' \u5DF2\u58F0\u660E credentials(),\u4E0D\u80FD\u518D\u58F0\u660E oauth(oauth \u6A21\u5F0F\u4E0B authRef \u6307\u5411\u7684 secret \u56FA\u5B9A\u5B58 clientId/clientSecret)`
22100
+ );
22101
+ }
22102
+ if (state.auth !== void 0) {
22103
+ throw new TBError("invalid_argument", `export '${id}' \u5DF2\u58F0\u660E auth,\u4E0D\u80FD\u518D\u58F0\u660E oauth`);
22104
+ }
22105
+ if (state.credentialProbe !== void 0) {
22106
+ throw new TBError(
22107
+ "invalid_argument",
22108
+ `export '${id}' \u5DF2\u58F0\u660E credentialProbe,\u4E0D\u80FD\u518D\u58F0\u660E oauth(\u51ED\u8BC1\u53EF\u7528\u6027\u7531\u6388\u6743\u6D41\u7A0B\u672C\u8EAB\u8BC1\u660E;\u62FF client \u51ED\u8BC1\u53BB\u8C03\u63A2\u9488\u65E2\u8BC1\u660E\u4E0D\u4E86\u4EC0\u4E48,\u53C8\u4F1A\u628A clientSecret \u9001\u8FDB\u63D2\u4EF6)`
22109
+ );
22110
+ }
22111
+ state.oauth = config2;
22112
+ return surface;
22113
+ },
22114
+ probeCredentialWith(name) {
22115
+ if (!state.registry.list().some((tool) => tool.name === name)) {
22116
+ throw new TBError(
22117
+ "invalid_argument",
22118
+ `credentialProbe '${name}' \u4E0D\u662F export '${id}' \u5DF2\u6CE8\u518C\u7684\u5DE5\u5177`
22119
+ );
22120
+ }
22121
+ if (state.oauth !== void 0) {
22122
+ throw new TBError(
22123
+ "invalid_argument",
22124
+ `export '${id}' \u5DF2\u58F0\u660E oauth,\u4E0D\u80FD\u518D\u58F0\u660E credentialProbe(\u51ED\u8BC1\u53EF\u7528\u6027\u7531\u6388\u6743\u6D41\u7A0B\u672C\u8EAB\u8BC1\u660E;\u62FF client \u51ED\u8BC1\u53BB\u8C03\u63A2\u9488\u65E2\u8BC1\u660E\u4E0D\u4E86\u4EC0\u4E48,\u53C8\u4F1A\u628A clientSecret \u9001\u8FDB\u63D2\u4EF6)`
22125
+ );
22126
+ }
22127
+ if (state.auth?.kind === "none") {
22128
+ throw new TBError("invalid_argument", `export '${id}' \u58F0\u660E auth:none,\u4E0D\u80FD\u518D\u58F0\u660E credentialProbe`);
22129
+ }
22130
+ state.credentialProbe = name;
22131
+ return surface;
22132
+ }
22133
+ };
22134
+ return surface;
22135
+ },
22136
+ proxyTools(id, handlers) {
22137
+ assertFreshId(id);
22138
+ if (handlers.auth !== void 0 && handlers.credentialFields !== void 0) {
22139
+ throw new TBError("invalid_argument", `export '${id}' \u7684 auth \u4E0D\u80FD\u4E0E credentialFields \u540C\u65F6\u58F0\u660E`);
22140
+ }
22141
+ exports.set(id, {
22142
+ auth: handlers.auth,
22143
+ kind: "proxyTools",
22144
+ id,
22145
+ description: handlers.description,
22146
+ credentialFields: handlers.credentialFields,
22147
+ handlers
22148
+ });
22149
+ return plugin;
22150
+ },
22151
+ context(id, handlers) {
22152
+ assertFreshId(id);
22153
+ exports.set(id, {
22154
+ auth: handlers.auth,
22155
+ kind: "context",
22156
+ id,
22157
+ description: handlers.description,
22158
+ handlers,
22159
+ mountConfigFields: handlers.mountConfigFields
22160
+ });
22161
+ return plugin;
22162
+ },
22163
+ async fetch(request, env) {
22164
+ try {
22165
+ const url2 = new URL(request.url);
22166
+ if (request.method === "GET") {
22167
+ if (url2.pathname === healthPath) return json2({ healthy: true });
22168
+ if (url2.pathname === "/~describe") return json2(describe3());
22169
+ if (url2.pathname === "/~help") return json2(help());
22170
+ throw TBError.notFound("no such path");
22171
+ }
22172
+ if (request.method !== "POST") throw TBError.notFound("no such path");
22173
+ return await handleEnvelope(request, env);
22174
+ } catch (err) {
22175
+ return errorResponse(err);
22176
+ }
22177
+ }
22178
+ };
22179
+ return plugin;
22180
+ }
22181
+
21874
22182
  export {
21875
22183
  TB_ERROR_CODES,
21876
22184
  TBError,
@@ -21927,6 +22235,10 @@ export {
21927
22235
  buildAuthorizationUrl,
21928
22236
  buildTokenRequest,
21929
22237
  parseTokenResponse,
22238
+ contextScopeForCmd,
22239
+ parseContextCmdArgs,
22240
+ dispatchContextCmd,
22241
+ dispatchContextUploadCmd,
21930
22242
  contextMethodsOf,
21931
22243
  isReadOnlyProvider,
21932
22244
  contextCapabilitiesOf,
@@ -21936,11 +22248,29 @@ export {
21936
22248
  pluginTokenSecretName,
21937
22249
  createStoreModule,
21938
22250
  RemoteAllowlistStore,
22251
+ tbErrorBodySchema,
22252
+ nodeInputSchema,
22253
+ helpJsonSchema,
22254
+ treeJsonSchema,
22255
+ toolSearchPageSchema,
22256
+ toolSearchRequestSchema,
22257
+ registryNodeSchema,
22258
+ feedbackViewSchema,
22259
+ feedbackDetailSchema,
22260
+ feedbackListSchema,
22261
+ feedbackSubmitRequestSchema,
22262
+ feedbackSubmitResponseSchema,
22263
+ feedbackVoteRequestSchema,
22264
+ feedbackRemoveResponseSchema,
22265
+ oauthAuthorizeRequestSchema,
22266
+ oauthAuthorizeResponseSchema,
22267
+ healthResponseSchema,
22268
+ livenessResponseSchema,
22269
+ readinessResponseSchema,
21939
22270
  parseNodeInput,
21940
22271
  createBuiltins,
21941
22272
  CONTEXT_CAPABILITIES,
21942
22273
  CONTEXT_DIRECT_UPLOAD_CAPABILITY,
21943
- contextScopeForCmd,
21944
22274
  contextUploadCmd,
21945
22275
  contextHelpModel,
21946
22276
  objectBodyToBytes,
@@ -21948,7 +22278,6 @@ export {
21948
22278
  DEFAULT_STORE_DRIVER_KEY_ROOT,
21949
22279
  normalizeEntryPath,
21950
22280
  PRESIGN_TTL_SEC_DEFAULT,
21951
- PRESIGN_TTL_SEC_MAX,
21952
22281
  assertPresignTtlSec,
21953
22282
  createObjectContextUploadGrant,
21954
22283
  createObjectContextProvider,
@@ -21976,21 +22305,18 @@ export {
21976
22305
  buildTree,
21977
22306
  storeUri,
21978
22307
  StoreService,
21979
- toToolResult,
21980
- OperationRegistry,
21981
- normalizeCanonicalOrigin,
21982
22308
  catalogSetDigest,
21983
22309
  resolveIntegration,
21984
22310
  parseCredentialValues,
21985
- RequestDedupe,
21986
22311
  HEADER_TB_CONTEXT,
21987
22312
  HEADER_TB_REQUEST_ID,
21988
22313
  HEADER_TB_UPSTREAM_AUTH,
21989
22314
  encodeCallContext,
21990
- decodeCallContext,
21991
22315
  assertPluginPayloadSize,
21992
22316
  encodePluginCall,
21993
- decodePluginCall,
22317
+ parseNonNegativeIntEnv,
22318
+ parsePortEnv,
22319
+ parseRuntimeEnv,
21994
22320
  TOOL_SEARCH_BATCH_LIMIT,
21995
22321
  TOOL_SEARCH_WORK_LIMIT,
21996
22322
  TOOL_SEARCH_AUDIT_NODE_LIMIT,
@@ -22012,8 +22338,9 @@ export {
22012
22338
  PG_SEARCH_INSERT_ROWS_MAX,
22013
22339
  pgSearchDialect,
22014
22340
  SecretStoreImpl,
22015
- SKILLHUB_CAPABILITIES,
22016
22341
  skillhubScopeForCmd,
22342
+ dispatchSkillhubCmd,
22343
+ SKILLHUB_CAPABILITIES,
22017
22344
  skillhubHelpModel,
22018
22345
  createSkillhubProvider,
22019
22346
  buildHttpRequest,
@@ -22028,5 +22355,6 @@ export {
22028
22355
  appendVia,
22029
22356
  virtualizeTools,
22030
22357
  resolveUpstreamTool,
22031
- NodeRegistryStore
22358
+ NodeRegistryStore,
22359
+ createPlugin
22032
22360
  };