diff --git a/.github/workflows/repair-kitchen-sink-latest.yml b/.github/workflows/repair-kitchen-sink-latest.yml deleted file mode 100644 index 695d8f32..00000000 --- a/.github/workflows/repair-kitchen-sink-latest.yml +++ /dev/null @@ -1,142 +0,0 @@ -name: Repair Kitchen Sink Latest Pointer - -on: - workflow_dispatch: - inputs: - expected_sha: - description: "Exact main SHA containing the repair mutation" - required: true - type: string - apply: - description: "Apply the repair after the dry-run" - required: true - default: false - type: boolean - confirm: - description: "Required confirmation token when apply is true" - required: false - type: string - -concurrency: - group: repair-kitchen-sink-latest - cancel-in-progress: false - -permissions: - contents: read - -jobs: - repair: - runs-on: ubuntu-latest - timeout-minutes: 15 - environment: - name: Production - url: https://clawhub.ai/packages/%40openclaw%2Fkitchen-sink - steps: - - name: Require exact main revision - env: - EXPECTED_SHA: ${{ inputs.expected_sha }} - run: | - set -euo pipefail - if [[ "$GITHUB_REF" != "refs/heads/main" ]]; then - echo "::error::The repair must run from main." - exit 1 - fi - if [[ "$GITHUB_SHA" != "$EXPECTED_SHA" ]]; then - echo "::error::Main moved: expected $EXPECTED_SHA, got $GITHUB_SHA." - exit 1 - fi - - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 - with: - bun-version: 1.3.10 - - - name: Install - run: bun install --frozen-lockfile - - - name: Dry-run repair - id: preflight - env: - CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_DEPLOY_KEY }} - run: | - set -euo pipefail - if [[ -z "$CONVEX_DEPLOY_KEY" ]]; then - echo "::error::Missing Production environment secret CONVEX_DEPLOY_KEY" - exit 1 - fi - result="$(bunx convex run maintenance:repairPackageLatestPointer \ - '{"name":"@openclaw/kitchen-sink"}' --prod)" - if jq -e ' - .dryRun == true and - .previousLatestVersion == "0.2.11" and - .selectedVersion == "0.2.12" and - .eligibleReleaseCount >= 2 - ' <<< "$result" >/dev/null; then - { - echo "already_repaired=false" - echo "plan_token=$(jq -r '.planToken' <<< "$result")" - } >> "$GITHUB_OUTPUT" - exit 0 - fi - if jq -e ' - .dryRun == true and - .previousLatestVersion == "0.2.12" and - .selectedVersion == "0.2.12" and - (.releaseTagChanges | length) == 0 - ' <<< "$result" >/dev/null; then - echo "already_repaired=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - echo "::error::Production package state did not match the expected pre- or post-repair state." - exit 1 - - - name: Require apply confirmation - if: inputs.apply - env: - CONFIRM: ${{ inputs.confirm }} - run: | - set -euo pipefail - if [[ "$CONFIRM" != "repair-package-latest-pointer-2026-07-30" ]]; then - echo "::error::The exact repair confirmation token is required." - exit 1 - fi - - - name: Apply repair - if: inputs.apply && steps.preflight.outputs.already_repaired != 'true' - env: - CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_DEPLOY_KEY }} - EXPECTED_PLAN_TOKEN: ${{ steps.preflight.outputs.plan_token }} - run: | - set -euo pipefail - required_confirm="repair-package-latest-pointer-2026-07-30" - args="$(jq -nc \ - --arg name "@openclaw/kitchen-sink" \ - --arg confirm "$required_confirm" \ - --arg planToken "$EXPECTED_PLAN_TOKEN" \ - '{ - name: $name, - dryRun: false, - confirm: $confirm, - expectedPlanToken: $planToken - }')" - result="$(bunx convex run maintenance:repairPackageLatestPointer "$args" --prod)" - jq -e ' - .dryRun == false and - .selectedVersion == "0.2.12" - ' <<< "$result" - - - name: Verify repaired state - if: inputs.apply - env: - CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_DEPLOY_KEY }} - run: | - set -euo pipefail - readback="$(bunx convex run maintenance:repairPackageLatestPointer \ - '{"name":"@openclaw/kitchen-sink"}' --prod)" - jq -e ' - .dryRun == true and - .previousLatestVersion == "0.2.12" and - .selectedVersion == "0.2.12" and - (.releaseTagChanges | length) == 0 - ' <<< "$readback" diff --git a/convex/lib/packageArtifacts.ts b/convex/lib/packageArtifacts.ts index c2be59c5..aa7e89df 100644 --- a/convex/lib/packageArtifacts.ts +++ b/convex/lib/packageArtifacts.ts @@ -1,4 +1,3 @@ -import type { PackageArtifactSummary } from "clawhub-schema"; import type { Doc } from "../_generated/dataModel"; type PackageReleaseArtifactHashFields = Pick< @@ -6,20 +5,6 @@ type PackageReleaseArtifactHashFields = Pick< "artifactKind" | "clawpackSha256" | "sha256hash" >; -type PackageReleaseArtifactSummaryFields = Pick< - Doc<"packageReleases">, - | "artifactKind" - | "clawpackSha256" - | "sha256hash" - | "clawpackSize" - | "clawpackFormat" - | "npmIntegrity" - | "npmShasum" - | "npmTarballName" - | "npmUnpackedSize" - | "npmFileCount" ->; - export function getPackageReleaseArtifactSha256( release: PackageReleaseArtifactHashFields, ): string | null { @@ -28,26 +13,3 @@ export function getPackageReleaseArtifactSha256( } return release.sha256hash ?? null; } - -export function summarizePackageReleaseArtifact( - release: PackageReleaseArtifactSummaryFields, -): PackageArtifactSummary { - if (release.artifactKind === "npm-pack") { - return { - kind: "npm-pack", - sha256: getPackageReleaseArtifactSha256(release) ?? undefined, - size: release.clawpackSize, - format: release.clawpackFormat ?? "tgz", - npmIntegrity: release.npmIntegrity, - npmShasum: release.npmShasum, - npmTarballName: release.npmTarballName, - npmUnpackedSize: release.npmUnpackedSize, - npmFileCount: release.npmFileCount, - }; - } - return { - kind: "legacy-zip", - sha256: getPackageReleaseArtifactSha256(release) ?? undefined, - format: "zip", - }; -} diff --git a/convex/maintenance.test.ts b/convex/maintenance.test.ts index e7bbc579..50474a32 100644 --- a/convex/maintenance.test.ts +++ b/convex/maintenance.test.ts @@ -83,7 +83,6 @@ const { applySkillLineageCycleRepairInternalHandler, inspectSkillLineageCycleInternalHandler, nominateEmptySkillSpammersInternalHandler, - repairPackageLatestPointerHandler, repairLegacyPluginSkillSpectorBatchInternalHandler, repairLegacyPublisherOwnershipForUserHandler, repairSkillLineageCyclesInternalHandler, @@ -2007,198 +2006,3 @@ describe("maintenance empty skill nominations", () => { ]); }); }); - -function makePackageLatestPointerRepairDb() { - const pkg = { - _id: "packages:kitchen-sink", - name: "@openclaw/kitchen-sink", - normalizedName: "@openclaw/kitchen-sink", - family: "code-plugin", - tags: { latest: "packageReleases:old" }, - latestReleaseId: "packageReleases:old", - }; - const releases = [ - { - _id: "packageReleases:old", - packageId: pkg._id, - version: "0.2.11", - publicationStatus: "published", - changelog: "old", - summary: "old summary", - icon: "old-icon", - distTags: ["latest"], - compatibility: {}, - verification: {}, - runtimeId: "old-runtime", - sourceRepo: "https://github.com/openclaw/kitchen-sink", - artifactKind: "npm-pack", - clawpackSha256: "old-sha", - clawpackSize: 10, - clawpackFormat: "tgz", - createdAt: 100, - }, - { - _id: "packageReleases:new", - packageId: pkg._id, - version: "0.2.12", - publicationStatus: "published", - changelog: "new", - summary: "new summary", - icon: "new-icon", - distTags: [], - compatibility: {}, - verification: {}, - runtimeId: "new-runtime", - sourceRepo: "https://github.com/openclaw/kitchen-sink", - artifactKind: "npm-pack", - clawpackSha256: "new-sha", - clawpackSize: 20, - clawpackFormat: "tgz", - createdAt: 200, - }, - { - _id: "packageReleases:pending", - packageId: pkg._id, - version: "0.2.13", - publicationStatus: "pending", - changelog: "pending", - distTags: [], - compatibility: {}, - verification: {}, - artifactKind: "npm-pack", - clawpackSha256: "pending-sha", - createdAt: 300, - }, - ]; - const patch = vi.fn(); - const insert = vi.fn(); - const query = vi.fn((table: string) => ({ - withIndex: (_index: string, applyIndex: (q: QueryEq) => unknown) => { - const q = { eq: vi.fn() } as unknown as QueryEq; - vi.mocked(q.eq).mockReturnValue(q); - applyIndex(q); - if (table === "packages") { - return { unique: async () => pkg }; - } - if (table === "packageReleases") { - return { collect: async () => releases }; - } - throw new Error(`Unexpected table: ${table}`); - }, - })); - - return { db: { query, patch, insert }, pkg, releases, patch, insert }; -} - -describe("maintenance package latest pointer repair", () => { - it("dry-runs the canonical published release without writing", async () => { - const fixture = makePackageLatestPointerRepairDb(); - - const result = await repairPackageLatestPointerHandler(fixture as never, { - name: "@openclaw/kitchen-sink", - }); - - expect(result).toMatchObject({ - dryRun: true, - confirmRequired: "repair-package-latest-pointer-2026-07-30", - previousLatestVersion: "0.2.11", - selectedVersion: "0.2.12", - eligibleReleaseCount: 2, - planToken: expect.stringMatching(/^[a-f\d]{64}$/), - releaseTagChanges: [ - { - releaseId: "packageReleases:old", - version: "0.2.11", - action: "remove", - }, - { - releaseId: "packageReleases:new", - version: "0.2.12", - action: "add", - }, - ], - }); - expect(fixture.patch).not.toHaveBeenCalled(); - expect(fixture.insert).not.toHaveBeenCalled(); - }); - - it("requires the exact confirmation token before applying", async () => { - const fixture = makePackageLatestPointerRepairDb(); - - await expect( - repairPackageLatestPointerHandler(fixture as never, { - name: "@openclaw/kitchen-sink", - dryRun: false, - confirm: "wrong", - }), - ).rejects.toThrow('Pass confirm="repair-package-latest-pointer-2026-07-30" to apply.'); - expect(fixture.patch).not.toHaveBeenCalled(); - }); - - it("requires the applied repair to match the dry-run plan", async () => { - const fixture = makePackageLatestPointerRepairDb(); - - await expect( - repairPackageLatestPointerHandler(fixture as never, { - name: "@openclaw/kitchen-sink", - dryRun: false, - confirm: "repair-package-latest-pointer-2026-07-30", - expectedPlanToken: "wrong", - }), - ).rejects.toThrow( - "Package latest repair plan changed after dry-run; rerun the dry-run before applying.", - ); - expect(fixture.patch).not.toHaveBeenCalled(); - expect(fixture.insert).not.toHaveBeenCalled(); - }); - - it("repoints the package, normalizes release tags, and audits the repair", async () => { - const fixture = makePackageLatestPointerRepairDb(); - const preflight = await repairPackageLatestPointerHandler(fixture as never, { - name: "@openclaw/kitchen-sink", - }); - - const result = await repairPackageLatestPointerHandler(fixture as never, { - name: "@openclaw/kitchen-sink", - dryRun: false, - confirm: "repair-package-latest-pointer-2026-07-30", - expectedPlanToken: preflight.planToken, - }); - - expect(result.selectedVersion).toBe("0.2.12"); - expect(fixture.patch).toHaveBeenCalledWith("packageReleases:old", { distTags: [] }); - expect(fixture.patch).toHaveBeenCalledWith("packageReleases:new", { - distTags: ["latest"], - }); - expect(fixture.patch).toHaveBeenCalledWith( - fixture.pkg._id, - expect.objectContaining({ - tags: { latest: "packageReleases:new" }, - latestReleaseId: "packageReleases:new", - summary: "new summary", - icon: "new-icon", - runtimeId: "new-runtime", - scanStatus: "not-run", - latestVersionSummary: expect.objectContaining({ - version: "0.2.12", - artifact: expect.objectContaining({ - kind: "npm-pack", - sha256: "new-sha", - }), - }), - }), - ); - expect(fixture.insert).toHaveBeenCalledWith( - "auditLogs", - expect.objectContaining({ - action: "package.latest_pointer.repair", - targetType: "package", - targetId: fixture.pkg._id, - metadata: expect.objectContaining({ - previousLatestVersion: "0.2.11", - selectedVersion: "0.2.12", - }), - }), - ); - }); -}); diff --git a/convex/maintenance.ts b/convex/maintenance.ts index 4d64541d..afa9961b 100644 --- a/convex/maintenance.ts +++ b/convex/maintenance.ts @@ -1,5 +1,4 @@ import { ConvexError, v } from "convex/values"; -import semver from "semver"; import { internal } from "./_generated/api"; import type { Doc, Id } from "./_generated/dataModel"; import type { ActionCtx, MutationCtx, QueryCtx } from "./_generated/server"; @@ -11,11 +10,7 @@ import { syncPackageSearchDigestForPackageId, } from "./functions"; import { assertRole, requireUserFromAction } from "./lib/access"; -import { sha256Hex } from "./lib/clawpack"; -import { summarizePackageReleaseArtifact } from "./lib/packageArtifacts"; -import { normalizePackageName } from "./lib/packageRegistry"; import { extractPackageDigestFields } from "./lib/packageSearchDigest"; -import { resolvePackageReleaseScanStatus } from "./lib/packageSecurity"; import { derivePersonalPublisherHandle, ensurePersonalPublisherForUser, @@ -51,7 +46,6 @@ const PUBLISHER_ABUSE_SIGNAL_SMOKE_OWNER_KEY = const PUBLISHER_ABUSE_SIGNAL_SMOKE_CONFIRM = "create-publisher-abuse-hermit-digest-smoke-2026-07-03" as const; const SKILL_LINEAGE_CYCLE_REPAIR_CONFIRM = "repair-skill-lineage-cycles-2026-07-23" as const; -const PACKAGE_LATEST_POINTER_REPAIR_CONFIRM = "repair-package-latest-pointer-2026-07-30" as const; const legacyPluginSkillSpectorRepairFamilyValidator = v.union( v.literal("code-plugin"), v.literal("bundle-plugin"), @@ -3279,203 +3273,6 @@ export const repairLegacyPublisherOwnershipForUser = internalMutation({ handler: repairLegacyPublisherOwnershipForUserHandler, }); -function isPublishedPackageRelease(release: Doc<"packageReleases">) { - return ( - !release.softDeletedAt && - release.ownerDeletedAt === undefined && - (release.publicationStatus === undefined || release.publicationStatus === "published") - ); -} - -function comparePackageLatestCandidates( - family: Doc<"packages">["family"], - a: Doc<"packageReleases">, - b: Doc<"packageReleases">, -) { - if (family === "bundle-plugin") { - if (a.createdAt !== b.createdAt) return a.createdAt - b.createdAt; - return a._id.localeCompare(b._id); - } - const aSemver = semver.valid(a.version); - const bSemver = semver.valid(b.version); - if (aSemver && bSemver) return semver.compare(aSemver, bSemver); - if (aSemver) return 1; - if (bSemver) return -1; - if (a.createdAt !== b.createdAt) return a.createdAt - b.createdAt; - return a._id.localeCompare(b._id); -} - -async function buildPackageLatestPointerPlanToken(params: { - pkg: Doc<"packages">; - releases: Doc<"packageReleases">[]; - selectedRelease: Doc<"packageReleases">; - releaseTagChanges: Array<{ - releaseId: Id<"packageReleases">; - version: string; - action: "add" | "remove"; - }>; -}) { - const payload = JSON.stringify({ - packageLatestReleaseId: params.pkg.latestReleaseId ?? null, - packageTags: params.pkg.tags, - selectedRelease: params.selectedRelease, - releaseTags: params.releases - .map((release) => ({ releaseId: release._id, distTags: release.distTags })) - .sort((a, b) => a.releaseId.localeCompare(b.releaseId)), - releaseTagChanges: params.releaseTagChanges, - }); - return await sha256Hex(new TextEncoder().encode(payload)); -} - -export async function repairPackageLatestPointerHandler( - ctx: Pick, - args: { - name: string; - dryRun?: boolean; - confirm?: string; - expectedPlanToken?: string; - }, -) { - const dryRun = args.dryRun !== false; - if (!dryRun && args.confirm !== PACKAGE_LATEST_POINTER_REPAIR_CONFIRM) { - throw new ConvexError(`Pass confirm="${PACKAGE_LATEST_POINTER_REPAIR_CONFIRM}" to apply.`); - } - - const normalizedName = normalizePackageName(args.name); - const pkg = await ctx.db - .query("packages") - .withIndex("by_name", (q) => q.eq("normalizedName", normalizedName)) - .unique(); - if (!pkg || pkg.softDeletedAt) { - throw new ConvexError(`Active package not found: ${normalizedName}`); - } - - const releases = await ctx.db - .query("packageReleases") - .withIndex("by_package", (q) => q.eq("packageId", pkg._id)) - .collect(); - const eligibleReleases = releases.filter(isPublishedPackageRelease); - const selectedRelease = eligibleReleases.reduce | null>( - (best, release) => - !best || comparePackageLatestCandidates(pkg.family, best, release) < 0 ? release : best, - null, - ); - if (!selectedRelease) { - throw new ConvexError(`No published releases found for package: ${normalizedName}`); - } - - const releaseTagChanges = releases.flatMap((release) => { - const hadLatest = release.distTags.includes("latest"); - const shouldHaveLatest = release._id === selectedRelease._id; - return hadLatest === shouldHaveLatest - ? [] - : [ - { - releaseId: release._id, - version: release.version, - action: shouldHaveLatest ? ("add" as const) : ("remove" as const), - }, - ]; - }); - const previousLatestRelease = pkg.latestReleaseId - ? (releases.find((release) => release._id === pkg.latestReleaseId) ?? null) - : null; - const planToken = await buildPackageLatestPointerPlanToken({ - pkg, - releases, - selectedRelease, - releaseTagChanges, - }); - - const result = { - dryRun, - confirmRequired: dryRun ? PACKAGE_LATEST_POINTER_REPAIR_CONFIRM : undefined, - packageId: pkg._id, - packageName: pkg.name, - normalizedName, - family: pkg.family, - releasesScanned: releases.length, - eligibleReleaseCount: eligibleReleases.length, - previousLatestReleaseId: pkg.latestReleaseId, - previousLatestVersion: previousLatestRelease?.version, - selectedReleaseId: selectedRelease._id, - selectedVersion: selectedRelease.version, - releaseTagChanges, - planToken, - }; - if (dryRun) return result; - if (!args.expectedPlanToken || args.expectedPlanToken !== planToken) { - throw new ConvexError( - "Package latest repair plan changed after dry-run; rerun the dry-run before applying.", - ); - } - - for (const change of releaseTagChanges) { - const release = releases.find((candidate) => candidate._id === change.releaseId); - if (!release) continue; - await ctx.db.patch(release._id, { - distTags: - change.action === "add" - ? [...release.distTags, "latest"] - : release.distTags.filter((tag) => tag !== "latest"), - }); - } - - const now = Date.now(); - const packagePatch: Partial> = { - tags: { ...pkg.tags, latest: selectedRelease._id }, - latestReleaseId: selectedRelease._id, - latestVersionSummary: { - version: selectedRelease.version, - createdAt: selectedRelease.createdAt, - changelog: selectedRelease.changelog, - icon: selectedRelease.icon, - compatibility: selectedRelease.compatibility, - verification: selectedRelease.verification, - artifact: summarizePackageReleaseArtifact(selectedRelease), - }, - summary: selectedRelease.summary, - icon: selectedRelease.icon, - sourceRepo: selectedRelease.sourceRepo ?? selectedRelease.verification?.sourceRepo, - runtimeId: selectedRelease.runtimeId, - compatibility: selectedRelease.compatibility, - verification: selectedRelease.verification, - scanStatus: resolvePackageReleaseScanStatus(selectedRelease), - updatedAt: now, - }; - // The wrapped internal mutation DB runs the package trigger in functions.ts, - // which refreshes package search digests from this patched document. - await ctx.db.patch(pkg._id, packagePatch); - await ctx.db.insert("auditLogs", { - action: "package.latest_pointer.repair", - targetType: "package", - targetId: pkg._id, - metadata: { - normalizedName, - previousLatestReleaseId: pkg.latestReleaseId, - previousLatestVersion: previousLatestRelease?.version, - selectedReleaseId: selectedRelease._id, - selectedVersion: selectedRelease.version, - releaseTagChanges, - }, - createdAt: now, - }); - - return result; -} - -// One-off production repair. Run dry first, then pass the exact confirmation token. -// npx convex run maintenance:repairPackageLatestPointer '{"name":"@scope/package"}' --prod -export const repairPackageLatestPointer = internalMutation({ - args: { - name: v.string(), - dryRun: v.optional(v.boolean()), - confirm: v.optional(v.string()), - expectedPlanToken: v.optional(v.string()), - }, - handler: repairPackageLatestPointerHandler, -}); - function clampInt(value: number, min: number, max: number) { const rounded = Math.trunc(value); if (!Number.isFinite(rounded)) return min; diff --git a/convex/packages.ts b/convex/packages.ts index 12561f6a..0463a5a2 100644 --- a/convex/packages.ts +++ b/convex/packages.ts @@ -68,10 +68,7 @@ import { normalizeGitHubRepository } from "./lib/githubActionsOidc"; import { readGlobalPublicPluginsCount } from "./lib/globalStats"; import { toDayKey } from "./lib/leaderboards"; import { isOfficialPublisher } from "./lib/officialPublishers"; -import { - getPackageReleaseArtifactSha256, - summarizePackageReleaseArtifact, -} from "./lib/packageArtifacts"; +import { getPackageReleaseArtifactSha256 } from "./lib/packageArtifacts"; import { assertPackageVersion, derivePluginManifestSummary, @@ -1219,7 +1216,7 @@ function toPublicPackage( latestRelease === undefined ? pkg.latestVersionSummary?.artifact : isPublishedPackageRelease(latestRelease) - ? summarizePackageReleaseArtifact(latestRelease) + ? packageArtifactSummary(latestRelease) : undefined, clawManifestSummary: pkg.family === "claw" && isPublishedPackageRelease(latestRelease) @@ -1348,6 +1345,41 @@ async function paginatePublishedPackageReleases( return { page, isDone, continueCursor: isDone ? "" : continueCursor }; } +function packageArtifactSummary( + release: Pick< + Doc<"packageReleases">, + | "artifactKind" + | "clawpackSha256" + | "sha256hash" + | "clawpackSize" + | "clawpackFormat" + | "npmIntegrity" + | "npmShasum" + | "npmTarballName" + | "npmUnpackedSize" + | "npmFileCount" + >, +): PackageArtifactSummary { + if (release.artifactKind === "npm-pack") { + return { + kind: "npm-pack", + sha256: getPackageReleaseArtifactSha256(release) ?? undefined, + size: release.clawpackSize, + format: release.clawpackFormat ?? "tgz", + npmIntegrity: release.npmIntegrity, + npmShasum: release.npmShasum, + npmTarballName: release.npmTarballName, + npmUnpackedSize: release.npmUnpackedSize, + npmFileCount: release.npmFileCount, + }; + } + return { + kind: "legacy-zip", + sha256: getPackageReleaseArtifactSha256(release) ?? undefined, + format: "zip", + }; +} + function digestMatchesFilters( digest: PackageDigestLike, args: { @@ -5740,7 +5772,7 @@ function packageLatestSummaryFromRelease(release: Doc<"packageReleases"> | null) icon: release.icon, compatibility: release.compatibility, verification: release.verification, - artifact: summarizePackageReleaseArtifact(release), + artifact: packageArtifactSummary(release), } : undefined; } @@ -5841,7 +5873,7 @@ async function restorePackageDoc( icon: nextLatest.icon, compatibility: nextLatest.compatibility, verification: nextLatest.verification, - artifact: summarizePackageReleaseArtifact(nextLatest), + artifact: packageArtifactSummary(nextLatest), } : undefined, summary: nextLatest?.summary, @@ -10889,7 +10921,7 @@ export const insertReleaseInternal = internalMutation({ icon: args.icon, compatibility: args.compatibility, verification: releaseVerification, - artifact: summarizePackageReleaseArtifact(args), + artifact: packageArtifactSummary(args), } : pkg.latestVersionSummary, tags: nextTags,