Embedder is a dependency-style updater for embedded text fragments.
It is meant for shared instructions, policies, documentation fragments, and other text blocks that must be materialized inside many repositories while still having one upstream source of truth.
The core use case is agent instructions such as shared AGENTS.md sections:
the consuming repository keeps a local copy that agents can read without network
access, and Embedder periodically opens pull requests when the upstream fragment
changes.
Embedder treats a fragment embedded inside any text file as a dependency.
consumer text file
contains embedded block marker
points to GitHub repository + ref + file path
Embedder fetches the file at that ref via the GitHub contents API
replaces only the managed block body
opens a pull request
This is intentionally not a project template manager. Embedder owns only the marked blocks, not the surrounding file.
Managed blocks use one-line markers:
<!-- embedder github.com/OWNER/REPO@v0.3.0:path/to/file.md -->
managed text goes here
<!-- /embedder -->The closing marker is always <!-- /embedder -->. Everything between the
markers is managed by Embedder. Everything outside is local to the consuming
repository.
Auto-latest — omit the tag to always track the latest release. The marker stays tagless; no version is written back, so there are no circular update loops:
<!-- embedder github.com/OWNER/REPO:path/to/file.md -->Pinned — include a semver tag to freeze the content at a specific release. Embedder never bumps a pinned marker automatically:
<!-- embedder github.com/OWNER/REPO@v0.3.0:path/to/file.md -->Branch — include a non-semver ref to track a branch or commit. Content is re-fetched on every update run; the marker ref is never changed:
<!-- embedder github.com/OWNER/REPO@main:path/to/file.md -->The file path is relative to the repository root and may include subdirectories:
<!-- embedder github.com/OWNER/REPO@v0.3.0:docs/fragments/policy.md -->Embedder fetches files directly from a GitHub repository's file tree using the GitHub contents API. Any file committed at the target ref is a valid fragment source — no need to attach files as release assets.
Embedder publishes its own introductory fragments under the fragments/
directory:
fragments/embedder-for-readmes.md
fragments/embedder-for-agents.md
These explain managed blocks to people and coding agents. Consumers can embed
them in README or AGENTS.md files to make the source-repository workflow
explicit.
Auto-latest markers resolve to the latest GitHub Release. GitHub prereleases are not considered latest releases. Publish normal releases when consumers should receive updates.
Embedder does not implement major/minor/patch update strategies or version constraints. If a fragment needs fundamentally different behavior, publish it under a different file path instead of relying on compatibility semantics.
Fragment sources may be public or private.
Public fragment sources can be fetched without authentication. Private repositories require a token with read access to the source repository.
This allows open source tooling in rubykatzen/embedder while keeping
organization-specific agent policies in private repositories.
Install from the repository checkout:
pip install -e .Commands:
embedder scan
embedder check
embedder update
embedder doctorembedder scan finds all managed blocks in text files and prints their source
repository, ref, file path, and containing file.
embedder check resolves each block's ref and exits non-zero when updates are
available. Auto-latest and branch markers are not reported as pending updates by
check; they are refreshed unconditionally by update.
embedder update fetches the current file for each managed block and replaces
only the managed body. The marker ref is preserved as-is; pinned tags are never
bumped automatically.
embedder doctor checks local prerequisites such as GitHub CLI availability and
authentication.
All commands that inspect or change managed blocks accept optional file or directory paths. When no path is provided, Embedder scans the current directory.
Use --json with scan, check, update, or doctor for machine-readable
output.
Add this workflow to the consuming repository to check for fragment updates daily and on demand:
name: Update embedded fragments
on:
schedule:
- cron: "0 3 * * *"
workflow_dispatch:
jobs:
update:
uses: rubykatzen/embedder/.github/workflows/update-fragments-shared.yml@v0When updates are available, Embedder opens a pull request:
## Embedded fragment updates
| File | Source | Asset | Old | New |
|---|---|---|---:|---:|
| AGENTS.md | dupmachine/agent-guidelines | agent-message-prefix.md | v0.3.0 | v0.4.0 |Repositories can rely on normal CI and automerge rules to land these PRs automatically.
Pass paths to limit the scan to specific files or directories:
jobs:
update:
uses: rubykatzen/embedder/.github/workflows/update-fragments-shared.yml@v0
with:
paths: AGENTS.md docs/Pass token to access fragments from private source repositories:
jobs:
update:
uses: rubykatzen/embedder/.github/workflows/update-fragments-shared.yml@v0
secrets:
token: ${{ secrets.FRAGMENT_SOURCE_TOKEN }}Embedder releases are cut with the rubykatzen/releaser CLI. Run from inside this repository:
releaser patch # or: releaser minor / releaser majorThe CLI verifies that CI is green on origin/main, calculates the next version,
dispatches prepare-release.yml, watches it run, then opens a release/vX.Y.Z
PR and enables auto-merge. publish-release.yml fires automatically once the PR
merges and creates the annotated tag, GitHub Release, and fragment release
assets using .github/actions/upload-fragments.
Check release readiness without triggering anything:
releaser status
releaser patch --dry-runInstall the CLI:
brew tap rubykatzen/tap && brew install releaser- Works with arbitrary text files, not only Markdown.
- Owns only explicitly marked blocks.
- Fetches files via the GitHub contents API; any file in the repo tree is a valid fragment source.
- Supports public and private source repositories.
- Does not execute code from source repositories.
- Does not perform dependency solving or SemVer compatibility filtering.
- Keeps fragments materialized locally so agents can read them without network access.
The local CLI supports scan, check, update, and doctor. The reusable
GitHub Actions workflow is available at
.github/workflows/update-fragments-shared.yml.