patchbay v0.3.0
Added
-
patchbay updates itself — the panel checks the signed release feed a
couple of seconds after launch and, when a newer build exists, says so in a
slim banner above the board:update and relaunch, ornot now. Applying is
always a click — patchbay is a thing you open to answer a question about your
logins, and an update must never be what happens instead — and the banner sits
in the flow rather than over the board, so the answer you came for is never
covered. The download is verified against a minisign public key compiled into
the app before anything is installed, which is the whole reason this is
allowed to be automatic at all. A failed check is silent: an offline machine
has no update to offer, and that is not news.not nowlasts for the session
and is written nowhere, because something you have neither accepted nor
refused should be asked again next launch.pb check-updatesgained the
matching row: patchbay reports its own installed version (the build answering
the question, not whicheverpbis onPATH) against the newest GitHub
release, on the same 24-hour cache and the same shared rate limit as every
other tool. ItsUPDATE WITHis a human instruction — download the DMG, curl
the CLI tarball — the waygcloud's is, rather than a command that does not
exist. -
The panel writes to the key vault —
add keyopens a form (id, provider,
label, a masked secret field, with purpose, scopes, expiry, endpoint and the
rotation checkbox folded away), and every row gets a trash affordance behind
an inline confirm that says what removing does not do: the entry and its
keychain value go, the credential keeps working until you revoke it at the
provider. Both commands (key_add,key_remove) are thin wrappers over the
sameKeyRegistrycalls the CLI makes, so the registry's rules — duplicate id
refused unless you are rotating, empty secret refused, both-or-neither writes —
and its error strings reach the panel verbatim. The vault view no longer tells
you to go and use the command line. The secret exists in the field, the invoke
payload andKeyRegistry::add, and nowhere else: it is cleared on submit,
never logged, never echoed back. The panel still cannot read a value —
get_secretis not wired up, there is no reveal and no copy, andpb key copy
remains the only way one leaves the vault. The old CLI-only rule was about
argv (ps, shell history), and a password field in a native window has
neither. -
The project env vault (
pb env) — the variables a
project needs, held the way the key vault holds credentials: names and
provenance in~/.config/patchbay/projects.json(0600), values in the macOS
Keychain, and no plaintext.envanywhere. A project is a portable name,
not a path: the manifest holds ids, environments and sync config and no
absolute path at all, so copying it to another machine is the supported way to
take your projects with you. Each of its environments has two layers:synced,
whichpb env pullreplaces wholesale from Infisical, andlocal, which you
set by hand and which wins on merge. Those are.env.localsemantics, and
they only hold because patchbay never pushes — there is no code path that
writes a variable to a remote, so a local override is invisible to the cloud
by construction rather than by policy, and a pull can never carry your
container'sDATABASE_URLinto the team's shared set. Values are stored one
Keychain item per project × environment × layer (account
env:<project>/<env>/<local|synced>), holding the whole layer as one JSON
blob, so an export is one Keychain round trip and not one per variable. No
last4is recorded: four characters oftrueor5432is not a hint, it is
the value.pb env pullalso pins the account a project belongs to and checks
it before spending a subprocess — the Infisical CLI's active login is
machine-global, and under the wrong one the API answers 403 with "project does
not belong to your selected organization", which reads like a problem with the
project rather than with the login; patchbay refuses first and names
pb use infisical <email>instead. -
Two ways a directory resolves to a project, in that order. An
attachment (pb env attach <id>/pb env detach) binds a directory on
this machine, in~/.config/patchbay/attachments.json— deepest attached
ancestor wins, several roots per project, so every worktree and second clone
shares one vault. A marker — a committed.patchbay.tomlholding
project = "<id>", written bypb env initunless--no-marker— resolves
a checkout by its content, so a freshgit cloneworks on any machine whose
registry holds that project, with no attach step. An attachment always beats a
marker: a deliberate local act outranks whatever the repo ships, and nothing
in a repo can take that override back. A marker can only name a project the
machine already has, and one that names an unknown project is a loud error
pointing at the machine'sprojects.jsonrather than a silent miss. The
tradeoff, taken deliberately: repo content selects which registered project's
variables the tooling hands out, which assumes you run repos you trust. -
Moving to a new machine is therefore: bring
projects.jsonover, clone the
repo (the marker travels with it),pb env pull.pb exportcarries that
manifest inside the bundle andpb importregisters what is not here yet, so
the migration path is the normal route and copying the file by hand is the
fallback; a project id the destination already has is skipped with a note
rather than overwritten, because the machine in front of you may be the newer
one. What does not travel:attachments.json, since those are paths from
a machine that is not this one; every variable value in either layer; and the
local layer's variable names along with them, because a name with no value
behind it would makepb env listpromise whatpb env runcould not
deliver.SETUP.md, thepb planchecklist and theplan_setupMCP tool
each carry onepb env pull --project <id>per linked project, marked
auto: falseand naming the pinned account — a pull under the wrong
machine-global infisical login fails confusingly, sopb use infisical <email>may have to come first. A project the old machine had unlinked but
with a synced layer is a gap instead: nothing on the new machine can rebuild
it. -
pb env—init(registers the project, attaches this directory, leaves
a marker to commit, picking up.infisical.json),attach,detach,
link,projects,list,pull,set,unset,import,diff,run,
export,forget.initin a worktree of a project this machine already
knows attaches it instead of failing on the duplicate id;forgettakes the
project, its Keychain blobs and this machine's attachments, and leaves
committed markers alone (rm .patchbay.toml).listanddiffanswer from
the name lists alone and never touch the Keychain;settakes its value from
stdin or a hidden prompt, never argv;run -- <cmd>injects the merged
environment into one child process and is the blessed read path, with
export(dotenv or JSON, TTY warning) there for the cases where a file is
genuinely what you need.
import <file>bulk-loads an existing.envinto the local layer,
all-or-nothing, reporting a bad line by number and never by content. -
MCP tools —
list_env_projects,list_env_vars,pull_envand
set_env_var.list_env_projectsreports each project's machine-local
rootsalongside its environments, and says what an empty list means, so an
agent does not read a path there as where the user is working. The first two
are metadata only;pull_envexecutes the Infisical CLI but its outcome
carries counts and names, not values, so it is ungated;
set_env_varis open likestore_key, so an agent that creates a
project credential registers it. Nothing reads a value back — not even behind
PATCHBAY_ALLOW_SECRET_READ. An environment is dozens of secrets at once,
andpb env runin your own terminal is the answer instead.
What's Changed
- [feature] project env vault: pb env with synced/local layers, pull-only Infisical sync, portable manifest by @YJack0000 in #2
- [feature] panel: key vault add/remove — masked secret entry, delete with confirm by @YJack0000 in #3
- [feature] migration: carry the env vault's portable manifest in pb export / import by @YJack0000 in #4
- [feature] panel self-update via tauri-plugin-updater; pb check-updates reports patchbay itself by @YJack0000 in #5
- [chore] release 0.3.0 by @YJack0000 in #6
New Contributors
- @YJack0000 made their first contribution in #2
Full Changelog: v0.2.0...v0.3.0