fix(mcp): align ChronoMind type enums with actual backend schema

Fix 3 type mismatches in MCP chronomind-client.ts + chronomind-tools.ts:

1. TimerDoc.type: Remove non-existent 'event', keep 'countdown'|'alarm'|'pomodoro'
2. TimerDoc.state: Remove non-existent 'idle', add missing 'snoozed'|'dismissed'
3. RoutineDoc.status: Replace wrong 'idle'|'running' with actual
   'template'|'ready'|'active'|'cancelled'

Fix cascading usages:
- chronomind.timers.create tool: default state 'idle' → 'active'
- chronomind.timers.list tool: update type/state enum in Zod schema + description
- calendar-import-pipeline.ts: 'idle' → 'active' for imported timers

MCP server typecheck passes. No runtime behavior change for existing tools.
This commit is contained in:
saravanakumardb1 2026-03-31 23:57:24 -07:00
parent efde14ba6e
commit af605a6e7d
3 changed files with 11 additions and 14 deletions

View File

@ -41,8 +41,8 @@ export interface TimerDoc {
productId: string; productId: string;
label: string; label: string;
description?: string; description?: string;
type: 'alarm' | 'countdown' | 'pomodoro' | 'event'; type: 'countdown' | 'alarm' | 'pomodoro';
state: 'idle' | 'active' | 'paused' | 'warning' | 'fired' | 'completed'; state: 'active' | 'paused' | 'fired' | 'snoozed' | 'dismissed' | 'completed' | 'warning';
urgency: 'critical' | 'important' | 'standard' | 'gentle' | 'passive'; urgency: 'critical' | 'important' | 'standard' | 'gentle' | 'passive';
duration?: number; duration?: number;
targetTime?: string; targetTime?: string;
@ -55,8 +55,8 @@ export interface TimerDoc {
export interface TimerCreateInput { export interface TimerCreateInput {
id: string; id: string;
label: string; label: string;
type: 'alarm' | 'countdown' | 'pomodoro' | 'event'; type: 'countdown' | 'alarm' | 'pomodoro';
state: 'idle' | 'active' | 'paused'; state: 'active' | 'paused';
urgency: 'critical' | 'important' | 'standard' | 'gentle' | 'passive'; urgency: 'critical' | 'important' | 'standard' | 'gentle' | 'passive';
duration?: number; duration?: number;
targetTime?: string; targetTime?: string;
@ -109,7 +109,7 @@ export interface RoutineDoc {
description?: string; description?: string;
steps: unknown[]; steps: unknown[];
totalDurationMinutes: number; totalDurationMinutes: number;
status: 'idle' | 'running' | 'paused' | 'completed'; status: 'template' | 'ready' | 'active' | 'paused' | 'completed' | 'cancelled';
isTemplate: boolean; isTemplate: boolean;
category?: string; category?: string;
createdAt: string; createdAt: string;

View File

@ -190,7 +190,7 @@ async function importValidEvents(
label: event.summary, label: event.summary,
targetTime: event.targetTime, targetTime: event.targetTime,
urgency: 'standard', urgency: 'standard',
state: 'idle', state: 'active',
syncVersion: 1, syncVersion: 1,
category: orig?.location ?? undefined, category: orig?.location ?? undefined,
}, },

View File

@ -38,7 +38,7 @@ registerTool({
inputSchema: z.object({ inputSchema: z.object({
id: z.string().min(1).describe('Client-generated timer UUID'), id: z.string().min(1).describe('Client-generated timer UUID'),
label: z.string().min(1).describe('Timer display name'), label: z.string().min(1).describe('Timer display name'),
type: z.enum(['alarm', 'countdown', 'pomodoro', 'event']), type: z.enum(['countdown', 'alarm', 'pomodoro']),
urgency: z.enum(['critical', 'important', 'standard', 'gentle', 'passive']).default('standard'), urgency: z.enum(['critical', 'important', 'standard', 'gentle', 'passive']).default('standard'),
duration: z.coerce.number().optional().describe('Duration in seconds (countdown/pomodoro)'), duration: z.coerce.number().optional().describe('Duration in seconds (countdown/pomodoro)'),
targetTime: z.string().optional().describe('ISO 8601 target time (alarm/event)'), targetTime: z.string().optional().describe('ISO 8601 target time (alarm/event)'),
@ -48,7 +48,7 @@ registerTool({
}), }),
async execute(args, req) { async execute(args, req) {
return chronomindTimerCreate( return chronomindTimerCreate(
{ ...args, state: 'idle' }, { ...args, state: 'active' },
{ token: tokenOf(req), requestId: req.id } { token: tokenOf(req), requestId: req.id }
); );
}, },
@ -59,15 +59,12 @@ registerTool({
registerTool({ registerTool({
name: 'chronomind.timers.list', name: 'chronomind.timers.list',
description: description:
'List cloud-synced timers for the authenticated user. Filter by type (alarm/countdown/pomodoro/event) or state (idle/active/paused/warning/fired/completed). Requires admin role.', 'List cloud-synced timers for the authenticated user. Filter by type (countdown/alarm/pomodoro) or state (active/paused/fired/snoozed/dismissed/completed/warning). Requires admin role.',
requiredRole: 'admin', requiredRole: 'admin',
inputSchema: z.object({ inputSchema: z.object({
type: z type: z.enum(['countdown', 'alarm', 'pomodoro']).optional().describe('Filter by timer type'),
.enum(['alarm', 'countdown', 'pomodoro', 'event'])
.optional()
.describe('Filter by timer type'),
state: z state: z
.enum(['idle', 'active', 'paused', 'warning', 'fired', 'completed']) .enum(['active', 'paused', 'fired', 'snoozed', 'dismissed', 'completed', 'warning'])
.optional() .optional()
.describe('Filter by timer state'), .describe('Filter by timer state'),
limit: z.coerce.number().min(1).max(config.QUERY_MAX_LIMIT).default(config.QUERY_DEFAULT_LIMIT), limit: z.coerce.number().min(1).max(config.QUERY_MAX_LIMIT).default(config.QUERY_DEFAULT_LIMIT),