@tool-bridge/server 0.4.0 → 0.7.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 (108) hide show
  1. package/dist/{airtable-K3I4W27V.js → airtable-BNVPDLF2.js} +4 -4
  2. package/dist/{alt_text_generator_ai-NE5YYNW3.js → alt_text_generator_ai-RMQPHK2Y.js} +4 -4
  3. package/dist/{amap-C2Y347XH.js → amap-PRNZPQ34.js} +4 -4
  4. package/dist/{anthropic-HEEOKRI7.js → anthropic-A76VIXR7.js} +4 -4
  5. package/dist/{apify-4SCWADEP.js → apify-2Q2CTLKE.js} +4 -4
  6. package/dist/{brave_search-UDLPBEMQ.js → brave_search-5YJJVPXH.js} +4 -4
  7. package/dist/{chunk-F4O6ZRH7.js → chunk-76YX7XSX.js} +91 -84
  8. package/dist/{chunk-OKQUN7BC.js → chunk-7ASYWVYP.js} +64 -24
  9. package/dist/{chunk-TKKRVFMK.js → chunk-BUHY4IE6.js} +2 -2
  10. package/dist/{chunk-CYTI7JDJ.js → chunk-EBO6Q4NR.js} +1 -1
  11. package/dist/{chunk-XE34TXY6.js → chunk-GMHELPK3.js} +1 -1
  12. package/dist/{circleci-UJEIISGE.js → circleci-TDXP3CPQ.js} +4 -4
  13. package/dist/{clerk-I2I22BUO.js → clerk-JRSGMXMS.js} +4 -4
  14. package/dist/{cloudflare_dns-5M2EY2RS.js → cloudflare_dns-G4CHNLO7.js} +4 -4
  15. package/dist/{cohere-XQWLOLCR.js → cohere-3KN27F2B.js} +4 -4
  16. package/dist/{confluence-JHCKTQX4.js → confluence-QV6J2PBV.js} +4 -4
  17. package/dist/{convertapi-B56OVE2W.js → convertapi-HETITAHL.js} +4 -4
  18. package/dist/{currencyapi-UPOFZ5P6.js → currencyapi-647DEY6G.js} +4 -4
  19. package/dist/{deepseek-OS75U3HY.js → deepseek-G63RUHM6.js} +4 -4
  20. package/dist/{docker_hub-LQVDQTQJ.js → docker_hub-RH72CRWO.js} +4 -4
  21. package/dist/{dropbox-HWO6JJ5L.js → dropbox-T4Y5KSZW.js} +4 -4
  22. package/dist/{dub-3J7YEZZ7.js → dub-ECKQT3DC.js} +4 -4
  23. package/dist/{e2b-KT6W4M6Y.js → e2b-N5SRTPLF.js} +4 -4
  24. package/dist/{exa-GWZZ6BWW.js → exa-525ZDM7G.js} +4 -4
  25. package/dist/{fal_ai-V4AQIJ5K.js → fal_ai-BFMVHAUW.js} +4 -4
  26. package/dist/{feishu-GLQBDJMW.js → feishu-NIDOD7EW.js} +3 -3
  27. package/dist/{feishu_custom_bot-TEEZ3BRW.js → feishu_custom_bot-V5RGAIUH.js} +4 -4
  28. package/dist/{figma-N7L3KF4A.js → figma-GH7TXJMP.js} +4 -4
  29. package/dist/{firehydrant-WJT2MLGI.js → firehydrant-5T3UHAQM.js} +4 -4
  30. package/dist/{fixer-TG5NW6OA.js → fixer-3RMJLMFO.js} +4 -4
  31. package/dist/{fly-LYK5NNBG.js → fly-NPHJC5MH.js} +4 -4
  32. package/dist/{front-MUQ4YT7O.js → front-PYGXJAQK.js} +4 -4
  33. package/dist/{geocodio-XXB2D3AN.js → geocodio-T6G3FVIF.js} +4 -4
  34. package/dist/{ghost-MWYITKQ5.js → ghost-L3XIF4SJ.js} +4 -4
  35. package/dist/{github-CIBT2UB2.js → github-7YDUB6N6.js} +4 -4
  36. package/dist/{gmail-JZECDA2U.js → gmail-RY2ZDG3B.js} +4 -4
  37. package/dist/{googlecalendar-ICIIDGEO.js → googlecalendar-EHOFMXHE.js} +4 -4
  38. package/dist/{googledocs-AV5CHSH3.js → googledocs-BA3OAMKA.js} +4 -4
  39. package/dist/{grafana-SJVGZAV5.js → grafana-PYZQ4CKI.js} +4 -4
  40. package/dist/{graphhopper-ZVBBXBHD.js → graphhopper-3P4YU45N.js} +4 -4
  41. package/dist/index.d.ts +35 -11
  42. package/dist/index.js +2 -2
  43. package/dist/{ip2proxy-EJMBZ4ZQ.js → ip2proxy-GQO6VF4P.js} +4 -4
  44. package/dist/{ipgeolocation_io-7BP766PO.js → ipgeolocation_io-VOZU6E7H.js} +4 -4
  45. package/dist/{ipqualityscore-QSB62FH3.js → ipqualityscore-XDJ3TTMM.js} +4 -4
  46. package/dist/{jina_ai-O5GT4ZZZ.js → jina_ai-ELXPSTUJ.js} +4 -4
  47. package/dist/{jira-DFOD6SAV.js → jira-INDXWO4I.js} +4 -4
  48. package/dist/{langsmith-B5HC4HNY.js → langsmith-PMCQBCIK.js} +4 -4
  49. package/dist/{lemlist-63EOIXDT.js → lemlist-VWZXIHJX.js} +4 -4
  50. package/dist/{linear-LBQC6RCY.js → linear-YXG4KZR4.js} +4 -4
  51. package/dist/{logsnag-YQL67XIX.js → logsnag-XENBYHHK.js} +4 -4
  52. package/dist/main.js +101 -101
  53. package/dist/{mattermost-VWLKWU7X.js → mattermost-BHVJP5MA.js} +4 -4
  54. package/dist/{mem0-2J5MMVIP.js → mem0-7AP5UBJV.js} +4 -4
  55. package/dist/{memos-ANAGWSHJ.js → memos-MNVRYSLG.js} +4 -4
  56. package/dist/{metabase-ONSZZ4E2.js → metabase-NSXM7EID.js} +4 -4
  57. package/dist/{mistral_ai-FYNVJRRG.js → mistral_ai-HXN625YX.js} +4 -4
  58. package/dist/{mother_duck-NRSVBZM7.js → mother_duck-46VQ3V3D.js} +4 -4
  59. package/dist/{ngrok-FXSVFLEE.js → ngrok-BWCVMS3T.js} +4 -4
  60. package/dist/{notes-VO45PFNB.js → notes-AVHKCFLU.js} +2 -2
  61. package/dist/{notion-AQH7ZGLG.js → notion-BSEN3KSU.js} +4 -4
  62. package/dist/{open_exchange_rates-G3MSI5KX.js → open_exchange_rates-DWO4T5TF.js} +4 -4
  63. package/dist/{openai-SZETZOPF.js → openai-HPZYRS3M.js} +4 -4
  64. package/dist/{opengraph_io-XNV4BFE5.js → opengraph_io-OLUAYD5P.js} +4 -4
  65. package/dist/{openrouter-TV5LQ55F.js → openrouter-4DQYZIG3.js} +4 -4
  66. package/dist/{outline-DTZCJ7NR.js → outline-ZDNMKXZ6.js} +4 -4
  67. package/dist/{paddle-T6RK3QSQ.js → paddle-HCOOYW3F.js} +4 -4
  68. package/dist/{perplexity-MVT3DWR2.js → perplexity-2GJJPDA7.js} +4 -4
  69. package/dist/{pinecone-Z4IVTJMV.js → pinecone-ZPOBKL5T.js} +4 -4
  70. package/dist/{pipedrive-PM2PBDDZ.js → pipedrive-3WN2RFMB.js} +4 -4
  71. package/dist/{polar-CKXLVP45.js → polar-DJFGBTXW.js} +4 -4
  72. package/dist/{posthog-QTYLJI3S.js → posthog-G4OXNEXP.js} +4 -4
  73. package/dist/{postmark-V6QQYQ6X.js → postmark-NJMGDQKO.js} +4 -4
  74. package/dist/{prerender-SQAU4FDE.js → prerender-2TUPKRK5.js} +4 -4
  75. package/dist/{pubmed-6ZMRZYGK.js → pubmed-CCXZZT34.js} +4 -4
  76. package/dist/{railway-PJBDYQYM.js → railway-ZUUY5YYR.js} +4 -4
  77. package/dist/{readwise-KJAOWBS5.js → readwise-PYSRGJ4J.js} +4 -4
  78. package/dist/{render-Z2YG43ZD.js → render-SFA3EMGM.js} +4 -4
  79. package/dist/{replicate-AXMIH4OJ.js → replicate-KGZHYBPK.js} +4 -4
  80. package/dist/{resend-HQBXFMOO.js → resend-HENMZC5U.js} +4 -4
  81. package/dist/{rootly-CJW5SJEL.js → rootly-HV2PXIDP.js} +4 -4
  82. package/dist/{scrapfly-7APCZZ7V.js → scrapfly-FOZFHUN3.js} +4 -4
  83. package/dist/{scrapingbee-HTUP6YCA.js → scrapingbee-VHUMSO2J.js} +4 -4
  84. package/dist/{screenshot_fyi-N6JAOGFQ.js → screenshot_fyi-FFDXAKHD.js} +4 -4
  85. package/dist/{semantic_scholar-METX5XVW.js → semantic_scholar-GHO37BZF.js} +4 -4
  86. package/dist/{sentry-QM7OGZZK.js → sentry-MZVZW3YE.js} +4 -4
  87. package/dist/{shodan-ZPQCN5RX.js → shodan-IDICOPGU.js} +4 -4
  88. package/dist/{shopify-FPLQQJXS.js → shopify-WQLO23JO.js} +4 -4
  89. package/dist/{stripe-NNGIPJRH.js → stripe-XOAKLAKU.js} +4 -4
  90. package/dist/{supabase-HKIEC7JZ.js → supabase-6DKGSLST.js} +4 -4
  91. package/dist/{tavily-WMQVNVQC.js → tavily-76QZGEHM.js} +4 -4
  92. package/dist/{telegram-VP76Z774.js → telegram-O536CLFR.js} +4 -4
  93. package/dist/{telnyx-7BGNYZMU.js → telnyx-XOPYXF3K.js} +4 -4
  94. package/dist/{todoist-MXXO72IA.js → todoist-YXHVWPP3.js} +4 -4
  95. package/dist/{trello-7RFKIFYN.js → trello-WMTM3WA2.js} +4 -4
  96. package/dist/{turso-SVWKUF5Y.js → turso-CG7PR5HM.js} +4 -4
  97. package/dist/{twilio-WGXCKTR7.js → twilio-ZW4SD36D.js} +4 -4
  98. package/dist/{umami-2BB5YCC7.js → umami-IJQ5VH77.js} +4 -4
  99. package/dist/{unsplash-W7TX5OXX.js → unsplash-JBQY7NKO.js} +4 -4
  100. package/dist/{upstash_redis-YJEWXBBX.js → upstash_redis-2BAO776T.js} +4 -4
  101. package/dist/{uptimerobot-BP4BGPOL.js → uptimerobot-BRIHMPB3.js} +4 -4
  102. package/dist/{v2ex-Y2ENEEYQ.js → v2ex-HWIHF4HX.js} +4 -4
  103. package/dist/{vercel-6EB3NZZP.js → vercel-MGMRY2DJ.js} +4 -4
  104. package/dist/{wolfram_alpha_api-EF3CZMNC.js → wolfram_alpha_api-JG6JD33L.js} +4 -4
  105. package/dist/{wordpress-JI3YVGXG.js → wordpress-ZSYJERWV.js} +4 -4
  106. package/dist/{workos-YDK42RA3.js → workos-QFEOSJAN.js} +4 -4
  107. package/dist/{zhihu-CNFASBUW.js → zhihu-5RF7BBFV.js} +4 -4
  108. package/package.json +5 -5
@@ -2,15 +2,15 @@ import {
2
2
  createProviderPlugin,
3
3
  requireApiKey,
4
4
  upstreamError
5
- } from "./chunk-TKKRVFMK.js";
5
+ } from "./chunk-BUHY4IE6.js";
6
6
  import {
7
7
  guardedFetch
8
- } from "./chunk-CYTI7JDJ.js";
9
- import "./chunk-XE34TXY6.js";
8
+ } from "./chunk-EBO6Q4NR.js";
9
+ import "./chunk-GMHELPK3.js";
10
10
  import {
11
11
  TBError,
12
12
  external_exports
13
- } from "./chunk-F4O6ZRH7.js";
13
+ } from "./chunk-76YX7XSX.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
 
16
16
  // ../plugins/src/airtable/api.ts
@@ -2,15 +2,15 @@ import {
2
2
  createProviderPlugin,
3
3
  requireApiKey,
4
4
  upstreamError
5
- } from "./chunk-TKKRVFMK.js";
5
+ } from "./chunk-BUHY4IE6.js";
6
6
  import {
7
7
  guardedFetch
8
- } from "./chunk-CYTI7JDJ.js";
9
- import "./chunk-XE34TXY6.js";
8
+ } from "./chunk-EBO6Q4NR.js";
9
+ import "./chunk-GMHELPK3.js";
10
10
  import {
11
11
  TBError,
12
12
  external_exports
13
- } from "./chunk-F4O6ZRH7.js";
13
+ } from "./chunk-76YX7XSX.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
 
16
16
  // ../plugins/src/alt_text_generator_ai/schema.ts
@@ -2,15 +2,15 @@ import {
2
2
  createProviderPlugin,
3
3
  requireApiKey,
4
4
  upstreamError
5
- } from "./chunk-TKKRVFMK.js";
5
+ } from "./chunk-BUHY4IE6.js";
6
6
  import {
7
7
  guardedFetch
8
- } from "./chunk-CYTI7JDJ.js";
9
- import "./chunk-XE34TXY6.js";
8
+ } from "./chunk-EBO6Q4NR.js";
9
+ import "./chunk-GMHELPK3.js";
10
10
  import {
11
11
  TBError,
12
12
  external_exports
13
- } from "./chunk-F4O6ZRH7.js";
13
+ } from "./chunk-76YX7XSX.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
 
16
16
  // ../plugins/src/amap/api.ts
@@ -2,15 +2,15 @@ import {
2
2
  createProviderPlugin,
3
3
  requireApiKey,
4
4
  upstreamError
5
- } from "./chunk-TKKRVFMK.js";
5
+ } from "./chunk-BUHY4IE6.js";
6
6
  import {
7
7
  guardedFetch
8
- } from "./chunk-CYTI7JDJ.js";
9
- import "./chunk-XE34TXY6.js";
8
+ } from "./chunk-EBO6Q4NR.js";
9
+ import "./chunk-GMHELPK3.js";
10
10
  import {
11
11
  TBError,
12
12
  external_exports
13
- } from "./chunk-F4O6ZRH7.js";
13
+ } from "./chunk-76YX7XSX.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
 
16
16
  // ../plugins/src/anthropic/api.ts
@@ -2,15 +2,15 @@ import {
2
2
  createProviderPlugin,
3
3
  requireApiKey,
4
4
  upstreamError
5
- } from "./chunk-TKKRVFMK.js";
5
+ } from "./chunk-BUHY4IE6.js";
6
6
  import {
7
7
  guardedFetch
8
- } from "./chunk-CYTI7JDJ.js";
9
- import "./chunk-XE34TXY6.js";
8
+ } from "./chunk-EBO6Q4NR.js";
9
+ import "./chunk-GMHELPK3.js";
10
10
  import {
11
11
  TBError,
12
12
  external_exports
13
- } from "./chunk-F4O6ZRH7.js";
13
+ } from "./chunk-76YX7XSX.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
 
16
16
  // ../plugins/src/apify/api.ts
@@ -2,15 +2,15 @@ import {
2
2
  createProviderPlugin,
3
3
  requireApiKey,
4
4
  upstreamError
5
- } from "./chunk-TKKRVFMK.js";
5
+ } from "./chunk-BUHY4IE6.js";
6
6
  import {
7
7
  guardedFetch
8
- } from "./chunk-CYTI7JDJ.js";
9
- import "./chunk-XE34TXY6.js";
8
+ } from "./chunk-EBO6Q4NR.js";
9
+ import "./chunk-GMHELPK3.js";
10
10
  import {
11
11
  TBError,
12
12
  external_exports
13
- } from "./chunk-F4O6ZRH7.js";
13
+ } from "./chunk-76YX7XSX.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
 
16
16
  // ../plugins/src/brave_search/api.ts
@@ -15089,24 +15089,27 @@ function projectExportAuth(exported) {
15089
15089
  return { kind: "fields", fields: exported.credentialFields };
15090
15090
  }
15091
15091
  if (exported.auth?.kind === "none") return { kind: "none" };
15092
+ if (exported.auth?.kind !== "single") {
15093
+ throw new TBError(
15094
+ "invalid_argument",
15095
+ `catalog export '${exported.id}' \u5FC5\u987B\u663E\u5F0F\u58F0\u660E auth\u3001oauth \u6216 credentialFields`
15096
+ );
15097
+ }
15092
15098
  return {
15093
15099
  kind: "single",
15094
- // 兼容旧 descriptor:未显式声明 auth 时沿用“单值但可留空”。
15095
- required: exported.auth?.required ?? false,
15096
- ...exported.auth?.label !== void 0 ? { label: exported.auth.label } : {},
15097
- ...exported.auth?.description !== void 0 ? { description: exported.auth.description } : {}
15100
+ required: exported.auth.required ?? false,
15101
+ ...exported.auth.label !== void 0 ? { label: exported.auth.label } : {},
15102
+ ...exported.auth.description !== void 0 ? { description: exported.auth.description } : {}
15098
15103
  };
15099
15104
  }
15100
15105
  function projectListItem(entry) {
15101
15106
  const exports = entry.describe.exports;
15102
15107
  const kinds = /* @__PURE__ */ new Set();
15103
- const exportKinds = {};
15104
15108
  const exportDetails = {};
15105
15109
  for (const e of exports) {
15106
15110
  const kind = NODE_KIND_BY_PROFILE[e.profile];
15107
15111
  if (kind !== void 0) {
15108
15112
  kinds.add(kind);
15109
- exportKinds[e.id] = kind;
15110
15113
  exportDetails[e.id] = {
15111
15114
  id: e.id,
15112
15115
  kind,
@@ -15116,20 +15119,14 @@ function projectListItem(entry) {
15116
15119
  };
15117
15120
  }
15118
15121
  }
15119
- const withFields = exports.find((e) => e.credentialFields !== void 0);
15120
- const withMountConfig = exports.find((e) => e.mountConfigFields !== void 0);
15121
15122
  const description = exports.find((e) => e.description !== void 0)?.description;
15122
15123
  return {
15123
15124
  id: entry.id,
15124
15125
  digest: entry.digest,
15125
15126
  exports: exports.map((e) => e.id),
15126
- exportKinds,
15127
15127
  exportDetails,
15128
15128
  nodeKinds: [...kinds].sort(),
15129
- needsOAuth: exports.some((e) => e.oauth !== void 0),
15130
- ...description !== void 0 ? { description } : {},
15131
- ...withFields?.credentialFields !== void 0 ? { credentialFields: withFields.credentialFields } : {},
15132
- ...withMountConfig?.mountConfigFields !== void 0 ? { mountConfigFields: withMountConfig.mountConfigFields } : {}
15129
+ ...description !== void 0 ? { description } : {}
15133
15130
  };
15134
15131
  }
15135
15132
  function matches2(item, query) {
@@ -15145,7 +15142,7 @@ function catalogCmds(nodePath) {
15145
15142
  path,
15146
15143
  h: "list built-in integrations available on this host (no credentials, read scope)",
15147
15144
  inputSchema: { type: "object", properties: { opts: LIST_OPTS_SCHEMA } },
15148
- returns: "Page<CatalogListItem> \u2014 id, exports, nodeKinds, credential field names",
15145
+ returns: "Page<CatalogListItem> \u2014 id, exports, nodeKinds, exportDetails",
15149
15146
  scope: "read"
15150
15147
  },
15151
15148
  {
@@ -15505,6 +15502,12 @@ function validatePluginContract(input) {
15505
15502
  throw new TBError("invalid_argument", `plugin '${manifest.id}' \u7684 export id \u91CD\u590D:'${exported.id}'`);
15506
15503
  }
15507
15504
  seen.add(exported.id);
15505
+ if (exported.auth === void 0 && exported.oauth === void 0 && exported.credentialFields === void 0) {
15506
+ throw new TBError(
15507
+ "invalid_argument",
15508
+ `plugin '${manifest.id}' export '${exported.id}' \u5FC5\u987B\u663E\u5F0F\u58F0\u660E auth\u3001oauth \u6216 credentialFields`
15509
+ );
15510
+ }
15508
15511
  if (exported.auth !== void 0) {
15509
15512
  if (exported.oauth !== void 0 || exported.credentialFields !== void 0) {
15510
15513
  throw new TBError(
@@ -15671,14 +15674,14 @@ var authSchema = external_exports.discriminatedUnion("kind", [
15671
15674
  ]);
15672
15675
  var manifestSchema = external_exports.object({
15673
15676
  id: external_exports.string().regex(ID_RE, "id \u987B\u4E3A path-segment \u5B89\u5168\u5B57\u7B26([A-Za-z0-9._-],\u4E0D\u4EE5\u6807\u70B9\u5F00\u5934)"),
15674
- protocolVersion: external_exports.string().default(PLUGIN_PROTOCOL_VERSION).refine((v) => v === PLUGIN_PROTOCOL_VERSION, {
15677
+ protocolVersion: external_exports.string().refine((v) => v === PLUGIN_PROTOCOL_VERSION, {
15675
15678
  error: `protocolVersion \u987B\u4E3A '${PLUGIN_PROTOCOL_VERSION}'`
15676
15679
  }),
15677
15680
  endpoint: external_exports.string().min(1),
15678
15681
  auth: authSchema,
15679
15682
  healthPath: external_exports.string().regex(/^\//, "healthPath \u987B\u4EE5 '/' \u5F00\u5934"),
15680
15683
  enabled: external_exports.boolean()
15681
- });
15684
+ }).strict();
15682
15685
  function parsePluginManifest(value, opts = {}) {
15683
15686
  const parsed = manifestSchema.safeParse(value);
15684
15687
  if (!parsed.success) {
@@ -15796,15 +15799,6 @@ function pluginCmds(nodePath) {
15796
15799
  inputSchema: idSchema2,
15797
15800
  returns: "{ id, healthy, checkedAt }",
15798
15801
  scope: "admin"
15799
- },
15800
- {
15801
- name: "catalog",
15802
- method: "POST",
15803
- path,
15804
- h: "list in-process plugins assembled by this host (available, not yet activated); register one via write with its endpoint value",
15805
- inputSchema: { type: "object", properties: {} },
15806
- returns: "{ items: Array<{ name, endpoint, registered, pluginId? }> }",
15807
- scope: "admin"
15808
15802
  }
15809
15803
  ];
15810
15804
  }
@@ -15824,10 +15818,14 @@ function createPluginModule(deps) {
15824
15818
  }
15825
15819
  async function view(record2) {
15826
15820
  const describe3 = await store.get(KEY_PLUGIN_META + record2.id);
15827
- return {
15828
- ...projectManifest(record2),
15829
- ...describe3?.exports !== void 0 ? { exports: describe3.exports } : {}
15830
- };
15821
+ if (describe3 === null) {
15822
+ throw new TBError(
15823
+ "unavailable",
15824
+ `plugin '${record2.id}' \u7F3A\u5C11 ~describe \u7F13\u5B58,\u8BF7\u91CD\u65B0\u6CE8\u518C`,
15825
+ { retryable: false }
15826
+ );
15827
+ }
15828
+ return { ...projectManifest(record2), exports: describe3.exports };
15831
15829
  }
15832
15830
  async function revokeToken(record2) {
15833
15831
  if (record2.tokenSkId !== void 0) await sk.delete(record2.tokenSkId);
@@ -15991,33 +15989,6 @@ function createPluginModule(deps) {
15991
15989
  const record2 = await probeAndRecord(manifest);
15992
15990
  return { id, healthy: record2.healthy, checkedAt: record2.checkedAt };
15993
15991
  }
15994
- case "catalog": {
15995
- const names = deps.bindings?.() ?? [];
15996
- const byEndpoint = /* @__PURE__ */ new Map();
15997
- let cursor;
15998
- do {
15999
- const page = await store.list(KEY_PLUGIN, {
16000
- limit: LIST_LIMIT_MAX,
16001
- ...cursor !== void 0 ? { cursor } : {}
16002
- });
16003
- for (const { value } of page.items) {
16004
- const record2 = value;
16005
- byEndpoint.set(record2.endpoint, record2.id);
16006
- }
16007
- cursor = page.cursor;
16008
- } while (cursor !== void 0);
16009
- const items = [...names].sort().map((name) => {
16010
- const endpoint = `binding:${name}`;
16011
- const pluginId = byEndpoint.get(endpoint);
16012
- return {
16013
- name,
16014
- endpoint,
16015
- registered: pluginId !== void 0,
16016
- ...pluginId !== void 0 ? { pluginId } : {}
16017
- };
16018
- });
16019
- return { items };
16020
- }
16021
15992
  default:
16022
15993
  throw new TBError("invalid_argument", `unknown cmd '${cmd}' on system/plugin`);
16023
15994
  }
@@ -17284,6 +17255,7 @@ var deviceNodeCmdSchema = external_exports.object({
17284
17255
  name: external_exports.string().min(1),
17285
17256
  description: external_exports.string().optional(),
17286
17257
  inputSchema: external_exports.unknown().optional(),
17258
+ outputSchema: external_exports.unknown().optional(),
17287
17259
  effect: external_exports.string().optional(),
17288
17260
  confirm: external_exports.boolean().optional()
17289
17261
  }).passthrough();
@@ -17305,6 +17277,16 @@ var deviceExposeSchema = external_exports.object({
17305
17277
  nodes: external_exports.array(nodeInputSchema).optional()
17306
17278
  });
17307
17279
  var idSchema = external_exports.string().min(1);
17280
+ var deviceCallContextSchema = external_exports.object({
17281
+ caller: external_exports.object({
17282
+ keyId: external_exports.string().min(1),
17283
+ owner: external_exports.string().min(1),
17284
+ displayName: external_exports.string().optional()
17285
+ }).passthrough(),
17286
+ traceId: external_exports.string().min(1),
17287
+ createdAt: external_exports.string().min(1),
17288
+ expiresAt: external_exports.string().min(1)
17289
+ }).passthrough();
17308
17290
  var schemaByType = {
17309
17291
  hello: external_exports.object({
17310
17292
  type: external_exports.literal("hello"),
@@ -17319,7 +17301,8 @@ var schemaByType = {
17319
17301
  id: idSchema,
17320
17302
  path: external_exports.string(),
17321
17303
  tool: external_exports.string().min(1),
17322
- arguments: external_exports.record(external_exports.string(), external_exports.unknown())
17304
+ arguments: external_exports.record(external_exports.string(), external_exports.unknown()),
17305
+ context: deviceCallContextSchema.optional()
17323
17306
  }),
17324
17307
  result: external_exports.discriminatedUnion("ok", [
17325
17308
  external_exports.object({ type: external_exports.literal("result"), id: idSchema, ok: external_exports.literal(true), value: external_exports.unknown() }),
@@ -17414,13 +17397,33 @@ function deviceDirectoryHelpModel(node, children = []) {
17414
17397
  node: {
17415
17398
  path: node.path,
17416
17399
  kind: "directory",
17417
- description: `${node.description} (${node.online ? "online" : "offline"})`
17400
+ description: `${node.description} (${node.presence.state})`
17418
17401
  },
17419
17402
  cmds: [],
17420
17403
  children
17421
17404
  };
17422
17405
  }
17423
17406
 
17407
+ // ../core/src/device/presence.ts
17408
+ var PRESENCE_STALE_AFTER_MS = 9e4;
17409
+ function derivePresence(input) {
17410
+ const lastSeenAt = input.lastSeenAt;
17411
+ const base = lastSeenAt !== void 0 ? { lastSeenAt } : {};
17412
+ if (input.online !== true) {
17413
+ return { state: "offline", ...base };
17414
+ }
17415
+ if (lastSeenAt === void 0) {
17416
+ return { state: "stale", ...base };
17417
+ }
17418
+ const seenMs = Date.parse(lastSeenAt);
17419
+ const nowMs = Date.parse(input.now);
17420
+ if (!Number.isFinite(seenMs) || !Number.isFinite(nowMs)) {
17421
+ return { state: "stale", ...base };
17422
+ }
17423
+ const ttl = input.staleAfterMs ?? PRESENCE_STALE_AFTER_MS;
17424
+ return { state: nowMs - seenMs <= ttl ? "online" : "stale", ...base };
17425
+ }
17426
+
17424
17427
  // ../core/src/device/session.ts
17425
17428
  var DEVICE_CALL_TIMEOUT_MS = 6e4;
17426
17429
  var DEVICE_REJECT_CLOSE_CODE = 1008;
@@ -17528,7 +17531,9 @@ var DeviceGatewaySession = class {
17528
17531
  id: req.id,
17529
17532
  path: req.path,
17530
17533
  tool: req.tool,
17531
- arguments: req.arguments
17534
+ arguments: req.arguments,
17535
+ // undefined 经 JSON.stringify 丢弃:老网关不带 context 时帧形状不变。
17536
+ ...req.context !== void 0 ? { context: req.context } : {}
17532
17537
  });
17533
17538
  }
17534
17539
  /** 幂等表回放种子(DO 从 ctx.storage 恢复时用);已有同 id 结果则忽略。 */
@@ -18028,7 +18033,7 @@ async function buildTree(opts) {
18028
18033
  visited.add(entry.path);
18029
18034
  count++;
18030
18035
  const node = { path: entry.path, kind: entry.kind, description: entry.description };
18031
- if (entry.online !== void 0) node.online = entry.online;
18036
+ if (entry.presence !== void 0) node.presence = entry.presence;
18032
18037
  if (depthLeft <= 0) {
18033
18038
  if (opts.opaqueKinds?.has(entry.kind)) {
18034
18039
  node.truncated = true;
@@ -18052,7 +18057,7 @@ async function buildTree(opts) {
18052
18057
  description: kid.description,
18053
18058
  truncated: true
18054
18059
  };
18055
- if (kid.online !== void 0) cyc.online = kid.online;
18060
+ if (kid.presence !== void 0) cyc.presence = kid.presence;
18056
18061
  count++;
18057
18062
  children.push(cyc);
18058
18063
  continue;
@@ -18247,8 +18252,7 @@ async function resolveExternalExport(store, id, nodeKind, what, exportId) {
18247
18252
  }
18248
18253
  async function resolveIntegration(store, catalog, id, nodeKind, what, exportId) {
18249
18254
  const manifest = await store.get(KEY_PLUGIN + id);
18250
- const isBinding = manifest?.endpoint.startsWith("binding:") === true;
18251
- if (manifest !== null && !(isBinding && catalog[id] !== void 0)) {
18255
+ if (manifest !== null) {
18252
18256
  return await resolveExternalExport(store, id, nodeKind, what, exportId);
18253
18257
  }
18254
18258
  return resolveBuiltinExport(catalog, id, nodeKind, what, exportId);
@@ -18424,25 +18428,6 @@ function decodePluginCall(body) {
18424
18428
  return parsed.data;
18425
18429
  }
18426
18430
 
18427
- // ../core/src/plugin/package.ts
18428
- var PLUGIN_BUNDLE_MAX_BYTES = 5 * 1024 * 1024;
18429
- var NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
18430
- var SHA256_HEX_RE = /^[0-9a-f]{64}$/;
18431
- var VERSION_RE = /^\d+\.\d+\.\d+(?:[-+.][A-Za-z0-9.-]+)?$/;
18432
- var packageSchema = external_exports.object({
18433
- name: external_exports.string().regex(NAME_RE, "name \u987B\u4E3A path-segment \u5B89\u5168\u5B57\u7B26([A-Za-z0-9._-],\u4E0D\u4EE5\u6807\u70B9\u5F00\u5934)"),
18434
- version: external_exports.string().regex(VERSION_RE, "version \u987B\u4E3A semver(\u5982 1.2.3)"),
18435
- bundleUrl: external_exports.string().min(1),
18436
- sha256: external_exports.string().regex(SHA256_HEX_RE, "sha256 \u987B\u4E3A 64 \u4F4D hex \u5C0F\u5199"),
18437
- protocolVersion: external_exports.string().default(PLUGIN_PROTOCOL_VERSION).refine((v) => v === PLUGIN_PROTOCOL_VERSION, {
18438
- error: `protocolVersion \u987B\u4E3A '${PLUGIN_PROTOCOL_VERSION}'`
18439
- }),
18440
- healthPath: external_exports.string().regex(/^\//, "healthPath \u987B\u4EE5 '/' \u5F00\u5934"),
18441
- description: external_exports.string().optional(),
18442
- configSchema: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
18443
- mountConfigSchema: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
18444
- });
18445
-
18446
18431
  // ../core/src/search/shortTermSql.ts
18447
18432
  function shortTermsSql(patterns) {
18448
18433
  return `short_terms(pattern) AS (VALUES ${patterns.map(() => "(?)").join(", ")})`;
@@ -19962,6 +19947,7 @@ var NodeRegistryStore = class {
19962
19947
  ...node.config !== void 0 ? { config: node.config } : {},
19963
19948
  ...node.virtualize !== void 0 ? { virtualize: node.virtualize } : {},
19964
19949
  ...opts.online !== void 0 ? { online: opts.online } : {},
19950
+ ...opts.lastSeenAt !== void 0 ? { lastSeenAt: opts.lastSeenAt } : {},
19965
19951
  registeredBy,
19966
19952
  createdAt: existing?.createdAt ?? now,
19967
19953
  updatedAt: now
@@ -19990,15 +19976,34 @@ var NodeRegistryStore = class {
19990
19976
  await this.store.put(this.keyOf(norm), merged);
19991
19977
  return merged;
19992
19978
  }
19993
- /** 设备生命周期专用:只更新节点 online 状态,不存在 → not_found。 */
19979
+ /**
19980
+ * 设备生命周期专用:更新节点 online 状态,不存在 → not_found。
19981
+ * online 翻 true 时视为一次存活观察,同步把 `lastSeenAt` 刷到 now;翻 false 时保留原
19982
+ * `lastSeenAt`(用于展示"最后在线于")。
19983
+ */
19994
19984
  async setOnline(path, online, now) {
19995
19985
  const norm = normalizePath(path);
19996
19986
  const existing = await this.read(norm);
19997
19987
  if (!existing) throw new TBError("not_found", `\u8282\u70B9\u4E0D\u5B58\u5728:'${norm}'`);
19998
- const updated = { ...existing, online, updatedAt: now };
19988
+ const updated = {
19989
+ ...existing,
19990
+ online,
19991
+ ...online ? { lastSeenAt: now } : {},
19992
+ updatedAt: now
19993
+ };
19999
19994
  await this.store.put(this.keyOf(norm), updated);
20000
19995
  return updated;
20001
19996
  }
19997
+ /**
19998
+ * 设备心跳专用:只把 `lastSeenAt` 刷到 now,不改 online 也不动 updatedAt(心跳不是元数据变更,
19999
+ * 不该扰动 updatedAt 的语义)。节点不存在时静默返回——心跳晚于节点删除是正常竞态,不报错。
20000
+ */
20001
+ async touchSeen(path, now) {
20002
+ const norm = normalizePath(path);
20003
+ const existing = await this.read(norm);
20004
+ if (!existing) return;
20005
+ await this.store.put(this.keyOf(norm), { ...existing, lastSeenAt: now });
20006
+ }
20002
20007
  /**
20003
20008
  * 卸载;不存在 → not_found。删除后自底向上级联回收:
20004
20009
  * 仅回收 registeredBy=system:auto 且再无子节点的 directory,遇显式节点/仍有子节点即停。
@@ -20137,6 +20142,8 @@ export {
20137
20142
  deviceShellHelpModel,
20138
20143
  deviceFsHelpModel,
20139
20144
  deviceDirectoryHelpModel,
20145
+ derivePresence,
20146
+ DEVICE_CALL_TIMEOUT_MS,
20140
20147
  DeviceGatewaySession,
20141
20148
  FEEDBACK_HIDE_SCORE,
20142
20149
  selectFeedbackSearchText,