diff --git a/src/tools/audit-workspace.ts b/src/tools/audit-workspace.ts index d4306bd..64d28e6 100644 --- a/src/tools/audit-workspace.ts +++ b/src/tools/audit-workspace.ts @@ -35,6 +35,7 @@ export function registerAuditWorkspace(server: McpServer): void { `Audit workspace documentation freshness vs actual project state. Compares .claude/ workspace docs against recent git commits to find stale or missing documentation. Call after completing a batch of work or at session end.`, {}, async () => { + try { const docs = findWorkspaceDocs(); const recentFiles = run("git diff --name-only HEAD~10 2>/dev/null || echo ''").split("\n").filter(Boolean); const sections: string[] = []; @@ -92,6 +93,9 @@ export function registerAuditWorkspace(server: McpServer): void { sections.push(`## Recommendation\n${recs.join("\n")}`); return { content: [{ type: "text" as const, text: sections.join("\n\n") }] }; + } catch (err) { + return { content: [{ type: "text" as const, text: `❌ audit_workspace failed: ${err instanceof Error ? err.message : String(err)}` }] }; + } } ); } diff --git a/src/tools/check-patterns.ts b/src/tools/check-patterns.ts index ffa7c46..debd25e 100644 --- a/src/tools/check-patterns.ts +++ b/src/tools/check-patterns.ts @@ -10,6 +10,7 @@ export function registerCheckPatterns(server: McpServer): void { prompt: z.string().describe("The prompt to check against known patterns"), }, async ({ prompt }) => { + try { const patterns = loadPatterns(); if (patterns.length === 0) { @@ -38,6 +39,9 @@ export function registerCheckPatterns(server: McpServer): void { text: formatPatternMatches(matches), }], }; + } catch (err) { + return { content: [{ type: "text" as const, text: `❌ check_patterns failed: ${err instanceof Error ? err.message : String(err)}` }] }; + } }, ); } diff --git a/src/tools/checkpoint.ts b/src/tools/checkpoint.ts index e086f01..bcb8c89 100644 --- a/src/tools/checkpoint.ts +++ b/src/tools/checkpoint.ts @@ -17,6 +17,7 @@ export function registerCheckpoint(server: McpServer): void { commit_mode: z.enum(["staged", "tracked", "all"]).optional().describe("What to commit: 'staged' (only staged files), 'tracked' (modified tracked files), 'all' (git add -A). Default: 'tracked'"), }, async ({ summary, next_steps, current_blockers, commit_mode }) => { + try { const mode = commit_mode || "tracked"; const branch = getBranch(); const dirty = getStatus(); @@ -114,6 +115,9 @@ ${current_blockers ? "- Current blockers\n" : ""}- Working tree state at checkpo Tell the next session/continuation: "Read .claude/last-checkpoint.md for where I left off"`, }], }; + } catch (err) { + return { content: [{ type: "text" as const, text: `❌ checkpoint failed: ${err instanceof Error ? err.message : String(err)}` }] }; + } } ); } diff --git a/src/tools/search-contracts.ts b/src/tools/search-contracts.ts index bb402d1..ba53826 100644 --- a/src/tools/search-contracts.ts +++ b/src/tools/search-contracts.ts @@ -15,6 +15,7 @@ export function registerSearchContracts(server: McpServer): void { kind: z.enum(["interface", "type", "enum", "route", "schema", "event", "model", "all"]).default("all").describe("Filter by contract kind"), }, async ({ query, scope, kind }) => { + try { const projectDirs: string[] = []; if (scope === "current" || scope === "all") { @@ -56,6 +57,9 @@ export function registerSearchContracts(server: McpServer): void { } return { content: [{ type: "text" as const, text: output.join("\n") }] }; + } catch (err) { + return { content: [{ type: "text" as const, text: `❌ search_contracts failed: ${err instanceof Error ? err.message : String(err)}` }] }; + } } ); } diff --git a/src/tools/sequence-tasks.ts b/src/tools/sequence-tasks.ts index 22dea23..02091bf 100644 --- a/src/tools/sequence-tasks.ts +++ b/src/tools/sequence-tasks.ts @@ -79,6 +79,7 @@ export function registerSequenceTasks(server: McpServer): void { strategy: z.enum(["dependency", "locality", "risk-first"]).default("locality").describe("Sequencing strategy"), }, async ({ tasks, strategy }) => { + try { const ts = now(); const classified = tasks.map((t) => ({ @@ -177,6 +178,9 @@ export function registerSequenceTasks(server: McpServer): void { ].join("\n"); return { content: [{ type: "text" as const, text: result }] }; + } catch (err) { + return { content: [{ type: "text" as const, text: `❌ sequence_tasks failed: ${err instanceof Error ? err.message : String(err)}` }] }; + } } ); } diff --git a/src/tools/session-health.ts b/src/tools/session-health.ts index bd6a819..fdb252c 100644 --- a/src/tools/session-health.ts +++ b/src/tools/session-health.ts @@ -20,6 +20,7 @@ export function registerSessionHealth(server: McpServer): void { stale_threshold_hours: z.number().optional().describe("Hours before a doc is considered stale. Default: 2"), }, async ({ stale_threshold_hours }) => { + try { const config = getConfig(); const staleHours = stale_threshold_hours ?? (config.thresholds.session_stale_minutes / 60); const branch = getBranch(); @@ -102,6 +103,9 @@ ${issues.length ? issues.join("\n") : "None — session is healthy"} ${recommendation}`, }], }; + } catch (err) { + return { content: [{ type: "text" as const, text: `❌ check_session_health failed: ${err instanceof Error ? err.message : String(err)}` }] }; + } } ); } diff --git a/src/tools/sharpen-followup.ts b/src/tools/sharpen-followup.ts index db5acaa..211c494 100644 --- a/src/tools/sharpen-followup.ts +++ b/src/tools/sharpen-followup.ts @@ -51,6 +51,7 @@ export function registerSharpenFollowup(server: McpServer): void { previous_files: z.array(z.string()).optional().describe("Files involved in the previous action"), }, async ({ followup_message, previous_action, previous_files }) => { + try { const msg = followup_message.trim(); const assumptions: string[] = []; const questions: string[] = []; @@ -195,6 +196,9 @@ export function registerSharpenFollowup(server: McpServer): void { lines.push(`_Generated ${now()}_`); return { content: [{ type: "text" as const, text: lines.join("\n") }] }; + } catch (err) { + return { content: [{ type: "text" as const, text: `❌ sharpen_followup failed: ${err instanceof Error ? err.message : String(err)}` }] }; + } } ); } diff --git a/src/tools/what-changed.ts b/src/tools/what-changed.ts index 913dfa2..d88ddf8 100644 --- a/src/tools/what-changed.ts +++ b/src/tools/what-changed.ts @@ -10,6 +10,7 @@ export function registerWhatChanged(server: McpServer): void { since: z.string().optional().describe("Git ref: 'HEAD~5', 'HEAD~3', etc. Default: HEAD~5"), }, async ({ since }) => { + try { const ref = since || "HEAD~5"; const diffStat = getDiffStat(ref); const diffFiles = run(`git diff ${ref} --name-only 2>/dev/null || git diff HEAD~3 --name-only`); @@ -43,6 +44,9 @@ ${diffStat || "no changes"} \`\`\``, }], }; + } catch (err) { + return { content: [{ type: "text" as const, text: `❌ what_changed failed: ${err instanceof Error ? err.message : String(err)}` }] }; + } } ); }