Skip to main content
Glama

sync_planning_doc

Update project planning documents by appending progress logs, updating active work status, or marking tasks as complete to maintain current development tracking.

Instructions

Update .context/dev/{branch}/ planning documents. Can append to progress log, update active work, or mark tasks complete.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
modeYesUpdate mode: append_progress_log, update_active_work, or mark_tasks_complete
completed_tasksNoList of completed task descriptions (for append_progress_log or mark_tasks_complete)
in_progressNoCurrent work in progress (for update_active_work)
decisionsNoKey decisions made (for append_progress_log)
blockersNoCurrent blockers or issues (for update_active_work)
next_stepsNoNext immediate steps (for update_active_work)
working_directoryNoWorking directory for git operations. Defaults to current directory.

Implementation Reference

  • The _sync_planning_doc function handles the logic for syncing planning documents, including parsing arguments, locating the plan file, and delegating the update to helper functions based on the mode.
    async def _sync_planning_doc(arguments: dict[str, Any]) -> dict:
        """Update .context planning documents."""
        mode = arguments.get("mode")
        working_dir = arguments.get("working_directory") or _get_working_directory()
    
        if not mode:
            return {"success": False, "error": "mode is required"}
    
        git = GitUtils(working_dir)
        plan_path = git.get_context_plan_path()
    
        if not plan_path:
            # Try to construct path even if file doesn't exist
            branch = git.get_current_branch()
            root = git.get_project_root()
            if branch and root:
                plan_path = root / ".context" / "dev" / branch / f"{branch}-detailed-plan.md"
            else:
                return {
                    "success": False,
                    "error": "Could not determine plan path. Not a git repo or no branch.",
                }
    
        if not plan_path.exists():
            return {
                "success": False,
                "error": f"Plan file not found: {plan_path}",
                "plan_path": str(plan_path),
            }
    
        # Read existing content
        content = plan_path.read_text(encoding="utf-8")
        sections_updated = []
    
        if mode == "append_progress_log":
            content, updated = _append_progress_log(
                content,
                completed_tasks=arguments.get("completed_tasks", []),
                decisions=arguments.get("decisions", []),
                blockers=arguments.get("blockers", []),
            )
            if updated:
                sections_updated.append("Progress Log")
    
        elif mode == "update_active_work":
            content, updated = _update_active_work(
                content,
                in_progress=arguments.get("in_progress"),
                next_steps=arguments.get("next_steps", []),
                blockers=arguments.get("blockers", []),
            )
            if updated:
                sections_updated.append("Active Work")
    
        elif mode == "mark_tasks_complete":
            completed_tasks = arguments.get("completed_tasks", [])
            for task in completed_tasks:
                content = content.replace(f"- [ ] {task}", f"- [x] {task}")
            if completed_tasks:
                sections_updated.append("Implementation Plan")
    
        else:
            return {"success": False, "error": f"Unknown mode: {mode}"}
    
        # Write updated content
        plan_path.write_text(content, encoding="utf-8")
    
        return {
            "success": True,
            "plan_path": str(plan_path),
            "sections_updated": sections_updated,
        }
  • Tool registration for 'sync_planning_doc' in the MCP server's list_tools definition.
        name="sync_planning_doc",
        description="Update .context/dev/{branch}/ planning documents. Can append to progress log, update active work, or mark tasks complete.",
        inputSchema={
            "type": "object",
            "properties": {
                "mode": {
                    "type": "string",
                    "enum": ["append_progress_log", "update_active_work", "mark_tasks_complete"],
                    "description": "Update mode: append_progress_log, update_active_work, or mark_tasks_complete",
                },
                "completed_tasks": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "List of completed task descriptions (for append_progress_log or mark_tasks_complete)",
                },
                "in_progress": {
                    "type": "string",
                    "description": "Current work in progress (for update_active_work)",
                },
                "decisions": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Key decisions made (for append_progress_log)",
                },
                "blockers": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Current blockers or issues (for update_active_work)",
                },
                "next_steps": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Next immediate steps (for update_active_work)",
                },
                "working_directory": {
                    "type": "string",
                    "description": "Working directory for git operations. Defaults to current directory.",
                },
            },
            "required": ["mode"],
        },
    ),
  • Helper function _append_progress_log for updating the progress log section of the plan file.
    def _append_progress_log(
        content: str,
        completed_tasks: list[str],
        decisions: list[str],
        blockers: list[str],
    ) -> tuple[str, bool]:
        """Append entry to Progress Log section."""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M")
    
        entry_lines = [f"\n### {timestamp} - Session Update"]
        if completed_tasks:
            entry_lines.append("- **Completed:**")
            for task in completed_tasks:
                entry_lines.append(f"  - {task}")
        if decisions:
            entry_lines.append("- **Decisions:**")
            for decision in decisions:
                entry_lines.append(f"  - {decision}")
        if blockers:
            entry_lines.append("- **Blockers:**")
            for blocker in blockers:
                entry_lines.append(f"  - {blocker}")
    
        entry = "\n".join(entry_lines) + "\n"
    
        # Find Progress Log section and insert after header
        marker = "## Progress Log"
        if marker in content:
            idx = content.find(marker)
            # Find end of line
            end_of_line = content.find("\n", idx)
            if end_of_line != -1:
                content = content[:end_of_line + 1] + entry + content[end_of_line + 1:]
                return content, True
    
        return content, False
  • Helper function _update_active_work for updating the active work section of the plan file.
    def _update_active_work(
        content: str,
        in_progress: str | None,
        next_steps: list[str],
        blockers: list[str],
    ) -> tuple[str, bool]:
        """Update Active Work section."""
        timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
    
        new_section_lines = [
            "## Active Work (Current Session)",
            f"**Last updated:** {timestamp}",
            "",
            "### In Progress:",
        ]
        if in_progress:
            new_section_lines.append(f"- {in_progress}")
        else:
            new_section_lines.append("- (none)")
    
        new_section_lines.extend(["", "### Next Immediate Steps:"])
        if next_steps:
            for step in next_steps:
                new_section_lines.append(f"- {step}")
        else:
            new_section_lines.append("- (none)")
    
        if blockers:
            new_section_lines.extend(["", "### Blockers/Notes:"])
            for blocker in blockers:
                new_section_lines.append(f"- {blocker}")
    
        new_section = "\n".join(new_section_lines) + "\n"
    
        # Find and replace Active Work section
        start_marker = "## Active Work"
        if start_marker in content:
            start_idx = content.find(start_marker)
            # Find next ## section
            next_section = content.find("\n## ", start_idx + 1)
            if next_section != -1:
                content = content[:start_idx] + new_section + "\n" + content[next_section + 1:]
            else:
                # Active Work is last section
                content = content[:start_idx] + new_section
            return content, True
    
        return content, False

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TimEvans/ccsession'

If you have feedback or need assistance with the MCP directory API, please join our Discord server