833f3348a0
apple / swift (push) Successful in 1m22s
release / apple (push) Successful in 9m59s
windows-host / package (push) Successful in 9m52s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 3m20s
apple / screenshots (push) Successful in 6m28s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 3m21s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 4m39s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 5m45s
audit / cargo-audit (push) Successful in 2m58s
audit / bun-audit (push) Successful in 13s
ci / web (push) Successful in 52s
ci / docs-site (push) Successful in 59s
android / android (push) Has been cancelled
arch / build-publish (push) Has been cancelled
ci / bench (push) Has been cancelled
ci / rust (push) Has been cancelled
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 11s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 10s
decky / build-publish (push) Successful in 23s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 10s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 10s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 35s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 49s
flatpak / build-publish (push) Successful in 7m53s
docker / deploy-docs (push) Has been cancelled
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
deb / build-publish (push) Successful in 11m41s
deb / build-publish-host (push) Successful in 13m32s
Console: a Plugins section (Browse / Installed / Sources) on a static nav entry, with install friction proportional to trust — a plain confirm for a verified entry, a warning naming the curator for an external one, and a danger dialog that makes you retype the spec for a raw package. Tier badges are permanent and follow the plugin onto its own UI page. Index: unom/punktfunk-plugin-index published and served from Gitea's raw endpoint (real HTTPS, byte-exact, no vhost to stand up) — merge to main is publish, which resolves the design's open hosting question. Four things only running it could find: - runner discovery matched @punktfunk/plugin-* only, so a third-party scoped plugin (which D8 requires) would install and never run - ...and that convention also matches @punktfunk/plugin-kit, a plugin's own framework: it listed as installed and would have been imported as a unit. Both now key off the plugins dir's top-level dependencies, with an emptied dependency list meaning 'nothing installed' rather than falling back to the naming convention - the store must not pass new flags to the runner: the scripting package ships separately and an older one reads an unknown flag's value as a package name. The host writes the bunfig scope mapping itself - ureq reports only >= 400 as Err, so a conditional request's 304 arrives as Ok with an empty body — handled as an error it made every refresh after the first verify a signature over zero bytes and sit stale Also: the console's first Tabs use exposed an @unom/ui theme gap that rendered inactive tabs invisible (caught in a browser pass, not by types). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
90 lines
2.4 KiB
TypeScript
90 lines
2.4 KiB
TypeScript
import {
|
|
BadgeCheck,
|
|
ShieldAlert,
|
|
ShieldQuestion,
|
|
Terminal,
|
|
} from "lucide-react";
|
|
import type { FC } from "react";
|
|
import type { StoreTier } from "@/api/store";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { cn } from "@/lib/utils";
|
|
import { m } from "@/paraglide/messages";
|
|
|
|
// The trust model, rendered. These badges are the only place the console makes a claim about where
|
|
// a plugin's code came from, so they are deliberately literal: ONLY the built-in `unom` source earns
|
|
// the check mark, everything else says out loud that nobody at unom looked at the code. An entry
|
|
// from an operator-added source additionally carries a <SourceChip> naming that source — attribution
|
|
// instead of a verification it hasn't got.
|
|
|
|
/** The short, permanent provenance badge for a tier. */
|
|
export const TierBadge: FC<{ tier: StoreTier; className?: string }> = ({
|
|
tier,
|
|
className,
|
|
}) => {
|
|
switch (tier) {
|
|
case "verified":
|
|
return (
|
|
<Badge
|
|
variant="success"
|
|
className={cn("gap-1", className)}
|
|
title={m.store_tier_verified_hint()}
|
|
>
|
|
<BadgeCheck className="size-3.5" />
|
|
{m.store_tier_verified()}
|
|
</Badge>
|
|
);
|
|
case "external":
|
|
return (
|
|
<Badge
|
|
variant="outline"
|
|
className={cn(
|
|
"gap-1 border-amber-600/40 text-amber-600 dark:border-amber-500/40 dark:text-amber-500",
|
|
className,
|
|
)}
|
|
title={m.store_tier_external_hint()}
|
|
>
|
|
<ShieldQuestion className="size-3.5" />
|
|
{m.store_tier_external()}
|
|
</Badge>
|
|
);
|
|
case "unverified":
|
|
return (
|
|
<Badge
|
|
variant="destructive"
|
|
className={cn("gap-1", className)}
|
|
title={m.store_tier_unverified_hint()}
|
|
>
|
|
<ShieldAlert className="size-3.5" />
|
|
{m.store_tier_unverified()}
|
|
</Badge>
|
|
);
|
|
default:
|
|
return (
|
|
<Badge
|
|
variant="secondary"
|
|
className={cn("gap-1", className)}
|
|
title={m.store_tier_cli_hint()}
|
|
>
|
|
<Terminal className="size-3.5" />
|
|
{m.store_tier_cli()}
|
|
</Badge>
|
|
);
|
|
}
|
|
};
|
|
|
|
/** "from <source>" — who curated this entry. Shown for anything not from the built-in source. */
|
|
export const SourceChip: FC<{ source: string; className?: string }> = ({
|
|
source,
|
|
className,
|
|
}) => (
|
|
<span
|
|
className={cn(
|
|
"inline-flex items-center gap-1 text-xs text-muted-foreground",
|
|
className,
|
|
)}
|
|
>
|
|
{m.store_from_source()}
|
|
<span className="font-medium text-foreground">{source}</span>
|
|
</span>
|
|
);
|