opencode-websearch 0.1.1 → 0.2.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.
@@ -0,0 +1,20 @@
1
+ import { AnthropicConfig } from "./types.js";
2
+ interface ProviderData {
3
+ models: Record<string, {
4
+ api: {
5
+ npm: string;
6
+ };
7
+ id: string;
8
+ options: Record<string, unknown>;
9
+ }>;
10
+ key?: string;
11
+ options: Record<string, unknown>;
12
+ }
13
+ /**
14
+ * Scan providers returned by the SDK for the first Anthropic model
15
+ * with `websearch: true` set in its options.
16
+ */
17
+ declare const resolveFromProviders: (providers: ProviderData[]) => AnthropicConfig | null;
18
+ declare const formatConfigError: () => string;
19
+ export { formatConfigError, resolveFromProviders };
20
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAI7C,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC/F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAqBD;;;GAGG;AACH,QAAA,MAAM,oBAAoB,GAAI,WAAW,YAAY,EAAE,KAAG,eAAe,GAAG,IAgB3E,CAAC;AAIF,QAAA,MAAM,iBAAiB,QAAO,MA6B0B,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ declare const ANTHROPIC_NPM_PACKAGE = "@ai-sdk/anthropic";
2
+ declare const DEFAULT_SEARCH_USES = 5;
3
+ declare const EMPTY_LENGTH = 0;
4
+ declare const MAX_RESPONSE_TOKENS = 16000;
5
+ declare const MAX_SEARCH_USES = 10;
6
+ declare const MIN_QUERY_LENGTH = 2;
7
+ declare const MIN_SEARCH_USES = 1;
8
+ declare const MONTH_OFFSET = 1;
9
+ declare const PAD_LENGTH = 2;
10
+ export { ANTHROPIC_NPM_PACKAGE, DEFAULT_SEARCH_USES, EMPTY_LENGTH, MAX_RESPONSE_TOKENS, MAX_SEARCH_USES, MIN_QUERY_LENGTH, MIN_SEARCH_USES, MONTH_OFFSET, PAD_LENGTH, };
11
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,qBAAqB,sBAAsB,CAAC;AAClD,QAAA,MAAM,mBAAmB,IAAI,CAAC;AAC9B,QAAA,MAAM,YAAY,IAAI,CAAC;AACvB,QAAA,MAAM,mBAAmB,QAAS,CAAC;AACnC,QAAA,MAAM,eAAe,KAAK,CAAC;AAC3B,QAAA,MAAM,gBAAgB,IAAI,CAAC;AAC3B,QAAA,MAAM,eAAe,IAAI,CAAC;AAC1B,QAAA,MAAM,YAAY,IAAI,CAAC;AACvB,QAAA,MAAM,UAAU,IAAI,CAAC;AAErB,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,UAAU,GACX,CAAC"}
@@ -0,0 +1,4 @@
1
+ declare const getTodayDate: () => string;
2
+ declare const getCurrentMonthYear: () => string;
3
+ export { getCurrentMonthYear, getTodayDate };
4
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,YAAY,QAAO,MAMxB,CAAC;AAEF,QAAA,MAAM,mBAAmB,QAAO,MAC4C,CAAC;AAE7E,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare const _default: () => Promise<{
1
+ declare const _default: (input: import("@opencode-ai/plugin").PluginInput) => Promise<{
2
2
  tool: {
3
3
  "web-search": {
4
4
  description: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAobA,wBAoDqB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AASA,wBAsEoB"}
package/dist/index.js CHANGED
@@ -1,156 +1,17 @@
1
- // src/index.ts
2
- import { existsSync, readFileSync } from "node:fs";
3
- import { homedir } from "node:os";
4
- import { join } from "node:path";
5
- import { tool } from "@opencode-ai/plugin";
6
- import Anthropic, { APIError } from "@anthropic-ai/sdk";
7
- var DEFAULT_MODEL = "claude-sonnet-4-5";
8
- var MONTH_OFFSET = 1;
9
- var PAD_LENGTH = 2;
10
- var ENV_VAR_CAPTURE_GROUP = 1;
11
- var FIRST_MODEL_INDEX = 0;
1
+ // src/constants.ts
2
+ var ANTHROPIC_NPM_PACKAGE = "@ai-sdk/anthropic";
3
+ var DEFAULT_SEARCH_USES = 5;
12
4
  var EMPTY_LENGTH = 0;
5
+ var MAX_RESPONSE_TOKENS = 16000;
6
+ var MAX_SEARCH_USES = 10;
13
7
  var MIN_QUERY_LENGTH = 2;
14
8
  var MIN_SEARCH_USES = 1;
15
- var MAX_SEARCH_USES = 10;
16
- var DEFAULT_SEARCH_USES = 5;
17
- var MAX_RESPONSE_TOKENS = 16000;
18
- var getTodayDate = () => {
19
- const now = new Date;
20
- const year = now.getFullYear();
21
- const month = String(now.getMonth() + MONTH_OFFSET).padStart(PAD_LENGTH, "0");
22
- const day = String(now.getDate()).padStart(PAD_LENGTH, "0");
23
- return `${year}-${month}-${day}`;
24
- };
25
- var resolveEnvVar = (value) => {
26
- const match = value.match(/^\{env:(\w+)\}$/);
27
- if (match?.[ENV_VAR_CAPTURE_GROUP]) {
28
- return process.env[match[ENV_VAR_CAPTURE_GROUP]] ?? "";
29
- }
30
- return value;
31
- };
32
- var normalizeBaseURL = (url) => url.replace(/\/v1\/?$/, "");
33
- var CONFIG_PATHS = [
34
- join(process.cwd(), "opencode.json"),
35
- join(process.cwd(), ".opencode", "opencode.json"),
36
- join(homedir(), ".config", "opencode", "opencode.json")
37
- ];
38
- var parseConfigFile = (configPath) => {
39
- try {
40
- return JSON.parse(readFileSync(configPath, "utf8"));
41
- } catch (error) {
42
- if (error instanceof SyntaxError) {
43
- return `Failed to parse ${configPath}: ${error.message}`;
44
- }
45
- return `Failed to parse ${configPath}: ${String(error)}`;
46
- }
47
- };
48
- var resolveProviderApiKey = (ctx, rawApiKey) => {
49
- const apiKey = resolveEnvVar(rawApiKey);
50
- if (apiKey) {
51
- return apiKey;
52
- }
53
- const envMatch = rawApiKey.match(/^\{env:(\w+)\}$/);
54
- if (envMatch) {
55
- ctx.errors.push(`${ctx.configPath}: Environment variable ${envMatch[ENV_VAR_CAPTURE_GROUP]} is not set`);
56
- } else {
57
- ctx.errors.push(`${ctx.configPath}: Provider "${ctx.providerName}" has empty apiKey`);
58
- }
59
- return;
60
- };
61
- var resolveModelName = (provider) => {
62
- if (!provider.models) {
63
- return DEFAULT_MODEL;
64
- }
65
- const models = Object.keys(provider.models);
66
- return models[FIRST_MODEL_INDEX] ?? DEFAULT_MODEL;
67
- };
68
- var resolveBaseURL = (provider) => {
69
- if (!provider.options?.baseURL) {
70
- return;
71
- }
72
- return normalizeBaseURL(resolveEnvVar(provider.options.baseURL));
73
- };
74
- var resolveProviderConfig = (ctx, provider) => {
75
- if (provider.npm !== "@ai-sdk/anthropic") {
76
- return;
77
- }
78
- if (!provider.options?.apiKey) {
79
- ctx.errors.push(`${ctx.configPath}: Provider "${ctx.providerName}" has no apiKey configured`);
80
- return;
81
- }
82
- const apiKey = resolveProviderApiKey(ctx, provider.options.apiKey);
83
- if (!apiKey) {
84
- return;
85
- }
86
- return {
87
- apiKey,
88
- baseURL: resolveBaseURL(provider),
89
- model: resolveModelName(provider)
90
- };
91
- };
92
- var scanProviders = (configPath, providers, errors) => {
93
- for (const [providerName, provider] of Object.entries(providers)) {
94
- const ctx = { configPath, errors, providerName };
95
- const resolved = resolveProviderConfig(ctx, provider);
96
- if (resolved) {
97
- return resolved;
98
- }
99
- }
100
- return;
101
- };
102
- var scanConfigFile = (configPath, errors) => {
103
- if (!existsSync(configPath)) {
104
- return;
105
- }
106
- const parsed = parseConfigFile(configPath);
107
- if (typeof parsed === "string") {
108
- errors.push(parsed);
109
- return;
110
- }
111
- if (!parsed.provider) {
112
- errors.push(`${configPath}: No "provider" field found`);
113
- return;
114
- }
115
- return scanProviders(configPath, parsed.provider, errors);
116
- };
117
- var scanAllConfigFiles = (errors) => {
118
- for (const configPath of CONFIG_PATHS) {
119
- const resolved = scanConfigFile(configPath, errors);
120
- if (resolved) {
121
- return resolved;
122
- }
123
- }
124
- return;
125
- };
126
- var getEnvFallback = () => {
127
- const envApiKey = process.env.ANTHROPIC_API_KEY;
128
- if (envApiKey) {
129
- return {
130
- config: {
131
- apiKey: envApiKey,
132
- model: DEFAULT_MODEL
133
- }
134
- };
135
- }
136
- return;
137
- };
138
- var getAnthropicConfig = () => {
139
- const errors = [];
140
- const fromConfig = scanAllConfigFiles(errors);
141
- if (fromConfig) {
142
- return { config: fromConfig };
143
- }
144
- const fromEnv = getEnvFallback();
145
- if (fromEnv) {
146
- return fromEnv;
147
- }
148
- if (errors.length > EMPTY_LENGTH) {
149
- return { config: null, error: errors.join(`
150
- `) };
151
- }
152
- return { config: null };
153
- };
9
+
10
+ // src/index.ts
11
+ import { tool } from "@opencode-ai/plugin";
12
+
13
+ // src/providers/anthropic.ts
14
+ import Anthropic, { APIError } from "@anthropic-ai/sdk";
154
15
  var formatSearchResult = (result) => {
155
16
  if (result.page_age) {
156
17
  return `- [${result.title}](${result.url}) (Updated: ${result.page_age})`;
@@ -202,31 +63,6 @@ var buildWebSearchTool = (args) => {
202
63
  }
203
64
  return searchTool;
204
65
  };
205
- var formatConfigError = (error) => {
206
- let hint = "";
207
- if (error) {
208
- hint = `
209
-
210
- ${error}`;
211
- }
212
- return `Error: web-search requires an Anthropic API key.
213
-
214
- Set the ANTHROPIC_API_KEY environment variable, or add an Anthropic provider to your opencode.json:
215
-
216
- {
217
- "provider": {
218
- "anthropic": {
219
- "npm": "@ai-sdk/anthropic",
220
- "options": {
221
- "apiKey": "{env:ANTHROPIC_API_KEY}"
222
- },
223
- "models": {
224
- "claude-sonnet-4-5": { "name": "Claude Sonnet 4.5" }
225
- }
226
- }
227
- }
228
- }${hint}`;
229
- };
230
66
  var formatErrorMessage = (error) => {
231
67
  if (error instanceof APIError) {
232
68
  return `Anthropic API error: ${error.message} (status: ${error.status})`;
@@ -275,41 +111,124 @@ var executeSearch = async (config, args) => {
275
111
  return results.join(`
276
112
  `) || "No results returned from web search.";
277
113
  };
278
- var src_default = async () => ({
279
- tool: {
280
- "web-search": tool({
281
- args: {
282
- allowed_domains: tool.schema.array(tool.schema.string()).optional().describe("Only include results from these domains"),
283
- blocked_domains: tool.schema.array(tool.schema.string()).optional().describe("Exclude results from these domains"),
284
- max_uses: tool.schema.number().min(MIN_SEARCH_USES).max(MAX_SEARCH_USES).optional().describe("Maximum number of searches to perform (default: 5)"),
285
- query: tool.schema.string().min(MIN_QUERY_LENGTH).describe("The search query to execute")
286
- },
287
- description: `Search the web using Anthropic's server-side web_search API.
288
114
 
289
- - Provides up-to-date information for current events and recent data
290
- - Returns search results with links as markdown hyperlinks
291
- - Use this for accessing information beyond the knowledge cutoff
115
+ // src/config.ts
116
+ var isAnthropicModel = (model) => model.api.npm === ANTHROPIC_NPM_PACKAGE;
117
+ var hasWebSearch = (model) => model.options.websearch === true;
118
+ var normalizeBaseURL = (url) => url.replace(/\/v1\/?$/, "");
119
+ var extractBaseURL = (options) => {
120
+ if (typeof options.baseURL !== "string") {
121
+ return;
122
+ }
123
+ return normalizeBaseURL(options.baseURL);
124
+ };
125
+ var resolveFromProviders = (providers) => {
126
+ for (const provider of providers) {
127
+ for (const model of Object.values(provider.models)) {
128
+ if (isAnthropicModel(model) && hasWebSearch(model)) {
129
+ if (!provider.key) {
130
+ return null;
131
+ }
132
+ return {
133
+ apiKey: provider.key,
134
+ baseURL: extractBaseURL(provider.options),
135
+ model: model.id
136
+ };
137
+ }
138
+ }
139
+ }
140
+ return null;
141
+ };
142
+ var formatConfigError = () => `Error: web-search requires an Anthropic provider with \`websearch: true\` set on at least one model.
292
143
 
293
- CRITICAL: After answering, you MUST include a "Sources:" section with URLs as markdown hyperlinks.
144
+ No model with \`"websearch": true\` was found in your opencode.json configuration.
294
145
 
295
- Today's date: ${getTodayDate()}. Use the current year when searching for recent information.`,
296
- async execute(args) {
297
- const { config, error } = getAnthropicConfig();
298
- if (!config) {
299
- return formatConfigError(error);
300
- }
301
- if (args.allowed_domains && args.blocked_domains) {
302
- return "Error: Cannot specify both allowed_domains and blocked_domains.";
303
- }
304
- try {
305
- return await executeSearch(config, args);
306
- } catch (error2) {
307
- return formatErrorMessage(error2);
146
+ To fix this, add an Anthropic provider to your opencode.json and set \`"websearch": true\` in the options of the model you want to use for web searches:
147
+
148
+ {
149
+ "provider": {
150
+ "anthropic": {
151
+ "npm": "@ai-sdk/anthropic",
152
+ "options": {
153
+ "apiKey": "{env:ANTHROPIC_API_KEY}"
154
+ },
155
+ "models": {
156
+ "claude-sonnet-4-5": {
157
+ "options": {
158
+ "websearch": true
159
+ }
308
160
  }
309
161
  }
310
- })
162
+ }
163
+ }
164
+ }
165
+
166
+ Steps:
167
+ 1. Open your opencode.json (project root, .opencode/opencode.json, or ~/.config/opencode/opencode.json)
168
+ 2. Ensure you have an Anthropic provider configured with a valid API key
169
+ 3. Add \`"websearch": true\` to the \`options\` of the Claude model you want to use for web search
170
+ 4. Restart OpenCode to pick up the configuration change`;
171
+
172
+ // src/helpers.ts
173
+ var getCurrentMonthYear = () => new Date().toLocaleDateString("en-US", { month: "long", year: "numeric" });
174
+
175
+ // src/index.ts
176
+ var src_default = async (input) => {
177
+ const { data } = await input.client.config.providers();
178
+ let config = null;
179
+ if (data) {
180
+ config = resolveFromProviders(data.providers);
311
181
  }
312
- });
182
+ return {
183
+ tool: {
184
+ "web-search": tool({
185
+ args: {
186
+ allowed_domains: tool.schema.array(tool.schema.string()).optional().describe("Only include results from these domains"),
187
+ blocked_domains: tool.schema.array(tool.schema.string()).optional().describe("Exclude results from these domains"),
188
+ max_uses: tool.schema.number().min(MIN_SEARCH_USES).max(MAX_SEARCH_USES).optional().describe("Maximum number of searches to perform (default: 5)"),
189
+ query: tool.schema.string().min(MIN_QUERY_LENGTH).describe("The search query to execute")
190
+ },
191
+ description: `- Allows OpenCode to search the web and use the results to inform responses
192
+ - Provides up-to-date information for current events and recent data
193
+ - Returns search result information formatted as search result blocks, including links as markdown hyperlinks
194
+ - Use this tool for accessing information beyond the model's knowledge cutoff
195
+ - Searches are performed automatically within a single API call
196
+
197
+ CRITICAL REQUIREMENT - You MUST follow this:
198
+ - After answering the user's question, you MUST include a "Sources:" section at the end of your response
199
+ - In the Sources section, list all relevant URLs from the search results as markdown hyperlinks: [Title](URL)
200
+ - This is MANDATORY - never skip including sources in your response
201
+ - Example format:
202
+
203
+ [Your answer here]
204
+
205
+ Sources:
206
+ - [Source Title 1](https://example.com/1)
207
+ - [Source Title 2](https://example.com/2)
208
+
209
+ Usage notes:
210
+ - Domain filtering is supported to include or block specific websites
211
+
212
+ IMPORTANT - Use the correct year in search queries:
213
+ - It is currently ${getCurrentMonthYear()}. You MUST use this when searching for recent information, documentation, or current events.
214
+ - Example: If the user asks for "latest React docs", search for "React documentation" with the current year, NOT last year`,
215
+ async execute(args) {
216
+ if (!config) {
217
+ return formatConfigError();
218
+ }
219
+ if (args.allowed_domains && args.blocked_domains) {
220
+ return "Error: Cannot specify both allowed_domains and blocked_domains.";
221
+ }
222
+ try {
223
+ return await executeSearch(config, args);
224
+ } catch (error) {
225
+ return formatErrorMessage(error);
226
+ }
227
+ }
228
+ })
229
+ }
230
+ };
231
+ };
313
232
  export {
314
233
  src_default as default
315
234
  };
@@ -0,0 +1,10 @@
1
+ import { AnthropicConfig } from "../types.js";
2
+ declare const formatErrorMessage: (error: unknown) => string;
3
+ declare const executeSearch: (config: AnthropicConfig, args: {
4
+ allowed_domains?: string[];
5
+ blocked_domains?: string[];
6
+ max_uses?: number;
7
+ query: string;
8
+ }) => Promise<string>;
9
+ export { executeSearch, formatErrorMessage };
10
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EAKhB,MAAM,aAAa,CAAC;AAqErB,QAAA,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,MAQ5C,CAAC;AAoBF,QAAA,MAAM,aAAa,GACjB,QAAQ,eAAe,EACvB,MAAM;IACJ,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,KACA,OAAO,CAAC,MAAM,CA0BhB,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,40 @@
1
+ interface AnthropicConfig {
2
+ apiKey: string;
3
+ baseURL?: string;
4
+ model: string;
5
+ }
6
+ interface WebSearchResult {
7
+ page_age?: string;
8
+ title: string;
9
+ type: "web_search_result";
10
+ url: string;
11
+ }
12
+ interface WebSearchToolResult {
13
+ content: WebSearchResult[] | {
14
+ error_code: string;
15
+ type: "web_search_tool_result_error";
16
+ };
17
+ tool_use_id: string;
18
+ type: "web_search_tool_result";
19
+ }
20
+ interface ServerToolUse {
21
+ id: string;
22
+ input: {
23
+ query: string;
24
+ };
25
+ name: string;
26
+ type: "server_tool_use";
27
+ }
28
+ interface SearchUsage {
29
+ input_tokens: number;
30
+ output_tokens: number;
31
+ server_tool_use?: {
32
+ web_search_requests?: number;
33
+ };
34
+ }
35
+ type ContentBlock = {
36
+ text: string;
37
+ type: "text";
38
+ } | ServerToolUse | WebSearchToolResult;
39
+ export { AnthropicConfig, ContentBlock, SearchUsage, ServerToolUse, WebSearchResult, WebSearchToolResult, };
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAID,UAAU,eAAe;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,mBAAmB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,mBAAmB;IAC3B,OAAO,EAAE,eAAe,EAAE,GAAG;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,8BAA8B,CAAA;KAAE,CAAC;IAC1F,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,wBAAwB,CAAC;CAChC;AAED,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,UAAU,WAAW;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE;QAAE,mBAAmB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD;AAED,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,GAAG,mBAAmB,CAAC;AAEzF,OAAO,EACL,eAAe,EACf,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,mBAAmB,GACpB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-websearch",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Claude Code's WebSearch tool ported to OpenCode",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -18,9 +18,12 @@
18
18
  "build": "bun build src/index.ts --outdir dist --target node --format esm --packages external && bun run build:types",
19
19
  "build:types": "tsc --emitDeclarationOnly --declaration --outDir dist",
20
20
  "dev": "bun run --watch src/index.ts",
21
+ "format": "oxfmt src/",
22
+ "format:check": "oxfmt --check src/",
21
23
  "lint": "oxlint --tsconfig tsconfig.json src/",
24
+ "lint:fix": "oxlint --tsconfig tsconfig.json --fix src/",
22
25
  "typecheck": "tsc --noEmit",
23
- "check": "bun run lint && bun run typecheck",
26
+ "check": "bun run format:check && bun run lint && bun run typecheck",
24
27
  "prepublishOnly": "bun run check && bun run build"
25
28
  },
26
29
  "keywords": [
@@ -35,7 +38,7 @@
35
38
  "url": "https://github.com/emilsvennesson/opencode-websearch.git"
36
39
  },
37
40
  "engines": {
38
- "node": ">=22"
41
+ "node": ">=24"
39
42
  },
40
43
  "license": "MIT",
41
44
  "dependencies": {
@@ -44,6 +47,7 @@
44
47
  "devDependencies": {
45
48
  "@opencode-ai/plugin": "^1.1.65",
46
49
  "@types/bun": "latest",
50
+ "oxfmt": "^0.32.0",
47
51
  "oxlint": "^1.47.0",
48
52
  "typescript": "^5.8.0"
49
53
  },