From 28da510571e540ceae4f758100b6f0f656415e55 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 2 May 2026 10:50:57 -0700 Subject: [PATCH] feat(packages): resolve package appeals --- convex/httpApiV1.handlers.test.ts | 89 +++++++++++ convex/httpApiV1/packagesV1.ts | 78 +++++++++ convex/packages.public.test.ts | 150 ++++++++++++++++++ convex/packages.ts | 145 +++++++++++++++++ convex/schema.ts | 1 + docs/cli.md | 35 ++++ docs/http-api.md | 72 +++++++++ docs/security.md | 3 + packages/clawhub/src/cli.ts | 31 ++++ .../clawhub/src/cli/commands/packages.test.ts | 66 ++++++++ packages/clawhub/src/cli/commands/packages.ts | 107 +++++++++++++ packages/clawhub/src/schema/packages.ts | 46 ++++++ packages/schema/dist/packages.d.ts | 40 +++++ packages/schema/dist/packages.js | 36 +++++ packages/schema/dist/packages.js.map | 2 +- packages/schema/src/packages.ts | 46 ++++++ 16 files changed, 946 insertions(+), 1 deletion(-) diff --git a/convex/httpApiV1.handlers.test.ts b/convex/httpApiV1.handlers.test.ts index b3b2a056..ee39631e 100644 --- a/convex/httpApiV1.handlers.test.ts +++ b/convex/httpApiV1.handlers.test.ts @@ -4075,6 +4075,95 @@ describe("httpApiV1 handlers", () => { }); }); + it("package appeals lists moderator appeal intake", async () => { + vi.mocked(requireApiTokenUser).mockResolvedValue({ + userId: "users:moderator", + user: { _id: "users:moderator", role: "moderator" }, + } as never); + const runQuery = vi.fn(async (_query: unknown, args: Record) => { + if (isRateLimitArgs(args)) return okRate(); + return { + items: [ + { + appealId: "packageAppeals:1", + packageId: "packages:1", + releaseId: "packageReleases:1", + name: "@scope/demo", + displayName: "Demo", + family: "code-plugin", + version: "1.2.3", + message: "please review", + status: "open", + createdAt: 123, + submitter: { userId: "users:owner", handle: "owner", displayName: "Owner" }, + resolvedAt: null, + resolvedBy: null, + resolutionNote: null, + }, + ], + nextCursor: null, + done: true, + }; + }); + const runMutation = vi.fn().mockResolvedValue(okRate()); + + const response = await __handlers.packagesGetRouterV1Handler( + makeCtx({ runQuery, runMutation }), + new Request("https://example.com/api/v1/packages/appeals?status=open&limit=10", { + headers: { Authorization: "Bearer clh_test" }, + }), + ); + + expect(response.status).toBe(200); + await expect(response.json()).resolves.toMatchObject({ + items: [{ appealId: "packageAppeals:1", name: "@scope/demo" }], + }); + expect(runQuery).toHaveBeenCalledWith(internal.packages.listPackageAppealsInternal, { + actorUserId: "users:moderator", + cursor: null, + limit: 10, + status: "open", + }); + }); + + it("package appeal resolve posts moderator decisions", async () => { + vi.mocked(requireApiTokenUser).mockResolvedValue({ + userId: "users:moderator", + user: { _id: "users:moderator", role: "moderator" }, + } as never); + const runMutation = vi.fn(async (_mutation: unknown, args: Record) => { + if (isRateLimitArgs(args)) return okRate(); + return { + ok: true, + appealId: "packageAppeals:1", + packageId: "packages:1", + releaseId: "packageReleases:1", + status: "rejected", + }; + }); + + const response = await __handlers.packagesPostRouterV1Handler( + makeCtx({ runMutation }), + new Request("https://example.com/api/v1/packages/appeals/packageAppeals%3A1/resolve", { + method: "POST", + headers: { Authorization: "Bearer clh_test" }, + body: JSON.stringify({ status: "rejected", note: "scanner finding still applies" }), + }), + ); + + expect(response.status).toBe(200); + await expect(response.json()).resolves.toMatchObject({ status: "rejected" }); + expect(runMutation).toHaveBeenCalledWith( + internal.packages.resolvePackageAppealForUserInternal, + { + actorUserId: "users:moderator", + appealId: "packageAppeals:1", + status: "rejected", + note: "scanner finding still applies", + }, + ); + }); + it("package artifact backfill posts admin dry-run requests", async () => { vi.mocked(requireApiTokenUser).mockResolvedValue({ userId: "users:admin", diff --git a/convex/httpApiV1/packagesV1.ts b/convex/httpApiV1/packagesV1.ts index dbed804f..b478d0c9 100644 --- a/convex/httpApiV1/packagesV1.ts +++ b/convex/httpApiV1/packagesV1.ts @@ -1,6 +1,7 @@ import { PackageArtifactBackfillRequestSchema, ApiV1PackageModerationStatusResponseSchema, + PackageAppealResolveRequestSchema, PackageAppealRequestSchema, PackageReportRequestSchema, PackageReportTriageRequestSchema, @@ -9,6 +10,7 @@ import { PackageTrustedPublisherUpsertRequestSchema, PublishTokenMintRequestSchema, parseArk, + type PackageAppealListStatus, type PackageModerationQueueStatus, type PackageReportListStatus, } from "clawhub-schema"; @@ -80,6 +82,8 @@ const internalRefs = internal as unknown as { triagePackageReportForUserInternal: unknown; getPackageModerationStatusForUserInternal: unknown; submitPackageAppealForUserInternal: unknown; + listPackageAppealsInternal: unknown; + resolvePackageAppealForUserInternal: unknown; backfillPackageArtifactKindsInternal: unknown; listPackageModerationQueueInternal: unknown; }; @@ -204,6 +208,20 @@ function parsePackageReportListStatus(value: string | null): PackageReportListSt return null; } +function parsePackageAppealListStatus(value: string | null): PackageAppealListStatus | null { + if (!value) return "open"; + const normalized = value.trim().toLowerCase(); + if ( + normalized === "open" || + normalized === "accepted" || + normalized === "rejected" || + normalized === "all" + ) { + return normalized; + } + return null; +} + type PackageListQueryArgs = { family?: "skill" | "code-plugin" | "bundle-plugin"; channel?: "official" | "community" | "private"; @@ -1428,6 +1446,46 @@ export async function packagesPostRouterV1Handler(ctx: ActionCtx, request: Reque } } + if ( + segments[0] === "appeals" && + segments[1] && + segments[2] === "resolve" && + segments.length === 3 + ) { + const rate = await applyRateLimit(ctx, request, "write"); + if (!rate.ok) return rate.response; + const auth = await requireApiTokenUserOrResponse(ctx, request, rate.headers); + if (!auth.ok) return auth.response; + + try { + const body = parseArk( + PackageAppealResolveRequestSchema, + await request.json(), + "Package appeal resolve payload", + ) as { + status: "open" | "accepted" | "rejected"; + note?: string; + }; + const result = await runMutationRef( + ctx, + internalRefs.packages.resolvePackageAppealForUserInternal, + { + actorUserId: auth.userId, + appealId: segments[1] as Id<"packageAppeals">, + status: body.status, + ...(body.note ? { note: body.note } : {}), + }, + ); + return json(result, 200, rate.headers); + } catch (error) { + return text( + error instanceof Error ? error.message : "Package appeal resolve failed", + 400, + rate.headers, + ); + } + } + if ( segments[1] === "versions" && segments[2] && @@ -1941,6 +1999,26 @@ export async function packagesGetRouterV1Handler(ctx: ActionCtx, request: Reques return json(result, 200, rate.headers); } + if (segments[0] === "appeals" && segments.length === 1) { + const rate = await applyRateLimit(ctx, request, "read"); + if (!rate.ok) return rate.response; + const auth = await requireApiTokenUserOrResponse(ctx, request, rate.headers); + if (!auth.ok) return auth.response; + + const url = new URL(request.url); + const status = parsePackageAppealListStatus(url.searchParams.get("status")); + if (!status) return text("Invalid package appeal status", 400, rate.headers); + const limit = Math.max(1, Math.min(toOptionalNumber(url.searchParams.get("limit")) ?? 25, 100)); + const cursor = url.searchParams.get("cursor"); + const result = await runQueryRef(ctx, internalRefs.packages.listPackageAppealsInternal, { + actorUserId: auth.userId, + cursor: cursor ?? null, + limit, + status, + }); + return json(result, 200, rate.headers); + } + if (segments[1] === "moderation" && segments.length === 2) { const rate = await applyRateLimit(ctx, request, "read"); if (!rate.ok) return rate.response; diff --git a/convex/packages.public.test.ts b/convex/packages.public.test.ts index 8366407a..3ee3c5a2 100644 --- a/convex/packages.public.test.ts +++ b/convex/packages.public.test.ts @@ -16,6 +16,8 @@ import { reportPackageForUserInternal, triagePackageReportForUserInternal, submitPackageAppealForUserInternal, + listPackageAppealsInternal, + resolvePackageAppealForUserInternal, getVersionByName, insertReleaseInternal, listPackageModerationQueueInternal, @@ -310,6 +312,38 @@ const submitPackageAppealForUserInternalHandler = ( } > )._handler; +const listPackageAppealsInternalHandler = ( + listPackageAppealsInternal as unknown as WrappedHandler< + { + actorUserId: string; + cursor?: string | null; + limit?: number; + status?: "open" | "accepted" | "rejected" | "all"; + }, + { + items: Array<{ appealId: string; name: string; status: string; message: string }>; + nextCursor: string | null; + done: boolean; + } + > +)._handler; +const resolvePackageAppealForUserInternalHandler = ( + resolvePackageAppealForUserInternal as unknown as WrappedHandler< + { + actorUserId: string; + appealId: string; + status: "open" | "accepted" | "rejected"; + note?: string; + }, + { + ok: true; + appealId: string; + packageId: string; + releaseId: string; + status: string; + } + > +)._handler; const getPackageReleaseScanBackfillBatchInternalHandler = ( getPackageReleaseScanBackfillBatchInternal as unknown as WrappedHandler< { @@ -3823,6 +3857,122 @@ describe("packages public queries", () => { }), ); }); + + it("lists package appeals for moderators", async () => { + const result = await listPackageAppealsInternalHandler( + { + db: { + get: vi.fn(async (id: string) => { + if (id === "users:moderator") return { _id: id, role: "moderator" }; + if (id === "users:owner") return { _id: id, handle: "owner" }; + if (id === "packages:demo") return makePackageDoc({ name: "@scope/demo" }); + return null; + }), + query: vi.fn((table: string) => { + if (table !== "packageAppeals") throw new Error(`Unexpected table ${table}`); + return { + withIndex: vi.fn(() => ({ + order: vi.fn(() => ({ + paginate: vi.fn().mockResolvedValue({ + page: [ + { + _id: "packageAppeals:1", + packageId: "packages:demo", + releaseId: "packageReleases:demo-1", + version: "1.2.3", + userId: "users:owner", + message: "please review", + status: "open", + createdAt: 123, + }, + ], + continueCursor: null, + isDone: true, + }), + })), + })), + }; + }), + }, + } as never, + { actorUserId: "users:moderator", status: "open", limit: 10 }, + ); + + expect(result).toEqual({ + items: [ + expect.objectContaining({ + appealId: "packageAppeals:1", + name: "@scope/demo", + version: "1.2.3", + message: "please review", + status: "open", + submitter: expect.objectContaining({ handle: "owner" }), + }), + ], + nextCursor: null, + done: true, + }); + }); + + it("resolves package appeals for moderators", async () => { + const patch = vi.fn(); + const insert = vi.fn(async () => "auditLogs:1"); + + const result = await resolvePackageAppealForUserInternalHandler( + { + db: { + get: vi.fn(async (id: string) => { + if (id === "users:moderator") return { _id: id, role: "moderator" }; + if (id === "packageAppeals:1") { + return { + _id: id, + packageId: "packages:demo", + releaseId: "packageReleases:demo-1", + version: "1.2.3", + userId: "users:owner", + message: "please review", + status: "open", + createdAt: 123, + }; + } + if (id === "packages:demo") return makePackageDoc({ name: "@scope/demo" }); + return null; + }), + patch, + insert, + query: vi.fn(), + replace: vi.fn(), + delete: vi.fn(), + normalizeId: vi.fn(), + }, + } as never, + { + actorUserId: "users:moderator", + appealId: "packageAppeals:1", + status: "rejected", + note: "scanner finding still applies", + }, + ); + + expect(result).toMatchObject({ + ok: true, + appealId: "packageAppeals:1", + status: "rejected", + }); + expect(patch).toHaveBeenCalledWith("packageAppeals:1", { + status: "rejected", + resolvedAt: expect.any(Number), + resolvedBy: "users:moderator", + resolutionNote: "scanner finding still applies", + }); + expect(insert).toHaveBeenCalledWith( + "auditLogs", + expect.objectContaining({ + action: "package.appeal.resolve", + targetType: "packageAppeal", + }), + ); + }); }); describe("package scan backfill", () => { diff --git a/convex/packages.ts b/convex/packages.ts index e546d0e5..e51228b2 100644 --- a/convex/packages.ts +++ b/convex/packages.ts @@ -215,6 +215,27 @@ type PackageReportListItem = { triagedBy?: Id<"users"> | null; triageNote?: string | null; }; +type PackageAppealStatus = "open" | "accepted" | "rejected"; +type PackageAppealListItem = { + appealId: Id<"packageAppeals">; + packageId: Id<"packages">; + releaseId: Id<"packageReleases">; + name: string; + displayName: string; + family: PackageFamily; + version: string; + message: string; + status: PackageAppealStatus; + createdAt: number; + submitter: { + userId: Id<"users">; + handle?: string | null; + displayName?: string | null; + }; + resolvedAt?: number | null; + resolvedBy?: Id<"users"> | null; + resolutionNote?: string | null; +}; type PackageModerationStatus = { package: { packageId: Id<"packages">; @@ -2637,6 +2658,130 @@ export const submitPackageAppealForUserInternal = internalMutation({ }, }); +function toPackageAppealListItem( + appeal: Doc<"packageAppeals">, + pkg: Doc<"packages">, + submitter: Doc<"users"> | null, +): PackageAppealListItem { + return { + appealId: appeal._id, + packageId: pkg._id, + releaseId: appeal.releaseId, + name: pkg.name, + displayName: pkg.displayName, + family: pkg.family, + version: appeal.version, + message: appeal.message, + status: appeal.status, + createdAt: appeal.createdAt, + submitter: { + userId: appeal.userId, + handle: submitter?.handle ?? null, + displayName: submitter?.displayName ?? submitter?.name ?? null, + }, + resolvedAt: appeal.resolvedAt ?? null, + resolvedBy: appeal.resolvedBy ?? null, + resolutionNote: appeal.resolutionNote ?? null, + }; +} + +export const listPackageAppealsInternal = internalQuery({ + args: { + actorUserId: v.id("users"), + cursor: v.optional(v.union(v.string(), v.null())), + limit: v.optional(v.number()), + status: v.optional( + v.union(v.literal("open"), v.literal("accepted"), v.literal("rejected"), v.literal("all")), + ), + }, + handler: async (ctx, args) => { + const actor = await ctx.db.get(args.actorUserId); + if (!actor || actor.deletedAt || actor.deactivatedAt) throw new ConvexError("Unauthorized"); + assertModerator(actor); + + const limit = Math.max(1, Math.min(Math.round(args.limit ?? 25), 100)); + const status = args.status ?? "open"; + const appealQuery = + status === "all" + ? ctx.db.query("packageAppeals").withIndex("by_createdAt", (q) => q) + : ctx.db + .query("packageAppeals") + .withIndex("by_status_createdAt", (q) => q.eq("status", status)); + const page = await appealQuery.order("desc").paginate({ + cursor: args.cursor ?? null, + numItems: limit, + }); + + const items: PackageAppealListItem[] = []; + for (const appeal of page.page) { + const pkg = await ctx.db.get(appeal.packageId); + if (!pkg || pkg.softDeletedAt || pkg.family === "skill") continue; + const submitter = await ctx.db.get(appeal.userId); + items.push(toPackageAppealListItem(appeal, pkg, submitter)); + } + + return { + items, + nextCursor: page.isDone ? null : page.continueCursor, + done: page.isDone, + }; + }, +}); + +export const resolvePackageAppealForUserInternal = internalMutation({ + args: { + actorUserId: v.id("users"), + appealId: v.id("packageAppeals"), + status: v.union(v.literal("open"), v.literal("accepted"), v.literal("rejected")), + note: v.optional(v.string()), + }, + handler: async (ctx, args) => { + const actor = await ctx.db.get(args.actorUserId); + if (!actor || actor.deletedAt || actor.deactivatedAt) throw new ConvexError("Unauthorized"); + assertModerator(actor); + + const appeal = await ctx.db.get(args.appealId); + if (!appeal) throw new ConvexError("Package appeal not found"); + const pkg = await ctx.db.get(appeal.packageId); + if (!pkg || pkg.softDeletedAt) throw new ConvexError("Package appeal not found"); + + const note = args.note?.trim(); + const isOpen = args.status === "open"; + if (!isOpen && !note) throw new ConvexError("Resolution note required."); + const now = Date.now(); + + await ctx.db.patch(appeal._id, { + status: args.status, + resolvedAt: isOpen ? undefined : now, + resolvedBy: isOpen ? undefined : actor._id, + resolutionNote: isOpen ? undefined : note?.slice(0, MAX_APPEAL_MESSAGE_LENGTH), + }); + + await ctx.db.insert("auditLogs", { + actorUserId: actor._id, + action: "package.appeal.resolve", + targetType: "packageAppeal", + targetId: appeal._id, + metadata: { + packageId: pkg._id, + releaseId: appeal.releaseId, + packageName: pkg.name, + version: appeal.version, + status: args.status, + }, + createdAt: now, + }); + + return { + ok: true as const, + appealId: appeal._id, + packageId: pkg._id, + releaseId: appeal.releaseId, + status: args.status, + }; + }, +}); + export const listPackageModerationQueueInternal = internalQuery({ args: { actorUserId: v.id("users"), diff --git a/convex/schema.ts b/convex/schema.ts index 2ad8836d..41d23677 100644 --- a/convex/schema.ts +++ b/convex/schema.ts @@ -1322,6 +1322,7 @@ const packageAppeals = defineTable({ createdAt: v.number(), }) .index("by_release_status_createdAt", ["releaseId", "status", "createdAt"]) + .index("by_createdAt", ["createdAt"]) .index("by_status_createdAt", ["status", "createdAt"]) .index("by_user_createdAt", ["userId", "createdAt"]); diff --git a/docs/cli.md b/docs/cli.md index a0416a10..aadf9571 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -367,6 +367,41 @@ Example: clawhub package appeal @openclaw/example-plugin --version 1.2.3 --message "linked source release explains the native binary" ``` +### `package appeals` + +- Moderator/admin command for listing package appeals. +- Calls `GET /api/v1/packages/appeals`. +- Flags: + - `--status open|accepted|rejected|all`: appeal state filter, default `open`. + - `--cursor `: resume cursor from a previous page. + - `--limit `: number of appeals to show, max 100. + - `--json`: machine-readable output. + +Examples: + +```bash +clawhub package appeals +clawhub package appeals --status all --limit 50 +``` + +### `package resolve-appeal` + +- Moderator/admin command for accepting, rejecting, or reopening a package + appeal. +- Calls `POST /api/v1/packages/appeals/{appealId}/resolve`. +- Resolving an appeal does not automatically change release moderation state; + use `package moderate` to approve, quarantine, or revoke the artifact. +- Flags: + - `--status open|accepted|rejected`: required appeal state. + - `--note `: required unless `--status open`. + - `--json`: machine-readable output. + +Example: + +```bash +clawhub package resolve-appeal packageAppeals:abc --status rejected --note "static finding still applies" +``` + ### `package reports` - Moderator/admin command for listing package reports. diff --git a/docs/http-api.md b/docs/http-api.md index b0f7da99..354cee56 100644 --- a/docs/http-api.md +++ b/docs/http-api.md @@ -556,6 +556,78 @@ Response: } ``` +### `GET /api/v1/packages/appeals` + +Moderator/admin endpoint for package appeal intake. + +Auth: + +- Requires an API token for a moderator or admin user. + +Query params: + +- `status` (optional): `open` (default), `accepted`, `rejected`, or `all` +- `limit` (optional): integer (1-100) +- `cursor` (optional): pagination cursor + +Response: + +```json +{ + "items": [ + { + "appealId": "packageAppeals:...", + "packageId": "packages:...", + "releaseId": "packageReleases:...", + "name": "@openclaw/example-plugin", + "displayName": "Example Plugin", + "family": "code-plugin", + "version": "1.2.3", + "message": "The native binary is signed.", + "status": "open", + "createdAt": 1730000000000, + "submitter": { + "userId": "users:...", + "handle": "publisher", + "displayName": "Publisher" + }, + "resolvedAt": null, + "resolvedBy": null, + "resolutionNote": null + } + ], + "nextCursor": null, + "done": true +} +``` + +### `POST /api/v1/packages/appeals/{appealId}/resolve` + +Moderator/admin endpoint for accepting, rejecting, or reopening an appeal. + +Request: + +```json +{ "status": "rejected", "note": "Static finding still applies." } +``` + +`note` is required for `accepted` and `rejected`; it may be omitted when +setting `status` back to `open`. Resolving an appeal does not automatically +change release moderation state; use release moderation to approve, quarantine, +or revoke the artifact. + +Response: + +```json +{ + "ok": true, + "appealId": "packageAppeals:...", + "packageId": "packages:...", + "releaseId": "packageReleases:...", + "status": "rejected" +} +``` + ### `GET /api/v1/packages/reports` Moderator/admin endpoint for package report intake. diff --git a/docs/security.md b/docs/security.md index e8cbe560..f3d6c36c 100644 --- a/docs/security.md +++ b/docs/security.md @@ -51,6 +51,9 @@ See also: [acceptable-usage.md](./acceptable-usage.md) for the marketplace polic - Package owners and publisher members can submit one open appeal per moderated package release. Appeals are audit-logged and do not automatically approve or unblock a release. +- Moderators can accept, reject, or reopen appeals with a resolution note. + Appeal resolution is audit-logged and intentionally separate from changing + release moderation state. - Public queries hide non-active moderation statuses; staff can still access via staff-only queries and unhide/restore/delete/ban. - Skills directory supports an optional "Hide suspicious" filter to exclude diff --git a/packages/clawhub/src/cli.ts b/packages/clawhub/src/cli.ts index 3ffcd0ef..80082ed4 100644 --- a/packages/clawhub/src/cli.ts +++ b/packages/clawhub/src/cli.ts @@ -24,12 +24,14 @@ import { cmdInspectPackage, cmdDeletePackageTrustedPublisher, cmdListPackageReports, + cmdListPackageAppeals, cmdModeratePackageRelease, cmdPackageModerationStatus, cmdPackageModerationQueue, cmdPackageReadiness, cmdPublishPackage, cmdReportPackage, + cmdResolvePackageAppeal, cmdSetPackageTrustedPublisher, cmdTriagePackageReport, cmdVerifyPackage, @@ -493,6 +495,35 @@ packageCmd await cmdAppealPackage(opts, name, options); }); +packageCmd + .command("appeals") + .description("List package appeals for moderator review") + .option("--status ", "open|accepted|rejected|all", "open") + .option("--cursor ", "Resume cursor") + .option( + "--limit ", + "Number of appeals to show (max 100)", + (value) => Number.parseInt(value, 10), + 25, + ) + .option("--json", "Output JSON") + .action(async (options) => { + const opts = await resolveGlobalOpts(); + await cmdListPackageAppeals(opts, options); + }); + +packageCmd + .command("resolve-appeal") + .description("Resolve or reopen a package appeal") + .argument("", "Package appeal id") + .requiredOption("--status ", "open|accepted|rejected") + .option("--note ", "Resolution note; required unless reopening") + .option("--json", "Output JSON") + .action(async (appealId, options) => { + const opts = await resolveGlobalOpts(); + await cmdResolvePackageAppeal(opts, appealId, options); + }); + packageCmd .command("reports") .description("List package reports for moderator review") diff --git a/packages/clawhub/src/cli/commands/packages.test.ts b/packages/clawhub/src/cli/commands/packages.test.ts index 70d66c53..bbd3954c 100644 --- a/packages/clawhub/src/cli/commands/packages.test.ts +++ b/packages/clawhub/src/cli/commands/packages.test.ts @@ -36,12 +36,14 @@ const { cmdInspectPackage, cmdBackfillPackageArtifacts, cmdListPackageReports, + cmdListPackageAppeals, cmdModeratePackageRelease, cmdPackageModerationStatus, cmdPackageModerationQueue, cmdPackageReadiness, cmdPublishPackage, cmdReportPackage, + cmdResolvePackageAppeal, cmdSetPackageTrustedPublisher, cmdTriagePackageReport, cmdVerifyPackage, @@ -548,6 +550,70 @@ describe("package commands", () => { expect(mockLog).toHaveBeenCalledWith("OK. Appeal submitted: packageAppeals:1"); }); + it("lists package appeals", async () => { + httpMocks.apiRequest.mockResolvedValueOnce({ + items: [ + { + appealId: "packageAppeals:1", + packageId: "pkg_1", + releaseId: "rel_1", + name: "@scope/demo", + displayName: "Demo", + family: "code-plugin", + version: "1.2.3", + message: "please review", + status: "open", + createdAt: 1, + submitter: { userId: "users:owner", handle: "owner", displayName: "Owner" }, + resolvedAt: null, + resolvedBy: null, + resolutionNote: null, + }, + ], + nextCursor: null, + done: true, + }); + + await cmdListPackageAppeals(makeOpts(), { status: "open", limit: 10 }); + + const request = httpMocks.apiRequest.mock.calls[0]?.[1] as { url?: string } | undefined; + const url = new URL(String(request?.url)); + expect(url.pathname).toBe("/api/v1/packages/appeals"); + expect(url.searchParams.get("status")).toBe("open"); + expect(url.searchParams.get("limit")).toBe("10"); + expect(mockLog).toHaveBeenCalledWith("packageAppeals:1 open @scope/demo@1.2.3"); + }); + + it("resolves package appeals", async () => { + httpMocks.apiRequest.mockResolvedValueOnce({ + ok: true, + appealId: "packageAppeals:1", + packageId: "pkg_1", + releaseId: "rel_1", + status: "rejected", + }); + + await cmdResolvePackageAppeal(makeOpts(), "packageAppeals:1", { + status: "rejected", + note: "scanner finding still applies", + }); + + expect(httpMocks.apiRequest).toHaveBeenCalledWith( + "https://clawhub.ai", + { + method: "POST", + path: "/api/v1/packages/appeals/packageAppeals%3A1/resolve", + token: "tkn", + body: { + status: "rejected", + note: "scanner finding still applies", + }, + }, + expect.anything(), + ); + expect(mockLog).toHaveBeenCalledWith("OK. Appeal packageAppeals:1 set to rejected."); + }); + it("lists package reports", async () => { httpMocks.apiRequest.mockResolvedValueOnce({ items: [ diff --git a/packages/clawhub/src/cli/commands/packages.ts b/packages/clawhub/src/cli/commands/packages.ts index 86ad0653..ab5a51aa 100644 --- a/packages/clawhub/src/cli/commands/packages.ts +++ b/packages/clawhub/src/cli/commands/packages.ts @@ -11,6 +11,8 @@ import { ApiV1PackageArtifactBackfillResponseSchema, ApiV1PackageArtifactResponseSchema, ApiV1PackageAppealResponseSchema, + ApiV1PackageAppealListResponseSchema, + ApiV1PackageAppealResolveResponseSchema, ApiV1PackageListResponseSchema, ApiV1PackageModerationStatusResponseSchema, ApiV1PackageModerationQueueResponseSchema, @@ -28,6 +30,8 @@ import { ApiV1PublishTokenMintResponseSchema, normalizeOpenClawExternalPluginCompatibility, type PackageArtifactSummary, + type PackageAppealListStatus, + type PackageAppealStatus, type PackageCapabilitySummary, type PackageCompatibility, type PackageFamily, @@ -143,6 +147,19 @@ type PackageAppealOptions = { json?: boolean; }; +type PackageAppealListOptions = { + status?: PackageAppealListStatus; + cursor?: string; + limit?: number; + json?: boolean; +}; + +type PackageAppealResolveOptions = { + status?: PackageAppealStatus; + note?: string; + json?: boolean; +}; + type PackageReportListOptions = { status?: PackageReportListStatus; cursor?: string; @@ -939,6 +956,96 @@ export async function cmdAppealPackage( } } +export async function cmdListPackageAppeals( + opts: GlobalOpts, + options: PackageAppealListOptions = {}, +) { + const status = options.status?.trim() || "open"; + if (!["open", "accepted", "rejected", "all"].includes(status)) { + fail("--status must be open, accepted, rejected, or all"); + } + + const token = await requireAuthToken(); + const registry = await getRegistry(opts, { cache: true }); + const url = registryUrl(`${ApiRoutes.packages}/appeals`, registry); + url.searchParams.set("status", status); + if (options.cursor?.trim()) url.searchParams.set("cursor", options.cursor.trim()); + url.searchParams.set("limit", String(clampLimit(options.limit ?? 25, 100))); + + const result = await apiRequest( + registry, + { + method: "GET", + url: url.toString(), + token, + }, + ApiV1PackageAppealListResponseSchema, + ); + + if (options.json) { + process.stdout.write(`${JSON.stringify(result, null, 2)}\n`); + return; + } + + if (result.items.length === 0) { + console.log("No package appeals found."); + } else { + for (const item of result.items) { + const submitter = item.submitter.handle ?? item.submitter.userId; + console.log(`${item.appealId} ${item.status} ${item.name}@${item.version}`); + console.log(` submitter: ${submitter}`); + console.log(` message: ${item.message}`); + if (item.resolutionNote) console.log(` resolution: ${item.resolutionNote}`); + } + } + if (!result.done && result.nextCursor) { + console.log(`Next cursor: ${result.nextCursor}`); + } +} + +export async function cmdResolvePackageAppeal( + opts: GlobalOpts, + appealId: string, + options: PackageAppealResolveOptions = {}, +) { + const trimmed = appealId.trim(); + if (!trimmed) fail("Appeal id required"); + const status = options.status?.trim(); + if (!status || !["open", "accepted", "rejected"].includes(status)) { + fail("--status must be open, accepted, or rejected"); + } + const note = options.note?.trim(); + if (status !== "open" && !note) fail("--note required unless reopening"); + + const token = await requireAuthToken(); + const registry = await getRegistry(opts, { cache: true }); + const spinner = options.json ? null : createSpinner(`Updating appeal ${trimmed}`); + try { + const result = await apiRequest( + registry, + { + method: "POST", + path: `${ApiRoutes.packages}/appeals/${encodeURIComponent(trimmed)}/resolve`, + token, + body: { + status, + ...(note ? { note } : {}), + }, + }, + ApiV1PackageAppealResolveResponseSchema, + ); + spinner?.stop(); + if (options.json) { + process.stdout.write(`${JSON.stringify(result, null, 2)}\n`); + return; + } + console.log(`OK. Appeal ${trimmed} set to ${result.status}.`); + } catch (error) { + spinner?.fail(formatError(error)); + throw error; + } +} + export async function cmdListPackageReports( opts: GlobalOpts, options: PackageReportListOptions = {}, diff --git a/packages/clawhub/src/schema/packages.ts b/packages/clawhub/src/schema/packages.ts index 0fb79edf..2179d427 100644 --- a/packages/clawhub/src/schema/packages.ts +++ b/packages/clawhub/src/schema/packages.ts @@ -80,6 +80,9 @@ export type PackageReportListStatus = (typeof PackageReportListStatusSchema)[inf export const PackageAppealStatusSchema = type('"open"|"accepted"|"rejected"'); export type PackageAppealStatus = (typeof PackageAppealStatusSchema)[inferred]; +export const PackageAppealListStatusSchema = PackageAppealStatusSchema.or('"all"'); +export type PackageAppealListStatus = (typeof PackageAppealListStatusSchema)[inferred]; + export const PackageArtifactSummarySchema = type({ kind: PackageArtifactKindSchema, sha256: "string?", @@ -352,6 +355,49 @@ export const ApiV1PackageAppealResponseSchema = type({ }); export type ApiV1PackageAppealResponse = (typeof ApiV1PackageAppealResponseSchema)[inferred]; +export const PackageAppealResolveRequestSchema = type({ + status: PackageAppealStatusSchema, + note: "string?", +}); +export type PackageAppealResolveRequest = (typeof PackageAppealResolveRequestSchema)[inferred]; + +export const ApiV1PackageAppealListResponseSchema = type({ + items: type({ + appealId: "string", + packageId: "string", + releaseId: "string", + name: "string", + displayName: "string", + family: PackageFamilySchema, + version: "string", + message: "string", + status: PackageAppealStatusSchema, + createdAt: "number", + submitter: type({ + userId: "string", + handle: "string|null?", + displayName: "string|null?", + }), + resolvedAt: "number|null?", + resolvedBy: "string|null?", + resolutionNote: "string|null?", + }).array(), + nextCursor: "string|null", + done: "boolean", +}); +export type ApiV1PackageAppealListResponse = + (typeof ApiV1PackageAppealListResponseSchema)[inferred]; + +export const ApiV1PackageAppealResolveResponseSchema = type({ + ok: "true", + appealId: "string", + packageId: "string", + releaseId: "string", + status: PackageAppealStatusSchema, +}); +export type ApiV1PackageAppealResolveResponse = + (typeof ApiV1PackageAppealResolveResponseSchema)[inferred]; + export const ApiV1PackageReportListResponseSchema = type({ items: type({ reportId: "string", diff --git a/packages/schema/dist/packages.d.ts b/packages/schema/dist/packages.d.ts index 83654ba7..df55c568 100644 --- a/packages/schema/dist/packages.d.ts +++ b/packages/schema/dist/packages.d.ts @@ -63,6 +63,8 @@ export declare const PackageReportListStatusSchema: import("arktype/internal/var export type PackageReportListStatus = (typeof PackageReportListStatusSchema)[inferred]; export declare const PackageAppealStatusSchema: import("arktype/internal/variants/string.ts").StringType<"open" | "accepted" | "rejected", {}>; export type PackageAppealStatus = (typeof PackageAppealStatusSchema)[inferred]; +export declare const PackageAppealListStatusSchema: import("arktype/internal/variants/string.ts").StringType<"open" | "all" | "accepted" | "rejected", {}>; +export type PackageAppealListStatus = (typeof PackageAppealListStatusSchema)[inferred]; export declare const PackageArtifactSummarySchema: import("arktype/internal/variants/object.ts").ObjectType<{ kind: "legacy-zip" | "npm-pack"; sha256?: string | undefined; @@ -513,6 +515,44 @@ export declare const ApiV1PackageAppealResponseSchema: import("arktype/internal/ status: "open" | "accepted" | "rejected"; }, {}>; export type ApiV1PackageAppealResponse = (typeof ApiV1PackageAppealResponseSchema)[inferred]; +export declare const PackageAppealResolveRequestSchema: import("arktype/internal/variants/object.ts").ObjectType<{ + status: "open" | "accepted" | "rejected"; + note?: string | undefined; +}, {}>; +export type PackageAppealResolveRequest = (typeof PackageAppealResolveRequestSchema)[inferred]; +export declare const ApiV1PackageAppealListResponseSchema: import("arktype/internal/variants/object.ts").ObjectType<{ + items: { + appealId: string; + packageId: string; + releaseId: string; + name: string; + displayName: string; + family: "skill" | "code-plugin" | "bundle-plugin"; + version: string; + message: string; + status: "open" | "accepted" | "rejected"; + createdAt: number; + submitter: { + userId: string; + handle?: string | null | undefined; + displayName?: string | null | undefined; + }; + resolvedAt?: number | null | undefined; + resolvedBy?: string | null | undefined; + resolutionNote?: string | null | undefined; + }[]; + nextCursor: string | null; + done: boolean; +}, {}>; +export type ApiV1PackageAppealListResponse = (typeof ApiV1PackageAppealListResponseSchema)[inferred]; +export declare const ApiV1PackageAppealResolveResponseSchema: import("arktype/internal/variants/object.ts").ObjectType<{ + ok: true; + appealId: string; + packageId: string; + releaseId: string; + status: "open" | "accepted" | "rejected"; +}, {}>; +export type ApiV1PackageAppealResolveResponse = (typeof ApiV1PackageAppealResolveResponseSchema)[inferred]; export declare const ApiV1PackageReportListResponseSchema: import("arktype/internal/variants/object.ts").ObjectType<{ items: { reportId: string; diff --git a/packages/schema/dist/packages.js b/packages/schema/dist/packages.js index cf98cb5e..667ec509 100644 --- a/packages/schema/dist/packages.js +++ b/packages/schema/dist/packages.js @@ -51,6 +51,7 @@ export const PackageReleaseModerationStateSchema = type('"approved"|"quarantined export const PackageReportStatusSchema = type('"open"|"triaged"|"dismissed"'); export const PackageReportListStatusSchema = PackageReportStatusSchema.or('"all"'); export const PackageAppealStatusSchema = type('"open"|"accepted"|"rejected"'); +export const PackageAppealListStatusSchema = PackageAppealStatusSchema.or('"all"'); export const PackageArtifactSummarySchema = type({ kind: PackageArtifactKindSchema, sha256: "string?", @@ -281,6 +282,41 @@ export const ApiV1PackageAppealResponseSchema = type({ releaseId: "string", status: PackageAppealStatusSchema, }); +export const PackageAppealResolveRequestSchema = type({ + status: PackageAppealStatusSchema, + note: "string?", +}); +export const ApiV1PackageAppealListResponseSchema = type({ + items: type({ + appealId: "string", + packageId: "string", + releaseId: "string", + name: "string", + displayName: "string", + family: PackageFamilySchema, + version: "string", + message: "string", + status: PackageAppealStatusSchema, + createdAt: "number", + submitter: type({ + userId: "string", + handle: "string|null?", + displayName: "string|null?", + }), + resolvedAt: "number|null?", + resolvedBy: "string|null?", + resolutionNote: "string|null?", + }).array(), + nextCursor: "string|null", + done: "boolean", +}); +export const ApiV1PackageAppealResolveResponseSchema = type({ + ok: "true", + appealId: "string", + packageId: "string", + releaseId: "string", + status: PackageAppealStatusSchema, +}); export const ApiV1PackageReportListResponseSchema = type({ items: type({ reportId: "string", diff --git a/packages/schema/dist/packages.js.map b/packages/schema/dist/packages.js.map index 6b6bb551..e6cb3450 100644 --- a/packages/schema/dist/packages.js.map +++ b/packages/schema/dist/packages.js.map @@ -1 +1 @@ -{"version":3,"file":"packages.js","sourceRoot":"","sources":["../src/packages.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"packages.js","sourceRoot":"","sources":["../src/packages.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/schema/src/packages.ts b/packages/schema/src/packages.ts index 77b5d937..a98fca11 100644 --- a/packages/schema/src/packages.ts +++ b/packages/schema/src/packages.ts @@ -80,6 +80,9 @@ export type PackageReportListStatus = (typeof PackageReportListStatusSchema)[inf export const PackageAppealStatusSchema = type('"open"|"accepted"|"rejected"'); export type PackageAppealStatus = (typeof PackageAppealStatusSchema)[inferred]; +export const PackageAppealListStatusSchema = PackageAppealStatusSchema.or('"all"'); +export type PackageAppealListStatus = (typeof PackageAppealListStatusSchema)[inferred]; + export const PackageArtifactSummarySchema = type({ kind: PackageArtifactKindSchema, sha256: "string?", @@ -358,6 +361,49 @@ export const ApiV1PackageAppealResponseSchema = type({ }); export type ApiV1PackageAppealResponse = (typeof ApiV1PackageAppealResponseSchema)[inferred]; +export const PackageAppealResolveRequestSchema = type({ + status: PackageAppealStatusSchema, + note: "string?", +}); +export type PackageAppealResolveRequest = (typeof PackageAppealResolveRequestSchema)[inferred]; + +export const ApiV1PackageAppealListResponseSchema = type({ + items: type({ + appealId: "string", + packageId: "string", + releaseId: "string", + name: "string", + displayName: "string", + family: PackageFamilySchema, + version: "string", + message: "string", + status: PackageAppealStatusSchema, + createdAt: "number", + submitter: type({ + userId: "string", + handle: "string|null?", + displayName: "string|null?", + }), + resolvedAt: "number|null?", + resolvedBy: "string|null?", + resolutionNote: "string|null?", + }).array(), + nextCursor: "string|null", + done: "boolean", +}); +export type ApiV1PackageAppealListResponse = + (typeof ApiV1PackageAppealListResponseSchema)[inferred]; + +export const ApiV1PackageAppealResolveResponseSchema = type({ + ok: "true", + appealId: "string", + packageId: "string", + releaseId: "string", + status: PackageAppealStatusSchema, +}); +export type ApiV1PackageAppealResolveResponse = + (typeof ApiV1PackageAppealResolveResponseSchema)[inferred]; + export const ApiV1PackageReportListResponseSchema = type({ items: type({ reportId: "string",