Skip to content

Module System

HQ uses a module system to pull external git repositories into an HQ instance. Each module maps a repository (or subdirectories within one) to one or more destinations inside the HQ directory. A declarative manifest lists the modules, and a lock file pins them to specific commits for reproducible syncs.

The module system is implemented in hq-cli (hq modules …). Content packs installed with hq install are recorded in the same manifest.

Manifest

On a fresh HQ the manifest lives at modules/modules.yaml. An existing flat modules.yaml at the HQ root is still read if present. The manifest holds a version and an array of module entries:

version: '1'
modules:
- name: ralph-methodology
repo: https://github.com/indigoai-us/ralph-methodology
branch: main
strategy: link
paths:
- src: docs
dest: knowledge/public/Ralph
- name: knowledge-workers
repo: git@github.com:indigoai-us/knowledge-workers.git
strategy: merge
paths:
- src: .
dest: knowledge/public/workers

Fields (git-repo modules)

FieldRequiredDescription
nameyesUnique module identifier
repoyesGit URL (https:// or git@)
branchnoBranch to track (defaults to main)
strategyyeslink, merge, or copy
pathsyesArray of { src, dest } mappings. src is a path inside the module repo; dest is a path relative to the HQ root
accessnopublic, team, or role:<name>

Entries with strategy: package are content packs written by hq install. They carry source, version, installed_at, and (for git sources) resolved_sha instead of repo and paths. hq modules sync skips them; packs are wired by the pack installer.

Lock File

modules.lock at the HQ root maps each module name to a commit SHA:

version: '1'
locked:
ralph-methodology: abc123def456...
knowledge-workers: 789fed321cba...

hq modules sync rewrites the lock with the commit each module ended on. hq modules sync --locked checks out the recorded commits instead of pulling the branch head, so syncs are deterministic across machines.

Strategies

The link strategy creates relative symlinks from each dest to the matching src inside the module clone at modules/<name>/.

knowledge/public/Ralph → ../../modules/ralph-methodology/docs
  • An existing symlink at dest is replaced.
  • A real file or directory at dest is left alone, and the CLI prints a warning.
  • Symlinks are relative, so they keep working if the whole HQ directory moves.

link is the default for hq modules add.

Merge

The merge strategy copies files from the module into dest and records a SHA256 hash per file in .hq-sync-state.json at the HQ root.

For each file:

  1. Hash the source file.
  2. If the destination exists, hash it and look up the hash recorded at the last sync.
  3. If the destination changed since the last sync and differs from the source, skip it as a conflict. Local edits are kept.
  4. Otherwise copy the file and record the new hash.

Use merge when the destination needs to be editable locally but should still receive upstream updates.

Copy

copy is accepted in the manifest but currently runs the merge implementation.

Commands

hq modules add <repo-url>

Adds an entry to the manifest. It does not clone anything; run hq modules sync afterward.

OptionDefaultDescription
--as <name>Repo name from the URLModule name
--branch <branch>mainBranch to track
--strategy <strategy>linklink, merge, or copy
--path <src:dest>.:workers/<name>Path mapping (repeatable)

The URL must start with https:// or git@. The default name is the last path segment with any .git suffix removed (for example https://github.com/indigoai-us/knowledge-workers.git becomes knowledge-workers).

hq modules sync

For each git-repo module in the manifest:

  1. Clone the repo into modules/<name>/, or fetch it if the clone exists.
  2. Pull the tracked branch, or check out the locked commit with --locked.
  3. Apply the module’s strategy to each path mapping.
  4. Record the resulting commit in modules.lock.
Terminal window
hq modules sync # sync to the latest commit on each branch
hq modules sync --locked # sync to the commits recorded in modules.lock

The first run adds modules/ to .gitignore.

hq modules list

Lists every module in the manifest with its repo or source, strategy, and current commit.

Terminal window
hq modules list

hq modules update [module-name]

Fetches and pulls the module clone, then writes the new HEAD commit to modules.lock. With no name, all modules are updated. It does not re-apply strategies; run hq modules sync --locked afterward to apply the new commits.

Terminal window
hq modules update ralph-methodology
hq modules update

Utilities

findHqRoot() walks up from the current directory until it finds a .claude/ or workers/ directory, so module commands work from any subdirectory of HQ.

parseRepoName() extracts the module name from an HTTPS or SSH GitHub URL.

Adding a Module

Terminal window
hq modules add https://github.com/indigoai-us/knowledge-design-styles \
--as knowledge-design-styles \
--path "docs:knowledge/public/design-styles"
hq modules sync
qmd update

hq modules sync adds modules/ to .gitignore, so the clones (and a manifest stored at modules/modules.yaml) are not tracked by HQ git.