sabuk (사북, n.) ① the pivot rivet that holds the blades of scissors or the ribs of a folding fan together at their crossing point ② figuratively, the most essential part of a thing
Real-time, bidirectional sync between your spec documents and issue trackers.
In spec-driven development, the plan/spec file is the sabuk of your project — the pivot everything else hinges on. sabuk treats your markdown spec as that pivot and keeps the issue tracker moving with it like the two blades of a pair of scissors. Edit the spec and the issues update; close an issue and the spec reflects it.
- The spec is the single source of truth — your plan.md is the issue list. No more maintaining two places that slowly drift apart.
- Real-time, bidirectional sync — changes propagate immediately, not at commit/push time. Tracker-side changes (close, assignee, labels) flow back into the markdown.
- Plain markdown — no proprietary format or mandatory frontmatter. sabuk understands your existing spec/plan file structure.
# Install
bun add -g @pleaseai/sabuk # or npm i -g @pleaseai/sabuk
# Initialize in your repo (includes GitHub auth)
sabuk init
# Link a plan file to GitHub Issues
sabuk link docs/plan.md
# Start watching for changes and syncing in real time
sabuk watchTask items in docs/plan.md are now created as GitHub Issues, and edits on either side propagate to the other.
docs/plan.md ←──── sabuk ────→ Issue Tracker
(spec: the pivot) (GitHub Issues)
sabuk linkparses task blocks in your markdown (checklists, sections) and creates a 1:1 mapping to issues.- Mappings are stored in
.sabuk/and committed, so the whole team shares them. sabuk watch(local) or sabuk Cloud (webhooks) detects changes on both sides and applies them immediately.- On conflict, the spec file wins. It's the pivot, after all.
| Command | Description |
|---|---|
sabuk init |
Initialize the repo and authenticate with the tracker |
sabuk link <file> |
Link a markdown file to the tracker |
sabuk sync |
One-off manual sync |
sabuk watch |
Watch file/tracker changes in real time |
sabuk status |
Show mapping state and drift |
sabuk unlink <file> |
Unlink (issues are kept) |
By default, one checklist item = one issue.
## Authentication
- [ ] Implement OAuth login <!-- sabuk:issue#42 -->
- [x] Session token refresh logic <!-- sabuk:issue#43 -->- The trailing comment is a mapping anchor managed automatically by sabuk — you never need to touch it.
- Section headings can map to issue labels/milestones (see
sabuk.config.ts). - Checking
[x]↔ closing the issue syncs in both directions.
sabuk.config.ts:
import { defineConfig } from '@pleaseai/sabuk'
export default defineConfig({
tracker: 'github', // supported today; asana and linear coming
repo: 'pleaseai/example',
files: ['docs/**/*.plan.md'],
conflict: 'spec-wins', // 'spec-wins' | 'tracker-wins' | 'manual'
labels: { fromHeadings: true },
})- Bidirectional sync with GitHub Issues
- Linear support
- Asana support
- sabuk Cloud — always-on webhook sync, team dashboard
- Link PRs to spec items (akwi integration)
sabuk is part of the Please Tools ecosystem by Passion Factory. Our philosophy: specs made explicit, implementation made autonomous, verification made automatic. sabuk is the pivot rivet that keeps specs and work tracking from drifting apart. Combined with akwi (Merge Queue + AI Conflict Resolve), spec-please, and work-please, it completes the full issue → worktree → PR → merge cycle.
Issues and PRs are welcome.
git clone https://github.com/pleaseai/sabuk
cd sabuk && bun install && bun test