From 33bff2b130edbeb2aca2944d1dc4bdf5b91a3fc8 Mon Sep 17 00:00:00 2001 From: Ben Stull Date: Tue, 9 Jun 2026 23:55:39 -0700 Subject: [PATCH] POC: vscode-free @cline/sdk driver with unit test (Feature #2) fetchSdkSummary() dynamic-imports the ESM-only SDK and returns its build version + builtin tool catalog (pure, key-free). Kept vscode-free so it is unit-testable in Node; test asserts a semver version and the read_files tool. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/cline.ts | 34 ++++++++++++++++++++++++++++++++++ test/cline.test.ts | 15 +++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/cline.ts create mode 100644 test/cline.test.ts diff --git a/src/cline.ts b/src/cline.ts new file mode 100644 index 0000000..252c035 --- /dev/null +++ b/src/cline.ts @@ -0,0 +1,34 @@ +/** + * vscode-free driver for @cline/sdk. + * + * @cline/sdk is ESM-only (Node >=22) and uses createRequire(import.meta.url), + * so it must NOT be bundled into the CJS extension. We load it at runtime via + * dynamic import(); the bundler keeps it external (see esbuild.mjs). + */ + +export interface ClineTool { + id: string; + description: string; +} + +export interface SdkSummary { + version: string; + tools: ClineTool[]; +} + +/** + * Drive @cline/sdk with pure, key-free calls and return a renderable summary: + * the SDK build version and the agent's builtin tool catalog. Proves the SDK + * is linked and callable from the extension host. + */ +export async function fetchSdkSummary(): Promise { + const sdk = await import("@cline/sdk"); + const catalog = sdk.getCoreBuiltinToolCatalog(); + return { + version: sdk.CORE_BUILD_VERSION, + tools: catalog.map((entry) => ({ + id: entry.id, + description: entry.description, + })), + }; +} diff --git a/test/cline.test.ts b/test/cline.test.ts new file mode 100644 index 0000000..593c33e --- /dev/null +++ b/test/cline.test.ts @@ -0,0 +1,15 @@ +import { describe, it, expect } from "vitest"; +import { fetchSdkSummary } from "../src/cline"; + +describe("fetchSdkSummary", () => { + it("loads @cline/sdk and returns its version and builtin tool catalog", async () => { + const summary = await fetchSdkSummary(); + expect(summary.version).toMatch(/^\d+\.\d+\.\d+/); + expect(summary.tools.length).toBeGreaterThan(0); + expect(summary.tools.map((t) => t.id)).toContain("read_files"); + for (const tool of summary.tools) { + expect(typeof tool.id).toBe("string"); + expect(typeof tool.description).toBe("string"); + } + }); +});