@tool-bridge/server 0.21.1 → 0.22.1

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 (178) hide show
  1. package/dist/admin.js +170 -0
  2. package/dist/airtable-ML2GIGCH.js +790 -0
  3. package/dist/{alt_text_generator_ai-W7O34SNG.js → alt_text_generator_ai-FGYQAF2A.js} +12 -11
  4. package/dist/{amap-VOX4T2AW.js → amap-G7V65NGK.js} +221 -220
  5. package/dist/anthropic-6ZK24TBB.js +203 -0
  6. package/dist/apify-VDGYHP6W.js +248 -0
  7. package/dist/brave_search-TAATLZOS.js +302 -0
  8. package/dist/chunk-2IAI3XQM.js +302 -0
  9. package/dist/chunk-7ISGFRC6.js +161 -0
  10. package/dist/{chunk-E6JCVKW6.js → chunk-BNMLA2RC.js} +3 -3
  11. package/dist/chunk-HA4BGL6C.js +8429 -0
  12. package/dist/{chunk-KMTT3I6D.js → chunk-RMAWSG7E.js} +19172 -25717
  13. package/dist/{chunk-XYBU3WZH.js → chunk-RTW5VRTK.js} +3 -3
  14. package/dist/chunk-U7PTOA3U.js +7320 -0
  15. package/dist/chunk-UY6ANCOY.js +378 -0
  16. package/dist/{chunk-ATK45BXV.js → chunk-X7ZUTKHR.js} +4 -2
  17. package/dist/circleci-BQ2UWXL2.js +389 -0
  18. package/dist/clerk-2JYWQNOI.js +1019 -0
  19. package/dist/cohere-6MI7AQM4.js +185 -0
  20. package/dist/{confluence-B3EWPZVE.js → confluence-6Y6GDETF.js} +105 -104
  21. package/dist/{convertapi-EUWSQYPF.js → convertapi-HBZCSWOX.js} +32 -31
  22. package/dist/{currencyapi-KVTIK3GL.js → currencyapi-337U5TGI.js} +71 -71
  23. package/dist/deepseek-OSPASO7O.js +210 -0
  24. package/dist/docker_hub-3ATQOY5L.js +933 -0
  25. package/dist/dropbox-LSA4GM2Y.js +1305 -0
  26. package/dist/dub-VZPJSPI6.js +680 -0
  27. package/dist/e2b-6SDYQZL2.js +278 -0
  28. package/dist/exa-B6EUYDVP.js +332 -0
  29. package/dist/{fal_ai-23E7JPNT.js → fal_ai-K4Q27IME.js} +81 -80
  30. package/dist/{feishu-7QRIDUV6.js → feishu-4TKXG4SU.js} +528 -572
  31. package/dist/{feishu_custom_bot-TJ4K7QNJ.js → feishu_custom_bot-7CTEAKRB.js} +57 -53
  32. package/dist/figma-OUKSZLD5.js +777 -0
  33. package/dist/firehydrant-7MOYL7QH.js +563 -0
  34. package/dist/{fixer-BWON27UO.js → fixer-H2BV2NO4.js} +34 -33
  35. package/dist/fly-PXKY6PNH.js +469 -0
  36. package/dist/{front-QCGXYEDJ.js → front-UZYIV5DW.js} +104 -104
  37. package/dist/geocodio-NSYO7TFP.js +213 -0
  38. package/dist/ghost-QBKKQQMF.js +338 -0
  39. package/dist/github-ENLSJ4CL.js +5421 -0
  40. package/dist/gmail-KQSDEB47.js +1887 -0
  41. package/dist/googlecalendar-5YCX4SZF.js +2524 -0
  42. package/dist/{googledocs-BUHL4J2H.js → googledocs-SSWIVFKA.js} +341 -340
  43. package/dist/{grafana-GLU2DWF2.js → grafana-TF2LXDQA.js} +221 -220
  44. package/dist/graphhopper-CURBVHYK.js +325 -0
  45. package/dist/index.d.ts +1132 -332
  46. package/dist/index.js +31 -14
  47. package/dist/{ip2proxy-EZ64Y4ZH.js → ip2proxy-YNVMTZEM.js} +28 -27
  48. package/dist/ipgeolocation_io-NAU7VJ4J.js +315 -0
  49. package/dist/ipqualityscore-OT63L4TI.js +279 -0
  50. package/dist/{jina_ai-EFBHTBXL.js → jina_ai-6WBMBGWM.js} +23 -23
  51. package/dist/{jira-HQSHAA5K.js → jira-DVDVTHNO.js} +118 -117
  52. package/dist/langsmith-IM5N4YAU.js +593 -0
  53. package/dist/lemlist-277SHUQF.js +289 -0
  54. package/dist/{linear-K7RYFYAD.js → linear-AEPH7B5V.js} +327 -326
  55. package/dist/logsnag-VEWRAGBG.js +150 -0
  56. package/dist/main.js +57 -280
  57. package/dist/{mattermost-S2BRCWLQ.js → mattermost-Q3A2BIZA.js} +59 -58
  58. package/dist/mem0-AXS7GZGI.js +544 -0
  59. package/dist/memos-7TXG4ZTU.js +744 -0
  60. package/dist/{metabase-MMSEPCOF.js → metabase-NSVACWQM.js} +90 -89
  61. package/dist/mistral_ai-YZ52RGD4.js +1196 -0
  62. package/dist/{mother_duck-H7PCQNZ2.js → mother_duck-XLLL6FVL.js} +94 -93
  63. package/dist/ngrok-4O4W3WZW.js +356 -0
  64. package/dist/{notes-PFMKRO33.js → notes-YTB3TJOO.js} +11 -9
  65. package/dist/notion-4W4O7J7V.js +940 -0
  66. package/dist/open_exchange_rates-23QJXVO5.js +215 -0
  67. package/dist/openai-ZS7GLSLH.js +800 -0
  68. package/dist/opengraph_io-PMVH7OYI.js +362 -0
  69. package/dist/openrouter-ONRGFNB6.js +441 -0
  70. package/dist/outline-UCUYZZ7J.js +599 -0
  71. package/dist/paddle-35HTKTUL.js +454 -0
  72. package/dist/perplexity-NVOBYN24.js +220 -0
  73. package/dist/pinecone-55CJY73C.js +571 -0
  74. package/dist/{pipedrive-Y2O7QGFF.js → pipedrive-WMCAKS72.js} +99 -98
  75. package/dist/polar-SM4ZM53B.js +395 -0
  76. package/dist/posthog-NWCXVXNJ.js +3464 -0
  77. package/dist/postmark-QJV5PHUQ.js +427 -0
  78. package/dist/{prerender-MENYM2TY.js → prerender-2W7UT4SC.js} +31 -30
  79. package/dist/{pubmed-GOXUVVH5.js → pubmed-VVV7XYLU.js} +239 -238
  80. package/dist/{railway-V2SID4WV.js → railway-KGI57S3O.js} +118 -117
  81. package/dist/readwise-AGHTQB42.js +470 -0
  82. package/dist/render-O4HBROCK.js +461 -0
  83. package/dist/{replicate-756MXPYX.js → replicate-KWBOMX7D.js} +81 -80
  84. package/dist/{resend-ZKH3BTBI.js → resend-DRH6Y6I4.js} +20 -16
  85. package/dist/rootly-XGCUDW6X.js +336 -0
  86. package/dist/{scrapfly-NSRHFDIQ.js → scrapfly-OIQ3OY6L.js} +62 -61
  87. package/dist/{scrapingbee-OQHLAVEY.js → scrapingbee-OCZO4FHX.js} +56 -56
  88. package/dist/{screenshot_fyi-DVWG3AXC.js → screenshot_fyi-CUNGFZOC.js} +16 -16
  89. package/dist/semantic_scholar-3UJRLKES.js +611 -0
  90. package/dist/{sentry-546MNDJG.js → sentry-5BWVZFJV.js} +208 -207
  91. package/dist/{shodan-C3OON3Z3.js → shodan-HI37CTEW.js} +62 -61
  92. package/dist/shopify-LJ2EV2HH.js +610 -0
  93. package/dist/stripe-3LHMV55K.js +585 -0
  94. package/dist/{supabase-U2SL4D63.js → supabase-H2KPX3Q2.js} +245 -244
  95. package/dist/tavily-FBEWGH3Z.js +326 -0
  96. package/dist/telegram-MYYO3JND.js +1767 -0
  97. package/dist/{telnyx-CXQ4EZUX.js → telnyx-H4ALEGAX.js} +57 -56
  98. package/dist/todoist-OBWICA5Q.js +664 -0
  99. package/dist/trello-GUFUJRWO.js +1080 -0
  100. package/dist/turso-NIAK4UMS.js +416 -0
  101. package/dist/{twilio-4PDBJKWX.js → twilio-K6SLK2CX.js} +70 -69
  102. package/dist/umami-42RS2EPS.js +389 -0
  103. package/dist/unsplash-V7TOTETT.js +351 -0
  104. package/dist/{upstash_redis-G4LQBYHA.js → upstash_redis-AWQMB6Y3.js} +51 -50
  105. package/dist/uptimerobot-AZC2DHOT.js +483 -0
  106. package/dist/v2ex-4TVRNMLS.js +667 -0
  107. package/dist/vercel-DPHTJ3XR.js +1076 -0
  108. package/dist/{wolfram_alpha_api-3G4PUJWB.js → wolfram_alpha_api-XAG7IXBW.js} +36 -35
  109. package/dist/wordpress-KMPKVGUX.js +812 -0
  110. package/dist/workos-PKB2YR7S.js +664 -0
  111. package/dist/zhihu-Y4H4XYPB.js +254 -0
  112. package/package.json +18 -9
  113. package/dist/airtable-LLZDFN7M.js +0 -789
  114. package/dist/anthropic-G23NN3X5.js +0 -202
  115. package/dist/apify-Y3SS734K.js +0 -247
  116. package/dist/brave_search-ZC7OAPSZ.js +0 -301
  117. package/dist/chunk-R6P4XAE5.js +0 -248
  118. package/dist/chunk-U7B6DS2O.js +0 -977
  119. package/dist/chunk-UZM2RXZH.js +0 -23436
  120. package/dist/circleci-3BAX5FCG.js +0 -388
  121. package/dist/clerk-6LEM6TNU.js +0 -1019
  122. package/dist/cloudflare_dns-KINYTJUD.js +0 -588
  123. package/dist/cohere-XCJ5AJ6B.js +0 -185
  124. package/dist/deepseek-PC5YGNC5.js +0 -209
  125. package/dist/docker_hub-C3MA5FU6.js +0 -932
  126. package/dist/dropbox-XBV7Z2IR.js +0 -1304
  127. package/dist/dub-LDOFG3HC.js +0 -679
  128. package/dist/e2b-JMCPSVBW.js +0 -277
  129. package/dist/exa-RAK7O7RD.js +0 -331
  130. package/dist/figma-E6IX5DTH.js +0 -773
  131. package/dist/firehydrant-ZBLPQREE.js +0 -562
  132. package/dist/fly-ZH3HFCZJ.js +0 -468
  133. package/dist/geocodio-YGNI7DA4.js +0 -212
  134. package/dist/ghost-EVSGKH2Q.js +0 -337
  135. package/dist/github-MA2BGRCJ.js +0 -5420
  136. package/dist/gmail-E5E6AADE.js +0 -1886
  137. package/dist/googlecalendar-BTLFPXTD.js +0 -2523
  138. package/dist/graphhopper-WSMB3TCD.js +0 -324
  139. package/dist/ipgeolocation_io-AA7HAS22.js +0 -315
  140. package/dist/ipqualityscore-BHJXVTJT.js +0 -277
  141. package/dist/langsmith-5W6SCT6F.js +0 -592
  142. package/dist/lemlist-HJWH6UMK.js +0 -288
  143. package/dist/logsnag-4KFOHL37.js +0 -150
  144. package/dist/mem0-CAW43CIC.js +0 -543
  145. package/dist/memos-TWEGPKFM.js +0 -740
  146. package/dist/mistral_ai-64BGZQHP.js +0 -1195
  147. package/dist/ngrok-GQCUGZKJ.js +0 -356
  148. package/dist/notion-DQWZWP4N.js +0 -936
  149. package/dist/open_exchange_rates-QMMD735E.js +0 -214
  150. package/dist/openai-W6PX32NZ.js +0 -799
  151. package/dist/opengraph_io-HNDBXYNW.js +0 -361
  152. package/dist/openrouter-JJYMEAUL.js +0 -437
  153. package/dist/outline-MCBNQZYY.js +0 -595
  154. package/dist/paddle-D2SKLUDN.js +0 -453
  155. package/dist/perplexity-XIFMKUAE.js +0 -219
  156. package/dist/pinecone-HUFTALV2.js +0 -570
  157. package/dist/polar-TYTOMOSR.js +0 -394
  158. package/dist/posthog-43JAR3VW.js +0 -3463
  159. package/dist/postmark-KL2QJYSG.js +0 -426
  160. package/dist/readwise-CI4GIMMJ.js +0 -469
  161. package/dist/render-SUBJ6YRZ.js +0 -460
  162. package/dist/rootly-CD2LJHPI.js +0 -336
  163. package/dist/semantic_scholar-T4A252KW.js +0 -610
  164. package/dist/shopify-Y2HN2MCQ.js +0 -609
  165. package/dist/stripe-VE3CD3AY.js +0 -584
  166. package/dist/tavily-KCZHK6HE.js +0 -326
  167. package/dist/telegram-3URFBCMY.js +0 -1766
  168. package/dist/todoist-HNPWNYTD.js +0 -663
  169. package/dist/trello-3W2MIXRP.js +0 -1079
  170. package/dist/turso-2EQF7C2Z.js +0 -415
  171. package/dist/umami-5REN7TGP.js +0 -388
  172. package/dist/unsplash-EIXL424F.js +0 -350
  173. package/dist/uptimerobot-KNJ3EYLY.js +0 -482
  174. package/dist/v2ex-RHJ234PZ.js +0 -666
  175. package/dist/vercel-AS6NCIC7.js +0 -1075
  176. package/dist/wordpress-KNDAAUV7.js +0 -811
  177. package/dist/workos-R6UITSJ7.js +0 -663
  178. package/dist/zhihu-AGK4HILK.js +0 -253
@@ -0,0 +1,302 @@
1
+ import {
2
+ createAuthedClient
3
+ } from "./chunk-RTW5VRTK.js";
4
+ import "./chunk-BNMLA2RC.js";
5
+ import {
6
+ asJsonObject,
7
+ compactDefined,
8
+ trimmedText
9
+ } from "./chunk-JXHMDBAY.js";
10
+ import {
11
+ createProviderPlugin,
12
+ upstreamError
13
+ } from "./chunk-X7ZUTKHR.js";
14
+ import "./chunk-7ISGFRC6.js";
15
+ import "./chunk-UY6ANCOY.js";
16
+ import {
17
+ TBError
18
+ } from "./chunk-HA4BGL6C.js";
19
+ import "./chunk-U67V476Y.js";
20
+
21
+ // ../plugins/src/brave_search/api.ts
22
+ var SERVICE = "brave_search";
23
+ var API_BASE = "https://api.search.brave.com";
24
+ var RATE_LIMIT_CODES = /* @__PURE__ */ new Set(["QUOTA_LIMITED", "RATE_LIMITED", "USAGE_LIMIT_EXCEEDED"]);
25
+ var AUTH_CODES = /* @__PURE__ */ new Set(["SUBSCRIPTION_TOKEN_INVALID", "SUBSCRIPTION_NOT_FOUND"]);
26
+ var INVALID_CODES = /* @__PURE__ */ new Set(["RESOURCE_NOT_ALLOWED", "OPTION_NOT_IN_PLAN", "INVALID_URL"]);
27
+ function nullableRecord(value) {
28
+ return value === null ? null : asJsonObject(value);
29
+ }
30
+ function requireRecord(value, label) {
31
+ const result = asJsonObject(value);
32
+ if (result === void 0) {
33
+ throw new TBError("unavailable", `${label}\u4E0D\u662F\u5BF9\u8C61`, { retryable: true });
34
+ }
35
+ return result;
36
+ }
37
+ function objectArray(value) {
38
+ if (!Array.isArray(value)) return void 0;
39
+ return value.map((item) => requireRecord(item, "Brave Search \u7ED3\u679C\u9879"));
40
+ }
41
+ function searchTerm(value) {
42
+ const term = trimmedText(value);
43
+ if (term === void 0) throw new TBError("invalid_argument", "q \u4E0D\u80FD\u662F\u7A7A\u767D");
44
+ return term;
45
+ }
46
+ function goggles(value) {
47
+ if (value === void 0 || typeof value === "string") return trimmedText(value);
48
+ const items = value.map((item) => trimmedText(item)).filter((item) => item !== void 0);
49
+ return items.length > 0 ? items : void 0;
50
+ }
51
+ function braveSearchError(status, payload) {
52
+ const error = asJsonObject(asJsonObject(payload)?.error);
53
+ const message = trimmedText(error?.detail) ?? trimmedText(error?.code) ?? `Brave Search \u8FD4\u56DE HTTP ${status}`;
54
+ const code = trimmedText(error?.code);
55
+ if (code !== void 0) {
56
+ if (RATE_LIMIT_CODES.has(code)) return upstreamError(429, message);
57
+ if (AUTH_CODES.has(code)) return upstreamError(401, message);
58
+ if (INVALID_CODES.has(code)) return upstreamError(400, message);
59
+ }
60
+ return upstreamError(status, message);
61
+ }
62
+ var http = createAuthedClient({
63
+ baseUrl: `${API_BASE}/`,
64
+ service: SERVICE,
65
+ auth: { kind: "header", name: "x-subscription-token" },
66
+ headers: { accept: "application/json" },
67
+ // 稳定错误码码表比 HTTP 状态准,整段覆写而不用标准键序提取。
68
+ mapError: ({ data: payload, status }) => braveSearchError(status, payload)
69
+ });
70
+ async function request(ctx, path, query) {
71
+ const { data } = await http.request(ctx, {
72
+ path,
73
+ method: "GET",
74
+ query: Object.entries(query),
75
+ invalidJsonMessage: "Brave Search \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94"
76
+ });
77
+ return data ?? null;
78
+ }
79
+ function normalizeWebSearch(payload) {
80
+ const result = requireRecord(payload, "Brave Search \u54CD\u5E94");
81
+ return compactDefined({
82
+ type: trimmedText(result.type) ?? "search",
83
+ query: nullableRecord(result.query),
84
+ web: nullableRecord(result.web),
85
+ news: nullableRecord(result.news),
86
+ videos: nullableRecord(result.videos),
87
+ locations: nullableRecord(result.locations),
88
+ discussions: nullableRecord(result.discussions),
89
+ faq: nullableRecord(result.faq),
90
+ infobox: nullableRecord(result.infobox),
91
+ mixed: nullableRecord(result.mixed),
92
+ summarizer: nullableRecord(result.summarizer),
93
+ rich: nullableRecord(result.rich)
94
+ });
95
+ }
96
+ function normalizeCollection(payload, withExtra) {
97
+ const result = requireRecord(payload, "Brave Search \u54CD\u5E94");
98
+ return compactDefined({
99
+ type: trimmedText(result.type) ?? "search",
100
+ query: nullableRecord(result.query),
101
+ results: objectArray(result.results),
102
+ extra: withExtra ? nullableRecord(result.extra) : void 0
103
+ });
104
+ }
105
+ async function webSearch(input, ctx) {
106
+ return normalizeWebSearch(await request(ctx, "/res/v1/web/search", {
107
+ q: searchTerm(input.q),
108
+ search_lang: trimmedText(input.search_lang),
109
+ ui_lang: trimmedText(input.ui_lang),
110
+ country: trimmedText(input.country),
111
+ safesearch: trimmedText(input.safesearch),
112
+ count: input.count,
113
+ offset: input.offset,
114
+ spellcheck: input.spellcheck,
115
+ freshness: trimmedText(input.freshness),
116
+ result_filter: trimmedText(input.result_filter),
117
+ extra_snippets: input.extra_snippets,
118
+ goggles: goggles(input.goggles),
119
+ text_decorations: input.text_decorations,
120
+ units: trimmedText(input.units),
121
+ operators: input.operators,
122
+ include_fetch_metadata: input.include_fetch_metadata
123
+ }));
124
+ }
125
+ async function newsSearch(input, ctx) {
126
+ const payload = await request(ctx, "/res/v1/news/search", {
127
+ q: searchTerm(input.q),
128
+ search_lang: trimmedText(input.search_lang),
129
+ ui_lang: trimmedText(input.ui_lang),
130
+ country: trimmedText(input.country),
131
+ safesearch: trimmedText(input.safesearch),
132
+ count: input.count,
133
+ offset: input.offset,
134
+ spellcheck: input.spellcheck,
135
+ freshness: trimmedText(input.freshness),
136
+ extra_snippets: input.extra_snippets,
137
+ goggles: goggles(input.goggles),
138
+ operators: input.operators,
139
+ include_fetch_metadata: input.include_fetch_metadata
140
+ });
141
+ return normalizeCollection(payload, false);
142
+ }
143
+ async function videoSearch(input, ctx) {
144
+ const payload = await request(ctx, "/res/v1/videos/search", {
145
+ q: searchTerm(input.q),
146
+ search_lang: trimmedText(input.search_lang),
147
+ ui_lang: trimmedText(input.ui_lang),
148
+ country: trimmedText(input.country),
149
+ safesearch: trimmedText(input.safesearch),
150
+ count: input.count,
151
+ offset: input.offset,
152
+ spellcheck: input.spellcheck,
153
+ freshness: trimmedText(input.freshness),
154
+ operators: input.operators,
155
+ include_fetch_metadata: input.include_fetch_metadata
156
+ });
157
+ return normalizeCollection(payload, true);
158
+ }
159
+ async function imageSearch(input, ctx) {
160
+ const payload = await request(ctx, "/res/v1/images/search", {
161
+ q: searchTerm(input.q),
162
+ search_lang: trimmedText(input.search_lang),
163
+ country: trimmedText(input.country),
164
+ safesearch: trimmedText(input.safesearch),
165
+ count: input.count,
166
+ spellcheck: input.spellcheck
167
+ });
168
+ return normalizeCollection(payload, true);
169
+ }
170
+
171
+ // ../plugins/src/brave_search/schema.ts
172
+ import { z } from "zod/v4";
173
+ var webSearchInput = z.strictObject({
174
+ q: z.string().min(1).max(400).describe("The user's search query term. Maximum of 400 characters."),
175
+ search_lang: z.string().min(2).describe("The preferred search result language code.").optional(),
176
+ ui_lang: z.string().min(2).describe("The preferred user interface language for response formatting.").optional(),
177
+ country: z.string().min(2).max(3).describe("The two-letter country code for result localization, or ALL for worldwide results.").optional(),
178
+ safesearch: z.enum(["off", "moderate", "strict"]).describe("Filters adult content from web results.").optional(),
179
+ count: z.int().min(1).max(20).describe("The maximum number of web results to return.").optional(),
180
+ offset: z.int().min(0).max(9).describe("The zero-based results page offset used for pagination.").optional(),
181
+ spellcheck: z.boolean().describe("Whether Brave Search should spellcheck the query before searching.").optional(),
182
+ freshness: z.union([z.enum(["pd", "pw", "pm", "py"]).describe("A predefined freshness window such as past day or past year."), z.string().min(1).describe("A custom date range in the format YYYY-MM-DDtoYYYY-MM-DD.")]).describe("Filters web results by page age.").optional(),
183
+ result_filter: z.string().min(1).describe("A comma-delimited list of result types to include, such as web,news,videos,locations,discussions,faq,infobox,mixed,summarizer or rich.").optional(),
184
+ extra_snippets: z.boolean().describe("Whether Brave Search should return extra alternate snippets.").optional(),
185
+ goggles: z.union([z.string().min(1).describe("One goggle URL or inline definition."), z.array(z.string().min(1).describe("One goggle URL or inline definition.")).min(1).describe("Multiple goggles to apply to the search request.")]).describe("One or more Brave Search goggles used to rerank results.").optional(),
186
+ text_decorations: z.boolean().describe("Whether display strings should include decoration markers such as highlights.").optional(),
187
+ units: z.enum(["metric", "imperial"]).describe("The measurement units used for localized results.").optional(),
188
+ operators: z.boolean().describe("Whether Brave Search should apply search operators.").optional(),
189
+ include_fetch_metadata: z.boolean().describe("Whether Brave Search should include fetch metadata in results when available.").optional()
190
+ }).describe("Input parameters for a Brave Search web search request.");
191
+ var webSearchOutput = z.strictObject({
192
+ type: z.string().describe("The Brave Search response type."),
193
+ query: z.looseObject({}).describe("Query metadata returned by Brave Search.").nullable().optional(),
194
+ web: z.looseObject({}).describe("Web result payload returned by Brave Search.").nullable().optional(),
195
+ news: z.looseObject({}).describe("News result payload returned by Brave Search.").nullable().optional(),
196
+ videos: z.looseObject({}).describe("Video result payload returned by Brave Search.").nullable().optional(),
197
+ locations: z.looseObject({}).describe("Location result payload returned by Brave Search.").nullable().optional(),
198
+ discussions: z.looseObject({}).describe("Discussion clusters returned by Brave Search.").nullable().optional(),
199
+ faq: z.looseObject({}).describe("Frequently asked questions returned by Brave Search.").nullable().optional(),
200
+ infobox: z.looseObject({}).describe("Infobox payload returned by Brave Search.").nullable().optional(),
201
+ mixed: z.looseObject({}).describe("Mixed ranking payload returned by Brave Search.").nullable().optional(),
202
+ summarizer: z.looseObject({}).describe("Summary metadata returned by Brave Search.").nullable().optional(),
203
+ rich: z.looseObject({}).describe("Rich result callback payload returned by Brave Search.").nullable().optional()
204
+ }).describe("A normalized Brave Search web search response.");
205
+ var newsSearchInput = z.strictObject({
206
+ q: z.string().min(1).max(400).describe("The user's search query term. Maximum of 400 characters."),
207
+ search_lang: z.string().min(2).describe("The preferred search result language code.").optional(),
208
+ ui_lang: z.string().min(2).describe("The preferred user interface language for response formatting.").optional(),
209
+ country: z.string().min(2).max(3).describe("The two-letter country code for result localization, or ALL for worldwide results.").optional(),
210
+ safesearch: z.enum(["off", "moderate", "strict"]).describe("Filters adult content from news results.").optional(),
211
+ count: z.int().min(1).max(50).describe("The maximum number of results to return.").optional(),
212
+ offset: z.int().min(0).max(9).describe("The zero-based results page offset used for pagination.").optional(),
213
+ spellcheck: z.boolean().describe("Whether Brave Search should spellcheck the query before searching.").optional(),
214
+ freshness: z.union([z.enum(["pd", "pw", "pm", "py"]).describe("A predefined freshness window such as past day or past year."), z.string().min(1).describe("A custom date range in the format YYYY-MM-DDtoYYYY-MM-DD.")]).describe("Filters news results by page age.").optional(),
215
+ extra_snippets: z.boolean().describe("Whether Brave Search should return extra alternate snippets.").optional(),
216
+ goggles: z.union([z.string().min(1).describe("One goggle URL or inline definition."), z.array(z.string().min(1).describe("One goggle URL or inline definition.")).min(1).describe("Multiple goggles to apply to the search request.")]).describe("One or more Brave Search goggles used to rerank results.").optional(),
217
+ operators: z.boolean().describe("Whether Brave Search should apply search operators.").optional(),
218
+ include_fetch_metadata: z.boolean().describe("Whether Brave Search should include fetch metadata in results when available.").optional()
219
+ }).describe("Input parameters for a Brave Search news request.");
220
+ var newsSearchOutput = z.strictObject({
221
+ type: z.string().describe("The Brave Search response type."),
222
+ query: z.looseObject({}).describe("Query metadata returned by Brave Search.").nullable().optional(),
223
+ results: z.array(z.looseObject({}).describe("One news result item returned by Brave Search.")).describe("The list of news results returned by Brave Search.").optional()
224
+ }).describe("A normalized Brave Search news response.");
225
+ var videoSearchInput = z.strictObject({
226
+ q: z.string().min(1).max(400).describe("The user's search query term. Maximum of 400 characters."),
227
+ search_lang: z.string().min(2).describe("The preferred search result language code.").optional(),
228
+ ui_lang: z.string().min(2).describe("The preferred user interface language for response formatting.").optional(),
229
+ country: z.string().min(2).max(3).describe("The two-letter country code for result localization, or ALL for worldwide results.").optional(),
230
+ safesearch: z.enum(["off", "moderate", "strict"]).describe("Filters adult content from video results.").optional(),
231
+ count: z.int().min(1).max(50).describe("The maximum number of results to return.").optional(),
232
+ offset: z.int().min(0).max(9).describe("The zero-based results page offset used for pagination.").optional(),
233
+ spellcheck: z.boolean().describe("Whether Brave Search should spellcheck the query before searching.").optional(),
234
+ freshness: z.union([z.enum(["pd", "pw", "pm", "py"]).describe("A predefined freshness window such as past day or past year."), z.string().min(1).describe("A custom date range in the format YYYY-MM-DDtoYYYY-MM-DD.")]).describe("Filters video results by page age.").optional(),
235
+ operators: z.boolean().describe("Whether Brave Search should apply search operators.").optional(),
236
+ include_fetch_metadata: z.boolean().describe("Whether Brave Search should include fetch metadata in results when available.").optional()
237
+ }).describe("Input parameters for a Brave Search video request.");
238
+ var videoSearchOutput = z.strictObject({
239
+ type: z.string().describe("The Brave Search response type."),
240
+ query: z.looseObject({}).describe("Query metadata returned by Brave Search.").nullable().optional(),
241
+ results: z.array(z.looseObject({}).describe("One video result item returned by Brave Search.")).describe("The list of video results returned by Brave Search.").optional(),
242
+ extra: z.looseObject({}).describe("Additional metadata returned with the video results.").nullable().optional()
243
+ }).describe("A normalized Brave Search video response.");
244
+ var imageSearchInput = z.strictObject({
245
+ q: z.string().min(1).max(400).describe("The user's search query term. Maximum of 400 characters."),
246
+ search_lang: z.string().min(2).describe("The preferred search result language code.").optional(),
247
+ country: z.string().min(2).max(3).describe("The two-letter country code for result localization, or ALL for worldwide results.").optional(),
248
+ safesearch: z.enum(["off", "strict"]).describe("Filters adult content from image results.").optional(),
249
+ count: z.int().min(1).max(200).describe("The maximum number of image results to return.").optional(),
250
+ spellcheck: z.boolean().describe("Whether Brave Search should spellcheck the query before searching.").optional()
251
+ }).describe("Input parameters for a Brave Search image request.");
252
+ var imageSearchOutput = z.strictObject({
253
+ type: z.string().describe("The Brave Search response type."),
254
+ query: z.looseObject({}).describe("Query metadata returned by Brave Search.").nullable().optional(),
255
+ results: z.array(z.looseObject({}).describe("One image result item returned by Brave Search.")).describe("The list of image results returned by Brave Search.").optional(),
256
+ extra: z.looseObject({}).describe("Additional metadata returned with the image results.").nullable().optional()
257
+ }).describe("A normalized Brave Search image response.");
258
+ var braveSearchActions = {
259
+ web_search: {
260
+ description: "Search the Brave Search web index and return the selected result families.",
261
+ effect: "write",
262
+ inputSchema: webSearchInput,
263
+ outputSchema: z.toJSONSchema(webSearchOutput, { io: "output", unrepresentable: "any" })
264
+ },
265
+ news_search: {
266
+ description: "Search Brave's news index for recent articles related to a query.",
267
+ effect: "write",
268
+ inputSchema: newsSearchInput,
269
+ outputSchema: z.toJSONSchema(newsSearchOutput, { io: "output", unrepresentable: "any" })
270
+ },
271
+ video_search: {
272
+ description: "Search Brave's video index for videos related to a query.",
273
+ effect: "write",
274
+ inputSchema: videoSearchInput,
275
+ outputSchema: z.toJSONSchema(videoSearchOutput, { io: "output", unrepresentable: "any" })
276
+ },
277
+ image_search: {
278
+ description: "Search Brave's image index for images related to a query.",
279
+ effect: "write",
280
+ inputSchema: imageSearchInput,
281
+ outputSchema: z.toJSONSchema(imageSearchOutput, { io: "output", unrepresentable: "any" })
282
+ }
283
+ };
284
+
285
+ // ../plugins/src/brave_search/index.ts
286
+ function createBraveSearchPlugin() {
287
+ return createProviderPlugin({
288
+ description: "Brave Search",
289
+ actions: braveSearchActions,
290
+ handlers: {
291
+ web_search: webSearch,
292
+ news_search: newsSearch,
293
+ video_search: videoSearch,
294
+ image_search: imageSearch
295
+ }
296
+ });
297
+ }
298
+ var brave_search_default = createBraveSearchPlugin();
299
+ export {
300
+ createBraveSearchPlugin,
301
+ brave_search_default as default
302
+ };
@@ -0,0 +1,302 @@
1
+ import {
2
+ TBError,
3
+ createEncryptionKeyring
4
+ } from "./chunk-HA4BGL6C.js";
5
+
6
+ // src/bootstrapState.ts
7
+ import {
8
+ createHash,
9
+ randomBytes,
10
+ randomUUID,
11
+ timingSafeEqual
12
+ } from "crypto";
13
+ import { chmod, mkdir, readFile, stat, unlink } from "fs/promises";
14
+ import writeFileAtomic from "write-file-atomic";
15
+ import lockfile from "proper-lockfile";
16
+ import { join } from "path";
17
+ import { z } from "zod";
18
+ var stateSchema = z.strictObject({
19
+ instanceId: z.uuid(),
20
+ revision: z.number().int().positive(),
21
+ phase: z.enum(["setup", "installing", "initialized"]),
22
+ databaseUrl: z.string().optional(),
23
+ redisUrl: z.string().optional(),
24
+ internalS3Origin: z.string().optional(),
25
+ port: z.number().int().min(0).max(65535).default(8787),
26
+ host: z.string().default("0.0.0.0")
27
+ });
28
+ var BootstrapStateStore = class {
29
+ constructor(directory) {
30
+ this.directory = directory;
31
+ }
32
+ directory;
33
+ path(name) {
34
+ return join(this.directory, name);
35
+ }
36
+ async exclusive(run, retries = 0) {
37
+ await mkdir(this.directory, { recursive: true, mode: 448 });
38
+ const release = await lockfile.lock(this.directory, {
39
+ retries,
40
+ stale: 6e4,
41
+ update: 1e4
42
+ }).catch((error) => {
43
+ if (error.code === "ELOCKED") {
44
+ throw new TBError("conflict", "another local maintenance operation is running");
45
+ }
46
+ throw error;
47
+ });
48
+ try {
49
+ return await run();
50
+ } finally {
51
+ await release();
52
+ }
53
+ }
54
+ async read(name) {
55
+ try {
56
+ const path = this.path(name);
57
+ const info = await stat(path);
58
+ if (process.platform !== "win32" && (info.mode & 63) !== 0) {
59
+ throw new TBError(
60
+ "unavailable",
61
+ "bootstrap files must be readable only by their owner"
62
+ );
63
+ }
64
+ return JSON.parse(await readFile(path, "utf8"));
65
+ } catch (error) {
66
+ if (error.code === "ENOENT") return void 0;
67
+ throw error;
68
+ }
69
+ }
70
+ async write(name, value) {
71
+ await writeFileAtomic(this.path(name), JSON.stringify(value) + "\n", {
72
+ mode: 384,
73
+ fsync: true
74
+ });
75
+ }
76
+ async state() {
77
+ const value = await this.read("bootstrap.json");
78
+ return value === void 0 ? void 0 : stateSchema.parse(value);
79
+ }
80
+ async initialize() {
81
+ return this.exclusive(async () => {
82
+ const current = await this.state();
83
+ if (current) {
84
+ if (await this.read("initialized.json"))
85
+ return { ...current, phase: "initialized" };
86
+ return current;
87
+ }
88
+ if (await this.read("identity.json"))
89
+ throw new TBError(
90
+ "unavailable",
91
+ "bootstrap state requires local recovery"
92
+ );
93
+ const state = {
94
+ instanceId: randomUUID(),
95
+ revision: 1,
96
+ phase: "setup",
97
+ port: 8787,
98
+ host: "0.0.0.0"
99
+ };
100
+ await this.write("identity.json", { instanceId: state.instanceId });
101
+ await this.write("keys.json", {
102
+ keyring: createEncryptionKeyring(randomBytes(32).toString("base64url")),
103
+ storeTokenKeyring: createEncryptionKeyring(
104
+ randomBytes(32).toString("base64url")
105
+ ),
106
+ oauthKey: randomBytes(32).toString("base64url"),
107
+ adminSk: `tb_sk_${randomBytes(32).toString("base64url")}`
108
+ });
109
+ await this.write("bootstrap.json", state);
110
+ await this.pair(state.instanceId, "setup");
111
+ return state;
112
+ }, 5);
113
+ }
114
+ async pair(instanceId, mode) {
115
+ const token = randomBytes(32).toString("base64url");
116
+ await this.write("pairing.json", {
117
+ instanceId,
118
+ mode,
119
+ tokenHash: this.hash(token),
120
+ expiresAt: Date.now() + 36e5
121
+ });
122
+ await writeFileAtomic(this.path("pairing-token"), token + "\n", {
123
+ mode: 384
124
+ });
125
+ return token;
126
+ }
127
+ async createLocalPairing(mode) {
128
+ return this.exclusive(async () => {
129
+ let state;
130
+ try {
131
+ state = await this.state();
132
+ } catch {
133
+ }
134
+ if (!state && mode === "recovery") {
135
+ const identity = await this.read(
136
+ "identity.json"
137
+ );
138
+ if (!identity || !z.uuid().safeParse(identity.instanceId).success)
139
+ throw new TBError(
140
+ "unavailable",
141
+ "instance identity requires a local backup"
142
+ );
143
+ const initialized = await this.read("initialized.json");
144
+ let keys = await this.read("keys.json");
145
+ if (!keys && !initialized) {
146
+ keys = {
147
+ keyring: createEncryptionKeyring(
148
+ randomBytes(32).toString("base64url")
149
+ ),
150
+ storeTokenKeyring: createEncryptionKeyring(
151
+ randomBytes(32).toString("base64url")
152
+ ),
153
+ oauthKey: randomBytes(32).toString("base64url"),
154
+ adminSk: `tb_sk_${randomBytes(32).toString("base64url")}`
155
+ };
156
+ await this.write("keys.json", keys);
157
+ }
158
+ state = {
159
+ instanceId: identity.instanceId,
160
+ phase: initialized ? "initialized" : "installing",
161
+ revision: 1,
162
+ port: 8787,
163
+ host: "0.0.0.0"
164
+ };
165
+ await this.write("bootstrap.json", state);
166
+ }
167
+ if (!state)
168
+ throw new TBError("unavailable", "bootstrap state unavailable");
169
+ if (mode === "setup" && (state.phase === "initialized" || await this.read("initialized.json")))
170
+ throw new TBError("permission_denied", "initial setup is closed");
171
+ return this.pair(state.instanceId, mode);
172
+ });
173
+ }
174
+ hash(value) {
175
+ return createHash("sha256").update(value).digest("hex");
176
+ }
177
+ async authorize(token, mode) {
178
+ const state = await this.state();
179
+ const pair = await this.read("pairing.json");
180
+ const initialized = await this.read(
181
+ "initialized.json"
182
+ );
183
+ if (!token || !state || !pair || pair.instanceId !== state.instanceId || pair.mode !== mode || pair.expiresAt <= Date.now() || initialized && initialized.instanceId !== state.instanceId || mode === "setup" && (state.phase === "initialized" || initialized !== void 0) || !/^[0-9a-f]{64}$/.test(pair.tokenHash) || !timingSafeEqual(
184
+ Buffer.from(this.hash(token)),
185
+ Buffer.from(pair.tokenHash)
186
+ )) {
187
+ throw new TBError(
188
+ "permission_denied",
189
+ "a valid local pairing credential is required"
190
+ );
191
+ }
192
+ return initialized ? { ...state, phase: "initialized" } : state;
193
+ }
194
+ async finish(state) {
195
+ await this.write("initialized.json", { instanceId: state.instanceId });
196
+ await this.write("bootstrap.json", {
197
+ ...state,
198
+ phase: "initialized",
199
+ revision: state.revision + 1
200
+ });
201
+ await unlink(this.path("pairing.json")).catch(() => {
202
+ });
203
+ await unlink(this.path("pairing-token")).catch(() => {
204
+ });
205
+ }
206
+ async defaults() {
207
+ return this.read(
208
+ "install-defaults.json"
209
+ );
210
+ }
211
+ async secureDirectory() {
212
+ await chmod(this.directory, 448);
213
+ }
214
+ };
215
+
216
+ // package.json
217
+ var package_default = {
218
+ name: "@tool-bridge/server",
219
+ version: "0.22.1",
220
+ description: "Self-hosted Tool Bridge Node server with PostgreSQL, S3 object storage and WebSocket device channels",
221
+ type: "module",
222
+ license: "MIT",
223
+ main: "src/index.ts",
224
+ exports: {
225
+ ".": "./src/index.ts"
226
+ },
227
+ bin: {
228
+ "tool-bridge-server": "./dist/main.js",
229
+ "tool-bridge-admin": "./dist/admin.js"
230
+ },
231
+ files: [
232
+ "dist"
233
+ ],
234
+ engines: {
235
+ node: ">=22"
236
+ },
237
+ publishConfig: {
238
+ access: "public",
239
+ main: "./dist/index.js",
240
+ types: "./dist/index.d.ts",
241
+ exports: {
242
+ ".": {
243
+ types: "./dist/index.d.ts",
244
+ import: "./dist/index.js"
245
+ }
246
+ }
247
+ },
248
+ keywords: [
249
+ "self-hosted",
250
+ "docker",
251
+ "mcp",
252
+ "htbp",
253
+ "tool-bridge",
254
+ "agent-tools"
255
+ ],
256
+ scripts: {
257
+ typecheck: "tsc --noEmit",
258
+ test: "vitest run",
259
+ build: "tsup",
260
+ start: "tsx src/main.ts"
261
+ },
262
+ dependencies: {
263
+ "@hono/node-server": "catalog:",
264
+ "@tool-bridge/dashboard": "workspace:*",
265
+ hono: "catalog:",
266
+ ioredis: "^6.0.0",
267
+ postgres: "^3.4.9",
268
+ ws: "catalog:",
269
+ "@aws-sdk/client-s3": "^3.1127.0",
270
+ "@smithy/node-http-handler": "^4.12.1",
271
+ "ipaddr.js": "^2.5.0",
272
+ "write-file-atomic": "^7.0.0",
273
+ "proper-lockfile": "^4.1.2",
274
+ zod: "catalog:",
275
+ commander: "~15.0.0",
276
+ "p-retry": "^7.1.1",
277
+ negotiator: "^1.0.0"
278
+ },
279
+ devDependencies: {
280
+ "@tool-bridge/app": "workspace:*",
281
+ "@tool-bridge/core": "workspace:*",
282
+ "@tool-bridge/plugins": "workspace:*",
283
+ "@types/node": "catalog:",
284
+ "@types/ws": "catalog:",
285
+ tsup: "catalog:",
286
+ tsx: "catalog:",
287
+ vitest: "catalog:",
288
+ "@types/write-file-atomic": "^4.0.3",
289
+ "@types/proper-lockfile": "^4.1.4",
290
+ "@types/negotiator": "^0.6.4"
291
+ },
292
+ repository: {
293
+ type: "git",
294
+ url: "git+https://github.com/TokenRollAI/tool-bridge.git",
295
+ directory: "packages/server"
296
+ }
297
+ };
298
+
299
+ export {
300
+ BootstrapStateStore,
301
+ package_default
302
+ };