fix: correct plugin marketplace attribution (#2926)
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
---
|
||||
spec: docs/specs/plugins/marketplace.md
|
||||
created: 2026-08-22
|
||||
status: building
|
||||
---
|
||||
|
||||
# Implementation Plan: Correct plugin marketplace attribution
|
||||
|
||||
## Overview
|
||||
|
||||
Correct the release manifests that feed the marketplace's visible author and
|
||||
repository metadata. The Kandev host registry pointer remains unchanged: the
|
||||
Bitbucket entry is already a first-party `kdlbs` repository, and the YouTrack
|
||||
entry must continue to point to the external contributor's repository. The
|
||||
changes land in the two plugin repositories, then the existing release
|
||||
workflows and registry builder verify that the catalog displays the corrected
|
||||
identities.
|
||||
|
||||
## Repository boundaries
|
||||
|
||||
- `kdlbs/kandev-plugin-bitbucket` owns the first-party Bitbucket manifest.
|
||||
- `ahmedbally/kandev-plugin-youtrack` owns the community YouTrack manifest.
|
||||
- `kdlbs/kandev` owns only the marketplace contract and verification. No new
|
||||
author override is added to `plugin-registry/plugins.yaml`; release manifest
|
||||
metadata remains authoritative.
|
||||
|
||||
## Plugin repository changes
|
||||
|
||||
### First-party Bitbucket attribution
|
||||
|
||||
In `kdlbs/kandev-plugin-bitbucket/manifest.yaml`, change the author from
|
||||
`kdlbs` to `kandev` and preserve the existing repository URL. Produce the next
|
||||
release through that repository's existing release workflow so the latest
|
||||
release tag and tarball contain the corrected manifest.
|
||||
|
||||
### Community YouTrack attribution
|
||||
|
||||
In `ahmedbally/kandev-plugin-youtrack/manifest.yaml`, change the author to the
|
||||
contributor handle `ahmedbally` and change `repo_url` to
|
||||
`https://github.com/ahmedbally/kandev-plugin-youtrack`. Produce a new release
|
||||
through the repository's existing release workflow so the registry's latest
|
||||
release lookup sees the corrected manifest.
|
||||
|
||||
## Tests
|
||||
|
||||
- **What:** The registry builder preserves a release manifest's declared author
|
||||
and emits the repository selected by the registry pointer.
|
||||
**File:** `plugin-registry/build-index.test.mjs` (existing coverage) and the
|
||||
generated `plugin-registry/index.json` after release publication.
|
||||
**How:** Run the focused Node test suite, then rebuild the live catalog and
|
||||
inspect the Bitbucket and YouTrack records for `author` and `repo_url`.
|
||||
- **What:** The first-party plugin still packages successfully after its
|
||||
manifest metadata change.
|
||||
**File:** `kdlbs/kandev-plugin-bitbucket` repository tests and package gate.
|
||||
**How:** Run `make test` and `make package-host verify-package-host`.
|
||||
- **What:** The community plugin still builds and passes its existing checks
|
||||
after its manifest metadata change.
|
||||
**File:** `ahmedbally/kandev-plugin-youtrack` repository tests.
|
||||
**How:** Run `go test ./...`, `go vet ./...`, and the release workflow's
|
||||
package step when publishing the new release.
|
||||
- **What:** The unchanged marketplace card renders the corrected author and
|
||||
repository link values.
|
||||
**File:** `apps/web/components/settings/plugins/marketplace-entry-row.test.tsx`.
|
||||
**How:** Run the existing focused component test after the catalog records
|
||||
are rebuilt; no component or layout change is expected.
|
||||
|
||||
## E2E and mobile parity
|
||||
|
||||
The repair changes release metadata only. It does not change the marketplace
|
||||
card's markup, interaction, navigation, responsive composition, or touch
|
||||
targets. The existing component test plus the post-release catalog inspection
|
||||
are the appropriate evidence; a new desktop or mobile Playwright flow would
|
||||
duplicate unchanged UI behavior.
|
||||
|
||||
## Verification Results
|
||||
|
||||
- 2026-08-22: Bitbucket branch `fix/marketplace-author` changes only
|
||||
`manifest.yaml`, declaring `author: "kandev"` while preserving the official
|
||||
repository URL. `make test`, `make package-host verify-package-host`,
|
||||
`make fmt`, and `make vet` pass. The package gate produced
|
||||
`kandev-plugin-bitbucket-0.2.1.tar.gz` with the corrected manifest.
|
||||
- 2026-08-22: YouTrack fork branch
|
||||
`fix/correct-marketplace-attribution` changes `manifest.yaml` to version
|
||||
`0.1.1`, author `ahmedbally`, and the external repository URL. README build
|
||||
references were updated for the new release version. `go test ./...`
|
||||
passes all 25 tests and `go vet ./...` passes. The temporary local SDK
|
||||
replacement and generated `go.sum` used for verification were removed.
|
||||
- 2026-08-22: Kandev verification passes with 8 registry-builder tests and 3
|
||||
marketplace-entry-row tests. `pnpm install --frozen-lockfile` also passes.
|
||||
- Live catalog records remain pending the two release publications. The
|
||||
existing registry pointer file was not changed; once the releases are
|
||||
published, rebuild the catalog and verify both author and repository fields.
|
||||
|
||||
## Implementation Waves And Parallel Candidates
|
||||
|
||||
Wave 1 contains two disjoint plugin-repository changes. They are marked as
|
||||
parallel-safe for planning purposes, but the primary session executes them
|
||||
sequentially unless the user explicitly authorizes delegation.
|
||||
|
||||
- [ ] [task-01-bitbucket-attribution](task-01-bitbucket-attribution.md) -
|
||||
in progress; local fix complete, release publication follows merge
|
||||
- [ ] [task-02-youtrack-attribution](task-02-youtrack-attribution.md) -
|
||||
in progress; local fix complete, upstream maintainer release publication
|
||||
follows merge
|
||||
|
||||
Wave 2 verifies the published releases and regenerated catalog:
|
||||
|
||||
- [ ] [task-03-registry-verification](task-03-registry-verification.md) -
|
||||
pending; blocked until the two corrected releases are published
|
||||
|
||||
## Open Questions
|
||||
|
||||
- The YouTrack repository is controlled by an external contributor. The source
|
||||
change can be prepared in an attached branch, but merging it and publishing
|
||||
its release remain subject to that repository's maintainer access.
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: "01-bitbucket-attribution"
|
||||
title: "Correct Bitbucket attribution"
|
||||
status: in_progress
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/plugins/marketplace.md"
|
||||
---
|
||||
|
||||
# Task 01: Correct Bitbucket attribution
|
||||
|
||||
## Acceptance
|
||||
|
||||
- `kdlbs/kandev-plugin-bitbucket/manifest.yaml` declares `author: "kandev"`.
|
||||
- The manifest continues to point at
|
||||
`https://github.com/kdlbs/kandev-plugin-bitbucket` and keeps its plugin id,
|
||||
capabilities, and package contract unchanged.
|
||||
- A newly published release contains the corrected manifest, so the official
|
||||
catalog can display `by kandev`.
|
||||
|
||||
## Verification
|
||||
|
||||
From the attached Bitbucket plugin worktree:
|
||||
|
||||
```bash
|
||||
make test
|
||||
make package-host verify-package-host
|
||||
```
|
||||
|
||||
Then run the repository's existing release workflow to publish the next
|
||||
release. Do not hand-edit generated changelog or release metadata when the
|
||||
workflow owns those files.
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `kdlbs/kandev-plugin-bitbucket/manifest.yaml`
|
||||
- Release metadata generated by the plugin repository's existing release
|
||||
workflow, if that workflow is run as part of implementation.
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Parallelism
|
||||
|
||||
parallel-safe with task 02 because it uses a separate repository and no shared
|
||||
registry files. The primary session remains sequential by default.
|
||||
|
||||
## Inputs
|
||||
|
||||
- `docs/specs/plugins/marketplace.md`, catalog attribution scenarios.
|
||||
- `docs/plans/plugin-marketplace-attribution/plan.md`, repository boundary and
|
||||
release requirements.
|
||||
- The plugin repository's `manifest.yaml`, `Makefile`, and release workflow.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report the branch/repository, exact files changed, release tag or publication
|
||||
blocker, commands and results, package path, and task/plan status update.
|
||||
|
||||
## Results
|
||||
|
||||
2026-08-22: Updated `manifest.yaml` on branch `fix/marketplace-author` in
|
||||
`kdlbs/kandev-plugin-bitbucket` to declare `author: "kandev"`. The existing
|
||||
plugin id, capabilities, version, and repository URL are unchanged.
|
||||
|
||||
Verification passed:
|
||||
|
||||
- `make test`
|
||||
- `make package-host verify-package-host`
|
||||
- `make fmt`
|
||||
- `make vet`
|
||||
|
||||
The package gate produced `kandev-plugin-bitbucket-0.2.1.tar.gz` and confirmed
|
||||
the packaged manifest. The next release still must be published through the
|
||||
repository workflow after the PR is merged.
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
id: "02-youtrack-attribution"
|
||||
title: "Correct YouTrack attribution"
|
||||
status: in_progress
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/plugins/marketplace.md"
|
||||
---
|
||||
|
||||
# Task 02: Correct YouTrack attribution
|
||||
|
||||
## Acceptance
|
||||
|
||||
- `ahmedbally/kandev-plugin-youtrack/manifest.yaml` declares
|
||||
`author: "ahmedbally"`.
|
||||
- The manifest declares
|
||||
`repo_url: "https://github.com/ahmedbally/kandev-plugin-youtrack"` and keeps
|
||||
the plugin id, capabilities, and package contract unchanged.
|
||||
- A newly published release contains the corrected manifest, so the official
|
||||
catalog displays the external contributor and links to the external repo.
|
||||
|
||||
## Verification
|
||||
|
||||
From the attached YouTrack plugin worktree:
|
||||
|
||||
```bash
|
||||
go test ./...
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
Then run the repository's existing release workflow to publish a new release
|
||||
containing the manifest. If the external repository cannot be attached or its
|
||||
maintainer cannot publish the release, report that as the task blocker instead
|
||||
of changing the Kandev registry to misrepresent ownership.
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `ahmedbally/kandev-plugin-youtrack/manifest.yaml`
|
||||
- Release metadata generated by the plugin repository's existing release
|
||||
workflow, if that workflow is run as part of implementation.
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Parallelism
|
||||
|
||||
parallel-safe with task 01 because it uses a separate repository and no shared
|
||||
registry files. The primary session remains sequential by default.
|
||||
|
||||
## Inputs
|
||||
|
||||
- `docs/specs/plugins/marketplace.md`, catalog attribution scenarios.
|
||||
- `docs/plans/plugin-marketplace-attribution/plan.md`, external ownership and
|
||||
release requirements.
|
||||
- The plugin repository's `manifest.yaml`, `Makefile`, and release workflow.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report the branch/repository, exact files changed, release tag or maintainer
|
||||
access blocker, commands and results, package path, and task/plan status update.
|
||||
|
||||
## Results
|
||||
|
||||
2026-08-22: Updated the external contributor fork branch
|
||||
`fix/correct-marketplace-attribution` in `ahmedbally/kandev-plugin-youtrack`.
|
||||
The manifest now uses version `0.1.1`, author `ahmedbally`, and
|
||||
`https://github.com/ahmedbally/kandev-plugin-youtrack`. README build references
|
||||
were updated for the new release version; plugin behavior and capabilities are
|
||||
unchanged.
|
||||
|
||||
Verification passed:
|
||||
|
||||
- `go test ./...` (25 tests)
|
||||
- `go vet ./...`
|
||||
|
||||
The fork cannot publish the upstream release directly. The upstream maintainer
|
||||
must merge the PR and run the existing release workflow before the official
|
||||
catalog can observe the corrected metadata.
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
id: "03-registry-verification"
|
||||
title: "Verify regenerated catalog attribution"
|
||||
status: pending
|
||||
wave: 2
|
||||
depends_on: ["01-bitbucket-attribution", "02-youtrack-attribution"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/plugins/marketplace.md"
|
||||
---
|
||||
|
||||
# Task 03: Verify regenerated catalog attribution
|
||||
|
||||
## Acceptance
|
||||
|
||||
- The generated official catalog record for Bitbucket has
|
||||
`author: "kandev"` and `repo_url: "https://github.com/kdlbs/kandev-plugin-bitbucket"`.
|
||||
- The generated official catalog record for YouTrack has
|
||||
`author: "ahmedbally"` and
|
||||
`repo_url: "https://github.com/ahmedbally/kandev-plugin-youtrack"`.
|
||||
- `plugin-registry/plugins.yaml` remains a pointer list with no author override
|
||||
or ownership rewrite.
|
||||
|
||||
## Verification
|
||||
|
||||
From the Kandev repository:
|
||||
|
||||
```bash
|
||||
node --test plugin-registry/build-index.test.mjs
|
||||
cd apps && pnpm install --frozen-lockfile
|
||||
pnpm --filter @kandev/web test -- --run components/settings/plugins/marketplace-entry-row.test.tsx
|
||||
```
|
||||
|
||||
After both releases are published, run `node plugin-registry/build-index.mjs`
|
||||
with the normal GitHub API credentials and inspect the two records in the
|
||||
generated `plugin-registry/index.json`. Preserve or remove the generated file
|
||||
according to the existing registry workflow and `.gitignore` policy. Finish
|
||||
with `git diff --check`.
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- No Kandev production source files are expected.
|
||||
- `plugin-registry/index.json` is a generated verification artifact only.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Tasks 01 and 02, including their release artifacts.
|
||||
|
||||
## Parallelism
|
||||
|
||||
sequential. The task depends on both external release outputs and reads the
|
||||
shared official catalog.
|
||||
|
||||
## Inputs
|
||||
|
||||
- `docs/specs/plugins/marketplace.md`, author and repository scenarios.
|
||||
- `plugin-registry/build-index.mjs`, release-manifest enrichment behavior.
|
||||
- `apps/web/components/settings/plugins/marketplace-entry-row.tsx`, unchanged
|
||||
presentation consumer.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report the exact catalog records, commands and results, generated-artifact
|
||||
handling, `git diff --check` result, and synchronized task/plan statuses.
|
||||
|
||||
## Results
|
||||
|
||||
2026-08-22: Local verification passed with:
|
||||
|
||||
- `node --test plugin-registry/build-index.test.mjs` (8 tests)
|
||||
- `cd apps && pnpm install --frozen-lockfile`
|
||||
- `pnpm --filter @kandev/web test -- --run components/settings/plugins/marketplace-entry-row.test.tsx` (3 tests)
|
||||
- `git diff --check`
|
||||
|
||||
The live catalog rebuild is blocked until the Bitbucket and YouTrack release
|
||||
publications exist. `plugin-registry/plugins.yaml` remains unchanged and
|
||||
contains no author override.
|
||||
@@ -36,6 +36,18 @@ while keeping install-by-URL and sideloading as escape hatches.
|
||||
or actively-maintained plugins are not buried under older high-star incumbents.
|
||||
- Each catalog entry shows: display name, description, author, categories, the source
|
||||
repository link, the latest published version, and its star count.
|
||||
- Release authors and registry reviewers SHALL apply the attribution convention:
|
||||
first-party `kdlbs/kandev-plugin-*` releases declare `author: "kandev"`,
|
||||
community releases declare the contributor's stable identity, and a plugin is
|
||||
not labeled `kandev` only because a maintainer curated it into the official
|
||||
source. This is a release and curation check, not an index-builder ownership
|
||||
validation rule. The builder preserves a declared manifest author and falls
|
||||
back to the repository owner for legacy releases without one.
|
||||
- The catalog source repository link SHALL identify the repository named by the
|
||||
registry entry. The index builder derives this value from the registry pointer.
|
||||
A release manifest's `repo_url`, when present, SHOULD identify the same
|
||||
repository so installed and marketplace views do not disagree; release and
|
||||
registry review is responsible for flagging mismatches.
|
||||
- Installing from the catalog SHALL be **one click**: it resolves to the plugin's
|
||||
latest release tarball URL and runs the existing verified install pipeline
|
||||
(`POST /api/plugins/install`). No new install mechanism is introduced.
|
||||
@@ -119,7 +131,7 @@ This is the fetch contract between a marketplace source and kandev. Additional
|
||||
"id": "agent-stats",
|
||||
"name": "Agent Stats", // from manifest display_name
|
||||
"description": "Per-session token & LOC dashboard",
|
||||
"author": "kandev",
|
||||
"author": "kandev", // from the release manifest
|
||||
"categories": ["analytics"],
|
||||
"icon_url": "https://raw.githubusercontent.com/kdlbs/kandev-plugin-agent-stats/v1.4.0/icon.svg",
|
||||
"repo_url": "https://github.com/kdlbs/kandev-plugin-agent-stats",
|
||||
@@ -300,6 +312,14 @@ response but stays `enabled`.
|
||||
- **GIVEN** a PR that adds an entry to `plugins.yaml` whose `id` does not match the
|
||||
target repo's latest-release manifest `id`, **WHEN** registry CI runs, **THEN** the
|
||||
schema/consistency check fails and the PR is blocked.
|
||||
- **GIVEN** the latest release of the first-party Bitbucket plugin declares
|
||||
`author: "kandev"` and its `repo_url` points to `kdlbs/kandev-plugin-bitbucket`,
|
||||
**WHEN** the official index is built, **THEN** the catalog shows **by kandev** and
|
||||
links to the `kdlbs` Bitbucket repository.
|
||||
- **GIVEN** the latest release of the community YouTrack plugin is owned by
|
||||
`ahmedbally` and declares `author: "ahmedbally"` with its matching repository URL,
|
||||
**WHEN** the official index is built, **THEN** the catalog shows **by ahmedbally**
|
||||
and links to `ahmedbally/kandev-plugin-youtrack`, not a `kdlbs` repository.
|
||||
|
||||
## Auto-update (opt-in)
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ test("buildEntry resolves release, manifest, icon_url and stars", async () => {
|
||||
published_at: "2026-01-01T00:00:00Z",
|
||||
assets: [{ name: "foo-1.2.0.tar.gz", browser_download_url: "https://dl/foo-1.2.0.tar.gz" }],
|
||||
},
|
||||
manifestText: "display_name: Foo\ndescription: A foo\nicon: icon.svg\ncategories: [x]",
|
||||
manifestText: "display_name: Foo\ndescription: A foo\nauthor: kandev\nicon: icon.svg\ncategories: [x]",
|
||||
repoMeta: { stargazers_count: 42, pushed_at: "2026-02-02T00:00:00Z", owner: { login: "acme" } },
|
||||
});
|
||||
|
||||
@@ -97,6 +97,7 @@ test("buildEntry resolves release, manifest, icon_url and stars", async () => {
|
||||
assert.equal(error, undefined);
|
||||
assert.equal(record.name, "Foo");
|
||||
assert.equal(record.version, "1.2.0");
|
||||
assert.equal(record.author, "kandev");
|
||||
assert.equal(record.package_url, "https://dl/foo-1.2.0.tar.gz");
|
||||
assert.equal(record.icon_url, "https://raw.githubusercontent.com/acme/foo/v1.2.0/icon.svg");
|
||||
assert.equal(record.stars, 42);
|
||||
@@ -119,6 +120,7 @@ test("buildEntry keeps stars null (never 0) when repo metadata lookup fails", as
|
||||
});
|
||||
const { record } = await buildEntry({ id: "foo", repo: "acme/foo" });
|
||||
assert.equal(record.stars, null);
|
||||
assert.equal(record.author, "acme"); // legacy fallback when the manifest has no author
|
||||
assert.equal(record.icon_url, null); // no manifest icon
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user