Files
internalai-agent/.agents/skills/project-sync/SKILL.md

13 KiB
Raw Blame History

name, description, disable-model-invocation, argument-hint
name description disable-model-invocation argument-hint
project-sync Sync a project timeline using subagents for parallelism. Splits work by week and datasource to stay within context limits. Handles both first-time and incremental syncs. true
project-name

Project Sync

When to use: Keep a project timeline up to date. Works whether the project has been synced before or not.

Precondition: projects/$0/datasources.md must exist. If it doesn't, run /project-init $0 first.

Architecture: Coordinator + Subagents

This skill is designed for subagent execution to stay within context limits. The main agent acts as a coordinator that delegates data-intensive work to subagents.

Coordinator
├── Phase 1: Gather (parallel subagents, one per datasource)
│   ├── Subagent: Zulip  → writes tmp/$0-sync/zulip.md
│   ├── Subagent: Git    → writes tmp/$0-sync/git.md
│   └── Subagent: Meetings → writes tmp/$0-sync/meetings.md
│
├── Phase 2: Synthesize (parallel subagents, one per week)
│   ├── Subagent: Week 1 → writes timeline/{year-month}/week-{n}.md
│   ├── Subagent: Week 2 → writes timeline/{year-month}/week-{n}.md
│   └── ...
│
└── Phase 3: Finalize (coordinator directly)
    ├── timeline/index.md (add links to new weeks)
    ├── project.md (update living document)
    └── sync-state.md (update sync status)

Coordinator Steps

Step 1: Determine Sync Range

Check whether projects/$0/sync-state.md exists.

Case A — First sync (no sync-state.md): Default range is last 12 months through today. If the user provided explicit dates as extra arguments ($1, $2), use those instead.

Case B — Incremental sync (sync-state.md exists): Read last_sync_date from projects/$0/sync-state.md. Range is last_sync_date to today.

Step 2: Read Datasources

Read projects/$0/datasources.md to determine:

  • Zulip stream IDs and search terms
  • Git repository URL
  • Meeting room names
  • Entity types to prioritize

Step 3: Prepare Scratch Directory

mkdir -p tmp/$0-sync

This directory holds intermediate outputs from Phase 1 subagents. It is ephemeral — delete it after the sync completes.

Step 4: Compute Week Boundaries

Split the sync range into ISO calendar weeks (MondaySunday). Produce a list of (week_number, week_start, week_end, year_month) tuples. This list drives Phase 2.


Phase 1: Gather Data (parallel subagents)

Launch one subagent per datasource, all in parallel. Each subagent covers the full sync range and writes its output to a scratch file. The output must be organized by week so Phase 2 subagents can consume it.

Subagent: Zulip

Input: Sync range, PRIMARY stream IDs and search terms from datasources.md.

Important: threaded_conversation entities only contain the last 50 messages in a topic. To get complete message history for a week, you must query conversation_message entities.

Task: Two-step process for each PRIMARY stream:

Step 1: List all thread IDs in the stream using id_prefix:

GET /api/v1/query
  entity_types=threaded_conversation
  connector_ids=zulip
  id_prefix=zulip:stream:{stream_id}
  limit=100
  offset=0

This returns all thread entities (e.g., zulip:stream:155:topic_name). Save these IDs.

Step 2: For each week in the sync range, query messages from each thread:

GET /api/v1/query
  entity_types=conversation_message
  connector_ids=zulip
  parent_id={thread_id}  # e.g., zulip:stream:155:standalone
  date_from={week_start}
  date_to={week_end}
  limit=100
  offset=0

Paginate through all messages for each thread/week combination.

Output: Write tmp/$0-sync/zulip.md with results grouped by week:

## Week {n} ({week_start} to {week_end})

### Stream: {stream_name}
- **Topic:** {topic} ({date}, {message_count} messages, {participant_count} participants)
  {brief summary or key quote}

Subagent: Git

Input: Sync range, git repository URL from datasources.md.

Task:

Important: Git commands may fail due to gitconfig permission issues. Use a temporary HOME directory:

# Set temporary HOME to avoid gitconfig permission issues
export HOME=$(pwd)/.tmp-home
mkdir -p ./tmp

# Clone if needed, pull if exists
if [ -d ./tmp/$0-clone ]; then
  export HOME=$(pwd)/.tmp-home && cd ./tmp/$0-clone && git pull
else
  export HOME=$(pwd)/.tmp-home && git clone --depth 500 {url} ./tmp/$0-clone
  cd ./tmp/$0-clone
fi

# Get commits in the date range
export HOME=$(pwd)/.tmp-home && git log --since="{range_start}" --until="{range_end}" --format="%H|%an|%ae|%ad|%s" --date=short

# Get contributor statistics
export HOME=$(pwd)/.tmp-home && git log --since="{range_start}" --until="{range_end}" --format="%an" | sort | uniq -c | sort -rn

Output: Write tmp/$0-sync/git.md with results grouped by week:

## Week {n} ({week_start} to {week_end})

**Commits:** {count}
**Contributors:** {name} ({count}), {name} ({count})

### Key Commits
- `{short_hash}` {subject} — {author} ({date})

Subagent: Meetings

Input: Sync range, meeting room names from datasources.md.

Task: For each PRIMARY room, query meetings and run semantic search:

GET /api/v1/query
  entity_types=meeting
  date_from={range_start}
  date_to={range_end}
  room_name={room-name}
  limit=100

POST /api/v1/search
  search_text={project-name}
  entity_types=["meeting"]
  date_from={range_start}
  date_to={range_end}
  limit=50

Output: Write tmp/$0-sync/meetings.md with results grouped by week:

## Week {n} ({week_start} to {week_end})

### Meeting: {title} ({date}, {room})
**Participants:** {names}
**Summary:** {brief summary}
**Key points:**
- {point}

Phase 2: Synthesize Week Files (parallel subagents)

After all Phase 1 subagents complete, launch one subagent per week, all in parallel. Each produces a single week file.

Subagent: Week {n}

Input: The relevant ## Week {n} sections extracted from each of:

  • tmp/$0-sync/zulip.md
  • tmp/$0-sync/git.md
  • tmp/$0-sync/meetings.md

Pass only the sections for this specific week — do NOT pass the full files.

Task: Merge and analyze the data from all three sources. Categorize into:

  1. Key Decisions — Technology migrations, architecture changes, vendor switches, security incidents, strategic pivots
  2. Technical Work — Feature implementations, bug fixes, infrastructure changes
  3. Team Activity — Core vs. occasional contributors, role changes
  4. Blockers — Issues, delays, dependencies
  5. Deadline Discussions — Target dates, commitments, timeline changes

Milestones: When documenting milestones, capture BOTH:

  • WHAT — The technical achievement (e.g., "PostgreSQL migration")
  • WHY — The business objective (e.g., "to improve query performance from 107ms to 27ms and enable concurrent access for scaling")

Search for business objectives in: meeting discussions about roadmap, Zulip threads about planning, PR descriptions, release notes, and any "why are we doing this" conversations.

Deadlines & Timeline Changes: Search all data sources for:

  • Explicit deadlines: "deadline is", "due by", "target date", "ship by X", "launch date"
  • ETAs and estimates: "ETA", "expected by", "should be done"
  • Changes: "pushed back", "extended", "delayed", "moved up", "ahead of schedule", "slipped"
  • Commitments: Agreements on when something will be delivered
  • Uncertainty: "not sure when", "TBD", "need to figure out timeline"

For each deadline discussion found, record:

  • What deliverable/milestone is being discussed
  • The date mentioned (if any)
  • Whether it's a new commitment, change, or removal
  • The source (which thread/meeting/commit)
  • Any context about why the timeline changed

Skip unless meaningful: Routine check-ins, minor documentation updates, social chat.

Output: Write projects/$0/timeline/{year-month}/week-{n}.md using the week file template from project-history. Also return a 3-5 line summary to the coordinator for use in Phase 3.

Create the month directory first if needed: mkdir -p projects/$0/timeline/{year-month}


Phase 3: Finalize (coordinator directly)

The coordinator collects the summaries returned by all Phase 2 subagents. These summaries are small enough to fit in the coordinator's context.

Step 5: Update Timeline Index

Add links to new week files in projects/$0/timeline/index.md. Append entries under the appropriate year/quarter sections. Update milestones if any were reached.

Step 6: Update Project Dashboard (project.md)

File: projects/$0/project.md

This is the living document — update it with current status from the week summaries:

Update these sections:

  1. This Week's Focus - What the team is actively working on now
  2. Last Week's Focus - What was completed in the most recent week
  3. Team - Current contributors and their focus areas
  4. Milestones - Update status and add new ones with business objectives
  5. Recent Decisions - Key decisions from the last 2-3 weeks
  6. Deadline History - Track timeline discussions, commitments, and changes

Deadline Tracking:

  • Scan all week summaries for deadline-related discussions
  • Add new entries to the "Timeline Evolution" table showing changes
  • Update "Current Commitments" with latest target dates
  • Note when deadlines are mentioned without specific dates (uncertainty)
  • Capture the reasoning behind timeline changes when available

Deadline History Format:

## Deadline History

### Current Commitments
| Deliverable | Current Target | Source | Confidence |
|-------------|---------------|--------|------------|
| Feature X | Mar 15, 2026 | Sprint planning meeting | High |
| Beta release | Q2 2026 | Roadmap discussion | Medium |

### Timeline Evolution
| Date | Change | Previous | New | Reason | Source |
|------|--------|----------|-----|--------|--------|
| Feb 10 | Extended | Feb 28 | Mar 15 | Additional testing needed | #dev channel |
| Jan 15 | Committed | - | Feb 28 | Initial sprint commitment | Sprint kickoff |

Milestone Format:

### In Progress 🔄
| Milestone | Target | Business Objective |
|-----------|--------|-------------------|
| Standalone deployment | Feb 2026 | Enable non-developers to self-host without complex setup |

### Recently Completed ✅
| Milestone | Date | Business Objective |
|-----------|------|-------------------|
| PostgreSQL migration | Mar 2025 | Improve performance (107ms→27ms) and enable scaling |

### Lost in Sight / Paused ⏸️
| Milestone | Status | Reason |
|-----------|--------|--------|
| Feature X | Paused | Resources reallocated to higher priority |

Note: Milestones in this company change frequently — update status (in progress/done/paused) as needed.

Step 7: Update Sync State

Create or update projects/$0/sync-state.md:

First sync (Case A):

# Sync State

status: synced
created_at: {today's date}
last_sync_date: {today's date}
initial_history_from: {range_start}
initial_history_to: {range_end}
last_incremental_sync: {today's date}

Incremental sync (Case B):

# Sync State

status: synced
created_at: {original value}
last_sync_date: {today's date}
initial_history_from: {original value}
initial_history_to: {original value}
last_incremental_sync: {today's date}

Step 8: Cleanup

rm -rf tmp/$0-sync

Step 9: Summary Report

Output a brief summary:

## Sync Summary: {Date}

### Period Covered
{range_start} to {range_end}

### Key Changes
1. Decision: {brief description}
2. Feature: {what was built}
3. Team: {who joined/left}
4. Timeline: {deadline changes or commitments made}

### Metrics
- {n} new commits
- {n} active contributors
- {n} weeks analyzed
- {n} new Zulip threads
- {n} meetings recorded

### Current Status
[Status description]

Key Rules

  • Link to sources: Always reference commit hashes, PR numbers, Zulip topic names, meeting dates
  • Be explicit about exclusions: Document what you're NOT analyzing and why
  • Write once: Week files are historical records — don't modify existing ones, only create new ones
  • Paginate all queries: Always loop through all pages of results
  • Distinguish contributor types: Core (regular activity) vs. occasional (sporadic)
  • Subagent isolation: Each subagent should be self-contained. Pass only the data it needs — never the full scratch files
  • Fail gracefully: If a datasource subagent fails (e.g., git clone errors, API down), the coordinator should continue with available data and note the gap in the summary