13 KiB
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 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 (Monday–Sunday). 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.mdtmp/$0-sync/git.mdtmp/$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:
- Key Decisions — Technology migrations, architecture changes, vendor switches, security incidents, strategic pivots
- Technical Work — Feature implementations, bug fixes, infrastructure changes
- Team Activity — Core vs. occasional contributors, role changes
- Blockers — Issues, delays, dependencies
- 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:
- This Week's Focus - What the team is actively working on now
- Last Week's Focus - What was completed in the most recent week
- Team - Current contributors and their focus areas
- Milestones - Update status and add new ones with business objectives
- Recent Decisions - Key decisions from the last 2-3 weeks
- 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