treefmt: apply prettier

Pure `nix fmt` output from the commit before this one — no hand edits.
203 files: 52 md, 42 tsx, 32 js, 32 css, 21 ts, 13 html, 8 json, 3 mjs.

Reproduce with `nix develop -c nix fmt` on the parent commit; the result
should be byte-identical to this tree.

None of the 13 `.prettierignore` entries appears here — verified by
intersecting the changed-file list against the ignore file, with a
control proving the intersection finds a match when one exists.
This commit is contained in:
atlas 2026-09-02 14:29:33 +02:00
commit 39b95c2ede
203 changed files with 10090 additions and 6085 deletions

View file

@ -5,8 +5,8 @@
// the UI derives from it, like the turn-state badge's elapsed-time text —
// goes stale until something proactively refetches; without this the
// only way back to a live reading was a full page reload.
import { useEffect, useRef, useState } from 'preact/hooks';
import type { AgentState } from '../types.js';
import { useEffect, useRef, useState } from "preact/hooks";
import type { AgentState } from "../types.js";
const POLL_MS = 4000;
const RETRY_MS = 5000;
@ -38,7 +38,7 @@ export function useAgentState(): UseAgentStateResult {
async function poll() {
try {
const resp = await fetch('api/state');
const resp = await fetch("api/state");
if (!resp.ok) throw new Error(`http ${resp.status}`);
const s = (await resp.json()) as AgentState;
if (stoppedRef.current) return;
@ -80,10 +80,10 @@ export function useAgentState(): UseAgentStateResult {
// component that calls this hook.
useEffect(() => {
function onVisible() {
if (document.visibilityState === 'visible') refresh();
if (document.visibilityState === "visible") refresh();
}
document.addEventListener('visibilitychange', onVisible);
return () => document.removeEventListener('visibilitychange', onVisible);
document.addEventListener("visibilitychange", onVisible);
return () => document.removeEventListener("visibilitychange", onVisible);
}, []);
return { state, error, refresh };

View file

@ -15,8 +15,8 @@
// initial history page, drop it from the buffer). `seq` alone is the
// whole dedup signal, see `TermEnvelope`'s doc in hive-agent's
// `web_ui/stream.rs`.
import { useEffect, useRef, useState } from 'preact/hooks';
import type { TermEnvelope, TermRow } from '../lib/termMsg.js';
import { useEffect, useRef, useState } from "preact/hooks";
import type { TermEnvelope, TermRow } from "../lib/termMsg.js";
export interface UseLiveStreamOptions {
historyUrl?: string;
@ -50,9 +50,11 @@ function appendRow(rows: TermRow[], row: TermRow): TermRow[] {
return [...rows, row];
}
export function useLiveStream(opts: UseLiveStreamOptions = {}): UseLiveStreamResult {
const historyUrl = opts.historyUrl ?? 'events/history';
const streamUrl = opts.streamUrl ?? 'events/stream';
export function useLiveStream(
opts: UseLiveStreamOptions = {},
): UseLiveStreamResult {
const historyUrl = opts.historyUrl ?? "events/history";
const streamUrl = opts.streamUrl ?? "events/stream";
const [rows, setRows] = useState<TermRow[]>([]);
const [hasMore, setHasMore] = useState(false);
@ -61,12 +63,16 @@ export function useLiveStream(opts: UseLiveStreamOptions = {}): UseLiveStreamRes
const keySeqRef = useRef(0);
function nextKey(): string {
keySeqRef.current += 1;
return 'r' + keySeqRef.current;
return "r" + keySeqRef.current;
}
function toRows(env: TermEnvelope, fromHistory: boolean): TermRow[] {
return env.msgs.map((m) => ({ ...m, key: nextKey(), fromHistory }));
}
function appendEnvelope(rows: TermRow[], env: TermEnvelope, fromHistory: boolean): TermRow[] {
function appendEnvelope(
rows: TermRow[],
env: TermEnvelope,
fromHistory: boolean,
): TermRow[] {
let next = rows;
for (const row of toRows(env, fromHistory)) next = appendRow(next, row);
return next;
@ -89,9 +95,14 @@ export function useLiveStream(opts: UseLiveStreamOptions = {}): UseLiveStreamRes
try {
env = JSON.parse(e.data);
} catch {
setRows((prev) => appendRow(prev, {
key: 'parse-err-' + Date.now(), level: 'warn', summary: '[parse err] ' + e.data, fromHistory: false,
}));
setRows((prev) =>
appendRow(prev, {
key: "parse-err-" + Date.now(),
level: "warn",
summary: "[parse err] " + e.data,
fromHistory: false,
}),
);
return;
}
if (!liveRef.current) {
@ -101,30 +112,54 @@ export function useLiveStream(opts: UseLiveStreamOptions = {}): UseLiveStreamRes
pushLive(env);
};
es.onerror = () => {
setRows((prev) => appendRow(prev, {
key: 'conn-note', level: 'warn', fromHistory: false, coalesce_key: 'conn-status',
summary: es.readyState === 0 /* CONNECTING */ ? '[reconnecting…]' : '[disconnected]',
}));
setRows((prev) =>
appendRow(prev, {
key: "conn-note",
level: "warn",
fromHistory: false,
coalesce_key: "conn-status",
summary:
es.readyState === 0 /* CONNECTING */
? "[reconnecting…]"
: "[disconnected]",
}),
);
};
async function backfill() {
try {
const resp = await fetch(historyUrl);
if (!resp.ok) throw new Error('http ' + resp.status);
if (!resp.ok) throw new Error("http " + resp.status);
const body = await resp.json();
const events: TermEnvelope[] = Array.isArray(body) ? body : body.events || [];
const boundarySeq: number | null = Array.isArray(body) ? null : (body.seq ?? null);
const events: TermEnvelope[] = Array.isArray(body)
? body
: body.events || [];
const boundarySeq: number | null = Array.isArray(body)
? null
: (body.seq ?? null);
if (!Array.isArray(body)) {
setHasMore(!!body.has_more);
if (typeof body.min_id === 'number') minIdRef.current = body.min_id;
if (typeof body.min_id === "number") minIdRef.current = body.min_id;
}
if (cancelled) return;
let initial: TermRow[] = [];
for (const env of events) initial = appendEnvelope(initial, env, true);
initial = events.length
? appendRow(initial, { key: 'live-sep', level: 'debug', fromHistory: true, summary: '─── live (older above) ───' })
: [{ key: 'placeholder', level: 'debug', fromHistory: true, summary: '(connected — waiting for events)' }];
? appendRow(initial, {
key: "live-sep",
level: "debug",
fromHistory: true,
summary: "─── live (older above) ───",
})
: [
{
key: "placeholder",
level: "debug",
fromHistory: true,
summary: "(connected — waiting for events)",
},
];
setRows(initial);
const drained = bufferedRef.current;
@ -133,11 +168,16 @@ export function useLiveStream(opts: UseLiveStreamOptions = {}): UseLiveStreamRes
for (const env of drained) {
// Already covered by the initial history page — drop it from
// the buffer rather than rendering it twice.
if (boundarySeq != null && typeof env.seq === 'number' && env.seq <= boundarySeq) continue;
if (
boundarySeq != null &&
typeof env.seq === "number" &&
env.seq <= boundarySeq
)
continue;
pushLive(env);
}
} catch (err) {
console.warn('history backfill failed', err);
console.warn("history backfill failed", err);
if (cancelled) return;
const drained = bufferedRef.current;
bufferedRef.current = [];
@ -157,30 +197,42 @@ export function useLiveStream(opts: UseLiveStreamOptions = {}): UseLiveStreamRes
if (!hasMore || loadingMore || minIdRef.current == null) return;
setLoadingMore(true);
try {
const sep = historyUrl.includes('?') ? '&' : '?';
const resp = await fetch(historyUrl + sep + 'before=' + minIdRef.current);
const sep = historyUrl.includes("?") ? "&" : "?";
const resp = await fetch(historyUrl + sep + "before=" + minIdRef.current);
if (!resp.ok) return;
const body = await resp.json();
const events: TermEnvelope[] = Array.isArray(body) ? body : body.events || [];
const events: TermEnvelope[] = Array.isArray(body)
? body
: body.events || [];
setHasMore(!!body.has_more);
if (typeof body.min_id === 'number') minIdRef.current = body.min_id;
if (typeof body.min_id === "number") minIdRef.current = body.min_id;
if (events.length) {
let older: TermRow[] = [];
for (const env of events) older = appendEnvelope(older, env, true);
older = appendRow(older, {
key: 'older-sep-' + minIdRef.current, level: 'debug', fromHistory: true, summary: '─── older above ───',
key: "older-sep-" + minIdRef.current,
level: "debug",
fromHistory: true,
summary: "─── older above ───",
});
setRows((prev) => [...older, ...prev]);
}
} catch (err) {
console.warn('loadMore failed', err);
console.warn("loadMore failed", err);
} finally {
setLoadingMore(false);
}
}
function pushLocalNote(text: string) {
setRows((prev) => appendRow(prev, { key: 'local-' + nextKey(), level: 'info', fromHistory: false, summary: text }));
setRows((prev) =>
appendRow(prev, {
key: "local-" + nextKey(),
level: "info",
fromHistory: false,
summary: text,
}),
);
}
function clearLocal() {
setRows([]);

View file

@ -3,8 +3,8 @@
// useAgentState: todos change asynchronously (matrix syncs, bash task
// starts/completions) independent of the state snapshot, and the old
// page polled them independently too.
import { useEffect, useRef, useState } from 'preact/hooks';
import type { TodoRow } from '../types.js';
import { useEffect, useRef, useState } from "preact/hooks";
import type { TodoRow } from "../types.js";
const POLL_MS = 4000;
@ -20,16 +20,16 @@ export function useTodos(): UseTodosResult {
async function poll() {
try {
const resp = await fetch('api/todos');
const resp = await fetch("api/todos");
if (!resp.ok) throw new Error(`http ${resp.status}`);
const body = (await resp.json()) as { todos?: TodoRow[] };
if (stoppedRef.current) return;
// Defensive filter: the wire type is the general `LooseEnd` tagged
// enum even though this endpoint only ever emits the `todo` variant
// today — see types.ts's TodoRow comment.
setTodos((body.todos ?? []).filter((t) => t.kind === 'todo'));
setTodos((body.todos ?? []).filter((t) => t.kind === "todo"));
} catch (err) {
console.warn('todos fetch failed', err);
console.warn("todos fetch failed", err);
if (!stoppedRef.current) setTodos([]);
}
}