When core/plugin imported core/internal/api/orchestrator/v1 for the
PluginVisibility enum, every consumer of core/plugin (including the
orchestrator) transitively pulled in core's generated bindings — and
those bindings register the same proto descriptors as the orchestrator's
own bindings, panicking at startup.
Move the label helper into the CLI's cmd package where it belongs;
core/plugin no longer references the proto package at all.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Tracks the shared proto rename that resolves the message-name collision
between PluginAuthService and AccountService.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When the orchestrator imports `block/core/internal/api/orchestrator/v1`
transitively through other core packages and also generates its own
bindings for the same files (accounts.proto etc.), proto registration
panics at startup: "file ... is already registered". Tests in the
orchestrator confirmed this.
Fix:
- buf generate now uses --path to limit core's output to
proto/orchestrator/v1/plugin_registry.proto (see new `make proto`).
- Adds a minimal MyAccount message and PluginAuthService.ListMyAccounts
RPC to plugin_registry.proto (already pushed to block/proto) so the
CLI's account picker no longer needs accounts.proto generated.
- CLI switches back to cli.Auth.ListMyAccounts; orchclient.Client drops
the Account field.
Side effect: every previously-generated orchestrator/v1 binding besides
plugin_registry is removed from this module.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Remove core's local proto/ fork and pull the canonical block/proto repo in
as a submodule at the same path. buf.yaml now sources from the submodule's
orchestrator/v1 namespace; everything outside that (blockninja, helpdesk)
is excluded from generation.
This brings the orchestrator's local-only RPCs (PluginScopeService.ListMyPlugins,
PluginRegistryService.SubmitForReview, the full PluginModerationService) into
core's bindings — harmless surface area for the CLI, prerequisite for the
orchestrator to also stop forking the proto.
Side effect: the CLI's account picker now uses the canonical
AccountService.ListMyAccounts in accounts.proto rather than the duplicate
PluginAuthService.ListMyAccounts that lived only in core's fork. The
existing Account message uses Name (no DisplayName / Role), so the picker
output collapses to "slug — Name".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- ninja login forces account selection (interactive when >1); creds now
carry ActiveAccountID/Slug. New `ninja account` group.
- ninja plugin list / delete / delete-version split public vs active-account
@private sections; `publish --private` is sticky in plugin.mod.
- GetPluginRequest gains active_account_id so @private resolution works
alongside the public (scope, name) path.
- publish auto-commits a dirty plugin.mod (path-scoped, leaves other staged
paths alone) so the bump→publish loop never trips the dirty check.
--allow-dirty is replaced with --strict (default now ships dirty trees
via stash-create).
- bump auto-commits its plugin.mod write with `bump to X.Y.Z`; --no-commit
opts out.
- Design doc updated to match the new defaults.
Add private-plugin RPCs (ListPrivatePlugins, DeletePrivatePlugin,
DeletePrivatePluginVersion, ListPrivatePluginInstallSites) and
ListMyAccounts to the proto/generated stubs; introduce PluginVisibility
enum replacing the loose string field; add ModPlugin.Private + Coords()
routing to @private/<name>@<version>; update ninja CLI to use
VisibilityLabel helper; bump go directive to 1.26.4 for ABI alignment.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Proves the publish command's warning surface end-to-end: tracked-yet-
gitignored files, declared submodules, untracked files on --allow-dirty,
and that the dirty-tree abort suppresses the untracked warning.
Pulls the three warning calls and the dirty-tree check out of the
publish RunE closure into a single helper so a refactor that drops one
warning can be caught by a fixture-based test.
Adds coverage for two git-edge cases: commits land correctly on a
detached HEAD with the prior commit as parent, and an empty PATH
produces a git-mentioning error rather than a panic.
Add fires/no-op pairs for gitignoredTrackedWarning, untrackedFilesWarning,
and submoduleWarning. The submodule case writes a hand-crafted .gitmodules
file rather than wiring real submodules — submodulePaths reads the file
directly so that's sufficient.
Pull the three inline warning blocks in newPluginPublishCmd —
gitignoredTrackedWarning, untrackedFilesWarning, submoduleWarning — into
package-private helpers that take a repo dir and an io.Writer. Output is
byte-identical to the previous inline code; this just makes them unit-
testable without driving the whole cobra command.
autoCommitPluginMod runs `git status --porcelain plugin.mod` then commits if
dirty. Add two cases: dirty plugin.mod produces an "Add plugin.mod" commit,
and a clean state leaves HEAD unchanged. Uses t.Chdir to scope CWD to the
temp repo without polluting parent state.
The dirty-tree branch (where git stash create captures uncommitted tracked
changes) was untested. Add two cases: one asserting the archive contains
the dirty working-copy contents (not HEAD) and the working tree is not
mutated; another asserting untracked files are excluded — the contract
the --allow-dirty publish warning relies on.
`git archive` does not recurse into submodules, so a plugin shipping
vendored code via submodule produced a tarball where the submodule path
existed but was empty — silent failure. Now publish reads .gitmodules
and lists submodule paths to stderr with guidance to vendor or pack
them separately. The publish still proceeds, since the developer may
not actually need the submodule contents in the archive.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`git stash create` only captures tracked content, so a developer using
--allow-dirty after creating new files (but forgetting to `git add`)
would ship a tarball missing them with no indication. Now publish lists
the untracked, non-ignored files to stderr and suggests `git add` when
--allow-dirty is in play.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously a brand-new repo (git init, no commits) surfaced `git stash
create: exit status 128: You do not have the initial commit yet` from
deep inside the archive helper. Now the publish flow detects this case
via `git rev-parse --verify HEAD` up front and prints "no commits in
repository; run `git add . && git commit` before publishing". Also
updates the init flow's hint to mention `git init && git commit` so
users aren't misled into thinking `git init` alone is enough.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pre-existing CLI improvements ahead of the tarball-publish refactor:
- New top-level `ninja scope` command (create, list, set-default).
- `init` accepts no --scope: prompts from ListMyScopes or uses creds default.
- Plugin name prompted if not provided.
- `plugin bump <major|minor|patch>` writes the bumped version into plugin.mod.
- `plugin version` prints the current plugin.mod version.
- `login` prints a URL with ?user_code= so the link is one click.
- creds: HostCreds gains optional default_scope.
- plugin/version: ParseBaseSemver + BumpVersion helpers, with tests.