{"version":"2.7.0","created":"2025-02-05T00:00:00.000Z","author":"eugene","changelog":["2.7.0: Plugin reconciliation (Phase 7b, trinity#1704 / ent#411) — `template.yaml plugins:` is the declared plugin set and Trinity re-installs it headlessly on every container boot; sync now checks it the way it checks schedules: `status` reports declared-vs-installed drift on the remote (via `claude plugin list --json` inside the agent, run through chat_with_agent), push/pull/deploy re-check after the code lands, and the new `plugins` subcommand reconciles on demand — install what is declared and missing (same two CLI calls the boot hook makes), never uninstall (additive; a live-only plugin is reported as drift for the operator, mirroring the schedule rule). Also flags a template.yaml with no plugins: block at all as SOFT drift with the one-line fix","2.6.0: Schedule reconcile matches on the literal `name`, not a `[id]` prefix — ent#89 materializes declared schedules verbatim and dedups on name, so the prefixed name never collided and Path-A agents ended up with two schedules firing the same cron. Remote pull now goes through mcp__trinity__git_pull instead of a chat_with_agent shell command (the platform path runs the .gitignore reconcile + trinity#2036 untracking, and a raw checkout desyncs a source-mode clone from the branch the DB records, trinity#1913); git MCP tools added to allowed-tools","2.5.0: Name the deploy path sync serves — repo-deployed agents (the default: create_agent with template: github:owner/repo) hold a clone tracking the branch, so push/pull IS the update mechanism and nothing is ever uploaded; a remote whose .trinity-remote.yaml `source` reads local-archive has no repo binding and is reported with the initialize_github_sync fix instead of silently no-opping","2.4.0: `pull` no longer blanket-discards before fast-forwarding — it stashes uncommitted work (tracked + untracked) and pops it back, discarding only known runtime paths, and uses `git pull --ff-only`. Fixes a data-loss hazard where a scheduled pull onto the remote's autonomous-loop commits wiped uncommitted agent-value edits (skills, memory, registries) via `git checkout -- .`","2.3.1: Added the canonical Trinity MCP connection prerequisite — delegates to /trinity:connect (the single connection owner) when the mcp__trinity__* tools aren't live, consistent with /trinity:loop and /trinity:onboard","2.3.0: Unified remote registry — sync's config is now `.trinity-remote.yaml` (was `.trinity-sync.yaml`), the same file `/trinity:onboard` writes and `/trinity:loop` reads. Fixes the onboard→sync handoff (sync now resolves the agent name onboard recorded instead of re-guessing). Schema gains onboard's machine-maintained `instance`/`profile`/`deployed_at` fields; migrates legacy single-remote files in place","2.2.0: Schedule reconciliation (Phase 7) — diff template.yaml schedules: against live Trinity schedules on push/pull/deploy/status; new `schedules` subcommand to reconcile on demand","2.1.1: Quote argument-hint — unquoted brackets broke YAML frontmatter, making the skill invisible","2.1: After syncing a remote, check its Operating Room queue and report any open ops notifications","2.0: Multi-remote support - one local agent can sync to multiple Trinity instances","1.1: Genericized - works with any agent via dynamic name detection","1.0: Initial version"]}
Agent Synchronization Skill
ℹ️ First, set expectations: before anything else, print one short line with this skill's version and its most recent change — the top entry of metadata.changelog above — e.g. sync vX.Y — recent: <summary>. Then proceed.
Synchronize the local agent with one or more remote instances on Trinity. Supports multiple remotes (e.g., production, staging, development) and branch-based versioning.
Prerequisite — Trinity MCP connection
The mcp__trinity__* tools below need a live connection. If they're unavailable (or a call errors with no connection), run /trinity:connect — it authenticates and writes .mcp.json (or refreshes it from your stored profile) — then reconnect with /mcp (full restart only as a fallback) and resume. Never fall back to the Trinity CLI or curl.
Multi-Remote Architecture
A single local agent can have multiple remote counterparts on Trinity:
Remote instances are configured in .trinity-remote.yaml at the agent root. This is the single registry of this agent's remote Trinity instances — the same file /trinity:onboard writes at deploy time and /trinity:loop reads to find its remote counterpart. Sync owns the multi-remote and branch fields; onboard maintains the deploy-tracking fields (instance, profile, deployed_at).
# .trinity-remote.yaml
# Remote Trinity instances of this agent.
# instance / profile / deployed_at are machine-maintained by onboard — safe to leave as-is.
default: prod # Which remote to use when none specified
remotes:
prod:
agent: my-agent # Trinity agent name (sync)
branch: main # Branch this remote tracks (sync)
instance: https://trinity.example.com # Trinity URL deployed on (onboard)
profile: default # CLI profile to reach it (onboard)
deployed_at: 2026-06-16T12:00:00Z # Last deploy, ISO 8601 (onboard)
description: Production instance
staging:
agent: my-agent-staging
branch: staging
description: Staging for testing
dev:
agent: my-agent-dev
branch: experimental
description: Development/experimental
Only agent is required per remote; branch defaults to main, and the onboard fields are optional (present once the remote has been deployed to). Sync never needs instance/profile/deployed_at and leaves them untouched.
Legacy single-remote file: Older .trinity-remote.yaml files written by onboard had top-level agent:/instance: keys and no remotes: block. When you encounter that shape, fold it into the unified form as the default remote (preserve its agent/instance/profile/deployed_at) before proceeding.
If no config exists: Falls back to auto-detection (template.yaml name or directory name) as a single "default" remote.
Quick Commands
Status & Discovery
/trinity-sync or /trinity-sync status - Show all remotes and their sync status
/trinity-sync status @prod - Check status of specific remote
/trinity-sync remotes - List configured remotes
/trinity-sync branches - List available branches (local and remote)
Syncing
/trinity-sync push - Push to default remote on its tracked branch
/trinity-sync push @staging - Push to staging remote
/trinity-sync push @prod main - Push main branch to prod remote
/trinity-sync pull - Pull from default remote
/trinity-sync pull @staging - Pull from staging remote
Deployment
/trinity-sync deploy experimental - Deploy branch to default remote
/trinity-sync deploy @staging experimental - Deploy branch to specific remote
Configuration
/trinity-sync add-remote <name> <agent-name> [branch] - Add a new remote
Verify agent exists on Trinity: mcp__trinity__list_agents
Add new remote entry:
<name>:
agent: <agent-name>
branch: <branch|main>
description: Added via trinity-sync
If this is the first explicit remote, set as default
Remove Remote Procedure
/trinity-sync remove-remote <name>
Verify remote exists in config
If removing default, require new default to be specified
Remove the remote entry
Update config file
Directory Structure: What Syncs vs What's Discardable
CRITICAL: Know the difference between agent identity and runtime state:
Path
Type
Sync?
Description
.claude/skills/
AGENT VALUE
YES
Agent capabilities - THIS IS THE AGENT
.claude/agents/
AGENT VALUE
YES
Sub-agent definitions
.claude/commands/
AGENT VALUE
YES
Command definitions
memory/
AGENT VALUE
YES
Schedules, persistent state
scripts/
AGENT VALUE
YES
Python/bash scripts
source-of-truth/
AGENT VALUE
YES
Business documentation
CLAUDE.md
AGENT VALUE
YES
Main agent instructions
template.yaml
AGENT VALUE
YES
Trinity metadata
.claude/debug/
Runtime
Discard
Debug logs
.claude/projects/
Runtime
Discard
Project cache
.claude/statsig/
Runtime
Discard
Analytics state
.claude/todos/
Runtime
Discard
Temporary todos
session-files/
Runtime
Discard
Session-specific work
content/
Runtime
Discard
Large generated content
Never run git checkout -- .claude/skills/ - this destroys agent capabilities!
Branch-Based Versioning
Use branches to maintain different versions or configurations of the agent:
Branch Pattern
Purpose
Example
main
Production-stable version
Default deployment
experimental
Testing new features
/trinity-sync deploy experimental
v1.x, v2.x
Tagged stable releases
/trinity-sync deploy v1.5
feature/*
Work-in-progress features
/trinity-sync push feature/new-skill
Typical Workflow
# 1. Create experimental branch locally
git checkout -b experimental
# 2. Make changes, test locally
# ... edit skills, memory, etc ...
# 3. Push and deploy to remote for testing
/trinity-sync push experimental
# 4. If successful, merge to main
git checkout main && git merge experimental
# 5. Deploy main to remote
/trinity-sync push
Sync Procedure
Phase 0: Remote Resolution
Before any operation, resolve which remote(s) to target:
1. Parse command for @remote specifier
2. Load .trinity-remote.yaml (if exists)
3. Resolve target remote:
- Explicit @remote → use that config
- $TRINITY_SYNC_TARGET → use that
- Config default → use that
- No config → auto-detect single remote
4. Extract remote config:
- agent_name: Trinity agent name
- tracked_branch: Branch this remote should track
- description: For display
For status without @remote: Show ALL configured remotes.
Phase 1: Discovery
Gather state from local and target remote(s):
Local state:
git status
git branch -a
git log -5 --oneline
git remote -v
Remote state (via MCP):
For each targeted remote, query the Trinity agent:
Current branch: git branch --show-current
Git status: git status
Recent commits: git log -5 --oneline
Any uncommitted changes
Multi-remote status display:
Remote Status Summary
─────────────────────────────────────────────────
Remote Agent Branch Status
─────────────────────────────────────────────────
prod* my-agent main ✓ In sync @ abc1234
staging my-agent-staging staging ↑ Local ahead by 2 commits
dev my-agent-dev feature/x ✗ Remote has uncommitted changes
─────────────────────────────────────────────────
* = default remote
Phase 2: Analysis
Compare the states and classify:
Scenario
Local Status
Remote Status
Action
In Sync
Same HEAD, clean
Same HEAD, clean
Nothing to do
Local Ahead
Ahead by N commits
Behind
Push to GitHub, remote pulls
Remote Ahead
Behind
Ahead by N commits
Local pulls from GitHub
Both Changed
Uncommitted changes
Uncommitted changes
Review diffs, decide winner
Diverged
Different commits
Different commits
Merge required (rare)
Different Branches
On branch X
On branch Y
Branch switch needed
Phase 3: Classify Uncommitted Changes
Runtime state (ALWAYS discard):
.claude/debug/ - Debug logs
.claude/projects/ - Project cache
.claude/statsig/ - Analytics state
.claude/todos/ - Temporary todos
session-files/ - Session work
content/ - Generated content
.npm/, .venv/, node_modules/
Any file in .gitignore
Agent value (MUST sync - this is the agent itself):
.claude/skills/ - Agent capabilities
.claude/agents/ - Sub-agent definitions
.claude/commands/ - Command definitions
memory/ - Schedules and persistent state
scripts/ - Automation scripts
source-of-truth/ - Business documentation
CLAUDE.md - Main agent instructions
template.yaml - Trinity metadata
Deletions are suspicious - Usually accidental, verify the content wasn't just refactored elsewhere.
Phase 4: Execute Sync
Based on analysis, command, and target remote:
If /trinity-sync push or /trinity-sync push @remote:
Resolve target remote (default if not specified)
Get remote's tracked branch from config
Ensure local changes are committed
Push: git push origin <tracked-branch>
Pull on the remote through the platform, not a shell:
Use this rather than a chat_with_agent shell command. The platform pull path is what runs the fleet-wide .gitignore reconcile and the trinity#2036 untracking that heals a leaked .claude/settings.json; a raw git checkout also moves a source-mode clone off the branch the DB records, which trinity#1913 re-derives and reverts on the next config-drift recreate.
Verify both at same HEAD: mcp__trinity__get_git_sync_state(agent_name: <remote.agent>) (or get_git_status / get_git_log for detail)
If /trinity-sync push @remote <branch>:
Resolve target remote
Ensure local changes are committed on specified branch
If branch doesn't exist remotely: git push -u origin <branch>
Otherwise: git push origin <branch>
Tell remote agent to fetch and checkout the branch
Update remote config if branch differs from tracked:
Ask: "Update @remote to track ? (y/n)"
If yes, update .trinity-remote.yaml
If /trinity-sync deploy <branch> or /trinity-sync deploy @remote <branch>:
Verify remote is on correct branch at expected HEAD
Update remote's tracked branch in config
If /trinity-sync pull or /trinity-sync pull @remote:
⚠️ Never blanket-discard before pulling.git checkout -- . wipes every
uncommitted change — including agent value (skills, memory, registries, thinking
files) the local session has edited but not yet committed. The remote's autonomous
loops commit those same files on a schedule, so a pull routinely lands on top of
live local edits. git checkout is unrecoverable; stash instead, so work
survives the pull.
Resolve the target remote and its tracked branch.
Discard ONLY known runtime paths (noise, recreated at runtime) — never a blanket checkout:
for p in .claude/debug .claude/projects .claude/statsig .claude/todos session-files content; do
git checkout -- "$p" 2>/dev/null || true
done
Stash everything still uncommitted (tracked + untracked) so agent-value edits survive:
Fast-forward onto the remote branch. --ff-only fails cleanly if the branches
have diverged — no half-finished merge/rebase state, and the stash stays intact:
git pull --ff-only origin <remote-branch>
Re-apply the stashed local edits on top of the pulled commits:
if [ "$STASHED" = 1 ]; then
git stash pop || {
echo "⚠ Local edits overlap the pulled changes — conflict on pop."
echo " Your work is preserved in the stash (git stash list). Resolve manually; nothing was lost."
}
fi
Verify at the remote's HEAD (plus any re-applied local edits). If step 4 could not
fast-forward, the branches have diverged — surface it as a merge decision; the stash
still holds the local work, so nothing is lost either way.
If both have uncommitted changes:
Compare the diffs
Determine which changes are meaningful vs accidental
Winner keeps changes, loser discards
Commit meaningful changes
Push/pull to sync
Phase 5: Verification
Confirm both agents report:
Same branch checked out
Same HEAD commit hash
Clean working tree (or only runtime state uncommitted)
Phase 6: Operator Queue Check
After syncing a remote (push/pull/deploy) — and for each remote shown in a status check — review the agent's Operating Room queue and surface any items awaiting human attention.
For each targeted remote, using its resolved Trinity agent name:
Treat items that are not already resolved/closed as open. For each open item, optionally fetch detail with mcp__trinity__get_operator_queue_item(<id>) to summarize what it needs.
Report back to the user:
No open items: one line — ✓ Operating Room: no open notifications for <remote>
Open items: list them so the user can act:
⚠ Operating Room: <N> open notification(s) for <remote> (<agent>)
• [<id>] <title/summary> — <status>
• [<id>] <title/summary> — <status>
This is report-only — the sync skill never resolves or answers queue items; it just makes the user aware they exist.
Phase 7: Schedule Reconciliation
Schedules are declared in template.yaml under a schedules: block (the design source of truth — schema defined in /trinity:onboard Step 3a) and materialized as live cron jobs on each Trinity instance. They drift: someone edits template.yaml, or an operator adds/removes a schedule on a live agent. This phase keeps the declared catalog and the live instance aligned.
When it runs:
push / pull / deploy — after the code sync completes, reconcile the target remote's schedules (the agent's capabilities just changed; its schedules should match).
status — report only: show declared-vs-live drift, change nothing.
schedules subcommand — reconcile on demand against the resolved remote(s).
Procedure — for each targeted remote, using its resolved Trinity agent name:
Read declared schedules from local template.yaml. If there's no schedules: block, skip this phase entirely.
List live schedules:mcp__trinity__list_agent_schedules(agent_name: <remote.agent>).
Match by name — Trinity materializes a template's declared schedules under their literal name (ent#89) and dedups on it, so the live counterpart of name: Weekly report is exactly Weekly report. Match on name and never stamp a prefix when creating: a [id]-prefixed name cannot collide with the platform's, so the agent ends up with two schedules firing the same cron. Diff:
Case
Condition
push/pull/deploy action
status action
Create
Declared, no live match
create_agent_schedule(...), enabled from manifest, name exactly as declared
update_agent_schedule(...) to match manifest (never touch enabled)
report "would update"
In sync
Declared + live, identical
nothing
—
Drift
Live name not in manifest
report, never delete
report
Never flip enabled on an existing schedule — turning schedules on/off on a live agent is the operator's decision (toggle_agent_schedule). The manifest's enabled is applied only at create time. Reconcile keeps configuration in sync, not activation.
Deletions are never automatic. A live schedule with no matching declaration is surfaced as drift for the operator to resolve (remove on the instance, or add to template.yaml).
Report:
Schedule Reconciliation — prod (my-agent)
─────────────────────────────────────────────────
id Cron State Action
─────────────────────────────────────────────────
weekly-report 0 9 * * 1 enabled ✓ in sync
daily-digest 0 7 * * * enabled ↑ updated (cron changed)
monthly-roll 0 0 1 * * disabled + created (operator can enable)
─────────────────────────────────────────────────
⚠ Drift: "[adhoc] manual cleanup" is live but not in template.yaml — left as-is
Phase 7b: Plugin Reconciliation
Plugins are declared in template.yaml under a plugins: block (schema in /trinity:onboard Step 3a — marketplaces: + installed:; trinity#1704) and materialized on the instance as a committed ~/.trinity/plugins.yaml that the container's boot hook re-installs headlessly on every start. Between boots, drift is possible in both directions: a plugin declared after creation is not present until the next restart, and a plugin someone installed by hand is not declared. Sync treats it exactly like schedules — the manifest is the design truth, the operator owns the live extras.
When it runs:status (report only) · after push / pull / deploy (the declaration may just have changed) · plugins subcommand (on demand).
Procedure — for each targeted remote:
Read declared plugins from local template.yaml: yq -r '.plugins.installed[]?' and .plugins.marketplaces[]. No plugins: block at all → report one SOFT line — "template.yaml declares no plugins: — add at least trinity@abilityai (see /trinity:onboard Step 3a) so the selection survives a rebuild" — and skip the rest.
Read what is installed on the remote — ask the agent itself (the CLI is inside its container):
mcp__trinity__chat_with_agent(agent_name: <remote.agent>, message: "Run: claude plugin marketplace list --json; claude plugin list --json — reply with the raw JSON only").
If the agent cannot run claude (image predates #1704), report unknown — image without plugin CLI and stop; do not guess.
Diff declared vs installed:
Case
Condition
push/pull/deploy · plugins action
status action
Install
Declared, not installed
have the agent run the boot hook's calls: claude plugin marketplace add <source> (if the marketplace is missing) then claude plugin install <plugin>@<mkt> --yes
report "would install"
In sync
Declared + installed
nothing
—
Extra
Installed, not declared
report, never uninstall — the operator either declares it in template.yaml (so it survives) or removes it by hand
report
Never uninstall. Same rule as schedules: reconciliation is additive; removals are the operator's act.
Remind about session boundaries: a plugin installed now loads on the agent's next execution.
Report:
Plugin Reconciliation — prod (my-agent)
─────────────────────────────────────────────────
plugin declared installed Action
─────────────────────────────────────────────────
trinity@abilityai yes yes ✓ in sync
agent-dev@abilityai yes no + installed (loads next execution)
utilities@abilityai no yes ⚠ extra — declare it or remove by hand
─────────────────────────────────────────────────
Branch Operations
List Branches
# Local branches
git branch
# Remote branches
git branch -r
# All branches with last commit
git branch -av
IMPORTANT: Never discard .claude/skills/, .claude/agents/, .claude/commands/, memory/, scripts/, or source-of-truth/ - these ARE the agent's capabilities and must be synced.
If this returns changes to skills/agents/commands/memory/scripts, these are meaningful - warn before proceeding.
Branch exists:
git ls-remote --heads origin <branch>
If branch doesn't exist, offer to push it first.
No merge conflicts expected:
Compare current HEAD with target branch for potential issues.
GitHub Repository
Both agents sync through the shared GitHub repository. GitHub is the source of truth. All meaningful changes must be committed and pushed.
This is the same repository the agent was deployed from. Agents are deployed repository-first — /trinity:onboard creates them with mcp__trinity__create_agent(template: "github:owner/repo[@branch]"), so the remote workspace is a clone tracking that branch, and sync is simply how it advances: commit → push → the remote pulls. Nothing is uploaded; the branch tip is the deployed state.
If a remote's source in .trinity-remote.yaml reads local-archive, that agent was deployed from a tar.gz snapshot and has no repo binding — sync has nothing to advance. Say so plainly and point at mcp__trinity__initialize_github_sync (or /trinity:onboard) to put it on the repo path; don't silently no-op.
Key Rules
GitHub is source of truth - All agents sync through the shared repo
Explicit remote targeting - Use @remote to target specific instances
Config over convention - Use .trinity-remote.yaml for explicit control
Agent value MUST sync - skills/, agents/, commands/, memory/, scripts/ are the agent itself
Runtime files are ephemeral - Only debug/, projects/, statsig/, todos/, session-files/ can be discarded
Deletions are suspicious - Usually accidental; verify before accepting
Meaningful changes win - Additions/improvements over deletions
Fast-forward preferred - Avoid merge commits when possible
Verify after sync - Always confirm target remote at expected HEAD
Clean before switch - Only discard runtime state before branch switch
Branches are cheap - Use them liberally for experiments
Track branch per remote - Each remote can track a different branch
Schedules reconcile from template.yaml - The schedules: block is the source of truth; reconcile aligns live cron jobs but never toggles activation (operator's call) or deletes drift
Pull stashes, never blanket-discards - pull stashes uncommitted work (tracked + untracked) before fast-forwarding and pops it back after; it only ever discards known runtime paths. A blanket git checkout -- . is forbidden — it destroys uncommitted agent value the local session hasn't committed yet, exactly what a scheduled pull lands on top of
When to Run Sync
Before starting significant work on any agent instance
After completing a major task
Weekly maintenance
When you notice drift between any remote instances
After recovering from errors
When deploying a new version or experiment
After creating a new Trinity instance - add it as a remote
When promoting changes - push to staging, then prod
Migration from Single to Multi-Remote
If you've been using trinity-sync without a config file:
User: /trinity-sync add-remote prod my-agent main
Agent: Creating .trinity-remote.yaml with initial configuration...
✓ Created config with 'prod' as default remote
Your existing workflow continues unchanged:
- `/trinity-sync push` → pushes to prod (my-agent on main)
Now you can add more remotes:
- /trinity-sync add-remote staging my-agent-staging staging
- /trinity-sync add-remote dev my-agent-dev experimental
Environment Variable Override
For CI/CD or scripted usage, set TRINITY_SYNC_TARGET:
# Push to staging in a script
TRINITY_SYNC_TARGET=staging /trinity-sync push
# Or export for session
export TRINITY_SYNC_TARGET=dev
/trinity-sync status # Shows dev remote
/trinity-sync push # Pushes to dev
This overrides the config default but can still be overridden by explicit @remote.
Example Sessions
Multi-Remote Status Check
User: /trinity-sync status
Agent: Checking sync status for all remotes...
[Queries local git status]
[Queries each configured remote via MCP]
┌─────────────────────────────────────────────────────────────────┐
│ Trinity Sync Status │
├─────────────────────────────────────────────────────────────────┤
│ Local: main @ 1cb2c9a (clean) │
├──────────┬──────────────────┬───────────┬───────────────────────┤
│ Remote │ Agent │ Branch │ Status │
├──────────┼──────────────────┼───────────┼───────────────────────┤
│ prod* │ my-agent │ main │ ✓ In sync @ 1cb2c9a │
│ staging │ my-agent-staging │ staging │ ↑ Local ahead by 2 │
│ dev │ my-agent-dev │ feature/x │ ⚠ Uncommitted changes │
└──────────┴──────────────────┴───────────┴───────────────────────┘
* = default remote
Recommendations:
- staging: Run `/trinity-sync push @staging` to update
- dev: Remote has uncommitted runtime changes, can push anyway
Status of Specific Remote
User: /trinity-sync status @staging
Agent: Checking staging remote...
Target: staging → my-agent-staging (tracking: staging branch)
Status Report:
- Local: staging @ 3f5a7c2 (clean)
- Remote: staging @ 1cb2c9a (clean, 2 commits behind)
Analysis: Local is 2 commits ahead on staging branch.
Run `/trinity-sync push @staging` to sync.
User: /trinity-sync deploy @dev experimental
Agent: Deploying 'experimental' branch to dev remote...
[Verifies branch exists on origin]
[Checks my-agent-dev working tree status]
⚠ Remote has uncommitted changes in session-files/ (runtime state)
[Discarding runtime state]
[Sending checkout commands to my-agent-dev]
Deployment Complete:
- Remote: my-agent-dev
- Switched from: feature/x @ abc1234
- Now on: experimental @ 8f3a1b2
Update config to track this branch? (y/n): y
Updated: dev remote now tracks 'experimental' branch.
User: /trinity-sync remotes
Agent: Configured remotes:
┌──────────┬──────────────────┬───────────┬─────────────────────────┐
│ Name │ Trinity Agent │ Branch │ Description │
├──────────┼──────────────────┼───────────┼─────────────────────────┤
│ prod* │ my-agent │ main │ Primary production │
│ staging │ my-agent-staging │ staging │ Staging for testing │
│ dev │ my-agent-dev │ experim. │ Development/experimental│
│ qa │ my-agent-qa │ staging │ QA testing environment │
└──────────┴──────────────────┴───────────┴─────────────────────────┘
* = default remote
Set different default: /trinity-sync set-default <name>
Set Default Remote
User: /trinity-sync set-default staging
Agent: Updating default remote...
Previous default: prod
New default: staging
Updated .trinity-remote.yaml
Now `/trinity-sync push` without @remote will target my-agent-staging.
No Config Fallback
User: /trinity-sync status
(no .trinity-remote.yaml exists)
Agent: No sync configuration found. Using auto-detection...
Detected agent: my-agent (from template.yaml)
Status Report:
- Local: main @ 1cb2c9a (clean)
- Remote: main @ 1cb2c9a (clean)
- ✓ In sync
Tip: Run `/trinity-sync add-remote prod my-agent main` to create explicit config.
This enables multi-remote support for staging/dev instances.
List Available Branches
User: /trinity-sync branches
Agent: Fetching branch information...
Local Branches:
* main 1cb2c9a Migrate google-workspace agent
staging 3f5a7c2 Staging release
experimental 8f3a1b2 Test new workflow
feature/new-skill 3d5e7f9 WIP: Adding skill X
Remote Branches (origin):
main 1cb2c9a Migrate google-workspace agent
staging 3f5a7c2 Staging release
experimental 8f3a1b2 Test new workflow
Remote Agent Status:
┌──────────┬──────────────────┬─────────────────────────┐
│ Remote │ Agent │ Currently On │
├──────────┼──────────────────┼─────────────────────────┤
│ prod* │ my-agent │ main @ 1cb2c9a │
│ staging │ my-agent-staging │ staging @ 3f5a7c2 │
│ dev │ my-agent-dev │ experimental @ 8f3a1b2 │
└──────────┴──────────────────┴─────────────────────────┘