Skip to content

Repositories

Repositories tell peppy where to look for nodes, launchers, and interfaces. When you run peppy repo refresh, peppy walks every configured repository and indexes:

  • Nodes, identified by filename: every peppy.json5 file is treated as a node config.
  • Launchers, identified by content: every .json5 file whose body declares peppy_schema: "launcher_v1" is treated as a launcher, regardless of its filename. The launcher is keyed by the file stem (e.g. openarm01_sim_teleop.json5 becomes the launcher named openarm01_sim_teleop).
  • Interfaces, identified by content: every .json5 file whose body declares peppy_schema: "interface_v1" is treated as an interface, regardless of its filename. An interface is a reusable contract of topics, services, and actions, keyed by the name:tag declared in its manifest; nodes reference interfaces by name:tag to declare conformance.

Out of the box, four repositories are configured:

  • nodes_hub (https://github.com/Peppy-bot/nodes_hub, tracked on main): a curated collection of ready-to-use nodes.
  • launchers_hub (https://github.com/Peppy-bot/launchers_hub, tracked on main): community launch files that compose nodes from the hubs.
  • interfaces_hub (https://github.com/Peppy-bot/interfaces_hub, tracked on main): shared interface definitions that nodes reference by name:tag to declare conformance.
  • openarm01_nodes (https://github.com/Peppy-bot/openarm01_nodes, tracked on main): nodes specific to the OpenArm01 robot.

Add your own local directory with peppy repo add /path/to/my/nodes so peppy can discover nodes you create locally.

Repository configuration lives in ~/.peppy/conf/, and the indexes built by peppy repo refresh are written to ~/.peppy/cache/:

FilePurpose
conf/repositories.json5Repositories to scan
conf/excluded_repositories.json5Repositories (or subdirectories) to skip
cache/nodes.json5Index of nodes discovered across repositories
cache/launchers.json5Index of launch files discovered across repositories
cache/interfaces.json5Index of interface definitions discovered across repositories

The two conf/ files are JSON5 arrays. Each entry has an id (auto-assigned if missing), a type, and source-specific fields:

repositories.json5
[
{ id: 1, type: "fs", path: "/home/user" },
{ id: 2, type: "git", url: "https://github.com/Peppy-bot/nodes_hub", ref: "main" },
{ id: 3, type: "url", url: "https://example.com/packages" },
]
TypeFieldsDescription
fspathA local directory. Peppy recursively walks it, indexing every peppy.json5 (node) and every .json5 file whose body declares peppy_schema: "launcher_v1" (launcher) or peppy_schema: "interface_v1" (interface).
giturl, ref (optional)A git repository. Peppy shallow-clones it and scans it the same way as an fs source. Use ref to pin a branch, tag, or commit.
urlurlAn HTTP endpoint (not yet implemented).
Terminal window
peppy repo init

Syncs repositories.json5 with the bundled default template. If the file does not yet exist it is created verbatim; otherwise any missing default entries are appended without touching your existing entries. Use this after upgrading peppy to pick up new defaults (for example when launchers_hub was added) without having to restart the daemon. The command operates directly on the local config file; no daemon connection is required.

Terminal window
peppy repo list

Shows all discovered nodes grouped by the repository that provides them. Each group is headed by the repository’s display label (path for fs, url (ref: r) for git) followed by the node count and source kind, then lists each node’s name, tag, and path. Duplicate nodes (same name:tag provided by multiple repositories) are flagged so you can see which repository currently wins resolution.

Terminal window
peppy repo refresh

Re-scans all configured repositories and rebuilds the node, launcher, and interface indexes. peppy repo update is accepted as an alias. During refresh, peppy:

  • Reads repositories.json5 (creates it with defaults on first run).
  • Skips any repository or path listed in excluded_repositories.json5.
  • Walks local directories and shallow-clones git repositories.
  • Records every peppy.json5 as a node, every .json5 file whose body declares peppy_schema: "launcher_v1" as a launcher (file stem becomes the launcher name), and every .json5 file whose body declares peppy_schema: "interface_v1" as an interface (keyed by the name:tag in its manifest).
  • Reports each discovered node, launcher, interface, and excluded repository in real time.
  • Caches results in ~/.peppy/cache/nodes.json5, ~/.peppy/cache/launchers.json5, and ~/.peppy/cache/interfaces.json5.

On completion it prints a summary, for example Repository refresh complete. 12 node(s), 3 launcher(s), 5 interface(s) found.

When multiple repositories provide the same name:tag pair, the repository with the lower id takes priority. The duplicate is still recorded and shown in repo list but does not override the primary source.

Terminal window
peppy repo add <source> [--ref <tag-or-branch>] [--top]

Adds a new repository to repositories.json5. The source format is auto-detected:

Terminal window
# Local directory
peppy repo add /path/to/my/nodes
# Git repository
peppy repo add https://github.com/org/repo.git
# Git repository pinned to a branch or tag
peppy repo add https://github.com/org/repo.git --ref v2.0
# Plain URL
peppy repo add https://example.com/packages
# Give the new repo top priority (lower `id` than every existing entry)
peppy repo add /path/to/my/nodes --top

The --ref flag is only valid for git sources. By default the new repository is appended with id = max(existing ids) + 1, so it has the lowest priority among configured repositories; pass --top to assign it an id just below the current minimum, giving it the highest priority. The priority id decides which repository wins when several of them provide the same name:tag (see Refresh the index).

Terminal window
peppy repo remove <id>

Removes a repository by its numeric ID (shown by peppy repo list). The repository index is automatically refreshed after removal.

Terminal window
peppy repo exclude <source> [--ref <tag-or-branch>]

Adds a source to excluded_repositories.json5. Excluded repositories are skipped during peppy repo refresh. You can exclude an entire repository or a specific subdirectory within a local repository:

Terminal window
# Exclude a whole git repository
peppy repo exclude https://github.com/org/repo.git
# Exclude a subdirectory of a local repository
peppy repo exclude /home/user/projects/private-nodes

Once a node appears in peppy repo list, you can add it by its name:tag without supplying a path or URL; peppy resolves the source through the cached index at ~/.peppy/cache/nodes.json5:

Terminal window
peppy node add uvc_camera:v1

This is the shortest form of peppy node add. It works for any node provided by any repository listed in repositories.json5, including the default nodes_hub community repository. When several repositories provide the same name:tag, the resolution rule from repo refresh applies: the repository with the lower id wins.

One constraint applies to this source shape:

  • --ref is rejected. The git ref (if any) is pinned once in repositories.json5 when you register the repo, not per-add.

If the node you want to add lives in a repository that is not in repositories.json5, keep using the full git URL or HTTP archive form shown in Sharing nodes.

peppy node sync regenerates a node’s interface code (peppygen) from its peppy.json5. By default, every dependency the node declares must already be in the node stack, otherwise the sync fails with an “X does not exist in the stack” error.

Pass -r (or --include-repositories) to let peppy fall back to the repository cache when a dependency is missing from the stack:

Terminal window
peppy node sync -r

The lookup order is:

  1. Node stack: wins whenever the dependency is already in the stack. Stack-resolved deps are listed under Synchronized from node stack: in the command output.
  2. Repository cache (~/.peppy/cache/nodes.json5): consulted only when the stack does not have the dependency. Repo-resolved deps are listed under Synchronized from repositories:, each tagged with its source kind (fs, git, or http).

Repository-resolved git dependencies reuse the same persistent checkout cache as peppy node add, so the same repository is never cloned more than once during a single sync run.

Example output when both layers contribute:

Syncing node from /workspace/my_robot_brain via daemon 'core-node-...'
Synced node interfaces at /workspace/my_robot_brain
Synchronized from node stack:
- already_added_dep:v1
Synchronized from repositories:
- uvc_camera:v1 (git)
- lidar_sensor:v1 (fs)

A dependency that is missing from both the node stack and every configured repository is a hard failure:

dep `gps_module:v2` not found in node stack or repository cache; run `peppy repo refresh`

Tip: register your local workspace as a repository

Section titled “Tip: register your local workspace as a repository”

When a node depends on another node you maintain locally, registering your workspace directory as a fs repository removes the need to peppy node add every dependency just to regenerate peppygen for a downstream node:

Terminal window
peppy repo add ~/code/my-nodes
peppy repo refresh
peppy node sync -r # picks up uvc_camera, lidar_sensor, ... from ~/code/my-nodes

Particularly useful during the early phase of a multi-node project, when the dependency graph is still in flux and you don’t want to re-add nodes after every interface change.

When scanning local and git repositories, peppy automatically skips the following directories:

  • .git
  • .peppy
  • target
  • node_modules
  • .venv
  • __pycache__