Files
paseo/packages/plugin/src/skill-examples.test.ts
T
paseo-bot[bot] 68938b668e fix(skills): make the paseo-plugin composer pill example match the plugin SDK (#5591)
The example passed title, Component, and onPress straight to
addComposerPill and treated its return value as a remover function, so it
failed to typecheck against @getpaseo/plugin. It also followed agents with
agents.subscribe, a local listener that never delivers agents that exist
before the plugin loads. The example now uses the button descriptor and an
owned list subscription, like the plugin reference and local-plugin
example, and a test typechecks it against the SDK.

Closes #5517

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-09-29 02:51:54 +02:00

41 lines
1.8 KiB
TypeScript

import { readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import ts from "typescript";
import { describe, expect, it } from "vitest";
const repository = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../..");
const skill = readFileSync(path.join(repository, "skills/paseo-plugin/SKILL.md"), "utf8");
function sectionCode(heading: string): string {
const section = skill.slice(skill.indexOf(`\n## ${heading}\n`));
const code = /```tsx\n([\s\S]*?)\n```/.exec(section)?.[1];
if (!code) throw new Error(`No tsx example under "${heading}"`);
return code;
}
// Checks the example as a plugin client file, with the same options as the plugin examples.
function typeErrors(code: string): string[] {
const configPath = path.join(repository, "packages/plugin/tsconfig.examples.json");
const { config } = ts.readConfigFile(configPath, ts.sys.readFile);
const { options } = ts.parseJsonConfigFileContent(config, ts.sys, path.dirname(configPath));
const file = path.join(repository, "plugin-examples/skill-example/client/example.tsx");
const host = ts.createCompilerHost(options);
const getSourceFile = host.getSourceFile;
host.getSourceFile = (name, language, ...rest) =>
path.resolve(name) === file
? ts.createSourceFile(name, code, language)
: getSourceFile.call(host, name, language, ...rest);
host.fileExists = (name) => path.resolve(name) === file || ts.sys.fileExists(name);
const program = ts.createProgram([file], options, host);
return ts
.getPreEmitDiagnostics(program)
.map((diagnostic) => ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
}
describe("paseo-plugin skill examples", () => {
it("composer pill example typechecks against the plugin SDK", () => {
expect(typeErrors(sectionCode("Add a composer pill"))).toEqual([]);
});
});