Arvore Repo Hub

Scan

As your workspace grows, new repos get cloned but not always added to your config file. Skills, agents, and steering files get created inside editor-specific folders but never promoted to the canonical skills/, agents/, or steering/ directories. MCP servers get added directly to editor configs without being declared in your hub config. The hub scan command finds all of them for you.

What it does

hub scan performs three passes:

1. Unregistered repositories

Walks the workspace root looking for directories that contain a .git folder but aren’t listed in your config. For each one it:

  1. Detects the tech stack by checking for framework-specific files (mix.exs → Elixir, nest-cli.json → NestJS, next.config.* → Next.js, etc.)
  2. Reads the git remote URL
  3. For YAML configs: offers to add them to hub.yaml
  4. For TypeScript configs: shows the suggested repo.*() helper call to add manually

2. Unsynced assets

Scans editor-specific directories (.kiro, .cursor, .opencode, .claude) for skills, agents, and steering files that don’t exist in the canonical hub folders (skills/, agents/, steering/). For each unsynced asset it:

  1. Identifies the type (skill, agent, or steering) and source editor
  2. Offers to copy them to the canonical location
  3. Strips front-matter during the copy so files are editor-agnostic

This ensures that assets created in one editor are available to all editors after the next hub generate.

3. Unsynced MCP servers

Scans editor-specific MCP config files for servers not declared in your hub config:

EditorConfig fileKey
Cursor.cursor/mcp.jsonmcpServers
Kiro.kiro/settings/mcp.jsonmcpServers
Claude Code.mcp.jsonmcpServers
OpenCodeopencode.jsonmcp

MCP servers found in editor configs but missing from your hub config are reported so you can add them manually (since MCPs require package, url, or image fields that can’t be inferred).

Usage

# Interactive — choose which repos and assets to sync
hub scan

# Auto-add and sync everything without prompting
hub scan --yes

# Check only — exit 1 if unsynced repos or assets are found
hub scan --check
FlagDescription
-y, --yesAdd all found repos and sync all assets without prompting
--checkCheck for unsynced repos and assets without prompting. Exits with code 1 if any are found, 0 if all synced. Useful in CI and pre-commit hooks.

Example

$ hub scan

Scanning for unregistered repositories...

Found 2 unregistered repo(s):

  notifications-service (nestjs)
  admin-dashboard (nextjs)

? Select repos to add to hub.yaml:
  ◉ notifications-service (nestjs)
  ◉ admin-dashboard (nextjs)

Added 2 repo(s) to hub.yaml.

Scanning for unsynced skills, agents, steering, and MCPs...

Found 4 unsynced asset(s):

  my-custom-skill (skill from .cursor)
  pr-review.md (agent from .kiro)
  code-standards.md (steering from .cursor)
  my-new-mcp (mcp from .kiro)

? Select assets to sync to canonical folders:
  ◉ my-custom-skill (skill from .cursor)
  ◉ pr-review.md (agent from .kiro)
  ◉ code-standards.md (steering from .cursor)
  ◉ my-new-mcp (mcp from .kiro)

  Synced skill: my-custom-skill (from .cursor)
  Synced agent: pr-review.md (from .kiro)
  Synced steering: code-standards.md (from .cursor)
  MCP 'my-new-mcp' found in .kiro but not in hub.yaml — add it manually.
Synced 4 asset(s).

Run hub generate to update editor configs.

How it works

Repository scanning

For YAML configs, the scan preserves your existing hub.yaml formatting. Instead of parsing and re-serializing the YAML (which would lose comments and ordering), it finds the end of the repos: array and inserts new entries as raw text.

For TypeScript configs (hub.config.ts), the scan cannot auto-modify the file. Instead, it prints the suggested repo.*() helper call for each detected repo:

Found new repo: payments (nestjs)
  → Add to hub.config.ts: repo.nestjs("payments", "git@github.com:company/payments.git")

Each added repo (YAML) gets the minimal fields:

  - name: notifications-service
    path: ./notifications-service
    url: git@github.com:company/notifications-service.git
    tech: nestjs

Asset syncing

For each editor directory, the scan checks:

SourceAsset typeCanonical destination
.kiro/skills/, .cursor/skills/, .opencode/skills/, .claude/skills/Skillskills/<name>/
.kiro/agents/, .cursor/agents/, .opencode/agents/, .claude/agents/Agentagents/<name>.md
.kiro/steering/Steeringsteering/<name>.md
.cursor/rules/ (.mdc files)Steeringsteering/<name>.md
.opencode/rules/Steeringsteering/<name>.md
.cursor/mcp.json, .kiro/settings/mcp.json, .mcp.json, opencode.jsonMCPReported only (add to hub.yaml manually)

Auto-generated files like orchestrator.md and hub-docs are skipped.

After scanning, run hub generate to regenerate editor configs with the new repos and assets.

Tech detection

File detectedTech assigned
mix.exselixir
next.config.js/ts/mjsnextjs
nest-cli.jsonnestjs
angular.jsonangular
svelte.config.jssvelte
nuxt.config.ts/jsvue
go.modgo
Gemfilerails
manage.pydjango
package.json (fallback)react

Ignored directories

The scan skips common non-repo directories: node_modules, dist, build, .cache, tasks, agents, skills, memories, docs, scripts, and editor config folders (.cursor, .kiro, .vscode, etc.).