Skip to main content
Glama

Task Trellis MCP

deleteObjectById.ts3.47 kB
import { readFile, rm, unlink } from "fs/promises"; import { dirname } from "path"; import { ServerConfig } from "../../configuration"; import { TrellisObject } from "../../models"; import { deserializeTrellisObject, isRequiredForOtherObjects, } from "../../utils"; import { findMarkdownFiles } from "./findMarkdownFiles"; interface FoundObject { filePath: string; object: TrellisObject; } // Should this be replaced by getObjectById? async function findObjectById( id: string, planningRoot: string, ): Promise<FoundObject> { const markdownFiles = await findMarkdownFiles(planningRoot); for (const filePath of markdownFiles) { try { const fileContent = await readFile(filePath, "utf-8"); const trellisObject: TrellisObject = deserializeTrellisObject(fileContent); if (trellisObject.id === id) { return { filePath, object: trellisObject }; } } catch (error) { console.error(`Warning: Could not deserialize file ${filePath}:`, error); continue; } } throw new Error(`No object found with ID: ${id}`); } async function checkObjectDependencies( targetObject: TrellisObject, planningRoot: string, ): Promise<void> { const { LocalRepository } = await import("./LocalRepository"); const config: ServerConfig = { mode: "local", planningRootFolder: planningRoot, autoCompleteParent: false, autoPrune: 0, }; const repository = new LocalRepository(config); const isRequired = await isRequiredForOtherObjects(targetObject, repository); if (isRequired) { throw new Error( `Cannot delete object ${targetObject.id} because it is required by other objects. Use force=true to override.`, ); } } async function deleteObjectFile(filePath: string): Promise<void> { await unlink(filePath); } async function deleteAssociatedFolder( id: string, filePath: string, ): Promise<void> { if (!id.startsWith("P-") && !id.startsWith("E-") && !id.startsWith("F-")) { return; } const associatedFolderPath = dirname(filePath); try { await rm(associatedFolderPath, { recursive: true, force: true }); } catch (error) { console.error( `Warning: Could not delete associated folder ${associatedFolderPath}:`, error, ); } } /** * Deletes a TrellisObject by its ID, including both the markdown file and associated folder * * By default, the function checks if the object is required by other objects (as a prerequisite) * and throws an error if it is. This safety check can be bypassed using the force parameter. * * @param id The ID of the object to delete * @param planningRoot The root directory to search for markdown files * @param force Optional. If true, bypasses dependency checks and deletes the object even if required by others. Defaults to false. * @returns Promise resolving when the object is successfully deleted * @throws Error if no object with the given ID is found * @throws Error if object is required by other objects and force is false * @throws Error if deletion fails due to file system issues */ export async function deleteObjectById( id: string, planningRoot: string, force?: boolean, ): Promise<void> { const foundObject = await findObjectById(id, planningRoot); const { filePath, object } = foundObject; if (!force) { await checkObjectDependencies(object, planningRoot); } await deleteObjectFile(filePath); await deleteAssociatedFolder(id, filePath); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/langadventurellc/task-trellis-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server