mirror of
https://github.com/Tencent/BrowserSkill.git
synced 2026-09-10 13:01:23 +08:00
feat(dsh-plugin-browserskill): publish the BSK skill through ctx.skills
The plugin exposed only tools; the BrowserSkill agent skill never reached the harness's <available_skills> catalog. Register it as an embedded runtime skill (progressive disclosure: catalog entry resident, body on skill-tool invocation) via the official ctx.skills seam — silent no-op when the composition lacks it. Content is build-time assembled so there is one source of truth: skill/prelude.md (committed, dsh-specific: tool<->CLI map, owned-session semantics, plugin-only overrides) + the canonical repo-root skill/SKILL.md verbatim (the same file crates/bsk-cli/build.rs mirrors; frontmatter stripped, name/description supplied by the registration). Generated into src/skill-content.generated.ts (gitignored) — registration and every pre-step snapshot are pure in-memory reads: no disk, no process, no daemon. Scripts: build:skill chained into build/test/typecheck (same pattern as build:css); biome excludes the generated artifacts. Tests: +3 (catalog content, in-memory weight, silent degradation). 116/116 green.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
// Assemble the plugin's skill content: the dsh-specific prelude (committed in
|
||||
// this package at skill/prelude.md) followed VERBATIM by the canonical CLI
|
||||
// skill body (repo-root skill/SKILL.md — the same source crates/bsk-cli's
|
||||
// build.rs mirrors, so the two can never drift apart). The original's YAML
|
||||
// frontmatter is stripped: name/description are supplied by the registration.
|
||||
// Output: src/skill-content.generated.ts (gitignored, built before tsdown and
|
||||
// before vitest) so the markdown ships inlined in the bundle and registration
|
||||
// is a pure in-memory read — never a per-step disk access.
|
||||
import { readFileSync, writeFileSync } from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const here = dirname(fileURLToPath(import.meta.url));
|
||||
const pkg = join(here, "..");
|
||||
const prelude = readFileSync(join(pkg, "skill", "prelude.md"), "utf8");
|
||||
const upstream = readFileSync(join(pkg, "..", "..", "skill", "SKILL.md"), "utf8");
|
||||
|
||||
function stripFrontmatter(markdown) {
|
||||
if (!markdown.startsWith("---\n")) return markdown;
|
||||
const end = markdown.indexOf("\n---\n", 4);
|
||||
return end === -1 ? markdown : markdown.slice(end + 5).replace(/^\s*\n/, "");
|
||||
}
|
||||
|
||||
const NAME = "browser-skill";
|
||||
const DESCRIPTION =
|
||||
"Browser automation against the user's logged-in Chromium through this plugin's browser_* " +
|
||||
"tools (bsk engine): visit and read pages, fill forms, click through flows, scrape data, " +
|
||||
"smoke-test UI changes. Use when a task needs a real browser; requires the bsk CLI and the " +
|
||||
"browser-skill extension connected.";
|
||||
|
||||
const content = `${prelude.trim()}\n\n${stripFrontmatter(upstream).trim()}\n`;
|
||||
|
||||
const banner =
|
||||
"// GENERATED by scripts/build-skill-content.mjs — do not edit.\n" +
|
||||
"// Sources: skill/prelude.md (this package) + ../../../skill/SKILL.md (repo root).\n";
|
||||
|
||||
writeFileSync(
|
||||
join(pkg, "src", "skill-content.generated.ts"),
|
||||
`${banner}export const BSK_SKILL_NAME = ${JSON.stringify(NAME)};\n` +
|
||||
`export const BSK_SKILL_DESCRIPTION = ${JSON.stringify(DESCRIPTION)};\n` +
|
||||
`export const BSK_SKILL_MARKDOWN = ${JSON.stringify(content)};\n`,
|
||||
);
|
||||
console.log(`skill-content.generated.ts written (${content.length} chars)`);
|
||||
Reference in New Issue
Block a user