Changelog
All notable changes to Peppy will be documented on this page.
Subscribe to the Atom feed for updates.
v0.31.10 (Alpha): Export the daemon's log files to an OpenTelemetry endpoint, and keep credentials out of the source URLs it logs.
- Set
otlp_endpointin the daemon configuration to export the launch, add, build, run and stack logs to an OpenTelemetry collector or intake over OTLP/HTTP, andotlp_min_severityto limit the severity sent. - Put export request headers, such as an API key, in the new
~/.peppy/conf/otlp_headers.json5file. - Git and HTTP source URLs that the daemon writes to log lines and error messages no longer carry their credentials.
- The "node not found" error now points at
peppy stack listandpeppy node add <dir>instead of a command that does not exist.
v0.31.9 (Alpha): When a pinned reference misses but the same name:tag is cached at other bytes, peppy now names each cached copy to help you fix the pin.
- When a pinned reference misses while that
name:tagis cached at other bytes,node addandnode syncnow name each cached copy and its source to help you fix the pin.
v0.31.8 (Alpha): Python builds can use a PyPI mirror and cache what uv downloads, and slow crate downloads no longer trip the build idle timeout.
Container builds
- Set
pypi_mirrorinpeppy_config.json5to a mirror's packages base URL to download the PyPI files a Python build'suv.lockpins from that mirror instead of PyPI. - Python container builds on the peppy base image now cache the packages and interpreters uv downloads, so a rebuild fetches neither again.
- Container builds expose a
PEPPY_DOWNLOAD_CACHEdirectory a def can use to cache files it downloads, keyed by their sha256. - Builds run cargo with progress always on, so a slow crate download keeps reporting progress and no longer trips the build idle timeout.
MCP
- On the per-robot surface, a refused member error now also names the other targets the robot fills with a member of that name.
Daemon
- On Linux, the daemon's managed Zenoh router now ends the moment the daemon process dies, so an unclean daemon death no longer leaves a router holding its port.
v0.31.6 (Alpha): Record an endpoint's state-changing calls, answer a service with a picture, and read the first message that arrives after the read.
The call record
- Declare a
call_recordin an exposure to publish a read-only tool that lists the last state-changing calls (mutating services and actions), newest first, with the client, arguments, outcome, and duration of each.
Services that answer with a picture
- A service can declare a
representationto answer its response's frame as an image beside the rest of the response, the way a picture tool does, withon_oversizeto downscale a frame that exceedsmax_result_bytes.
Reads return the next message
- A topic read, and a picture tool, now answers with the first message the endpoint receives after the read, so a client that changes state and reads at once sees the result of its change, bounded by
freshness.max_age_ms.
v0.31.7 (Alpha): The peppy platform commands are rebuilt around workspaces, projects, and enrolling machines in a project's cloud router.
Breaking changes
peppy platform listis removed;peppy platform peersnow lists a project's router peers, with columns for peer name, status, certificate expiry, and id.PEPPY_API_KEYpersonal-access-token authentication is removed; sign in withpeppy platform logininstead.- The
zenoh.managed.federationblock (withconnect_timeout_secs) is gone frompeppy_config.json5; remove it or the daemon refuses to load the config. peppy platform statusnow reports this machine's enrollment and router link; usepeppy platform whoamifor the signed-in identity.- Run
peppy platform loginagain after upgrading, because the previous credentials file is no longer read.
Signing in and enrolling
peppy platform loginsigns you in and then enrolls this machine in a project's cloud router, with--workspace,--project, and--no-enrollto steer it.peppy platform enrolljoins an already-signed-in machine to a project,--replacemints a fresh identity, andpeppy platform unenrollremoves it (--local-onlydeletes only the local record).- Enrolling or unenrolling restarts the daemon under the new identity and wipes the running node stack, prompting first unless you pass
--yes. - The daemon renews the peer certificate automatically while you stay signed in, so an enrolled machine keeps its cloud-router link without manual steps.
peppy platform logoutrevokes the session and clears the selection but leaves the machine enrolled, so the daemon stays connected until its certificate expires.
Workspaces, projects, and the router
peppy platform workspaceandpeppy platform project(each withshow,list,use, andclear) pick the default workspace and project the other commands act on.peppy platform router restartapplies pending changes such as a removed peer, andpeppy platform router startstarts a stopped router.
v0.31.5 (Alpha): New MCP picture tools, camera blobs, and progress-bounded actions; --nv GPU on Jetson; launcher adjustments reworked.
Breaking changes
- A launcher option no longer accepts a bare list of fragments; write several files as
{ fragments: ["a.json5", "b.json5"] }, the object form that also carries the option's ownadjustments. - A fragment may adjust only the instances it deploys; move writes to other instances into the launcher's
adjustments, at the top level or under the option that selects the fragment. - An MCP read of a topic with a
representationreturns its frame as a separate typed blob, removed from the JSON document and its schema;resources/listnow reports the blob's image MIME type.
MCP exposures
- A topic with a
jpegrepresentation can declare apicturetool that returns the latest frame as an image beside the rest of the message. - An action tool can set
progress_timeout_msinstead ofdeadline_msto bound a goal by its time without progress; it needs a feedback topic and no confirmation gate. - A cancelled action goal now returns the provider's result, in the tool error for a call or the status message for a task, and says why it was cancelled.
Containers
--nvcontainers on an NVIDIA Jetson now receive every driver library from the host's L4T container manifest, so CUDA and graphics run there as on desktop.
Actions
- Unread action feedback buffers the newest messages, drops the oldest when full while always keeping the stream's end, and never blocks reading the goal's result.
v0.31.3 (Alpha): Repository refresh gains --strict and can pin a repository to a tag or commit; one_or_more axes run as launcher copies.
- Run
peppy repo refresh --strictto fail the command when any repository cannot be read, so CI and release checks stop instead of continuing. - A git repository's
refcan name a tag or a commit that is not a branch head, andpeppy repo refreshfetches it before reading the repository. - A launcher with a
one_or_moreaxis in itscomponentsruns that axis as copies you can add and remove while its other instances keep running.
v0.31.4 (Alpha): The default hubs now track your Peppy version through the new `@{peppy-release}` ref.
- New installs pin the default hubs with
ref: "@{peppy-release}", which reads thepeppy-release/<version>tag matching your Peppy version, so their content changes only when you install another version. - Set a git repository's
refto@{peppy-release}inrepositories.json5, or pass--ref @{peppy-release}topeppy repo addandpeppy repo exclude, to track your version's hub content. - Existing
repositories.json5entries are never rewritten, so a default hub already onmainkeeps readingmain, which can now hold content that only a later Peppy version reads. To follow your Peppy version, set itsrefto@{peppy-release}, or delete~/.peppy/conf/repositories.json5, runpeppy repo initto write the default entries again, then runpeppy repo refresh. - Before you downgrade to a version earlier than v0.31.4, delete
~/.peppy/conf/repositories.json5and runpeppy repo initwith that version: an earlier version cannot readref: "@{peppy-release}", so it cannot read the default hubs. - After you install a different Peppy version, the daemon reads the
@{peppy-release}repositories again at its next start, before it answers any request. peppy repo list, search, andpeppy repo showlabel a repository on@{peppy-release}with the ref it resolves to, such asreads peppy-release/v0.32.0.
v0.31.0 (Alpha): Serve every robot from one MCP endpoint, start named copies with a launch, and publish lossless 16-bit depth frames.
Breaking changes
peppy stack joinnow takes oneOPTION:NAMEargument in place ofOPTION -i NAME; update commands and scripts that add a copy to a running stack.peppy stack resolvepreviews joined copies with repeatable--join OPTION:NAME(addressed by--with NAME.option), replacing the removed--join,--join-name,--join-with, and--join-set-argumentsflags.- A bound member's
copyis now aCopyTagcarrying the copynameand its fragment's instance id, not a plain name string; update readers ofmember.copyand ofstack list --json. - The
with_bound_producer_in_copybuilder now takes the copy name and the fragment's instance id (running the producer asNAME_<id>) instead of the full instance id and copy name.
Copies at launch
peppy stack launchandpeppy stack buildaccept repeatable, comma-separated--join OPTION:NAMEto start named copies with the launch, addressed byNAME.optionwords and--place NAME@CORE_NODE.- A launcher
deploymentsentry on azero_or_moreaxis may list no copies, instead describing how every copy of that option is set up for later--joinorstack join.
MCP exposures
- An MCP exposure that declares
robotsbecomes a per-robot surface: one endpoint serving every robot of the stack, where each tool names its robot and resources are published per robot. - Image representations add a lossless
png16codec for 16-bit single-channel depth frames, usable withon_oversize: "downscale", and now read frames labeledz16,mono16, or16UC1. - An exposure target may select the same topic member several times, each entry with its own resource name, representation, and policies.
v0.31.1 (Alpha): On Linux, container builds authenticate to private registries with your Docker or Apptainer login.
- On Linux, pull base images from a private registry by logging in with
docker loginorapptainer registry loginbefore you build; peppy hands your credentials to Apptainer. - Builds that used Docker's browser login no longer fail at random with "incorrect username or password", because peppy leaves Docker's session tokens out of the credentials it gives Apptainer.
- Log in or out while the daemon runs and the change applies to your next build, with no daemon restart.
v0.31.2 (Alpha): Launcher axes gain a `one_or_more` cardinality, and installation now supports only Ubuntu-based Linux and Apple Silicon macOS.
Breaking changes
- The installer supports only Ubuntu and the Linux distributions built on it (x86_64 and aarch64) plus macOS on Apple Silicon; on Fedora, Arch, or any other system it stops before making changes.
Launcher copies
- Give a launcher axis
cardinality: "one_or_more"to run it as named copies with a floor of one: every launch must start at least one, fromdeploymentsor--join, andstack removerefuses the last.
v0.30.5 (Alpha): `peppy stack join` and `stack remove` now grow and shrink a running instance's producer and observer sets, delivered live to running nodes.
Breaking changes
-
peppy stack list --jsonnow nests eachslot_bindingsproducer under aproducerkey, with an optionalcopykey; update anything that parses that output. -
Rust generated
bound_producers()accessors return owned values (NonEmptyProducers,Vec<ProducerRef>) instead of borrowed slices, so bind the result to a variable before calling.first(). -
peppy stack joinadds a copy's own instances to a running instance'sone_or_moreorzero_or_moreproducer or observer slot, delivering the grown set to the running node. -
peppy stack removetakes the members a copy added back out of the running sets, and refuses a removal that would empty aone_or_moreslot, naming it. -
A running node's bound producer and observer sets, and its topic subscriptions, follow copies joining and leaving, so call
bound_producers()orsources()at the point of use. -
Generated set slots gain a
bound_members()accessor returning each producer with the copy its instance belongs to, and Python gains apeppylib.BoundMembertype. -
peppy stack listshows the set members each copy added underSet members:and marks each bound member a copy brought with[copy NAME]. -
Standalone nodes gain
with_bound_producer_in_copyandwith_peer_pin_in_copybuilders for a binding or pair whose instance belongs to a copy.
v0.30.6 (Alpha): A jpeg MCP image representation can render z16 depth frames as a greyscale picture over the depth range you configure.
- A
jpegMCP image representation can renderz16depth frames as a greyscale picture, using a newdepth_rangefield that sets the distances its shades span. - A federation join is refused when the machine of an instance whose set it grows is offline, while a removal proceeds and reports the sets it left unchanged.
v0.30.7 (Alpha): Add `peppy stack build` to build every node a launch would run, replacing the node stack without starting anything.
peppy stack build <launcher>builds every node a launch would run and replaces the node stack without starting any instance; it takes every flagpeppy stack launchtakes, including--rebuild.- A later
peppy stack launchwith the same launcher, placement, and--withwords reuses those builds, so you can build onto a disk image that boots ready to launch. - After a build,
peppy stack listshows each nodeReadywith0instances, andpeppy stack joinis refused until apeppy stack launchstarts the stack.
v0.30.4 (Alpha): Action-backed MCP tools now run their goal inside the call for clients that lack the tasks extension.
- A client without the MCP tasks extension can now call an action-backed tool: the goal runs inside the call, streams feedback as progress notifications, and cancels when the call closes.
- An action-backed tool that requires confirmation still needs the tasks extension, and a client without it is refused with a clear missing-capability error.
- Stopping a daemon now waits for its container to exit before the stop completes.
- Stopping now waits for in-flight goals to finish tearing down before it returns.
v0.30.3 (Alpha): Join several robots into one simulation, each bringing its own model, plus a warning-free generated test harness.
Simulation
- Join several robots into one simulation, each a copy bringing its own model; Isaac Sim and Waldo stand many at once, while MuJoCo stands one at a time.
- Remove a simulated robot with
peppy stack removeand only that robot leaves; the simulation stays running for the next join. - The simulation's model catalogue carries OpenArm v1, OpenArm v2, and SO-101, and a simulated SO-101 starts in its home posture with the jaw closed.
Generated test harness
- The Rust test harness peppygen generates now compiles warning-free for a node that publishes nothing.
v0.30.2 (Alpha): MCP and node servers take a free port when theirs is held, and a joined stack copy inherits its option's settings.
Breaking changes
- A
zero_or_moreaxis option may be named in only onedeploymentsentry now; a launcher that lists the same option twice is refused, so merge those entries into one.
Ports and endpoints
- The built-in MCP server treats its
portas a preference and takes an OS-assigned loopback port when another process holds it, so any number of MCP instances run on one machine. - Rust nodes can bind with
peppylib::runtime::bind_preferredto take their chosen port, or an OS-assigned fallback on the same host when it is held, and learn which happened. - Endpoint blocks that
stack launchandnode runprint are now tinted by field when color is enabled.
Launch files
- A
stack joincopy inherits its option'sdeploymentsentry, taking that entry'swith,arguments, andadjustmentswith the join's own--withand--set-argumentson top.
Networking
- In the default
"peer"topology a node session binds a network-reachable0.0.0.0listener on an ephemeral port; use"router"for a deployment that must not accept inbound peer links.
Core-node functions
stack.listnow returns two more fields,copiesandshutdown_grace_secs, beside its node graph and daemon identity.
v0.30.1 (Alpha): Nodes can now serve web pages and MCP endpoints, and peppy reports their URLs across its commands.
Breaking changes
peppy stack listendpoint output changed: the table addsKINDandLABELcolumns and--jsonlists each endpoint as{label, kind, urls}rather than a URL string — update your parsers.
Serving pages and MCP endpoints
- Declare a node's served endpoints under
execution.endpointsinpeppy.json5— each with a label, apageormcpkind, and a description — and announce each bound socket fromsetupwithannounce_endpoint. peppy node run,peppy stack launch, andpeppy stack joinnow end by printing the URLs each started instance serves, grouped underWeb pages:andMCP endpoints:headings.peppy node infoandpeppy stack listnow show each running instance's endpoints with their kind, label, and every URL.
Auditing composed launches
peppy stack resolvenow checks link rules for git-published nodes too, reading their manifests from the checkout cachepeppy repo refreshfills instead of skipping them, without touching the network.
v0.30.0 (Alpha): A pairing slot can hold several peers through a declared cardinality, and `--nv` now renders through the GPU on Jetson boards.
Breaking changes
- A pairing slot states that it may run empty with
cardinality: "zero_or_one"instead ofoptional: true; replaceoptional: trueon everydepends_on.pairingsentry (the defaultonestill requires a pair). peppy repo showand its--jsonoutput report each pairing slot'scardinalityin place of the formeroptionalflag; update any parser reading that field.
Pairing
- A pairing slot can hold several pairs: declaring
cardinality: "one_or_more"or"zero_or_more"pairs one instance with many peers, read through the generatedpeers()and published to withpublish_to. peppy stack listprints one row per pair tagged with each peer's copy, andstack join/stack removeadd and dissolve pairs on a running multi slot.- An observer link can watch a single pair by naming its other end (
watch: "peer_instance/link") instead of the whole source slot. - The generated test harness gives a multi pairing slot
<link>_instancesand<link>_membersknobs that start one mock peer per member.
Containers
- Passing
apptainer_run_extra_args: ["--nv"]now binds the Tegra driver libraries, so a node renders or computes through the GPU on Jetson boards as it does on desktop NVIDIA hardware.
Other changes
- While a build is quiet, each build-progress line names the last line the build printed and how long ago.
- A daemon's derived core-node name now takes the form
cn-{adjective}-{animal}.
v0.28.5 (Alpha): CPU a build burns now counts as build progress, so long silent compiles no longer trip the build idle timeout.
- A
%poststep or abuild_cmdthat compiles silently no longer trips the build idle timeout: the CPU it burns now counts as progress alongside bytes written to disk. - Build progress feedback now appears during
build_cmdruns too, and every progress line reports CPU time consumed as well as bytes written. - Peppy refuses a container bind path containing a
:or a,on either side, because Apptainer's mount spec reads both as separators with no way to escape them. - Removing a stack copy that had paired into a stack instance's vacant slot now restores that slot to vacant, as the original launch declared it.
v0.28.6 (Alpha): `peppy repo index --check` now catches file copies that can never start and stops flagging ones their own constraints refuse by design.
peppy repo index --checknow reports a file's copy whose ownconstraintsrefuse it under every admitted selection, since what the file deploys could never start; loosen a constraint or change the copy'swith.peppy repo index --checkno longer flags a file copy under a stack whose selection itsconstraintsrefuse by design, matching how a join of that copy is judged.
v0.29.0 (Alpha): Named clock domains a launch selects per instance, hosted alongside wall time with no daemon restart.
Breaking changes
-
peppy service serveno longer accepts--clock-source=wall|sim; a launch now chooses its clock through domains, so remove the flag from your serve commands and scripts. -
The per-instance
framework: { use_sim_time }andframework: { publishes_sim_time }keys are gone; declare domains in a launcher's rootframework.clocksand bind each instance withframework: { clock: "<domain>" }. -
Standalone configuration replaces
with_use_sim_timeandwith_sim_time_participantswith a singlewith_clock, taking aClockBindingthat names the domain the node reads or publishes. -
The generated test harness replaces its
use_sim_timeandsim_time_participantsconfig with oneclockknob set towall,consumer, orpublisher. -
SimTimePublisher::for_nodeis renamedClockPublisher::for_node, and it reports the single domain it supplies throughdomain()rather than a participant list. -
One daemon hosts wall time and any number of simulated domains at once, so simulations and wall-time nodes run together and each launch picks its clock without a daemon restart.
-
peppy clock listshows every clock domain running across the federation: who publishes each, whether it has ticked, and how many instances read it, with--jsonfor machine output. -
peppy node run --clock <DOMAIN>binds an instance to a running domain and--publish-clock <DOMAIN>starts it as a domain's publisher; both also work withpeppy node add --run. -
peppy stack listadds a CLOCK column per instance, andpeppy stack resolvereports the clock every instance of a plan reads before anything runs. -
A producer binding, pairing, or observation whose two endpoints read different clocks is refused before anything starts, at launch,
stack resolve, andnode runalike. -
Launcher adjustments gain a
set_frameworkoperation that binds a target instance's clock, letting one shared control or recorder fragment run on whichever domain selects it. -
The generated
clockmodule'snow_nsreads whichever clock its instance is bound to, returning a simulated domain's last tick or the machine's own wall time.
v0.28.4 (Alpha): Generated Python code now decodes an unset optional field to None instead of failing when that field contains a fixed-length array.
- Generated Python deserialization now reads an optional field only when it is present, so a message with an absent optional struct decodes to None instead of raising a fixed-length array error.
v0.28.0 (Alpha): Add and remove named launcher copies on a running stack, with steadier instance health and safer concurrent stack changes.
Breaking changes
- Component axes no longer accept
defaultoroptional; add adeploymentsentry{ <axis>: "<option>" }to pick which option runs, and usecardinality: "zero_or_one"in place ofoptional. message_formatno longer accepts the type aliasesfloat,double, andstr; usef32,f64, andstringinstead.
Repeatable copies
- Declare a component axis with
cardinality: "zero_or_more"to run its options as named copies you start, add, and remove independently under one launcher. peppy stack join OPTION -i NAMEadds a copy to a running stack, selecting its axes with--with, its machine with--place, and per-instance overrides with--set-arguments.peppy stack remove NAMEstops one copy and drops it from the stack, leaving every other copy and the stack's own nodes running.peppy stack listandpeppy stack list --jsonreport each copy's option, host, selection, and instances.peppy stack resolvepreviews a copy joined onto a launch with--join,--join-name,--join-with, and--join-set-arguments.peppy stack reset --federatedclears the launch from every machine it reached.- Fragments can declare their own component axes and reference other fragments across directories within a repository.
- Constraint and adjustment
when,requires, andforbidsconditions accept a list of option names per axis, matching any of them.
Instance health and stack safety
- A running instance is flagged
unhealthyonly after three consecutive missed health probes, and returns tohealthyon the first probe it answers. peppy nodeadd, build, run, stop, and remove serialize with stack operations: refused while one holds the stack, and cancelled whenstack resetruns after a cleanup window.- Cancelling a
peppy nodeadd, build, run, stop, or remove now stops the work on the daemon instead of letting it finish unattended.
v0.28.1 (Alpha): A daemon reserved for a launch now refuses `peppy node remove` and `peppy node stop`, not just `add` and `run`.
- A daemon reserved for a launch now also refuses
peppy node removeandpeppy node stop, alongside thepeppy node addandpeppy node runit already blocked, naming the launch and coordinator holding the reservation.
v0.28.2 (Alpha): Generated peppygen packages now pin ruff's lint rules, so upgrading peppy no longer reformats the code peppy generates.
- Generated peppygen packages now pin ruff's lint rule set in their
pyproject.toml, keeping the generated code stable when the embedded ruff is upgraded.
v0.28.3 (Alpha): Environment variables now reach container nodes whole, and removing a stack copy restores the vacancies it filled.
- Environment variable values that contain commas now reach container nodes whole, instead of being split into separate variables.
- Removing a copy from a running stack now restores the vacant slots it had filled, unless another copy still occupies them.
- A container bind mount whose source or destination path contains
:or,is now refused with a clear error instead of being silently misparsed.
v0.27.8 (Alpha): Consumed-topic schemas are now generated one file per slot, so two same-named topics with different message formats each decode correctly.
Breaking changes
-
Consumed-topic Cap'n Proto schemas are now generated one file per slot, keyed as
on_next_<link_id>_<topic>instead of per topic name; regenerate and rebuild your node bindings after upgrading. -
You can now consume two same-named topics from different producers even when their message formats differ, because each slot decodes through its own schema instead of whichever one was registered last.
v0.27.7 (Alpha): The generated test harness can now make the node under test the launch's source of simulated time, publishing its own clock.
- Pass
sim_time_participantswithuse_sim_timein the test harness to make the node under test the launch's source of simulated time, so it publishes its own clock instead of the test ticking.
v0.27.6 (Alpha): Peppy authenticates git over SSH using the agent and identity files your ~/.ssh/config selects per host, so 1Password, Secretive, and gpg-agent work.
- Git over SSH now authenticates with the agent and identity files
~/.ssh/configselects for each host throughssh -G, honoring yourHost,Match,Include,IdentityAgent, andIdentityFilesettings. - The daemon binds the agent your
IdentityAgentnames once at startup and logs which one, making 1Password, Secretive, and gpg-agent reachable even from a service installed withpeppy service install. - SSH credential failures now name the agent socket, the identity files offered, and any configured paths that do not exist, so a typo in
~/.ssh/configis visible in the message.
v0.27.5 (Alpha): node build and stack launch now reuse a cached artifact for unchanged sources, with --rebuild to force a fresh build.
Breaking changes
-
Built node artifacts now live at
~/.peppy/built_nodes/<name>_<tag>/<fingerprint>.tar.zst(or.sif) rather than~/.peppy/built_nodes/<name>_<tag>.tar.zst; update any scripts that reference the old fixed path. -
peppy node buildreuses a stored artifact when the staged sources are byte-identical to an earlier build's, skippingbuild_cmdorapptainer buildand loggingReusing cached build of .... -
The cache is a content-keyed directory tree that survives daemon restarts and carries built nodes to any machine booted from the same disk with a matching peppy version, OS, and architecture.
-
peppy stack launchreuses cached builds for every deployment, on the coordinator and on every peer, so relaunching the same launcher skips rebuilding unchanged nodes. -
Pass
--rebuildtopeppy node buildorpeppy stack launchto rebuild from the staged sources even when a matching artifact exists, replacing it; this is independent of--force.
v0.27.2 (Alpha): `peppy repo add` gains an `--id` flag to register a repository under an exact id from the reserved `>= 2000` band.
peppy repo add --id <id>pins a new repository under an exact id from the reserved band (>= 2000) instead of a derived one, so setups that re-register it keep a stable id.
v0.27.3 (Alpha): Peppy now reads git repositories over SSH, so private repositories are reachable without embedding a credential in your config.
- You can now give
peppy repo add,peppy node add, andgitentries inrepositories.json5an SSH URL (git@host:owner/repo.gitorssh://) to reach a private repository, authenticating through your ssh-agent and~/.sshkeys the waysshdoes.
v0.27.4 (Alpha): A launch can name one instance its simulated-time source, fed to every machine, with one clock source enforced across the fleet.
Breaking changes
-
In Rust, read a clock tick's instant with
tick.time()instead of thetick.timefield; Python keeps the.timeattribute. -
Reading simulated time now requires a daemon that serves it, so an instance with
use_sim_time: trueis refused on a wall-mode daemon instead of running; start it with--clock-source=sim. -
Declare one launch instance its simulated-time source with
framework: { publishes_sim_time: true }; peppy hands itsSimTimePublisherevery machine of the launch so one clock reaches the whole fleet. -
Federated launches require every machine to serve the same clock source; a sim/wall disagreement is refused at preflight, naming the machine and the flag that fixes it.
-
A launch may declare only one simulated-time source; a second is refused when the launcher is checked, including by
peppy stack resolve. -
Launch feedback names the simulated-time source, and warns when a declared source runs on a wall launch or when a simulated launch declares none.
v0.27.1 (Alpha): `peppy repo show` now reports each pairing slot a node declares alongside the indexed nodes that could fill it.
peppy repo show <node>:<tag>now ends with one section per pairing slot the node declares, listing the indexed nodes that could fill it by playing the pairing's other role, and saying so when none can.- The
--jsonoutput ofpeppy repo shownow carries apairing_slotsarray in each report, each entry giving the slot'slink_id,pairing,role,optional, and thepeersthat could fill it.
v0.26.3 (Alpha): Adds `peppy repo search` and `repo show` to find any indexed item by regex and report who implements, consumes, or observes it.
Breaking changes
- A bare launcher name (no path separator, no
.json5) passed topeppy stack launchorstack resolvenow resolves through the repository cache only, never a same-named file in the current directory; write./name.json5to launch a local file. - Run
peppy repo refreshafter upgrading: peppy refuses a nodes cache written by an earlier release, and the commands that read it fail until it is rebuilt.
Repository search and inspection
peppy repo search <name-regex>[:<tag-regex>][@<sha256>]finds any indexed node, launcher, contract, pairing, or MCP exposure by unanchored regex, listing each match's kind, repository, path, and fingerprint.peppy repo show <query>reports every matched identity: where each document is published and, for a contract or pairing, the nodes that implement, consume, participate in, or observe it, with each pin's status.- Both
repo searchandrepo showaccept--jsonfor machine-readable output and read the local caches, so they need no daemon.
Other improvements
peppy stack list --jsonprints the discovered core nodes and their stacks as one JSON document.stack listpanels and therepo search/repo showtables now fit the terminal, wrapping over-long cells inside the borders; piped output stays unwrapped.- On Linux, replacing the
peppybinary while the daemon runs no longer strands built-in MCP nodes: the daemon serves them from its running image, warns in the add log, and adopts the new binary on restart.
v0.27.0 (Alpha): Peppy now configures pairings-hub as a fifth default repository, so shared pairing definitions resolve without any setup.
- Reference shared pairing definitions by
name:tagindepends_on.pairingsstraight away, withpairings-hub(id1004) now configured as a default repository.
v0.26.2 (Alpha): MCP tasks for feedback-less actions now settle on their result, and release artifacts no longer carry the build machine's identity.
MCP server
- MCP tasks backed by an action that declares no feedback now settle on the provider's result instead of stalling until the task deadline.
Release artifacts
- Release archives are packed with neutral ownership, so installing them as root inside a user namespace no longer fails or hands the files to a same-named local account.
- The
peppybinary and the bundled apptainer man pages no longer embed the build machine's home directory or source paths.
v0.26.0 (Alpha): Serve MCP exposures from the server built into peppy by listing them in a launcher, with no node to generate or build.
Breaking changes
-
peppy repo exposureis removed, and an exposure is no longer a committed bundle plus a generated MCP server node. Validate exposures withpeppy repo index --check --validate-mcp-exposuresand delete the old generated artifacts. -
Serve an exposure from a launcher's
source: { exposures: ["<name>:<tag>", ...] }instead of deploying its generated<name>_mcpnode; the server built intopeppybinds127.0.0.1:<port>, one endpoint per exposure at/<name>/<tag>/mcp. -
peppy mcp catalog <name:tag>prints the catalog an endpoint advertises: every resource, tool, and task with its public name, policies, and derived JSON Schemas. -
A target's contract
sha256is now optional; omit it and the exposure follows the contract as its repository evolves, with each launch pinning the bytes it resolves. -
One deployment can serve several exposures on a single port, sharing a contract slot when two exposures name the same target and the same contract.
-
peppy stack listadds anInstance endpointstable listing each endpoint URL an instance serves. -
Exposure deployments work in a federated launch: the exposure documents and the contracts they reference are pinned and shipped to the machine hosting the instance.
-
A new default
mcp-hubrepository resolves the MCP exposure documents a launcher lists. -
An exposure manifest may carry a
labelslist of free-form strings for whoever browses the repository.
v0.26.1 (Alpha): The OpenArm-specific node repository is no longer configured out of the box, leaving four default repositories whose ids shift.
Breaking changes
- The default repositories no longer include
openarm-nodes(the OpenArm01-specific nodes); to keep using those nodes, add the repository to your configuration yourself. - The built-in ids of
contracts-hubandmcp-hubare now1002and1003(previously1003and1004); update anything that references them by id.
v0.25.7 (Alpha): `stack resolve` now checks link rules without a daemon, and generated bindings decode string-list payload fields.
stack resolve
stack resolvenow checks the flat plan against the link rules it can verify without a daemon (slot keys, vacancies, and pairing coverage) and fails early when one breaks.- The resolution report ends with a line saying whether those link rules were checked, or why the check was skipped and to run
peppy repo refresh.
Message payloads
- Topic and action payloads can now include string-list fields (
$type: "array"with$items: "string"), and the generated bindings decode them.
v0.25.5 (Alpha): Pin a contract or pairing's generic arrays to your node's length with `refine`, and harden how servers decode goals.
- Pin a contract or pairing document's generic arrays to a fixed length for your node with a
refineblock on an implements, consumes, or pairing entry. - A generated action server now rejects a goal whose request bytes do not fit its declared shape with the decode error and keeps serving, never reaching your decider.
- Python nodes now raise a
ValueErrorwhen a fixed-length array is encoded or decoded with any other number of elements, matching Rust's fixed-size arrays.
v0.25.6 (Alpha): Adds a `peppy --version` flag that prints the CLI version straight from the binary, without contacting the daemon.
- Run
peppy --version(or-V) to print the CLI version alone, straight from the binary, without starting or contacting the daemon.
v0.25.2 (Alpha): The generated test harness serves the daemon clock, so you can boot nodes in sim time and drive it, or skew wall time.
- Boot a node in sim time under the generated test harness with
use_sim_timeand drive its virtual clock yourself withharness.clock.tick(...), with no time existing until you tick. - Skew the wall clock the harness serves with
harness.clock.set_offset_ns(...)to exercise a node's clock-offset handling without touching the host clock. - Run standalone (daemon-less) nodes in sim time with
StandaloneConfig.with_use_sim_time(...), which no longer requires a real daemon stack. peppygen.clock.initnow rebinds when a different node initializes it, so consecutive test-harness boots in one process each read their own clock.
v0.25.3 (Alpha): A maintenance release with internal updates only; no user-facing changes.
- No user-facing changes in this release.
v0.25.4 (Alpha): This release contains internal maintenance only, with no user-facing changes.
No user-facing changes. This release contains internal maintenance only.
v0.25.0 (Alpha): peppy generates mock and fixtures test surfaces for Rust and Python nodes, plus a Testing guide and a scaffolded harness.
Testing
- peppy now emits mock and fixtures test surfaces into the generated
peppygenpackage for both Rust and Python nodes, so you can test your nodes against generated mocks and fixtures. - Multi-instance mock slots now carry explicit instance ids, so tests can address each instance individually.
- Optional pairing slots gain a vacant-boot knob for booting a node with the optional peer left unpaired.
- Generated mocks honor the per-interface consumer link ids you declare.
peppy node initnow scaffolds a lib/main split and a harness smoke test for new nodes.- A new Testing guide covers writing tests with mocks, teardown, and the cardinality knobs.
v0.25.1 (Alpha): Spawned nodes no longer inherit the caller's PYTHONPATH and PYTHONHOME, alongside documentation fixes for node commands and launcher options.
Breaking changes
- Spawned nodes no longer inherit the caller's
PYTHONPATHandPYTHONHOMEfrom the launching environment. If a node relied on either variable being passed through, set it explicitly for that node.
Documentation
- The
peppy node runexample in the actions guide is corrected so it works as written. - The quickstart and README now document the launcher-with-options syntax.
v0.24.1 (Alpha): Launchers can now declare `constraints`, including `forbids`, that refuse incompatible selections in the composition model and explain each refusal.
Launcher constraints
- Launcher definitions accept a new
constraintsblock that turns invalid combinations into selection refusals in the composition model, rejecting incompatible choices before a launch is composed. - The
forbidsrule declares selections that cannot be combined, and refusal messages lead with the choice that triggered them so it is clear which selection to change. - Constraint diagnostics name the constraint that shadows an unreachable one and flag a bare launch that exceeds the allowed ceiling.
v0.24.0 (Alpha): Compose launchers from fragments with --with selections and a new stack resolve command, plus sturdier container builds.
Launch composition
- Peppy parses composed launchers and flattens a launcher selection into a single flat launcher.
--withselections are resolved on the coordinator, and the newstack resolvecommand reports the resolved stack.- A single launcher fragment can no longer both replace and append to the same slot; peppy rejects fragments that do.
- Launcher fragment validation covers previously missed cases, tightening composition safety.
Containers
- Container builds are retried automatically when the base image fetch fails transiently.
- Peppy checks for
fuse2fson hosts that run rootless Apptainer containers.
Networking
- Peppy supports a wildcard peer listener for peer discovery.
Output
- Peppy announces a cached-checkout reuse once per checkout population.
v0.23.3 (Alpha): Adds the mcp_exposure/v1 format for generating MCP server nodes and task bridges, and keeps slow-connection launches alive.
MCP exposure
- The new
mcp_exposure/v1format lets you declare MCP exposures, which peppy wires into the repository and publishes as exposure bundles. - An exposure generates an MCP server node together with action-backed task bridges, whose feedback QoS is derived from the contract rather than a fixed default.
Launches and containers
- Container
mount_pathsthat start with~are now expanded to the home directory on the machine that binds them. - Launches over slow connections stay alive by reporting genuine build progress instead of stalling.
Documentation
- MCP exposure is now covered by its own dedicated advanced guide.
v0.23.2 (Alpha): Absent optional node dependencies are now accepted when the slot allows an empty bound set, with clearer guides.
Dependencies
- A node dependency may now be absent when its slot admits an empty set of bounds, so optional dependencies no longer need to be present to satisfy resolution.
Documentation
- The guides now document how to add an optional dependency and correct the wording used to describe the dependency walk.
- The guides now name the both-sources failure and describe the add-path cache fallback.
- The guides now accurately describe worklist deduplication and launch vacancy.
v0.23.1 (Alpha): Observer seeding now covers peer-placed observers, and generated code gains typed accessors for observed pairings.
Observers
- Observer membership is stamped into the boot config when an observer spawns, so observers are seeded correctly, including observers placed on peers.
- The observation seed spawn path is fixed so observations seed reliably.
Generated code
- Generated Rust and Python code now exposes cardinality-typed
source()andsources()accessors for observed pairings.
Documentation
- The pairing and standalone node documentation now reference the
--linkflag.
v0.23.0 (Alpha): This release contains no user-facing changes.
No user-facing changes in this release.
v0.22.1 (Alpha): Generated pairing subscriptions now tag each message with the subscribing slot's identity.
Pairing
- Generated pairing subscriptions now tag every message with the subscribing slot's identity, so paired nodes can tell which slot a message came from.
v0.22.0 (Alpha): Slots gain cardinality-based sizing, links can be left vacant, and refreshes report unreadable repositories instead of failing.
Breaking changes
defer_linksis replaced by a vacant link value. Replace anydefer_linksentry in your links maps with the vacant link value.- Participant slots no longer accept the
optionalfield. Express whether a participant slot may be left unfilled through its cardinality instead.
Slots and links
- Producer slots now bind at most one producer.
- Observer slots are sized by their cardinality.
- A link may be left vacant only when the node manifest declares itself optional.
Repository refresh
- A refresh now reports the repositories it could not read and continues instead of failing the entire run.
v0.21.0 (Alpha): Federated launches span machines, repositories resolve through a committed index, and launchers pin registry sources.
Breaking changes
- Repository entries now resolve through a committed repository index rather than being resolved ad hoc, and every cache entry is pinned to a git commit; generate and commit the index with the new
peppy repo indexcommand, whose--checkmode verifies the committed index is up to date. - Launcher deployment sources are restricted to
name:tagregistry references that resolve to node pins, and retired source keys are refused with a migration message, so update your launcher files to reference nodes by registryname:tag.
Federation
- A federated launch now spans multiple machines through cross-machine dispatch.
- The launcher places and preflights federated core node links across machines.
peppy resetrediscovers federated reset targets from the federation instead of from local memory.- Cross-daemon pairing peers are stamped with their own core node in display reads.
- Filesystem-backed repositories cannot participate in federation.
Pairing and dependencies
depends_ongains a fourth peer-coupling level,pairing_observers, across the daemon and launcher.- The surviving instance of a pair still receives the dissolution notice after its partner has already stopped.
Launcher and launch
- Launcher files accept per-instance
env_vars. - The launch summary lists every machine's node log files.
- A coordinator's next launch takes over its own stale reservation through a lease instead of being blocked by it.
- The caller's environment stays on the caller's machine, so peer builds no longer inherit it.
Containers
- Each peer prepares its own container bind mounts, and relative container mount sources are forwarded to Lima as absolute paths.
- Restarts that would kill running containers are refused, and container bind sources are prepared before a participant slice takeover.
- Apptainer SIF images are FUSE-mounted instead of extracted, with squashfuse bundled alongside apptainer.
Repositories
peppy repo refreshcaches its checkout for reuse, prunes orphaned checkouts, applies filesystem exclusions before reading declared items, and skips re-pushing stack entries whose manifest is unchanged.- Repository resolution failures are reported and contained instead of guessed, with clearer failure reports.
Messaging and code generation
- The Rust and Python generators handle
$optionalscalars and payload-less feedback topics consistently.
Documentation
- The documentation is aligned with the current commands, outputs, and behavior.
- Federation coordination guidance and the producer-link example are clarified, with the example showing separate per-node manifests.
v0.20.0 (Alpha): Adds `peppy platform list` to view your workspace's core nodes and makes `peppy platform logout` deregister this machine's node.
Platform
- The new
peppy platform listcommand shows your workspace's core nodes and their status, reporting both the application layer and the network layer for each node. peppy platform logoutnow deregisters this machine's core node when you log out.
Documentation
- The quickstart page now includes a quickstart video.
- The README has been rewritten with installation instructions, CLI usage, and links to the documentation.
v0.19.1 (Alpha): Peppy tightens how container nodes handle host and temp paths, and adds a Quickstart from install to a simulated arm.
Breaking changes
- Container nodes no longer inherit the caller's temporary directory. If a container node relied on that path, provide it explicitly.
- Peppy no longer auto-creates bind mount source paths that the host is expected to provide. Create those directories before starting the node, or the mount will fail.
Container and host-runtime behavior
- When a host runtime path is not available inside the VM, peppy now reports the actual constraint instead of a less specific error.
- Closed a case where a run command could bypass the restrictions on host runtime paths.
Documentation
- Added a Quickstart that walks you from installing peppy to a simulated OpenArm in three steps.
v0.19.0 (Alpha): Actions adopt the goal-ack envelope and split goal/result endpoints; the generator now honors declared goal response schemas.
Breaking changes
- Actions now use the framework goal-ack envelope for goal acknowledgements; update any consumer that parses goal acknowledgement messages to the new envelope format.
- Action endpoints are now split into separate goal and result endpoint types; update any configuration or code that referenced the previous combined action endpoint type.
- Generated goal responses no longer include an error field; update any code that read that field.
Code generation
- The code generator now honors the goal response schemas you declare, so generated goal responses match your declaration; regenerate to pick up the change.
Documentation
- The guide pages have been revised to fix inconsistencies and formatting issues.
v0.18.0 (Alpha): Adds observer slots, unifies binding and pairing into links, reworks zenoh config, and spans stack list across daemons.
Breaking changes
- The
peppy authcommand group is renamed topeppy platform; update any commands or scripts that callpeppy auth. - The
--bindand--pairflags are replaced by a single--linkflag; switch your commands to use--link. - Launch files now use unified
linksanddefer_linksfields in place of the previous separate binding and pairing entries; migrate your launch files to the new fields. - Zenoh settings in
peppy_config.json5are restructured into azenohsection with taggedzenoh.managedandzenoh.externalblocks, replacing the flatzenoh,zenohd, andpeerfields, and unknown fields underzenohare now rejected; move your settings into the new blocks. The newzenoh.externalblock lets peppy run against an operator-managed zenoh router. peppy stack listno longer prints DOT graph output; it now always renders a report of per-core-node sections aggregated across every live daemon, including live instance counts and the answering daemon's identity, so update anything that parsed the old graph output.- Generated peppygen modules for slots are now nested at
<category>/<link_id>/<member>; update the import paths for your generated code. - The
PEPPY_DAEMON_STATE_FILEenvironment override is removed; the daemon state file now lives under$PEPPY_HOME, so stop settingPEPPY_DAEMON_STATE_FILE. - The "organization"/"org-id" concept is renamed to "workspace"/"namespace" across authentication and daemon output; update references and scripts that use the old terms.
Observers
- Nodes can now declare observer slots to observe topics, with generated observer bindings (including an
ObservedSourcetype) and delivery of observers to running nodes. - Guides and launch-file documentation now cover observer slots and the
links/defer_linksmodel.
Multi-daemon and federation
- Daemons can participate in a federated peer topology across zenoh routers.
- Federation-aware CLI commands now surface listener and serve errors instead of hanging.
Other changes
- Removing a node with
node remove --stop-instancesnow also dissolves that node's links. - A new
PEPPY_CONFIGenvironment variable overrides the daemon config file path. - Only one peppy daemon can run per
$PEPPY_HOMEdata root, enforced by an exclusive singleton lock. - Config drift now logs which
peppy_config.json5settings it adds when completing missing defaults. - Newly generated core-node default names use the compact
cn-{adj}-{surname}format instead of the longercore-node-{adj}-{surname}-{4digits}-{10digits}form. - The bundled Cap'n Proto compiler is now installed under
$PEPPY_HOME/bin, and its location is documented.
Documentation
- External federation guidance adds a dedicated section on namespace handling outside the Peppy platform.
v0.17.0 (Alpha): Dependency slots gain explicit cardinality, letting a slot bind to multiple producers through a uniform consumer API.
Dependency-slot cardinality
- Dependency slots now support explicit cardinality, letting a slot bind to one or more producers instead of exactly one.
- Bindings can target multiple producers, and consumers read them through a uniform
bound_producers()API regardless of cardinality. - Generated producer accessors reflect each slot's cardinality: single-producer slots expose
bound_producer()while multi-producer slots exposebound_producers(). - Bindings can now specify explicit service and action targets.
- Slots declared
one_or_moremust be non-empty, and this check now applies to programmatically suppliedFlagsvalues as well as arrays.
v0.16.0 (Alpha): Renames interfaces to contracts, tightens `depends_on` slot validation, and fixes macOS container builds.
Breaking changes
- The
conforms_tomanifest field has been renamed toimplementsas part of a broader rename of "interfaces" to "contracts"; renameconforms_totoimplementsin yourpeppy.json5and update any "interface" wording to "contract". - Dependency slots (
depends_on) now require a single producer each, replacing the previousfrom_anybinding model, and peppy now fails validation whenever adepends_onslot is left unfulfilled; update your bindings so every slot names exactly one producer.
Container builds and runs (macOS)
- macOS container builds no longer silently default to
$HOMEand now use the current working directory. - The peppy data root is now mounted into the Lima VM so container builds and runs can access it.
- Fixed a hang where restarting the Lima VM blocked the async runtime while registering a host mount for the first time.
- Container Python bindings no longer ship stale native extensions after shared-crate changes.
Validation and output
- Contract (
implements) validation failures now report per-slot coverage mismatches instead of a single combined string. - The CLI info output formatting has been simplified.
Documentation
- The advanced guides now include Python examples alongside the existing Rust examples.
- The Python async examples now wrap
select!in a loop and hold references to asyncio tasks so they are not cleaned up or garbage-collected prematurely.
v0.15.1 (Alpha): Adds remote core node targeting and collision detection, renames the serve command and the shared-directory variable.
Breaking changes
- The
PEPPYOS_SHARED_DIRenvironment variable has been renamed toPEPPY_SHARED_DIR; update your environment so the shared directory stays configured.
Core node targeting
- The
--core-nodeflag can now target a remote core node and is accepted bynode add,node sync, andrepo add. - The
--core-nodeflag is now validated as the command is parsed, so invalid values are reported immediately. - peppy now detects core node name collisions.
Serve reliability
peppy service servenow shuts down cleanly when an error occurs during startup.
v0.15.0 (Alpha): Nodes can now declare, establish, and dissolve pairings with one another, and serve restarts and shutdowns are more reliable.
Node pairing
- Nodes can now declare, establish, and dissolve pairings (peer links) with one another at runtime.
- Each paired node exposes a
LINK_IDand apairingsview in its generated module so node code can identify and work with its active links. peppy stack listnow shows an "Instance pairings" section listing the active pairings between running instances.- Malformed pairing targets are now rejected, and pairing delivery is protected against a link being dissolved concurrently.
Serve reliability
peppy serveno longer drops shutdown signals or races when restarting, so restarts and shutdowns now behave reliably.
v0.14.0 (Alpha): Logging in now connects your daemon to a per-user TLS-verified cloud router, and topics move to a new Subscription API.
Breaking changes
- Topic subscriptions no longer use the per-call
on_next_message_receivedmethod; subscribing now returns aSubscriptionthat you hold and read messages from, so update your node code to use it.
Authentication and cloud routers
- Logging in now fetches and caches your per-user cloud (zenoh) router configuration and federates your daemon to it live.
- peppy verifies the router's TLS certificate when you log in.
- Logging in or out now takes effect immediately, regenerating and restarting the daemon and propagating your organization namespace through it.
- Fixed a cross-identity organization cache leak, added a daemon restart when the namespace drifts at startup, and hardened login and logout edge cases.
- The restart warning is now skipped when your daemon stack has no user nodes.
Releasing
- Added a
--skip-prod-cert-checkflag to bypass the production-router certificate gate when running a release.
Topics
- Tightened how subscriptions behave once they are closed, across generated node code and the docs.
Reliability
- peppy now retries transient
ETXTBSYandENOENTexec errors when extracting the ruff binary during parallel binary extraction.
Documentation
- Clarified that
reconnect_after_secsandrepull_afterare cache-freshness hints rather than keepalive deadlines.
v0.14.1 (Alpha): Bundle downloads retry transient failures, AppArmor profiles are per-install, and node run drops the legacy --link-id flag.
Breaking changes
- The legacy
--link-idflag has been removed fromnode run; remove it from any commands or scripts that still pass it.
Node downloads and runtime
- Transient HTTP failures when downloading node bundles are now retried automatically with bounded backoff, making node setup more resilient to flaky networks.
- Empty environment variable path overrides are now treated as unset, so an empty value falls back to the default instead of being used as a literal path.
AppArmor
- AppArmor profiles are now namespaced per Apptainer installation path, so multiple Apptainer installations no longer collide.
- The AppArmor fix script now shell-escapes the starter path correctly, so installation paths containing special characters work.
v0.13.0 (Alpha): Adds OAuth device-flow sign-in through the new peppy auth commands and moves schema identifiers to a slash-separated form.
Breaking changes
- Schema identifiers now use a slash separator (
node/v1,interface/v1,launcher/v1); update the schema references in yourpeppy.json5to the new slash-separated form.
Authentication
- Added
peppy auth login,peppy auth logout, andpeppy auth whoamito sign in, sign out, and check your current identity using the OAuth device flow.
v0.12.1 (Alpha): Adds signal handling and bind-mount safety.
Container lifecycle
- Lima liveness checks now share a bounded wait helper and enforce per-probe timeouts.
- Native containers now fall back to a host SIGTERM when the in-guest signal is unavailable.
- In-VM container processes on macOS now receive a cooperative SIGTERM phase before being force-killed.
Stack
- All container bind mounts are now pre-flighted before any instance is started.
v0.12.0 (Alpha): Remove emit topics API that could cause deadlocks on large payloads
What's Changed
Full Changelog: v0.11.1...v0.12.0
v0.11.1 (Alpha): Fix a bunch of deadlocks on node stop
What's Changed
- Optimize config-internal by @godardt in #252
- Optimize core-node-api by @godardt in #253
- Optimize core-node-internal by @godardt in #254
- Optimize generator-internal by @godardt in #255
- Optimize containers-internal by @godardt in #256
- Optimize latency-report by @godardt in #257
- Optimize the peppy crate by @godardt in #259
- Optimize node-stack-internal by @godardt in #258
- refactor(pmi): harden public API, purify session-config builder, forbid unsafe by @godardt in #260
- Refactor peppylib and peppylib-py by @godardt in #261
- Fix stop clock and heartbeat publishers before closing the messaging session by @godardt in #262
- Fix nodes termination unhealthy when nodes are tasks that exit by @godardt in #263
- Release v0.11.1 by @godardt in #264
Full Changelog: v0.11.0...v0.11.1
v0.11.0 (Alpha): Add many fixes to the public APIs, especially with actions
What's Changed
- Deploy peppylib as a standalone installable project in Python nodes by @godardt in #240
- Fix producer death block by @godardt in #242
- Add on_shutdown hook phase with grace-bounded LIFO execution across all node stop paths by @godardt in #243
- Add
stack benchmarkimprovements by @godardt in #244 - fix: Replace half-address producer refs with fully-qualified ProducerRef by @godardt in #246
- Fix force node stop on
node buildby @godardt in #245 - Fix
node stoptargeting wildcard core nodes by @godardt in #247 - fix: isolate peppy data root per CI run to prevent cross-run collisions by @godardt in #249
- Return full producer identity (core_node + instance_id) from consumed topic callbacks by @godardt in #248
- docs: sync with PR #250 by @godardt in #251
- Release v0.11.0 by @godardt in #250
Full Changelog: v0.10.5...v0.11.0
v0.10.5 (Alpha): Fix `node stop` and daemon kill graceful shutdowns
What's Changed
- Switch to Zenoh peer sessions for direct peer-to-peer data paths by @godardt in #236
- docs: sync with PR #234 by @godardt in #235
- Fix zombie processes of nodes in the node stack by @godardt in #237
- Refactor build helpers by @godardt in #238
- Release v0.10.5 by @godardt in #239
Full Changelog: v0.10.4...v0.10.5
v0.10.3 (Alpha): Add support for shared datastore
What's Changed
- Remove deferred binding support by @godardt in #229
- Add from_any bidirectional guide with robot arm snippets by @godardt in #230
- Add memory store by @godardt in #228
- Extract router feature flag and split zenohd submodules by @godardt in #232
- Release v0.10.3 by @godardt in #231
Full Changelog: v0.10.2...v0.10.3
v0.10.2 (Alpha): Fix bidirectional communication design
What's Changed
- docs: sync with PR #221 by @godardt in #222
- Remove external consumed topics, all consumed topics now require a link_id by @godardt in #223
- Rework bidirectional comm by @godardt in #224
- Add bidirectional communication via interfaces by @godardt in #225
- Release v0.10.2 by @godardt in #226
Full Changelog: v0.10.1...v0.10.2
v0.10.1 (Alpha): Fix stack list display as well as --force flag on node build
What's Changed
- fix: release gate slot before completing goal to eliminate "action already in progress" race by @godardt in #217
- Fix zenohd stdout/stderr to file to prevent pipe buffer deadlock by @godardt in #218
- Improve the output of the
stack listcommand by @godardt in #219 - Fix zombie processes by @godardt in #220
- Release v0.10.1 by @godardt in #221
Full Changelog: v0.10.0...v0.10.1
v0.10.0 (Alpha): Add interface conformance along with fixes to action
What's Changed
- Improve install script by @godardt in #192
- Variants removal by @godardt in #191
- Release v0.9.3 by @godardt in #196
- Interfaces conformances 1 by @godardt in #197
- Interfaces conformances: standard structures by @godardt in #198
- Replace semver tags with non-dotted tags by @godardt in #199
- Refactor pmi-internal by @godardt in #201
- Implement the
conforms_tobusiness logic for interface conformance by @godardt in #200 - Fix interfaces & nodes on the wire by @godardt in #202
- Add depends.on.interfaces business logic by @godardt in #203
- Add launcher bindings business logic by @godardt in #204
- Throw warnings on missing
link_idduringpeppy runby @godardt in #205 - Fix launcher and
node runbindings by @godardt in #206 - Add instance_ids fetch by node name + node tag by @godardt in #207
- docs: sync with PR #209 by @godardt in #210
- Fix action communication by goal ID by @godardt in #214
- Replace raw cancel/result payloads with typed ResultStatus and CancelState by @godardt in #215
- Revision release v0.10.0 by @godardt in #211
- Release v0.10.0 by @godardt in #216
Full Changelog: v0.9.3...v0.10.0
v0.9.3 (Alpha): Fix peppy actions misalignment
What's Changed
- feat: bundle gocryptfs alongside apptainer for encrypted overlay support by @godardt in #193
- Fix action communication misalignment by @godardt in #195
Full Changelog: v0.9.2...v0.9.3
v0.9.2 (Alpha): Add documentation for actions with optional fields
What's Changed
Full Changelog: v0.9.1...v0.9.2
v0.9.1 (Alpha): Fix cancel token during action feedback when the action ends
What's Changed
- docs: sync with PR #184 by @godardt in #185
- Fix Action feedback deadlock by @godardt in #187
- Release v0.9.1 by @godardt in #188
Full Changelog: v0.9.0...v0.9.1
v0.9.0 (Alpha): Add support for launchers repositories
Main changes
schema_versionis nowpeppy_schema: "node_v1"orpeppy_schema: "launcher_v1"depending if it's a node or a launcherpeppy stack launch <launcher_filename>now works with remote launchers. The https://github.com/Peppy-bot/launchers_hub repository is added by default. Runningpeppy stack launch ./<launcher_filename>defaults to a local path, whilepeppy stack launch <launcher_filename>defaults to a launcher in the repositories
What's Changed
Full Changelog: v0.8.5...v0.9.0
v0.8.5 (Alpha): Add ability to use `peppy node sync -r` to use repositories
What's Changed
- Add
node sync -rto synchronize with repositories by @godardt in #181 - Release v0.8.5 by @godardt in #182
Full Changelog: v0.8.4...v0.8.5
v0.8.3 (Alpha): Add wall & sim clock support
What's Changed
- Feature clock sync by @godardt in #176
- Add sim-clock mode with per-instance framework overrides by @godardt in #177
- Release v0.8.3 by @godardt in #178
Full Changelog: v0.8.2...v0.8.3
v0.8.2 (Alpha): Add core node information available to peppylib
What's Changed
- Extract capnp encoding types into new core-node-api crate by @godardt in #172
- Peppylib stack list command implementation by @godardt in #173
- docs: sync with PR #174 by @godardt in #175
- Release v0.8.2 by @godardt in #174
Full Changelog: v0.8.1...v0.8.2
v0.8.0 (Alpha): Add support for repositories
What's Changed
✨ Highlight: Repositories. This release introduces first-class repositories, a new way to tell peppy where to discover nodes. Register local directories, git repositories (with optional branch/tag pinning via --ref), or HTTP endpoints with peppy repo add, then run peppy repo refresh to build a cached index of every available node. Once indexed, nodes can be added by their short name:tag form (e.g. peppy node add uvc_camera:0.1.0) and launched in the node stack without pointing at a path or URL.
- Add repositories feature by @godardt in #161
- Automatically test for docs drift by @godardt in #163
node addcommand now works with node name + tag from repositories by @godardt in #162- Add ability to use
stack launchwith nodes from repositories by @godardt in #164 - docs: sync with PR #165 by @godardt in #166
- docs: sync with PR #165 by @godardt in #167
- docs: sync with PR #165 by @godardt in #168
- Release v0.8.0 by @godardt in #165
Full Changelog: v0.7.0...v0.8.0
v0.7.0 (Alpha): Separate `node add/start` into `node add/build/run`
What's Changed
- Add
node buildstep to workflow by @godardt in #153 - Separate
node addfromnode buildcommands by @godardt in #155 - refactor: rename
start_cmdtorun_cmdby @godardt in #156 - Fix standalone integration by @godardt in #157
- Change
node infoto look up nodes by name:tag by @godardt in #158 - Add
nodecommand shorthands by @godardt in #159 - Release v0.7.0 by @godardt in #160
Full Changelog: v0.6.2...v0.7.0
v0.6.2 (Alpha): Add code and command optimizations
What's Changed
- Code cleanup & optimization by @godardt in #149
- Node sync path by @godardt in #150
- Core node name is now fixed across reboot/reinstallation by @godardt in #151
- Release v0.6.2 by @godardt in #152
Full Changelog: v0.6.1...v0.6.2
v0.6.1 (Alpha): Add support for arrays of objects in message format schemas
What's Changed
- Support arrays of objects in message format schemas by @godardt in #147
- Release v0.6.1 by @godardt in #148
Full Changelog: v0.6.0...v0.6.1
v0.6.0 (Alpha): Add support for node variants
What's Changed
- Create a dedicated
runtimesection to holdlanguage,container,parametersandadd_cmd/start_cmdby @godardt in #136 - Node variants by @godardt in #137
- Docker base images by @godardt in #143
- Fix variants by @godardt in #142
- Add more meaningful output to the
node addoperation by @godardt in #144 - Add variant launchers support by @godardt in #145
- Release v0.6.0 by @godardt in #146
Full Changelog: v0.5.10...v0.6.0
v0.5.10 (Alpha): Add support for installation in containers
What's Changed
Full Changelog: v0.5.9...v0.5.10
v0.5.8 (Alpha): Fix architecture mismatch in Apptainer binary
What's Changed
Full Changelog: v0.5.7...v0.5.8
v0.5.7 (Alpha): Official support for more Linux distros
What's Changed
Full Changelog: v0.5.6...v0.5.7
v0.5.6 (Alpha): Add support for mounted devices in containers
What's Changed
- refactor: simplify PR 128 by @claude[bot] in #131
- Add extra args support for apptainer build/run and lima shell by @godardt in #128
- Add documentation for llms by @godardt in #132
- v0.5.6 by @godardt in #133
Full Changelog: v0.5.5...v0.5.6
v0.5.5 (Alpha): Fix issues with installation script on some systems
What's Changed
- Improve install scripts by @godardt in #126
- Containers mounts with runtime vars by @godardt in #125
- fix: switch container images to standard registries by @godardt in #129
- v0.5.5 by @godardt in #130
Full Changelog: v0.5.4...v0.5.5
v0.5.0 (Alpha): Bidirectional communication support
What's Changed
- Rework peppy structure by @godardt in #102
- Separate DAG from communication by @godardt in #104
- Fix/actions revamp by @godardt in #106
- Add bidirectional communication by @godardt in #107
- Fix node add with existing instances by @godardt in #109
- Improvement launch files by @godardt in #112
- Fix yanked file by @godardt in #114
- Optimize modules by @godardt in #113
- Release 0.5.0 by @godardt in #115
Full Changelog: v0.4.0...v0.5.0
v0.5.1 (Alpha): Add more explanatory logs for add_cmd and start_cmd failures
What's Changed
- Include command name in spawn and execution failure error messages by @godardt in #116
- Add more explanatory logs for add_cmd and start_cmd failures by @godardt in #117
Full Changelog: v0.5.0...v0.5.1
v0.5.3 (Alpha): Fix Linux .so Python lib not available for x86_64 systems
What's Changed
- Fix Linux .so Python lib not available for x86_64 systems by @godardt in #121
- Release v0.5.3 by @godardt in #122
Full Changelog: v0.5.2...v0.5.3
v0.5.4 (Alpha): Add various fixes to the install script
What's Changed
- Various fixes to the install script by @godardt in #123
- Add various fixes to the install script by @godardt in #124
Full Changelog: v0.5.3...v0.5.4
v0.4.0 (Alpha): Containers support
What's Changed
- Feature/fix cross compilation by @godardt in #90
- Add fakeroot pre-flight check and service stop/uninstall commands by @godardt in #91
- Final implementation for containers by @godardt in #88
- fix: auto-create host-side bind mount source directories by @godardt in #92
- Replace fixed timeouts with idle + max timeout model for node by @godardt in #93
- Fix python libs by @godardt in #95
- Optimize codegen by @godardt in #96
- Fix containers warnings by @godardt in #97
- fix: move DEBIAN_FRONTEND export to %post section in apptainer templates by @godardt in #98
- rename: daemon-node crate and related identifiers renamed to core-node by @godardt in #99
- Add Lima VM cross-compilation for multi-target releases by @godardt in #100
- Release v0.4.0 by @godardt in #101
Full Changelog: https://github.com/Peppy-bot/peppy/commits/v0.4.0
v0.3.6 (Alpha): Optimize PeppyOS internal behavior
- sccache support
- Optimize
node addcommand - Update Python node template to use direct venv execution
- Add external JSON parameter loading for standalone nodes in Python and Rust
v0.3.5 (Alpha): Trim Rust nodes size
v0.3.4 (Alpha): Optimize crates boundary crossing with Rust nodes
v0.3.0 (Alpha): Python support
- Add python support
- Rust codegen refactor
- Rename master-node to daemon-node
- Remove extra deps in nodes
v0.3.1 (Alpha): Add Python support with macOS (aarch64) and Linux (x86_64/aarch64) support
- Add python support
- Rust codegen refactor
- Rename master-node to daemon-node
- Remove extra deps in nodes
v0.3.2 (Alpha): Fix missing binaries for Python
v0.3.3 (Alpha): Support dataclass instances in with_parameters method in Python
v0.2.17 (Alpha): Fix for names-generator
v0.2.18 (Alpha): Update all dependencies
v0.2.15 (Alpha): Add interfaces integrity
v0.2.13 (Alpha): Add dependency check to add command
v0.2.14 (Alpha): Add user defined timeouts to add/start and launch cmd
v0.2.12 (Alpha): Fix add_cmd and start_cmd user vars
Fixed user variables not being properly applied in add_cmd and start_cmd operations.
v0.2.11 (Alpha): Update docs & add optimizations
Implement internal code optimizations
v0.2.10 (Alpha): Initial alpha release of PeppyOS
Features
- Core node system with Rust support
- Topic-based communication between nodes
- Service and action patterns
- Parameter system for node configuration
- Launch files for multi-node orchestration
- Node stack management
- Standalone node execution mode
- CLI tools for project management