water bucket release!
release / build (push) Successful in 6m12s

same version for everyone this time. This makes stuff easy
This commit is contained in:
lda
2026-04-29 00:37:35 +07:00 Verified
parent 76982195ab
commit 2b98662bcc
8 changed files with 82 additions and 32 deletions
Generated
+5 -5
View File
@@ -3701,7 +3701,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "wakey" name = "wakey"
version = "0.2.2" version = "0.2.3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@@ -3722,7 +3722,7 @@ dependencies = [
[[package]] [[package]]
name = "wakey-agent" name = "wakey-agent"
version = "0.1.2" version = "0.2.3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@@ -3746,7 +3746,7 @@ dependencies = [
[[package]] [[package]]
name = "wakey-control-plane" name = "wakey-control-plane"
version = "0.1.2" version = "0.2.3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"axum", "axum",
@@ -3774,7 +3774,7 @@ dependencies = [
[[package]] [[package]]
name = "wakey-core" name = "wakey-core"
version = "0.2.2" version = "0.2.3"
dependencies = [ dependencies = [
"macaddr", "macaddr",
"serde", "serde",
@@ -3785,7 +3785,7 @@ dependencies = [
[[package]] [[package]]
name = "wakey-linux" name = "wakey-linux"
version = "0.2.2" version = "0.2.3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"futures", "futures",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "wakey" name = "wakey"
version = "0.2.2" version = "0.2.3"
edition = "2024" edition = "2024"
publish = ["gitea"] publish = ["gitea"]
+1 -3
View File
@@ -50,9 +50,7 @@ export function AppLayout() {
<div className="mx-auto max-w-7xl p-4"> <div className="mx-auto max-w-7xl p-4">
<header className="mb-4 flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between"> <header className="mb-4 flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
<div> <div>
<h1 className="text-2xl font-semibold tracking-tight"> <h1 className="text-2xl font-semibold tracking-tight">Wakey</h1>
Wakey
</h1>
<p className="mt-1 text-sm text-muted-foreground"> <p className="mt-1 text-sm text-muted-foreground">
Fleet devices, presence, and wake controls Fleet devices, presence, and wake controls
</p> </p>
+71 -19
View File
@@ -198,7 +198,8 @@ export function DevicesPage({ agents, onAfterWake }: Props) {
if (sort.key === "last_seen") { if (sort.key === "last_seen") {
return dir * ((a.last_seen_unix ?? 0) - (b.last_seen_unix ?? 0)); return dir * ((a.last_seen_unix ?? 0) - (b.last_seen_unix ?? 0));
} }
if (sort.key === "agents") return dir * (a.agents.length - b.agents.length); if (sort.key === "agents")
return dir * (a.agents.length - b.agents.length);
if (sort.key === "ip") { if (sort.key === "ip") {
return dir * (a.ips[0] ?? "").localeCompare(b.ips[0] ?? ""); return dir * (a.ips[0] ?? "").localeCompare(b.ips[0] ?? "");
} }
@@ -220,7 +221,8 @@ export function DevicesPage({ agents, onAfterWake }: Props) {
<div> <div>
<CardTitle>Devices</CardTitle> <CardTitle>Devices</CardTitle>
<p className="mt-1 text-sm text-muted-foreground"> <p className="mt-1 text-sm text-muted-foreground">
{devices.length} fleet rows from stored observations and known devices {devices.length} fleet rows from stored observations and known
devices
</p> </p>
</div> </div>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
@@ -239,7 +241,9 @@ export function DevicesPage({ agents, onAfterWake }: Props) {
disabled={refreshing || connectedCount === 0} disabled={refreshing || connectedCount === 0}
> >
<RefreshCw className="size-4" aria-hidden /> <RefreshCw className="size-4" aria-hidden />
{refreshing ? "Collecting" : `Collect fleet (${connectedCount})`} {refreshing
? "Collecting"
: `Collect fleet (${connectedCount})`}
</Button> </Button>
</div> </div>
</div> </div>
@@ -272,9 +276,20 @@ export function DevicesPage({ agents, onAfterWake }: Props) {
/> />
<label className="grid gap-1 text-sm text-muted-foreground"> <label className="grid gap-1 text-sm text-muted-foreground">
<span>Agent</span> <span>Agent</span>
<Select value={agentId} onValueChange={(value) => setAgentId(value ?? "all")}> <Select
value={agentId}
onValueChange={(value) => setAgentId(value ?? "all")}
>
<SelectTrigger> <SelectTrigger>
<span>{agentId === "all" ? "all agents" : agentLabel(agentId, agents.find((agent) => agent.agent_id === agentId)?.nickname)}</span> <span>
{agentId === "all"
? "all agents"
: agentLabel(
agentId,
agents.find((agent) => agent.agent_id === agentId)
?.nickname,
)}
</span>
</SelectTrigger> </SelectTrigger>
<SelectContent alignItemWithTrigger={false}> <SelectContent alignItemWithTrigger={false}>
<SelectItem value="all">all agents</SelectItem> <SelectItem value="all">all agents</SelectItem>
@@ -413,7 +428,11 @@ function FleetDeviceRow({
</span> </span>
<span className="min-w-0 text-muted-foreground xl:truncate"> <span className="min-w-0 text-muted-foreground xl:truncate">
<MobileLabel label="Agents" /> <MobileLabel label="Agents" />
{summarize(device.agents.map((agent) => agentLabel(agent.agent_id, agent.nickname)))} {summarize(
device.agents.map((agent) =>
agentLabel(agent.agent_id, agent.nickname),
),
)}
</span> </span>
<span className="text-muted-foreground"> <span className="text-muted-foreground">
<MobileLabel label="Last seen" /> <MobileLabel label="Last seen" />
@@ -544,9 +563,13 @@ function FleetDeviceDetailsDialog({
<DialogHeader> <DialogHeader>
<div className="flex min-w-0 items-start justify-between gap-3 pr-8"> <div className="flex min-w-0 items-start justify-between gap-3 pr-8">
<div className="min-w-0"> <div className="min-w-0">
<DialogTitle className="truncate">{device.display_name}</DialogTitle> <DialogTitle className="truncate">
{device.display_name}
</DialogTitle>
<DialogDescription> <DialogDescription>
{device.known_device ? "Remembered fleet device" : "Observed fleet device"} {device.known_device
? "Remembered fleet device"
: "Observed fleet device"}
</DialogDescription> </DialogDescription>
</div> </div>
<PresenceBadge presence={device.presence} /> <PresenceBadge presence={device.presence} />
@@ -562,10 +585,16 @@ function FleetDeviceDetailsDialog({
<div className="grid gap-3 md:grid-cols-2"> <div className="grid gap-3 md:grid-cols-2">
<DetailBlock label="IPs" values={device.ips} onCopy={onCopy} /> <DetailBlock label="IPs" values={device.ips} onCopy={onCopy} />
<DetailBlock label="MACs" values={device.macs} onCopy={onCopy} /> <DetailBlock label="MACs" values={device.macs} onCopy={onCopy} />
<DetailBlock label="Hostnames" values={device.hostnames} onCopy={onCopy} /> <DetailBlock
label="Hostnames"
values={device.hostnames}
onCopy={onCopy}
/>
<DetailBlock <DetailBlock
label="Agents" label="Agents"
values={device.agents.map((agent) => agentLabel(agent.agent_id, agent.nickname))} values={device.agents.map((agent) =>
agentLabel(agent.agent_id, agent.nickname),
)}
onCopy={onCopy} onCopy={onCopy}
/> />
</div> </div>
@@ -584,7 +613,10 @@ function FleetDeviceDetailsDialog({
{busy ? "Waking" : "Wake"} {busy ? "Waking" : "Wake"}
</Button> </Button>
</div> </div>
<Select value={routeId} onValueChange={(value) => setRouteId(value ?? "")}> <Select
value={routeId}
onValueChange={(value) => setRouteId(value ?? "")}
>
<SelectTrigger> <SelectTrigger>
<span> <span>
{selectedRoute {selectedRoute
@@ -613,21 +645,32 @@ function FleetDeviceDetailsDialog({
onChange={(event) => setDisplayName(event.target.value)} onChange={(event) => setDisplayName(event.target.value)}
placeholder="Device name" placeholder="Device name"
/> />
<Button onClick={() => void createRemembered()} disabled={!identifiers.length}> <Button
onClick={() => void createRemembered()}
disabled={!identifiers.length}
>
Remember device Remember device
</Button> </Button>
</div> </div>
)} )}
<div className="grid gap-2 md:grid-cols-[minmax(0,1fr)_auto_auto]"> <div className="grid gap-2 md:grid-cols-[minmax(0,1fr)_auto_auto]">
<Select value={targetDeviceId} onValueChange={(value) => setTargetDeviceId(value ?? "")}> <Select
value={targetDeviceId}
onValueChange={(value) => setTargetDeviceId(value ?? "")}
>
<SelectTrigger> <SelectTrigger>
<span> <span>
{targetDeviceId {targetDeviceId
? knownDevices.find((known) => known.device_id === targetDeviceId)?.display_name ? knownDevices.find(
(known) => known.device_id === targetDeviceId,
)?.display_name
: "Select known device"} : "Select known device"}
</span> </span>
</SelectTrigger> </SelectTrigger>
<SelectContent className="max-w-[min(92vw,30rem)]" alignItemWithTrigger={false}> <SelectContent
className="max-w-[min(92vw,30rem)]"
alignItemWithTrigger={false}
>
{otherKnownDevices.map((known) => ( {otherKnownDevices.map((known) => (
<SelectItem key={known.device_id} value={known.device_id}> <SelectItem key={known.device_id} value={known.device_id}>
{known.display_name} {known.display_name}
@@ -651,7 +694,9 @@ function FleetDeviceDetailsDialog({
</Button> </Button>
</div> </div>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
Proposed identifiers: {identifiers.map((id) => `${id.kind}:${id.value}`).join(", ") || "-"} Proposed identifiers:{" "}
{identifiers.map((id) => `${id.kind}:${id.value}`).join(", ") ||
"-"}
</p> </p>
</div> </div>
@@ -719,7 +764,10 @@ function DetailBlock({
onClick={() => onCopy(label, value)} onClick={() => onCopy(label, value)}
> >
<span className="min-w-0 truncate">{value}</span> <span className="min-w-0 truncate">{value}</span>
<Copy className="size-3.5 shrink-0 text-muted-foreground" aria-hidden /> <Copy
className="size-3.5 shrink-0 text-muted-foreground"
aria-hidden
/>
</button> </button>
)) ))
) : ( ) : (
@@ -771,7 +819,9 @@ function presenceRank(presence: string): number {
return 0; return 0;
} }
function identifiersFor(device: FleetDevice): { kind: string; value: string }[] { function identifiersFor(
device: FleetDevice,
): { kind: string; value: string }[] {
return [ return [
...device.macs.map((value) => ({ kind: "mac", value })), ...device.macs.map((value) => ({ kind: "mac", value })),
...device.ips.map((value) => ({ kind: "ip", value })), ...device.ips.map((value) => ({ kind: "ip", value })),
@@ -785,6 +835,8 @@ function agentLabel(agentId: string, nickname?: string | null): string {
function routeLabel(route: FleetWakeRoute): string { function routeLabel(route: FleetWakeRoute): string {
const status = route.connected ? "connected" : "offline"; const status = route.connected ? "connected" : "offline";
const target = route.mac ? `${route.mac}${route.ip ? ` / ${route.ip}` : ""}` : route.ip ?? "-"; const target = route.mac
? `${route.mac}${route.ip ? ` / ${route.ip}` : ""}`
: (route.ip ?? "-");
return `${agentLabel(route.agent_id, route.nickname)} · ${target} · ${route.source} · ${status}`; return `${agentLabel(route.agent_id, route.nickname)} · ${target} · ${route.source} · ${status}`;
} }
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "wakey-agent" name = "wakey-agent"
version = "0.1.2" version = "0.2.3"
edition = "2024" edition = "2024"
publish = ["gitea"] publish = ["gitea"]
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "wakey-control-plane" name = "wakey-control-plane"
version = "0.1.2" version = "0.2.3"
edition = "2024" edition = "2024"
publish = ["gitea"] publish = ["gitea"]
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "wakey-core" name = "wakey-core"
version = "0.2.2" version = "0.2.3"
edition = "2024" edition = "2024"
publish = ["gitea"] publish = ["gitea"]
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "wakey-linux" name = "wakey-linux"
version = "0.2.2" version = "0.2.3"
edition = "2024" edition = "2024"
publish = ["gitea"] publish = ["gitea"]