├── .cursor ├── mcp.json ├── memory.json └── rules │ ├── accurate_timestamps.mdc │ ├── clean_code_priority.mdc │ ├── contributing_workflow.mdc │ ├── cursor_rules.mdc │ ├── docstring_standards.mdc │ ├── documentation.mdc │ ├── git_timestamps.mdc │ ├── pyproject-dependencies.mdc │ ├── refactoring_first.mdc │ ├── self_improve.mdc │ ├── task_completion_workflow.mdc │ ├── tdd_requirements.mdc │ └── test_suite_integrity.mdc ├── .github └── workflows │ └── tests.yml ├── .gitignore ├── .mcp-commit-storyrc.yaml ├── .mcp-commit-storyrc.yaml.example ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── blog-post-7-hour-debugging-cascade-story.md ├── blog-post-castle-unstable-ground.md ├── conftest.py ├── docs ├── README.md ├── ai-context-capture-guide.md ├── ai-provider-setup.md ├── ai_function_pattern.md ├── architecture.md ├── chat-integration-guide.md ├── context-collection.md ├── cursor-chat-api-reference.md ├── cursor-chat-discovery.md ├── cursor-chat-setup-guide.md ├── cursor-db-implementation-notes.md ├── git_diff_collection.md ├── git_hook_background_mode.md ├── implementation-guide.md ├── journal-behavior.md ├── journal-core.md ├── mcp-api-specification.md ├── multi-exporter.md ├── on-demand-directory-pattern.md ├── reflection-core.md ├── server_setup.md ├── setup.md ├── structured-logging.md ├── summary-generation.md ├── telemetry.md └── testing_standards.md ├── engineering-mcp-journal-spec-final.md ├── fictional-user-story.md ├── ideal-daily-summary-prompt.md ├── package-lock.json ├── package.json ├── pyproject.toml ├── pytest.ini ├── sandbox-journal ├── daily │ ├── 2025-05-19-journal.md │ ├── 2025-05-20-journal.md │ ├── 2025-05-21-journal.md │ ├── 2025-05-22-journal.md │ ├── 2025-05-23-journal.md │ ├── 2025-05-24-journal.md │ ├── 2025-05-25-journal.md │ ├── 2025-05-26-journal.md │ ├── 2025-05-27-journal.md │ ├── 2025-05-28-journal.md │ ├── 2025-05-29-journal.md │ ├── 2025-05-30-journal.md │ ├── 2025-05-31-journal.md │ ├── 2025-06-01-journal.md │ ├── 2025-06-02-journal.md │ ├── 2025-06-03-journal.md │ ├── 2025-06-04-journal.md │ ├── 2025-06-05-journal.md │ ├── 2025-06-06-journal.md │ ├── 2025-06-07-journal.md │ ├── 2025-06-08-journal.md │ ├── 2025-06-09-journal.md │ ├── 2025-06-10-journal.md │ ├── 2025-06-11-journal.md │ ├── 2025-06-12-journal.md │ ├── 2025-06-13-journal.md │ ├── 2025-06-14-journal.md │ ├── 2025-06-21-journal.md │ ├── 2025-06-23-journal.md │ ├── 2025-06-24-journal.md │ ├── 2025-06-25-journal.md │ ├── 2025-06-26-journal.md │ ├── 2025-06-27-journal.md │ ├── 2025-06-29-journal.md │ ├── 2025-06-30-journal.md │ ├── 2025-07-01-journal.md │ ├── 2025-07-02-journal.md │ ├── 2025-07-03-journal.md │ ├── 2025-07-04-journal.md │ ├── 2025-07-05-journal.md │ ├── 2025-07-06-journal.md │ ├── 2025-07-07-journal.md │ ├── 2025-07-09-journal.md │ ├── 2025-07-10-journal.md │ ├── 2025-07-11-journal.md │ ├── 2025-07-12-journal.md │ ├── 2025-07-13-journal.md │ ├── 2025-07-14-journal.md │ ├── 2025-07-15-journal.md │ ├── 2025-07-16-journal.md │ ├── 2025-07-17-journal.md │ ├── 2025-07-19-journal.md │ ├── 2025-07-20-journal.md │ ├── 2025-07-21-journal.md │ └── 2025-07-24-journal.md ├── summaries │ ├── daily │ │ ├── 2025-05-19-daily.md │ │ ├── 2025-05-20-daily.md │ │ ├── 2025-05-21-daily.md │ │ ├── 2025-05-22-daily.md │ │ ├── 2025-05-23-daily.md │ │ ├── 2025-05-24-daily.md │ │ ├── 2025-05-25-daily.md │ │ ├── 2025-05-26-daily.md │ │ ├── 2025-05-27-daily.md │ │ ├── 2025-05-28-daily.md │ │ ├── 2025-05-29-daily.md │ │ ├── 2025-05-30-daily.md │ │ ├── 2025-05-31-daily.md │ │ ├── 2025-06-01-daily.md │ │ ├── 2025-06-02-daily.md │ │ ├── 2025-06-03-daily.md │ │ ├── 2025-06-04-daily.md │ │ ├── 2025-06-05-summary.md │ │ ├── 2025-06-06.md │ │ ├── 2025-06-07.md │ │ ├── 2025-06-08.md │ │ ├── 2025-06-09-daily.md │ │ ├── 2025-06-10-summary.md │ │ ├── 2025-06-11-summary.md │ │ ├── 2025-06-12-daily.md │ │ ├── 2025-06-13-daily.md │ │ ├── 2025-06-14-summary.md │ │ ├── 2025-06-21-summary.md │ │ ├── 2025-07-13-summary.md │ │ ├── 2025-07-14-summary.md │ │ ├── 2025-07-15-summary.md │ │ ├── 2025-07-16-summary.md │ │ ├── 2025-07-17-summary.md │ │ └── 2025-07-19-summary.md │ ├── monthly │ │ └── 2025-05.md │ └── weekly │ │ ├── 2025-05-week3.md │ │ ├── 2025-05-week4.md │ │ └── 2025-06-week1.md └── summariesV2 │ ├── daily │ ├── 2025-05-19-summary.md │ ├── 2025-05-20-summary.md │ ├── 2025-05-21-summary.md │ ├── 2025-05-22-summary.md │ ├── 2025-05-23-summary.md │ ├── 2025-05-24-summary.md │ ├── 2025-05-25-summary.md │ ├── 2025-05-26-summary.md │ ├── 2025-05-27-summary.md │ ├── 2025-05-28-summary.md │ ├── 2025-05-29-summary.md │ ├── 2025-05-30-summary.md │ ├── 2025-05-31-summary.md │ ├── 2025-06-01-summary.md │ ├── 2025-06-02-summary.md │ ├── 2025-06-03-summary.md │ ├── 2025-06-04-summary.md │ ├── 2025-06-05-summary.md │ ├── 2025-06-06-summary.md │ ├── 2025-06-07-summary.md │ ├── 2025-06-08-summary.md │ ├── 2025-06-09-summary.md │ ├── 2025-06-10-summary.md │ ├── 2025-06-11-summary.md │ ├── 2025-06-12-summary.md │ ├── 2025-06-13-summary.md │ ├── 2025-06-14-summary.md │ ├── 2025-06-21-summary.md │ ├── 2025-06-23-summary.md │ ├── 2025-06-24-summary.md │ ├── 2025-06-25-summary.md │ ├── 2025-06-26-summary.md │ ├── 2025-06-27-summary.md │ ├── 2025-06-29-summary.md │ ├── 2025-06-30-summary.md │ ├── 2025-07-01-summary.md │ ├── 2025-07-02-summary.md │ ├── 2025-07-03-summary.md │ ├── 2025-07-04-summary.md │ ├── 2025-07-05-summary.md │ ├── 2025-07-06-summary.md │ ├── 2025-07-07-summary.md │ ├── 2025-07-09-summary.md │ ├── 2025-07-10-summary.md │ ├── 2025-07-11-summary.md │ ├── 2025-07-12-summary.md │ ├── 2025-07-13-summary.md │ ├── 2025-07-14-summary.md │ ├── 2025-07-15-summary.md │ ├── 2025-07-16-summary.md │ ├── 2025-07-17-summary.md │ └── 2025-07-19-summary.md │ ├── monthly │ ├── 2025-05.md │ └── 2025-06.md │ └── weekly │ ├── 2025-05-week3.md │ ├── 2025-05-week4.md │ ├── 2025-06-week1.md │ ├── 2025-06-week2.md │ ├── 2025-06-week3.md │ ├── 2025-06-week4.md │ ├── 2025-07-week1.md │ ├── 2025-07-week2.md │ └── 2025-07-week3.md ├── scripts ├── agent_model_test_harness.py ├── analyze_message_counts.py ├── archive_completed_tasks.py ├── example_prd.txt ├── explore_cursor_databases.py ├── mcp-commit-story-prd.md ├── message_limit_research_findings.txt ├── run_tests.sh └── setup_test_env.sh ├── src └── mcp_commit_story │ ├── __init__.py │ ├── __main__.py │ ├── ai_context_filter.py │ ├── ai_function_executor.py.backup │ ├── ai_invocation.py │ ├── ai_provider.py │ ├── background_journal_worker.py │ ├── chat_context_manager.py │ ├── cli.py │ ├── commit_time_window.py │ ├── composer_chat_provider.py │ ├── config.py │ ├── context_collection.py │ ├── context_types.py │ ├── cursor_db │ ├── __init__.py │ ├── composer_integration.py │ ├── connection.py │ ├── exceptions.py │ ├── message_extraction.py │ ├── message_limiting.py │ ├── multiple_database_discovery.py │ ├── platform.py │ ├── query_executor.py │ ├── validation.py │ └── workspace_detection.py │ ├── daily_summary.py │ ├── daily_summary_standalone.py │ ├── git_hook_worker.py │ ├── git_utils.py │ ├── journal │ ├── __init__.py │ ├── models.py │ ├── sections │ │ └── __init__.py │ └── telemetry_utils.py │ ├── journal_ai_utilities.py │ ├── journal_generate.py │ ├── journal_handlers.py │ ├── journal_init.py │ ├── journal_orchestrator.py │ ├── journal_workflow.py │ ├── journal_workflow_types.py │ ├── monthly_summary.py │ ├── multi_exporter.py │ ├── quarterly_summary.py │ ├── reflection_core.py │ ├── server.py │ ├── structured_logging.py │ ├── summary_utils.py │ ├── telemetry.py │ ├── weekly_summary.py │ └── yearly_summary.py ├── talk_plan_how_to_trust_a_liar.md ├── tasks ├── completed_tasks │ ├── completed_tasks.json │ ├── task_001.txt │ ├── task_002.txt │ ├── task_003.txt │ ├── task_004.txt │ ├── task_005.txt │ ├── task_006.txt │ ├── task_007.txt │ ├── task_008.txt │ ├── task_009.txt │ ├── task_010.txt │ ├── task_014.txt │ ├── task_016.txt │ ├── task_018.txt │ ├── task_020.txt │ ├── task_023.txt │ ├── task_024.txt │ ├── task_025.txt │ ├── task_027.txt │ ├── task_035.txt │ ├── task_036.txt │ ├── task_037.txt │ ├── task_045.txt │ ├── task_046.txt │ ├── task_047.txt │ ├── task_048.txt │ ├── task_050.txt │ ├── task_051.txt │ ├── task_053.txt │ ├── task_055.txt │ ├── task_056.txt │ ├── task_057.txt │ ├── task_059.txt │ ├── task_061.txt │ ├── task_062.txt │ ├── task_064.txt │ ├── task_067.txt │ ├── task_069.txt │ ├── task_073.txt │ └── tasks.json ├── task_011.txt ├── task_012.txt ├── task_013.txt ├── task_015.txt ├── task_019.txt ├── task_021.txt ├── task_022.txt ├── task_026.txt ├── task_029.txt ├── task_030.txt ├── task_031.txt ├── task_032.txt ├── task_033.txt ├── task_037.txt ├── task_042.txt ├── task_043.txt ├── task_044.txt ├── task_052.txt ├── task_063.txt ├── task_065.txt ├── task_066.txt ├── task_068.txt ├── task_070.txt ├── task_071.txt ├── task_072.txt ├── task_074.txt ├── task_075.txt ├── task_076.txt ├── task_077.txt ├── task_078.txt └── task_080.txt └── tests ├── conftest.py ├── fixtures ├── .keep ├── cursor_databases │ ├── create_test_databases.py │ ├── test_global.vscdb │ └── test_workspace.vscdb └── summary_test_data.py ├── integration ├── .keep ├── test_ai_config_integration.py ├── test_ai_context_capture_integration.py ├── test_ai_filtering_real_data.py ├── test_bubbleid_preservation.py ├── test_composer_integration.py ├── test_composer_performance.py ├── test_composer_smoke.py ├── test_cursor_db_integration.py ├── test_daily_summary_consolidation.py ├── test_daily_summary_end_to_end.py ├── test_daily_summary_integration.py ├── test_git_diff_integration.py ├── test_git_hook_integration.py ├── test_journal_init_integration.py ├── test_mcp_cli_integration.py ├── test_mcp_server_integration.py ├── test_multi_database_integration.py ├── test_reflection_integration.py ├── test_signal_architecture_removal.py └── test_telemetry_validation_integration.py ├── test_datadog_enhancement.py ├── test_journal_entry.py ├── test_journal_orchestrator.py ├── test_journal_telemetry.py ├── test_mcp_server_telemetry_integration.py ├── test_multi_exporter_config.py ├── test_reflection_core.py ├── test_structured_logging.py ├── test_structured_logging_integration.py ├── test_telemetry.py ├── test_telemetry_integration.py └── unit ├── test_agent_model_documentation.py ├── test_agent_model_framework.py ├── test_agent_model_metrics.py ├── test_agent_model_validation.py ├── test_ai_context_filter.py ├── test_ai_context_integration.py ├── test_ai_invocation.py ├── test_ai_invocation_config.py ├── test_ai_telemetry.py ├── test_boundary_detection.py ├── test_capture_context_handler.py ├── test_capture_context_mcp_handler.py ├── test_chat_context_manager.py ├── test_cli.py ├── test_cli_install_hook.py ├── test_cli_limitations.py ├── test_collect_git_context_parameter_fix.py ├── test_collect_recent_journal_context.py ├── test_commit_time_window.py ├── test_composer_chat_provider.py ├── test_composer_error_handling.py ├── test_composer_multi_field_extraction.py ├── test_composer_session_ordering.py ├── test_config.py ├── test_config_ai_section.py ├── test_config_env_interpolation.py ├── test_config_telemetry.py ├── test_context_collection.py ├── test_context_collection_telemetry.py ├── test_context_types.py ├── test_cursor_db_exceptions.py ├── test_cursor_db_incremental_processing.py ├── test_cursor_db_query_executor.py ├── test_cursor_db_telemetry.py ├── test_daily_summary.py ├── test_database_discovery_bug.py ├── test_documentation_completeness.py ├── test_error_handling.py ├── test_file_operation_compliance.py ├── test_file_operations.py ├── test_git_context_posixpath_bug.py ├── test_git_diff_collection.py ├── test_git_hook_daily_summary.py ├── test_git_hook_installation.py ├── test_git_hook_worker_journal_integration.py ├── test_git_utils.py ├── test_imports.py ├── test_journal.py ├── test_journal_ai_generators.py ├── test_journal_context_telemetry.py ├── test_journal_entry_generation.py ├── test_journal_file_operations.py ├── test_journal_init.py ├── test_journal_integration.py ├── test_journal_json_parsing_fix.py ├── test_journal_sections_utilities.py ├── test_journal_utils.py ├── test_journal_workflow_types.py ├── test_mcp_server_entry_point.py ├── test_message_extraction.py ├── test_message_limiting.py ├── test_multi_database_chat_extraction.py ├── test_multiple_database_discovery.py ├── test_openai_provider.py ├── test_openai_provider_config.py ├── test_platform_detection.py ├── test_platform_detection_telemetry.py ├── test_pyproject.py ├── test_query_cursor_chat_database_composer.py ├── test_reflection_format.py ├── test_reflection_mcp.py ├── test_sanitize_chat_content.py ├── test_server.py ├── test_structure.py ├── test_summary_source_links.py ├── test_telemetry_decorator_functionality.py ├── test_validation.py ├── test_workspace_detection.py └── test_workspace_path_detection.py /.cursor/mcp.json: -------------------------------------------------------------------------------- 1 | { 2 | "mcpServers": { 3 | "memory": { 4 | "command": "npx", 5 | "args": [ 6 | "-y", 7 | "@modelcontextprotocol/server-memory" 8 | ], 9 | "env": { 10 | "MEMORY_FILE_PATH": "./.cursor/memory.json" 11 | } 12 | }, 13 | "taskmaster-ai": { 14 | "command": "npx", 15 | "args": [ 16 | "-y", 17 | "--package=task-master-ai", 18 | "task-master-ai" 19 | ], 20 | "env": { 21 | "MODEL": "claude-3-7-sonnet-20250219", 22 | "PERPLEXITY_MODEL": "sonar-pro", 23 | "MAX_TOKENS": 64000, 24 | "TEMPERATURE": 0.2, 25 | "DEFAULT_SUBTASKS": 5, 26 | "DEFAULT_PRIORITY": "medium", 27 | "ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}" 28 | } 29 | }, 30 | "context7": { 31 | "command": "npx", 32 | "args": [ 33 | "-y", 34 | "@upstash/context7-mcp" 35 | ] 36 | }, 37 | "commit-story": { 38 | "command": "/Users/whitney.lee/.pyenv/shims/python", 39 | "args": ["-m", "mcp_commit_story"], 40 | "cwd": "/Users/whitney.lee/Documents/Repositories/mcp-commit-story", 41 | "env": { 42 | "LOG_LEVEL": "INFO" 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /.cursor/memory.json: -------------------------------------------------------------------------------- 1 | {"type":"entity","name":"numbered list change proposal preference","entityType":"user preference","observations":["When proposing multiple changes, present them as a numbered list."]} 2 | {"type":"entity","name":"memorize keyword meaning (project-local)","entityType":"user instruction","observations":["When I say 'memorize', I mean to add it to this project's memory.json."]} 3 | {"type":"entity","name":"user workflow and response preferences (project-local)","entityType":"user instruction","observations":["Terminal commands should be formatted as clickable bash code blocks.","Automatic execution of commands via tools is acceptable.","When I say 'sync changes' I want a git workflow where the git commands add, commit, and push are proposed individually for approval and execution, as clickable bash code blocks. To recap: When the user says 'Sync changes,' perform the full git status, add all staged/unstaged tracked changes, commit with a generated message (or prompt for one if needed), and push sequence.","Always preserve image aspect ratios.","Provide detailed explanations for steps.","Evaluate user requests against good practices & Inform the user if a request goes against good practices and suggest alternatives.","Always use Context7 tools for current documentation on libraries/frameworks before implementation or discussion.","When a Taskmaster plan involves making a change, explicitly include one or more verification steps for that change.","Prioritize factual accuracy over creativity.","Cross-reference information with multiple sources before presenting as fact.","Clearly state when information is speculative or inferred.","Avoid making assumptions or filling in gaps with unverified details.","Focus on information directly present in provided context or established knowledge.","If evidence is weak or contradictory, point this out.","Prefer to state 'I don't know' over providing a potentially incorrect answer.","Break down complex queries into smaller, manageable parts.","DO NOT add extra features or style elements that weren't explicitly requested.","Focus only on implementing exactly what was asked for, nothing more.","If uncertain about a requirement, ask for clarification rather than guessing.","if github is needed, use the gh cli tool."]} 4 | {"text": "After any subtask is marked 'done' or 'complete', sync changes (git add, commit, push).", "timestamp": "2024-06-07T17:23:00Z"} -------------------------------------------------------------------------------- /.cursor/rules/accurate_timestamps.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Always check actual system time before using timestamps in documentation, changelogs, and manual entries 3 | globs: *.md, *.py, *.json, *.txt 4 | alwaysApply: true 5 | --- 6 | 7 | # Accurate Timestamp Usage Rule 8 | 9 | **Always verify actual system time before writing any timestamp in documentation, changelogs, analysis documents, or any manual time entries.** 10 | 11 | ## Core Principle 12 | 13 | - **NEVER guess or assume dates/times** 14 | - **ALWAYS check system time first: `date` command or equivalent** 15 | - **Include both date AND time for same-day tracking** 16 | - **Use timezone abbreviation for clarity** 17 | 18 | ## Implementation Patterns 19 | 20 | ### ✅ DO: Check System Time First 21 | 22 | ```bash 23 | # Always run this first 24 | date 25 | # Output: Fri Jul 11 07:39:24 CDT 2025 26 | 27 | # Then use in documentation 28 | ### Subtask 63.1 Completed - 2025-07-11 07:39 CDT 29 | ``` 30 | 31 | ### ✅ DO: Include Date and Time 32 | 33 | ```markdown 34 | # ✅ Good - includes date and time for same-day tracking 35 | ### Subtask 63.1 Completed - 2025-07-11 07:39 CDT 36 | ### Subtask 63.2 Completed - 2025-07-11 09:15 CDT 37 | 38 | # ✅ Good - for longer intervals, date may be sufficient 39 | ### Task 63 Completed - 2025-07-11 40 | ``` 41 | 42 | ### ✅ DO: Use Consistent Format 43 | 44 | ```markdown 45 | # ✅ Consistent format across all entries 46 | - 2025-07-11 07:39 CDT 47 | - 2025-07-11 09:15 CDT 48 | - 2025-07-11 14:22 CDT 49 | ``` 50 | 51 | ### ❌ DON'T: Guess or Assume Timestamps 52 | 53 | ```markdown 54 | # ❌ Wrong - guessing dates 55 | ### Subtask 63.1 Completed - 2025-01-27 56 | 57 | # ❌ Wrong - vague time references 58 | ### Completed this morning 59 | 60 | # ❌ Wrong - no time for same-day tracking 61 | ### Subtask 63.1 Completed - 2025-07-11 62 | ### Subtask 63.2 Completed - 2025-07-11 63 | ``` 64 | 65 | ## When This Rule Applies 66 | 67 | ### **Documentation Updates** 68 | - Changelogs in analysis documents 69 | - Task completion tracking 70 | - README updates with timestamps 71 | - Any manual documentation entry 72 | 73 | ### **Code Comments with Timestamps** 74 | - TODO comments with dates 75 | - Bug fix timestamps 76 | - Implementation notes with timing 77 | 78 | ### **Configuration and Data Files** 79 | - JSON files with timestamp fields 80 | - Configuration updates 81 | - Manual data entries 82 | 83 | ## Required Process 84 | 85 | 1. **Before writing any timestamp:** 86 | ```bash 87 | date 88 | ``` 89 | 90 | 2. **Extract the relevant parts:** 91 | - Date: 2025-07-11 92 | - Time: 07:39 93 | - Timezone: CDT 94 | 95 | 3. **Format consistently:** 96 | - Full: `2025-07-11 07:39 CDT` 97 | - Date only (for longer intervals): `2025-07-11` 98 | 99 | ## Examples in Context 100 | 101 | ### **Analysis Documents** 102 | ```markdown 103 | ## Changelog 104 | ### Subtask 63.1 Completed - 2025-07-11 07:39 CDT 105 | - Initial analysis completed 106 | - Identified 18 total items 107 | 108 | ### Subtask 63.2 Completed - 2025-07-11 09:15 CDT 109 | - Created module structure 110 | - Moved core classes 111 | ``` 112 | 113 | ### **Task Updates** 114 | ```json 115 | { 116 | "lastUpdated": "2025-07-11 07:39 CDT", 117 | "completedAt": "2025-07-11 07:39 CDT" 118 | } 119 | ``` 120 | 121 | ### **Code Comments** 122 | ```python 123 | # Fixed circular import issue - 2025-07-11 07:39 CDT 124 | # TODO: Refactor this pattern - 2025-07-11 07:39 CDT 125 | ``` 126 | 127 | ## Benefits 128 | 129 | - **Accuracy**: No more wrong dates/times 130 | - **Same-day tracking**: Can distinguish between subtasks completed on the same day 131 | - **Timezone clarity**: Clear what timezone the work was done in 132 | - **Professional**: Demonstrates attention to detail 133 | 134 | ## Related Rules 135 | 136 | - [Git Timestamps](mdc:.cursor/rules/git_timestamps.mdc) - for git-related operations 137 | - [Documentation](mdc:.cursor/rules/documentation.mdc) - for general doc standards 138 | -------------------------------------------------------------------------------- /.cursor/rules/clean_code_priority.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Prioritize clean code and maintainability over backwards compatibility since there are no external users 3 | globs: src/**/*.py, tests/**/*.py, **/*.py 4 | alwaysApply: true 5 | --- 6 | 7 | ## Clean Code Over Backwards Compatibility 8 | 9 | **This project has no external users - prioritize code quality over compatibility.** 10 | 11 | - **Breaking Changes Are Acceptable** 12 | - Refactor freely to improve code structure 13 | - Remove deprecated patterns without transition periods 14 | - Rename functions, classes, and modules for clarity 15 | - Change APIs to be more intuitive or consistent 16 | 17 | - **Code Quality Principles** 18 | - **DRY (Don't Repeat Yourself)**: Remove duplicate code aggressively 19 | - **KISS (Keep It Simple, Stupid)**: Simplify complex implementations 20 | - **Single Responsibility**: Split overly complex functions/classes 21 | - **Clear Naming**: Use descriptive names even if it requires breaking changes 22 | 23 | - **Refactoring Guidelines** 24 | - Remove dead code immediately rather than deprecating 25 | - Consolidate similar functions into cleaner interfaces 26 | - Extract common patterns into reusable utilities 27 | - Fix import paths and module organization without compatibility layers 28 | 29 | - **Examples of Clean Code Priority** 30 | ```python 31 | # ✅ DO: Clean, direct approach 32 | from mcp_commit_story.journal_generate import generate_summary_section 33 | 34 | # ❌ DON'T: Backwards compatibility shims 35 | # Re-export old function names "for compatibility" 36 | from mcp_commit_story.journal import old_function_name as generate_summary_section 37 | ``` 38 | 39 | - **When This Rule Applies** 40 | - **Always** - until the project has external users 41 | - During refactoring and code organization 42 | - When fixing import paths and module structure 43 | - When consolidating duplicate functionality 44 | 45 | - **When To Reconsider** 46 | - Once external users depend on the APIs 47 | - When the project reaches stable release (1.0+) 48 | - If breaking changes would affect documented public interfaces 49 | 50 | - **Implementation Strategy** 51 | - Make changes in focused commits for easy tracking 52 | - Update all references systematically in the same change 53 | - Remove old patterns completely rather than leaving them 54 | - Prioritize readability and maintainability in all decisions 55 | 56 | **Remember**: Clean, maintainable code is more valuable than compatibility when there are no users to break. 57 | -------------------------------------------------------------------------------- /.cursor/rules/cursor_rules.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness 3 | globs: .cursor/rules/*.mdc 4 | alwaysApply: true 5 | --- 6 | # Cursor Rules Structure and Maintenance 7 | 8 | ## Subtask Execution Flow 9 | When working on subtasks: 10 | - **Complete each subtask fully without pausing for approval** unless the subtask explicitly contains the phrase "PAUSE FOR MANUAL APPROVAL" or similar explicit instructions to stop and ask for approval 11 | - Follow appropriate structure based on subtask type (see [tdd_requirements.mdc](mdc:.cursor/rules/tdd_requirements.mdc)) 12 | - **Pause only between subtasks** to confirm the next one to work on 13 | - When you see phrases like "GET APPROVAL FOR DESIGN CHOICES", "PAUSE FOR MANUAL APPROVAL", or similar explicit instructions to stop, pause and ask for approval on those specific items only 14 | - Never ask for approval on implementation details that aren't marked for approval 15 | 16 | ## Automatic Documentation and Completion 17 | At the end of each subtask automatically: 18 | - Add documentation following [documentation.mdc](mdc:.cursor/rules/documentation.mdc) standards 19 | - Do not remove existing information unless it's incorrect 20 | - Do not ask for approval on documentation changes 21 | - Double check all subtask requirements are met 22 | - If all requirements are met, mark the subtask complete 23 | - Only ask for help if you can't determine whether requirements are met 24 | 25 | ## Explicit Approval Pauses 26 | - **If a subtask plan contains 'PAUSE FOR MANUAL APPROVAL' or similar instructions, always pause and request approval at that step, even if general rules say to proceed.** 27 | - After writing failing tests and a stub, check the subtask plan for required approval points before implementing. 28 | - Echo the next step and approval checkpoint to the user before proceeding. 29 | - Summarize required approval points at the start of each subtask. 30 | - This rule takes precedence over general 'no approval needed' rules. 31 | 32 | ## Rule Structure Guidelines 33 | 34 | ### Required Rule Structure 35 | ```markdown 36 | --- 37 | description: Clear, one-line description of what the rule enforces 38 | globs: path/to/files/*.ext, other/path/**/* 39 | alwaysApply: boolean 40 | --- 41 | 42 | - **Main Points in Bold** 43 | - Sub-points with details 44 | - Examples and explanations 45 | ``` 46 | 47 | ### File References 48 | - Use `[filename](mdc:path/to/file)` ([filename](mdc:filename)) to reference files 49 | - Example: [prisma.mdc](mdc:.cursor/rules/prisma.mdc) for rule references 50 | - Example: [schema.prisma](mdc:prisma/schema.prisma) for code references 51 | 52 | ### Code Examples 53 | - Use language-specific code blocks 54 | ```typescript 55 | // ✅ DO: Show good examples 56 | const goodExample = true; 57 | 58 | // ❌ DON'T: Show anti-patterns 59 | const badExample = false; 60 | ``` 61 | 62 | ### Rule Content Guidelines 63 | - Start with high-level overview 64 | - Include specific, actionable requirements 65 | - Show examples of correct implementation 66 | - Reference existing code when possible 67 | - Keep rules DRY by referencing other rules 68 | 69 | ### Rule Maintenance 70 | - Update rules when new patterns emerge 71 | - Add examples from actual codebase 72 | - Remove outdated patterns 73 | - Cross-reference related rules 74 | 75 | ### Best Practices 76 | - Use bullet points for clarity 77 | - Keep descriptions concise 78 | - Include both DO and DON'T examples 79 | - Reference actual code over theoretical examples 80 | - Use consistent formatting across rules 81 | - **Present options as numbered lists** 82 | - When offering the user a set of choices, always use numbers (1., 2., 3., etc.) so the user can quickly respond with a number. 83 | - This improves response speed and clarity for the user. 84 | -------------------------------------------------------------------------------- /.cursor/rules/docstring_standards.mdc: -------------------------------------------------------------------------------- 1 | # Docstring Standards 2 | 3 | ## Core Principle 4 | **Write docstrings that are succinct and direct - avoid verbose explanations.** 5 | 6 | ## Docstring Requirements 7 | - **Succinct communication** - Essential information only, no verbose explanations 8 | - **Direct language** - Get to the point quickly 9 | - **Follow @documentation forbidden content rules**: 10 | - No task references or historical processes 11 | - No abstract corporate speak 12 | - No development journey narratives 13 | - **External reader accessible** - Assume zero project knowledge but keep it brief 14 | - **Practical focus** - What they need to know, not extensive examples 15 | 16 | ## Structure Guidelines 17 | - **Brief description** - One clear sentence about what the function does 18 | - **Essential args/returns** - Key parameters and return values only 19 | - **Minimal examples** - Only when necessary for clarity 20 | - **No extensive prerequisites** - Basic requirements only 21 | 22 | ## Examples 23 | 24 | ### ✅ Good Docstring 25 | ```python 26 | def generate_daily_summary(date: str) -> Optional[DailySummary]: 27 | """Generate a daily summary from journal entries. 28 | 29 | Args: 30 | date: Date string in YYYY-MM-DD format. 31 | 32 | Returns: 33 | DailySummary object or None if no entries found. 34 | """ 35 | ``` 36 | 37 | ### ❌ Avoid Verbose Docstrings 38 | ```python 39 | def generate_daily_summary(date: str) -> Optional[DailySummary]: 40 | """Generate a daily summary from journal entries. 41 | 42 | This function orchestrates the complete workflow for generating daily summaries 43 | from journal entries. It handles the entire process from loading configuration 44 | to processing entries through AI and saving the final formatted results. 45 | 46 | ## Prerequisites 47 | - Journal files must exist in the expected directory structure 48 | - Configuration file must be properly set up with journal paths 49 | - AI provider must be configured with valid API keys 50 | 51 | ## Usage Examples 52 | ```python 53 | # Generate for today 54 | summary = generate_daily_summary("2025-01-15") 55 | 56 | # Handle the result 57 | if summary: 58 | print(f"Generated: {summary['summary']}") 59 | else: 60 | print("No entries found") 61 | ``` 62 | 63 | ## Technical Context 64 | This function was created to replace the MCP-based approach... 65 | """ 66 | ``` 67 | 68 | ## Apply to Docstrings Only 69 | - **These standards apply specifically to docstrings** - not other documentation 70 | - **Other documentation** (README, docs/) can be more comprehensive 71 | - **Code comments** can be brief but don't need to follow these specific rules 72 | - **Module docstrings** should be concise but can include essential usage examples 73 | 74 | ## Quality Check 75 | **Could a developer understand and use this function from the docstring alone, without reading a manual?** 76 | -------------------------------------------------------------------------------- /.cursor/rules/documentation.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Documentation standards requiring external-reader accessibility and concrete language 3 | globs: **/*.md, **/docs/**, **/*.rst, **/*.txt 4 | alwaysApply: true 5 | --- 6 | 7 | # Documentation Standards 8 | 9 | ## Core Principle 10 | **Write for a future developer with zero project knowledge who needs to understand and modify this system.** 11 | 12 | ## Some Possible Elements 13 | - **Function-level docstrings** for all new functions following the core principle 14 | - **Module-level docstrings** for new modules explaining their purpose and approach 15 | - **Complete examples** that are copy-pasteable and work 16 | - **Technical context** explaining why decisions were made when it affects future changes 17 | - **Prerequisites**: What they need to install/know first 18 | - **Clear steps**: How to use, modify, or extend 19 | 20 | ## Documentation Updates for Code Changes 21 | - **Evaluate existing documentation** before creating new files - determine if new information should be added to existing docs rather than creating separate files 22 | - **When code is changed** (as opposed to net-new), these must be evaluated and updated if needed: 23 | - Documentation files 24 | - README.md 25 | - Engineering specifications 26 | - PRD (Product Requirements Document) 27 | 28 | ## Forbidden Content 29 | - **Process references**: No task IDs, sprint numbers, team workflows 30 | - **Historical narrative**: Skip "we tried X then Y" stories 31 | - **Assumed knowledge**: No insider team decisions or project history 32 | - **Personal references**: No names, meetings, or timeline details 33 | - **Abstract corporate speak**: Use concrete problem descriptions instead 34 | - **Meaningless task references**: Describe actual accomplishments, not task numbers 35 | 36 | ## Writing Style Requirements 37 | - **Specific, concrete language** - avoid abstract buzzwords 38 | - **Real problem/solution statements** - not theoretical concepts 39 | - **External reader accessibility** - assume no prior project context 40 | - **Focus on what's happening** - not the development journey 41 | 42 | ## Quality Test 43 | **Could a new developer use this documentation successfully without asking questions?** 44 | 45 | ## Examples 46 | 47 | ### ✅ Good 48 | ```markdown 49 | # Email Service 50 | 51 | ## Prerequisites 52 | - Node.js 18+, environment vars: `SMTP_HOST`, `SMTP_USER`, `SMTP_PASS` 53 | 54 | ## Usage 55 | ```javascript 56 | import { sendEmail } from './email-service'; 57 | await sendEmail('user@example.com', 'Welcome!', template); 58 | ``` 59 | 60 | ## Configuration 61 | - `TIMEOUT=10000`: 10s timeout prevents hanging on slow SMTP servers 62 | ``` 63 | 64 | ### ❌ Bad 65 | ```markdown 66 | # Email Service 67 | After task #45, the team decided on nodemailer. Sarah's timeout fix solved our production issues. 68 | ``` 69 | -------------------------------------------------------------------------------- /.cursor/rules/pyproject-dependencies.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: 3 | globs: 4 | alwaysApply: false 5 | --- 6 | ## **pyproject.toml Dependency Management** 7 | 8 | - **Critical Rule: All Production Dependencies Must Be in pyproject.toml** 9 | - CI environment ONLY installs from `pyproject.toml` main dependencies section 10 | - Never rely on `requirements.txt` or other dependency files for production code 11 | - Dev dependencies go in `[project.optional-dependencies.dev]` section 12 | 13 | - **When to Update pyproject.toml Dependencies:** 14 | - **Every time you add a new import statement** in production code (`src/` directory) 15 | - **When adding new test dependencies** that import external packages 16 | - **Before committing code that uses new libraries** 17 | - **When CI fails with ModuleNotFoundError but tests pass locally** 18 | 19 | - **Common CI Failure Pattern Recognition:** 20 | ```bash 21 | # CI Error Pattern: 22 | ModuleNotFoundError: No module named 'some_package' 23 | # But locally: tests pass ✅ 24 | 25 | # Root Cause: Package installed locally but missing from pyproject.toml 26 | # Solution: Add to main dependencies section 27 | ``` 28 | 29 | - **Dependency Addition Checklist:** 30 | ```python 31 | # ✅ DO: When you add imports like this 32 | from opentelemetry.exporter.prometheus import PrometheusMetricReader 33 | from opentelemetry.instrumentation.requests import RequestsInstrumentor 34 | 35 | # ✅ DO: Immediately add to pyproject.toml 36 | dependencies = [ 37 | "opentelemetry-exporter-prometheus>=0.54b0", 38 | "opentelemetry-instrumentation-requests>=0.41b0", 39 | ] 40 | ``` 41 | 42 | - **Version Specification Best Practices:** 43 | - **Research actual available versions** on PyPI before specifying 44 | - **Don't assume version patterns** across related packages (e.g., OpenTelemetry packages have different schemes) 45 | - **Check for yanked versions** if you get "no matching distribution" errors 46 | - **Use conservative version constraints** (`>=X.Y.Z`) rather than exact pins for libraries 47 | 48 | - **Local vs CI Environment Differences:** 49 | - **Local development** often has extra packages from manual installs, requirements.txt, or previous environments 50 | - **CI is clean** and only installs what's explicitly declared in pyproject.toml 51 | - **Always test dependency changes** with a clean virtual environment when possible 52 | - **Push dependency updates immediately** after adding new imports to catch issues early 53 | 54 | - **Error Resolution Workflow:** 55 | 1. **CI fails with ModuleNotFoundError** → Check if package is in pyproject.toml main dependencies 56 | 2. **Local tests pass but CI fails** → Almost always a missing dependency issue 57 | 3. **"No matching distribution found"** → Check available versions on PyPI, look for yanked versions 58 | 4. **Import works locally** → Verify the package name and version in pyproject.toml 59 | 60 | - **Prevention Strategy:** 61 | - **Add dependencies BEFORE writing the import** when possible 62 | - **Use `pip install package-name` AND update pyproject.toml** when adding new packages 63 | - **Review imports in every commit** to ensure corresponding dependencies exist 64 | - **Test in clean environments** periodically to catch environment drift 65 | 66 | - **Examples from This Project:** 67 | ```python 68 | # ❌ DON'T: Add imports without updating pyproject.toml 69 | from opentelemetry.exporter.prometheus import PrometheusMetricReader # CI will fail! 70 | 71 | # ✅ DO: Add import AND update pyproject.toml 72 | from opentelemetry.exporter.prometheus import PrometheusMetricReader 73 | # In pyproject.toml: "opentelemetry-exporter-prometheus>=0.54b0" 74 | ``` 75 | 76 | - **Historical Issues Resolved:** 77 | - **Auto-instrumentation packages** (requests, aiohttp, asyncio, logging instrumentors) 78 | - **Prometheus exporter** with version specification corrections 79 | - **Pattern**: Code worked locally, CI failed on import, fixed by adding to pyproject.toml 80 | 81 | This rule prevents the "works on my machine" problem that has caused multiple CI failures in this project. 82 | -------------------------------------------------------------------------------- /.cursor/rules/self_improve.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Guidelines for continuously improving Cursor rules based on emerging code patterns and best practices. 3 | globs: **/* 4 | alwaysApply: true 5 | --- 6 | 7 | - **Rule Improvement Triggers:** 8 | - New code patterns not covered by existing rules 9 | - Repeated similar implementations across files 10 | - Common error patterns that could be prevented 11 | - New libraries or tools being used consistently 12 | - Emerging best practices in the codebase 13 | 14 | - **Analysis Process:** 15 | - Compare new code with existing rules 16 | - Identify patterns that should be standardized 17 | - Look for references to external documentation 18 | - Check for consistent error handling patterns 19 | - Monitor test patterns and coverage 20 | 21 | - **Rule Updates:** 22 | - **Add New Rules When:** 23 | - A new technology/pattern is used in 3+ files 24 | - Common bugs could be prevented by a rule 25 | - Code reviews repeatedly mention the same feedback 26 | - New security or performance patterns emerge 27 | 28 | - **Modify Existing Rules When:** 29 | - Better examples exist in the codebase 30 | - Additional edge cases are discovered 31 | - Related rules have been updated 32 | - Implementation details have changed 33 | 34 | - **Example Pattern Recognition:** 35 | ```typescript 36 | // If you see repeated patterns like: 37 | const data = await prisma.user.findMany({ 38 | select: { id: true, email: true }, 39 | where: { status: 'ACTIVE' } 40 | }); 41 | 42 | // Consider adding to [prisma.mdc](mdc:.cursor/rules/prisma.mdc): 43 | // - Standard select fields 44 | // - Common where conditions 45 | // - Performance optimization patterns 46 | ``` 47 | 48 | - **Rule Quality Checks:** 49 | - Rules should be actionable and specific 50 | - Examples should come from actual code 51 | - References should be up to date 52 | - Patterns should be consistently enforced 53 | 54 | - **Continuous Improvement:** 55 | - Monitor code review comments 56 | - Track common development questions 57 | - Update rules after major refactors 58 | - Add links to relevant documentation 59 | - Cross-reference related rules 60 | 61 | - **Rule Deprecation:** 62 | - Mark outdated patterns as deprecated 63 | - Remove rules that no longer apply 64 | - Update references to deprecated rules 65 | - Document migration paths for old patterns 66 | 67 | - **Documentation Updates:** 68 | - Keep examples synchronized with code 69 | - Update references to external docs 70 | - Maintain links between related rules 71 | - Document breaking changes 72 | Follow [cursor_rules.mdc](mdc:.cursor/rules/cursor_rules.mdc) for proper rule formatting and structure. 73 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | python-version: ['3.10', '3.11'] 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Set up Python ${{ matrix.python-version }} 20 | uses: actions/setup-python@v4 21 | with: 22 | python-version: ${{ matrix.python-version }} 23 | 24 | - name: Configure Git for tests 25 | run: | 26 | git config --global user.name "CI Test Runner" 27 | git config --global user.email "ci@test.example.com" 28 | 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip 32 | python -m pip install -e ".[dev]" 33 | 34 | - name: Test with pytest 35 | run: | 36 | python -m pytest --cov=src 37 | 38 | - name: Upload coverage to Codecov 39 | uses: codecov/codecov-action@v3 40 | with: 41 | file: ./coverage.xml 42 | fail_ci_if_error: false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .mcp-commit-storyrc.yaml # Ignore local configuration 3 | # But track the example configuration 4 | !.mcp-commit-storyrc.yaml.example 5 | !verify_config.py # Utility script for verifying configuration 6 | 7 | # Added by Claude Task Master 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | dev-debug.log 15 | 16 | # Claude Code 17 | .claude/settings.local.json 18 | 19 | # MCP signal files (local AI processing artifacts) 20 | .mcp-commit-story/ 21 | 22 | # Dependency directories 23 | node_modules/ 24 | 25 | # Journal directories - test artifacts (but not Python package) 26 | /journal/ 27 | /test-journal/ 28 | 29 | # Environment variables 30 | 31 | # Editor directories and files 32 | .idea 33 | .vscode 34 | *.suo 35 | *.ntvs* 36 | *.njsproj 37 | *.sln 38 | *.sw? 39 | 40 | # OS specific 41 | .DS_Store 42 | Thumbs.db 43 | 44 | # Task files 45 | # tasks.json 46 | # tasks/ 47 | 48 | # Python cache and build artifacts 49 | __pycache__/ 50 | *.py[cod] 51 | *$py.class 52 | *.so 53 | .Python 54 | *.egg-info/ 55 | dist/ 56 | build/ 57 | eggs/ 58 | .eggs/ 59 | *.egg 60 | 61 | # Test coverage 62 | .coverage 63 | .coverage.* 64 | htmlcov/ 65 | 66 | # Virtual environments 67 | venv/ 68 | .venv/ 69 | ENV/ 70 | env/ 71 | 72 | # Python virtual environment 73 | .venv/ 74 | 75 | # Python bytecode and cache 76 | __pycache__/ 77 | *.pyc 78 | 79 | # Build artifacts 80 | src/mcp_commit_story.egg-info/ scripts/message_limit_research_findings.txt 81 | -------------------------------------------------------------------------------- /.mcp-commit-storyrc.yaml: -------------------------------------------------------------------------------- 1 | # MCP Journal Configuration 2 | # This file contains essential configuration options for the MCP Journal tool 3 | 4 | # Journal settings 5 | journal: 6 | # Base path for all journal files (relative to repo root) 7 | path: "sandbox-journal/" 8 | 9 | # Git repository settings 10 | git: 11 | # Files to exclude from analysis in journal entries 12 | exclude_patterns: 13 | - "journal/**" # Ignore journal directory to prevent recursion 14 | - ".mcp-journalrc.yaml" # Ignore config file itself 15 | 16 | # Telemetry settings 17 | telemetry: 18 | # Whether to collect telemetry 19 | enabled: false 20 | -------------------------------------------------------------------------------- /.mcp-commit-storyrc.yaml.example: -------------------------------------------------------------------------------- 1 | # Example configuration file for MCP Commit Story 2 | # Copy this file to .mcp-commit-storyrc.yaml in your project root 3 | 4 | # Journal configuration 5 | journal: 6 | # Directory for journal files (relative to project root) 7 | path: journal/ 8 | 9 | # Git configuration 10 | git: 11 | # Files to exclude from git processing 12 | exclude_patterns: 13 | - journal/** 14 | - .mcp-commit-storyrc.yaml 15 | 16 | # AI configuration 17 | ai: 18 | # OpenAI API key - use environment variable interpolation for security 19 | openai_api_key: "${OPENAI_API_KEY}" 20 | 21 | # Telemetry configuration 22 | telemetry: 23 | # Enable/disable telemetry collection 24 | enabled: false -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Whitney Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /conftest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test configuration and fixtures for MCP Commit Story tests. 3 | 4 | This file provides fixtures for both unit and integration testing, 5 | with special support for OpenTelemetry integration testing. 6 | """ 7 | 8 | import pytest 9 | from opentelemetry import trace, metrics 10 | from opentelemetry.sdk.trace import TracerProvider 11 | from opentelemetry.sdk.metrics import MeterProvider 12 | from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter 13 | from opentelemetry.sdk.resources import Resource 14 | 15 | 16 | @pytest.fixture 17 | def otel_integration_setup(): 18 | """ 19 | Fixture for integration tests that need real OpenTelemetry providers. 20 | Only use this for integration tests, not unit tests. 21 | 22 | This fixture creates fresh providers that work independently of global state. 23 | It doesn't try to override global providers since OpenTelemetry doesn't allow this. 24 | 25 | Usage: 26 | def test_real_spans(self, otel_integration_setup): 27 | tracer = otel_integration_setup['tracer'] 28 | with tracer.start_as_current_span("test") as span: 29 | # Test with real span that should have valid IDs 30 | """ 31 | # Create fresh providers with proper configuration 32 | resource = Resource.create({"service.name": "test-service"}) 33 | tracer_provider = TracerProvider(resource=resource) 34 | 35 | # Add processor so spans are actually recorded and get proper IDs 36 | tracer_provider.add_span_processor( 37 | SimpleSpanProcessor(ConsoleSpanExporter()) 38 | ) 39 | 40 | meter_provider = MeterProvider(resource=resource) 41 | 42 | # Get tracers directly from our providers (not global state) 43 | tracer = tracer_provider.get_tracer("test-tracer") 44 | 45 | yield { 46 | 'tracer_provider': tracer_provider, 47 | 'meter_provider': meter_provider, 48 | 'tracer': tracer 49 | } 50 | 51 | # Clean shutdown 52 | try: 53 | tracer_provider.shutdown() 54 | meter_provider.shutdown() 55 | except Exception: 56 | pass # Ignore shutdown errors in tests -------------------------------------------------------------------------------- /docs/ai-provider-setup.md: -------------------------------------------------------------------------------- 1 | # AI Provider Setup 2 | 3 | The system uses **OpenAI's API** for all AI operations. 4 | 5 | ## Setup 6 | 7 | ### Configuration 8 | 9 | Add your OpenAI API key to `.mcp-commit-storyrc.yaml`: 10 | 11 | ```yaml 12 | ai: 13 | openai_api_key: "${OPENAI_API_KEY}" # Uses environment variable interpolation 14 | ``` 15 | 16 | ### Environment Variable 17 | 18 | Set your OpenAI API key as an environment variable: 19 | 20 | ```bash 21 | export OPENAI_API_KEY="your-openai-api-key-here" 22 | ``` 23 | 24 | ## Quick Start 25 | 26 | 1. **Get API Key**: Visit [OpenAI API Keys](https://platform.openai.com/account/api-keys) 27 | 2. **Set Environment Variable**: `export OPENAI_API_KEY="your-key"` 28 | 3. **Update Config File**: Add the AI section to your `.mcp-commit-storyrc.yaml` 29 | 30 | ## Troubleshooting 31 | 32 | ### Common Issues 33 | 34 | 1. **Configuration Not Found** 35 | - Verify `.mcp-commit-storyrc.yaml` exists in your project root 36 | - Ensure the `ai` section is present with `openai_api_key` field 37 | 38 | 2. **Environment Variable Issues** 39 | - Verify the environment variable exists: `echo $OPENAI_API_KEY` 40 | - Restart your shell after setting the variable 41 | 42 | 3. **API Authentication Errors** 43 | - Verify your OpenAI API key is valid 44 | - Check that your OpenAI account has sufficient credits 45 | 46 | ## Best Practices 47 | 48 | 1. **Security**: 49 | - Never commit API keys to version control 50 | - Use environment variable interpolation in config 51 | - Rotate API keys regularly 52 | 53 | 2. **Configuration**: 54 | - Keep settings in `.mcp-commit-storyrc.yaml` 55 | - Use environment variables for sensitive values 56 | 57 | ## See Also 58 | 59 | - [Server Setup](server_setup.md) 60 | - [Implementation Guide](implementation-guide.md) -------------------------------------------------------------------------------- /docs/on-demand-directory-pattern.md: -------------------------------------------------------------------------------- 1 | # On-Demand Directory Creation Pattern for MCP Journal 2 | 3 | ## Overview 4 | The MCP Journal system uses an on-demand directory creation pattern: directories are created only when needed by file operations, not upfront during initialization. This keeps the repo clean and avoids empty folders. 5 | 6 | ## Canonical Usage 7 | Always call `ensure_journal_directory(file_path)` before writing to any journal file: 8 | 9 | ```python 10 | from mcp_commit_story.journal import ensure_journal_directory 11 | file_path = Path("journal/daily/2025-05-28-journal.md") 12 | ensure_journal_directory(file_path) 13 | with open(file_path, "a") as f: 14 | f.write(entry) 15 | ``` 16 | 17 | ## Anti-Patterns (What NOT to Do) 18 | - ❌ Do NOT create all subdirectories at initialization (no more `create_journal_directories`) 19 | - ❌ Do NOT assume parent directories exist before writing 20 | - ❌ Do NOT manually check for directory existence before every write (use the utility) 21 | 22 | ## Integration Checklist 23 | - [ ] All file-writing functions call `ensure_journal_directory` before writing 24 | - [ ] No code references or uses `create_journal_directories` 25 | - [ ] Tests cover directory creation on-demand (not upfront) 26 | - [ ] Docstrings mention on-demand pattern where relevant 27 | 28 | ## Development Guidelines 29 | 30 | ### For New File-Writing Features 31 | - Always call `ensure_journal_directory(file_path)` before writing to any journal file. 32 | - Do not create directories at initialization; rely on on-demand pattern. 33 | - Add tests to verify operations work when parent directories do not exist. 34 | 35 | ### For Summary Generation Features 36 | - Use `ensure_journal_directory(file_path)` for all summary types (daily, weekly, monthly, quarterly, yearly). 37 | - Add tests to verify summaries are saved correctly when directories do not exist. 38 | 39 | ### For MCP Server Handlers 40 | - Ensure all MCP server handlers that write files use `ensure_journal_directory` before writing. 41 | - Add tests to verify handlers work when directories do not exist. 42 | 43 | ## References 44 | - See the engineering spec (engineering-mcp-journal-spec-final.md) for rationale and requirements. 45 | - See function docstrings in `journal.py` for usage examples. 46 | 47 | ## Troubleshooting & Common Errors 48 | - **PermissionError**: Raised if directory creation fails due to permissions. Handle gracefully and report to user. 49 | - **FileNotFoundError**: Should not occur if `ensure_journal_directory` is used correctly. 50 | - **Test Failures**: If tests fail due to missing directories, check that the utility is called before file writes. 51 | 52 | ## For Developers 53 | - Always use the utility for new file-writing features. 54 | - Review and update tests to cover on-demand directory creation. 55 | - Update docstrings and documentation to mention the pattern where relevant. -------------------------------------------------------------------------------- /docs/server_setup.md: -------------------------------------------------------------------------------- 1 | # Server Setup 2 | 3 | This guide explains how to set up and configure the MCP server for the `mcp-commit-story` project. 4 | 5 | ## What is the MCP Server? 6 | The MCP server is a Python service that exposes journal operations (such as `journal/add-reflection`, `journal/capture-context`, etc.) for engineering teams. It integrates with Git, collects commit and context data, and provides additional functionality beyond the automatic journal generation that happens via git hooks. 7 | 8 | ## Architecture Overview 9 | 10 | The MCP Commit Story system uses a hybrid approach: 11 | 12 | - **Automatic Journal Generation**: Git post-commit hooks → `git_hook_worker.py` → direct journal creation 13 | - **Additional Operations**: MCP server provides manual tools, reflections, context capture, and setup operations 14 | - **AI Integration**: Both paths use the same underlying AI-powered journal generation logic 15 | 16 | The MCP server complements the automatic git hook system by providing: 17 | 18 | 1. **Manual journal operations** for special cases (missed commits, batch processing) 19 | 2. **User interaction tools** (add reflections, capture context) 20 | 3. **Setup and configuration** (initialize journals, install hooks) 21 | 4. **Summary generation** (daily, weekly, monthly summaries) 22 | 23 | This design ensures journal entries are created automatically during normal development while providing rich tooling for enhanced workflow integration. 24 | 25 | ## Installation 26 | 1. **Clone the repository:** 27 | ```sh 28 | git clone 29 | cd mcp-commit-story 30 | ``` 31 | 2. **Install dependencies:** 32 | ```sh 33 | pip install -r requirements.txt 34 | # or, if using poetry or uv: 35 | poetry install 36 | # or 37 | uv pip install -r requirements.txt 38 | ``` 39 | 40 | ## Configuration 41 | 42 | The server uses a YAML configuration file (`.mcp-commit-storyrc.yaml`) that supports environment variable interpolation using `${VAR_NAME}` syntax. 43 | 44 | ### Example Configuration 45 | 46 | ```yaml 47 | # .mcp-commit-storyrc.yaml 48 | journal: 49 | path: journal/ 50 | 51 | git: 52 | exclude_patterns: 53 | - journal/** 54 | - .mcp-commit-storyrc.yaml 55 | 56 | ai: 57 | openai_api_key: "${OPENAI_API_KEY}" 58 | 59 | telemetry: 60 | enabled: false 61 | ``` 62 | 63 | ### Configuration Sections 64 | 65 | - `journal.path`: Directory for journal files 66 | - `git.exclude_patterns`: Files to exclude from git processing 67 | - `ai.openai_api_key`: OpenAI API key (supports ${VAR_NAME} syntax) 68 | - `telemetry.enabled`: Enable/disable telemetry 69 | 70 | ## Error Handling 71 | 72 | The server provides clear error messages for configuration issues: 73 | 74 | 1. **Missing Configuration** 75 | ``` 76 | ConfigError: Missing required config: journal.path 77 | ``` 78 | 79 | 2. **Invalid Environment Variables** 80 | ``` 81 | ConfigError: Environment variable 'OPENAI_API_KEY' not found 82 | ``` 83 | 84 | ## See Also 85 | 86 | - [AI Provider Setup](ai-provider-setup.md) 87 | - [Implementation Guide](implementation-guide.md) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=61.0"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "mcp-commit-story" 7 | version = "0.1.0" 8 | description = "A Model Context Protocol (MCP) server for engineering commit story journal entries." 9 | authors = [ 10 | { name = "Your Name", email = "your.email@example.com" } 11 | ] 12 | readme = "README.md" 13 | requires-python = ">=3.10" 14 | dependencies = [ 15 | "mcp>=1.0.0", 16 | "click>=8.0.0", 17 | "pyyaml>=6.0", 18 | "gitpython>=3.1.0", 19 | "python-dateutil>=2.8.0", 20 | "typing_extensions>=4.0.0; python_version<'3.12'", 21 | "psutil>=5.9.0", 22 | "opentelemetry-api>=1.15.0", 23 | "opentelemetry-sdk>=1.15.0", 24 | "opentelemetry-exporter-otlp>=1.15.0", 25 | "opentelemetry-exporter-prometheus>=0.54b0", 26 | # Auto-instrumentation dependencies (required for telemetry tests) 27 | "opentelemetry-instrumentation>=0.41b0", 28 | "opentelemetry-instrumentation-requests>=0.41b0", 29 | "opentelemetry-instrumentation-aiohttp-client>=0.41b0", 30 | "opentelemetry-instrumentation-asyncio>=0.41b0", 31 | "opentelemetry-instrumentation-logging>=0.41b0", 32 | # AI provider integration 33 | "openai>=1.0.0" 34 | ] 35 | 36 | [project.optional-dependencies] 37 | dev = [ 38 | "pytest>=7.0.0", 39 | "pytest-mock>=3.10.0", 40 | "pytest-cov>=4.0.0", 41 | "pytest-watch>=4.2.0", 42 | "pytest-asyncio>=0.21.0", 43 | "black>=23.0.0", 44 | "flake8>=6.0.0", 45 | "mypy>=1.0.0", 46 | "toml>=0.10.0" 47 | ] 48 | 49 | [project.scripts] 50 | mcp-commit-story-setup = "mcp_commit_story.cli:main" -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | testpaths = tests 3 | addopts = -ra 4 | asyncio_mode = auto 5 | asyncio_default_fixture_loop_scope = function 6 | markers = 7 | integration: marks tests as integration tests (may be slow, require external dependencies) 8 | manual: marks tests that require manual setup or verification -------------------------------------------------------------------------------- /sandbox-journal/daily/2025-05-22-journal.md: -------------------------------------------------------------------------------- 1 | ### 2025-05-22 10:30 — Commit 1af62e4 2 | 3 | #### Summary 4 | 5 | Planned and restructured the implementation approach for section generators in the journal system. Updated the Taskmaster plan to use granular subtasks, each with clear responsibilities and dependencies, and added an integration test subtask. This commit sets the stage for future modular, testable, and extensible implementation, but does not yet refactor or break down any monolithic code. 6 | 7 | #### Accomplishments 8 | 9 | - Designed a new plan to break down section generator logic into seven focused subtasks, each responsible for a single section (summary, accomplishments, frustrations, tone, terminal, discussion, commit details) 10 | 11 | - Established explicit dependencies between subtasks to enforce correct implementation order in the plan 12 | 13 | - Added a final integration subtask to test all section generators as a system (planning only) 14 | 15 | - Updated the Taskmaster plan and dependencies to reflect the new structure 16 | 17 | - Improved clarity and maintainability of the project plan and future codebase 18 | 19 | #### Terminal Commands (AI Session) 20 | Commands executed by AI during this work session: 21 | ```bash 22 | git commit -m "refactor: restructure section generators into granular subtasks with proper dependencies and integration testing" 23 | ``` 24 | 25 | #### Discussion Notes (from chat) 26 | > **Human:** AI should use all available data (commit info, terminal context, and chat context) to generate each section. The artificial separation between "commit-based" and "context-based" sections doesn't make much sense because: 27 | > 28 | > Summary should consider commit changes AND what was discussed AND what commands were run 29 | > Accomplishments should look at commit diffs AND chat discussions about what worked AND terminal evidence of successful operations 30 | > Frustrations should consider commit messages AND chat expressions of frustration AND failed terminal commands 31 | > Tone/Mood should consider commit message language AND chat language AND terminal command patterns 32 | > 33 | > Better Approach: One Subtask Per Section 34 | > There should be one subtask per section generator function. This would be: 35 | > 36 | > 5.4.1: Implement generate_summary_section(commit, terminal_context, chat_context) 37 | > 5.4.2: Implement generate_accomplishments_section(commit, terminal_context, chat_context) 38 | > 5.4.3: Implement generate_frustrations_section(commit, terminal_context, chat_context) 39 | > 5.4.4: Implement generate_tone_section(commit, terminal_context, chat_context) 40 | > 5.4.5: Implement generate_terminal_section(terminal_context) 41 | > 5.4.6: Implement generate_discussion_section(chat_context) 42 | > 5.4.7: Implement generate_commit_details_section(commit) 43 | > 44 | > Why This Is Better 45 | > 46 | > Each function gets all relevant data - No artificial constraints about what data source to use 47 | > More granular progress tracking - You can complete and test each section independently 48 | > Clearer collaboration - You can get user feedback on each specific section's design 49 | > Better TDD - Each function can have focused, comprehensive tests 50 | > More logical - The separation is by output (what section is being generated) rather than input (what data is being used) 51 | 52 | > **Agent:** Your reasoning is excellent, and your proposed restructuring is both logical and practical. Here's a summary of why your approach is superior and how it would improve the project: ... 53 | 54 | #### Tone/Mood 55 | > Productive and collaborative. The team demonstrated a willingness to rethink architecture for long-term maintainability and clarity. The mood was constructive, with a focus on best practices and future extensibility. 56 | 57 | #### Behind the Commit 58 | - **files_changed:** 2 59 | - **insertions:** 181 60 | - **deletions:** 68 -------------------------------------------------------------------------------- /sandbox-journal/daily/2025-06-13-journal.md: -------------------------------------------------------------------------------- 1 | # 2025-06-13 Engineering Journal 2 | 3 | ### 4:59 AM — Reflection 4 | 5 | If I do this method of making journal entries silently in the background in a non-MCP way, what are the MCP tools I should offer on top of autogenerated journal data? 6 | 7 | Why should the extra functionality even be a collection of MCP tools and not CLI tools? A feature would benefit from being an MCP tool if (1) the desired outcome of the tool could be enhanced by having the current project context, and/or (2) it would simply be convient to be able to access it from within Cursor chat. The possible tools I brainstormed last night are: 8 | 9 | * arbitrary date range journal summaries 10 | * brainstorming content topics 11 | * transforming content into blog posts or conference talks 12 | * generating project retrospectives 13 | * performing AI-powered search through the accumulated journal data 14 | 15 | Some of those would benefit from being MCP tools, some not. Also something like a blogify function could be either/both MCP and CLI. 16 | 17 | Also this morning I thought of other MCP functionality: 18 | * a tool to add arbitrary reflections to the journal (VERY useful! Doing it now!) 19 | * a tool to add the current project state/context to the journal - just a quick manual request to capture a moment in time 20 | 21 | ^^^ That last thing feels like a big winner of an idea!!! Those last two tools are enough to justify the MCP server on top of the autojenerated journal entries and summaries imho 22 | 23 | More food for thought: why add a reflection via Cursor chat when you could directly write it in the file? I guess if you have to find or make the journal file, then find the right spot in the file, that could break flow. Also later when I add machine-friendly formatting and tags, the reflections will benefit from that too. -------------------------------------------------------------------------------- /sandbox-journal/daily/2025-07-02-journal.md: -------------------------------------------------------------------------------- 1 | # Journal Entry - July 2, 2025 2 | 3 | ### 11:53 AM — Reflection 4 | 5 | When generating the journal entry, I think there should be some kind of instruction (maybe even programatic) for the journal to include any user comments that use '!' at the end of any sentences -------------------------------------------------------------------------------- /sandbox-journal/daily/2025-07-03-journal.md: -------------------------------------------------------------------------------- 1 | # Journal Entry - July 3, 2025 2 | 3 | ### 11:57 AM — Reflection 4 | 5 | I'm thinking that the journal entry layer should prioritize AI parse/readability over human readability and then MCP tools should exist that allow the user to ask arbitrary questions like "What did I do yesterday?" or "Summaries my March contributions to this repo" 6 | 7 | Then there are two backend paths: 8 | * One that auto-constructs a human-readable journal with daily, monthly, weekly, etc summaries 9 | 10 | * One that summarizes & chunks user data in an AI parseable/readable way so that the data is available & ready to answer these questions at any time granularity 11 | 12 | Maybe having two paths is redundant. Maybe the best way is a human-readable journal that is very consistently formatted and tagged for AI. But the idea of MCP tools to ask AI to leverage journal knowledge to talk about past progress seems very nice. 13 | 14 | That said, I'm not going to do any architectural changes now, I need to get to MVP. -------------------------------------------------------------------------------- /sandbox-journal/daily/2025-07-21-journal.md: -------------------------------------------------------------------------------- 1 | # Daily Journal Entries - July 21, 2025 2 | 3 | ### 5:33 PM — Commit 68007b5fff5fe4df2933abc6e7cd3920571537ca 4 | 5 | #### Accomplishments 6 | 7 | - Completed: Modify OpenAIProvider to accept configuration object and use config-only approach for API key loading 8 | 9 | - Successfully updated 3 files 10 | 11 | #### Commit Metadata 12 | 13 | - **files_changed:** 3 14 | - **size_classification:** small -------------------------------------------------------------------------------- /sandbox-journal/daily/2025-07-24-journal.md: -------------------------------------------------------------------------------- 1 | # Daily Journal Entries - July 24, 2025 2 | 3 | ### 6:38 PM — Commit 36f87ed1d56b3e8e0a377a06dedaf19d3ea12576 4 | 5 | #### Accomplishments 6 | 7 | - Completed: Verify 80.3 completion and mark it ask such 8 | 9 | - Modified tasks/task_080.txt 10 | 11 | #### Commit Metadata 12 | 13 | - **files_changed:** 1 14 | - **size_classification:** small 15 | --- 16 | ### 7:14 PM — Commit ee861aa6cb4bf0488ae679530e45b078b3e65562 17 | 18 | #### Accomplishments 19 | 20 | - Completed: Update ai_invocation.py to load configuration and pass it to OpenAIProvider 21 | 22 | - Successfully updated 3 files 23 | 24 | #### Commit Metadata 25 | 26 | - **files_changed:** 3 27 | - **size_classification:** small 28 | --- 29 | 30 | 31 | ### 7:16 PM — AI Context Capture 32 | 33 | Completed Subtask 80.4: Update AI Invocation to Use Config-Based Provider (2025-07-24 19:16 CDT) 34 | 35 | Implemented config-based AI invocation by updating ai_invocation.py to use the configuration system for OpenAI API key management. Key changes: 36 | 37 | 1. Added config loading to invoke_ai() using load_config() 38 | 2. Integrated with OpenAIProvider's new config-based constructor 39 | 3. Implemented warning message generation for API key issues 40 | 4. Added telemetry for config loading operations 41 | 5. Created comprehensive test suite in test_ai_invocation_config.py 42 | 43 | The implementation follows the config-only approach, removing direct environment variable access in favor of the more robust configuration system with ${VAR_NAME} interpolation. Added graceful degradation with informative warning messages when AI features are unavailable due to configuration issues. 44 | 45 | All verification checklist items completed and tests passing. 46 | 47 | Completed Subtask 80.5: Integration Testing and Documentation Updates (2025-07-24 19:20 CDT) 48 | 49 | 1. Created comprehensive integration test in `tests/integration/test_ai_config_integration.py` that verifies: 50 | - Config loading with environment variable interpolation 51 | - AI section validation 52 | - OpenAI provider initialization 53 | - AI invocation with config-based API key 54 | - Telemetry collection during config-based operations 55 | 56 | 2. Updated documentation to reflect the config-based approach: 57 | - Updated `docs/ai-provider-setup.md` with config file recommendations 58 | - Updated `docs/server_setup.md` with comprehensive configuration docs 59 | - Added detailed examples and troubleshooting guidance 60 | - Created `.mcp-commit-storyrc.yaml.example` with commented configuration 61 | 62 | All verification checklist items completed and tests passing. The config-based approach for managing the OpenAI API key is now fully implemented, tested, and documented. -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-05-19-daily.md: -------------------------------------------------------------------------------- 1 | # 2025-05-19-daily.md 2 | 3 | ## Summary 4 | Today was a productive day focused on implementing key Git utilities and journal entry parsing functionality through rigorous Test-Driven Development. The work progressed methodically from test fixture creation to full implementation of Git hook management. Beginning with validation of the agent/model journal framework, the day culminated in robust implementations for parsing journal entries and managing Git hooks with thorough error handling. The development approach consistently followed TDD principles, with careful attention to edge cases and proper error handling. 5 | 6 | ## Key Accomplishments 7 | - Validated that AI agents can follow the engineering spec to generate structured journal entries 8 | - Created a reusable pytest fixture for temporary Git repositories 9 | - Implemented comprehensive Git utilities including get_commit_diff_summary and hook management functions 10 | - Developed robust parsing logic for journal entries with markdown edge case handling 11 | - Completed full TDD cycles for six significant components 12 | 13 | ## Notable Challenges 14 | - Encountered limitations with GitPython's binary file detection in temporary test repositories 15 | - Initial failures in journal entry parsing due to leading blank lines in test markdown 16 | - Worked around these issues through documentation, normalization of inputs, and alternative detection approaches 17 | 18 | ## Mood & Tone Patterns 19 | Overall mood: Methodical, thorough, and increasingly confident 20 | Notable progression: Started methodical (4:18 PM), became satisfied (4:30 PM), grew productive (4:47 PM), thorough (5:19 PM), satisfied (5:33 PM), efficient (7:18 PM), disciplined (8:27 PM), and satisfied (8:31 PM) 21 | Emotional arc: Consistent focus on systematic development with no significant frustrations 22 | 23 | ## Decision Points 24 | - Decided to document GitPython binary file detection limitations rather than force unreliable tests 25 | - Opted to normalize input by stripping leading whitespace in journal entry parsing 26 | - Prioritized comprehensive error handling in hook management functions 27 | 28 | ## Developer Reflections 29 | No manual reflections were added to any entries today 30 | 31 | ## Basic Metrics 32 | - Number of commits: 8 33 | - Time span: 4:18 PM to 8:31 PM (approximately 4 hours) 34 | - Focus areas: Test infrastructure (3 commits), parsing logic (1 commit), git utilities (4 commits) 35 | - Test coverage: All implemented functionality has corresponding tests 36 | 37 | ## Key Files Modified 38 | - src/mcp_journal/git_utils.py: Added multiple Git utility functions 39 | - tests/unit/test_git_utils.py: Added comprehensive tests for Git utilities 40 | - tests/unit/test_agent_model_validation.py: Improved parsing logic for journal entries 41 | - tests/conftest.py: Added pytest fixture for temporary Git repositories 42 | - sample-journal-entry.md: Created example of spec-compliant journal entry -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-05-20-daily.md: -------------------------------------------------------------------------------- 1 | # 2025-05-20-daily.md 2 | 3 | ## Summary 4 | Completed package rename from mcp_journal to mcp_commit_story, implemented journal entry generation with comprehensive TDD testing, and improved documentation quality. Resolved major duplication bug in journal file. Key milestone: project rebranding is complete and core journal functionality is operational. 5 | 6 | ## Key Accomplishments 7 | - Successfully renamed entire package structure from mcp_journal to mcp_commit_story 8 | - Implemented JournalEntry class with full test coverage (9/9 tests passing) 9 | - Fixed major data integrity issue: removed 1,400+ duplicate entries from journal 10 | - Updated all documentation, configuration, and CI/CD references 11 | - Added content quality guidelines to engineering spec 12 | 13 | ## Challenges Overcome 14 | - Tedious but critical package rename across multiple files and configs 15 | - Subtle duplication problem required careful diagnosis and scripting to resolve 16 | - Markdown formatting issue in engineering spec affecting GitHub rendering 17 | 18 | ## Technical Progress 19 | - 9 commits made throughout the day 20 | - Files changed: 50+ across multiple commits 21 | - Test coverage: All tests passing (95/95) 22 | - Major refactoring completed without breaking functionality 23 | 24 | ## Learning & Insights 25 | - Package rename process made much easier with AI agent assistance 26 | - Importance of data integrity validation in automated workflows 27 | - TDD approach prevented issues during major structural changes 28 | 29 | ## Next Steps 30 | - Continue with Task 5 implementation: file operations for journal management 31 | - Implement MCP server operations 32 | - Add CLI interface with Click framework 33 | 34 | ## Mood Indicators 35 | Methodical and satisfied - complex refactoring completed successfully with no major blockers. Relieved to have data integrity issues resolved and project properly rebranded. -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-05-21-daily.md: -------------------------------------------------------------------------------- 1 | # 2025-05-21-daily.md 2 | 3 | ## Summary 4 | Made significant progress on the journal system's core infrastructure, implementing file operations, context collection, and formatting improvements. Reorganized project structure for clarity and rewrote the README to better communicate the vision. Key milestone: the foundational layers for reliable journal entry generation are now in place. 5 | 6 | ## Key Accomplishments 7 | - Implemented comprehensive file operations with full TDD coverage (get_journal_file_path, create_journal_directories, append_to_journal_file) 8 | - Added AI-powered context collection functions with anti-hallucination safeguards 9 | - Enhanced journal entry formatting with proper header hierarchy, spacing, and code blocks 10 | - Reorganized project structure by moving samples to sandbox-journal directory 11 | - Completely rewrote README to be more engaging and narrative-focused 12 | 13 | ## Challenges Overcome 14 | - Balanced simplicity with extensibility in file operation design 15 | - Refined formatting rules and test logic for markdown conventions 16 | - Navigated uncertainty about AI mood inference and explicit indicator requirements 17 | - Integrated anti-hallucination rules into AI prompts for reliable context extraction 18 | 19 | ## Technical Progress 20 | - 6 commits made throughout the day 21 | - Files changed: 19 total across all commits 22 | - Test coverage: All file operations and context collection tests passing 23 | - Major infrastructure components now ready for integration 24 | 25 | ## Learning & Insights 26 | - TDD approach continues to prevent issues during rapid development 27 | - Project structure clarity becomes more important as complexity grows 28 | - Documentation tone significantly impacts how people perceive and engage with the project 29 | - Anti-hallucination rules are critical for maintaining journal entry integrity 30 | 31 | ## Process Improvements 32 | - Added manual reflection capability with timestamping 33 | - Clarified distinction between experimental and production journal entries 34 | - Established clearer guidelines for mood/tone inference based on explicit indicators 35 | 36 | ## Next Steps 37 | - Continue with section generation and integration work 38 | - Implement MCP server operations and CLI interface 39 | - Monitor AI mood inference behavior for future refinements 40 | 41 | ## Mood Indicators 42 | Productive and systematic - steady progress on core infrastructure with good balance of implementation and documentation. Thoughtful about process improvements and maintaining quality standards while moving quickly. -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-05-22-daily.md: -------------------------------------------------------------------------------- 1 | # 2025-05-22-daily.md 2 | 3 | ## Summary 4 | Restructured the implementation plan for journal section generators, shifting to a granular, subtask-driven approach. The new plan emphasizes modularity, clear dependencies, and testability, laying the groundwork for a maintainable and extensible engineering journal system. No code refactoring was performed, but the architectural foundation for future work was established and documented. 5 | 6 | ## Key Accomplishments 7 | - Designed a new plan to break down section generator logic into seven focused subtasks, each responsible for a single journal section 8 | - Established explicit dependencies between subtasks to enforce correct implementation order 9 | - Added an integration subtask to test all section generators as a system 10 | - Updated the Taskmaster plan and dependencies to reflect the new structure 11 | - Improved clarity and maintainability of the project plan and future codebase 12 | 13 | ## Challenges Overcome 14 | - Addressed the artificial separation between "commit-based" and "context-based" sections by unifying data sources for all section generators 15 | - Navigated architectural decisions to ensure each section generator receives all relevant context (commit, terminal, chat) 16 | - Balanced the need for granular progress tracking with logical, maintainable task breakdown 17 | 18 | ## Technical Progress 19 | - 1 commit made during the day 20 | - Files changed: Taskmaster plan, journal system planning documents 21 | - Insertions: 181, Deletions: 68 22 | - No code refactoring performed; all work focused on planning and documentation 23 | 24 | ## Learning & Insights 25 | - Granular, output-driven subtasks improve progress tracking, collaboration, and TDD 26 | - Unified context for section generators eliminates artificial constraints and improves narrative fidelity 27 | - Explicit dependencies between subtasks enforce correct implementation order and reduce risk of errors 28 | 29 | ## Mood & Tone Patterns 30 | Overall mood: Productive and collaborative 31 | Notable progression: The team demonstrated a willingness to rethink architecture for long-term maintainability and clarity 32 | Emotional arc: Constructive, with a focus on best practices and future extensibility 33 | 34 | ## Decision Points 35 | - Chose to restructure section generator implementation into one subtask per section 36 | - Opted for unified context input for all section generators 37 | - Added an integration subtask to ensure system-level testability 38 | 39 | ## Developer Reflections 40 | No manual reflections were added to any entries today -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-05-23-daily.md: -------------------------------------------------------------------------------- 1 | # 2025-05-23-daily.md 2 | 3 | ## Summary 4 | Focused on foundational architecture and reliability improvements for the engineering journal MCP server. The day was dedicated to formalizing context collection data structures, consolidating git data collection, and ensuring robust, portable test coverage. All work followed strict TDD and type safety principles, with careful attention to documentation and anti-hallucination requirements. 5 | 6 | ## Key Accomplishments 7 | - Marked Task 5.11 (Document and Formalize Context Collection Data Structures) as in progress and logged a detailed implementation plan 8 | - Refactored `collect_chat_history` and `collect_ai_terminal_commands` to use message-based boundaries, eliminating time-based logic 9 | - Updated engineering spec and PRD to clarify message-based context collection and anti-hallucination rules 10 | - Consolidated git data collection into a single `collect_git_context` function, replacing mock functions and improving maintainability 11 | - Implemented and tested `collect_git_context` with robust handling for initial commits and file type classification 12 | - Refactored all tests to use temporary git repos and explicit commit hashes, ensuring reliability in all environments (including CI) 13 | - Updated all context collection and integration points to use the new unified structure 14 | - Maintained alignment between code, documentation, and Taskmaster task tracking 15 | 16 | ## Challenges Overcome 17 | - Addressed issues with GitPython's diff API for initial commits by using the canonical NULL_TREE approach 18 | - Resolved test failures due to repo context mismatches by passing explicit repo and commit references 19 | - Ensured test isolation and reliability by creating temporary repos and commits for all git-dependent tests 20 | - Navigated feedback and iteration on docstring prompts to preserve user-authored content while clarifying new requirements 21 | 22 | ## Technical Progress 23 | - 5 commits made throughout the day 24 | - Files changed: context_types.py, journal.py, git_utils.py, engineering-mcp-journal-spec-final.md, scripts/mcp-commit-story-prd.md, test_journal.py, test_git_utils.py, test_context_collection.py, tasks.json, task_005.txt 25 | - Test coverage: All context collection and integration tests passing in local and CI environments 26 | - Major architectural improvements to context collection and git integration 27 | 28 | ## Learning & Insights 29 | - TDD and type safety are critical for maintainability and reliability in context-driven systems 30 | - Message-based boundaries are more robust than time-based logic for AI context collection 31 | - Canonical git approaches (e.g., NULL_TREE) prevent edge case bugs in diff analysis 32 | - Test isolation and explicit context setup are essential for CI reliability 33 | 34 | ## Mood & Tone Patterns 35 | Overall mood: Satisfied, methodical, and confident 36 | Notable progression: Started with foundational planning, moved through iterative refactoring and testing, and ended with robust, reliable test coverage and architectural clarity 37 | Emotional arc: Minor frustrations with test failures, but resolved quickly with best-practice solutions 38 | 39 | ## Decision Points 40 | - Chose to formalize all context collection data structures before implementing section generators 41 | - Opted for message-based context boundaries and explicit anti-hallucination rules 42 | - Consolidated git data collection for maintainability and narrative fidelity 43 | - Prioritized test reliability and CI compatibility in all refactors 44 | 45 | ## Developer Reflections 46 | No manual reflections were added to any entries today -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-05-24-daily.md: -------------------------------------------------------------------------------- 1 | # 2025-05-24-daily.md 2 | 3 | ## Summary 4 | A milestone day focused on formalizing the unified context model, implementing and testing all section generator scaffolds, and advancing the engineering journal MCP server's type safety and TDD rigor. The team completed foundational work on TypedDicts, section generator stubs, and comprehensive test fixtures, ensuring robust anti-hallucination compliance and future maintainability. All progress was meticulously tracked, with documentation, tests, and code kept in sync. 5 | 6 | ## Key Accomplishments 7 | - Defined and documented TypedDicts for all context and section generator outputs (chat, terminal, git, journal, and all journal sections) 8 | - Updated all context collection functions and downstream code to use the new types 9 | - Implemented canonical AI-driven stubs for all section generators, each with a detailed, user-approved prompt and placeholder return 10 | - Created comprehensive test fixtures and mock data for all section generators, covering edge cases and ensuring robust TDD 11 | - Refactored journal entry structure to new canonical section order and renamed "Behind the Commit" to "Commit Metadata" throughout the codebase 12 | - Updated engineering spec, PRD, and README to reflect the new unified context model and section order 13 | - Added robust filtering of journal files to `collect_git_context` to prevent recursion and contamination 14 | - Ensured all local/dev tests pass and AI/content tests are xfail as expected 15 | - Maintained strict alignment between code, documentation, and Taskmaster task tracking 16 | 17 | ## Challenges Overcome 18 | - Required careful coordination across code, tests, documentation, and task files to ensure consistency 19 | - Addressed friction updating all references to renamed sections and new order 20 | - Resolved test setup issues for git context filtering by ensuring all test files are created within the repo directory 21 | - Managed complexity in scaffolding and testing all section generators in a single day 22 | 23 | ## Technical Progress 24 | - 7+ commits made throughout the day 25 | - Files changed: context_types.py, journal.py, git_utils.py, engineering-mcp-journal-spec-final.md, scripts/mcp-commit-story-prd.md, test_journal.py, test_journal_entry.py, test_git_utils.py, test_context_collection.py, summary_test_data.py, tasks.json, task_005.txt, README.md 26 | - Test coverage: All structure, compliance, and placeholder tests passing; AI/content tests xfail as expected 27 | - Major architectural improvements to section generator scaffolding, context model, and anti-hallucination safeguards 28 | 29 | ## Learning & Insights 30 | - Canonical AI-driven function pattern (prompt in docstring, placeholder return) streamlines TDD and future AI integration 31 | - Unified context model and strict type safety reduce errors and improve maintainability 32 | - Comprehensive test fixtures and mock data are essential for robust, edge-case-driven TDD 33 | - Filtering journal files from git context is critical for recursion prevention and narrative fidelity 34 | 35 | ## Mood & Tone Patterns 36 | Overall mood: Thorough, systematic, and satisfied 37 | Notable progression: Moved from foundational type/model work to broad implementation and test scaffolding, ending with robust, maintainable architecture 38 | Emotional arc: Some friction with coordination and test setup, but resolved with methodical, best-practice solutions 39 | 40 | ## Decision Points 41 | - Chose to formalize all context and section generator types before implementing content logic 42 | - Opted for a unified context model and canonical section order for all journal entries 43 | - Prioritized anti-hallucination compliance and test-driven development in all new code 44 | - Added robust filtering to git context collection to prevent recursion 45 | 46 | ## Developer Reflections 47 | No manual reflections were added to any entries today -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-05-25-daily.md: -------------------------------------------------------------------------------- 1 | ## 2025-05-25 — Daily Summary 2 | 3 | ### Summary 4 | - Major progress was made on the core journal entry generation pipeline, with all canonical section generators (tone/mood, discussion notes, terminal commands, commit metadata) implemented and tested. 5 | - The context collection logic was refactored into a dedicated module, improving modularity and future extensibility. 6 | - The test suite was rigorously expanded and cleaned up, achieving full coverage for all section types, error handling, and integration scenarios. 7 | - Taskmaster dependencies and priorities were updated to clarify the MVP critical path, and new subtasks were added for post-commit automation. 8 | - The codebase underwent several rounds of cleanup and refactoring, resulting in a leaner, more maintainable, and robust foundation for future development. 9 | 10 | ### Technical Synopsis 11 | - Implemented and tested all major journal section generators in `journal.py`, each with strict anti-hallucination and formatting rules. 12 | - Extracted all context collection functions to `context_collection.py`, updating all references and tests. 13 | - Added and expanded tests for all section TypedDicts, integration, and error handling. 14 | - Refactored and cleaned up the test suite, removing obsolete cases and ensuring all tests pass or are properly xfail/xpass. 15 | - Updated Taskmaster task files and documentation to reflect new dependencies, priorities, and acceptance criteria for summary weighting. 16 | 17 | ### Accomplishments 18 | - Canonicalized the journal entry pipeline with robust, test-driven section generators. 19 | - Achieved full test coverage for all context types, section generators, and integration scenarios. 20 | - Improved codebase modularity and maintainability through targeted refactoring. 21 | - Clarified MVP priorities and critical path in Taskmaster. 22 | - Maintained a green test suite throughout all major changes. 23 | 24 | ### Frustrations or Roadblocks 25 | - Some frustration with Python's lack of runtime TypedDict enforcement, requiring careful test design. 26 | - Integration and normalization of new section generators surfaced subtle edge cases, especially in tone/mood handling. 27 | - The majority of context extraction logic remains as AI-prompt-driven placeholders, pending future implementation. 28 | 29 | ### Tone/Mood 30 | > Methodical, focused, and confident 31 | > The day was marked by steady, detail-oriented progress, with a sense of satisfaction in achieving a robust and extensible foundation. -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-05-26-daily.md: -------------------------------------------------------------------------------- 1 | ## 2025-05-26 — Daily Summary 2 | 3 | ### Summary 4 | A comprehensive day focused on building the complete MCP server infrastructure and git automation foundation for the journal system. Major milestones included implementing all core MCP operations, creating robust journal initialization logic, and establishing fully automated git hook integration. The development process maintained strict TDD discipline throughout, resulting in a production-ready foundation with extensive test coverage and comprehensive documentation. 5 | 6 | ### Key Accomplishments 7 | - Implemented complete MCP server core with dynamic version loading, configuration management, and error handling 8 | - Built all essential MCP operation handlers (journal/new-entry, journal/add-reflection, journal/init, journal/install-hook) 9 | - Created comprehensive journal initialization system with directory creation, config generation, and git validation 10 | - Implemented robust git hook automation with portable script generation, backup logic, and automated installation 11 | - Established CLI interface with standardized JSON output contracts and error codes 12 | - Maintained strict TDD throughout with over 95% test coverage across unit and integration tests 13 | - Updated all documentation, PRD, and engineering specs to reflect new capabilities 14 | 15 | ### Challenges Overcome 16 | - Adapted to FastMCP limitations by implementing config/telemetry setup before server instantiation 17 | - Resolved complex test isolation issues for git hook execution verification 18 | - Navigated Python import path complexities in test suite due to src/ layout 19 | - Managed coordination across multiple files and documentation to maintain consistency 20 | - Addressed platform-specific permission handling for git repository operations 21 | 22 | ### Technical Progress 23 | - 25+ commits made throughout the day spanning early morning to evening 24 | - Files changed: 100+ across all commits with major additions to server infrastructure 25 | - Test coverage: All tests passing with comprehensive unit and integration coverage 26 | - Major architectural milestone: Complete MCP server ready for journal operations 27 | - Git automation: Fully functional post-commit hook system with backup and recovery 28 | 29 | ### Learning & Insights 30 | - Strict TDD discipline prevents regressions during rapid, complex development 31 | - Comprehensive documentation and planning pays dividends when coordinating multiple system components 32 | - Integration testing is critical for validating real-world behavior beyond unit test coverage 33 | - Hot config reload and robust error handling improve developer experience significantly 34 | - Automated git integration requires careful attention to portability and non-blocking behavior 35 | 36 | ### Mood & Tone Patterns 37 | Overall mood: Determined, methodical, and increasingly satisfied 38 | Notable progression: Started with foundational server work, progressed through systematic feature implementation, and ended with confident validation of complete automation workflow 39 | Emotional arc: Some friction with test complexity and coordination requirements, but resolved through disciplined problem-solving and comprehensive validation 40 | 41 | ### Decision Points 42 | - Chose to implement hot config reload for improved developer experience 43 | - Opted for always-backup approach for git hook installation to ensure safety 44 | - Prioritized JSON output contracts for CLI commands to support scripting and automation 45 | - Added comprehensive integration testing to validate real-world git hook execution 46 | - Updated Cursor rules to reduce approval friction and improve development velocity -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-07-15-summary.md: -------------------------------------------------------------------------------- 1 | # Daily Summary for 2025-07-15 2 | 3 | ## Summary 4 | Today proved to be a pivotal day for enhancing the daily summary functionality within the MCP Commit Story system. My focus was on two main subtasks aimed at streamlining the existing codebase and ensuring seamless integration of real AI capabilities into the summary generation process. In the morning, I tackled the removal of redundant reflection extraction methods from the daily summary module, leading to a cleaner and more maintainable structure. Following that, I pivoted towards implementing real AI invocation for generating daily summaries, replacing mock responses with actual AI interactions. This effort required diligent debugging to properly handle AI errors, leading to a successful completion of the task. As the day progressed, I also engaged in multiple cleanup activities across the test suite to address inconsistencies and enhance overall reliability. By the end of the day, my research and debugging had paid off, leading to robust implementations with strong test coverage and functionality integration, all while navigating various obstacles with tenacity. 5 | 6 | ## Reflections 7 | 8 | - [10:58 AM] My new team is pretty cool 9 | --- 10 | 11 | 12 | ## Progress Made 13 | I successfully consolidated the daily summary functions into a single module, improving maintainability and performance. After cleaning up redundancy in the reflection extraction process, I integrated real AI responses into the summary generation, which previously relied on mock data. Furthermore, I refined error handling to manage AI invocation failures gracefully, ensuring the robustness of the functionality. Visiting the test suite, I resolved multiple xpassing tests, ensuring greater reliability in the CI pipeline. 14 | 15 | ## Key Accomplishments 16 | 17 | - Merged daily_summary_standalone.py functionality into daily_summary.py and deprecated the standalone module. 18 | - Implemented real AI invocation in the daily summary generation process. 19 | - Successfully cleaned up xpassing tests in the testing suite. 20 | 21 | ## Technical Progress (Detailed Implementation) 22 | In this series of commits, significant architectural updates were made. The first main change involved merging the functionality of `daily_summary_standalone.py` into `daily_summary.py`, leading to a more centralized and maintainable architecture. This included deprecating the standalone module and updating related tests to align with the new flow. I then implemented a robust AI invocation process in the `generate_daily_summary` function, integrating detailed prompt logic that enhanced AI interactions while addressing error handling to re-raise exceptions during failures. Finally, I undertook a thorough review of the test suite to correct xpassing tests, focusing on enhancing the accuracy and reliability of our testing framework. 23 | 24 | ## Challenges Overcome 25 | 26 | - Resolved the issue of missing AI API key during tests affecting reliability by establishing clear mocking strategies. 27 | 28 | - Addressed multiple test failures caused by incorrect mocks and lack of expected failures in tests marked as xfail, leading to a more accurate test suite. 29 | 30 | ## Learning & Insights 31 | 32 | - Came to understand the importance of robust error handling in AI interactions, as it significantly impacts the consistency of automated testing. 33 | 34 | - Recognized the value of maintaining clear, readable documentation in codebases—removing trivial content directly contributes to better maintainability. 35 | 36 | ## Discussion Highlights 37 | 38 | - No specific insightful discussions recorded, but the interactions helped clarify the implementation details for error handling and testing strategy. 39 | 40 | ## Tone/Mood 41 | **Mood:** accomplished and satisfied 42 | **Indicators:** Feeling of successful implementation and resolution of multiple test issues, with all integration tests passing and robust AI features integrated. 43 | 44 | ## Daily Metrics 45 | 46 | - **Commits:** 3 47 | - **Files Changed:** 10 48 | 49 | #### Source Files 50 | 51 | **Coverage**: July 15, 2025 52 | 53 | **Available Files**: 54 | - [2025-07-15-journal.md](sandbox-journal/daily/2025-07-15-journal.md) 55 | -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-07-16-summary.md: -------------------------------------------------------------------------------- 1 | # Daily Summary for 2025-07-16 2 | 3 | ## Summary 4 | Today was one of mixed challenges and accomplishments. The day started with a focus on troubleshooting the manual installation of the MCP Commit Story, where I faced a series of issues including `.env` parsing errors and malfunctioning MCP tools. Instead of shying away from these obstacles, I took the initiative to create a new task aimed at conducting hands-on testing in multiple local repositories to identify and resolve these issues. This proactive approach will not only help solve current problems but also streamline future deployments. Later in the day, I shifted my attention to improving the `CONTRIBUTING.md` file, where I successfully fixed several formatting issues that had caused checklist items to display improperly on GitHub. This essential update will greatly enhance readability and usability for future contributors, ensuring clearer guidance in the project's documentation. Overall, the day's work was rooted in practical problem-solving and a commitment to maintaining well-structured documentation for contributors. 5 | 6 | ## Progress Made 7 | I tackled significant technical hurdles today and found solutions to improve both the installation process of my project and the contributing documentation. Creating a task for troubleshooting was crucial in setting a clear direction for resolving existing issues. Fixing the formatting in the `CONTRIBUTING.md` file was another highlight, leading to a more user-friendly document that will benefit future contributors. 8 | 9 | ## Key Accomplishments 10 | 11 | - Established a task for manual installation and troubleshooting of the MCP Commit Story 12 | - Fixed markdown formatting issues in the CONTRIBUTING.md file 13 | 14 | ## Technical Progress (Detailed Implementation) 15 | Today's work focused on significant updates to the MCP Commit Story's documentation and installation processes. Initiated a new task that documents the manual installation and troubleshooting steps after encountering various deployment challenges such as `.env` parsing errors and malfunctions in the MCP tools. Additionally, corrected markdown formatting in the `CONTRIBUTING.md` file to ensure proper display of checklist items on GitHub, enhancing usability for project contributors. 16 | 17 | ## Challenges Overcome 18 | 19 | - Resolved `.env` parsing errors by establishing a systematic approach to troubleshooting deployment issues, ensuring a smoother installation experience moving forward. 20 | 21 | - Fixed the formatting issues in the `CONTRIBUTING.md` file that impeded readability, thus enhancing clarity of guidance for future contributors. 22 | 23 | ## Tone/Mood 24 | **Mood:** proactive and focused 25 | **Indicators:** Demonstrated determination in addressing installation challenges and attention to detail while fixing documentation issues. 26 | 27 | ## Daily Metrics 28 | 29 | - **Commits:** 2 30 | - **Files Changed:** 2 31 | 32 | #### Source Files 33 | 34 | **Coverage**: July 16, 2025 35 | 36 | **Available Files**: 37 | - [2025-07-16-journal.md](daily/2025-07-16-journal.md) 38 | -------------------------------------------------------------------------------- /sandbox-journal/summaries/daily/2025-07-19-summary.md: -------------------------------------------------------------------------------- 1 | # Daily Summary for 2025-07-19 2 | 3 | ## Summary 4 | Today was a day of significant troubleshooting and refinement for the AI-enhanced journal entries. I focused on diagnosing recurring issues stemming from environmental configurations after switching machines. I discovered that my terminal was using a placeholder API key during commits, leading to basic entries instead of rich AI-generated content. This realization prompted me to implement a centralized configuration approach in the `.mcp-commit-storyrc.yaml` file, providing a clean solution for API key management through variable interpolation. I also enhanced the error logging in the AI provider to better capture failures, aiming for a robust understanding of the environmental discrepancies affecting AI functionality. Overall, I made substantial progress in creating a more resilient journaling experience and improved the configuration system to prevent future issues. 5 | 6 | ## Reflections 7 | 8 | - I hate when you just change stuff without talking to me first. 9 | 10 | ## Progress Made 11 | I implemented significant enhancements to the journal generation system, focusing on the API key configuration and improving the error logging mechanism for better diagnostics of issues encountered during AI enhancements. This included addressing the problems caused by placeholder values and ensuring that future entries would be rich with AI-generated content. 12 | 13 | ## Key Accomplishments 14 | 15 | - Centralized API key management in the .mcp-commit-storyrc.yaml file. 16 | - Enhanced error logging in ai_provider.py for diagnosing intermittent failures. 17 | 18 | ## Technical Progress (Detailed Implementation) 19 | The commit introduced a new section in the configuration system for the OpenAI API key, allowing for seamless variable interpolation and reducing reliance on potentially incorrect environment variables. The changes were tested rigorously, achieving compliance with all existing tests and improving telemetry for configuration validation. 20 | 21 | ## Challenges Overcome 22 | 23 | - Addressed the issue of the OpenAI API key using a placeholder value by centralizing its configuration to prevent silent failures in AI functions. 24 | 25 | - Implemented a more detailed error logging system to capture the context of failures, making it easier to diagnose future issues related to AI enhancements. 26 | 27 | ## Learning & Insights 28 | 29 | - The need for centralized configuration not only simplifies user setup but also significantly reduces the risk of errors stemming from environmental inconsistencies. 30 | 31 | - Enhancing logging practices is crucial in software development, especially when diagnosing intermittent problems that can be challenging to reproduce. 32 | 33 | ## Tone/Mood 34 | **Mood:** frustrated but determined 35 | **Indicators:** Expressed frustration with changes made without communication while showing determination to correctly configure the system. 36 | 37 | ## Daily Metrics 38 | 39 | - **Commits:** 8 40 | - **Files Changed:** 15 41 | 42 | #### Source Files 43 | 44 | **Coverage**: July 19, 2025 45 | 46 | **Available Files**: 47 | - [2025-07-19-journal.md](daily/2025-07-19-journal.md) 48 | -------------------------------------------------------------------------------- /sandbox-journal/summaries/weekly/2025-05-week3.md: -------------------------------------------------------------------------------- 1 | # 2025-05-week3 — Weekly Summary (May 19–25, 2025) 2 | 3 | ## Summary 4 | This week marked a major leap in the MCP engineering journal system, with the team moving from foundational infrastructure to a robust, test-driven, and extensible architecture. The core journal entry pipeline was fully implemented, all canonical section generators were scaffolded and tested, and the context collection logic was refactored for modularity. The project underwent significant refactoring, documentation, and planning improvements, culminating in a green test suite and clarified MVP priorities. 5 | 6 | ## Technical Synopsis 7 | - Implemented and tested all major journal section generators in `journal.py` with strict anti-hallucination and formatting rules. 8 | - Extracted and unified context collection logic into `context_collection.py`, updating all references and tests. 9 | - Defined and documented TypedDicts for all context and section generator outputs, enforcing type safety and maintainability. 10 | - Refactored the test suite for full coverage, removing obsolete cases and ensuring all tests pass or are properly xfail/xpass. 11 | - Updated engineering spec, PRD, and README to reflect the new unified context model, section order, and anti-hallucination safeguards. 12 | - Consolidated git data collection and improved test reliability with temporary repos and explicit commit hashes. 13 | 14 | ## Accomplishments 15 | - Achieved full test coverage for all context types, section generators, and integration scenarios. 16 | - Canonicalized the journal entry pipeline with robust, test-driven section generators. 17 | - Improved codebase modularity and maintainability through targeted refactoring. 18 | - Clarified MVP priorities and critical path in Taskmaster, adding new subtasks for post-commit automation. 19 | - Maintained a green test suite throughout all major changes. 20 | - Completed a major package rename and resolved a large-scale data duplication bug. 21 | 22 | ## Challenges / Frustrations 23 | - Frustration with Python's lack of runtime TypedDict enforcement, requiring careful test design. 24 | - Integration and normalization of new section generators surfaced subtle edge cases, especially in tone/mood handling. 25 | - Test setup issues for git context filtering and context extraction required methodical debugging and best-practice solutions. 26 | - The majority of context extraction logic remains as AI-prompt-driven placeholders, pending future implementation. 27 | 28 | ## Mood / Tone 29 | > Methodical, focused, and confident. The week was marked by steady, detail-oriented progress, with a sense of satisfaction in achieving a robust and extensible foundation. Team sentiment was positive, with minor friction resolved through systematic approaches. 30 | 31 | ## Decision Points 32 | - Chose to formalize all context and section generator types before implementing content logic. 33 | - Opted for a unified context model and canonical section order for all journal entries. 34 | - Prioritized anti-hallucination compliance and test-driven development in all new code. 35 | - Decided to document GitPython binary file detection limitations and normalize input for journal entry parsing. 36 | - Added robust filtering to git context collection to prevent recursion. 37 | 38 | ## Metrics 39 | - Number of commits: 40+ (across all days) 40 | - Files changed: 100+ (including major refactors and documentation updates) 41 | - Test coverage: All implemented functionality has corresponding tests; all structure, compliance, and placeholder tests passing; AI/content tests xfail as expected 42 | - Major refactors: context collection, section generators, test suite, and documentation -------------------------------------------------------------------------------- /sandbox-journal/summariesV2/daily/2025-06-14-summary.md: -------------------------------------------------------------------------------- 1 | # Daily Summary - June 14, 2025 2 | 3 | ## Reflections 4 | 5 | ### 6:15 AM — Reflection 6 | 7 | I'm a bit overwhelmed by the refactor and by how much of this is in my head and not in Taskmaster or the repo, except for current journal entries 8 | 9 | The thing to focus on now is making the journal entries, then I'll worry about the rest. So 10 | 11 | 1 - Make chat collection work 12 | 13 | 2 - Make a function that intelligently knows which chat information to parse based on git diff (and other git info) 14 | 15 | 2 - Refactor the journal entry generator function (and orchestration layer?) that is triggered by git hook. It should take in three things: (1) git context, (2) relevant AI chat history and (3) today's journal entries if there are any, and perhaps the most recent 2 days' worth or something 16 | 17 | I do think there should be some sort of high-level project overview (like the project's README?) that the brand-new AI gets as input each time too. 18 | 19 | Then the funciton outputs a journal entry that is human readable but also tagged and machine readable for future AI parsing 20 | 21 | This function is NOT an MCP tool and it will run silently in the background. Again triggered by git hook, and so are the summaries. 22 | 23 | The function will invoke a brand-new AI instance that has no awareness of current project context except for what it is given 24 | 25 | 3 - This will happen later, but creating a new MCP tool journal/capture-context will be a high priority. 26 | The idea is that the user can manually run journal/capture-context and, because the journal entry generator function reads recent journal files, that context will make its way to the brand new AI that generates the entries 27 | 28 | ### 6:45 AM — Reflection 29 | 30 | After that last reflection I went down a rabbit hole, converting my thoughts into Taskmaster tasks. I *think* I have a path to MVP captured. Except I'd like to refactor the daily summary function to use the the new type of background, non-MCP generation... I'd consider that part of MVP. 31 | 32 | I feel better now that I'm more organized. And even though I got down about the git hook not being able to trigger the Cursor AI agent, ultimately I think the refactor makes for a stronger and better system. 33 | 34 | The only thing that could stop me now is if I can't produce the journal entry quality that I'm after without the Cursor AI's current context. But even then, I'm empowering the human user to add it. 35 | 36 | I'm excited. ٩(ˊᗜˋ*)و -------------------------------------------------------------------------------- /sandbox-journal/summariesV2/daily/2025-06-23-summary.md: -------------------------------------------------------------------------------- 1 | # Daily Summary - June 23, 2025 2 | 3 | ## Reflections 4 | 5 | *No manual reflections recorded for this date* 6 | 7 | ## Summary 8 | 9 | **A day of learning to simplify: what started as building complex database schema validation code ended up as a simple structure check plus a one-time exploration script** 10 | 11 | June 23rd revealed how easy it is to over-engineer a simple task. Task 45.4 was supposed to be basic database validation, but increasingly complex functionality was built until guidance led back to the minimal approach that was actually needed. 12 | 13 | ## Breakthrough Moments 14 | 15 | **🎯 The Over-Engineering Trap**: Complex schema validation with data exploration functions was initially built for Task 45.4. Multiple rounds of feedback were needed to simplify: "this is getting a bit over engineered," then "the data validation is too complex," then "this is still too over built." 16 | 17 | **🔍 One-Time Scripts vs Permanent Code**: The key insight was separating exploration work from production code. Instead of building complex validation functions, we created `scripts/explore_cursor_databases.py` for one-time investigation and kept Task 45.4 as just basic structure checks. 18 | 19 | **📊 Finding the Real Database Files**: The exploration script initially failed because it searched for `.db` files, but Cursor actually uses `.vscdb` files in `~/Library/Application Support/Cursor/User/workspaceStorage/`. This discovery unblocked all future chat collection work. 20 | 21 | **🧩 Task Scope Clarity**: We split the work properly: Task 45.4 became minimal validation (`validate_database_basics()` and `check_database_integrity()`), while deeper chat format research became new Task 45.7. 22 | 23 | ## Strategic Insights 24 | 25 | **Simple is Better**: The repeated simplification rounds showed that when someone says "this is too complex," they usually mean it's WAY too complex. The final solution was much simpler and more maintainable than the original approach. 26 | 27 | **Exploration vs Production**: Not everything needs to be permanent code. Sometimes a throwaway script that helps you understand the problem is more valuable than production functions that try to handle every edge case. 28 | 29 | **Listen to Feedback**: Multiple corrections were needed before the scope was properly understood. Each correction made the solution better and more focused. 30 | 31 | ## Technical Achievements 32 | 33 | **Minimal Validation Module**: Built simple `validation.py` with just two functions - `validate_database_basics()` (checks if ItemTable exists) and `check_database_integrity()` (basic SQLite health check). 34 | 35 | **Database Discovery Script**: Created 326-line `scripts/explore_cursor_databases.py` that finds Cursor databases, analyzes their structure, and reports on chat data availability. 36 | 37 | **Real Database Structure**: Discovered Cursor stores chat data in `.vscdb` files with `ItemTable` containing key-value pairs, where chat conversations are stored under the `aiService.prompts` key. 38 | 39 | ## Learning & Wisdom 40 | 41 | **Over-Engineering Recognition**: Complex schema validation, data format detection, and exploration functions were built when all that was needed was "does this database have the basic table structure we expect?" 42 | 43 | **Scope Boundaries**: Task 45.4 was about basic validation, not chat parsing. Task 46 would handle actual data extraction. Mixing these concerns made both tasks more complex than necessary. 44 | 45 | **Feedback Value**: The repeated guidance to simplify wasn't criticism - it was teaching to build exactly what's needed, not what might be needed someday. 46 | 47 | ## Context for Future Self 48 | 49 | This day taught a crucial lesson about scope creep and over-engineering. When tasked with "database validation," the temptation is to build comprehensive validation that handles every scenario. But often what's needed is much simpler: just verify the basic structure exists and is readable. 50 | 51 | The discovery of Cursor's actual file structure (`.vscdb` not `.db`) was the real breakthrough that unblocked chat collection development. 52 | 53 | **Key Lesson**: Build the minimum viable solution first, then expand only when you encounter actual problems. 54 | **Technical Discovery**: Cursor databases are `.vscdb` files in workspace storage with `ItemTable` schema 55 | **Process Insight**: Throwaway exploration scripts are often more valuable than premature production code -------------------------------------------------------------------------------- /sandbox-journal/summariesV2/daily/2025-07-02-summary.md: -------------------------------------------------------------------------------- 1 | # Daily Summary for 2025-07-02 2 | 3 | ## Summary 4 | 5 | July 2nd was a quiet reflection day with one idea: capturing user comments that end with exclamation points in journal entries. Whitney thought about adding either instructions or programmatic detection to automatically include user comments that use '!' at the end of sentences. This represents the kind of incremental thinking that happens between major development work - small ideas that could improve the journal generation process by making it more responsive to user emphasis and excitement. 6 | 7 | ## Reflections 8 | 9 | **11:53 AM**: When generating the journal entry, I think there should be some kind of instruction (maybe even programatic) for the journal to include any user comments that use '!' at the end of any sentences 10 | 11 | ## Progress Made 12 | 13 | This was a thinking day rather than an implementation day. Whitney considered how to make the journal system more responsive to user emphasis by automatically capturing comments that end with exclamation points. The idea addresses a gap in current journal generation - how to programmatically detect and preserve user excitement or emphasis markers during automated content creation. 14 | 15 | ## Key Accomplishments 16 | 17 | - Identified potential improvement for journal entry generation to capture user enthusiasm markers 18 | - Considered both instruction-based and programmatic approaches for detecting exclamation point usage 19 | 20 | ## Technical Progress (Detailed Implementation) 21 | 22 | No technical implementation occurred today. The reflection focused on feature design - specifically how to programmatically detect user comments ending with '!' and ensure they get included in journal entries. This could involve either prompt instructions for AI generation or automated text parsing during the journal creation process. 23 | 24 | ## Challenges Overcome 25 | 26 | None identified for this date. 27 | 28 | ## Learning & Insights 29 | 30 | **User Emphasis Detection**: The reflection reveals an interesting insight about automated journal generation - how do you programmatically detect and preserve user emotional indicators like exclamation points? This touches on a broader challenge in AI-assisted content creation: maintaining human emotional context during automated processing. 31 | 32 | ## Discussion Highlights 33 | 34 | None for this date. 35 | 36 | ## Tone/Mood 37 | 38 | **contemplative**: A quiet day of thinking about system improvements rather than active development. The reflection shows systematic thinking about user experience details - how to capture and preserve user enthusiasm in automated content generation. 39 | 40 | ## Daily Metrics 41 | 42 | - **Commits**: 0 43 | - **Reflections**: 1 44 | - **Ideas Generated**: 1 (exclamation point detection feature) 45 | - **Development Work**: 0 46 | 47 | #### Source Files 48 | 49 | **Coverage**: July 2, 2025 50 | 51 | **Available Files**: 52 | - [2025-07-02-journal.md](daily/2025-07-02-journal.md) -------------------------------------------------------------------------------- /scripts/agent_model_test_harness.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../tests/unit'))) 4 | from test_agent_model_validation import ( 5 | agent_model_parse, 6 | agent_model_generate_summary, 7 | DAILY_NOTE_MD, 8 | REFLECTION_MD, 9 | SUMMARY_MD, 10 | EMPTY_MD, 11 | MALFORMED_MD, 12 | ) 13 | 14 | def run_test_case(name, func, *args): 15 | print(f'--- {name} ---') 16 | try: 17 | result = func(*args) 18 | print('Result:', result) 19 | except Exception as e: 20 | print('Exception:', type(e).__name__, str(e)) 21 | print() 22 | 23 | def main(): 24 | run_test_case('Parse Daily Note', agent_model_parse, DAILY_NOTE_MD) 25 | run_test_case('Parse Reflection', agent_model_parse, REFLECTION_MD) 26 | run_test_case('Generate Summary', agent_model_generate_summary, SUMMARY_MD) 27 | run_test_case('Handle Empty Entry', agent_model_parse, EMPTY_MD) 28 | run_test_case('Handle Malformed Entry', agent_model_parse, MALFORMED_MD) 29 | 30 | if __name__ == '__main__': 31 | main() -------------------------------------------------------------------------------- /scripts/example_prd.txt: -------------------------------------------------------------------------------- 1 | 2 | # Overview 3 | [Provide a high-level overview of your product here. Explain what problem it solves, who it's for, and why it's valuable.] 4 | 5 | # Core Features 6 | [List and describe the main features of your product. For each feature, include: 7 | - What it does 8 | - Why it's important 9 | - How it works at a high level] 10 | 11 | # User Experience 12 | [Describe the user journey and experience. Include: 13 | - User personas 14 | - Key user flows 15 | - UI/UX considerations] 16 | 17 | 18 | # Technical Architecture 19 | [Outline the technical implementation details: 20 | - System components 21 | - Data models 22 | - APIs and integrations 23 | - Infrastructure requirements] 24 | 25 | # Development Roadmap 26 | [Break down the development process into phases: 27 | - MVP requirements 28 | - Future enhancements 29 | - Do not think about timelines whatsoever -- all that matters is scope and detailing exactly what needs to be build in each phase so it can later be cut up into tasks] 30 | 31 | # Logical Dependency Chain 32 | [Define the logical order of development: 33 | - Which features need to be built first (foundation) 34 | - Getting as quickly as possible to something usable/visible front end that works 35 | - Properly pacing and scoping each feature so it is atomic but can also be built upon and improved as development approaches] 36 | 37 | # Risks and Mitigations 38 | [Identify potential risks and how they'll be addressed: 39 | - Technical challenges 40 | - Figuring out the MVP that we can build upon 41 | - Resource constraints] 42 | 43 | # Appendix 44 | [Include any additional information: 45 | - Research findings 46 | - Technical specifications] 47 | -------------------------------------------------------------------------------- /scripts/message_limit_research_findings.txt: -------------------------------------------------------------------------------- 1 | # Message Limit Research Findings - Task 47.1 2 | # Analysis conducted: 2025-06-27 3 | # Research scope: Current workspace historical databases only 4 | 5 | ## DATA COLLECTED 6 | - Total databases analyzed: 7 Cursor state.vscdb files 7 | - Total messages analyzed: 910 messages 8 | - Human messages: 457 (50.2%) 9 | - AI messages: 453 (49.8%) 10 | - Average messages per database: 65.3 human, 64.7 AI 11 | 12 | ## RESEARCH LIMITATIONS 13 | ⚠️ CRITICAL LIMITATION: Human messages lack timestamps 14 | ⚠️ Cannot analyze true 48-hour development session patterns 15 | ⚠️ Analysis based on total volume across databases, not time windows 16 | ⚠️ Database modification times span multiple days/weeks of development 17 | 18 | ## CONSERVATIVE ANALYSIS 19 | Given the limitations, we make conservative inferences: 20 | - 910 total messages represents days/weeks of active development 21 | - Messages evenly split between human (457) and AI (453) 22 | - Even if all 910 messages occurred in 48 hours (impossible), that's only ~455 per type 23 | - Real development spans much longer periods 24 | 25 | ## RESEARCH CONCLUSION 26 | ✅ 200/200 limits are highly conservative and appropriate for solo developers 27 | ✅ Based on actual usage data showing much lower volumes 28 | ✅ Provides significant safety margin for edge cases 29 | ✅ Will not impact normal development workflows 30 | 31 | ## RECOMMENDED IMPLEMENTATION 32 | DEFAULT_MAX_HUMAN_MESSAGES = 200 33 | DEFAULT_MAX_AI_MESSAGES = 200 34 | 35 | These limits act as a safety net against extreme edge cases (automation, testing gone wrong) 36 | while never affecting normal solo developer usage patterns. -------------------------------------------------------------------------------- /scripts/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Test runner script for MCP Journal 3 | # This script activates the virtual environment and runs pytest 4 | 5 | set -e # Exit on any error 6 | 7 | # Print with colors 8 | GREEN='\033[0;32m' 9 | YELLOW='\033[1;33m' 10 | RED='\033[0;31m' 11 | NC='\033[0m' # No Color 12 | 13 | VENV_PATH=".venv" 14 | 15 | # Check if virtual environment exists 16 | if [ ! -d "$VENV_PATH" ]; then 17 | echo -e "${RED}Error: Virtual environment not found at $VENV_PATH.${NC}" 18 | echo -e "${YELLOW}Please run scripts/setup_test_env.sh first.${NC}" 19 | exit 1 20 | fi 21 | 22 | # Activate virtual environment 23 | echo -e "${YELLOW}Activating virtual environment...${NC}" 24 | source "$VENV_PATH/bin/activate" 25 | 26 | # Run pytest with arguments 27 | echo -e "${GREEN}Running tests...${NC}" 28 | python -m pytest "$@" 29 | TEST_EXIT_CODE=$? 30 | 31 | # Echo the test results 32 | if [ $TEST_EXIT_CODE -eq 0 ]; then 33 | echo -e "${GREEN}All tests passed!${NC}" 34 | else 35 | echo -e "${RED}Tests failed with exit code $TEST_EXIT_CODE${NC}" 36 | fi 37 | 38 | # Return the pytest exit code 39 | exit $TEST_EXIT_CODE -------------------------------------------------------------------------------- /scripts/setup_test_env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Setup script for MCP Journal test environment 3 | # This script creates a virtual environment and installs all development dependencies 4 | 5 | set -e # Exit on any error 6 | 7 | VENV_PATH=".venv" 8 | PROJ_ROOT=$(pwd) 9 | 10 | # Print with colors 11 | GREEN='\033[0;32m' 12 | YELLOW='\033[1;33m' 13 | RED='\033[0;31m' 14 | NC='\033[0m' # No Color 15 | 16 | echo -e "${GREEN}Setting up test environment for MCP Journal...${NC}" 17 | 18 | # Check if Python 3.9+ is installed 19 | if ! command -v python3 &> /dev/null; then 20 | echo -e "${RED}Error: Python 3 not found. Please install Python 3.9 or higher.${NC}" 21 | exit 1 22 | fi 23 | 24 | PYTHON_VERSION=$(python3 --version | cut -d' ' -f2) 25 | PYTHON_MAJOR=$(echo $PYTHON_VERSION | cut -d'.' -f1) 26 | PYTHON_MINOR=$(echo $PYTHON_VERSION | cut -d'.' -f2) 27 | 28 | if [ "$PYTHON_MAJOR" -lt 3 ] || ([ "$PYTHON_MAJOR" -eq 3 ] && [ "$PYTHON_MINOR" -lt 9 ]); then 29 | echo -e "${RED}Error: Python 3.9 or higher is required. Found Python $PYTHON_VERSION.${NC}" 30 | exit 1 31 | fi 32 | 33 | # Create virtual environment if it doesn't exist 34 | if [ ! -d "$VENV_PATH" ]; then 35 | echo -e "${YELLOW}Creating virtual environment at $VENV_PATH...${NC}" 36 | python3 -m venv "$VENV_PATH" 37 | else 38 | echo -e "${YELLOW}Using existing virtual environment at $VENV_PATH...${NC}" 39 | fi 40 | 41 | # Activate virtual environment 42 | echo -e "${YELLOW}Activating virtual environment...${NC}" 43 | source "$VENV_PATH/bin/activate" 44 | 45 | # Upgrade pip 46 | echo -e "${YELLOW}Upgrading pip...${NC}" 47 | pip install --upgrade pip 48 | 49 | # Install development dependencies 50 | echo -e "${YELLOW}Installing development dependencies...${NC}" 51 | pip install -e ".[dev]" 52 | 53 | # Verify pytest is installed and working 54 | echo -e "${YELLOW}Verifying pytest installation...${NC}" 55 | if pytest --version; then 56 | echo -e "${GREEN}Pytest is installed and working.${NC}" 57 | else 58 | echo -e "${RED}Failed to run pytest. Check your installation.${NC}" 59 | exit 1 60 | fi 61 | 62 | # Create a simple test runner script 63 | echo -e "${YELLOW}Creating test runner script...${NC}" 64 | cat > scripts/run_tests.sh << EOF 65 | #!/bin/bash 66 | # Test runner script for MCP Journal 67 | source .venv/bin/activate 68 | python -m pytest \$@ 69 | EOF 70 | chmod +x scripts/run_tests.sh 71 | 72 | echo -e "${GREEN}Test environment setup complete!${NC}" 73 | echo -e "${GREEN}You can run tests with: ./scripts/run_tests.sh${NC}" 74 | echo -e "${GREEN}Or activate the virtual environment with: source .venv/bin/activate${NC}" 75 | 76 | # Verification message 77 | echo "" 78 | echo -e "${YELLOW}Verifying Task 1 tests...${NC}" 79 | echo -e "Run: ./scripts/run_tests.sh tests/unit/test_structure.py tests/unit/test_imports.py" 80 | echo -e "All Task 1 tests must pass before marking Task 1 as complete." -------------------------------------------------------------------------------- /src/mcp_commit_story/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | MCP Commit Story - Automated journal creation from git commits and development context. 3 | 4 | This package provides TypedDict definitions and workflow functions for creating 5 | structured journal entries from development sessions. 6 | """ 7 | 8 | # Export workflow types for external use 9 | from .journal_workflow_types import * 10 | from .context_types import * 11 | -------------------------------------------------------------------------------- /src/mcp_commit_story/cursor_db/validation.py: -------------------------------------------------------------------------------- 1 | """ 2 | Basic database structure validation for Cursor SQLite workspaces. 3 | 4 | This module provides minimal validation functions to ensure Cursor databases 5 | have the basic structure needed for chat data extraction. All complex chat 6 | data validation is handled in separate modules. 7 | """ 8 | 9 | import sqlite3 10 | from typing import Dict, Any 11 | 12 | from .exceptions import CursorDatabaseSchemaError, CursorDatabaseQueryError 13 | 14 | 15 | def validate_database_basics(conn: sqlite3.Connection) -> bool: 16 | """ 17 | Validate basic database structure requirements. 18 | 19 | Verifies that the database has the minimum structure needed for 20 | chat data extraction: 21 | - ItemTable exists 22 | - ItemTable has key and value columns 23 | - Database can be queried successfully 24 | 25 | Args: 26 | conn: SQLite database connection 27 | 28 | Returns: 29 | True if database meets basic requirements 30 | 31 | Raises: 32 | CursorDatabaseSchemaError: If required structure is missing 33 | CursorDatabaseQueryError: If database cannot be queried 34 | """ 35 | try: 36 | cursor = conn.cursor() 37 | 38 | # Check if ItemTable exists 39 | cursor.execute( 40 | "SELECT name FROM sqlite_master WHERE type='table' AND name='ItemTable'" 41 | ) 42 | if not cursor.fetchone(): 43 | raise CursorDatabaseSchemaError( 44 | "Missing required ItemTable - database may not be a valid Cursor workspace" 45 | ) 46 | 47 | # Verify ItemTable has required columns 48 | cursor.execute("PRAGMA table_info(ItemTable)") 49 | columns = cursor.fetchall() 50 | 51 | column_names = [col[1] for col in columns] # Column name is at index 1 52 | 53 | if 'key' not in column_names: 54 | raise CursorDatabaseSchemaError( 55 | "ItemTable missing required 'key' column" 56 | ) 57 | 58 | if 'value' not in column_names: 59 | raise CursorDatabaseSchemaError( 60 | "ItemTable missing required 'value' column" 61 | ) 62 | 63 | # Verify we can query the table 64 | cursor.execute("SELECT COUNT(*) FROM ItemTable") 65 | cursor.fetchone() # Just verify the query works 66 | 67 | return True 68 | 69 | except sqlite3.Error as e: 70 | raise CursorDatabaseQueryError(f"Database query failed: {e}") from e 71 | 72 | 73 | def check_database_integrity(conn: sqlite3.Connection) -> Dict[str, Any]: 74 | """ 75 | Perform basic SQLite integrity checks. 76 | 77 | Args: 78 | conn: SQLite database connection 79 | 80 | Returns: 81 | Dictionary with integrity check results 82 | 83 | Raises: 84 | CursorDatabaseQueryError: If integrity checks cannot be performed 85 | """ 86 | try: 87 | cursor = conn.cursor() 88 | 89 | # Run integrity check 90 | cursor.execute("PRAGMA integrity_check") 91 | integrity_result = cursor.fetchone()[0] 92 | 93 | # Run quick check 94 | cursor.execute("PRAGMA quick_check") 95 | quick_check_result = cursor.fetchone()[0] 96 | 97 | is_healthy = ( 98 | integrity_result == "ok" and 99 | quick_check_result == "ok" 100 | ) 101 | 102 | return { 103 | 'healthy': is_healthy, 104 | 'integrity_check': integrity_result, 105 | 'quick_check': quick_check_result 106 | } 107 | 108 | except sqlite3.Error as e: 109 | raise CursorDatabaseQueryError(f"Integrity check failed: {e}") from e -------------------------------------------------------------------------------- /src/mcp_commit_story/daily_summary_standalone.py: -------------------------------------------------------------------------------- 1 | """DEPRECATED: Standalone daily summary generation module. 2 | 3 | ⚠️ DEPRECATION NOTICE ⚠️ 4 | 5 | This module has been consolidated into daily_summary.py as of task 73.3. 6 | All functionality has been moved to the main daily_summary module. 7 | 8 | For new code, import directly from daily_summary: 9 | from mcp_commit_story.daily_summary import generate_daily_summary_standalone 10 | 11 | This module now provides delegation functions for backwards compatibility only. 12 | It will be removed in a future version. 13 | 14 | Legacy usage (deprecated but still works): 15 | ```python 16 | from mcp_commit_story.daily_summary_standalone import generate_daily_summary_standalone 17 | 18 | # This still works but delegates to daily_summary.py 19 | summary = generate_daily_summary_standalone("2025-01-15") 20 | ``` 21 | 22 | New recommended usage: 23 | ```python 24 | from mcp_commit_story.daily_summary import generate_daily_summary_standalone 25 | 26 | # Use the consolidated module directly 27 | summary = generate_daily_summary_standalone("2025-01-15") 28 | ``` 29 | """ 30 | 31 | import warnings 32 | from typing import Optional, Dict 33 | 34 | def generate_daily_summary_standalone(date: Optional[str] = None, repo_path: Optional[str] = None, commit_metadata: Optional[Dict] = None): 35 | """DEPRECATED: Use mcp_commit_story.daily_summary.generate_daily_summary_standalone instead. 36 | 37 | This function delegates to the consolidated daily_summary module. 38 | """ 39 | warnings.warn( 40 | "daily_summary_standalone module is deprecated. Use 'from mcp_commit_story.daily_summary import generate_daily_summary_standalone' instead.", 41 | DeprecationWarning, 42 | stacklevel=2 43 | ) 44 | 45 | # Delegate to the consolidated module 46 | from .daily_summary import generate_daily_summary_standalone as consolidated_function 47 | return consolidated_function(date, repo_path, commit_metadata) 48 | 49 | 50 | # Legacy exports for backwards compatibility (all deprecated) 51 | __all__ = ['generate_daily_summary_standalone'] -------------------------------------------------------------------------------- /src/mcp_commit_story/journal/__init__.py: -------------------------------------------------------------------------------- 1 | """Journal module for engineering journal entry generation and management.""" 2 | 3 | # Re-export classes for backward compatibility 4 | from .models import JournalParser, JournalParseError 5 | from ..journal_generate import JournalEntry 6 | 7 | # Re-export functions from telemetry_utils module 8 | from .telemetry_utils import ( 9 | _add_ai_generation_telemetry, 10 | _record_ai_generation_metrics, 11 | log_ai_agent_interaction, 12 | _get_size_bucket, 13 | ) 14 | 15 | # Re-export utility functions and AI generators from journal_generate.py 16 | from ..journal_generate import ( 17 | ensure_journal_directory, 18 | get_journal_file_path, 19 | append_to_journal_file, 20 | load_journal_context, 21 | generate_summary_section, 22 | generate_technical_synopsis_section, 23 | generate_accomplishments_section, 24 | generate_frustrations_section, 25 | generate_tone_mood_section, 26 | generate_discussion_notes_section, 27 | generate_commit_metadata_section, 28 | ) 29 | 30 | __all__ = [ 31 | 'JournalEntry', 'JournalParser', 'JournalParseError', 32 | '_add_ai_generation_telemetry', '_record_ai_generation_metrics', 33 | 'log_ai_agent_interaction', '_get_size_bucket', 34 | 'ensure_journal_directory', 'get_journal_file_path', 35 | 'append_to_journal_file', 'load_journal_context', 36 | 'generate_summary_section', 'generate_technical_synopsis_section', 37 | 'generate_accomplishments_section', 'generate_frustrations_section', 38 | 'generate_tone_mood_section', 'generate_discussion_notes_section', 39 | 'generate_commit_metadata_section', 40 | ] -------------------------------------------------------------------------------- /src/mcp_commit_story/journal/sections/__init__.py: -------------------------------------------------------------------------------- 1 | """Journal section generators for different types of journal content.""" -------------------------------------------------------------------------------- /src/mcp_commit_story/journal_ai_utilities.py: -------------------------------------------------------------------------------- 1 | """ 2 | Shared AI utilities for journal section generation. 3 | 4 | This module provides utilities for AI-powered journal section generation, 5 | replacing the ai_function_executor.py abstraction layer with direct API calls. 6 | """ 7 | 8 | import json 9 | import logging 10 | from typing import Dict, Any, Optional 11 | from mcp_commit_story.context_types import JournalContext 12 | 13 | logger = logging.getLogger(__name__) 14 | 15 | 16 | def format_ai_prompt(docstring: str, context: Optional[JournalContext]) -> str: 17 | """ 18 | Format AI prompt with JSON context for direct invocation. 19 | 20 | This function replaces the ai_function_executor.py abstraction layer 21 | by providing a simple way to format prompts for direct OpenAI API calls. 22 | 23 | Args: 24 | docstring: The prompt text (usually from a function's docstring) 25 | context: Journal context data to provide to AI, or None 26 | 27 | Returns: 28 | Formatted prompt string ready for AI invocation 29 | 30 | Examples: 31 | >>> context = JournalContext(git={'metadata': {'hash': 'abc123'}}, chat=None, journal=None) 32 | >>> prompt = format_ai_prompt("Generate a summary", context) 33 | >>> print(prompt) 34 | Generate a summary 35 | 36 | The journal_context object has the following structure: 37 | ```json 38 | { 39 | "git": { 40 | "metadata": { 41 | "hash": "abc123" 42 | } 43 | }, 44 | "chat": null, 45 | "journal": null 46 | } 47 | ``` 48 | """ 49 | try: 50 | # Start with the docstring 51 | if not docstring: 52 | docstring = "" 53 | 54 | # Handle None context gracefully 55 | if context is None: 56 | context_json = json.dumps(None, indent=2) 57 | else: 58 | # Format context as JSON with proper indentation 59 | context_json = json.dumps(context, indent=2, default=str) 60 | 61 | # Format the complete prompt using the same structure as ai_function_executor 62 | full_prompt = f"{docstring}\n\nThe journal_context object has the following structure:\n```json\n{context_json}\n```" 63 | 64 | return full_prompt 65 | 66 | except Exception as e: 67 | logger.warning(f"Error formatting AI prompt: {e}") 68 | # Fallback to basic formatting 69 | return f"{docstring}\n\nContext: {str(context)}" -------------------------------------------------------------------------------- /src/mcp_commit_story/monthly_summary.py: -------------------------------------------------------------------------------- 1 | """ 2 | Monthly summary generation module. 3 | 4 | This module provides functionality for generating monthly summaries from weekly summaries. 5 | """ 6 | 7 | import logging 8 | from typing import Dict, Any 9 | from mcp_commit_story.summary_utils import add_source_links_to_summary 10 | 11 | logger = logging.getLogger(__name__) 12 | 13 | 14 | def generate_monthly_summary(month_str: str, config: Dict) -> Dict[str, Any]: 15 | """ 16 | Generate a monthly summary from weekly summaries. 17 | 18 | Args: 19 | month_str: Month identifier in YYYY-MM format 20 | config: Configuration dictionary with journal configuration 21 | 22 | Returns: 23 | Monthly summary dictionary with source file links 24 | """ 25 | # Placeholder implementation for testing 26 | monthly_summary = { 27 | "month": month_str, 28 | "summary": f"Monthly summary for {month_str}", 29 | "key_accomplishments": [], 30 | "monthly_metrics": {} 31 | } 32 | 33 | # Add source file links 34 | journal_path = config.get("journal", {}).get("path", "") 35 | summary_with_links = add_source_links_to_summary(monthly_summary, "monthly", month_str, journal_path) 36 | 37 | return summary_with_links -------------------------------------------------------------------------------- /src/mcp_commit_story/quarterly_summary.py: -------------------------------------------------------------------------------- 1 | """ 2 | Quarterly summary generation module. 3 | 4 | This module provides functionality for generating quarterly summaries from monthly summaries. 5 | """ 6 | 7 | import logging 8 | from typing import Dict, Any 9 | from mcp_commit_story.summary_utils import add_source_links_to_summary 10 | 11 | logger = logging.getLogger(__name__) 12 | 13 | 14 | def generate_quarterly_summary(year_quarter_str: str, config: Dict) -> Dict[str, Any]: 15 | """ 16 | Generate a quarterly summary from monthly summaries. 17 | 18 | Args: 19 | year_quarter_str: Year and quarter in format "YYYY,Q" (e.g., "2025,2" for Q2 2025) 20 | config: Configuration dictionary with journal configuration 21 | 22 | Returns: 23 | Quarterly summary dictionary with source file links 24 | """ 25 | # Placeholder implementation for testing 26 | quarterly_summary = { 27 | "year_quarter": year_quarter_str, 28 | "summary": f"Quarterly summary for {year_quarter_str}", 29 | "key_accomplishments": [], 30 | "quarterly_metrics": {} 31 | } 32 | 33 | # Add source file links 34 | journal_path = config.get("journal", {}).get("path", "") 35 | summary_with_links = add_source_links_to_summary(quarterly_summary, "quarterly", year_quarter_str, journal_path) 36 | 37 | return summary_with_links -------------------------------------------------------------------------------- /src/mcp_commit_story/weekly_summary.py: -------------------------------------------------------------------------------- 1 | """ 2 | Weekly summary generation module. 3 | 4 | This module provides functionality for generating weekly summaries from daily summaries. 5 | """ 6 | 7 | import logging 8 | from typing import Dict, Any 9 | from mcp_commit_story.summary_utils import add_source_links_to_summary 10 | 11 | logger = logging.getLogger(__name__) 12 | 13 | 14 | def generate_weekly_summary(start_date: str, config: Dict) -> Dict[str, Any]: 15 | """ 16 | Generate a weekly summary from daily summaries. 17 | 18 | Args: 19 | start_date: Start date of the week in YYYY-MM-DD format (should be Monday) 20 | config: Configuration dictionary with journal configuration 21 | 22 | Returns: 23 | Weekly summary dictionary with source file links 24 | """ 25 | # Placeholder implementation for testing 26 | weekly_summary = { 27 | "start_date": start_date, 28 | "summary": f"Weekly summary for week starting {start_date}", 29 | "key_accomplishments": [], 30 | "weekly_metrics": {} 31 | } 32 | 33 | # Add source file links 34 | journal_path = config.get("journal", {}).get("path", "") 35 | summary_with_links = add_source_links_to_summary(weekly_summary, "weekly", start_date, journal_path) 36 | 37 | return summary_with_links -------------------------------------------------------------------------------- /src/mcp_commit_story/yearly_summary.py: -------------------------------------------------------------------------------- 1 | """ 2 | Yearly summary generation module. 3 | 4 | This module provides functionality for generating yearly summaries from quarterly summaries. 5 | """ 6 | 7 | import logging 8 | from typing import Dict, Any 9 | from mcp_commit_story.summary_utils import add_source_links_to_summary 10 | 11 | logger = logging.getLogger(__name__) 12 | 13 | 14 | def generate_yearly_summary(year_str: str, config: Dict) -> Dict[str, Any]: 15 | """ 16 | Generate a yearly summary from quarterly summaries. 17 | 18 | Args: 19 | year_str: Year in format "YYYY" (e.g., "2025") 20 | config: Configuration dictionary with journal configuration 21 | 22 | Returns: 23 | Yearly summary dictionary with source file links 24 | """ 25 | # Placeholder implementation for testing 26 | yearly_summary = { 27 | "year": year_str, 28 | "summary": f"Yearly summary for {year_str}", 29 | "key_accomplishments": [], 30 | "yearly_metrics": {} 31 | } 32 | 33 | # Add source file links 34 | journal_path = config.get("journal", {}).get("path", "") 35 | summary_with_links = add_source_links_to_summary(yearly_summary, "yearly", year_str, journal_path) 36 | 37 | return summary_with_links -------------------------------------------------------------------------------- /talk_plan_how_to_trust_a_liar.md: -------------------------------------------------------------------------------- 1 | # “How to Trust a Liar” — Talk Planning Notes 2 | 3 | > A living outline capturing discussion threads and options for upcoming conference presentations about MCP Commit Story. Keep language concrete and avoid corporate buzzwords. 4 | 5 | --- 6 | 7 | ## 1. Context 8 | 9 | - **Project**: MCP Commit Story — automated engineering journal powered by Git data, Cursor chat logs, and AI section generators. 10 | - **Initial Architecture**: MCP server + AI agents triggered by git hooks (proved impossible). 11 | - **Current Architecture**: Background process (event-driven) that spawns fresh AI calls after each commit. 12 | - **Core Pain Point**: AI supplied confident but wrong guidance → required architectural pivot (see *“Building a Castle on Unstable Ground”* blog post). 13 | - **Observability**: Comprehensive OpenTelemetry spans wrap each `invoke_ai()` call and major pipeline steps (git-hook trigger, diff collection, file write). 14 | 15 | --- 16 | 17 | ## 2. Key Lessons 18 | 19 | 1. **AI Confidence ≠ AI Accuracy** — validate every assumption. 20 | 2. **Observability for Fuzzy Execution** — traces can reveal cost, latency, and silent content failures even when AI work lives in a single span. 21 | 3. **Pivot Early, Document Everything** — crisis stories become assets for teaching and tooling demos. 22 | 23 | --- 24 | 25 | ## 3. Talk Title (Locked-in) 26 | 27 | - **“How to Trust a Liar: Instrumenting AI Execution with OpenTelemetry”** 28 | 29 | --- 30 | 31 | ## 4. Presentation Shapes 32 | 33 | ### 4.1 Single-Talk Strategy 34 | 35 | | Aspect | Details | 36 | | --- | --- | 37 | | Audience | Keynote & breakout reuse | 38 | | Focus | Deep dive into instrumentation of AI pipeline | 39 | | Pros | One deck to maintain; heavy cloud-native tooling content | 40 | | Cons | Risk of losing non-practitioners during detail sections | 41 | 42 | ### 4.2 Two-Talk Strategy *(Recommended in discussion)* 43 | 44 | | Slot | Title / Angle | Ratio (Story : Tech) | Notes | 45 | | --- | --- | --- | --- | 46 | | Keynote | “How to Trust a Liar: Lessons from Rebuilding an AI-Powered System” | 70 : 30 | Narrative arc (castle-on-sand crisis → recovery) + one polished trace demo | 47 | | Breakout | “How to Trust a Liar — Deep Dive: OpenTelemetry Patterns for AI Pipelines” | 20 : 80 | Span design, cost & latency tags, FinOps dashboards, validation alerts | 48 | 49 | ### 4.3 Narrative-Only Strategy 50 | 51 | - Keynote (and any slot) focuses on emotional journey with light tooling cameo. 52 | - Pros: universally digestible; minimal prep. 53 | - Cons: Technical crowd may feel underserved. 54 | 55 | --- 56 | 57 | ## 5. Possible Otel Angles (for demos) 58 | 59 | 1. **Cost & Latency Governance** 60 | - Custom span attrs: `prompt_tokens`, `completion_tokens`, `usd_cost`, `latency_ms`, `retry_count`. 61 | - Dashboard: cost per section generator, P95 latency, error heat-map. 62 | 2. **Semantic Failure Detection** 63 | - Tag `valid_output` on spans; alert when false > x %. 64 | - Shows mismatch between 200 OK and “content is junk.” 65 | 3. **Pivot Feedback Loop** 66 | - Use trace to demonstrate how observability shortened iteration cycles after the architecture change. 67 | 68 | --- 69 | 70 | ## 6. Open Questions 71 | 72 | - Which conference slots will be offered (keynote only vs keynote + breakout)? 73 | - How quickly can Datadog dashboards be demo-ready? 74 | - Do we want to engineer a “bad prompt” example for the semantic-failure story? 75 | 76 | --- -------------------------------------------------------------------------------- /tasks/completed_tasks/task_007.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 7 2 | # Title: Implement CLI Interface 3 | # Status: done 4 | # Dependencies: None 5 | # Priority: medium 6 | # Description: Create the command-line interface using Click to provide setup functionality for the journal. This is a necessary foundation component for the MVP and other tasks. 7 | # Details: 8 | Implement the CLI interface in `src/mcp_journal/cli.py` with the following features: 9 | 10 | 1. CLI setup: 11 | ```python 12 | import click 13 | 14 | @click.group() 15 | def cli(): 16 | """MCP Journal - Engineering journal for Git repositories""" 17 | pass 18 | ``` 19 | 20 | 2. Setup command implementations: 21 | ```python 22 | @cli.command() 23 | @click.option("--debug", is_flag=True, help="Show debug information") 24 | def journal_init(debug): 25 | """Initialize journal in current repository""" 26 | # Implementation 27 | 28 | @cli.command() 29 | @click.option("--debug", is_flag=True, help="Show debug information") 30 | def install_hook(debug): 31 | """Install Git hook to connect with MCP server""" 32 | # Implementation 33 | ``` 34 | 35 | 3. Global options: 36 | ```python 37 | @click.option("--config", help="Override config file location") 38 | @click.option("--dry-run", is_flag=True, help="Preview operations without writing files") 39 | @click.option("--verbose", is_flag=True, help="Detailed output for debugging") 40 | ``` 41 | 42 | 4. Main entry point: 43 | ```python 44 | def main(): 45 | """Main entry point for CLI""" 46 | try: 47 | cli() 48 | except Exception as e: 49 | click.echo(f"Error: {e}", err=True) 50 | sys.exit(1) 51 | 52 | if __name__ == "__main__": 53 | main() 54 | ``` 55 | 56 | Note: This CLI is focused primarily on setup commands (journal-init, install-hook), but is a necessary foundation for the MVP as it's a blocking dependency for tasks 11, 12, 13, and 15, and has subtasks from MVP Task 9 that require CLI functionality. Most operational tasks (journal entry creation, reflection addition, summarization, etc.) are handled by the MCP server and AI agents, not through this CLI. 57 | 58 | # Test Strategy: 59 | 1. Unit tests for setup CLI commands (journal-init, install-hook) 60 | 2. Tests for command options and arguments 61 | 3. Tests for error handling 62 | 4. Tests for global options 63 | 5. Integration tests for setup commands 64 | 6. Tests for exit codes and error messages 65 | -------------------------------------------------------------------------------- /tasks/completed_tasks/task_024.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 24 2 | # Title: Update CLI Command Naming to journal-init and Refactor Tests 3 | # Status: done 4 | # Dependencies: None 5 | # Priority: high 6 | # Description: Refactor the CLI command for journal initialization from 'init' to 'journal-init' for clarity and consistency with MCP tool naming conventions. Update all integration and unit tests, Taskmaster plan, PRD, and documentation to reflect this change. Add or update tests to ensure the new command is discoverable and works as expected. Follow strict TDD for each subtask. 7 | # Details: 8 | Implementation Steps: 9 | 1. Update all integration and unit tests to use 'journal-init' instead of 'init'. 10 | 2. Update the Taskmaster plan, PRD, and engineering spec to reference 'journal-init'. 11 | 3. Add or update tests to verify 'journal-init' appears in CLI help and functions correctly. 12 | 4. Document the rationale for the naming change in the engineering spec and/or docs. 13 | 5. Mark the task complete when all tests pass and documentation is updated. 14 | 15 | Test Strategy: 16 | - All CLI and integration tests pass with the new command name. 17 | - CLI help output includes 'journal-init'. 18 | - Documentation and plan are consistent. 19 | 20 | # Test Strategy: 21 | 22 | 23 | # Subtasks: 24 | ## 1. Update Integration and Unit Tests to Use 'journal-init' [done] 25 | ### Dependencies: None 26 | ### Description: Update all integration and unit tests to use 'journal-init' instead of 'init'. 27 | 28 | TDD Steps: 29 | 1. WRITE TESTS FIRST 30 | - Identify all tests that reference the 'init' CLI command. 31 | - Write or update tests to expect 'journal-init'. 32 | - Test cases: CLI invocation, help output, error handling for unknown commands. 33 | - RUN TESTS - VERIFY THEY FAIL 34 | 2. IMPLEMENT FUNCTIONALITY 35 | - Update test code to use 'journal-init'. 36 | - Ensure all test scenarios are covered. 37 | - RUN TESTS - VERIFY THEY PASS 38 | 3. DOCUMENT AND COMPLETE 39 | - Add documentation IF NEEDED in three places (docs, PRD, engineering spec). 40 | - Double check all subtask requirements are met. 41 | - MARK COMPLETE. 42 | ### Details: 43 | 44 | 45 | ## 2. Update Taskmaster Plan, PRD, and Engineering Spec to Reference 'journal-init' [done] 46 | ### Dependencies: None 47 | ### Description: Update the Taskmaster plan, PRD, and engineering spec to reference 'journal-init' instead of 'init'. 48 | 49 | TDD Steps: 50 | 1. WRITE TESTS FIRST 51 | - Identify all documentation and plan references to the 'init' CLI command. 52 | - Write or update tests (if applicable) to check for correct references. 53 | - RUN TESTS - VERIFY THEY FAIL (if automated; otherwise, manual check). 54 | 2. IMPLEMENT FUNCTIONALITY 55 | - Update all documentation and plans to use 'journal-init'. 56 | - Ensure consistency across all references. 57 | - RUN TESTS - VERIFY THEY PASS (or manual verification). 58 | 3. DOCUMENT AND COMPLETE 59 | - Add documentation IF NEEDED in three places (docs, PRD, engineering spec). 60 | - Double check all subtask requirements are met. 61 | - MARK COMPLETE. 62 | ### Details: 63 | 64 | 65 | ## 3. Add or Update Tests to Verify 'journal-init' in CLI Help and Functionality [done] 66 | ### Dependencies: None 67 | ### Description: Add or update tests to verify that 'journal-init' appears in CLI help output and functions as expected. 68 | 69 | TDD Steps: 70 | 1. WRITE TESTS FIRST 71 | - Write or update tests to check that 'journal-init' is listed in CLI help output. 72 | - Test cases: help output, command invocation, error handling for unknown commands. 73 | - RUN TESTS - VERIFY THEY FAIL 74 | 2. IMPLEMENT FUNCTIONALITY 75 | - Ensure CLI help and command registration are correct. 76 | - Update code or tests as needed. 77 | - RUN TESTS - VERIFY THEY PASS 78 | 3. DOCUMENT AND COMPLETE 79 | - Add documentation IF NEEDED in three places (docs, PRD, engineering spec). 80 | - Double check all subtask requirements are met. 81 | - MARK COMPLETE. 82 | ### Details: 83 | 84 | 85 | -------------------------------------------------------------------------------- /tasks/completed_tasks/task_025.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 25 2 | # Title: Eliminate General CLI - Focus on MCP Server + AI Agent Workflow 3 | # Status: done 4 | # Dependencies: None 5 | # Priority: high 6 | # Description: Remove general-purpose CLI commands and focus on MCP server + AI agent workflow, keeping only essential setup commands. 7 | 8 | Architectural Decision Rationale: 9 | - Core journal functionality requires AI analysis (humans can't meaningfully analyze chat/terminal/git context) 10 | - Automation is the primary value proposition ("set and forget" journal) 11 | - Simpler product with clearer value proposition 12 | - Eliminates feature creep and maintenance overhead 13 | 14 | Required Changes: 15 | 1. Code Changes 16 | - Update src/mcp_commit_story/cli.py: Remove new-entry and add-reflection commands; keep only journal-init and install-hook (setup tasks); rename CLI group to focus on setup; update help text 17 | - Update pyproject.toml: Change entry point to mcp-commit-story-setup; update CLI references 18 | - Update src/mcp_commit_story/server.py: Add journal/add-reflection MCP operation; move functionality from CLI; ensure proper error handling and structured response 19 | 2. Documentation Changes 20 | - Update README.md: Remove operational CLI examples; add setup-only section; explain AI-agent workflow; emphasize automation 21 | - Update engineering-mcp-journal-spec-final.md: Remove/minimize CLI Interface section; focus on MCP server operations; update MCP Operations; remove CLI command examples 22 | 3. Task Plan Updates 23 | - Update tasks.json: Modify Task 7 to "Setup CLI Only"; update Tasks 9, 10, 11 to remove CLI requirements; update Task 22 to add journal/add-reflection MCP handler; note architectural change 24 | 4. Testing Updates 25 | - Remove CLI tests for operational commands; keep setup command tests; add MCP server tests for journal/add-reflection; update integration tests 26 | 27 | Implementation Steps: 28 | - Write failing tests for new MCP journal/add-reflection operation 29 | - Remove operational CLI commands, keep setup commands 30 | - Implement MCP add-reflection handler with error handling 31 | - Update documentation for AI-first architecture 32 | - Update pyproject.toml entry point 33 | - Run full test suite 34 | - Update task plan 35 | 36 | Success Criteria: 37 | - Only setup commands remain in CLI 38 | - All operational functionality via MCP server 39 | - journal/add-reflection works as MCP operation 40 | - Documentation reflects AI-first workflow 41 | - All existing functionality preserved via MCP server 42 | - Clear, simplified value proposition in docs 43 | 44 | # Details: 45 | This task represents a major architectural shift from general-purpose CLI to MCP-first with setup-only CLI. The goal is to simplify the product by clearly separating setup (human) from operations (AI/automated). 46 | 47 | Files to modify: 48 | - src/mcp_commit_story/cli.py 49 | - src/mcp_commit_story/server.py 50 | - pyproject.toml 51 | - scripts/mcp-commit-story-prd.md 52 | - engineering-mcp-journal-spec-final.md 53 | - docs/ (create architecture.md) 54 | - tests/unit/test_cli.py 55 | - tests/integration/test_mcp_server_integration.py 56 | 57 | # Test Strategy: 58 | Write tests to verify CLI is setup-only and MCP operations work correctly. Update existing tests to reflect new architecture. 59 | 60 | -------------------------------------------------------------------------------- /tasks/completed_tasks/task_036.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 36 2 | # Title: Implement Cursor Chat Database Integration for Journal Context Collection 3 | # Status: done 4 | # Dependencies: None 5 | # Priority: high 6 | # Description: Research and document the SQLite integration with the Cursor chat database to access complete conversation history for journal context collection, focusing on database structure, message extraction, and intelligent boundary detection. 7 | # Details: 8 | This task focused on researching the core SQLite integration with the Cursor chat database to enable reliable access to complete conversation history for journal context collection. The research phase has been completed successfully. 9 | 10 | ## Research Achievements 11 | 12 | 1. Investigated the current limited `collect_ai_chat_context` function in `context_collection.py` and identified its limitations. 13 | 14 | 2. Researched SQLite database locations and access patterns: 15 | - Documented multi-method workspace detection based on cursor-chat-browser patterns: 16 | * Windows: %APPDATA%\Cursor\User\workspaceStorage 17 | * WSL2: /mnt/c/Users//AppData/Roaming/Cursor/User/workspaceStorage 18 | * macOS: ~/Library/Application Support/Cursor/User/workspaceStorage 19 | * Linux: ~/.config/Cursor/User/workspaceStorage 20 | * Linux (remote/SSH): ~/.cursor-server/data/User/workspaceStorage 21 | - Analyzed workspace hash discovery and validation logic 22 | - Documented user configuration options for edge cases 23 | - Identified potential error scenarios for missing or inaccessible databases 24 | 25 | 3. Researched database query requirements: 26 | - Identified key tables and query patterns for `ItemTable` where key is one of: 27 | * `'aiService.prompts'` (legacy format) 28 | * `'workbench.panel.aichat.view.aichat.chatdata'` (standard format) 29 | * `'composerData'` (new format in globalStorage/state.vscdb) 30 | - Documented message structure for both human and AI messages 31 | - Analyzed message threading and conversation context preservation requirements 32 | - Documented timestamp and metadata formats for intelligent boundary detection 33 | - Analyzed JSON format parsing requirements for structured conversation history 34 | - Identified necessary error handling and logging approaches 35 | 36 | 4. Researched chat boundary detection approaches: 37 | - Documented smart boundary detection techniques using complete chat history access 38 | - Analyzed conversation breaks, topic changes, and manual delimiter patterns 39 | - Researched configurable limits and intelligent defaults based on cursor-chat-browser insights 40 | - Documented topic change detection mechanisms and session separation logic 41 | - Analyzed requirements for both automatic and manual boundary configuration 42 | - Documented approaches to ensure boundaries preserve the context of relevant chat segments 43 | 44 | ## Implementation Requirements (Moved to Separate Tasks) 45 | 46 | Based on the research findings, the implementation work has been divided into separate focused tasks (Tasks 45, 46, 47) to ensure proper execution of each component. 47 | 48 | Comprehensive documentation of all research findings can be found in docs/cursor-chat-database-research.md. 49 | 50 | # Test Strategy: 51 | The testing strategy has been updated to reflect the completion of the research phase. Implementation testing will be handled in the separate implementation tasks (45, 46, 47). 52 | 53 | 1. Research Documentation Review: 54 | - Verify all database access patterns are properly documented 55 | - Confirm database schema documentation is accurate and comprehensive 56 | - Ensure all identified error scenarios are documented 57 | - Verify boundary detection approaches are clearly explained 58 | - Confirm cross-platform considerations are thoroughly documented 59 | 60 | 2. Implementation Task Division Review: 61 | - Verify that all implementation requirements from the research are properly assigned to the new tasks 62 | - Ensure no critical implementation details are missed in the task division 63 | - Confirm that dependencies between implementation tasks are properly identified 64 | -------------------------------------------------------------------------------- /tasks/completed_tasks/task_055.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 55 2 | # Title: Implement collect_journal_context() for Reading Existing Journal Entries 3 | # Status: pending 4 | # Dependencies: 51 5 | # Priority: high 6 | # Description: Create a function to extract reflections and manual context from the current day's journal file that were added after the last journal entry, enabling iterative journaling where each commit builds upon new insights. 7 | # Details: 8 | Implement the `collect_journal_context(journal_date=None)` function in `context_collection.py` with the following specifications: 9 | 10 | 1. Function signature: 11 | ```python 12 | def collect_journal_context(journal_date=None): 13 | """ 14 | Extract reflections and manual context added after the last journal entry. 15 | 16 | Args: 17 | journal_date (str, optional): Date in YYYY-MM-DD format. Defaults to today. 18 | 19 | Returns: 20 | dict: Structured data containing reflections and manual context 21 | """ 22 | ``` 23 | 24 | 2. Implementation steps: 25 | - If journal_date is None, use the current date 26 | - Construct the path to the journal file: `journal/daily/YYYY-MM-DD-journal.md` 27 | - Check if the file exists; if not, return empty context 28 | - Read the journal file content 29 | - Identify the last journal entry marker (likely a timestamp or specific header) 30 | - Extract only content that appears after the last journal entry 31 | - Parse this content to identify: 32 | - Reflection sections (added via journal/add-reflection tool) 33 | - Manual context sections (added via journal/capture-context tool) 34 | - Structure the extracted data into a dictionary with appropriate categories 35 | - Ensure the function handles edge cases (no previous entries, malformed content) 36 | 37 | 3. Helper functions that may be needed: 38 | - A parser for reflection sections 39 | - A parser for manual context sections 40 | - A function to identify the last journal entry marker 41 | 42 | 4. Integration with existing code: 43 | - Ensure compatibility with the journal generation process 44 | - Maintain consistent data structures with other context collection functions 45 | 46 | 5. Research consideration: 47 | - During implementation, evaluate whether README/project context collection should be included in this function 48 | - Note that architecture docs specify four context sources: Git Context and Chat History (already implemented), Recent Journals (current focus), and Project Context (README or configured overview file) 49 | - Consider if Project Context should be part of collect_journal_context() or remain as a separate function 50 | - Document your decision and rationale in the implementation 51 | 52 | # Test Strategy: 53 | 1. Unit tests: 54 | - Create test_collect_journal_context.py with the following test cases: 55 | - Test with a journal file containing no entries (should return empty context) 56 | - Test with a journal file containing one entry but no post-entry content 57 | - Test with a journal file containing one entry followed by reflections 58 | - Test with a journal file containing one entry followed by manual context 59 | - Test with a journal file containing one entry followed by both reflections and manual context 60 | - Test with a journal file containing multiple entries with content between them 61 | - Test with invalid/malformed journal content 62 | - Test with non-existent date 63 | 64 | 2. Integration tests: 65 | - Verify the function works with the journal generation process 66 | - Test a complete workflow: add journal entry, add reflection, add manual context, generate new entry 67 | - Verify that only new content is incorporated into subsequent journal entries 68 | 69 | 3. Manual testing: 70 | - Create a sample journal file with multiple entries and post-entry content 71 | - Run the function and verify the output matches expectations 72 | - Test with real user journal files (if available) 73 | - Verify the function correctly handles different formatting styles 74 | 75 | 4. If Project Context collection is included: 76 | - Add tests for README/project context extraction 77 | - Test with various README formats and sizes 78 | - Test with custom configured overview files 79 | - Verify appropriate integration with other context sources 80 | -------------------------------------------------------------------------------- /tasks/completed_tasks/task_056.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 56 2 | # Title: Remove Terminal Command Collection Infrastructure 3 | # Status: done 4 | # Dependencies: None 5 | # Priority: high 6 | # Description: Remove all terminal command collection code and references from the codebase since this functionality is no longer feasible in the current architecture and provides limited value. 7 | # Details: 8 | This task involves systematically removing all terminal command collection infrastructure from the codebase: 9 | 10 | 1. First, identify all references to terminal-related code: 11 | - Use grep to search for "collect_ai_terminal_commands", "TerminalContext", "TerminalCommand", "TerminalCommandsSection", "generate_terminal_commands", and "journal_context.terminal" 12 | - Document all locations for systematic removal 13 | 14 | 2. Remove from Type System in src/mcp_commit_story/context_types.py: 15 | - Remove TerminalCommand TypedDict 16 | - Remove TerminalContext TypedDict 17 | - Remove TerminalCommandsSection TypedDict 18 | - Update JournalContext to remove terminal: Optional[TerminalContext] field 19 | 20 | 3. Remove Collection Function from src/mcp_commit_story/context_collection.py: 21 | - Remove entire collect_ai_terminal_commands() function 22 | - Remove related imports 23 | 24 | 4. Remove from Journal Generation in src/mcp_commit_story/journal.py: 25 | - Remove generate_terminal_commands_section() function 26 | - Remove related imports 27 | - Remove any calls to terminal generation 28 | 29 | 5. Update Integration Points: 30 | - Fix any code that constructs JournalContext to not include terminal field 31 | - Update any journal workflow code that expects terminal context 32 | - Ensure clean removal with no dangling references 33 | 34 | 6. Update Tests: 35 | - Remove tests specifically for terminal functionality 36 | - Update any integration tests that construct JournalContext 37 | - Fix any test fixtures that include terminal data 38 | 39 | 7. Documentation Cleanup: 40 | - Update docs/context-collection.md 41 | - Remove terminal command references from all documentation 42 | - Add removal note to architecture docs 43 | 44 | 8. Add architecture decision note to context_collection.py: 45 | ```python 46 | # Architecture Decision: Terminal Command Collection Removed (2025-06-27) 47 | # Terminal commands were originally designed to be collected by Cursor's AI with 48 | # access to its execution context. With the shift to external journal generation, 49 | # we no longer have access. Git diffs and chat context provide sufficient narrative. 50 | ``` 51 | 52 | # Test Strategy: 53 | 1. Before making changes: 54 | - Run full test suite to establish baseline: `python -m pytest tests/ -x --tb=short` 55 | - Note any tests that currently reference terminal functionality 56 | - Document current test count for comparison after removal 57 | 58 | 2. After making changes: 59 | - Run full test suite again: `python -m pytest tests/ -x --tb=short` 60 | - Verify same number of tests pass (minus any terminal-specific tests removed) 61 | - Re-run grep commands from identification step - all should return empty: 62 | ``` 63 | grep -r "collect_ai_terminal_commands" src/ tests/ 64 | grep -r "TerminalContext" src/ tests/ 65 | grep -r "TerminalCommand" src/ tests/ 66 | grep -r "TerminalCommandsSection" src/ tests/ 67 | grep -r "generate_terminal_commands" src/ tests/ 68 | grep -r "journal_context.terminal" src/ tests/ 69 | ``` 70 | - Manually verify that journal generation still works by running the journal generation process 71 | - Check that no references to terminal commands appear in generated journals 72 | - Verify documentation is updated and consistent with the removal of terminal command functionality 73 | 74 | 3. Final verification checklist: 75 | - All terminal-related types removed 76 | - All terminal-related functions removed 77 | - All references in other code updated 78 | - Tests updated and passing 79 | - Documentation updated 80 | - Architecture decision documented 81 | -------------------------------------------------------------------------------- /tasks/task_015.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 15 2 | # Title: Create Comprehensive Tests and Documentation 3 | # Status: pending 4 | # Dependencies: 11, 12, 13 5 | # Priority: high 6 | # Description: Develop comprehensive tests for all components and create documentation for the project. 7 | # Details: 8 | Create comprehensive tests and documentation with the following features: 9 | 10 | 1. Test fixtures: 11 | ```python 12 | @pytest.fixture 13 | def mock_git_repo(): 14 | """Create temporary git repo with test commits""" 15 | # Implementation 16 | 17 | @pytest.fixture 18 | def sample_journal_entries(): 19 | """Load sample journal files""" 20 | # Implementation 21 | 22 | @pytest.fixture 23 | def mock_terminal_history(): 24 | """Provide test terminal command history""" 25 | # Implementation 26 | 27 | @pytest.fixture 28 | def mock_chat_history(): 29 | """Provide test chat history""" 30 | # Implementation 31 | 32 | @pytest.fixture 33 | def mock_telemetry_exporter(): 34 | """Provide a test exporter that captures telemetry events""" 35 | # Implementation 36 | ``` 37 | 38 | 2. Unit tests: 39 | ```python 40 | def test_config_loading(): 41 | """Test configuration loading""" 42 | # Implementation 43 | 44 | def test_git_utils(): 45 | """Test git utilities""" 46 | # Implementation 47 | 48 | def test_journal_entry_generation(): 49 | """Test journal entry generation""" 50 | # Implementation 51 | 52 | def test_telemetry(): 53 | """Test telemetry integration""" 54 | # Implementation 55 | 56 | # Additional unit tests for all components 57 | ``` 58 | 59 | 3. Integration tests: 60 | ```python 61 | def test_cli_init(): 62 | """Test CLI init command""" 63 | # Implementation 64 | 65 | def test_cli_new_entry(): 66 | """Test CLI new-entry command""" 67 | # Implementation 68 | 69 | def test_mcp_server(): 70 | """Test MCP server operations""" 71 | # Implementation 72 | 73 | # Additional integration tests for all workflows 74 | ``` 75 | 76 | 4. Documentation: 77 | - README.md with project overview, installation, and usage 78 | - Configuration documentation 79 | - CLI command reference 80 | - MCP server API reference 81 | - Development guide 82 | - Examples and tutorials 83 | 84 | 5. Test coverage: 85 | - Configure pytest-cov for coverage reporting 86 | - Ensure >90% test coverage 87 | - Add coverage reporting to CI pipeline 88 | 89 | 6. Documentation structure: 90 | ``` 91 | README.md 92 | docs/ 93 | ├── configuration.md 94 | ├── cli.md 95 | ├── mcp-server.md 96 | ├── development.md 97 | └── examples/ 98 | ├── basic-usage.md 99 | ├── custom-configuration.md 100 | └── integration-examples.md 101 | ``` 102 | 103 | # Test Strategy: 104 | 1. Verify test coverage meets >90% threshold 105 | 2. Ensure all components have unit tests 106 | 3. Verify integration tests cover all workflows 107 | 4. Test documentation for accuracy and completeness 108 | 5. Verify examples work as documented 109 | 6. Test installation and usage instructions 110 | 7. Verify CI pipeline runs all tests 111 | 8. Ensure telemetry system is thoroughly tested with both unit and integration tests 112 | 113 | # Subtasks: 114 | ## 15.1. Implement telemetry-specific tests [pending] 115 | ### Dependencies: None 116 | ### Description: Create comprehensive tests for the telemetry system implemented in task 4 117 | ### Details: 118 | Develop unit and integration tests for the telemetry infrastructure including: 119 | 1. Test telemetry event generation 120 | 2. Test telemetry data collection 121 | 3. Test telemetry exporters 122 | 4. Test telemetry configuration options 123 | 5. Test telemetry integration with other components 124 | 125 | ## 15.2. Document telemetry system [pending] 126 | ### Dependencies: None 127 | ### Description: Create documentation for the telemetry system 128 | ### Details: 129 | Add telemetry documentation including: 130 | 1. Overview of telemetry capabilities 131 | 2. Configuration options for telemetry 132 | 3. How to extend telemetry with custom exporters 133 | 4. Privacy considerations 134 | 5. Add a telemetry.md file to the docs directory 135 | 136 | -------------------------------------------------------------------------------- /tasks/task_019.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 19 2 | # Title: Document MCP Server Configuration and Integration 3 | # Status: pending 4 | # Dependencies: None 5 | # Priority: medium 6 | # Description: Ensure the MCP server launch/discovery/configuration requirements are documented in the PRD, README, and codebase. The MCP server must be launchable as a standalone process, expose the required journal operations, and be discoverable by compatible clients. The method for launching the MCP server is not prescribed; it may be started via CLI, Python entry point, etc. 7 | # Details: 8 | 9 | 10 | # Test Strategy: 11 | 12 | 13 | # Subtasks: 14 | ## 1. Provide generic client/editor config block example [pending] 15 | ### Dependencies: None 16 | ### Description: Add a JSON example of a configuration block for connecting to the MCP server, showing command, args, and optional env vars. 17 | ### Details: 18 | 19 | 20 | ## 2. Clarify API key/env var requirements [pending] 21 | ### Dependencies: None 22 | ### Description: Document that API keys or environment variables are only required if the underlying SDK or provider needs them, not for all deployments. 23 | ### Details: 24 | 25 | 26 | ## 3. Ensure separation of MCP server config from journal config [pending] 27 | ### Dependencies: None 28 | ### Description: Make sure documentation clearly distinguishes between MCP server configuration and the journal system's .mcp-journalrc.yaml. 29 | ### Details: 30 | 31 | 32 | ## 4. Review and update README/docs [pending] 33 | ### Dependencies: 19.1, 19.2, 19.3 34 | ### Description: Review and update the README.md and other documentation to reflect changes made in this task. Ensure documentation is clear, accurate, and up to date. 35 | ### Details: 36 | 37 | 38 | -------------------------------------------------------------------------------- /tasks/task_021.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 21 2 | # Title: Integrate Codecov for Test Coverage Reporting 3 | # Status: pending 4 | # Dependencies: None 5 | # Priority: medium 6 | # Description: Set up Codecov integration with the GitHub repository to track and report test coverage metrics, culminating in a functional coverage badge in the README. 7 | # Details: 8 | This task involves establishing a connection between the repository and Codecov to enable automated test coverage reporting. Implementation steps include: 9 | 10 | 1. Create a Codecov account if not already available and link it to the organization's GitHub account 11 | 2. Add the repository to Codecov's dashboard 12 | 3. Generate a Codecov token for secure communication between CI and Codecov 13 | 4. Update the CI pipeline configuration (GitHub Actions, CircleCI, etc.) to: 14 | - Install necessary coverage tools (e.g., pytest-cov for Python) 15 | - Run tests with coverage collection enabled 16 | - Upload coverage reports to Codecov using the token 17 | 5. Add a `.codecov.yml` configuration file to the repository root to customize coverage settings (thresholds, exclusions, etc.) 18 | 6. Uncomment or add the Codecov badge in the README.md file using the format provided by Codecov 19 | 7. Verify the badge displays the actual coverage percentage after the first successful upload 20 | 21 | Consider setting coverage thresholds to maintain code quality and potentially configure PR comments from Codecov to highlight coverage changes in code reviews. 22 | 23 | # Test Strategy: 24 | To verify successful completion of this task: 25 | 26 | 1. Manually trigger a CI build and confirm the coverage report is generated and uploaded to Codecov 27 | 2. Check the Codecov dashboard to ensure: 28 | - The repository appears with correct coverage data 29 | - Historical data begins tracking from the first upload 30 | - Coverage reports include all relevant files (no critical omissions) 31 | 3. Verify the Codecov badge in the README: 32 | - Badge is properly displayed (not broken) 33 | - Badge shows an actual percentage value (not "unknown" or "N/A") 34 | - The percentage matches what's shown in the Codecov dashboard 35 | 4. Create a test PR with code changes that would affect coverage (both positively and negatively) to confirm: 36 | - Codecov reports the coverage change in the PR 37 | - The badge updates accordingly after merging 38 | 5. Document the integration process in the project documentation for future reference 39 | 6. Have another team member verify they can access the Codecov dashboard for the repository 40 | -------------------------------------------------------------------------------- /tasks/task_022.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 22 2 | # Title: Implement Remaining MCP Server Handlers 3 | # Status: pending 4 | # Dependencies: 11, 12, 13 5 | # Priority: medium 6 | # Description: Add the remaining non-MVP MCP tool handlers to complete the full feature set after their backend dependencies are implemented. 7 | # Details: 8 | Implement the remaining MCP server tool handlers in `src/mcp_commit_story/server.py` to complete the full feature set: 9 | 10 | 1. **journal/summarize** handler: 11 | - Depends on Task 11 (Summary Generation) 12 | - Handle daily, weekly, monthly, yearly summary requests 13 | - Return summary content and file paths 14 | - Must use on-demand directory creation pattern 15 | 16 | 2. **journal/blogify** handler: 17 | - Depends on Task 12 (Blog Post Generation) 18 | - Convert journal entries to blog post format 19 | - Accept multiple file inputs 20 | - Must use on-demand directory creation pattern 21 | 22 | 3. **journal/backfill** handler: 23 | - Depends on Task 13 (Backfill Functionality) 24 | - Detect and create entries for missed commits 25 | - Return list of created entries 26 | - Must use on-demand directory creation pattern 27 | 28 | 4. **journal/add-reflection** handler: 29 | - Add reflection content to existing journal entries 30 | - Accept entry path and reflection content 31 | - Must use on-demand directory creation pattern 32 | 33 | All handlers should: 34 | - Use existing `@handle_mcp_error` decorator 35 | - Follow TypedDict patterns established in Tasks 6.3-6.4 36 | - Include proper async/await support 37 | - Integrate with existing backend logic from their dependency tasks 38 | - Include comprehensive error handling and validation 39 | - Call ensure_journal_directory(file_path) before writing any files 40 | - Never create directories upfront - only on demand when needed 41 | - Implement as MCP operations only (no CLI commands required) 42 | - Focus exclusively on MCP/AI agent operations for file-writing handlers 43 | 44 | Note that the CLI functionality is limited to setup commands (journal-init, install-hook) only. All file-writing functionality must be implemented as MCP operations. Refer to the updated engineering spec and README.md for implementation details and test patterns. 45 | 46 | # Test Strategy: 47 | 1. Unit tests for each new handler 48 | 2. Integration tests with backend logic 49 | 3. Error handling validation 50 | 4. End-to-end workflow testing 51 | 5. Backward compatibility with existing handlers 52 | 6. Verify on-demand directory creation pattern is used correctly 53 | 7. Test that directories are only created when files are actually written 54 | 8. Verify ensure_journal_directory() is called before file writes 55 | 9. Verify all file-writing functionality is accessible via MCP operations only 56 | 10. Test the journal/add-reflection handler functionality as an MCP operation 57 | -------------------------------------------------------------------------------- /tasks/task_065.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 65 2 | # Title: Update Journal Section Prompts for Concrete Language and Improved Content Quality 3 | # Status: pending 4 | # Dependencies: 66 5 | # Priority: high 6 | # Description: Revise all journal section prompts to replace abstract corporate language with concrete, specific language that captures real development stories, emotional journeys, and decision points. 7 | # Details: 8 | This task involves implementing the External Reader Accessibility Guidelines across all journal section prompts to improve content quality: 9 | 10 | 1. Identify all existing journal section prompts in the codebase: 11 | - Daily summary prompts 12 | - Weekly reflection prompts 13 | - Milestone documentation prompts 14 | - Any other journal content generation prompts 15 | 16 | 2. For each prompt: 17 | - Remove abstract corporate language and replace with guidance for concrete, specific descriptions 18 | - Add explicit instructions to capture important statements with emphasis ('!') 19 | - Remove artificial mood categorizations and encourage authentic emotional expression 20 | - Add specific prompting for decision points and trade-offs made during development 21 | - Include guidance to connect technical progress with the emotional journey 22 | 23 | 3. Example prompt transformation: 24 | From: "Describe the revolutionary implementation of architectural components" 25 | To: "Describe specifically what you built today, including: 26 | - Exact problems you encountered and how you solved them 27 | - Key decisions you made and why (what alternatives did you consider?) 28 | - How you felt during challenging moments and what you learned 29 | - Concrete examples of code or functionality you implemented" 30 | 31 | 4. Update the prompt templates in the codebase: 32 | - Modify prompt template files 33 | - Update any hardcoded prompts in the AI function implementations 34 | - Ensure all journal-related functions use the updated prompts 35 | 36 | 5. Document the changes in a README or documentation file explaining the new guidelines for journal content. 37 | 38 | # Test Strategy: 39 | 1. Manual Review: 40 | - Review all updated prompt templates against the External Reader Accessibility Guidelines 41 | - Verify each prompt explicitly requests concrete language, emotional journey, and decision points 42 | - Check that artificial mood categorizations have been removed 43 | 44 | 2. Test Journal Generation: 45 | - Generate sample journal entries using the updated prompts 46 | - Verify the generated content includes specific technical details rather than abstract language 47 | - Confirm the content captures decision points, trade-offs, and emotional aspects 48 | - Have team members review sample outputs to ensure they provide value to external readers 49 | 50 | 3. User Testing: 51 | - Have 2-3 team members use the updated journal prompts for their actual work 52 | - Collect feedback on whether the prompts are clear and produce better quality content 53 | - Compare before/after examples of journal content to verify improvement 54 | 55 | 4. AI Analysis: 56 | - Run a test where an AI analyzes old vs. new journal content 57 | - Verify the AI can extract more concrete information and insights from the new content 58 | - Confirm the new content provides more value for future reference 59 | -------------------------------------------------------------------------------- /tasks/task_066.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 66 2 | # Title: Optimize Journal Sections - Remove Low-Value Sections and Enhance High-Value Ones 3 | # Status: pending 4 | # Dependencies: 63 5 | # Priority: medium 6 | # Description: Analyze historical journal usage patterns to identify and remove low-value sections while enhancing high-value ones, making the journal leaner and more focused on what provides meaningful insights to developers. 7 | # Details: 8 | This task involves a data-driven approach to optimize the journal's content based on actual usage patterns: 9 | 10 | 1. **Data Collection and Analysis**: 11 | - Review past journal reflections and daily summaries (at least 2-4 weeks of data) 12 | - Create a spreadsheet or structured document to track: 13 | - Which sections developers reference in their reflections 14 | - Which sections receive substantive responses vs. minimal/repetitive ones 15 | - Patterns of skipped sections or sections with low engagement 16 | - Quantify the value of each section based on this analysis 17 | 18 | 2. **Decision Framework**: 19 | - Establish criteria for keeping, modifying, or removing sections: 20 | - High value: Sections frequently referenced or built upon in reflections 21 | - Medium value: Sections with inconsistent but occasional value 22 | - Low value: Sections rarely engaged with or providing minimal insight 23 | 24 | 3. **Implementation**: 25 | - For sections to remove: 26 | - Document the rationale for removal 27 | - Update the modular structure to remove these section files 28 | - Update any imports or references in the main journal.py file 29 | - For sections to keep: 30 | - Enhance prompts to be more specific and thought-provoking 31 | - Improve the context provided to these sections 32 | - Consider merging related sections if appropriate 33 | 34 | 4. **Prompt Engineering**: 35 | - For high-value sections, refine prompts to: 36 | - Be more specific and targeted 37 | - Include better context from the codebase or previous entries 38 | - Encourage deeper reflection rather than surface-level responses 39 | 40 | 5. **Documentation Updates**: 41 | - Update documentation to reflect the new streamlined journal structure 42 | - Document the reasoning behind section removals and enhancements 43 | - Provide guidance on how to best utilize the remaining sections 44 | 45 | The goal is to create a leaner, more focused journal that emphasizes quality over quantity, ensuring developers spend time on reflections that provide genuine value rather than filling out sections that don't contribute to insights or growth. 46 | 47 | # Test Strategy: 48 | 1. **Quantitative Testing**: 49 | - Compare journal completion times before and after optimization (should decrease) 50 | - Track the average length and depth of responses in remaining sections (should increase) 51 | - Measure the frequency of developers referencing journal insights in their work 52 | 53 | 2. **Qualitative Testing**: 54 | - Conduct user interviews with 3-5 developers after using the optimized journal for 1-2 weeks 55 | - Create a survey to gather feedback on: 56 | - Perceived value of the journal before vs. after 57 | - Whether removed sections are missed 58 | - Whether enhanced sections provide better prompts for reflection 59 | - Review the quality of reflections in the optimized journal compared to previous entries 60 | 61 | 3. **Functional Testing**: 62 | - Verify all remaining journal sections render correctly 63 | - Ensure no references to removed sections remain in the codebase 64 | - Test the journal generation process end-to-end to confirm no errors 65 | 66 | 4. **A/B Testing (if possible)**: 67 | - Allow some developers to use the original journal and others the optimized version 68 | - Compare engagement metrics and quality of reflections between the two groups 69 | 70 | 5. **Regression Testing**: 71 | - Ensure that the journal still integrates properly with other system components 72 | - Verify that historical journal entries can still be accessed and viewed correctly 73 | - Check that any analytics or reporting based on journal data still functions properly 74 | 75 | Success criteria: Developers report higher satisfaction with the journal process, spend less time completing entries, but produce more valuable insights in the sections that remain. 76 | -------------------------------------------------------------------------------- /tasks/task_072.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 72 2 | # Title: Integrate Tagging System into Daily Summary Generation 3 | # Status: pending 4 | # Dependencies: 71 5 | # Priority: medium 6 | # Description: Update the daily summary generation system to leverage the tagging and narrative threading system from task 71, enabling daily summaries to surface story arcs, recurring themes, and emotional-technical connections. 7 | 8 | # Requirements: 9 | - Integrate tagging system from task 71 into daily summary generation workflow 10 | - Enable daily summaries to detect and display recurring themes from journal entries 11 | - Incorporate emotion-tech pairing insights into daily summary structure 12 | - Implement narrative threading to connect story arcs within daily summaries 13 | - Add AI-as-character elements to daily summary generation prompts 14 | - Maintain existing daily summary functionality while adding tagging capabilities 15 | - Ensure tagged content is properly preserved and displayed in summary output 16 | - Add comprehensive testing for tagging integration with daily summaries 17 | - Update telemetry to track tagging system usage and effectiveness in daily summaries 18 | - Maintain backward compatibility with existing daily summary consumers 19 | 20 | # Notes: 21 | ## Initial Context: 22 | - Task 71 provides the core tagging system with #breakthrough, #AI-misstep, #pivot, #recurring-issue tags 23 | - Daily summaries should leverage this tagging to create more narrative-driven content 24 | - Need to consider how tagging fits into existing daily summary structure and format 25 | 26 | ## Design Decisions for Future Consideration: 27 | 28 | ### Architecture Questions: 29 | 1. **Summary Structure Philosophy**: Should journal sections remain consistent between entries and summaries, or should summaries have their own specialized sections? 30 | 31 | 2. **Individual Generator Pattern**: Should we create separate generators for different summary types (daily, weekly, monthly)? 32 | 33 | 3. **Tagging Integration Point**: Where should tagging be applied in the daily summary workflow? 34 | 35 | 4. **Narrative Threading Scope**: How much narrative context should daily summaries include? 36 | 37 | 5. **Story Arc Discovery**: How should daily summaries help surface longer story arcs? 38 | 39 | ## Implementation Strategy: 40 | - TBD after design decisions are made during Phase 2 discussion 41 | 42 | --- 43 | 44 | # Subtasks 45 | TBD - Subtasks will be created in Phase 2 after design decisions are discussed and finalized. 46 | 47 | --- 48 | 49 | ## Task Completion 50 | Final verification: 51 | [ ] All requirements above completed -------------------------------------------------------------------------------- /tasks/task_074.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 74 2 | # Title: Create Multi-Layered Entertaining Demo for Git Hook → Journal Workflow 3 | # Status: pending 4 | # Dependencies: None 5 | # Priority: high 6 | # Description: Create an entertaining, multi-layered demo showing the complete git hook → journal workflow for codebase presentation, combining multiple demo elements to tell a cohesive story of progressive codebase cleanup 7 | 8 | # Requirements: 9 | - Create multiple demo elements that can be combined into a cohesive demonstration flow 10 | - Show git hook triggering journal entry creation through multiple commit cycles 11 | - Demonstrate chat integration with AI context capture workflow 12 | - Include manual reflection addition to show complete journal ecosystem 13 | - Make demo memorable, engaging, and fun for presentation audience 14 | - Ensure predictable, reliable results for live demonstration 15 | - Show before/after workflow states clearly at each stage 16 | - Demonstrate multiple aspects of the journal system (commits, AI chat, reflections, prompts) 17 | 18 | # Notes: 19 | ## Initial Context: 20 | - Demo scheduled for tomorrow's presentation - 2025-07-14 22:09 CDT 21 | - Should demonstrate core value proposition of git hook → journal workflow 22 | - Multiple demo elements can be combined (not mutually exclusive) 23 | - Focus on showing concrete before/after states rather than just theory 24 | - Need to balance entertainment value with professional presentation requirements 25 | 26 | ## Potential Demo Elements Identified: 27 | 1. **Baklava References**: Hidden throughout codebase in comments, function names, documentation 28 | 2. **Rick Roll Console Logs**: Console logs that spell out "Never gonna give you up" during journal generation 29 | 3. **AI Prompt Modifications**: Temporary prompt changes (southern drawl, Office quotes, etc.) 30 | 4. **Chat Integration**: Show AI conversation → context capture → journal integration 31 | 5. **Manual Reflections**: Demonstrate reflection addition workflow 32 | 6. **Progressive Cleanup**: Show multiple commit cycles of improvement 33 | 34 | ## Success Criteria: 35 | - Demonstrates complete git hook → journal workflow end-to-end 36 | - Shows multiple system capabilities (commits, chat, reflections, AI customization) 37 | - Reliable and predictable for live presentation 38 | - Engaging and memorable for audience 39 | - Professional but entertaining tone 40 | 41 | # Design Decisions for Future Consideration: 42 | - Which specific demo elements to implement and in what combination 43 | - Optimal sequencing of demo phases for maximum impact 44 | - Where to place each type of demo element for best demonstration effect 45 | - How many commit cycles to show (balance between comprehensive and concise) 46 | - Whether to include AI prompt modification (currently not user-configurable) 47 | - What additional creative demo elements beyond the initial three options 48 | - Integration approach for chat → context capture → journal workflow 49 | 50 | --- 51 | 52 | # Subtasks 53 | [To be created after design decisions made] -------------------------------------------------------------------------------- /tasks/task_075.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 75 2 | # Title: Fix Over-Mocking Anti-Pattern in Test Suite 3 | # Status: pending 4 | # Dependencies: None 5 | # Priority: medium 6 | # Description: Improve test quality by reducing over-mocking and focusing tests on behavior rather than implementation details 7 | 8 | # Requirements: 9 | - Identify test files with excessive function-level mocking that makes tests brittle 10 | - Replace over-mocked tests with behavior-focused tests that mock only external dependencies 11 | - Preserve test coverage while improving test maintainability and value 12 | - Establish clear guidelines for what should and shouldn't be mocked 13 | - Update test patterns to follow "mock external dependencies, test internal behavior" principle 14 | - Ensure tests remain valuable during refactoring by testing public interfaces rather than implementation 15 | 16 | # Notes: 17 | ## Current Problem: 18 | The test suite uses extensive `@patch` decorators to mock every internal function, creating brittle tests that break during refactoring even when behavior is preserved. This pattern tests implementation rather than behavior, reducing test value and maintainability. 19 | 20 | ## Examples of Over-Mocking: 21 | ```python 22 | @patch('module.function_a') 23 | @patch('module.function_b') 24 | @patch('module.function_c') 25 | def test_main_function(mock_c, mock_b, mock_a): 26 | # Tests implementation, not behavior 27 | ``` 28 | 29 | ## Better Pattern: 30 | ```python 31 | @patch('module.external_api_call') # Mock external dependency only 32 | def test_main_function(mock_api): 33 | # Test real internal function interactions and behavior 34 | ``` 35 | 36 | ## Design Decisions for Future Consideration: 37 | 1. **Scope**: Should we fix all test files at once, or focus on specific modules first? 38 | 2. **Mock boundaries**: What constitutes an "external dependency" vs "internal behavior"? 39 | 3. **Coverage preservation**: How do we ensure refactored tests maintain the same coverage? 40 | 4. **Pattern documentation**: Should we create testing guidelines as part of this task? 41 | 5. **Integration with existing patterns**: How do we align with current TDD methodology while improving test quality? 42 | 43 | --- 44 | 45 | # Subtasks 46 | [To be created after design decisions are made] -------------------------------------------------------------------------------- /tasks/task_076.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 76 2 | # Title: Cross-Workspace Installation and Troubleshooting 3 | # Status: pending 4 | # Dependencies: 70 5 | # Priority: high 6 | # Description: Manual installation and troubleshooting of MCP Commit Story in 2 additional local workspaces to identify and fix real-world deployment issues through hands-on testing and iterative problem-solving. 7 | 8 | # Requirements: 9 | - Manually install MCP Commit Story in 2 different local workspaces 10 | - Document and fix all problems encountered during installation and setup 11 | - Fix git hook .env file parsing issues that cause export errors with comments and malformed environment variables 12 | - Reduce excessive default configuration 13 | - Resolve MCP tool functionality issues including incorrect date handling and content generation failures 14 | - Create troubleshooting diagnostics for common installation and operational issues 15 | - Verify proper multi-workspace behavior through real-world testing 16 | - Establish reliable AI provider integration with proper fallback mechanisms 17 | - Create user-friendly error reporting and resolution guidance 18 | 19 | # Context: 20 | During initial cross-workspace deployment testing, multiple critical issues were discovered: 21 | 22 | 1. **Git Hook Environment Issues**: Hook fails with `.env` parsing errors when file contains comments or complex formatting 23 | 2. **MCP Tool Failures**: Both `journal/add-reflection` and `journal/capture-context` tools exhibit serious functionality issues 24 | 3. **Date/Time Issues**: MCP responses show incorrect dates (Dec 19 2024 instead of July 16 2025) suggesting timestamp handling problems 25 | 4. **Content Generation Problems**: Tools appear to hallucinate content rather than creating actual reflections 26 | 5. **Configuration Complexity**: Default configuration contains excessive detail that confuses initial setup 27 | 28 | These issues prevent successful deployment across multiple workspaces and significantly impact user experience. 29 | 30 | ## Specific Error Examples: 31 | ```bash 32 | # Git hook .env parsing errors: 33 | .git/hooks/post-commit: line 4: export: `#': not a valid identifier 34 | .git/hooks/post-commit: line 4: export: `Required:': not a valid identifier 35 | .git/hooks/post-commit: line 4: export: `Format:': not a valid identifier 36 | .git/hooks/post-commit: line 4: export: `sk-ant-api03-...': not a valid identifier 37 | .git/hooks/post-commit: line 4: export: `pplx-...': not a valid identifier 38 | ``` 39 | 40 | ## MCP Tool Failure Patterns: 41 | - **Add reflection tool**: Reports success but creates no files, uses wrong dates (Dec 19 2024 instead of July 16 2025), generates hallucinated content 42 | - **Capture context tool**: Returns null errors, creates no journal entries 43 | - **Both tools**: Report successful file paths that don't correspond to actual file creation 44 | 45 | ## Approach: 46 | This will be a **manual, hands-on troubleshooting exercise** where issues are discovered through real installation attempts and fixed iteratively as problems arise. The focus is on practical problem-solving rather than theoretical development. 47 | 48 | ## Test Workspaces: 49 | - **Workspace 1**: vibe_practice (already partially tested - has known issues) 50 | - **Workspace 2**: [TBD - second local repository] 51 | - **Workspace 3**: [TBD - third local repository] 52 | 53 | ## Manual Testing Process: 54 | 1. **Fresh Installation**: Install MCP Commit Story from scratch in each workspace 55 | 2. **Document Issues**: Record every problem, error message, and unexpected behavior 56 | 3. **Iterative Fixes**: Address issues one at a time based on real-world impact 57 | 4. **Validation**: Test fixes across all workspaces to ensure consistency 58 | 5. **Documentation**: Create practical troubleshooting guides based on actual problems encountered 59 | 60 | ## Initial Constraints: 61 | - Should not break current working configurations during fixes 62 | - Must work reliably across different operating systems and workspace configurations 63 | - Focus on fixing critical blockers before addressing minor usability issues 64 | 65 | # Design Decisions for Future Consideration: 66 | 67 | ## .env File Parsing Strategy 68 | ## Configuration Simplification Approach 69 | ## MCP Tool Debugging Strategy 70 | ## Workspace Isolation Testing 71 | ## Installation Validation Framework 72 | ## Error Reporting and resolution 73 | 74 | # Subtasks: 75 | [To be created in Phase 2 based on actual problems discovered during manual testing] -------------------------------------------------------------------------------- /tasks/task_077.txt: -------------------------------------------------------------------------------- 1 | # Task ID: 77 2 | # Title: Fix Git Hook Execution Sequence to Eliminate Race Conditions 3 | # Status: pending 4 | # Dependencies: None 5 | # Priority: high 6 | # Description: Reorder git hook operations to generate journal entries before checking summary triggers, eliminating file system race conditions and AI resource conflicts that cause inconsistent summary generation and poor-quality journal sections. 7 | 8 | # Requirements: 9 | - Move journal entry generation to execute before summary trigger checks in git_hook_worker.py 10 | - Eliminate file system race conditions where summary logic reads incomplete journal files 11 | - Prevent AI resource conflicts between concurrent journal generation and summary generation 12 | - Maintain all existing error handling and graceful degradation patterns 13 | - Preserve comprehensive telemetry for all operations in new sequence 14 | - Update background_journal_worker.py for sequence consistency across execution paths 15 | - Ensure period summary triggers (weekly/monthly/quarterly) work correctly in new sequence 16 | - Add sequence-specific integration tests to prevent regression 17 | - Update documentation to reflect new execution model 18 | 19 | # Notes: 20 | ## Current Problem Analysis: 21 | - Git hook currently runs: (1) check summary triggers → (2) generate summaries → (3) generate journal entry 22 | - This causes race conditions where summary logic uses `os.path.getmtime` on files being written 23 | - AI resource conflicts occur when summary generation and journal generation run simultaneously 24 | - Results in poor-quality journal sections (thin Technical Synopsis, incomplete Accomplishments) 25 | - Exception handling masks timing failures with generic "No daily summary generation needed" messages 26 | 27 | ## Implementation Context: 28 | - Git hook affects every commit - any bugs block development workflow 29 | - Complex error handling across 6 different phases, each with telemetry and graceful degradation 30 | - Two code paths need consistency: git_hook_worker.py and background_journal_worker.py 31 | - Current tests don't verify execution order or timing-sensitive behavior 32 | 33 | ## Design Decisions for Future Consideration: 34 | - Error handling strategy: If journal generation fails, should summaries still run? 35 | - Failure isolation: Should summary generation failures block git operations? 36 | - Testing approach: How to test file system timing and AI resource conflicts? 37 | - Sequence validation: How to ensure both execution paths maintain consistent ordering? 38 | - Rollback strategy: How to safely deploy changes to critical git hook infrastructure? 39 | - Performance impact: Does sequential execution significantly increase git hook duration? 40 | 41 | # Subtasks: 42 | (To be created in Phase 2 after design discussion) -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import os 3 | import shutil 4 | import tempfile 5 | import git 6 | from unittest.mock import Mock, patch 7 | 8 | @pytest.fixture 9 | def git_repo(): 10 | # Create a temporary directory 11 | temp_dir = tempfile.mkdtemp() 12 | try: 13 | # Initialize a new git repo (no commits by default) 14 | repo = git.Repo.init(temp_dir) 15 | # Yield the repo object for use in tests 16 | yield repo 17 | finally: 18 | # Cleanup: remove the temp directory 19 | shutil.rmtree(temp_dir) 20 | 21 | @pytest.fixture 22 | def mock_query_cursor_chat_database(): 23 | """Mock fixture for query_cursor_chat_database function.""" 24 | with patch('mcp_commit_story.context_collection.query_cursor_chat_database') as mock: 25 | yield mock 26 | 27 | @pytest.fixture 28 | def mock_filter_chat_for_commit(): 29 | """Mock fixture for filter_chat_for_commit function.""" 30 | with patch('mcp_commit_story.context_collection.filter_chat_for_commit') as mock: 31 | yield mock 32 | 33 | @pytest.fixture 34 | def mock_collect_git_context(): 35 | """Mock fixture for collect_git_context function.""" 36 | with patch('mcp_commit_story.context_collection.collect_git_context') as mock: 37 | yield mock -------------------------------------------------------------------------------- /tests/fixtures/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiggitywhitney/mcp-commit-story/bb08c9c433da0f5bfba23b4ae113d5dfc3d855b0/tests/fixtures/.keep -------------------------------------------------------------------------------- /tests/fixtures/cursor_databases/test_global.vscdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiggitywhitney/mcp-commit-story/bb08c9c433da0f5bfba23b4ae113d5dfc3d855b0/tests/fixtures/cursor_databases/test_global.vscdb -------------------------------------------------------------------------------- /tests/fixtures/cursor_databases/test_workspace.vscdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiggitywhitney/mcp-commit-story/bb08c9c433da0f5bfba23b4ae113d5dfc3d855b0/tests/fixtures/cursor_databases/test_workspace.vscdb -------------------------------------------------------------------------------- /tests/fixtures/summary_test_data.py: -------------------------------------------------------------------------------- 1 | from mcp_commit_story.context_types import JournalContext, GitContext, ChatHistory 2 | 3 | def mock_context_with_explicit_purpose(): 4 | return JournalContext( 5 | git=GitContext( 6 | metadata={"hash": "abc123", "author": "Dev", "date": "2025-05-24", "message": "refactor: improve auth because it's messy"}, 7 | diff_summary="Refactored authentication logic in auth.py.", 8 | changed_files=["auth.py"], 9 | file_stats={}, 10 | commit_context={} 11 | ), 12 | chat=ChatHistory(messages=[ 13 | {"speaker": "Human", "text": "Refactoring auth because it's messy"} 14 | ]), 15 | terminal=None 16 | ) 17 | 18 | def mock_context_evolution_thinking(): 19 | return JournalContext( 20 | git=GitContext( 21 | metadata={"hash": "def456", "author": "Dev", "date": "2025-05-24", "message": "fix: resolve auth timeout"}, 22 | diff_summary="Fixed timeout in authentication, improved connection pooling.", 23 | changed_files=["auth.py", "db.py"], 24 | file_stats={}, 25 | commit_context={} 26 | ), 27 | chat=ChatHistory(messages=[ 28 | {"speaker": "Human", "text": "Started fixing auth timeout"}, 29 | {"speaker": "Human", "text": "Actually the real problem is connection pooling"} 30 | ]), 31 | terminal=None 32 | ) 33 | 34 | def mock_context_unkind_language(): 35 | return JournalContext( 36 | git=GitContext( 37 | metadata={"hash": "ghi789", "author": "Dev", "date": "2025-05-24", "message": "fix: build"}, 38 | diff_summary="Fixed build error in ci.yml.", 39 | changed_files=["ci.yml"], 40 | file_stats={}, 41 | commit_context={} 42 | ), 43 | chat=ChatHistory(messages=[ 44 | {"speaker": "Human", "text": "I'm such an idiot, I broke the build again. Fixing it now."} 45 | ]), 46 | terminal=None 47 | ) 48 | 49 | def mock_context_no_chat(): 50 | return JournalContext( 51 | git=GitContext( 52 | metadata={"hash": "jkl012", "author": "Dev", "date": "2025-05-24", "message": "update: renamed variables"}, 53 | diff_summary="Renamed variables in utils.py.", 54 | changed_files=["utils.py"], 55 | file_stats={}, 56 | commit_context={} 57 | ), 58 | chat=None, 59 | terminal=None 60 | ) -------------------------------------------------------------------------------- /tests/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiggitywhitney/mcp-commit-story/bb08c9c433da0f5bfba23b4ae113d5dfc3d855b0/tests/integration/.keep -------------------------------------------------------------------------------- /tests/integration/test_mcp_cli_integration.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | def call_mcp_server(*args, **kwargs): 4 | if kwargs.get('invalid'): 5 | return {'success': False, 'error': 'Invalid input'} 6 | return {'success': True, 'output': 'journal entry created'} 7 | 8 | def call_cli_tool(*args, **kwargs): 9 | if kwargs.get('invalid'): 10 | return {'success': False, 'error': 'Invalid input'} 11 | return {'success': True, 'output': 'journal entry created'} 12 | 13 | def test_mcp_server_minimal_journal_entry(): 14 | response = call_mcp_server() 15 | assert response['success'] is True 16 | assert 'journal entry' in response['output'] 17 | 18 | def test_cli_tool_minimal_journal_entry(): 19 | response = call_cli_tool() 20 | assert response['success'] is True 21 | assert 'journal entry' in response['output'] 22 | 23 | def test_mcp_server_handles_error(): 24 | response = call_mcp_server(invalid=True) 25 | assert response['success'] is False 26 | assert 'error' in response 27 | 28 | def test_cli_tool_handles_error(): 29 | response = call_cli_tool(invalid=True) 30 | assert response['success'] is False 31 | assert 'error' in response -------------------------------------------------------------------------------- /tests/unit/test_agent_model_documentation.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | sample_results = [ 4 | {'name': 'Parse Daily Note', 'status': 'success', 'output': {'timestamp': '2:17 PM'}}, 5 | {'name': 'Parse Reflection', 'status': 'exception', 'exception': 'NotImplementedError'}, 6 | {'name': 'Generate Summary', 'status': 'success', 'output': 'Today was a productive day.'}, 7 | ] 8 | sample_metrics = { 9 | 'relevance': True, 10 | 'accuracy': False, 11 | 'completeness': True, 12 | 'consistency': True, 13 | } 14 | 15 | empty_results = [] 16 | empty_metrics = {} 17 | 18 | def generate_documentation(results, metrics): 19 | if not results: 20 | return 'No test results to document' 21 | doc = ['# Test Results Summary'] 22 | # Successes 23 | successes = [r for r in results if r['status'] == 'success'] 24 | doc.append('## Successes') 25 | if successes: 26 | for s in successes: 27 | doc.append(f"- {s['name']}") 28 | else: 29 | doc.append('None') 30 | # Failures 31 | failures = [r for r in results if r['status'] != 'success'] 32 | doc.append('## Failures') 33 | if failures: 34 | for f in failures: 35 | doc.append(f"- {f['name']}: {f.get('exception', f.get('status'))}") 36 | else: 37 | doc.append('None') 38 | # Recommendations 39 | doc.append('## Recommendations') 40 | recs = [] 41 | if not metrics.get('accuracy', True): 42 | recs.append('- Improve accuracy') 43 | if not metrics.get('relevance', True): 44 | recs.append('- Improve relevance') 45 | if not metrics.get('completeness', True): 46 | recs.append('- Improve completeness') 47 | if not metrics.get('consistency', True): 48 | recs.append('- Improve consistency') 49 | if recs: 50 | doc.extend(recs) 51 | else: 52 | doc.append('No major recommendations') 53 | return '\n'.join(doc) 54 | 55 | def test_documentation_generates_markdown_summary(): 56 | doc = generate_documentation(sample_results, sample_metrics) 57 | assert doc.startswith('# Test Results Summary') 58 | assert 'Parse Daily Note' in doc 59 | assert 'Parse Reflection' in doc 60 | assert 'Generate Summary' in doc 61 | 62 | def test_documentation_includes_sections(): 63 | doc = generate_documentation(sample_results, sample_metrics) 64 | assert '## Successes' in doc 65 | assert '## Failures' in doc 66 | assert '## Recommendations' in doc 67 | 68 | def test_documentation_recommendations_are_actionable(): 69 | doc = generate_documentation(sample_results, sample_metrics) 70 | assert '- Improve accuracy' in doc or 'accuracy' in doc 71 | 72 | def test_documentation_handles_empty_results(): 73 | doc = generate_documentation(empty_results, empty_metrics) 74 | assert 'No test results to document' in doc or doc.strip() == '' -------------------------------------------------------------------------------- /tests/unit/test_agent_model_framework.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import sys 3 | import os 4 | from test_agent_model_validation import ( 5 | agent_model_parse, 6 | agent_model_generate_summary, 7 | DAILY_NOTE_MD, 8 | REFLECTION_MD, 9 | SUMMARY_MD, 10 | EMPTY_MD, 11 | MALFORMED_MD, 12 | ) 13 | 14 | def run_agent_model_tests(): 15 | results = [] 16 | # Test: Parse Daily Note 17 | try: 18 | entry = agent_model_parse(DAILY_NOTE_MD) 19 | results.append({'name': 'Parse Daily Note', 'status': 'success', 'output': entry}) 20 | except Exception as e: 21 | results.append({'name': 'Parse Daily Note', 'status': 'exception', 'exception': str(e)}) 22 | # Test: Parse Reflection 23 | try: 24 | entry = agent_model_parse(REFLECTION_MD) 25 | results.append({'name': 'Parse Reflection', 'status': 'success', 'output': entry}) 26 | except Exception as e: 27 | results.append({'name': 'Parse Reflection', 'status': 'exception', 'exception': str(e)}) 28 | # Test: Generate Summary 29 | try: 30 | summary = agent_model_generate_summary(SUMMARY_MD) 31 | results.append({'name': 'Generate Summary', 'status': 'success', 'output': summary}) 32 | except Exception as e: 33 | results.append({'name': 'Generate Summary', 'status': 'exception', 'exception': str(e)}) 34 | # Test: Handle Empty Entry 35 | try: 36 | agent_model_parse(EMPTY_MD) 37 | results.append({'name': 'Handle Empty Entry', 'status': 'failure', 'output': 'No exception raised'}) 38 | except Exception as e: 39 | results.append({'name': 'Handle Empty Entry', 'status': 'exception', 'exception': str(e)}) 40 | # Test: Handle Malformed Entry 41 | try: 42 | agent_model_parse(MALFORMED_MD) 43 | results.append({'name': 'Handle Malformed Entry', 'status': 'failure', 'output': 'No exception raised'}) 44 | except Exception as e: 45 | results.append({'name': 'Handle Malformed Entry', 'status': 'exception', 'exception': str(e)}) 46 | return results 47 | 48 | # Minimal TDD tests for the agent/model test execution framework 49 | 50 | def test_framework_runs_and_captures_results(): 51 | results = run_agent_model_tests() 52 | assert isinstance(results, list) 53 | assert any(r['status'] == 'success' for r in results) or any(r['status'] == 'failure' for r in results) 54 | 55 | 56 | def test_framework_logs_results(capsys): 57 | results = run_agent_model_tests() 58 | for r in results: 59 | print(f"{r['name']}: {r['status']}") 60 | captured = capsys.readouterr() 61 | assert any('success' in captured.out or 'failure' in captured.out for _ in results) 62 | 63 | 64 | def test_framework_handles_exceptions(): 65 | results = run_agent_model_tests() 66 | assert any(r['status'] == 'exception' for r in results) -------------------------------------------------------------------------------- /tests/unit/test_agent_model_metrics.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | def evaluate_metrics(outputs, expected): 4 | # Handle list of outputs for consistency 5 | if isinstance(outputs, list): 6 | consistency = all(o == outputs[0] for o in outputs) 7 | # Evaluate metrics for the first output 8 | output = outputs[0] if outputs else {} 9 | else: 10 | output = outputs 11 | consistency = True 12 | # Handle malformed input 13 | if not isinstance(output, dict): 14 | return { 15 | 'relevance': False, 16 | 'accuracy': False, 17 | 'completeness': False, 18 | 'consistency': False, 19 | } 20 | # Relevance: all expected summary_keywords in summary 21 | summary = output.get('summary', '') 22 | summary_keywords = expected.get('summary_keywords', []) 23 | relevance = all(kw in summary for kw in summary_keywords) 24 | # Accuracy: timestamp and commit_hash match 25 | accuracy = ( 26 | output.get('timestamp') == expected.get('timestamp') and 27 | output.get('commit_hash') == expected.get('commit_hash') 28 | ) 29 | # Completeness: all required fields are non-empty 30 | required_fields = ['accomplishments', 'frustrations', 'summary', 'reflections'] 31 | completeness = all( 32 | (isinstance(output.get(f), list) and output.get(f)) or 33 | (isinstance(output.get(f), str) and output.get(f).strip()) 34 | for f in required_fields 35 | ) 36 | return { 37 | 'relevance': relevance, 38 | 'accuracy': accuracy, 39 | 'completeness': completeness, 40 | 'consistency': consistency, 41 | } 42 | 43 | # Sample outputs and expected values for metrics tests 44 | sample_output = { 45 | 'timestamp': '2:17 PM', 46 | 'commit_hash': 'def456', 47 | 'accomplishments': ['Implemented feature X', 'Fixed bug Y'], 48 | 'frustrations': ['Spent hours debugging config'], 49 | 'summary': 'A friendly, succinct summary that captures what was accomplished.', 50 | 'reflections': ['This was a tough one!'], 51 | } 52 | expected = { 53 | 'timestamp': '2:17 PM', 54 | 'commit_hash': 'def456', 55 | 'accomplishments': ['Implemented feature X', 'Fixed bug Y'], 56 | 'frustrations': ['Spent hours debugging config'], 57 | 'summary_keywords': ['summary', 'accomplished'], 58 | 'reflections': ['tough'], 59 | } 60 | 61 | sample_output_incomplete = { 62 | 'timestamp': '2:17 PM', 63 | 'commit_hash': 'def456', 64 | 'accomplishments': [], 65 | 'frustrations': [], 66 | 'summary': '', 67 | 'reflections': [], 68 | } 69 | 70 | sample_output_malformed = 'not a dict' 71 | 72 | sample_outputs_multiple = [sample_output, sample_output] 73 | 74 | 75 | def test_metrics_relevance(): 76 | metrics = evaluate_metrics(sample_output, expected) 77 | assert metrics['relevance'] is True 78 | 79 | def test_metrics_accuracy(): 80 | metrics = evaluate_metrics(sample_output, expected) 81 | assert metrics['accuracy'] is True 82 | 83 | def test_metrics_completeness(): 84 | metrics = evaluate_metrics(sample_output, expected) 85 | assert metrics['completeness'] is True 86 | 87 | def test_metrics_consistency(): 88 | metrics = evaluate_metrics(sample_outputs_multiple, expected) 89 | assert metrics['consistency'] is True 90 | 91 | def test_metrics_handles_edge_cases(): 92 | metrics = evaluate_metrics(sample_output_incomplete, expected) 93 | assert metrics['completeness'] is False 94 | metrics = evaluate_metrics(sample_output_malformed, expected) 95 | assert metrics['relevance'] is False -------------------------------------------------------------------------------- /tests/unit/test_cli_install_hook.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import json 3 | from click.testing import CliRunner 4 | from unittest.mock import patch, MagicMock 5 | from mcp_commit_story.cli import cli 6 | 7 | # Note: CliRunner doesn't properly propagate return-based exit codes 8 | # We test JSON output instead, which contains error codes 9 | 10 | @patch('mcp_commit_story.cli.install_post_commit_hook') 11 | def test_cli_install_hook_success(mock_install): 12 | runner = CliRunner() 13 | mock_install.return_value = None 14 | result = runner.invoke(cli, ['install-hook']) 15 | data = json.loads(result.output) 16 | assert data["status"] == "success" 17 | assert "hook" in data["result"]["message"].lower() 18 | assert result.output.strip().startswith('{') and result.output.strip().endswith('}') 19 | 20 | @patch('mcp_commit_story.cli.install_post_commit_hook', side_effect=FileNotFoundError('Not a git repo')) 21 | def test_cli_install_hook_not_git_repo(mock_install): 22 | runner = CliRunner() 23 | result = runner.invoke(cli, ['install-hook']) 24 | data = json.loads(result.output) 25 | assert data["status"] == "error" 26 | assert data["code"] == 4 # filesystem error 27 | assert 'not a git repo' in data["message"].lower() 28 | assert result.output.strip().startswith('{') and result.output.strip().endswith('}') 29 | 30 | @patch('mcp_commit_story.cli.install_post_commit_hook', side_effect=PermissionError('Hooks dir not writable')) 31 | def test_cli_install_hook_hooks_dir_not_writable(mock_install): 32 | runner = CliRunner() 33 | result = runner.invoke(cli, ['install-hook']) 34 | data = json.loads(result.output) 35 | assert data["status"] == "error" 36 | assert data["code"] == 1 # general error 37 | assert 'writable' in data["message"].lower() 38 | assert result.output.strip().startswith('{') and result.output.strip().endswith('}') 39 | 40 | @patch('mcp_commit_story.cli.install_post_commit_hook', side_effect=FileExistsError('Hook already installed')) 41 | def test_cli_install_hook_already_installed(mock_install): 42 | runner = CliRunner() 43 | result = runner.invoke(cli, ['install-hook']) 44 | data = json.loads(result.output) 45 | assert data["status"] == "error" 46 | assert data["code"] == 2 # already_initialized 47 | assert 'already' in data["message"].lower() 48 | assert result.output.strip().startswith('{') and result.output.strip().endswith('}') 49 | 50 | # Output format test (should always be JSON) 51 | def test_cli_install_hook_output_format(monkeypatch): 52 | runner = CliRunner() 53 | monkeypatch.setattr('mcp_commit_story.cli.install_post_commit_hook', lambda *a, **kw: None) 54 | result = runner.invoke(cli, ['install-hook']) 55 | assert result.output.strip().startswith('{') and result.output.strip().endswith('}') 56 | 57 | @patch('mcp_commit_story.cli.install_post_commit_hook') 58 | def test_cli_install_hook_with_backup(mock_install): 59 | runner = CliRunner() 60 | mock_install.return_value = True # Simulate successful installation 61 | result = runner.invoke(cli, ['install-hook']) 62 | data = json.loads(result.output) 63 | assert data["status"] == "success" 64 | assert "synchronous mode" in data["result"]["message"] 65 | assert data["result"]["background_mode"] == False -------------------------------------------------------------------------------- /tests/unit/test_error_handling.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from mcp_commit_story import context_collection 3 | from mcp_commit_story import journal_generate as journal 4 | from mcp_commit_story.context_types import ChatHistory, GitContext, JournalContext 5 | from unittest.mock import patch 6 | 7 | # --- Context Collection Edge Cases --- 8 | def test_collect_chat_history_none(): 9 | # Should handle None gracefully (return empty ChatHistory or raise ValueError) 10 | with pytest.raises(Exception): 11 | context_collection.collect_chat_history(since_commit=None, max_messages_back=None) 12 | 13 | # Terminal command collection removed per architectural decision 14 | # See Task 56: Remove Terminal Command Collection Infrastructure 15 | 16 | def test_collect_git_context_invalid_commit(): 17 | # Should raise on invalid commit hash 18 | with pytest.raises(Exception): 19 | context_collection.collect_git_context(commit_hash="notarealhash") 20 | 21 | # --- Journal Section Generators Edge Cases --- 22 | def test_generate_summary_section_empty(): 23 | # Should not raise, should return valid SummarySection even with empty context 24 | ctx = JournalContext() 25 | result = journal.generate_summary_section(ctx) 26 | assert isinstance(result, dict) 27 | assert 'summary' in result 28 | 29 | def test_generate_technical_synopsis_section_none(): 30 | # Should not raise, should return valid TechnicalSynopsisSection 31 | result = journal.generate_technical_synopsis_section(None) 32 | assert isinstance(result, dict) 33 | assert 'technical_synopsis' in result 34 | 35 | # --- File Operations Edge Cases --- 36 | def test_append_to_journal_file_permission_error(tmp_path): 37 | """append_to_journal_file should raise ValueError if file cannot be written due to permissions.""" 38 | file_path = tmp_path / "file.md" 39 | with patch("mcp_commit_story.journal_generate.open", side_effect=PermissionError("Permission denied")): 40 | with pytest.raises(ValueError) as excinfo: 41 | journal.append_to_journal_file("entry", file_path) 42 | 43 | # --- JournalEntry/Parser Edge Cases --- 44 | def test_journal_entry_to_markdown_missing_fields(): 45 | # Should not raise, should handle missing optional fields 46 | entry = journal.JournalEntry(timestamp="now", commit_hash="abc123") 47 | md = entry.to_markdown() 48 | assert isinstance(md, str) 49 | assert "### now" in md 50 | 51 | def test_journal_parser_malformed_markdown(): 52 | # Should raise JournalParseError on malformed markdown 53 | with pytest.raises(journal.JournalParseError): 54 | journal.JournalParser.parse("not a real journal entry") 55 | 56 | # --- TODO: Add more tests for each function in context_collection.py and journal.py --- 57 | # - Test partial/invalid TypedDicts 58 | # - Test boundary conditions (empty lists, large data) 59 | # - Test file permission errors 60 | # - Test error logging/fallbacks -------------------------------------------------------------------------------- /tests/unit/test_file_operations.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | from unittest import mock 4 | from pathlib import Path 5 | from mcp_commit_story import journal_generate as journal 6 | 7 | # Assume these will be imported from the journal module 8 | # from mcp_commit_story.journal import get_journal_file_path, append_to_journal_file, create_journal_directories 9 | 10 | @pytest.mark.parametrize("date, entry_type, expected_path", [ 11 | ("2025-05-14", "daily", "journal/daily/2025-05-14-journal.md"), 12 | ("2025-05-14", "daily_summary", "journal/summaries/daily/2025-05-14-summary.md"), 13 | ("2025-05-01_07", "weekly_summary", "journal/summaries/weekly/2025-05-01_07-weekly.md"), 14 | ("2025-05", "monthly_summary", "journal/summaries/monthly/2025-05-monthly.md"), 15 | ("2025", "yearly_summary", "journal/summaries/yearly/2025-yearly.md"), 16 | ]) 17 | def test_get_journal_file_path(date, entry_type, expected_path): 18 | path = journal.get_journal_file_path(date=date, entry_type=entry_type) 19 | assert str(path) == expected_path 20 | 21 | def test_append_to_journal_file_creates_and_appends(tmp_path): 22 | file_path = tmp_path / "journal" / "daily" / "2025-05-14-journal.md" 23 | entry1 = "### 2025-05-14 09:00 — Commit abc123\n\nFirst entry." 24 | entry2 = "### 2025-05-14 10:00 — Commit def456\n\nSecond entry." 25 | # File does not exist yet 26 | journal.append_to_journal_file(entry1, file_path) 27 | with open(file_path) as f: 28 | content = f.read() 29 | assert entry1 in content 30 | # Append second entry 31 | journal.append_to_journal_file(entry2, file_path) 32 | with open(file_path) as f: 33 | content = f.read() 34 | assert entry1 in content and entry2 in content 35 | # Should separate entries with a horizontal rule 36 | assert "\n---\n" in content 37 | 38 | def test_append_to_journal_file_handles_filesystem_errors(tmp_path): 39 | file_path = tmp_path / "journal" / "daily" / "2025-05-14-journal.md" 40 | entry = "### 2025-05-14 09:00 — Commit abc123\n\nFirst entry." 41 | # Simulate permission error 42 | with mock.patch("builtins.open", side_effect=PermissionError): 43 | with pytest.raises(ValueError): 44 | journal.append_to_journal_file(entry, file_path) -------------------------------------------------------------------------------- /tests/unit/test_imports.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import pytest 3 | 4 | MODULES = [ 5 | 'mcp_commit_story.cli', 6 | 'mcp_commit_story.server', 7 | 'mcp_commit_story.journal', 8 | 'mcp_commit_story.git_utils', 9 | 'mcp_commit_story.config', 10 | ] 11 | 12 | @pytest.mark.parametrize('module_name', MODULES) 13 | def test_module_import(module_name): 14 | try: 15 | importlib.import_module(module_name) 16 | except Exception as e: 17 | pytest.fail(f"Failed to import {module_name}: {e}") 18 | -------------------------------------------------------------------------------- /tests/unit/test_journal_utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import tempfile 4 | import pytest 5 | from pathlib import Path 6 | 7 | from mcp_commit_story.journal_generate import ensure_journal_directory 8 | 9 | def setup_temp_dir(): 10 | temp_dir = tempfile.mkdtemp() 11 | yield temp_dir 12 | shutil.rmtree(temp_dir) 13 | 14 | @pytest.fixture 15 | def temp_path(): 16 | with tempfile.TemporaryDirectory() as tmpdirname: 17 | yield Path(tmpdirname) 18 | 19 | def test_creates_missing_directories(temp_path): 20 | file_path = temp_path / "nested/dir/journal.md" 21 | assert not file_path.parent.exists() 22 | ensure_journal_directory(file_path) 23 | assert file_path.parent.exists() 24 | assert file_path.parent.is_dir() 25 | 26 | def test_handles_existing_directories(temp_path): 27 | dir_path = temp_path / "existing/dir" 28 | dir_path.mkdir(parents=True) 29 | file_path = dir_path / "journal.md" 30 | ensure_journal_directory(file_path) 31 | assert dir_path.exists() 32 | assert dir_path.is_dir() 33 | 34 | import builtins 35 | from unittest import mock 36 | 37 | def test_permission_error(monkeypatch, temp_path): 38 | file_path = temp_path / "no_permission/journal.md" 39 | # Simulate permission error on mkdir 40 | with mock.patch.object(Path, "mkdir", side_effect=PermissionError("No permission")): 41 | with pytest.raises(PermissionError): 42 | ensure_journal_directory(file_path) 43 | 44 | def test_creates_nested_paths(temp_path): 45 | file_path = temp_path / "deep/nested/structure/journal.md" 46 | assert not file_path.parent.exists() 47 | ensure_journal_directory(file_path) 48 | assert file_path.parent.exists() 49 | assert file_path.parent.is_dir() -------------------------------------------------------------------------------- /tests/unit/test_openai_provider_config.py: -------------------------------------------------------------------------------- 1 | """ 2 | Unit tests for OpenAIProvider configuration handling. 3 | 4 | Tests the OpenAIProvider's ability to handle API keys through the Config class 5 | rather than environment variables. 6 | """ 7 | 8 | import pytest 9 | from unittest.mock import Mock, patch 10 | from mcp_commit_story.ai_provider import OpenAIProvider 11 | from mcp_commit_story.config import Config, ConfigError 12 | 13 | def test_openai_provider_init_with_config(): 14 | """Test OpenAIProvider initialization with valid config.""" 15 | mock_config = Mock(spec=Config) 16 | mock_config.ai_openai_api_key = "test-api-key" 17 | 18 | provider = OpenAIProvider(config=mock_config) 19 | assert provider.client.api_key == "test-api-key" 20 | 21 | def test_openai_provider_init_without_config(): 22 | """Test OpenAIProvider initialization fails without config.""" 23 | with pytest.raises(ValueError) as exc: 24 | OpenAIProvider() 25 | assert "config parameter is required" in str(exc.value) 26 | 27 | def test_openai_provider_init_with_empty_api_key(): 28 | """Test OpenAIProvider initialization fails with empty API key in config.""" 29 | mock_config = Mock(spec=Config) 30 | mock_config.ai_openai_api_key = "" 31 | 32 | with pytest.raises(ValueError) as exc: 33 | OpenAIProvider(config=mock_config) 34 | assert "OpenAI API key not configured" in str(exc.value) 35 | 36 | def test_openai_provider_init_with_none_api_key(): 37 | """Test OpenAIProvider initialization fails with None API key in config.""" 38 | mock_config = Mock(spec=Config) 39 | mock_config.ai_openai_api_key = None 40 | 41 | with pytest.raises(ValueError) as exc: 42 | OpenAIProvider(config=mock_config) 43 | assert "OpenAI API key not configured" in str(exc.value) 44 | 45 | def test_openai_provider_call_with_valid_config(): 46 | """Test OpenAIProvider.call() works with valid config.""" 47 | mock_config = Mock(spec=Config) 48 | mock_config.ai_openai_api_key = "test-api-key" 49 | 50 | # Create a properly structured mock response 51 | mock_response = Mock() 52 | mock_response.choices = [Mock()] 53 | mock_response.choices[0].message = Mock() 54 | mock_response.choices[0].message.content = "Test response" 55 | 56 | with patch('openai.OpenAI') as mock_openai: 57 | mock_client = Mock() 58 | mock_client.chat.completions.create.return_value = mock_response 59 | mock_openai.return_value = mock_client 60 | 61 | provider = OpenAIProvider(config=mock_config) 62 | response = provider.call("Test prompt", {"test": "context"}) 63 | 64 | assert response == "Test response" 65 | mock_client.chat.completions.create.assert_called_once() 66 | 67 | def test_openai_provider_call_handles_error(): 68 | """Test OpenAIProvider.call() handles API errors gracefully.""" 69 | mock_config = Mock(spec=Config) 70 | mock_config.ai_openai_api_key = "test-api-key" 71 | 72 | with patch('openai.OpenAI') as mock_openai: 73 | mock_client = Mock() 74 | mock_client.chat.completions.create.side_effect = Exception("API error") 75 | mock_openai.return_value = mock_client 76 | 77 | provider = OpenAIProvider(config=mock_config) 78 | response = provider.call("Test prompt", {"test": "context"}) 79 | 80 | assert response == "" # Graceful degradation returns empty string -------------------------------------------------------------------------------- /tests/unit/test_pyproject.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | import toml 4 | 5 | REQUIRED_METADATA = { 6 | 'name': 'mcp-commit-story', 7 | 'requires-python': '>=3.10', 8 | } 9 | 10 | REQUIRED_RUNTIME_DEPS = [ 11 | 'mcp', 12 | 'click', 13 | 'pyyaml', 14 | 'gitpython', 15 | 'python-dateutil', 16 | 'opentelemetry-api', 17 | 'opentelemetry-sdk', 18 | 'opentelemetry-exporter-otlp', 19 | ] 20 | 21 | REQUIRED_DEV_DEPS = [ 22 | 'pytest', 23 | 'pytest-mock', 24 | 'pytest-cov', 25 | 'pytest-watch', 26 | 'black', 27 | 'flake8', 28 | 'mypy', 29 | ] 30 | 31 | def test_pyproject_toml_exists(): 32 | assert os.path.isfile('pyproject.toml'), "Missing pyproject.toml file" 33 | 34 | def test_pyproject_metadata_and_dependencies(): 35 | data = toml.load('pyproject.toml') 36 | # Check build system 37 | assert 'build-system' in data, "Missing [build-system] section" 38 | # Check project metadata 39 | project = data.get('project', {}) 40 | for key, val in REQUIRED_METADATA.items(): 41 | assert key in project, f"Missing project metadata: {key}" 42 | if key == 'requires-python': 43 | assert val in project[key], f"Incorrect Python version: {project[key]}" 44 | # Check runtime dependencies 45 | runtime_deps = project.get('dependencies', []) 46 | for dep in REQUIRED_RUNTIME_DEPS: 47 | assert any(dep in d for d in runtime_deps), f"Missing runtime dependency: {dep}" 48 | # Check dev dependencies (optional-dependencies.dev) 49 | opt_deps = project.get('optional-dependencies', {}).get('dev', []) 50 | for dep in REQUIRED_DEV_DEPS: 51 | assert any(dep in d for d in opt_deps), f"Missing dev dependency: {dep}" 52 | -------------------------------------------------------------------------------- /tests/unit/test_reflection_format.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test suite for reflection format functionality. 3 | 4 | Tests the format_reflection function to ensure it includes proper separator 5 | and uses unified header format consistent with other journal entries. 6 | """ 7 | 8 | import pytest 9 | from unittest.mock import patch 10 | from datetime import datetime 11 | 12 | from mcp_commit_story.reflection_core import format_reflection 13 | 14 | 15 | class TestReflectionFormat: 16 | """Test the format_reflection function to ensure it includes the separator and unified header format.""" 17 | 18 | def test_format_reflection_includes_separator(self): 19 | """Test that format_reflection uses the correct header format.""" 20 | test_reflection = "This is a test reflection" 21 | 22 | result = format_reflection(test_reflection) 23 | 24 | # Should start with header format (no separator) 25 | assert result.startswith("\n\n###") 26 | 27 | # Should have the reflection content 28 | assert test_reflection in result 29 | 30 | def test_format_reflection_unified_header_format(self): 31 | """Test that format_reflection uses the unified header format.""" 32 | test_reflection = "This is a test reflection" 33 | 34 | with patch('mcp_commit_story.reflection_core.datetime') as mock_datetime: 35 | mock_datetime.now.return_value = datetime(2025, 7, 9, 14, 30, 0) 36 | mock_datetime.strftime = datetime.strftime 37 | 38 | result = format_reflection(test_reflection) 39 | 40 | # Should include unified header format (no separator) 41 | expected_header = "\n\n### 2:30 PM — Reflection\n\n" 42 | assert expected_header in result 43 | assert test_reflection in result 44 | 45 | def test_format_reflection_timestamp_formatting(self): 46 | """Test that timestamp formatting matches the unified format.""" 47 | test_reflection = "Test reflection content" 48 | 49 | with patch('mcp_commit_story.reflection_core.datetime') as mock_datetime: 50 | # Test various times to verify format consistency 51 | test_times = [ 52 | (datetime(2025, 7, 9, 9, 5, 0), "9:05 AM"), # Single digit hour/minute 53 | (datetime(2025, 7, 9, 14, 30, 0), "2:30 PM"), # PM time 54 | (datetime(2025, 7, 9, 0, 0, 0), "12:00 AM"), # Midnight 55 | (datetime(2025, 7, 9, 12, 0, 0), "12:00 PM"), # Noon 56 | ] 57 | 58 | for dt, expected_time in test_times: 59 | mock_datetime.now.return_value = dt 60 | mock_datetime.strftime = datetime.strftime 61 | 62 | result = format_reflection(test_reflection) 63 | assert f"### {expected_time} — Reflection" in result 64 | 65 | def test_format_reflection_content_preservation(self): 66 | """Test that reflection content is preserved exactly.""" 67 | test_reflection = "This is a multi-line\nreflection with\nspecial characters: @#$%" 68 | 69 | result = format_reflection(test_reflection) 70 | 71 | # Original content should be preserved 72 | assert test_reflection in result 73 | 74 | # Should have proper structure: header + content (no separator) 75 | assert "### " in result 76 | assert " — Reflection\n\n" in result 77 | 78 | def test_format_reflection_complete_structure(self): 79 | """Test the complete structure of formatted reflection.""" 80 | test_reflection = "Complete structure test" 81 | 82 | with patch('mcp_commit_story.reflection_core.datetime') as mock_datetime: 83 | mock_datetime.now.return_value = datetime(2025, 7, 9, 15, 45, 0) 84 | mock_datetime.strftime = datetime.strftime 85 | 86 | result = format_reflection(test_reflection) 87 | 88 | # Should have the complete expected structure (no separator) 89 | expected_structure = "\n\n### 3:45 PM — Reflection\n\n" + test_reflection 90 | assert result == expected_structure -------------------------------------------------------------------------------- /tests/unit/test_structure.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | 4 | REQUIRED_DIRS = [ 5 | 'src/mcp_commit_story', 6 | 'tests/unit', 7 | 'tests/integration', 8 | 'tests/fixtures', 9 | ] 10 | 11 | REQUIRED_FILES = [ 12 | 'src/mcp_commit_story/__init__.py', 13 | 'src/mcp_commit_story/cli.py', 14 | 'src/mcp_commit_story/server.py', 15 | 'src/mcp_commit_story/journal_generate.py', 16 | 'src/mcp_commit_story/git_utils.py', 17 | 'src/mcp_commit_story/config.py', 18 | 'src/mcp_commit_story/telemetry.py', 19 | 'README.md', 20 | '.mcp-commit-storyrc.yaml', 21 | ] 22 | 23 | def test_required_directories_exist(): 24 | for d in REQUIRED_DIRS: 25 | assert os.path.isdir(d), f"Missing directory: {d}" 26 | 27 | def test_required_files_exist(): 28 | for f in REQUIRED_FILES: 29 | assert os.path.isfile(f), f"Missing file: {f}" 30 | --------------------------------------------------------------------------------