Skip to main content

Share documentation files between Git repositories

Project description

tlc-shared-docs

Share documentation files between Git repositories. Pull files from a remote repo into your local docs tree, or push local files back — all configured through a single shared.json.

Installation

pip install tlc-shared-docs

Quick Start

1. Create the config

Create docs/source/shared/shared.json in your project:

{
  "source_repo": {
    "url": "https://github.com/your-org/shared-docs.git",
    "branch": "main"
  },
  "shared_files": [
    {
      "remote_path": "guides/getting-started.md",
      "local_path": "getting-started.md",
      "action": "get"
    },
    {
      "remote_path": "guides/api-reference.md",
      "local_path": "api-reference.md",
      "action": "push"
    }
  ]
}

2. Pull shared files

tlc-shared-docs get

This fetches every file with "action": "get" from the remote repo and saves it locally.

3. Push local files

tlc-shared-docs push

This pushes every file with "action": "push" to the remote repo. If a remote file has changed since you last pulled, the command aborts with a conflict warning. Use --force to overwrite:

tlc-shared-docs push --force

4. Preview changes

Both commands support --dry-run:

tlc-shared-docs get --dry-run
tlc-shared-docs push --dry-run

5. Clean up stale files

If the central repo removes files from your share list, the old copies remain on disk. Use --clean to remove them:

# Remove files no longer in the share list
tlc-shared-docs get --clean

# Preview what would be removed
tlc-shared-docs get --clean --dry-run

# Combine with project selection
tlc-shared-docs get -p agent-coder --clean

With --clean, only files inside the project subdirectory (or shared root for legacy configs) are scanned. Internal files (.gitignore, shared.json, .shared-hashes.json) are never removed.

Configuration Reference

shared.json

Field Description
source_repo.url Git clone URL for the shared repo
source_repo.branch Branch to pull from / push to (default: main)
shared_files[].remote_path Path to the file in the remote repo (supports glob patterns for get)
shared_files[].local_path Local destination path (relative to docs/source/shared/)
shared_files[].action get (pull from remote) or push (push to remote). Default: get

Wildcard / glob patterns

The remote_path field supports glob patterns for get actions, allowing you to fetch multiple files with a single entry:

{
  "remote_path": "stories/**/*",
  "local_path": "stories",
  "action": "get"
}

Supported patterns:

  • * — matches any file in a single directory (e.g., docs/*.md)
  • **/* — matches files recursively across directories (e.g., stories/**/*)
  • ? — matches a single character (e.g., chapter?.md)
  • [seq] — matches any character in the set (e.g., file[0-9].txt)

When using globs, local_path acts as the destination directory. Matched files preserve their directory structure relative to the non-glob prefix of the pattern. For example:

Pattern Matched remote file local_path Written to
stories/**/* stories/ch1/intro.md mystories mystories/ch1/intro.md
Global/*.gitignore Global/Vim.gitignore ignores ignores/Vim.gitignore
*.md README.md docs docs/README.md

Local path resolution

  • Relative paths (e.g., guide.md) resolve relative to docs/source/shared/.
  • Absolute paths (starting with /, e.g., /src/docs/guide.md) resolve relative to the project root.

Git ignore

On first run, tlc-shared-docs get creates docs/source/shared/ with a .gitignore that tracks only shared.json — all fetched files are ignored so they don't bloat your repo.

The auto-generated docs/source/shared/.gitignore contains:

# Auto-generated by tlc-shared-docs
# Ignore all fetched shared files; only track the config
*
!.gitignore
!shared.json

This means:

  • shared.json is committed to your repo (so teammates share the same config)
  • All fetched/pushed doc files are ignored locally
  • The .gitignore itself is also tracked

Versioning specific shared files in your own repo

The .gitignore is written once and never overwritten by tlc-shared-docs. You can edit it freely to commit specific shared files to your own repo.

For example, to version-control getting-started.md and everything under guides/ while still ignoring everything else:

# Auto-generated by tlc-shared-docs
# Ignore all fetched shared files; only track the config
*
!.gitignore
!shared.json

# Files I want to version in THIS repo:
!getting-started.md
!guides/
!guides/**

This is useful when your team wants certain shared docs to appear in your repo's git history — for example, files that are reviewed during PRs or that tools like GitHub Pages need to find in the repository.

Central mode

Central mode lets an architecture repo control what documentation each consumer repo receives. The consumer's shared.json just points at the source repo with "mode": "central" — the architecture repo decides the rest.

Setting up central mode? See README_CENTRAL.md for a detailed walkthrough covering architecture repo setup, per-consumer config files, identity detection, permissions, and the full end-to-end flow.

Auto-uploading new files (central mode)

When running in central mode, consumer repos can automatically upload new files to the shared repo. The central config controls which paths are allowed:

{
  "shared_files": [
    { "remote_path": "guides/intro.md", "local_path": "intro.md", "action": "get" }
  ],
  "uploads": {
    "allowed": true,
    "paths": [
      "contributions/**/*.md",
      "images/*.png"
    ]
  }
}
Field Description
uploads.allowed Set to true to enable auto-upload for this repo
uploads.paths Glob patterns for permitted remote paths (supports *, **, ?)

How it works

  1. Place new files anywhere under docs/source/shared/ in your local repo.
  2. Run tlc-shared-docs push. The tool automatically scans for files that are not already listed in shared_files.
  3. Each new file's path (relative to docs/source/shared/) is checked against the uploads.paths patterns.
    • Permitted files are included in the push commit.
    • Denied files produce a DENIED: warning and are skipped.
  4. Use --dry-run to preview which files would be uploaded or denied.
# Preview what would be uploaded
tlc-shared-docs push --dry-run

# Push configured files + upload new ones
tlc-shared-docs push

# Force-push (skip conflict check)
tlc-shared-docs push --force

Note: Auto-upload only works in central mode. In local mode, add new entries directly to your shared.json shared_files list.

Multi-project configs

If your repo participates in multiple architecture projects (e.g., auth, events, agent-coder), you can define them all in a single shared.json and select which one to use at runtime:

{
  "projects": {
    "auth": {
      "source_repo": { "url": "https://github.com/your-org/tlc-auth-arch.git" },
      "mode": "central"
    },
    "events": {
      "source_repo": { "url": "https://github.com/your-org/tlc-events-arch.git", "branch": "dev" },
      "mode": "central"
    },
    "agent-coder": {
      "source_repo": { "url": "https://github.com/your-org/agent-coder.git" },
      "mode": "central"
    }
  },
  "default_project": "agent-coder"
}

Each project entry supports the same fields as the legacy single-source format (source_repo, mode, shared_files, uploads).

Usage

# See what projects are available
tlc-shared-docs list

# Pull docs for a specific project
tlc-shared-docs get --project agent-coder
tlc-shared-docs get -p auth

# Uses default_project when --project is omitted
tlc-shared-docs get

# Push works the same way
tlc-shared-docs push -p events --dry-run

The list command shows all available projects with their source URLs, branches, and modes — useful when you don't know the exact project name.

Field Description
projects.<name> A named project entry (same schema as legacy root config)
default_project Project to use when --project is not specified

If no --project flag is given and no default_project is set, the command exits with an error listing available projects.

Automatic file isolation

In multi-project mode, each project's files are automatically placed into a subdirectory named after the project. You don't need to manually prefix local_path — it's handled for you:

docs/source/shared/
├── shared.json
├── auth/              ← files from the "auth" project
│   └── guide.md
├── events/            ← files from the "events" project
│   └── architecture.md
└── agent-coder/       ← files from the "agent-coder" project
    └── spec.md

For example, if the central config for the agent-coder project defines "local_path": "spec.md", the file is written to docs/source/shared/agent-coder/spec.md. Absolute paths (starting with /) bypass this prefix and resolve from the project root as usual.

Project name rules

Project names must be valid folder names: alphanumerics, hyphens, underscores, and dots, starting with a letter or digit. Invalid names (e.g., ../escape, names with spaces or special characters) are rejected at config load time.

Backward compatibility: The legacy single-source format (with source_repo at the root) still works exactly as before — no prefixing, no migration needed.

Claude agent skills

If you use Claude Code or other Claude-based agents, you can install a skill file that teaches the agent how to work with tlc-shared-docs in your repo.

Available skills

Skill For Description
player1 Architecture repos Teaches Claude how to manage .configs/, onboard consumers, and maintain shared docs
player2 Consumer repos Teaches Claude how to pull/push shared docs, use --dry-run, and contribute new files

You can install both in the same repo if it acts as both an architecture repo and a consumer.

Installing a skill

# For architecture repos (central/source of shared docs)
tlc-shared-docs init --skill player1

# For consumer repos (pull/push shared docs from an arch repo)
tlc-shared-docs init --skill player2

# Both can coexist in the same repo
tlc-shared-docs init --skill player1
tlc-shared-docs init --skill player2

This does two things:

  1. Writes the skill instructions to .claude/tlc-shared-docs-<skill>.md
  2. Adds a generic reference block to CLAUDE.md (with HTML comment markers) that directs Claude to read all installed skill files

Re-running init always overwrites the skill file with the latest content and replaces the CLAUDE.md block in-place — safe to run repeatedly.

When does Claude use the skill?

Claude reads CLAUDE.md at the start of every conversation. The reference block tells it to read all .claude/tlc-shared-docs-*.md files whenever you mention:

  • shared docs / shared documents / shared files
  • document sharing / doc sharing / doc sync
  • .configs/ / consumer configs / architecture docs
  • tlc-shared-docs

No special syntax needed — just talk naturally about shared docs and Claude will know what to do.

If both player1 and player2 are installed, Claude reads both and asks for clarification when it's ambiguous whether you mean docs managed by this repo or consumed from a remote.

Requirements

  • Python 3.9+
  • Git installed and on PATH
  • Valid Git credentials for the source repo

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tlc_shared_docs-1.1.38.tar.gz (33.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tlc_shared_docs-1.1.38-py3-none-any.whl (34.2 kB view details)

Uploaded Python 3

File details

Details for the file tlc_shared_docs-1.1.38.tar.gz.

File metadata

  • Download URL: tlc_shared_docs-1.1.38.tar.gz
  • Upload date:
  • Size: 33.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.13.6 Windows/11

File hashes

Hashes for tlc_shared_docs-1.1.38.tar.gz
Algorithm Hash digest
SHA256 9928ffd9b71656c5330011a5d2694c18b7cb8504242e85b4e07c3c425219c356
MD5 04e5a9148693371ff971f1ee59ac9b9b
BLAKE2b-256 73273ffc141b7d6942cef368ad5ae15c86d61f1acb257cfb0aee3e06760795e0

See more details on using hashes here.

File details

Details for the file tlc_shared_docs-1.1.38-py3-none-any.whl.

File metadata

  • Download URL: tlc_shared_docs-1.1.38-py3-none-any.whl
  • Upload date:
  • Size: 34.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.13.6 Windows/11

File hashes

Hashes for tlc_shared_docs-1.1.38-py3-none-any.whl
Algorithm Hash digest
SHA256 7422ad9bb33e6ae6c1e4dc3a2ac011e9f8da0129d0be54c2c4fb113a0a84c7ea
MD5 79aa1a2b1146204d0952f8863aeed7a1
BLAKE2b-256 22e4afc01ef2ebfa46db0409804469e073d1f86e0d25821c537726fec8c56464

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page