epic_update
Update an epic by passing only the fields you want to change. Set status to cancelled to soft-delete, or use the branch parameter to pin to the active branch.
Instructions
Update an epic. Pass only the fields you want to change. Set status to "cancelled" to soft-delete. Pass branch="current" to pin to the active branch, or empty string to clear.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Epic ID | |
| name | No | ||
| description | No | ||
| status | No | ||
| priority | No | ||
| sort_order | No | ||
| branch | No | Git branch this epic is scoped to. Pass "current" to auto-detect; pass empty string to clear (branch-agnostic). | |
| tags | No |
Implementation Reference
- src/tools/epics.ts:150-173 (handler)Core handler function for epic_update. Fetches the existing epic, resolves branch, builds an UPDATE SQL via buildUpdate helper, executes it, logs changes with logEntityUpdate, and returns the updated row.
function handleEpicUpdate(args: Record<string, unknown>) { const db = getDb(); const id = args.id as number; const oldRow = db.prepare('SELECT * FROM epics WHERE id = ?').get(id) as Record<string, unknown> | undefined; if (!oldRow) throw new Error(`Epic ${id} not found`); // Branch is handled separately so that explicit null/empty clears it; buildUpdate skips undefined. const branchResolution = args.branch !== undefined ? resolveBranch(args.branch) : undefined; const fieldsForBuilder: Record<string, unknown> = { ...args }; if (branchResolution !== undefined) { fieldsForBuilder.branch = branchResolution; } else { delete fieldsForBuilder.branch; } const update = buildUpdate('epics', id, fieldsForBuilder, ['name', 'description', 'status', 'priority', 'sort_order', 'branch', 'tags']); if (!update) throw new Error('No fields to update'); const newRow = db.prepare(update.sql).get(...update.params) as Record<string, unknown>; logEntityUpdate(db, 'epic', id, newRow.name as string, oldRow, newRow, ['name', 'status', 'priority', 'branch']); return newRow; } - src/tools/epics.ts:58-80 (schema)Tool definition and input schema for epic_update. Declares the tool name, description, annotations, and inputSchema with updatable fields: id (required), name, description, status, priority, sort_order, branch, and tags.
{ name: 'epic_update', description: 'Update an epic. Pass only the fields you want to change. Set status to "cancelled" to soft-delete. Pass branch="current" to pin to the active branch, or empty string to clear.', annotations: { title: 'Update Epic', readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false }, inputSchema: { type: 'object', properties: { id: { type: 'integer', description: 'Epic ID' }, name: { type: 'string' }, description: { type: 'string' }, status: { type: 'string', enum: ['planned', 'in_progress', 'completed', 'cancelled'] }, priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] }, sort_order: { type: 'integer' }, branch: { type: 'string', description: 'Git branch this epic is scoped to. Pass "current" to auto-detect; pass empty string to clear (branch-agnostic).', }, tags: { type: 'array', items: { type: 'string' } }, }, required: ['id'], }, }, - src/index.ts:37-49 (registration)Registration of all tool handlers including epicHandlers which contains epic_update mapped to handleEpicUpdate.
const ALL_HANDLERS: Record<string, (args: Record<string, unknown>) => unknown> = { ...projectHandlers, ...epicHandlers, ...taskHandlers, ...subtaskHandlers, ...noteHandlers, ...commentHandlers, ...templateHandlers, ...dashboardHandlers, ...searchHandlers, ...activityHandlers, ...exportImportHandlers, }; - src/tools/epics.ts:175-179 (registration)Export of the epic handlers map where 'epic_update' is mapped to the handleEpicUpdate function.
export const handlers: Record<string, ToolHandler> = { epic_create: handleEpicCreate, epic_list: handleEpicList, epic_update: handleEpicUpdate, }; - src/helpers/sql-builder.ts:3-28 (helper)The buildUpdate helper used by handleEpicUpdate to dynamically construct an UPDATE SQL statement with only the provided fields.
export function buildUpdate( table: string, id: number, fields: Record<string, unknown>, allowedColumns: string[] ): { sql: string; params: unknown[] } | null { const updates: string[] = []; const params: unknown[] = []; for (const col of allowedColumns) { if (fields[col] !== undefined) { updates.push(`${col} = ?`); params.push(JSON_COLUMNS.has(col) ? JSON.stringify(fields[col]) : fields[col]); } } if (updates.length === 0) return null; updates.push("updated_at = datetime('now')"); params.push(id); return { sql: `UPDATE ${table} SET ${updates.join(', ')} WHERE id = ? RETURNING *`, params, }; }