Chapter 8: Contribution Workflow and Team Adoption

April 13, 2026 ยท View on GitHub

Welcome to Chapter 8: Contribution Workflow and Team Adoption. In this part of Planning with Files Tutorial: Persistent Markdown Workflow Memory for AI Coding Agents, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.

This chapter explains how to scale and evolve planning-with-files in teams.

Learning Goals

  • contribute improvements with clear compatibility notes
  • standardize team onboarding and workflow contracts
  • evaluate forks/extensions and adopt safely
  • maintain shared quality expectations across environments

Team Adoption Pattern

  1. publish standard template and command usage policy
  2. define review checks for plan/findings/progress quality
  3. document IDE-specific install and support steps
  4. add recovery and troubleshooting runbook to team docs

Contribution Guidance

  • keep changes scoped and backward-compatible where possible
  • document behavior changes in release/changelog notes
  • include examples for new rules, templates, or scripts

Source References

Summary

You now have an end-to-end model for deploying planning-with-files across teams.

Next steps:

  • define team-level template quality standards
  • run pilot adoption on one active project
  • contribute one improvement with docs and compatibility notes

Source Code Walkthrough

skills/planning-with-files-zh/scripts/session-catchup.py

The find_last_planning_update function in skills/planning-with-files-zh/scripts/session-catchup.py handles a key part of this chapter's functionality:



def find_last_planning_update(messages: List[Dict]) -> Tuple[int, Optional[str]]:
    """
    Find the last time a planning file was written/edited.
    Returns (line_number, filename) or (-1, None) if not found.
    """
    last_update_line = -1
    last_update_file = None

    for msg in messages:
        msg_type = msg.get('type')

        if msg_type == 'assistant':
            content = msg.get('message', {}).get('content', [])
            if isinstance(content, list):
                for item in content:
                    if item.get('type') == 'tool_use':
                        tool_name = item.get('name', '')
                        tool_input = item.get('input', {})

                        if tool_name in ('Write', 'Edit'):
                            file_path = tool_input.get('file_path', '')
                            for pf in PLANNING_FILES:
                                if file_path.endswith(pf):
                                    last_update_line = msg['_line_num']
                                    last_update_file = pf

    return last_update_line, last_update_file


def extract_messages_after(messages: List[Dict], after_line: int) -> List[Dict]:

This function is important because it defines how Planning with Files Tutorial: Persistent Markdown Workflow Memory for AI Coding Agents implements the patterns covered in this chapter.

skills/planning-with-files-zh/scripts/session-catchup.py

The extract_messages_after function in skills/planning-with-files-zh/scripts/session-catchup.py handles a key part of this chapter's functionality:



def extract_messages_after(messages: List[Dict], after_line: int) -> List[Dict]:
    """Extract conversation messages after a certain line number."""
    result = []
    for msg in messages:
        if msg['_line_num'] <= after_line:
            continue

        msg_type = msg.get('type')
        is_meta = msg.get('isMeta', False)

        if msg_type == 'user' and not is_meta:
            content = msg.get('message', {}).get('content', '')
            if isinstance(content, list):
                for item in content:
                    if isinstance(item, dict) and item.get('type') == 'text':
                        content = item.get('text', '')
                        break
                else:
                    content = ''

            if content and isinstance(content, str):
                if content.startswith(('<local-command', '<command-', '<task-notification')):
                    continue
                if len(content) > 20:
                    result.append({'role': 'user', 'content': content, 'line': msg['_line_num']})

        elif msg_type == 'assistant':
            msg_content = msg.get('message', {}).get('content', '')
            text_content = ''
            tool_uses = []

This function is important because it defines how Planning with Files Tutorial: Persistent Markdown Workflow Memory for AI Coding Agents implements the patterns covered in this chapter.

skills/planning-with-files-zh/scripts/session-catchup.py

The main function in skills/planning-with-files-zh/scripts/session-catchup.py handles a key part of this chapter's functionality:

    """Get all session files sorted by modification time (newest first)."""
    sessions = list(project_dir.glob('*.jsonl'))
    main_sessions = [s for s in sessions if not s.name.startswith('agent-')]
    return sorted(main_sessions, key=lambda p: p.stat().st_mtime, reverse=True)


def parse_session_messages(session_file: Path) -> List[Dict]:
    """Parse all messages from a session file, preserving order."""
    messages = []
    with open(session_file, 'r') as f:
        for line_num, line in enumerate(f):
            try:
                data = json.loads(line)
                data['_line_num'] = line_num
                messages.append(data)
            except json.JSONDecodeError:
                pass
    return messages


def find_last_planning_update(messages: List[Dict]) -> Tuple[int, Optional[str]]:
    """
    Find the last time a planning file was written/edited.
    Returns (line_number, filename) or (-1, None) if not found.
    """
    last_update_line = -1
    last_update_file = None

    for msg in messages:
        msg_type = msg.get('type')

        if msg_type == 'assistant':

This function is important because it defines how Planning with Files Tutorial: Persistent Markdown Workflow Memory for AI Coding Agents implements the patterns covered in this chapter.

How These Components Connect

flowchart TD
    A[find_last_planning_update]
    B[extract_messages_after]
    C[main]
    A --> B
    B --> C