Files
fusion/packages/engine/src/__tests__/plugin-skill-integration.test.ts
gsxdsm cb57093d03 refactor: domain folder layout (types, API, core, engine) (#2398)
## Summary

Wave 17 organizes Fusion into **domain folders** (stacks on #2397).

### Layout
- **core/types/** — board, task, agents, settings, merge, workflow,
mesh, …
- **core/src/** — agents, ai, async-stores, workflows, tasks, config,
db, …
- **dashboard/app/api/** — client, tasks, agents, git, missions,
planning, …
- **engine/src/** — agents, auth, execution, merge, missions, overseer,
worktree, …

Root keepers retained for large entrypoints (`store.ts`, `executor.ts`,
`merger.ts`, …).

Public barrels (`@fusion/core`, `@fusion/engine`, `app/api.ts` → legacy)
stay stable.

## Test plan
- [x] `@fusion/core` typecheck
- [x] `@fusion/engine` typecheck (pre-existing playwright-core noise
only)
- [ ] CI merge gate

**Stack:** #2394 → #2397 → **this PR**
2026-08-03 00:20:53 -07:00

89 lines
3.2 KiB
TypeScript

import { describe, it, expect, vi } from "vitest";
import type { AgentStore } from "@fusion/core";
import type { PluginRunner } from "../plugins/plugin-runner.js";
import { buildSessionSkillContext } from "../cli-runtime/session-skill-context.js";
import { createSkillsOverrideFromSelection, resolveSessionSkills } from "../cli-runtime/skill-resolver.js";
import type { Skill } from "@earendil-works/pi-coding-agent";
describe("plugin skill integration", () => {
const projectRootDir = "/test/project";
it("merges enabled plugin skills, excludes disabled, and dedupes with agent skills", async () => {
const agentStore = {
getAgent: vi.fn().mockResolvedValue({
id: "agent-1",
metadata: { skills: ["fusion", "agent-only"] },
}),
} as unknown as AgentStore;
const pluginRunner = {
getPluginSkills: vi.fn().mockReturnValue([
{ pluginId: "plugin-a", skill: { name: "fusion", enabled: true } },
{ pluginId: "plugin-a", skill: { name: "plugin-enabled", enabled: true } },
{ pluginId: "plugin-b", skill: { name: "plugin-disabled", enabled: false } },
]),
} as unknown as PluginRunner;
const contextResult = await buildSessionSkillContext({
agentStore,
task: { assignedAgentId: "agent-1" },
sessionPurpose: "executor",
projectRootDir,
pluginRunner,
});
expect(contextResult.skillSelectionContext?.requestedSkillNames).toEqual([
"fusion",
"agent-only",
"plugin-enabled",
]);
});
it("coexists with role fallback and flows through resolver pipeline", async () => {
const agentStore = {
getAgent: vi.fn().mockResolvedValue(null),
} as unknown as AgentStore;
const pluginRunner = {
getPluginSkills: vi.fn().mockReturnValue([
{ pluginId: "plugin-a", skill: { name: "plugin-skill", enabled: true } },
]),
} as unknown as PluginRunner;
const contextResult = await buildSessionSkillContext({
agentStore,
task: {},
sessionPurpose: "triage",
projectRootDir,
pluginRunner,
});
expect(contextResult.skillSelectionContext?.requestedSkillNames).toEqual(["fusion", "plugin-skill"]);
const resolved = resolveSessionSkills(contextResult.skillSelectionContext!);
const skillsOverride = createSkillsOverrideFromSelection(resolved, {
requestedSkillNames: contextResult.skillSelectionContext?.requestedSkillNames,
sessionPurpose: contextResult.skillSelectionContext?.sessionPurpose,
});
const makeSkill = (name: string, filePath: string): Skill => ({
name,
description: `${name} description`,
filePath,
baseDir: "/skills",
sourceInfo: {} as Skill["sourceInfo"],
disableModelInvocation: false,
});
const filtered = skillsOverride({
skills: [
makeSkill("fusion", "/skills/fusion/SKILL.md"),
makeSkill("plugin-skill", "/skills/plugin/SKILL.md"),
makeSkill("other", "/skills/other/SKILL.md"),
],
diagnostics: [],
});
expect(contextResult.skillSelectionContext?.requestedSkillNames).toEqual(["fusion", "plugin-skill"]);
expect(filtered.skills.map((skill) => skill.name)).toEqual(["fusion", "plugin-skill"]);
});
});