Skip to main content

SpecSync

Selective Markdown sync between your repo and any workspace folder.

SpecSync is a lightweight Python CLI that bridges your repo's ignored specs/ folder and an external workspace (e.g. an Obsidian vault, a Hugo content directory, or any notes folder). It lets you pull only the Markdown files you choose (via frontmatter), keep them in sync in both directions, and work seamlessly with AI coding tools — so your specs stay organized without cluttering your codebase.


Features

  • Frontmatter filtering – pull only notes with expose: true (and matching project: if set).
  • Two-way sync – pull specs from workspace → repo or push changes back from repo → workspace.
  • Safe by default – interactive prompts for conflicts, --force to skip prompts.
  • Flexible – works with any folder structure, not tied to Obsidian.
  • Git-like workflow – familiar pull and push commands.

Documentation

📚 Read the full documentation


Quick Start

Install with pipx or uv:

pipx install specsync
# or
uv tool install specsync

Set your workspace location using environment variables or direnv:

# Option 1: Direct export (temporary, current session only)
export SPECSYNC_WORKSPACE_ROOT="~/Documents/Obsidian"

# Option 2: Using direnv (recommended for project-specific config)
# Copy the example file and customize:
cp .envrc.example .envrc
# Edit .envrc with your workspace path, then:
direnv allow

Initialize in a repo (creates specs/ folder and updates pyproject.toml):

specsync init

Pull specs from your workspace into the repo's specs/ folder:

specsync pull

Push changes from the repo back to your workspace:

specsync push

Show current configuration:

specsync info

Configuration

SpecSync looks for configuration in this order:

  1. Command-line flags
  2. Environment variables (e.g., SPECSYNC_WORKSPACE_ROOT)
  3. pyproject.toml under [tool.specsync]

Using direnv for Local Configuration

For project-specific environment variables, create a .envrc file in your repo root:

# .envrc
export SPECSYNC_WORKSPACE_ROOT="/Users/you/Library/Mobile Documents/iCloud~md~obsidian/Documents/YourVault"
export SPECSYNC_REPO_SPECS_DIR="specs"
export SPECSYNC_PROJECT_NAME="my-project"

Then activate it:

direnv allow

Add .envrc to your .gitignore to keep local paths private:

echo ".envrc" >> .gitignore

Project Configuration

Example pyproject.toml:

[tool.specsync]
workspace_subdir = "specs"    # Subdirectory in workspace
repo_specs_dir = "specs"      # Directory in repo (git-ignored)
project_name = "my-project"   # Optional, auto-detected if not set

[tool.specsync.filter]
require_expose = true         # Only sync files with expose: true
match_project = true          # Only sync files matching project name

Example Frontmatter

Mark specs for syncing with frontmatter:

---
expose: true                  # Required for syncing
project: my-project          # Optional, must match if match_project is true
title: GPU Crash Fix
status: draft
---

# GPU Crash Investigation
...

Only notes with expose: true (and matching project when configured) are synced.


License

MIT

Metadata

Release files for specsync 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for specsync 0.1.0
File Size Uploaded
specsync-0.1.0.tar.gz 10.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for specsync 0.1.0
File Interpreter ABI Platform
specsync-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.2 kB

Release files / specsync-0.1.0.tar.gz

Download URL specsync-0.1.0.tar.gz
Size 10.9 kB
Tags Source
SHA-256 checksum
How to use checksums
7c48ec38870dfe7bb09b71039b05926a5a20620b1961e18fb465e5f0e30ec4d4
BLAKE2b-256 checksum
How to use checksums
7a3488b3c96a9cfe727836eaadd98e5cb05b6b67d2c12b5d0f699fd264297332
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.22

Release files / specsync-0.1.0-py3-none-any.whl

Download URL specsync-0.1.0-py3-none-any.whl
Size 15.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
95aa25efd94ac127ca29ee02d352f8ebdf807614b636f7b383c93ebd6f8212dc
BLAKE2b-256 checksum
How to use checksums
b3a2037c04d3bf48de38aabd6d0fdea2020653f8efd77b487a085402b75dee51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.22

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page