| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- import assert from "node:assert/strict";
- import { execFile } from "node:child_process";
- import { access, mkdtemp, readFile, rm } from "node:fs/promises";
- import { tmpdir } from "node:os";
- import { dirname, join, resolve } from "node:path";
- import test from "node:test";
- import { fileURLToPath } from "node:url";
- import { promisify } from "node:util";
- import { smokePackage } from "./smoke-package.mjs";
- import { smokeMcp } from "./smoke-mcp.mjs";
- const execFileAsync = promisify(execFile);
- const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
- test("package structure and plan validation smoke", async () => {
- const result = await smokePackage();
- assert.equal(result.status, "ok");
- });
- test("MCP exposes the image-set tools", async () => {
- const result = await smokeMcp();
- assert.equal(result.status, "ok");
- assert.deepEqual(result.tools.sort(), ["fmode_image_set_run", "fmode_image_set_validate"].sort());
- const validator = result.toolDefinitions.find((tool) => tool.name === "fmode_image_set_validate");
- assert.deepEqual(validator.annotations, {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- });
- });
- test("skill can call its MCP tools and delegates unsupported images to the attachment bridge", async () => {
- const skill = await readFile(join(root, "skills", "fmode-image-set", "SKILL.md"), "utf8");
- assert.doesNotMatch(skill, /^allowed-tools:/m);
- assert.match(skill, /\[Unsupported Image\]/);
- assert.match(skill, /`fmode_image_set_run` 的 `action=start`/);
- assert.match(skill, /不得先用 Glob 搜图/);
- });
- test("workspace install places the complete package under the discoverable skill root", async () => {
- const workspace = await mkdtemp(join(tmpdir(), "fmode-image-set-workspace-"));
- try {
- await execFileAsync(
- process.execPath,
- [join(root, "bin", "fmode-image-set.js"), "workspace", "--skip-install"],
- { cwd: workspace },
- );
- const target = join(workspace, ".claude", "skills", "fmode-image-set");
- for (const relativePath of [
- ".claude-plugin/plugin.json",
- "bin/fmode-image-set.js",
- "docs/capability-map.md",
- "mcp/src/server.mjs",
- "memory-templates/image-set-profile.json",
- "scripts/smoke-package.mjs",
- "skills/fmode-image-set/SKILL.md",
- "skill-package-manifest.json",
- "SKILL.md",
- "references/image-set-planner.md",
- "agents/openai.yaml",
- ]) {
- await access(join(target, relativePath));
- }
- const config = JSON.parse(await readFile(join(workspace, ".mcp.json"), "utf8"));
- assert.equal(
- resolve(config.mcpServers["fmode-image-set"].cwd),
- resolve(target),
- );
- } finally {
- await rm(workspace, { recursive: true, force: true });
- }
- });
|