Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add commands/convocli/convosync-plugin/resumegit clone --depth 1 https://github.com/convocli/convosync-pluginWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00000 | $0.03113 |
| Opus 5 | $0.00000 | $0.01556 |
| Sonnet 5 | $0.00000 | $0.00623 |
| Haiku 4.5 | $0.00000 | $0.00311 |
Grade A, and why
resume scanned grade A with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Runs shell commandslowCapability
Expected in a hook, worth knowing in a rule or an instructions file.
subprocess.run(["git", "pull"], check=True, capture_output=True) How it starts
The opening of the file, as written. The whole thing — 407 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Resume ConvoSync Session
Resume work on another device by viewing session handoffs from other devices.
What this does:
- Pulls latest code and handoff file from git
- Parses handoffs from all devices
- Cleans up old handoffs from THIS device (keeps latest only)
- Displays handoffs from OTHER devices in current conversation
- Commits cleaned handoff file back to git
Prerequisites:
- Another device must have run
/convosync:generate-handoffand/convosync:save - Git repository must be configured
Usage:
/convosync:resume
Execute the resume process:
python3 << 'RESUME_SCRIPT'
import subprocess
import sys
from pathlib import Path
from datetime import datetime, timezone
import re
print("🔄 ConvoSync: Resuming session...")
print()
# ============================================================================
# 1. Git pull
# ============================================================================
print("→ Pulling latest code and handoffs...")
try:
subprocess.run(["git", "pull"], check=True, capture_output=True)
commit_short = subprocess.run(['git', 'rev-parse', '--short', 'HEAD'], capture_output=True, text=True).stdout.strip()
print(f"✓ Code pulled: {commit_short}")
except subprocess.CalledProcessError as e:
print(f"⚠️ Git pull failed: {e.stderr}")
print(" Continuing with local version...")
print()
# ============================================================================
# 2. Get device ID
# ============================================================================
def get_or_create_device_id():
"""Get unique device identifier, create if doesn't exist."""
device_file = Path('.convosync/device-id')
if device_file.exists():
return device_file.read_text().strip()
# Generate device ID from hostname
try:
hostname = subprocess.run(['hostname'], capture_output=True, text=True).stdout.strip()
device_id = re.sub(r'[^a-zA-Z0-9-]', '-', hostname)
except:
device_id = 'unknown-device'
# Prompt if generic hostname
if device_id.lower() in ['localhost', 'android', 'termux', 'pc', 'unknown-device', '']:
print("┌────────────────────────────────────────────────────────────────┐")
print("│ DEVICE IDENTIFICATION │")
print("└────────────────────────────────────────────────────────────────┘")
print()
print(f"Detected hostname: '{device_id}'")
print()
print("Please give this device a friendly name")
print("(e.g., 'desktop', 'mobile', 'laptop', 'work-laptop'):")
print()
try:
user_input = input("Device name: ").strip()
if user_input:
device_id = re.sub(r'[^a-zA-Z0-9-]', '-', user_input)
except:
pass # Keep default if input fails
print()
# Save device ID
device_file.parent.mkdir(exist_ok=True)
device_file.write_text(device_id)
subprocess.run(['git', 'add', str(device_file)], check=False)
return device_id
device_id = get_or_create_device_id()
print(f"→ Device: {device_id}")
print()
# ============================================================================
# 3. Check for handoff file
# ============================================================================
handoff_file = Path('.convosync/session-handoff.md')
if not handoff_file.exists():
print("┌────────────────────────────────────────────────────────────────┐")
print("│ ℹ️ NO HANDOFFS FOUND │")
print("└────────────────────────────────────────────────────────────────┘")
print()
print("No session handoffs found in this repository.")
print()
print("This is normal for:")
print(" • First time using ConvoSync on this project")
print(" • No other devices have saved sessions yet")
print()
print("To create a handoff:")
print(" 1. Run: /convosync:generate-handoff")
print(" 2. Ask Claude to generate the handoff")
print(" 3. Run: /convosync:save \"your message\"")
print()
sys.exit(0)
# ============================================================================
# 4. Parse handoff file
# ============================================================================
def parse_handoffs(content):
"""Parse handoff markdown file into structured data."""
handoffs = []
# Split on handoff headers (## Handoff from {device})
sections = re.split(r'^---\s*$', content, flags=re.MULTILINE)
for section in sections:
section = section.strip()
if not section or section.startswith('# ConvoSync'):
continue
# Extract device from header
device_match = re.search(r'^## Handoff from (.+?)$', section, re.MULTILINE)
if not device_match:
continue
device = device_match.group(1).strip()
# Extract metadata
timestamp_match = re.search(r'\*\*Timestamp:\*\* (.+?)$', section, re.MULTILINE)
commit_match = re.search(r'\*\*Commit:\*\* (.+?)$', section, re.MULTILINE)
branch_match = re.search(r'\*\*Branch:\*\* (.+?)$', section, re.MULTILINE)
timestamp = timestamp_match.group(1).strip() if timestamp_match else None
commit = commit_match.group(1).strip() if commit_match else None
branch = branch_match.group(1).strip() if branch_match else None
# Extract content (everything after metadata)
content_start = section.find('**Branch:**')
if content_start == -1:
content_start = section.find('**Commit:**')
if content_start == -1:
content_start = section.find('**Timestamp:**')
if content_start != -1:
# Find end of metadata line
content_start = section.find('\n', content_start)
if content_start != -1:
handoff_content = section[content_start:].strip()
else:
handoff_content = ''
else:
handoff_content = section
handoffs.append({
'device': device,
'timestamp': timestamp,
'commit': commit,
'branch': branch,
'content': handoff_content,
'raw': section
})
return handoffs
content = handoff_file.read_text()
handoffs = parse_handoffs(content)
print(f"→ Found {len(handoffs)} handoff(s)")
print()
if not handoffs:
print("⚠️ Handoff file exists but contains no valid handoffs")
sys.exit(0)
# ============================================================================
# 5. Smart cleanup: Keep latest from current device, all from others
# ============================================================================
def cleanup_handoffs(handoffs, current_device):
"""Keep only latest from current device, all from other devices."""
from_current = [h for h in handoffs if h['device'] == current_device]
from_others = [h for h in handoffs if h['device'] != current_device]
if from_current:
# Sort by timestamp (most recent first)
from_current.sort(key=lambda h: h['timestamp'] or '', reverse=True)
kept_from_current = [from_current[0]] # Keep only most recent
removed_count = len(from_current) - 1
else:
kept_from_current = []
removed_count = 0
cleaned = from_others + kept_from_current
return cleaned, removed_count
cleaned_handoffs, removed_count = cleanup_handoffs(handoffs, device_id)
if removed_count > 0:
print(f"→ Cleaned up {removed_count} old handoff(s) from this device")
# Write cleaned handoffs back to file
new_content = "# ConvoSync Session Handoffs\n\n"
for h in cleaned_handoffs:
new_content += "---\n"
new_content += h['raw'] + "\n\n"
handoff_file.write_text(new_content)
# Commit cleaned file
subprocess.run(['git', 'add', str(handoff_file)], check=False)
try:
subprocess.run(
['git', 'commit', '-m', f'chore: cleanup old handoffs from {device_id}'],
check=False,
capture_output=True
)
print(" Committed cleanup")
except:
pass # OK if nothing to commit
print()
# ============================================================================
# 6. Display handoffs from OTHER devices
# ============================================================================
other_handoffs = [h for h in cleaned_handoffs if h['device'] != device_id]
if not other_handoffs:
print("┌────────────────────────────────────────────────────────────────┐")
print("│ ℹ️ NO HANDOFFS FROM OTHER DEVICES │")
print("└────────────────────────────────────────────────────────────────┘")
print()
print("All handoffs in this repository are from this device.")
print()
print("To sync from another device:")
print(" 1. Switch to another device")
print(" 2. Run: /convosync:generate-handoff")
print(" 3. Run: /convosync:save \"message\"")
print(" 4. Return to this device and run: /convosync:resume")
print()
sys.exit(0)
# Format timestamps nicely
def time_ago(timestamp_str):
"""Convert ISO timestamp to human-readable time ago."""
if not timestamp_str:
return "unknown time"
try:
# Parse ISO format timestamp
ts = datetime.fromisoformat(timestamp_str.replace('Z', '+00:00'))
now = datetime.now(timezone.utc)
delta = now - ts
seconds = delta.total_seconds()
if seconds < 60:
return "just now"
elif seconds < 3600:
minutes = int(seconds / 60)
return f"{minutes} minute{'s' if minutes != 1 else ''} ago"
elif seconds < 86400:
hours = int(seconds / 3600)
return f"{hours} hour{'s' if hours != 1 else ''} ago"
else:
days = int(seconds / 86400)
return f"{days} day{'s' if days != 1 else ''} ago"
except:
return timestamp_str
print()
print("╔════════════════════════════════════════════════════════════════════╗")
print("║ 📝 SESSION HANDOFFS FROM OTHER DEVICES ║")
print("╚════════════════════════════════════════════════════════════════════╝")
print()
for i, handoff in enumerate(other_handoffs, 1):
print(f"{'═' * 70}")
print(f"📱 Handoff {i}/{len(other_handoffs)} from: {handoff['device']}")
print(f"{'═' * 70}")
print()
print(f"⏰ {time_ago(handoff['timestamp'])}")
if handoff['commit']:
print(f"📌 Commit: {handoff['commit'][:7]}")
if handoff['branch']:
print(f"🌿 Branch: {handoff['branch']}")
print()
print(handoff['content'])
print()
print("╔════════════════════════════════════════════════════════════════════╗")
print("║ ✅ CONTEXT RESTORED! ║")
print("╚════════════════════════════════════════════════════════════════════╝")
print()
print(f"Loaded {len(other_handoffs)} handoff(s) from other device(s).")
print()
print("I can now reference the session context above to continue your work!")
print()
print("When you're done on this device:")
print(" 1. Run: /convosync:generate-handoff")
print(" 2. Run: /convosync:save \"your message\"")
print()
RESUME_SCRIPT
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago First seen · 407 lines · 0 tokens per session scan A c115681389ff
resume is a command published in the GitHub repository convocli/convosync-plugin (4 stars, last pushed 10mo ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 3,113 tokens. A static security scan graded it A with 1 finding (runs shell commands). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other commands, from other repositories
minutes-ideas
Surface recent voice memos and ideas captured from any device. Use when the user asks "what ideas did I have?", "what were my recent memos?", "what did I record while walking?", or wants to recall a captured thought.
autobot-result
Print the most recent result.md for an autobot session, so the user can see how a bot is doing without attaching to its tmux session.
engage.actions
Execute Phase 7 - Actions on Objectives and Goal Achievement.
version
Show installed vs latest ai-sdlc plugin version. Bypasses the 24h SessionStart cache.
thread
Manage conversation threads (create, switch, update, delete, show).
handoff
Generate or load a session handoff. Usage: /handoff [create|resume].