Sparse Document Hub CLI — repo level management for docs & personal playbook across projects.
Create a central my-stack-playbook or my-docuhub repo. Linked into every project via git submodule. Zero duplication.
Allow your agents to edit documents in .documents/ and use dh sync to keep the central hub updated.
Parent repository pointer updates are handled gracefully and do not require a remote.
dh init— add the dochub submodule + AGENTS.md instructionsdh sync— update & pull latest playbookdh update— non-destructive pulldh contribute— push new patterns back to the hubdh search- search your .documents using grepdh add-pattern <name>— create a new pattern template
- Node.js (for the CLI itself)
- Git (for submodule operations)
- SSH keys set up with GitHub (recommended) — or GitHub CLI (
gh) for HTTPS authentication
# Install globally from npm
npm install -g @ubuntupunk/dhdh init → sets up submodule + adds note to AGENTS.md
dh add-pattern foo → creates markdown with .md suffix, no need to add it.
dh sync
dh contribute "new setup"
dh search foo# SSH (recommended — requires SSH keys set up with GitHub)
export DOC_HUB_REPO="git@github.com:yourusername/my-stack-playbook.git"
# HTTPS alternative (requires gh auth login or a credential helper)
# export DOC_HUB_REPO="https://github.com/yourusername/my-stack-playbook.git"# Recommended Hub Structure (my-stack-playbook)
.documents/
├── README.md
├── core/
├── patterns/ ← your top skills & solutions
├── templates/
├── divergences/
└── decisions/This happens when using an HTTPS remote without a credential helper configured. Options:
- Switch to SSH (recommended): Set
DOC_HUB_REPOto an SSH URL (see above). - Use
gh: Rungh auth loginto authenticate, thengh auth setup-gitto configure git to use your token. - Use a PAT: Create a GitHub personal access token and use a credential helper like
git config --global credential.helper store.
You'll see something like:
→ git push origin main
Username for 'https://github.com':If dh sync is interrupted after committing local changes but before pushing, running it again is safe and idempotent. It will:
- Pull from remote (no-op if already up to date)
- Attempt to commit again — skips with "No changes in submodule" if nothing new
- Push any pending local commits in
.documents - Update and push the parent repo's submodule pointer
Alternatively, manually complete the interrupted push:
cd .documents && git push origin main
cd .. && git add .documents && git commit -m "chore: update pointer" && git pushI got tired of technical docs scattered across repos. Now everything lives in one place and is instantly available (and updatable) in every project.