import { Channel, ChannelType, Guild } from "discord.js"; import * as fs from "node:fs"; import { DisclawDatabase } from "../db/database.js"; import { DisclawConfig } from "../config/loader.js"; import { ResolvedCategories, ensureCategories } from "./categories.js"; import { childLogger } from "../runtime/logger.js"; const log = childLogger("lifecycle:channel-delete"); export interface ChannelDeleteContext { db: DisclawDatabase; config: DisclawConfig; guild: Guild; categories: ResolvedCategories; managementChannelId: string; setManagementChannelId: (id: string) => void; setCategories: (cats: ResolvedCategories) => void; } export async function handleChannelDelete( channel: Channel, ctx: ChannelDeleteContext ): Promise { const channelId = channel.id; // 1. Was the management channel deleted? if (channelId === ctx.managementChannelId) { log.warn({ channelId }, "Management channel was deleted — recreating"); try { const newChannel = await ctx.guild.channels.create({ name: ctx.config.management_channel, type: ChannelType.GuildText, topic: "DisClaw Management -- verwende /new-agent um Agenten zu erstellen", }); ctx.setManagementChannelId(newChannel.id); // Update DB: remove old entry, add new one ctx.db.deleteWorkspaceByChannelId(channelId); ctx.db.createWorkspace(newChannel.id, ctx.guild.id, ctx.config.management_channel, "__management__"); log.info({ newChannelId: newChannel.id }, "Management channel recreated"); } catch (err) { log.error({ err }, "Failed to recreate management channel"); } return; } // 2. Was one of the lifecycle category channels deleted? const isCategoryChannel = channelId === ctx.categories.active.id || channelId === ctx.categories.inactive.id || channelId === ctx.categories.archive.id; if (isCategoryChannel) { log.warn({ channelId }, "Lifecycle category channel was deleted — re-ensuring categories"); try { const newCats = await ensureCategories(ctx.guild); ctx.setCategories(newCats); log.info("Categories re-ensured"); } catch (err) { log.error({ err }, "Failed to re-ensure categories"); } return; } // 3. Was an agent channel deleted? const workspace = ctx.db.getWorkspaceByChannelId(channelId); if (workspace) { const workspacePath = workspace.workspace_path; // Delete workspace directory before removing from DB if (workspacePath && workspacePath !== "__management__") { try { fs.rmSync(workspacePath, { recursive: true, force: true }); log.info({ workspacePath }, "Agent workspace directory deleted"); } catch (err) { log.warn({ workspacePath, err }, "Failed to delete agent workspace directory"); } } // Remove from DB ctx.db.deleteWorkspaceByChannelId(channelId); log.info({ channelId, agentName: workspace.agent_name }, "Agent channel and workspace removed from DB"); } }