import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent"; import { resetTemplateReferences } from "../config/update-config.ts"; import { tryResolveGitRepositoryRoot } from "../git/collect-changes.ts"; import { GitClient } from "../git/git-client.ts"; import { listTemplates } from "../templates/list-templates.ts"; import { DEFAULT_TEMPLATE_NAME } from "../templates/load-template.ts"; import { stageUserTemplateRemoval } from "../templates/save-template.ts"; const CANCELLED_MESSAGE = "Cancelled. No template was removed."; /** * 执行 /git-commit remove 的模板删除工作流: * 选择或指定用户模板,确认后删除文件,并把仍引用它的配置回退到 default。 */ export async function runRemoveTemplateFlow( pi: ExtensionAPI, ctx: ExtensionCommandContext, ): Promise { const templates = await listTemplates(); const userNames = templates .filter((template) => template.source === "user") .map((template) => template.name); if (userNames.length === 0) { ctx.ui.notify("No user templates to remove. Built-in templates cannot be removed.", "warning"); return; } const name = await ctx.ui.select("Select template to remove", userNames); if (name === undefined) { ctx.ui.notify(CANCELLED_MESSAGE, "info"); return; } const confirmed = await ctx.ui.confirm( "Remove template", `Delete template "${name}" permanently? This cannot be undone.`, ); if (!confirmed) { ctx.ui.notify(CANCELLED_MESSAGE, "info"); return; } // 在隐藏的同目录备份中暂存删除;配置更新失败时可以恢复原模板。 const removal = await stageUserTemplateRemoval(name); let updated: string[] = []; try { if (name !== DEFAULT_TEMPLATE_NAME) { const projectDir = await tryResolveGitRepositoryRoot(new GitClient(pi), ctx.cwd); updated = await resetTemplateReferences(name, projectDir); } await removal.commit(); } catch (error) { try { await removal.rollback(); } catch (rollbackError) { const detail = rollbackError instanceof Error ? rollbackError.message : String(rollbackError); throw new Error( `Template removal failed and the staged file could not be restored to ${removal.path}: ${detail}`, { cause: error }, ); } throw error; } if (name === DEFAULT_TEMPLATE_NAME) { ctx.ui.notify( `Template "${name}" removed. The built-in default template is now used.\n${removal.path}`, "info", ); return; } if (updated.length > 0) { ctx.ui.notify( `Template "${name}" removed. Configurations referencing it were reset to "${DEFAULT_TEMPLATE_NAME}":\n${updated.join("\n")}`, "info", ); return; } ctx.ui.notify(`Template "${name}" removed.\n${removal.path}`, "info"); }