From bcb6dfbe8c43a0cbdff529eee3a5cca630f9373d Mon Sep 17 00:00:00 2001 From: ArthurErlich Date: Sat, 3 Oct 2026 19:26:31 +0200 Subject: [PATCH] feat: wire the fastCRW provider into the plugin entry Co-Authored-By: Claude Sonnet 5.5 --- src/index.ts | 21 +++++++++++++++-- test/index.test.ts | 59 ++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 3 ++- 3 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 test/index.test.ts diff --git a/src/index.ts b/src/index.ts index 39d58de..67bde09 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,19 @@ -// ponytail: placeholder so `tsc` has an input; replaced by the plugin entry. -export {} +import { Plugin } from "@opencode/plugin" +import { resolveConfig } from "./config.ts" +import { search } from "./search.ts" + +export default Plugin.define({ + id: "fastcrw.websearch", + async setup(ctx) { + // Throws on bad options so a misconfigured plugin fails loudly instead of silently searching elsewhere. + const config = resolveConfig(ctx.options, process.env) + await ctx.websearch.transform((editor) => { + editor.add({ + id: "fastcrw", + name: "fastCRW", + execute: ({ query }, { signal }) => search(config, query, signal), + }) + editor.default.set("fastcrw") + }) + }, +}) diff --git a/test/index.test.ts b/test/index.test.ts new file mode 100644 index 0000000..aeca65f --- /dev/null +++ b/test/index.test.ts @@ -0,0 +1,59 @@ +import assert from "node:assert/strict" +import { test } from "node:test" +import plugin from "../src/index.ts" + +function fakeContext(options: Record) { + const added: { id: string; name: string; execute: Function }[] = [] + const defaults: unknown[] = [] + const editor = { + add: (definition: (typeof added)[number]) => added.push(definition), + default: { get: () => undefined, set: (value: unknown) => defaults.push(value) }, + } + const ctx = { + options, + websearch: { transform: async (fn: (e: typeof editor) => void) => fn(editor) }, + } + return { ctx: ctx as never, added, defaults } +} + +test("plugin id", () => { + assert.equal(plugin.id, "fastcrw.websearch") +}) + +test("setup registers the fastcrw provider and makes it the default", async () => { + const { ctx, added, defaults } = fakeContext({ baseURL: "http://crw.test:3000" }) + await plugin.setup(ctx) + assert.equal(added.length, 1) + assert.equal(added[0].id, "fastcrw") + assert.equal(added[0].name, "fastCRW") + assert.deepEqual(defaults, ["fastcrw"]) +}) + +test("setup throws on bad options and registers nothing", async () => { + const { ctx, added, defaults } = fakeContext({ baseURL: "nope" }) + await assert.rejects(Promise.resolve(plugin.setup(ctx)), /baseURL/) + assert.equal(added.length + defaults.length, 0) +}) + +test("the registered provider searches the configured endpoint", async () => { + const { ctx, added } = fakeContext({ baseURL: "http://crw.test:3000", limit: 2 }) + await plugin.setup(ctx) + const realFetch = globalThis.fetch + let seen = "" + globalThis.fetch = (async (url: string) => { + seen = url + return new Response( + JSON.stringify({ success: true, data: [{ url: "https://a", title: "A", snippet: "s" }] }), + ) + }) as typeof fetch + try { + const results = await added[0].execute( + { query: "cats" }, + { signal: new AbortController().signal }, + ) + assert.equal(seen, "http://crw.test:3000/v1/search") + assert.deepEqual(results, [{ url: "https://a", title: "A", content: "s", time: {} }]) + } finally { + globalThis.fetch = realFetch + } +}) diff --git a/tsconfig.json b/tsconfig.json index d8c61b5..e105566 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,8 @@ "outDir": "dist", "rootDir": "src", "types": ["node"], - "skipLibCheck": true + "skipLibCheck": true, + "rewriteRelativeImportExtensions": true }, "include": ["src"] }