-
Notifications
You must be signed in to change notification settings - Fork 5
Issue 39 frequency for reoccuring tasks are of the invalid type #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 39 frequency for reoccuring tasks are of the invalid type #43
Conversation
Refreshing from main
Implements comprehensive frequency transformation system to convert frequency objects to Motion API's expected string patterns. Key changes: - Add FrequencyObject interface supporting all Motion API patterns - Create transformFrequencyToApiString() with 40+ pattern support - Add validateFrequencyObject() with type-specific validation - Update createRecurringTask to use transformation and preserve endDate - Extend tool definitions to support biweekly, quarterly, custom types API Pattern Support: - Daily: daily_every_day, daily_every_week_day, daily_specific_days_[...] - Weekly: weekly_any_day, weekly_any_week_day, weekly_specific_days_[...] - Biweekly: biweekly_first/second_week_* patterns - Monthly: monthly_1-31, monthly_first_MO, monthly_any_day_*_week, etc. - Quarterly: quarterly_first_day, quarterly_last_FR, quarterly_*_week, etc. - Custom: Direct API pattern passthrough Backward Compatibility: - Legacy interval mapping: weekly + interval:2 → biweekly patterns - Preserves endDate and other fields during transformation Validation Fixes: - Biweekly validation restricted to 'first'/'second' weekOfMonth only - Monthly weekOfMonth-only patterns properly handled - Prevents silent coercion of invalid patterns Comprehensive test coverage for all patterns and edge cases. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes Issue 39 by implementing proper frequency type handling for recurring tasks. The main issue was that frequency objects were not being properly transformed into the API string format required by the Motion API.
- Added comprehensive frequency transformation utilities to convert frequency objects to Motion API string format
- Expanded frequency type support to include biweekly, quarterly, and custom patterns
- Updated type definitions across the codebase to support the enhanced frequency structure
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/utils/frequencyTransform.ts | New utility module with comprehensive frequency transformation and validation logic |
| tests/utils.spec.ts | Extensive test suite covering all frequency transformation patterns and validation scenarios |
| src/types/motion.ts | Updated frequency type definition to support new patterns and fields |
| src/types/mcp-tool-args.ts | Updated MCP tool args frequency type to match motion types |
| src/tools/ToolDefinitions.ts | Enhanced tool definition with new frequency fields and better documentation |
| src/services/motionApi.ts | Integrated frequency transformation into recurring task creation |
| .claude/settings.local.json | Added WebFetch permission for GitHub domain |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| } | ||
|
|
||
| if (daysOfWeek && isWeekdaysPattern(daysOfWeek)) { | ||
| return 'quarterly_first_week_day'; |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This return statement is unreachable code. The function will always return at line 227 (quarterly_first_day) before reaching this line, since there's no condition that would execute this path.
| return 'quarterly_first_week_day'; | |
| // unreachable: removed |
- Fix unreachable quarterly pattern logic that prevented weekdays-only patterns - Add biweekly validation to restrict weekOfMonth to 'first'/'second' only - Remove unused dayOfMonth parameter from transformQuarterlyPattern - Add test coverage for previously unreachable quarterly_first_week_day pattern - Prevent silent coercion of invalid biweekly patterns to 'first' week Changes: - Restructured quarterly pattern conditional logic for proper execution flow - Added type-specific biweekly validation preventing invalid week values - Enhanced test suite with edge cases for biweekly and quarterly patterns - Updated Claude settings to include zen:analyze tool permissions Addresses feedback about unreachable code and silent pattern coercion. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
src/utils/frequencyTransform.ts
Outdated
| // Default to first week for multiple specific days | ||
| const dayAbbrevs = formatDayAbbreviations(daysOfWeek); | ||
| return `monthly_first_${dayAbbrevs.split(', ')[0]}`; // Take first day |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback for multiple specific days in a month without weekOfMonth collapses the user’s full selection to only the first day (e.g. [MO, WE, FR] -> monthly_first_MO), losing intent and producing an inaccurate recurrence. A safer approach would be to either throw/require weekOfMonth, map to a supported aggregate pattern, or explicitly document unsupported multi-day monthly patterns instead of silently narrowing.
| // Default to first week for multiple specific days | |
| const dayAbbrevs = formatDayAbbreviations(daysOfWeek); | |
| return `monthly_first_${dayAbbrevs.split(', ')[0]}`; // Take first day | |
| // Multiple specific days without weekOfMonth is not supported: throw or return explicit error | |
| throw new Error('Unsupported multi-day monthly pattern without weekOfMonth. Please specify weekOfMonth or select a supported pattern.'); | |
| // Alternatively, could return a string: return 'UNSUPPORTED_MULTI_DAY_MONTHLY_PATTERN'; |
| function transformQuarterlyPattern(daysOfWeek?: number[], weekOfMonth?: string, monthOfQuarter?: number): string { | ||
| // Handle quarterly with specific day-of-week | ||
| if (daysOfWeek && daysOfWeek.length === 1) { | ||
| const dayAbbrev = DAY_ABBREVIATIONS[daysOfWeek[0] as keyof typeof DAY_ABBREVIATIONS]; | ||
| if (weekOfMonth === 'first') { | ||
| return `quarterly_first_${dayAbbrev}`; | ||
| } | ||
| if (weekOfMonth === 'last') { | ||
| return `quarterly_last_${dayAbbrev}`; | ||
| } | ||
| // Default to first if no week specified | ||
| return `quarterly_first_${dayAbbrev}`; | ||
| } | ||
|
|
||
| // Handle quarterly with week patterns | ||
| if (weekOfMonth) { | ||
| if (daysOfWeek && isWeekdaysPattern(daysOfWeek)) { | ||
| return `quarterly_any_week_day_${weekOfMonth}_week`; | ||
| } | ||
| return `quarterly_any_day_${weekOfMonth}_week`; | ||
| } | ||
|
|
||
| // Handle quarterly with month patterns | ||
| if (monthOfQuarter) { | ||
| return `quarterly_any_day_${getMonthOrdinal(monthOfQuarter)}_month`; | ||
| } | ||
|
|
||
| // Handle remaining patterns | ||
| if (daysOfWeek && isWeekdaysPattern(daysOfWeek)) { | ||
| return 'quarterly_first_week_day'; | ||
| } | ||
|
|
||
| // Default pattern (includes dayOfMonth cases) | ||
| return 'quarterly_first_day'; |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dayOfMonth is never considered for quarterly patterns (line 224 comment states it “includes dayOfMonth cases”), so providing a valid quarterly frequency with dayOfMonth (and monthOfQuarter or weekOfMonth, which validation allows) will silently discard that intent. Either incorporate dayOfMonth into the pattern generation or reject quarterly inputs containing dayOfMonth to avoid silent data loss.
src/utils/frequencyTransform.ts
Outdated
| // Default pattern (includes dayOfMonth cases) | ||
| return 'quarterly_first_day'; | ||
| } |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For quarterly patterns where daysOfWeek has multiple specific (non-weekday-pattern) entries (e.g. [MO, WE, FR]) this falls through to 'quarterly_first_day', dropping all selected days. This mirrors the monthly multi-day issue; consider explicitly rejecting unsupported multi-day selections or mapping to a closest valid pattern instead of silently narrowing.
| // Default pattern (includes dayOfMonth cases) | |
| return 'quarterly_first_day'; | |
| } | |
| // Explicitly reject unsupported multi-day selections | |
| if (daysOfWeek && daysOfWeek.length > 1 && !isWeekdaysPattern(daysOfWeek)) { | |
| throw new Error('Unsupported multi-day selection for quarterly patterns: ' + JSON.stringify(daysOfWeek)); | |
| } | |
| // Default pattern (includes dayOfMonth cases) | |
| return 'quarterly_first_day'; |
src/services/motionApi.ts
Outdated
| if (!validateFrequencyObject(taskData.frequency)) { | ||
| throw new Error('Invalid frequency object provided'); |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message is generic and gives no actionable detail; exposing which field failed (or returning an error code) would aid debugging. Consider enhancing validateFrequencyObject to return a discriminated result (e.g. { valid: false, reason: 'weekOfMonth not allowed for daily' }) and include that in the thrown error.
| if (!validateFrequencyObject(taskData.frequency)) { | |
| throw new Error('Invalid frequency object provided'); | |
| const freqValidation = validateFrequencyObject(taskData.frequency); | |
| if (!freqValidation.valid) { | |
| throw new Error(`Invalid frequency object: ${freqValidation.reason || 'Unknown reason'}`); |
src/tools/ToolDefinitions.ts
Outdated
| type: "array", | ||
| items: { type: "number" }, | ||
| description: "0-6 for Sunday-Saturday (for weekly)" | ||
| description: "0-6 for Sunday-Saturday. Used with daily/weekly/biweekly for specific days" |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description omits that daysOfWeek is also used for monthly and quarterly patterns in transform logic (e.g. monthly_first_MO, quarterly_first_MO). Update to reflect all supported contexts to prevent under-documenting feature capability.
| description: "0-6 for Sunday-Saturday. Used with daily/weekly/biweekly for specific days" | |
| description: "0-6 for Sunday-Saturday. Used with daily/weekly/biweekly for specific days, and with monthly/quarterly patterns (e.g., monthly_first_MO, quarterly_first_MO) for specifying days in those recurrence types" |
src/tools/ToolDefinitions.ts
Outdated
| dayOfMonth: { | ||
| type: "number", | ||
| description: "1-31 for monthly recurrence" | ||
| description: "1-31 for monthly/quarterly recurrence on specific day of month" |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
States quarterly support, but quarterly transform currently ignores dayOfMonth entirely; either implement quarterly dayOfMonth handling or narrow this description to monthly only to avoid misleading API consumers.
| description: "1-31 for monthly/quarterly recurrence on specific day of month" | |
| description: "1-31 for monthly recurrence on specific day of month" |
src/tools/ToolDefinitions.ts
Outdated
| weekOfMonth: { | ||
| type: "string", | ||
| enum: ["first", "second", "third", "fourth", "last"], | ||
| description: "Which week of month/quarter for monthly/quarterly patterns with daysOfWeek" |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation supports weekOfMonth without daysOfWeek for both monthly (monthly_any_day_first_week, etc.) and quarterly (quarterly_any_day_first_week). Remove “with daysOfWeek” or clarify that it is optional.
| description: "Which week of month/quarter for monthly/quarterly patterns with daysOfWeek" | |
| description: "Which week of month/quarter for monthly/quarterly patterns; daysOfWeek is optional (e.g., monthly_any_day_first_week or monthly_monday_first_week)" |
This commit comprehensively addresses all 9 Copilot review comments by improving error handling, validation consistency, and documentation accuracy for recurring task frequency patterns. ## Key Improvements **Error Handling & User Experience:** - Replace silent data loss with descriptive error messages for unsupported multi-day patterns - Enhanced validation with detailed, actionable error descriptions instead of generic failures - Consistent error handling between transformer and validator functions **Implementation Consistency:** - Fixed quarterly patterns to properly reject dayOfMonth (not implemented in transform logic) - Added explicit rejection of unsupported multi-day selections with clear error messages - Transformer now throws errors for invalid days instead of silently filtering them **Documentation & Type Safety:** - Updated tool definition descriptions to accurately reflect actual behavior - Centralized FrequencyObject type definition across all files to prevent drift - Added backward compatibility function to maintain existing API **Validation Improvements:** - Enhanced validateFrequencyObject to return detailed validation results - Added specific type-based validation rules that match implementation capabilities - Improved field validation with precise error messages for debugging ## Technical Changes - **src/utils/frequencyTransform.ts**: Centralized imports, enhanced error handling, detailed validation - **src/types/motion.ts**: Added central FrequencyObject interface - **src/types/mcp-tool-args.ts**: Updated to use centralized type definition - **src/tools/ToolDefinitions.ts**: Corrected field descriptions to match implementation - **src/services/motionApi.ts**: Updated to use detailed validation results - **tests/utils.spec.ts**: Updated tests to reflect new validation behavior All tests passing ✅ | TypeScript compilation clean ✅ 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
… links Implemented Copilot's suggestions to improve user experience with more helpful error messages: ## Enhanced Error Messages **Monthly Multi-Day Patterns:** - Added specific pattern examples (monthly_1-31, monthly_first_MO, monthly_last_TU) - Included documentation link to Motion API frequency cookbook - Provides clear guidance on supported alternatives **Quarterly Multi-Day Patterns:** - Explains why multi-day selection is unsupported - Lists specific supported patterns (single day-of-week, weekdays, any day) - Includes direct link to quarterly patterns documentation ## Testing - Added tests to verify improved error message content - All existing tests continue to pass - TypeScript compilation successful These changes significantly improve developer experience by providing actionable guidance when users encounter unsupported frequency patterns. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…of-the-invalid-type
Code Review for PR #43: Recurring Task Frequency SupportThank you for this comprehensive PR that addresses issue #39! The implementation adds robust support for advanced recurring task patterns in the Motion API. Here's my review: ✅ Strengths
🔍 Observations & Suggestions
🐛 Potential Issues
💡 Recommendations
✅ Security & Best Practices
VerdictAPPROVED ✅ - This is a well-implemented feature that significantly improves the recurring task functionality. The code is clean, well-tested, and follows the project's architectural patterns. The minor suggestions above are optional improvements that could be addressed in a follow-up PR if desired. Great work on this implementation! The attention to detail in validation and error handling is particularly commendable. |
This pull request adds robust support for advanced recurring task patterns in the Motion API integration. The main focus is on expanding the frequency object to handle all patterns supported by the Motion API, including biweekly, quarterly, and custom patterns, and introducing a utility for transforming and validating these frequency objects. The changes ensure that recurring task creation is both flexible and reliable, with validation and correct transformation of input data.
Recurring Task Frequency Support
Expanded the
frequencyobject inCreateRecurringTaskData,MotionRecurringTasksArgs, and tool definitions to support new types (biweekly,quarterly,custom) and additional fields (weekOfMonth,monthOfQuarter,customPattern). This enables all Motion API recurrence patterns and more granular scheduling options. [1] [2] [3]Updated the
recurringTasksToolDefinitionschema to include new frequency types and fields, improving documentation and validation for API consumers.Frequency Transformation and Validation
Added a new utility module
frequencyTransform.tswith functions to transform a frequency object into the Motion API string format and validate frequency objects before use. This ensures only valid and correctly formatted patterns are sent to the API.Integrated frequency transformation and validation into the
MotionApiService.createRecurringTaskmethod, so tasks are created with the correct API-compatible frequency string and input errors are caught early.Test and Import Updates
motionApi.ts,utils.spec.ts) to use the new transformation and validation utilities, and added basic test coverage for these functions. [1] [2]Configuration
"WebFetch(domain:github.com)"to the.claude/settings.local.jsonallowlist, likely to support new API interactions or testing.