Sync OpenCode agents and skills from an Obsidian vault to workspace directories
Project description
piagentsync
Sync OpenCode agents, skills, commands, and context files from an Obsidian vault to workspace directories.
Install
uv add piagentsync
# or
pip install piagentsync
Quick start
- Initialize a new project in your vault:
piagentsync init myproject --workspace ~/workspace/myproject
- Pull the synced files to your workspace:
piagentsync pull myproject
- If you made edits in the workspace and want to push them back into the vault:
piagentsync push myproject
Configuration
Environment variables (also configurable via .env file):
| Variable | Default | Description |
|---|---|---|
PIAGENTSYNC_VAULT_PATH |
~/vault |
Path to Obsidian vault |
PIAGENTSYNC_GLOBAL_OPENCODE_PATH |
~/.config/opencode |
Path to global OpenCode config |
PIAGENTSYNC_VAULT_GITHUB_USER |
Piwero |
GitHub username for vault repository (used in clone instructions) |
CLI reference
piagentsync pull <project>
Sync a single project from vault to workspace. This synchronizes agents, skills, commands, and the AGENTS.md context file.
Options:
--dry-run/--no-dry-run— preview changes without writing--global/--no-global— also sync global agents--all— sync all discovered projects
piagentsync push <project>
Sync a single project from workspace back to the vault. This synchronizes agents, skills, commands, and the AGENTS.md context file. It is the inverse of pull and is intended for bootstrapping the vault from existing workspaces or pushing emergency/local edits back into the vault (the user is expected to review and commit the vault afterwards).
Options:
--dry-run— preview what would be pushed without writing--global— also push global agents from your local global opencode config intovault/agents/global/--all— push all discovered projects
Behavior notes:
- Direction: workspace (
.opencode/) → vault - Conflict rule: workspace wins (files in the vault will be overwritten if different)
- Unchanged files are skipped using hash comparison
- After a successful push the CLI will print a reminder to run:
cd ~/vault && git add -A && git commit -m "..." && git push
Auto-commit behavior
When piagentsync push completes successfully (not a dry-run and no errors),
the CLI will automatically attempt to commit changes to the vault repository
using a conventional commit message (e.g. feat(push): sync <project> from workspace to vault). If the auto-commit succeeds you'll see a message like
✓ Vault committed: <git output>. If there are no changes to commit you'll see
No changes to commit. If auto-commit fails, the CLI prints a warning and the
manual fallback instructions (e.g. cd ~/vault && git add -A && git commit).
Note: the auto-commit step requires that git is available and configured
(user.name and user.email).
piagentsync sync <project>
Bidirectional sync with automatic conflict detection and resolution.
Performs intelligent two-way sync of agents, skills, commands, and context files:
- Files unchanged in both locations: synced normally
- Files changed only in one location: synced from that location
- Files changed in both locations: resolved by conflict resolution strategy
Conflict resolution strategies:
--strategy vault-wins— vault version always wins (push workspace edits → conflicts resolve to vault)--strategy workspace-wins— workspace version always wins (pull edits → conflicts resolve to workspace)--strategy ask— default — report conflicts without auto-resolving (human review required)
Examples:
# Show conflicts without auto-resolving (default):
piagentsync sync myproject
# Auto-resolve to vault version:
piagentsync sync myproject --strategy vault-wins
# Auto-resolve to workspace version:
piagentsync sync myproject --strategy workspace-wins
# Sync all projects with auto-resolution:
piagentsync sync --all --strategy workspace-wins
Legacy flags (still supported but deprecated):
--vault-wins— equivalent to--strategy vault-wins--workspace-wins— equivalent to--strategy workspace-wins
Do not mix old and new flags (will error).
Options:
--dry-run/--no-dry-run— preview changes without writing--global/--no-global— also sync global agents--all— sync all discovered projects
WORKSPACE_WINS behavior and auto-commit
The workspace-wins strategy writes the workspace copy back into the vault
(destination → source). When piagentsync sync runs without --dry-run and
completes successfully, the CLI will attempt to auto-commit changes to the
vault repository. Use --dry-run to preview changes without writing.
Example (dry-run, will not write):
piagentsync sync myproject --strategy workspace-wins --dry-run
piagentsync status [project]
Show sync status (differences between vault and workspace) for agents, skills, commands, and context files.
By default shows both project agents and global agents. Use --no-global to show only project agents.
Options:
--global/--no-global— toggle global agent display (default: shows global agents)
Examples:
# Show status for all projects (includes global agents by default):
piagentsync status
# Show status for a specific project (includes global agents by default):
piagentsync status myproject
# Show only project agents (exclude global agents):
piagentsync status --no-global
# Show only global agents:
# To view global agents only, run `piagentsync status` and filter the "Project"
# column for `global`, or explicitly request a global-only view by running the
# command on a machine configured with only global agents. The CLI currently
# shows project and global agents together by default; use `--no-global` to
# exclude global agents.
piagentsync init <project>
Scaffold a new project in the vault.
Options:
--workspace PATH— required, workspace directory--notion-board-id TEXT— optional Notion DB ID--notion-project-filter TEXT— optional Notion project filter (defaults to project slug)
piagentsync bootstrap
Bootstrap machine from an existing vault. This is a one‑time setup to configure OpenCode and install global agents.
Options:
--force— overwrite existingopencode.jsonif present
Steps performed:
- Verifies that the vault exists (
PIAGENTSYNC_VAULT_PATH). If missing, prints a helpfulgit clonecommand. - Writes
{PIAGENTSYNC_GLOBAL_OPENCODE_PATH}/opencode.jsonwith Notion and Obsidian MCPs and disables tool globs. Skips if file exists unless--forceis used. - Runs
opencode mcp auth notioninteractively to authenticate with Notion. Ifopencodeis not on PATH, a warning is printed and the step is skipped. - Copies the
chief-pmglobal agent from the vault's configuration into your global OpenCode config. For new-style vaults this is{vault}/config/agents/global/chief-pm.md; for legacy vaults it is{vault}/agents/global/chief-pm.md. If neither exists, a warning is printed.
All steps produce clear Rich output and non‑critical warnings. The command exits 1 only if the vault is missing or a file write fails.
--version
Print version and exit.
AGENTS.md manifest format
Each project must have an AGENTS.md file in its root with YAML frontmatter:
---
project: myproject
workspace: ~/workspace/myproject
notion_board_id: 3305f9479a8d8055b3c3e86a9006cf91
notion_project_filter: myproject
---
The body below the frontmatter is the OpenCode routing table.
Expected vault structure
New layout (recommended)
vault/
├── config/ # Global OpenCode configuration
│ ├── agents/ # Global agents
│ │ └── global/ # agents available in all projects
│ │ └── *.md
│ ├── commands/ # Global commands
│ │ └── global/
│ │ └── *.md
│ └── tools/ # Tool documentation (*.md)
└── projects/ # Project-specific configuration
└── {project}/
├── AGENTS.md # Project manifest (required)
├── context.md # Optional project context
├── decisions.md # Optional decisions log
├── agents/ # Project-specific agents
│ └── *.md
├── skills/ # Project-specific skills
│ └── *.md
└── commands/ # Project-specific commands
└── *.md
Legacy layout (still supported)
vault/
├── agents/
│ └── global/
│ └── *.md
└── agents/
└── projects/
└── {project}/
├── AGENTS.md
├── agents/
│ └── *.md
├── skills/
│ └── *.md
└── commands/
└── *.md
The CLI automatically detects which layout you are using. New projects created with piagentsync init will use the new layout if the vault contains a projects/ directory at the root; otherwise the legacy layout under agents/projects/ is used.
Migrating from legacy layout
If your vault still uses the legacy layout (agents/projects/ and agents/global/), you can continue using piagentsync without changes — the CLI automatically falls back to the legacy paths. To migrate to the new layout:
- Create a
projects/directory at the vault root. - Move each project from
agents/projects/<project>/toprojects/<project>/. - Move global agents from
agents/global/toconfig/agents/global/(create theconfig/directory as needed). - Optionally, move global commands from
commands/global/toconfig/commands/global/. - Remove the old
agents/projects/andagents/global/directories once you have verified the new layout works.
The legacy layout will remain supported for the foreseeable future.
Commands not yet documented or experimental
- watch: The
watchcommand is polling-based and checks the vault git repository for new commits every--intervalseconds (minimum 10). When it detects new commits, it determines affected projects and prints a message indicating which projects were synced. Note: the watcher currently prints which projects are affected and contains a TODO placeholder in the code where a full sync could be triggered. We therefore markwatchas experimental until the automatic sync implementation is finished.
Contributing
Development setup:
uv sync
uv run pytest
Lint and format:
uv run ruff check src/ tests/
uv run ruff format src/ tests/
Type checking (MyPy)
We use strict mypy checks for the codebase. To run type checking locally:
uv run mypy src/ tests/ --strict
Notes:
- The repository includes a
py.typedmarker so the package is PEP-561 compatible. - Pre-commit runs
ruff(format + lint). Running mypy in pre-commit was avoided due to isolated pre-commit environments — instead run mypy manually or add it to CI for consistent enforcement.
Test files to check
If you want to run the tests that validate sync and diff behavior locally, run:
- tests/test_sync.py::test_sync_entries_workspace_wins_writes_to_vault
- tests/test_cli.py::test_status_diff_shows_absolute_paths_and_legend
All commits follow Conventional Commits.
Publishing (maintainers)
This repository uses GitHub Actions for CI and automated releases.
One-time PyPI setup (trusted publisher)
-
Enable OIDC on PyPI for the repository:
- Publisher: GitHub Actions
- Repository owner:
Piwero - Repository name:
piagentsync - Workflow filename:
release.yml - Environment name: (leave blank)
-
The Release workflow handles everything: bump version, create tag, build, publish to PyPI, and create a GitHub Release.
Release process
git push → ci.yml passes
→ trigger release.yml (choose MAJOR/MINOR/PATCH/RC)
→ tests re-run → changelog generated → version bumped → tag pushed
→ GitHub Release created with assets → package published to PyPI
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file piagentsync-2.0.0.tar.gz.
File metadata
- Download URL: piagentsync-2.0.0.tar.gz
- Upload date:
- Size: 73.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5cca4d224adebbe4dc56d3cb47e0dcf96d2cf2a9a17f65d50741c0ac636c2e3
|
|
| MD5 |
9efcc3ac327d30ac55b20c5707adea89
|
|
| BLAKE2b-256 |
4ab29313a70723516e5a374d7467c886fc67cad17e46a573f8562269973fac00
|
File details
Details for the file piagentsync-2.0.0-py3-none-any.whl.
File metadata
- Download URL: piagentsync-2.0.0-py3-none-any.whl
- Upload date:
- Size: 25.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d92e9b6fa6c996247e4d380b7e7cc2bef2eac3f598232b9bc0de36c632d3f42
|
|
| MD5 |
d3398bab4567bbd074cc717697fe84b2
|
|
| BLAKE2b-256 |
efbf3a67d2435693f6919434c744276a23f0809125df3f85674e06bf38d0d4e9
|