import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { registerDiceTool } from "./tools/dice"; import { registerDBTools } from "./tools/db"; import { registerSkillCheckTool } from "./tools/skill-check"; import { registerCombatTool } from "./tools/combat"; import { registerLootTool } from "./tools/loot"; import { registerConsumeTool } from "./tools/consume"; import { registerCraftTool } from "./tools/craft"; import { registerTradeTool } from "./tools/trade"; import { registerStatusRuntimeTools } from "./tools/status-runtime"; import { registerLevelUpTool } from "./tools/level-up"; import { registerLegendaryGenTool } from "./tools/legendary-gen"; import { registerWeaponGenTool } from "./tools/weapon-gen"; import { registerArmorGenTool } from "./tools/armor-gen"; import { registerAccessoryGenTool } from "./tools/accessory-gen"; import { registerEquipTools } from "./tools/equip"; import { registerEventLogTools } from "./tools/event-log"; import { registerExplorationTools } from "./tools/exploration"; import { registerGMGuideTool } from "./tools/gm-guide"; import { registerEncounterTool } from "./tools/encounter"; import { registerTraderTool } from "./tools/trader"; import { registerLootGenTool } from "./tools/loot-gen"; import { registerTakeLootTool } from "./tools/take-loot"; import { registerTimeTools, registerSetTimerTool, registerCheckTimersTool } from "./tools/time"; import { registerQuestTools } from "./tools/quest"; import { registerToolHelpTool } from "./tools/tool-help"; import { registerCreateCharacterTool } from "./tools/create-character"; import { registerTimeContextHook } from "./tools/time-context"; import { readFileSync, rmSync, existsSync } from "node:fs"; import { fileURLToPath } from "node:url"; import { dirname, resolve, join } from "node:path"; import os from "node:os"; export default function (pi: ExtensionAPI) { registerDiceTool(pi); registerDBTools(pi); registerSkillCheckTool(pi); registerCombatTool(pi); registerLootTool(pi); registerConsumeTool(pi); registerCraftTool(pi); registerTradeTool(pi); registerStatusRuntimeTools(pi); registerLevelUpTool(pi); registerLegendaryGenTool(pi); registerWeaponGenTool(pi); registerArmorGenTool(pi); registerAccessoryGenTool(pi); registerEquipTools(pi); registerEventLogTools(pi); registerExplorationTools(pi); registerGMGuideTool(pi); registerEncounterTool(pi); registerTraderTool(pi); registerLootGenTool(pi); registerTakeLootTool(pi); registerTimeTools(pi); registerSetTimerTool(pi); registerCheckTimersTool(pi); registerQuestTools(pi); registerToolHelpTool(pi); registerCreateCharacterTool(pi); registerTimeContextHook(pi); pi.on("session_start", async (_event, ctx) => { // 读取当前版本号 let version = "?"; try { const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "package.json"), "utf8")); version = pkg.version; } catch {} ctx.ui.notify(`⚙️ Chronika Engine v${version} loaded`, "info"); // ── 缓存版本自检 ── // 检测当前是否运行在 pi 的 tmp 扩展缓存目录中 const currentFile = fileURLToPath(import.meta.url); const currentDir = dirname(currentFile); if (currentDir.includes("tmp/extensions/npm/")) { try { // 读取当前加载版本的 package.json const loadedPkg = JSON.parse( readFileSync(join(currentDir, "package.json"), "utf8") ); // 读取 npm 安装目录的 package.json const npmPkgPath = join( os.homedir(), ".pi/agent/npm/node_modules/chronika-engine/package.json" ); if (existsSync(npmPkgPath)) { const npmPkg = JSON.parse(readFileSync(npmPkgPath, "utf8")); if (npmPkg.version !== loadedPkg.version) { // 版本不一致 → 清除缓存目录,下次启动加载新版 const cacheDir = resolve(currentDir, "../.."); // 退到 / 目录 if (cacheDir.includes("tmp/extensions/npm/")) { rmSync(cacheDir, { recursive: true, force: true }); } ctx.ui.notify( `🔄 Chronika Engine 缓存版本 (${loadedPkg.version}) 与安装版本 (${npmPkg.version}) 不一致,已清除缓存。请重启 Pi 加载新版本。`, "warning" ); } } } catch { // 静默失败,不影响扩展加载 } } }); }