fix: regenerate pi-claude-cli MCP config per session and auto-sync skill tools
The MCP config was generated lazily once and locked, so engine session-scoped tools (fn_review_spec, fn_review_step) never reached the Claude CLI subprocess and triage/executor sessions failed with "unknown tool" errors. Now the config is hashed per call and rewritten when the tool set changes. Also adds scripts/sync-fusion-skill-tools.mjs to regenerate the SKILL.md tool-categories block from extension.ts at build time, with a --check mode wired into skill-sync tests so drift fails CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "tsx src/bin.ts",
|
||||
"prebuild": "node ../../scripts/sync-fusion-skill-tools.mjs",
|
||||
"build": "tsup",
|
||||
"build:exe": "bun run build.ts",
|
||||
"build:exe:all": "bun run build.ts --all",
|
||||
|
||||
@@ -24,11 +24,13 @@ Mission → Milestone → Slice → Feature → Task
|
||||
**Naming boundary:** The published skill surface always uses `fn_*` tool names (for example `fn_task_create`, `fn_mission_create`). Internal engine runtime tools like `task_create`, `task_update`, `task_log`, and `task_done` are intentionally unprefixed and not part of this skill.
|
||||
|
||||
**Tool categories:**
|
||||
<!-- BEGIN: tool-categories (auto-generated by scripts/sync-fusion-skill-tools.mjs — do not edit by hand) -->
|
||||
- **Task tools** — `fn_task_create`, `fn_task_update`, `fn_task_list`, `fn_task_show`, `fn_task_attach`, `fn_task_pause`, `fn_task_unpause`, `fn_task_retry`, `fn_task_duplicate`, `fn_task_refine`, `fn_task_archive`, `fn_task_unarchive`, `fn_task_delete`, `fn_task_plan`
|
||||
- **GitHub tools** — `fn_task_import_github`, `fn_task_import_github_issue`, `fn_task_browse_github_issues`
|
||||
- **Mission tools** — `fn_mission_create`, `fn_mission_list`, `fn_mission_show`, `fn_mission_delete`, `fn_milestone_add`, `fn_slice_add`, `fn_feature_add`, `fn_slice_activate`, `fn_feature_link_task`
|
||||
- **Agent tools** — `fn_agent_stop`, `fn_agent_start`
|
||||
- **Skills tools** — `fn_skills_search`, `fn_skills_install`
|
||||
<!-- END: tool-categories -->
|
||||
- **Dashboard** — Use `/fn` command to start/stop the dashboard
|
||||
|
||||
</essential_principles>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, it, expect } from "vitest";
|
||||
import { readFileSync, existsSync, readdirSync } from "node:fs";
|
||||
import { resolve, dirname, relative, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { spawnSync } from "node:child_process";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const cliRoot = resolve(__dirname, "../..");
|
||||
@@ -194,6 +195,19 @@ describe("Skill-Extension Sync", () => {
|
||||
expect(dashboardCli).toContain("/fn");
|
||||
});
|
||||
|
||||
it("SKILL.md tool-categories block matches the sync script output (no drift)", () => {
|
||||
const repoRoot = resolve(cliRoot, "../..");
|
||||
const script = resolve(repoRoot, "scripts/sync-fusion-skill-tools.mjs");
|
||||
const result = spawnSync("node", [script, "--check"], {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
if (result.status !== 0) {
|
||||
throw new Error(
|
||||
`sync-fusion-skill-tools --check failed:\n${result.stderr || result.stdout}`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("package.json includes skills in pi config and files array", () => {
|
||||
const pkg = JSON.parse(
|
||||
readFileSync(resolve(cliRoot, "package.json"), "utf-8"),
|
||||
|
||||
Reference in New Issue
Block a user