English | 日本語
Shared configurations for OzzyLabs repositories.
dist/ -> Distributed to every repo
.claude/
rules/ -> Rules
settings.json -> Allowed tools and permissions
.devcontainer/ -> Devcontainer config
.gemini/
settings.json -> Gemini CLI config (loads AGENTS.md)
.github/
workflows/ -> PR title & branch name validation
ISSUE_TEMPLATE/ -> Issue templates
pull_request_template.md
.vscode/ -> VS Code settings & extensions
lefthook-base.yaml -> Shared lefthook base config
lefthook.yaml -> Lefthook config extending shared base
.commitlintrc.yaml -> Commitlint config
.editorconfig -> Editor settings
.gitattributes -> Line ending normalization
.mdformat.toml -> Markdown formatter config
.mise.toml -> Tool version management
trivy.yaml -> Trivy security scanner config
...
templates/ -> Scaffold-only files (copied manually for new repos, never synced)
AGENTS.md -> Shared AI agent instructions template
CLAUDE.md -> Claude Code specific config
sync.sh -> Sync script
sync-skills.sh -> @ozzylabs/skills adapter sync script (opt-in per consumer)
setup-repo.sh -> GitHub repository setup script
init-templates.sh -> Bootstrap templates with placeholder substitution + repo metadata
templates/ ships starter content that every repo customizes (project name, tech stack, available skills). It is intentionally outside dist/ so sync.sh never touches it — copy these files once when bootstrapping a new repo and edit in place.
Shared skills (.agents/skills/, .claude/skills/) are no longer distributed from this repo. They live in ozzy-labs/skills and are pulled into consumer repos via the @ozzylabs/skills Renovate preset (see ADR-0016).
End-to-end flow for a brand-new ozzy-labs repo. Each script ends with its own "Next steps" hint, so this list is mainly about the order. Detailed flags for each command live in the sections below.
-
Create the GitHub repo and clone it locally.
gh repo create ozzy-labs/<name> --public --description "..." gh repo clone ozzy-labs/<name> cd <name>
-
Apply ozzy-labs GitHub settings — merge rules (squash only), branch protection, security, Conventional Commits labels.
/path/to/commons/setup-repo.sh ozzy-labs/<name>
-
Sync shared config — distributes lefthook, mise, editorconfig, workflows, etc., and seeds
.commons/sync.yaml(including theskills_commit:/skills_adapters:opt-in stubs)./path/to/commons/sync.sh -y . -
Bootstrap templates — copies
AGENTS.md/CLAUDE.md, substitutes{{project_name}}/{{description}}placeholders, and applies the repo description + topics via the GitHub API in one shot./path/to/commons/init-templates.sh \ --name <name> \ --description "..." \ --topics ai,cli,multi-agent,... \ .
-
(Optional) Opt in to
@ozzylabs/skills— edit.commons/sync.yaml'sskills_commit:andskills_adapters:. The seeded comment in the file names the exactghcommand for fetching the SHA. Then runsync-skills.shagainst a local clone ofozzy-labs/skills. -
Add project-specific files (
package.json,tsconfig.json,src/, etc.) and editAGENTS.md/CLAUDE.mdto fill in tech stack and project specifics. -
Open the bootstrap PR. Direct push to
mainis blocked by the ruleset installed in step 2:git checkout -b chore/bootstrap git add . && git commit -m "chore: bootstrap repo" git push -u origin chore/bootstrap gh pr create --fill && gh pr merge --squash --delete-branch
# OzzyLabs Commons CLI
/path/to/commons/commons <command> [args]
# Commands:
# sync Sync shared files
# check Run health check
# setup Initialize repository
# skills Sync skills adapters
# init Bootstrap templates and metadata# Sync with interactive confirmation (shows diff for changed files)
commons sync /path/to/target-repo
# Sync without confirmation (overwrite all non-pinned changed files)
commons sync -y /path/to/target-repo
# Preview changes without copying
commons sync --dry-run /path/to/target-repo
# Check if files are in sync (for CI, exits 1 if out of sync)
commons sync --check /path/to/target-repoAll files use the same sync policy. In interactive mode, changed files show a diff and prompt for action: update (y), merge (m), skip (N), pin (pin), or update all remaining (all). Pinned files are skipped in all modes including -y. After sync, metadata is written to .commons/sync.yaml in the target repo.
# Run health check to verify compliance with OzzyLabs conventions
commons check /path/to/target-repoVerifies:
- All shared files are in sync.
- Presence of mandatory files (
LICENSE,AGENTS.md, etc.). - Presence of required markers in Markdown and YAML files.
- Security configurations (Lefthook, Gitleaks).
When a file is intentionally customized in a target repo, it can be pinned to prevent future syncs from overwriting it. Pin during interactive sync by choosing pin at the prompt, or edit .commons/sync.yaml directly.
Sync metadata lives in the consumer repo at .commons/sync.yaml. sync.sh reads and writes this single canonical path, and the Renovate preset (commons-sync.json's managerFilePatterns) tracks it for commit: field bumps.
The earlier .dev-config/sync.yaml path was supported as a temporary fallback during the migration documented in ADR-0014. All consumers have now completed the rename and the fallback has been removed.
Shared skills live in ozzy-labs/skills and are produced as per-agent adapter outputs under dist/{adapter-id}/. The first run of commons sync seeds .commons/sync.yaml with empty skills_commit: and skills_adapters: keys plus a comment naming the exact gh command for fetching the SHA — opt-in is then a matter of editing those keys in place. The seeded shape:
# Skills sync (opt-in). Add adapter ids to skills_adapters and a SHA
# to skills_commit. The skills repo's main HEAD SHA can be obtained via:
# gh api repos/ozzy-labs/skills/commits/main --jq .sha
skills_commit: ""
skills_adapters: []Once filled in, the metadata looks like:
# Tracked by Renovate via the @ozzylabs/skills preset
skills_commit: <40-char-sha>
# Opt-in per consumer (manual)
skills_adapters:
- claude-code # → .claude/skills/{name}/
- codex-cli # → .agents/skills/{name}/ + AGENTS.md snippet
- gemini-cli # → .gemini/settings.json + AGENTS.md snippet
- copilot # → .github/copilot-instructions.md snippetRunning sync-skills.sh against a repo with empty skills_adapters is non-fatal: it prints opt-in guidance (including the SHA fetch command) and exits 0, so the consumer's sync workflow keeps succeeding while the repo is still in opt-out state.
The consumer's sync workflow clones ozzy-labs/skills at skills_commit: and runs sync-skills.sh to apply the opted-in adapter outputs:
# Sync without confirmation (workflow use)
/path/to/commons/sync-skills.sh -y /path/to/skills/dist /path/to/target-repo
# Preview only
/path/to/commons/sync-skills.sh --dry-run /path/to/skills/dist /path/to/target-repo
# Check if files are in sync (CI, exits 1 if out of sync)
/path/to/commons/sync-skills.sh --check /path/to/skills/dist /path/to/target-repoSnippet targets (AGENTS.md, .github/copilot-instructions.md) must already contain the marker block — only the content between <!-- begin: @ozzylabs/skills --> and <!-- end: @ozzylabs/skills --> is replaced. templates/AGENTS.md ships with the marker block pre-installed, so new repos scaffolded from the template are ready for codex-cli / gemini-cli adapter opt-in without manual edits. commons check warns when the marker is missing from AGENTS.md so existing repos can be retrofitted before opt-in. Pinning a path in the metadata file's pinned: list (with a trailing / for whole directories) skips it across all adapters. Consumer-only skill directories under .claude/skills/ or .agents/skills/ are preserved.
# Configure GitHub repository settings
/path/to/commons/setup-repo.sh owner/repo
# Preview changes without applying
/path/to/commons/setup-repo.sh --dry-run owner/repoSets merge rules (squash only), branch protection (Rulesets), security settings, and Conventional Commits labels. See ADR-0004 for design decisions.
init-templates.sh copies templates/AGENTS.md and templates/CLAUDE.md into a target repo, substitutes {{project_name}} and {{description}} placeholders, and (when invoked with --description or --topics) applies the GitHub repo description and topics in one shot. It complements setup-repo.sh: that script handles ozzy-labs-wide GitHub settings, while this one handles per-repo bootstrap content.
# Full bootstrap (file ops + GitHub metadata)
/path/to/commons/init-templates.sh \
--name agentic-watch \
--description "Multi-agent CLI that watches blogs..." \
--topics ai,cli,multi-agent,claude-code,codex,gemini \
/path/to/agentic-watch
# Files only (no gh API calls)
/path/to/commons/init-templates.sh --name <name> --skip-gh-edit /path/to/repo
# Preview changes
/path/to/commons/init-templates.sh --name <name> --dry-run /path/to/repo--name is required. Existing AGENTS.md / CLAUDE.md files in the target are protected: the script aborts with a diff summary unless --force is passed. The repo for gh api is auto-detected from the target's origin remote, or pass --repo owner/repo to override.
Consumer repos get a workflow distributed at .github/workflows/sync-commons.yaml. It runs weekly (Monday 00:00 UTC) and on manual dispatch, checks the repo against the latest commons, and — if any non-pinned file diverges — runs sync.sh --yes and opens a pull request. Review and merge manually; the workflow never auto-merges.
First-time setup for a consumer repo:
- Run
sync.shmanually once to pick upsync-commons.yamlinto.github/workflows/ - The repo settings must allow creating PRs (already the case if
setup-repo.shwas run) - The weekly schedule takes over from the next Monday;
workflow_dispatchlets you trigger it on demand
As a lower-latency alternative to the weekly schedule, consumer repos can opt into the commons-sync Renovate preset. Renovate watches the commons main branch and opens a PR bumping the commit: field in .commons/sync.yaml whenever a new commit lands. Actual file materialisation remains the consumer workflow's job (it runs sync.sh --yes on the Renovate PR branch).
Consumer renovate.json:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>ozzy-labs/commons:commons-sync"]
}Design details are in ADR-0006. Consumer-side workflow integration is tracked by the Renovate PoC rollout (handbook#18 / handbook#42); until that lands, the scheduled workflow above is the supported path.
- Domain-specific skills and rules
- Customized files after initial setup (pinned to prevent overwrite)
- Default: Japanese
- Public files (e.g., README): English with Japanese version
- Commit messages: English
- PR title: English
- PR description: Japanese
Conventional Commits: <type>[optional scope]: <description>
Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore
GitHub Flow: main + feature branches (no direct push)
Naming: <type>/<short-description>
Title: Conventional Commits format
Merge: squash merge only, delete branch after merge