Skip to content

chore(packmind): nightly artifacts update#364

Open
github-actions[bot] wants to merge 2815 commits into
mainfrom
packmind-cli-update
Open

chore(packmind): nightly artifacts update#364
github-actions[bot] wants to merge 2815 commits into
mainfrom
packmind-cli-update

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Automated update of Packmind artifacts via packmind-cli install. Review the diff under .packmind/ and packmind-lock.json.

quentinlebourles-packmind and others added 30 commits June 3, 2026 15:06
Sprint group G2 (feature-flag) for feature remove-published-plugin-from-marketplace.

Completed tasks:
- 1.7: Declare MARKETPLACE_PLUGIN_REMOVAL_FEATURE_KEY feature flag

Refs: tmp/feature-specs/remove-published-plugin-from-marketplace/

Co-Authored-By: Claude <noreply@anthropic.com>
Sprint group G3 (migrations) for feature remove-published-plugin-from-marketplace.

Completed tasks:
- 2.5: No-op migration documenting new distribution lifecycle states (to_be_removed, removed)

Refs: tmp/feature-specs/remove-published-plugin-from-marketplace/

Co-Authored-By: Claude <noreply@anthropic.com>
Sprint group G9 (docs) for feature remove-published-plugin-from-marketplace.

Completed tasks:
- 9.1: Add "Retire a plugin" end-user documentation
- 9.2: CHANGELOG entry under [Unreleased]

Refs: tmp/feature-specs/remove-published-plugin-from-marketplace/

Co-Authored-By: Claude <noreply@anthropic.com>
…ft detection

Sprint group G4 (backend-deployments) for feature remove-published-plugin-from-marketplace.

Completed tasks:
- 2.1: Extend IMarketplaceDistributionRepository with new finders
- 2.2: Implement new finders in MarketplaceDistributionRepository
- 2.3: Distribution test factory .toBeRemoved() / .removed() helpers
- 2.4: Repository spec covering new finders and status transitions
- 3.1: markPluginForRemoval use case
- 3.2: markPluginForRemoval spec
- 3.3: cancelPluginRemoval use case
- 3.4: cancelPluginRemoval spec
- 3.5: listMarketplaceDistributions use case
- 3.6: listMarketplaceDistributions spec
- 3.7: Emit PackagesDeletedEvent from DeletePackagesBatchUsecase
- 3.8: DeletePackagesBatchUsecase spec for event emission
- 3.9: PackageDeletedDistributionsListener
- 3.10: Listener spec
- 3.11: Extend MarketplaceReconciliationDelayedJob with distribution cross-check
- 3.12: Reconciliation job spec
- 3.13: Wire new use cases + listener into DeploymentsHexa
- 3.14: Expose new methods on DeploymentsAdapter
- 3.15: Adapter spec for new methods

Notes:
- MarketplaceDescriptor gained optional driftedPluginSlugs?: string[] for drift persistence.
- MarketplaceReconciliationJobFactory and DeploymentsAdapter constructors now take IMarketplaceDistributionRepository.

Refs: tmp/feature-specs/remove-published-plugin-from-marketplace/

Co-Authored-By: Claude <noreply@anthropic.com>
Sprint group G5 (amplitude) for feature remove-published-plugin-from-marketplace.

Completed tasks:
- 4.1: Subscribe Amplitude listener to MarketplacePluginRemovalInitiatedEvent
- 4.2: Amplitude listener spec

Refs: tmp/feature-specs/remove-published-plugin-from-marketplace/

Co-Authored-By: Claude <noreply@anthropic.com>
Sprint group G6 (api-marketplaces) for feature remove-published-plugin-from-marketplace.

Completed tasks:
- 5.1: Add marketplace removal routes to controller (GET distributions, POST removal by distribution/package, DELETE removal)
- 5.2: Controller spec covering new routes + error mapping

Refs: tmp/feature-specs/remove-published-plugin-from-marketplace/

Co-Authored-By: Claude <noreply@anthropic.com>
Sprint group G7 (frontend-marketplaces) for feature remove-published-plugin-from-marketplace.

Completed tasks:
- 6.1: Extend marketplace gateway interface + impl
- 6.2: Add distribution query options + removal/cancel mutation hooks
- 6.3: Queries spec
- 7.1: DistributionStatusBadge component + spec
- 7.2: RemovePluginButton component + spec
- 7.3: CancelRemovalButton component + spec
- 7.4: MarketplaceDistributionsTable component + spec
- 7.5: MarketplaceDetailsHeader component + spec
- 7.6: Extend MarketplaceStateBadge with driftedPluginSlugs tooltip
- 7.7: Link MarketplaceRow name to details route
- 7.8: New marketplace details route
- 7.9: PackageMarketplaceDistributions component + spec
- 7.10: Insert PackageMarketplaceDistributions in package details page (flag-gated)

All action regions gated behind <PMFeatureFlag featureKeys={[MARKETPLACE_PLUGIN_REMOVAL_FEATURE_KEY]}>.

Refs: tmp/feature-specs/remove-published-plugin-from-marketplace/

Co-Authored-By: Claude <noreply@anthropic.com>
Sprint group G8 (integration-tests) for feature remove-published-plugin-from-marketplace.

Completed tasks:
- 8.1: Removal → reconciliation path
- 8.2: Drift detection on direct repo delete
- 8.3: Cancellation reverts state
- 8.4: Package-delete cascade across marketplaces
- 8.5: Both manual-trigger routes (by-distributionId and by-packageId)

Notes:
- Registered MarketplaceDistributionSchema in deploymentsSchemas barrel so the
  integration-test datasource synchronizes the table (was wired into
  DeploymentsHexa but missing from the schemas index).
- 8.1: when a to_be_removed slug disappears from the descriptor the descriptor
  itself diffs, so the marketplace lands in 'drift' rather than 'healthy'; the
  test asserts the AC10 invariant (driftedPluginSlugs stays undefined — expected
  removals are suppressed from drift).

Refs: tmp/feature-specs/remove-published-plugin-from-marketplace/

Co-Authored-By: Claude <noreply@anthropic.com>
Reword the PackagesDeletedEvent comment and its emission site to the generic
wording used in the OSS repo so the shared files are byte-identical across
repos and the OSS→proprietary sync merges cleanly (no add/add or overlapping
-edit conflict). No behavior change.

Co-Authored-By: Claude <noreply@anthropic.com>
The removal/cancel actions were gated behind <PMFeatureFlag> but only
featureKeys was passed — the required featureDomainMap and userEmail were
missing, so the flag resolved to false and hid the actions for everyone.
Wire the auth context + DEFAULT_FEATURE_DOMAIN_MAP on both the marketplace
distributions table and the package Distributions tab.

Also fix latent type errors swc did not catch: add the to_be_removed/removed
keys to PackageArtifactsTable's status-badge map, widen PMConfirmationModal
message to ReactNode, and drop a dead __testables__ export.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nc PR

Marking a distribution for removal (and the package-delete cascade) now
enqueues RemovePluginFromMarketplaceDelayedJob, which drops the plugin from
the descriptor and deletes its plugins/<slug>/ directory on the packmind/sync
branch — symmetric to publishing, so the rolling Packmind sync PR updates
automatically instead of requiring a manual CLI deletion.

The job reads the descriptor from the sync branch (so it stacks on pending
publishes rather than clobbering them) and uses the distribution's stored
pluginSlug, so the package-deletion cascade works even though the package is
already gone. The distribution stays to_be_removed; reconciliation owns the
terminal removed transition once the PR merges.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The close-effect depended on the whole `publishMutation` object, which
react-query returns as a fresh reference every render. That made the
effect re-run each render and call `reset()`, re-rendering into a
"Maximum update depth exceeded" loop. Depend on the stable `reset`
callback instead, and add a regression test using the real mutation hook.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The test waited a fixed 50ms for a fire-and-forget cascade and left the
removal job's addJob unmocked, so under the SyncJob harness it ran real
git ops inline between the two distribution updates. Combined with the
non-deterministic findActiveByPackageId ordering, the row processed
second raced the sleep. Stub addJob and replace the sleep with
condition-based polling on the observable outcome.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sprint group D (integration tests + changelog) for feature
`publish-package-as-managed-plugin`.

Add six integration specs under packages/integration-tests/src/deployments/
that drive the publish use case + delayed job inline against a real datasource
with a mocked IGitPort. Scenarios match the PRD engineering checklist:
rolling-PR amend (two publishes converge to one PR, status='success' on
both rows, prUrl shared), no-op idempotency (NO_CHANGES_DETECTED →
status='no_changes', wasNoop=true event), descriptor missing → marketplace
state flipped to 'bad_format' + no row left in success, expired token
preflight (synchronous failure, no row, no enqueue, no token in error
strings), name collision with an unmanaged plugin (no PR opened), two
concurrent publishers (single rolling PR with ordered commits, both rows
end success, both plugins land in descriptor.plugins).

Add a CHANGELOG entry under Unreleased / Added.

End-user docs (apps/doc/) intentionally left out of this commit — the
feature is still gated by the marketplace feature flag and the docs will
be merged on a separate branch once the flag opens to the public.

Completed tasks:
- 4.1: Integration test — rolling-PR amend
- 4.2: Integration test — no-op idempotency
- 4.3: Integration test — descriptor missing → bad_format
- 4.4: Integration test — expired token preflight
- 4.5: Integration test — name collision with unmanaged plugin
- 4.6: Integration test — two concurrent publishers
- 4.7: DEFERRED — end-user docs held on a branch until the feature flag opens
- 4.8: Update CHANGELOG.md Unreleased

Refs: GH-580, tmp/feature-specs/publish-package-as-managed-plugin/

Co-Authored-By: Claude <noreply@anthropic.com>
…packmind-lock.json

Lift the Packmind publish-tracking metadata out of `marketplace.json` —
the vendor (Anthropic) descriptor schema should not carry non-standard
fields. Replace the embedded `packmindLock` with a dedicated
`/packmind-lock.json` file at the marketplace repo root that records,
per published plugin, the version, content hash, last-publish timestamp,
and last-publisher user id.

Schema stays unchanged (just lifted to its own file):
```
{
  schemaVersion: 1,
  plugins: Record<pluginSlug, {
    version, contentHash, lastPublishedAt, lastPublishedBy
  }>
}
```

Key changes:
- `MarketplaceDescriptor` drops the `packmindLock` field; new
  `PackmindMarketplaceLock` type lives next to it in `@packmind/types`.
- New `packmindMarketplaceLock.ts` service handles parse / serialize /
  fetch (missing file = empty lock → normal first-publish flow). Companion
  `applyPackmindMarketplaceLockMutation.ts` provides pure add + remove
  helpers used by both the publish and unpublish jobs.
- `AnthropicMarketplaceDescriptorParser` becomes single-purpose again;
  legacy `packmindLock` fields on existing descriptors round-trip via
  `raw` and get silently stripped from the descriptor on the next
  publish (no migration needed — feature is feature-flagged to internal
  users).
- `PluginDescriptorMutator` shrinks: no more lock handling, just
  upserts `descriptor.plugins[]`.
- Publish job + use case now fetch the lock alongside the descriptor;
  the name-collision check consults `lock.plugins`; the job commits
  both the updated descriptor and the updated lock in the same
  `commitToGit` call. A malformed lock maps to
  `MarketplaceDescriptorBadFormatError` (marketplace is unhealthy).
- Unpublish job (`RemovePluginFromMarketplaceDelayedJob`) follows the
  same model: drops the slug from the lock, strips any legacy
  embedded field from the descriptor, commits both files together.
  Falls back to an empty lock on parse failure (cleanup must not be
  blocked by lock corruption — different policy from publish).
- Integration specs updated: 6 publish-flow specs now mock the lock
  via path-aware `getFileFromRepo`; the rolling-PR + concurrent specs
  additionally assert that the standalone lock accumulates entries
  across publishes — closing the parser round-trip gap that was
  flagged at the end of group D.

Refs: GH-580, tmp/feature-specs/publish-package-as-managed-plugin/

Co-Authored-By: Claude <noreply@anthropic.com>
⚠️ Sync from upstream repository (conflicts to resolve)
The published `marketplace.json` was emitting bare plugin entries
(`{ slug, name, version }`), which Claude Code's plugin installer
rejects — installs failed locally on the marketplace consumer side.

Each Packmind-managed plugin entry now carries a `source` block with
the Claude Code git-subdir shape:

```json
{
  "slug": "<plugin>",
  "name": "<plugin>",
  "version": "0.1.0",
  "source": {
    "source": "git-subdir",
    "url": "https://github.com/<owner>/<repo>.git",
    "path": "plugins/<plugin>"
  }
}
```

- `PluginRef` gains an optional `source: PluginSource` field
  (`{ source: 'git-subdir'; url; path }`); legacy entries on disk that
  lack it round-trip unchanged so existing unmanaged plugins are
  preserved.
- `AnthropicMarketplaceDescriptorParser` now reads/writes the source
  field on every plugin entry it touches.
- `applyPluginDescriptorMutation` requires a `pluginSource` parameter,
  so every Packmind-managed publish writes a fully-formed installable
  entry; disk converges on the next republish for any legacy entries.
- Publish job builds the source block at job time: the URL via a
  vendor-aware `buildMarketplaceCloneUrl` helper (GitHub /
  GitLab; mirrors the existing `buildRepositoryWebUrl` switch in
  listMarketplaces, suffixed with `.git`), the path as
  `plugins/<pluginSlug>`.
- Integration specs (rolling-PR, concurrent, no-op) assert the
  installable shape on first publish, on republish, and across
  concurrent publishers.

Refs: GH-580, tmp/feature-specs/publish-package-as-managed-plugin/

Co-Authored-By: Claude <noreply@anthropic.com>
…ranch

Successive marketplace publishes dropped previously-published plugin
entries from `marketplace.json` and `packmind-lock.json`: each publish
read the two files from the marketplace's default branch (where the
previous publish's entries had not yet been merged), mutated, and
overwrote the rolling `packmind/sync` branch with only the current
plugin's data.

Resolve the read branch via a new shared helper
`resolveMarketplaceReadBranch(gitPort, marketplaceGitRepo)` — when the
`packmind/sync` rolling branch exists, the descriptor + lock are read
from it so accumulated entries are preserved; otherwise we fall back
to the marketplace's default branch, which is correct for both
first-publish (empty state) and post-merge-then-republish flows (the
merged entries now live on main).

Applied symmetrically in:
- `PublishPluginToMarketplaceDelayedJob` (descriptor + lock fetch)
- `PublishPackageOnMarketplaceUseCase` (preflight + name-collision)
- `RemovePluginFromMarketplaceDelayedJob` (descriptor + lock fetch)

Plugin folders were already preserved across publishes by GitHub's
`base_tree` inheritance in `commitFiles` — only the descriptor + lock
content was being clobbered. After this fix, the accumulating
descriptor entries match the on-tree plugin folders again, so
consumers can install every previously-published plugin from the same
rolling PR.

Integration specs:
- `rolling-pr.spec.ts` now drives an in-memory descriptor+lock state
  and a `rollingBranchExists` flag flipped by the commit spy; the
  second-publish assertions confirm both plugin slugs survive in both
  files.
- `concurrent.spec.ts` exercises the real accumulation path across two
  parallel publishers.
- Other specs add `checkBranchExists` mocks to stay compatible.

Refs: GH-580, tmp/feature-specs/publish-package-as-managed-plugin/

Co-Authored-By: Claude <noreply@anthropic.com>
cteyton and others added 14 commits June 18, 2026 14:07
Add the search domain types (SearchResult, SearchResponse,
SearchArtifactType, SearchMatchSource) and the ISearchPort hexagonal port
with SearchCommand, completing the untracked search type scaffolding.
Export the search domain from the @packmind/types root barrel so the
frontend gateway can import SearchResponse.

Co-Authored-By: Claude <noreply@anthropic.com>
Add OrganizationsSearchModule with:
- SearchController (GET /organizations/:orgId/search?q=, guarded by
  OrganizationAccessGuard, rejects queries shorter than 2 chars)
- SearchService (resolves the user's member spaces via ISpacesPort and
  builds the spaceSlugById map)
- SearchAdapter (read-only ILIKE QueryBuilders over standards, recipes,
  skills and packages, scoped to the member spaces; recipes join the
  latest RecipeVersion for the command summary; results ordered
  name-match first then description, capped at 15, soft-delete filtered)

Wire the module into OrganizationsModule imports and the AppModule
RouterModule tree as /organizations/:orgId/search.

Co-Authored-By: Claude <noreply@anthropic.com>
Wire the navbar search bar to the org-scoped backend endpoint
GET /api/v0/organizations/:orgId/search via the existing spaces-domain
data-flow pattern.

- SearchGatewayApi extends PackmindGateway and implements ISearchGateway
  (GET /organizations/:orgId/search?q=<term>)
- searchQueryKeys scoped under the organization query scope
- getSearchQueryOptions / useSearchQuery gated on orgId and a trimmed
  term length >= 2, with keepPreviousData to keep results visible while a
  new keystroke is in flight
- complete the pre-existing search domain api barrel (gateway + queries
  + queryKeys)

Co-Authored-By: Claude <noreply@anthropic.com>
Surface a debounced global search bar in a new slim top navbar above the
sidebar/content shell, letting users find any artifact (standard, command,
skill, package) across the spaces they belong to without knowing which space
it lives in.

- TopNavbar: slim PMHStack, background.primary surface + border.tertiary
  divider, holds only the search bar (per the agreed navbar scope)
- GlobalSearchBar: PMInputGroup + PMInput (LuSearch start element), debounced
  (250 ms) search triggered at >=2 chars, results in a PMPopover dropdown
  anchored (not triggered) to the input so refining the query never closes it
- SearchResultRow: bold name + single-line description preview with the
  searched term highlighted (blue.subtle/blue.fg palette), a type badge, and
  click/keyboard navigation to the single-item page (skills by slug, others
  by id)
- highlightMatch util splits case-insensitively and wraps matches with PMText
- useDebouncedValue shared hook (manual setTimeout, no new dependency)
- AuthenticatedLayout wraps sidebar+content in a PMVStack with TopNavbar above

All UI uses @packmind/ui PM-prefixed components and Packmind semantic tokens
only; no raw div/input or hardcoded hex. Renders correctly in the single dark
theme.

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove PACKMIND_EDITION branching in docker.yml and release.yml
- Add OSS tag variants alongside proprietary tags via docker tag
- Always push public (unsuffixed) images on release
- List both OSS and Enterprise image tags in release notes

Co-Authored-By: Claude <noreply@anthropic.com>
…362)

Drive the deploy workflow off github.ref only, dropping the
PACKMIND_EDITION gating. Each main-branch commit now updates the prod
cloud, staging cloud and staging on-prem OSS values together, matching
the unified Docker build that publishes both image variants per run.
Each release tag updates both the OSS and enterprise on-prem values.


Claude-Session: https://claude.ai/code/session_01GnFUbyMuQHkpiRmYXHTN2H

Co-authored-by: Claude <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

PR title or description contains an excluded keyword.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants