@@ -489,9 +489,9 @@ function TracesEmptyState({ hasFilters }: { hasFilters: boolean }) {
@@ -511,19 +511,19 @@ interface PeekPanelProps {
}
function TracesPeekPanel({ traceId, envelope, cliCommand, listParams }: PeekPanelProps) {
- const firstEvent = envelope.events[0];
+ const [firstEvent] = envelope.events;
const closeHref = listHref(listParams, { peek: undefined });
const detailHref = `/audit/${encodeURIComponent(traceId)}`;
return (
-
+
@@ -532,19 +532,19 @@ function TracesPeekPanel({ traceId, envelope, cliCommand, listParams }: PeekPane
{/* Summary meta */}
-
+
{envelope.events.length} events
{firstEvent ? (
-
+
actor{" "}
{firstEvent.actor_type}/{firstEvent.actor_id}
@@ -559,19 +559,19 @@ function TracesPeekPanel({ traceId, envelope, cliCommand, listParams }: PeekPane
-
+
{event.event_type}
@@ -584,8 +584,8 @@ function TracesPeekPanel({ traceId, envelope, cliCommand, listParams }: PeekPane
{event.status}
@@ -603,20 +603,20 @@ function TracesPeekPanel({ traceId, envelope, cliCommand, listParams }: PeekPane
{/* CLI command */}
CLI
diff --git a/apps/console/src/app/(console)/components/cli-copy-consistency.test.ts b/apps/console/src/app/(console)/components/cli-copy-consistency.test.ts
index 073d35a38..f075d31be 100644
--- a/apps/console/src/app/(console)/components/cli-copy-consistency.test.ts
+++ b/apps/console/src/app/(console)/components/cli-copy-consistency.test.ts
@@ -61,24 +61,26 @@ const PEEK_NO_INSTALL_HOOK = /peek-cli-no-install/;
const DETAIL_NO_INSTALL_HOOK = /cli-no-install-command/;
test("no surfaced file advertises legacy bare pdpp run/grant/trace aliases", async () => {
- for (const relPath of SURFACED_FILES) {
- const src = await read(relPath);
- assert.equal(
- LEGACY_RUN_TIMELINE.test(src),
- false,
- `${relPath}: found legacy 'pdpp run timeline' - use 'pdpp ref run timeline'`
- );
- assert.equal(
- LEGACY_GRANT_TIMELINE.test(src),
- false,
- `${relPath}: found legacy 'pdpp grant timeline' - use 'pdpp ref grant timeline'`
- );
- assert.equal(
- LEGACY_TRACE_SHOW.test(src),
- false,
- `${relPath}: found legacy 'pdpp trace show' - use 'pdpp ref trace show'`
- );
- }
+ await Promise.all(
+ SURFACED_FILES.map(async (relPath) => {
+ const src = await read(relPath);
+ assert.equal(
+ LEGACY_RUN_TIMELINE.test(src),
+ false,
+ `${relPath}: found legacy 'pdpp run timeline' - use 'pdpp ref run timeline'`
+ );
+ assert.equal(
+ LEGACY_GRANT_TIMELINE.test(src),
+ false,
+ `${relPath}: found legacy 'pdpp grant timeline' - use 'pdpp ref grant timeline'`
+ );
+ assert.equal(
+ LEGACY_TRACE_SHOW.test(src),
+ false,
+ `${relPath}: found legacy 'pdpp trace show' - use 'pdpp ref trace show'`
+ );
+ })
+ );
});
test("reference-implementation.md advertises canonical pdpp ref commands", async () => {
diff --git a/apps/console/src/app/(console)/components/deployment-readiness-panel.tsx b/apps/console/src/app/(console)/components/deployment-readiness-panel.tsx
index 90d435195..33b0b70cf 100644
--- a/apps/console/src/app/(console)/components/deployment-readiness-panel.tsx
+++ b/apps/console/src/app/(console)/components/deployment-readiness-panel.tsx
@@ -89,7 +89,7 @@ function useRefreshTokenAdvertisement(): RefreshTokenProbe {
const grants = Array.isArray(body.grant_types_supported) ? body.grant_types_supported : [];
const refreshTokenSupported = grants.some((g) => g === "refresh_token");
if (!cancelled) {
- setProbe({ state: "loaded", refreshTokenSupported });
+ setProbe({ refreshTokenSupported, state: "loaded" });
}
} catch {
if (!cancelled) {
@@ -118,32 +118,32 @@ function verdictPresentation(verdict: Verdict): { label: string; body: string; t
switch (verdict) {
case "ready":
return {
- label: "Ready to share with Claude / ChatGPT",
body: "Owner gate, origin, storage, embeddings, and refresh-token metadata all check out.",
+ label: "Ready to share with Claude / ChatGPT",
toneClass: "border-[color:var(--success)]/30 bg-[color:var(--success-wash)] text-[color:var(--success)]",
};
case "attention":
return {
- label: "Attention needed before sharing",
body: "Some rows are usable but suboptimal. Read the hints below.",
+ label: "Attention needed before sharing",
toneClass: "border-[color:var(--warning)]/30 bg-[color:var(--warning-wash)] text-[color:var(--warning)]",
};
case "blocked":
return {
- label: "Not yet ready to share",
body: "At least one row is in an error state. Fix it before handing the MCP URL to an agent.",
+ label: "Not yet ready to share",
toneClass: "border-destructive/30 bg-destructive/5 text-destructive",
};
case "unknown":
return {
- label: "Some checks still running",
body: "Browser-side probes have not returned yet.",
+ label: "Some checks still running",
toneClass: "border-border/80 bg-muted/40 text-foreground",
};
default:
return {
- label: "Some checks still running",
body: "Browser-side probes have not returned yet.",
+ label: "Some checks still running",
toneClass: "border-border/80 bg-muted/40 text-foreground",
};
}
@@ -163,27 +163,27 @@ function ReadinessRowItem({ row }: { row: ReadinessRow }) {
}
const STATUS_TONE: Record = {
- ok: "bg-[color:var(--success-wash)] text-[color:var(--success)]",
- warn: "bg-[color:var(--warning-wash)] text-[color:var(--warning)]",
error: "bg-destructive/10 text-destructive",
info: "bg-muted text-muted-foreground",
+ ok: "bg-[color:var(--success-wash)] text-[color:var(--success)]",
unknown: "bg-muted text-muted-foreground",
+ warn: "bg-[color:var(--warning-wash)] text-[color:var(--warning)]",
};
const STATUS_LABEL: Record = {
- ok: "ready",
- warn: "attention",
error: "blocked",
info: "n/a",
+ ok: "ready",
unknown: "checking",
+ warn: "attention",
};
const STATUS_BADGE_TONE: Record = {
- ok: "success",
- warn: "warning",
error: "danger",
info: "neutral",
+ ok: "success",
unknown: "neutral",
+ warn: "warning",
};
function StatusChip({ status }: { status: ReadinessStatus }) {
diff --git a/apps/console/src/app/(console)/components/deployment-readiness-rows.test.ts b/apps/console/src/app/(console)/components/deployment-readiness-rows.test.ts
index d3a5417ce..c12815123 100644
--- a/apps/console/src/app/(console)/components/deployment-readiness-rows.test.ts
+++ b/apps/console/src/app/(console)/components/deployment-readiness-rows.test.ts
@@ -30,25 +30,25 @@ import {
} from "./deployment-readiness-rows.ts";
const HEALTHY_DISK_HEADROOM: DiskHeadroomInputs = {
- path: "/data",
freeBytesOnDataFs: 20 * 1024 * 1024 * 1024, // 20 GiB
- totalBytesOnDataFs: 100 * 1024 * 1024 * 1024,
largestRelationBytes: null,
largestRelationName: null,
mountLabel: null,
+ path: "/data",
+ totalBytesOnDataFs: 100 * 1024 * 1024 * 1024,
};
const baseInputs: ServerInputs = {
- ownerPasswordProvenance: "redacted",
- referenceOriginConfigured: "https://example.com",
- embeddingBackendConfigured: true,
+ databasePath: "/data/pdpp.db",
+ diskHeadroom: [HEALTHY_DISK_HEADROOM],
embeddingBackendAvailable: true,
- embeddingModelCachePresent: true,
+ embeddingBackendConfigured: true,
embeddingDownloadAllowed: true,
+ embeddingModelCachePresent: true,
+ ownerPasswordProvenance: "redacted",
+ referenceOriginConfigured: "https://example.com",
vectorIndexKind: "sqlite-vec",
vectorIndexState: "built",
- databasePath: "/data/pdpp.db",
- diskHeadroom: [HEALTHY_DISK_HEADROOM],
};
const OWNER_PASSWORD_ENV_RE = /PDPP_OWNER_PASSWORD/;
@@ -138,8 +138,8 @@ test("embeddingCacheRow is error when uncached and download disabled", () => {
const row = embeddingCacheRow({
...baseInputs,
embeddingBackendAvailable: false,
- embeddingModelCachePresent: false,
embeddingDownloadAllowed: false,
+ embeddingModelCachePresent: false,
});
assert.equal(row.status, "error");
});
@@ -148,8 +148,8 @@ test("embeddingCacheRow is warn while cache is warming", () => {
const row = embeddingCacheRow({
...baseInputs,
embeddingBackendAvailable: false,
- embeddingModelCachePresent: false,
embeddingDownloadAllowed: true,
+ embeddingModelCachePresent: false,
});
assert.equal(row.status, "warn");
});
@@ -167,11 +167,11 @@ test("refreshTokenRow is warn when well-known is unreachable", () => {
});
test("refreshTokenRow is ok when refresh_token is advertised", () => {
- assert.equal(refreshTokenRow({ state: "loaded", refreshTokenSupported: true }).status, "ok");
+ assert.equal(refreshTokenRow({ refreshTokenSupported: true, state: "loaded" }).status, "ok");
});
test("refreshTokenRow is error when refresh_token is missing", () => {
- const row = refreshTokenRow({ state: "loaded", refreshTokenSupported: false });
+ const row = refreshTokenRow({ refreshTokenSupported: false, state: "loaded" });
assert.equal(row.status, "error");
assert.match(row.hint ?? "", DOCKER_COMPOSE_PULL_RE);
});
@@ -179,31 +179,31 @@ test("refreshTokenRow is error when refresh_token is missing", () => {
// ─── Overall verdict ────────────────────────────────────────────────────────
test("overallVerdict ready when every row is ok", () => {
- const rows: ReadinessRow[] = [{ check: "x", status: "ok", detail: "" }];
+ const rows: ReadinessRow[] = [{ check: "x", detail: "", status: "ok" }];
assert.equal(overallVerdict(rows), "ready");
});
test("overallVerdict blocked when any row is error", () => {
const rows: ReadinessRow[] = [
- { check: "x", status: "ok", detail: "" },
- { check: "y", status: "error", detail: "" },
- { check: "z", status: "warn", detail: "" },
+ { check: "x", detail: "", status: "ok" },
+ { check: "y", detail: "", status: "error" },
+ { check: "z", detail: "", status: "warn" },
];
assert.equal(overallVerdict(rows), "blocked");
});
test("overallVerdict attention when any row is warn but none is error", () => {
const rows: ReadinessRow[] = [
- { check: "x", status: "ok", detail: "" },
- { check: "y", status: "warn", detail: "" },
+ { check: "x", detail: "", status: "ok" },
+ { check: "y", detail: "", status: "warn" },
];
assert.equal(overallVerdict(rows), "attention");
});
test("overallVerdict unknown when probes still loading and nothing worse", () => {
const rows: ReadinessRow[] = [
- { check: "x", status: "ok", detail: "" },
- { check: "y", status: "unknown", detail: "" },
+ { check: "x", detail: "", status: "ok" },
+ { check: "y", detail: "", status: "unknown" },
];
assert.equal(overallVerdict(rows), "unknown");
});
@@ -279,9 +279,9 @@ test("diskHeadroomRow includes workload hint when free < largestRelationBytes",
makeEntry({
// 4 GiB free — below warn (5 GiB) and below largest relation (6 GiB).
freeBytesOnDataFs: 4 * GiB,
- totalBytesOnDataFs: 100 * GiB,
largestRelationBytes: 6 * GiB,
largestRelationName: "records",
+ totalBytesOnDataFs: 100 * GiB,
}),
],
});
@@ -297,9 +297,9 @@ test("diskHeadroomRow omits workload hint when free >= largestRelationBytes", ()
makeEntry({
// 4 GiB free — below warn but ABOVE largest relation (3 GiB).
freeBytesOnDataFs: 4 * GiB,
- totalBytesOnDataFs: 100 * GiB,
largestRelationBytes: 3 * GiB,
largestRelationName: "records",
+ totalBytesOnDataFs: 100 * GiB,
}),
],
});
@@ -313,9 +313,9 @@ test("diskHeadroomRow omits workload hint when largestRelationBytes is null (SQL
diskHeadroom: [
makeEntry({
freeBytesOnDataFs: 4 * GiB,
- totalBytesOnDataFs: 100 * GiB,
largestRelationBytes: null,
largestRelationName: null,
+ totalBytesOnDataFs: 100 * GiB,
}),
],
});
@@ -330,12 +330,12 @@ test("diskHeadroomRows returns one row per entry", () => {
...baseInputs,
diskHeadroom: [
makeEntry({ freeBytesOnDataFs: 20 * GiB, mountLabel: "data" }),
- makeEntry({ path: "/var/lib/postgresql/data", freeBytesOnDataFs: 8 * GiB, mountLabel: "postgres" }),
+ makeEntry({ freeBytesOnDataFs: 8 * GiB, mountLabel: "postgres", path: "/var/lib/postgresql/data" }),
],
});
assert.equal(rows.length, 2);
- const dataRow = rows[0];
- const postgresRow = rows[1];
+ const [dataRow] = rows;
+ const [, postgresRow] = rows;
assert.ok(dataRow);
assert.ok(postgresRow);
assert.match(dataRow.check, /data/);
@@ -356,10 +356,10 @@ test("diskHeadroomRows: unmeasured postgres entry shows info, not a false green"
diskHeadroom: [
makeEntry({ freeBytesOnDataFs: 20 * GiB, mountLabel: "data" }),
makeEntry({
- path: "/var/lib/postgresql/data",
freeBytesOnDataFs: null,
- totalBytesOnDataFs: null,
mountLabel: "postgres",
+ path: "/var/lib/postgresql/data",
+ totalBytesOnDataFs: null,
}),
],
});
diff --git a/apps/console/src/app/(console)/components/deployment-readiness-rows.ts b/apps/console/src/app/(console)/components/deployment-readiness-rows.ts
index fdd679223..463fb32d6 100644
--- a/apps/console/src/app/(console)/components/deployment-readiness-rows.ts
+++ b/apps/console/src/app/(console)/components/deployment-readiness-rows.ts
@@ -68,23 +68,23 @@ export function extractReadinessInputs(report: DeploymentDiagnostics): ServerInp
const largestRelation = report.database.top_relations?.[0] ?? null;
const dhEntries = report.disk_headroom ?? [];
return {
- ownerPasswordProvenance: owner?.provenance ?? "absent",
- referenceOriginConfigured: origin?.provenance === "present" ? origin.value : null,
- embeddingBackendConfigured: report.semantic.backend.configured,
- embeddingBackendAvailable: report.semantic.backend.available,
- embeddingModelCachePresent: report.semantic.backend.model_cache_present,
- embeddingDownloadAllowed: report.semantic.backend.download_allowed,
- vectorIndexKind: report.semantic.index.kind,
- vectorIndexState: report.semantic.index.state,
databasePath: report.database.path,
diskHeadroom: dhEntries.map((dh) => ({
- path: dh.path,
freeBytesOnDataFs: dh.free_bytes,
- totalBytesOnDataFs: dh.total_bytes,
- mountLabel: dh.mount_label ?? null,
largestRelationBytes: largestRelation?.bytes ?? null,
largestRelationName: largestRelation?.name ?? null,
+ mountLabel: dh.mount_label ?? null,
+ path: dh.path,
+ totalBytesOnDataFs: dh.total_bytes,
})),
+ embeddingBackendAvailable: report.semantic.backend.available,
+ embeddingBackendConfigured: report.semantic.backend.configured,
+ embeddingDownloadAllowed: report.semantic.backend.download_allowed,
+ embeddingModelCachePresent: report.semantic.backend.model_cache_present,
+ ownerPasswordProvenance: owner?.provenance ?? "absent",
+ referenceOriginConfigured: origin?.provenance === "present" ? origin.value : null,
+ vectorIndexKind: report.semantic.index.kind,
+ vectorIndexState: report.semantic.index.state,
};
}
@@ -92,15 +92,15 @@ export function ownerPasswordRow(inputs: ServerInputs): ReadinessRow {
if (inputs.ownerPasswordProvenance === "redacted") {
return {
check: "Owner password gate",
- status: "ok",
detail: "PDPP_OWNER_PASSWORD is set; owner surfaces require sign-in.",
+ status: "ok",
};
}
return {
check: "Owner password gate",
- status: "error",
detail: "PDPP_OWNER_PASSWORD is not set.",
hint: "Set `PDPP_OWNER_PASSWORD` in your env and restart; otherwise `/owner`, `/device`, `/consent`, and `/` are reachable without auth.",
+ status: "error",
};
}
@@ -108,17 +108,17 @@ export function referenceOriginRow(inputs: ServerInputs, browserOrigin: string |
if (!inputs.referenceOriginConfigured) {
return {
check: "Reference origin alignment",
- status: "warn",
detail:
"PDPP_REFERENCE_ORIGIN is not set. The deployment will infer the origin from request headers, which is brittle behind proxies.",
hint: "Set `PDPP_REFERENCE_ORIGIN` to the URL you are visiting (e.g. `https://-3002.proxy.runpod.net`). Mismatches break the MCP and OAuth callback flows.",
+ status: "warn",
};
}
if (browserOrigin === null) {
return {
check: "Reference origin alignment",
- status: "unknown",
detail: `PDPP_REFERENCE_ORIGIN=${inputs.referenceOriginConfigured}. Browser origin not yet observed.`,
+ status: "unknown",
};
}
const configured = stripTrailingSlash(inputs.referenceOriginConfigured);
@@ -126,15 +126,15 @@ export function referenceOriginRow(inputs: ServerInputs, browserOrigin: string |
if (configured === observed) {
return {
check: "Reference origin alignment",
- status: "ok",
detail: `Configured origin matches the browser origin (${observed}).`,
+ status: "ok",
};
}
return {
check: "Reference origin alignment",
- status: "warn",
detail: `PDPP_REFERENCE_ORIGIN=${configured}; you are viewing this dashboard from ${observed}.`,
hint: "Set `PDPP_REFERENCE_ORIGIN` to the URL you are visiting (e.g. `https://-3002.proxy.runpod.net`). Mismatches break the MCP and OAuth callback flows.",
+ status: "warn",
};
}
@@ -142,29 +142,29 @@ export function storageBackendRow(inputs: ServerInputs): ReadinessRow {
if (inputs.vectorIndexKind === null && inputs.vectorIndexState === null) {
return {
check: "Storage backend",
- status: "info",
detail: `Database at ${inputs.databasePath}. No vector index configured yet.`,
+ status: "info",
};
}
if (inputs.vectorIndexState === "stale") {
return {
check: "Storage backend",
- status: "warn",
detail: `Database at ${inputs.databasePath}; vector index (${inputs.vectorIndexKind ?? "unknown"}) is stale.`,
hint: "Storage backend reports unhealthy. See `docs/operator/selfhost-quickstart.md` for storage layout.",
+ status: "warn",
};
}
if (inputs.vectorIndexState === "building") {
return {
check: "Storage backend",
- status: "info",
detail: `Database at ${inputs.databasePath}; vector index (${inputs.vectorIndexKind ?? "unknown"}) is still building.`,
+ status: "info",
};
}
return {
check: "Storage backend",
- status: "ok",
detail: `Database at ${inputs.databasePath}; vector index (${inputs.vectorIndexKind ?? "n/a"}) is built.`,
+ status: "ok",
};
}
@@ -172,30 +172,30 @@ export function embeddingCacheRow(inputs: ServerInputs): ReadinessRow {
if (!inputs.embeddingBackendConfigured) {
return {
check: "Embedding cache",
- status: "info",
detail: "No semantic embedding backend configured. Lexical retrieval still works.",
+ status: "info",
};
}
if (inputs.embeddingModelCachePresent === true && inputs.embeddingBackendAvailable) {
return {
check: "Embedding cache",
- status: "ok",
detail: "Embedding model is cached and the backend is available.",
+ status: "ok",
};
}
if (inputs.embeddingModelCachePresent === false && inputs.embeddingDownloadAllowed === false) {
return {
check: "Embedding cache",
- status: "error",
detail: "Embedding model is not cached and download is disabled.",
hint: "Embedding cache is still downloading or missing. Wait for first-boot download to finish, or set `PDPP_EMBEDDING_DOWNLOAD_ALLOWED=0` if you do not need semantic search yet.",
+ status: "error",
};
}
return {
check: "Embedding cache",
- status: "warn",
detail: "Embedding model cache is still warming up or the backend is not yet ready.",
hint: "Embedding cache is still downloading or missing. Wait for first-boot download to finish, or set `PDPP_EMBEDDING_DOWNLOAD_ALLOWED=0` if you do not need semantic search yet.",
+ status: "warn",
};
}
@@ -203,30 +203,30 @@ export function refreshTokenRow(probe: RefreshTokenProbe): ReadinessRow {
if (probe.state === "loading") {
return {
check: "MCP refresh-token advertisement",
- status: "unknown",
detail: "Checking the authorization-server metadata…",
+ status: "unknown",
};
}
if (probe.state === "unreachable") {
return {
check: "MCP refresh-token advertisement",
- status: "warn",
detail: "Could not reach `/.well-known/oauth-authorization-server` from this origin.",
hint: "If your `AS_ISSUER` is not co-located with the dashboard origin, this check may show `warn` even on a healthy deployment. Confirm `grant_types_supported` includes `refresh_token` on your AS metadata directly.",
+ status: "warn",
};
}
if (probe.refreshTokenSupported) {
return {
check: "MCP refresh-token advertisement",
- status: "ok",
detail: "Authorization-server metadata advertises `refresh_token`.",
+ status: "ok",
};
}
return {
check: "MCP refresh-token advertisement",
- status: "error",
detail: "Authorization-server metadata does not advertise `refresh_token`.",
hint: "Reference image is too old to advertise `refresh_token`. `docker compose pull` to the current image.",
+ status: "error",
};
}
@@ -266,8 +266,8 @@ function diskHeadroomEntryRow(dh: DiskHeadroomInputs): ReadinessRow {
if (dh.freeBytesOnDataFs === null) {
return {
check: checkLabel,
- status: "info",
detail: `Disk headroom could not be measured${dh.path ? ` on ${dh.path}` : ""}.`,
+ status: "info",
};
}
const free = dh.freeBytesOnDataFs;
@@ -275,23 +275,23 @@ function diskHeadroomEntryRow(dh: DiskHeadroomInputs): ReadinessRow {
if (free < DISK_ERROR_BYTES) {
return {
check: checkLabel,
- status: "error",
detail: `Only ${formatBytes(free)} free${pathLabel}. A restart or image build will very likely fail with "No space left on device".${workloadSuffix(dh, free)}`,
hint: "Run `docker builder prune` or `docker system prune` to reclaim build cache and stopped containers. Inspect Docker volumes manually before removing any volume data.",
+ status: "error",
};
}
if (free < DISK_WARN_BYTES) {
return {
check: checkLabel,
- status: "warn",
detail: `${formatBytes(free)} free${pathLabel}. Disk space is running low.${workloadSuffix(dh, free)}`,
hint: "Consider running `docker system prune` to reclaim build cache before the next restart.",
+ status: "warn",
};
}
return {
check: checkLabel,
- status: "ok",
detail: `${formatBytes(free)} free${pathLabel}.`,
+ status: "ok",
};
}
@@ -303,8 +303,8 @@ export function diskHeadroomRows(inputs: ServerInputs): ReadinessRow[] {
return [
{
check: "Disk headroom",
- status: "info",
detail: "Disk headroom could not be measured on this filesystem.",
+ status: "info",
},
];
}
@@ -318,18 +318,18 @@ export function diskHeadroomRow(inputs: ServerInputs): ReadinessRow {
if (inputs.diskHeadroom.length === 0) {
return {
check: "Disk headroom",
- status: "info",
detail: "Disk headroom could not be measured on this filesystem.",
+ status: "info",
};
}
- const first = inputs.diskHeadroom[0];
+ const [first] = inputs.diskHeadroom;
// Guarded by the length check above; TypeScript sees index access as possibly
// undefined when noUncheckedIndexedAccess is set.
if (!first) {
return {
check: "Disk headroom",
- status: "info",
detail: "Disk headroom could not be measured on this filesystem.",
+ status: "info",
};
}
return diskHeadroomEntryRow(first);
diff --git a/apps/console/src/app/(console)/components/record-inspector.tsx b/apps/console/src/app/(console)/components/record-inspector.tsx
index c76ce825d..379fddea7 100644
--- a/apps/console/src/app/(console)/components/record-inspector.tsx
+++ b/apps/console/src/app/(console)/components/record-inspector.tsx
@@ -80,7 +80,6 @@ function BlobAffordanceView({
return (
{isImage ? (
- // biome-ignore lint/performance/noImgElement: blob fetch_url is a grant-scoped RS URL, not a static asset Next can optimize.
// biome-ignore lint/correctness/useImageSize: a remote record blob has no known intrinsic dimensions; the CSS box constrains it.

) : null}
@@ -131,8 +130,11 @@ export function RecordInspector({ record, relationships, streamRecordsHref }: Re
const totalDeclared = record.fields.length;
const blob = blobAffordance(record);
const blobMime = blob ? declaredBlobMime(body, blob.fieldName) : undefined;
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
const relatedLinks = relationships?.relatedLinks ?? [];
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
const parentBackLinks = relationships?.parentBackLinks ?? [];
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
const reverseChildListLinks = relationships?.reverseChildListLinks ?? [];
const hasRelationships = relatedLinks.length > 0 || parentBackLinks.length > 0 || reverseChildListLinks.length > 0;
diff --git a/apps/console/src/app/(console)/components/route-loading.invariants.test.ts b/apps/console/src/app/(console)/components/route-loading.invariants.test.ts
index 384955c73..f2cd67ce7 100644
--- a/apps/console/src/app/(console)/components/route-loading.invariants.test.ts
+++ b/apps/console/src/app/(console)/components/route-loading.invariants.test.ts
@@ -64,11 +64,13 @@ test("every high-value sources/runs surface ships a route-level loading.tsx", ()
});
test("each loading.tsx renders inside the shared DashboardShell for stable chrome", async () => {
- for (const rel of LOADING_FILES) {
- const src = await readFile(`${DASHBOARD}${rel}`, "utf8");
- assert.match(src, DASHBOARD_SHELL_RE, `${rel} must reuse DashboardShell`);
- assert.match(src, SHARED_SKELETON_IMPORT_RE, `${rel} must use the shared skeleton`);
- }
+ await Promise.all(
+ LOADING_FILES.map(async (rel) => {
+ const src = await readFile(`${DASHBOARD}${rel}`, "utf8");
+ assert.match(src, DASHBOARD_SHELL_RE, `${rel} must reuse DashboardShell`);
+ assert.match(src, SHARED_SKELETON_IMPORT_RE, `${rel} must use the shared skeleton`);
+ })
+ );
});
test("the shared skeleton is lightweight and accessible", async () => {
diff --git a/apps/console/src/app/(console)/components/segment-error.tsx b/apps/console/src/app/(console)/components/segment-error.tsx
index bb290fbc1..73ec0ede5 100644
--- a/apps/console/src/app/(console)/components/segment-error.tsx
+++ b/apps/console/src/app/(console)/components/segment-error.tsx
@@ -54,10 +54,11 @@ export function SegmentError({
{title}
{description}
-
diff --git a/apps/console/src/app/(console)/components/shell.tsx b/apps/console/src/app/(console)/components/shell.tsx
index 00bbbfa65..b5f8f2e56 100644
--- a/apps/console/src/app/(console)/components/shell.tsx
+++ b/apps/console/src/app/(console)/components/shell.tsx
@@ -6,7 +6,7 @@ import { MobileDrawer, MobileDrawerProvider, MobileDrawerTrigger } from "@pdpp/o
import { dashboardRoutes, type Routes, sandboxRoutes } from "@pdpp/operator-ui/components/views/routes";
import Link from "next/link";
import { cache, type ReactNode } from "react";
-import DensityToggle from "@/components/density/density-toggle.tsx";
+import { DensityToggle } from "@/components/density/density-toggle.tsx";
import { PdppLogo } from "@/components/pdpp-logo.tsx";
import { ThemeToggle } from "@/components/theme/theme-toggle.tsx";
import { getAsInternalUrl, getOwnerLoginPath, getReferencePublicOrigin, getRsInternalUrl } from "../lib/owner-token.ts";
diff --git a/apps/console/src/app/(console)/components/source-setup-catalog.tsx b/apps/console/src/app/(console)/components/source-setup-catalog.tsx
index e58f7079a..64ba80c6e 100644
--- a/apps/console/src/app/(console)/components/source-setup-catalog.tsx
+++ b/apps/console/src/app/(console)/components/source-setup-catalog.tsx
@@ -14,7 +14,7 @@ import {
sourceSetupSecondaryAction,
sourceSetupStatus,
} from "../lib/source-setup-presentation.ts";
-import { formatTotalRecordsLabel } from "../sources/sources-view-model.ts";
+import { formatTotalRecordsLabel } from "../lib/total-records.ts";
export interface ExistingSourceSetupLink {
connectionId: string;
@@ -186,13 +186,13 @@ function ExistingSourceLinks({
Open in Explore
Source details
@@ -263,11 +263,11 @@ function SourceSetupCard({
{action ? (
<>
Next
-
+
{action.label}
{secondaryAction ? (
-
+
{secondaryAction.label}
) : null}
@@ -305,7 +305,7 @@ function ServerSetupSummary({ entries }: { entries: readonly ConnectorCatalogEnt
{entry.displayName}
{sourceMethodLine(entry, 0)}
-
+
Open server settings
diff --git a/apps/console/src/app/(console)/components/views/standing-demo-data.ts b/apps/console/src/app/(console)/components/views/standing-demo-data.ts
index c4d5142e6..38de770d2 100644
--- a/apps/console/src/app/(console)/components/views/standing-demo-data.ts
+++ b/apps/console/src/app/(console)/components/views/standing-demo-data.ts
@@ -32,169 +32,169 @@ function iso(daysAgo: number): string {
}
const BEARERS: OwnerIssuedClient[] = [
- { client_id: "cli_claude_desktop", client_name: "Claude Desktop", active_token_count: 1, created_at: iso(40) },
- { client_id: "cli_framework", client_name: "CLI on framework", active_token_count: 2, created_at: iso(120) },
+ { active_token_count: 1, client_id: "cli_claude_desktop", client_name: "Claude Desktop", created_at: iso(40) },
+ { active_token_count: 2, client_id: "cli_framework", client_name: "CLI on framework", created_at: iso(120) },
// Worst case: a real owner bearer with NO human name — the long machine
// client_id IS the identity and must truncate without breaking the row.
{
+ active_token_count: 1,
client_id: "single-use-proof-1781473829100-7f3a9c2e-b04d-4e51-9a2f-6c8e1d0b5a73",
client_name: null,
- active_token_count: 1,
created_at: iso(3),
},
// Named client whose machine id is a full OAuth client URL — name stays
// prominent, the long id rides beneath it, truncated.
{
+ active_token_count: 4,
client_id: "https://chatgpt.com/connector_platform_oauth_client/2f1a8b3c-9d4e-4f0a-8c7b-1e2d3f4a5b6c",
client_name: "ChatGPT",
- active_token_count: 4,
created_at: iso(7),
},
];
const GRANTS: GrantSummary[] = [
{
- object: "grant_summary",
- grant_id: "grant_atlas",
client_id: "Atlas Mortgage",
connector_id: "plaid",
- status: "active",
- first_at: iso(30),
- last_at: iso(0),
event_count: 12,
- kinds: ["pay_statements", "transactions"],
failure: null,
+ first_at: iso(30),
+ grant_id: "grant_atlas",
+ kinds: ["pay_statements", "transactions"],
+ last_at: iso(0),
+ object: "grant_summary",
+ status: "active",
},
{
- object: "grant_summary",
- grant_id: "grant_northstar",
client_id: "Northstar HR",
connector_id: "employment",
- status: "issued",
- first_at: iso(14),
- last_at: iso(2),
event_count: 4,
- kinds: ["employment"],
failure: null,
+ first_at: iso(14),
+ grant_id: "grant_northstar",
+ kinds: ["employment"],
+ last_at: iso(2),
+ object: "grant_summary",
+ status: "issued",
},
];
const TRACES: TraceSummary[] = [
{
- object: "trace_summary",
- trace_id: "trace_1",
- status: "succeeded",
actor_id: "Claude Desktop",
actor_type: "client",
client_id: "Claude Desktop",
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: iso(0),
- last_at: iso(0),
event_count: 412,
- kinds: ["transactions"],
failure: null,
- },
- {
+ first_at: iso(0),
+ grant_id: null,
+ kinds: ["transactions"],
+ last_at: iso(0),
object: "trace_summary",
- trace_id: "trace_2",
+ request_id: null,
+ run_id: null,
status: "succeeded",
+ trace_id: "trace_1",
+ },
+ {
actor_id: "Atlas Mortgage",
actor_type: "client",
client_id: "Atlas Mortgage",
- grant_id: "grant_atlas",
- run_id: null,
- request_id: null,
- first_at: iso(1),
- last_at: iso(1),
event_count: 38,
- kinds: ["pay_statements"],
failure: null,
+ first_at: iso(1),
+ grant_id: "grant_atlas",
+ kinds: ["pay_statements"],
+ last_at: iso(1),
+ object: "trace_summary",
+ request_id: null,
+ run_id: null,
+ status: "succeeded",
+ trace_id: "trace_2",
},
{
- object: "trace_summary",
- trace_id: "trace_3",
- status: "denied",
actor_id: "Unknown app",
actor_type: "client",
client_id: "Unknown app",
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: iso(2),
- last_at: iso(2),
event_count: 0,
- kinds: ["browsing"],
failure: { event_type: "trace.denied", reason: "scope not granted" },
+ first_at: iso(2),
+ grant_id: null,
+ kinds: ["browsing"],
+ last_at: iso(2),
+ object: "trace_summary",
+ request_id: null,
+ run_id: null,
+ status: "denied",
+ trace_id: "trace_3",
},
];
const FAILED_RUNS: RunSummary[] = [
{
- object: "run_summary",
- run_id: "run_meridian",
- status: "failed",
connector_id: "current_activity",
- grant_id: null,
- provider_id: null,
- first_at: iso(2),
- last_at: iso(2),
event_count: 3,
+ failure_reason: "First Meridian's connection expired. Reconnect to resume syncing.",
+ first_at: iso(2),
+ grant_id: null,
kinds: ["run.failed"],
+ last_at: iso(2),
needs_input: false,
- failure_reason: "First Meridian's connection expired. Reconnect to resume syncing.",
+ object: "run_summary",
+ provider_id: null,
+ run_id: "run_meridian",
+ status: "failed",
},
];
const PENDING: PendingApproval[] = [
{
- object: "approval",
approval_id: "appr_atlas",
client_id: "Atlas Mortgage",
created_at: iso(0),
- kind: "consent",
- user_code: "WXYZ-1234",
grant_preview: {
source: null,
streams: [{ name: "pay_statements" }, { name: "employment" }, { name: "transactions" }],
},
+ kind: "consent",
+ object: "approval",
+ user_code: "WXYZ-1234",
},
];
const SUMMARY = {
- object: "dataset_summary" as const,
- record_count: 48_120,
- connector_count: 10,
- stream_count: 24,
- total_retained_bytes: 1_073_741_824,
blob_bytes: 0,
- record_json_bytes: 0,
- record_changes_json_bytes: 0,
- earliest_record_time: iso(365),
- latest_record_time: iso(0),
+ connector_count: 10,
earliest_ingested_at: iso(365),
+ earliest_record_time: iso(365),
latest_ingested_at: iso(0),
+ latest_record_time: iso(0),
+ object: "dataset_summary" as const,
+ projection: { computed_at: iso(0), state: "fresh" as const },
+ record_changes_json_bytes: 0,
+ record_count: 48_120,
+ record_json_bytes: 0,
+ stream_count: 24,
top_connectors: [],
- projection: { state: "fresh" as const, computed_at: iso(0) },
+ total_retained_bytes: 1_073_741_824,
};
export function buildDemoInputs(scenario: DemoScenario, hrefs: StandingHrefs): StandingInputs {
const base: StandingInputs = {
- now: NOW,
- hrefs,
- summary: SUMMARY,
- bearerClients: BEARERS,
- grants: GRANTS,
- traces: TRACES,
- pendingApprovals: [],
- failedTraces: [],
- failedRuns: [],
- sourceWork: EMPTY_SOURCE_WORK_GROUPS,
advisoryOwnerActions: [],
attentionConnections: [],
+ bearerClients: BEARERS,
+ failedRuns: [],
+ failedTraces: [],
+ grants: GRANTS,
+ hrefs,
+ now: NOW,
overviewLoadIssues: [],
+ pendingApprovals: [],
sourceIssues: [],
+ sourceWork: EMPTY_SOURCE_WORK_GROUPS,
+ summary: SUMMARY,
+ traces: TRACES,
};
if (scenario === "decide") {
return { ...base, pendingApprovals: PENDING };
@@ -202,17 +202,17 @@ export function buildDemoInputs(scenario: DemoScenario, hrefs: StandingHrefs): S
if (scenario === "alarm") {
return {
...base,
- failedRuns: FAILED_RUNS,
attentionConnections: [
{
+ actionLabel: "Check the collector",
connectorKey: "claude-code",
- routeId: "cin_demo_claude_code",
deviceLocal: true,
label: "Claude Code on workstation",
+ routeId: "cin_demo_claude_code",
what: "Check the collector before this source can make progress.",
- actionLabel: "Check the collector",
},
],
+ failedRuns: FAILED_RUNS,
};
}
return base;
diff --git a/apps/console/src/app/(console)/components/views/standing-view-model.test.ts b/apps/console/src/app/(console)/components/views/standing-view-model.test.ts
index d2e4b71a5..6e8e00198 100644
--- a/apps/console/src/app/(console)/components/views/standing-view-model.test.ts
+++ b/apps/console/src/app/(console)/components/views/standing-view-model.test.ts
@@ -33,18 +33,18 @@ import {
} from "./standing-view-model.ts";
const HREFS: StandingHrefs = {
- grants: "/grants",
- grantPackages: "/grants/packages",
- notifications: "/notifications",
- runs: "/syncs",
- sources: "/sources",
- traces: "/audit",
+ connection: (id) => `/sources/${id}`,
deployment: "/deployment",
deploymentTokens: "/deployment/tokens",
- connection: (id) => `/sources/${id}`,
grant: (id) => `/grants/${id}`,
+ grantPackages: "/grants/packages",
+ grants: "/grants",
+ notifications: "/notifications",
run: (id) => `/syncs/${id}`,
+ runs: "/syncs",
+ sources: "/sources",
trace: (id) => `/audit/${id}`,
+ traces: "/audit",
};
const NOW = new Date("2026-06-13T12:00:00Z");
@@ -78,35 +78,35 @@ const WILL_NOT_CLAIM_ALL_CLEAR_RE = /will not claim all-clear from partial data/
function baseInputs(over: Partial = {}): StandingInputs {
return {
- now: NOW,
+ advisoryOwnerActions: [],
+ attentionConnections: [],
+ bearerClients: [],
+ failedRuns: [],
+ failedTraces: [],
+ grants: [],
hrefs: HREFS,
+ now: NOW,
+ overviewLoadIssues: [],
+ pendingApprovals: [],
+ sourceIssues: [],
+ sourceWork: EMPTY_SOURCE_WORK_GROUPS,
summary: {
- object: "dataset_summary",
- record_count: 48_120,
- connector_count: 10,
- stream_count: 24,
- total_retained_bytes: 0,
blob_bytes: 0,
- record_json_bytes: 0,
- record_changes_json_bytes: 0,
- earliest_record_time: null,
- latest_record_time: null,
+ connector_count: 10,
earliest_ingested_at: null,
+ earliest_record_time: null,
latest_ingested_at: null,
- top_connectors: [],
+ latest_record_time: null,
+ object: "dataset_summary",
projection: { state: "fresh" },
+ record_changes_json_bytes: 0,
+ record_count: 48_120,
+ record_json_bytes: 0,
+ stream_count: 24,
+ top_connectors: [],
+ total_retained_bytes: 0,
},
- bearerClients: [],
- grants: [],
traces: [],
- pendingApprovals: [],
- failedTraces: [],
- failedRuns: [],
- sourceWork: EMPTY_SOURCE_WORK_GROUPS,
- advisoryOwnerActions: [],
- attentionConnections: [],
- overviewLoadIssues: [],
- sourceIssues: [],
...over,
};
}
@@ -141,18 +141,18 @@ test("grantEndorseStatus collapses the live vocab to active", () => {
});
test("grantReads humanizes kinds, falls back to connector, then generic", () => {
- const withKinds = { kinds: ["pay_statements", "transactions"], connector_id: "plaid" } as GrantSummary;
+ const withKinds = { connector_id: "plaid", kinds: ["pay_statements", "transactions"] } as GrantSummary;
assert.equal(grantReads(withKinds), "reads only your pay and your spending");
- const onlyConnector = { kinds: ["read"], connector_id: "employment" } as GrantSummary;
+ const onlyConnector = { connector_id: "employment", kinds: ["read"] } as GrantSummary;
assert.equal(grantReads(onlyConnector), "reads only your employment history");
- const nothing = { kinds: [], connector_id: null } as unknown as GrantSummary;
+ const nothing = { connector_id: null, kinds: [] } as unknown as GrantSummary;
assert.equal(grantReads(nothing), "reads a scoped slice of your data");
});
test("grantReads humanizes protocol audit stream names instead of raw event ids", () => {
const auditGrant = {
- kinds: ["consent.approved", "token.issued", "query.received", "disclosure.served", "query.rejected"],
connector_id: "pdpp",
+ kinds: ["consent.approved", "token.issued", "query.received", "disclosure.served", "query.rejected"],
} as GrantSummary;
assert.equal(
@@ -175,12 +175,12 @@ test("relDay produces calm relative labels", () => {
test("hero is DECIDE when an approval is pending", () => {
const pending: PendingApproval = {
- object: "approval",
approval_id: "a1",
client_id: "Atlas Mortgage",
created_at: NOW.toISOString(),
- kind: "consent",
grant_preview: { streams: [{ name: "pay_statements" }, { name: "transactions" }] },
+ kind: "consent",
+ object: "approval",
};
const hero = computeHero(baseInputs({ pendingApprovals: [pending] }));
assert.equal(hero.tone, "decide");
@@ -196,12 +196,12 @@ test("hero ALARM for a DEVICE-LOCAL recovery: CTA NAVIGATES (does not restate th
baseInputs({
attentionConnections: [
{
+ actionLabel: "Recover local collector uploads",
connectorKey: "claude-code",
- routeId: "ci_laptop",
deviceLocal: true,
label: "laptop Claude Code",
+ routeId: "ci_laptop",
what: "The local collector has saved records on its host that did not upload to this server.",
- actionLabel: "Recover local collector uploads",
},
],
})
@@ -224,12 +224,12 @@ test("hero ALARM for a DASHBOARD-ACTIONABLE recovery keeps its action verb", ()
baseInputs({
attentionConnections: [
{
+ actionLabel: "Reconnect",
connectorKey: "chase",
- routeId: "cin_chase",
deviceLocal: false,
label: "Chase - Personal",
+ routeId: "cin_chase",
what: "Reconnect Chase.",
- actionLabel: "Reconnect",
},
],
})
@@ -242,20 +242,20 @@ test("hero ALARM with several attention connections → CTA routes to the syncs
baseInputs({
attentionConnections: [
{
+ actionLabel: "Check the collector",
connectorKey: "claude-code",
- routeId: "ci_laptop",
deviceLocal: true,
label: "laptop Claude Code",
+ routeId: "ci_laptop",
what: "Check the collector.",
- actionLabel: "Check the collector",
},
{
+ actionLabel: "Reconnect",
connectorKey: "chase",
- routeId: "cin_chase",
deviceLocal: false,
label: "Chase - Personal",
+ routeId: "cin_chase",
what: "Reconnect Chase.",
- actionLabel: "Reconnect",
},
],
})
@@ -268,29 +268,29 @@ test("hero ALARM with several attention connections → CTA routes to the syncs
test("failed syncs/traces alone do NOT drive the alarm — only the rendered-verdict attention set does", () => {
// The old bug: a failed YNAB trace inflated the alarm while YNAB was healthy.
- const run = { run_id: "r1", connector_id: "current_activity", failure_reason: "expired" } as RunSummary;
- const trace = { trace_id: "t1", client_id: "ynab" } as TraceSummary;
- const hero = computeHero(baseInputs({ failedRuns: [run], failedTraces: [trace], attentionConnections: [] }));
+ const run = { connector_id: "current_activity", failure_reason: "expired", run_id: "r1" } as RunSummary;
+ const trace = { client_id: "ynab", trace_id: "t1" } as TraceSummary;
+ const hero = computeHero(baseInputs({ attentionConnections: [], failedRuns: [run], failedTraces: [trace] }));
assert.notEqual(hero.tone, "alarm");
});
test("decide wins over alarm", () => {
const pending = {
- object: "approval",
approval_id: "a1",
created_at: NOW.toISOString(),
kind: "consent",
+ object: "approval",
} as PendingApproval;
const both = computeHero(
baseInputs({
attentionConnections: [
{
+ actionLabel: "Reconnect",
connectorKey: "chase",
- routeId: "cin_chase",
deviceLocal: false,
label: "Chase - Personal",
+ routeId: "cin_chase",
what: "x",
- actionLabel: "Reconnect",
},
],
pendingApprovals: [pending],
@@ -343,18 +343,17 @@ function verdict(
over: Partial>
): RefConnectorSummary["rendered_verdict"] {
return {
+ annotations: [],
channel: "attention",
- pill: { label: "Can't collect", tone: "red" },
+ detail: undefined,
forward_statement: "Check the collector before this source can make progress.",
+ pill: { label: "Can't collect", tone: "red" },
required_actions: [
{
affects: [],
audience: "owner",
cta: "Check the collector",
kind: "add_info",
- satisfied_when: { kind: "attention_resolved" },
- terminal: false,
- urgency: "now",
remediation: {
cause: "dead_letter_backlog",
commands: [],
@@ -363,17 +362,18 @@ function verdict(
summary: "The local collector has saved records on its host that did not upload to this server.",
target: { identity_source: "source_instance_bindings", kind: "local_device" },
},
+ satisfied_when: { kind: "attention_resolved" },
+ terminal: false,
+ urgency: "now",
},
],
- annotations: [],
- detail: undefined,
...over,
} as RefConnectorSummary["rendered_verdict"];
}
test("attention truth: only attention-channel connections with an owner-satisfiable action count", () => {
const connectors: RefConnectorSummary[] = [
- connector({ connector_id: "claude-code", connection_id: "cin_laptop", rendered_verdict: verdict({}) }), // ✓ attention + owner action
+ connector({ connection_id: "cin_laptop", connector_id: "claude-code", rendered_verdict: verdict({}) }), // ✓ attention + owner action
connector({ connector_id: "calm-source", rendered_verdict: verdict({ channel: "calm" }) }), // ✗ calm
connector({ connector_id: "ynab", rendered_verdict: null }), // ✗ no verdict (e.g. healthy)
connector({
@@ -392,7 +392,7 @@ test("attention truth: only attention-channel connections with an owner-satisfia
],
}),
}), // ✗ attention but no owner-satisfiable action (S1 — code_fix is the maintainer's, not the owner's)
- connector({ connector_id: "revoked", revoked_at: "2026-06-01T00:00:00Z", rendered_verdict: verdict({}) }), // ✗ revoked
+ connector({ connector_id: "revoked", rendered_verdict: verdict({}), revoked_at: "2026-06-01T00:00:00Z" }), // ✗ revoked
];
const attention = attentionConnectionsFromConnectors(connectors);
assert.deepEqual(
@@ -409,9 +409,9 @@ test("attention truth: only attention-channel connections with an owner-satisfia
test("attention truth falls back to legacy blocked health when rendered verdict is absent", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "chase",
- connection_id: "cin_chase",
connection_health: legacyHealth("blocked"),
+ connection_id: "cin_chase",
+ connector_id: "chase",
display_name: "Chase",
rendered_verdict: null,
}),
@@ -430,13 +430,13 @@ test("attention truth falls back to legacy blocked health when rendered verdict
test("source issues show non-owner material verdicts without alarming as owner attention", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "chase",
connection_id: "cin_chase",
+ connector_id: "chase",
display_name: "Chase",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Can't collect", tone: "red" },
forward_statement: "This connector needs a code fix before it can collect again.",
+ pill: { label: "Can't collect", tone: "red" },
required_actions: [
{
affects: [],
@@ -456,8 +456,8 @@ test("source issues show non-owner material verdicts without alarming as owner a
}),
connector({
connector_id: "revoked",
- revoked_at: "2026-06-01T00:00:00Z",
rendered_verdict: verdict({ pill: { label: "Can't collect", tone: "red" } }),
+ revoked_at: "2026-06-01T00:00:00Z",
}),
];
@@ -479,13 +479,13 @@ test("source issues show non-owner material verdicts without alarming as owner a
test("advisory owner actions surface non-urgent Amazon retry work without calm all-clear copy", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "amazon",
connection_id: "cin_amazon",
+ connector_id: "amazon",
display_name: "Amazon - Personal",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Degraded", tone: "amber" },
forward_statement: "Some order detail is still outstanding. Retry this source to collect the missing detail.",
+ pill: { label: "Degraded", tone: "amber" },
required_actions: [
{
affects: ["orders"],
@@ -525,13 +525,13 @@ test("advisory owner actions surface non-urgent Amazon retry work without calm a
test("advisory owner actions surface Reddit refresh work in the home summary", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "reddit",
connection_id: "cin_reddit",
+ connector_id: "reddit",
display_name: "Reddit",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Healthy", tone: "green" },
forward_statement: "Run a refresh when you want the latest saved posts.",
+ pill: { label: "Healthy", tone: "green" },
required_actions: [
{
affects: [],
@@ -558,13 +558,13 @@ test("advisory owner actions surface Reddit refresh work in the home summary", (
test("source actionability groups live-shaped rows with scoped counts", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "chatgpt",
connection_id: "cin_chatgpt",
+ connector_id: "chatgpt",
display_name: "ChatGPT - personal",
rendered_verdict: verdict({
channel: "attention",
- pill: { label: "Can't collect", tone: "red" },
forward_statement: "Reconnect this account and collection resumes.",
+ pill: { label: "Can't collect", tone: "red" },
required_actions: [
{
affects: [],
@@ -579,13 +579,13 @@ test("source actionability groups live-shaped rows with scoped counts", () => {
}),
}),
connector({
- connector_id: "usaa",
connection_id: "cin_usaa",
+ connector_id: "usaa",
display_name: "USAA - Personal",
rendered_verdict: verdict({
channel: "attention",
- pill: { label: "Can't collect", tone: "red" },
forward_statement: "Reconnect this account and collection resumes.",
+ pill: { label: "Can't collect", tone: "red" },
required_actions: [
{
affects: [],
@@ -600,19 +600,19 @@ test("source actionability groups live-shaped rows with scoped counts", () => {
}),
}),
connector({
- connector_id: "claude-code",
connection_id: "cin_claude",
+ connector_id: "claude-code",
display_name: "Local Claude Code",
rendered_verdict: verdict({}),
}),
connector({
- connector_id: "amazon",
connection_id: "cin_amazon",
+ connector_id: "amazon",
display_name: "Amazon - Personal",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Degraded", tone: "amber" },
forward_statement: "Run a refresh to bring this up to date.",
+ pill: { label: "Degraded", tone: "amber" },
required_actions: [
{
affects: [],
@@ -627,13 +627,13 @@ test("source actionability groups live-shaped rows with scoped counts", () => {
}),
}),
connector({
- connector_id: "chase",
connection_id: "cin_chase",
+ connector_id: "chase",
display_name: "Chase - Personal",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Degraded", tone: "amber" },
forward_statement: "Latest collection completed with known coverage gaps.",
+ pill: { label: "Degraded", tone: "amber" },
required_actions: [
{
affects: [],
@@ -648,13 +648,13 @@ test("source actionability groups live-shaped rows with scoped counts", () => {
}),
}),
connector({
- connector_id: "github",
connection_id: "cin_github",
+ connector_id: "github",
display_name: "GitHub - Personal",
rendered_verdict: verdict({
channel: "calm",
- pill: { label: "Not measured", tone: "grey" },
forward_statement: "Coverage has not been measured yet.",
+ pill: { label: "Not measured", tone: "grey" },
required_actions: [],
}),
}),
@@ -694,8 +694,8 @@ const DASHBOARD_PASSIVE_RECOVERY_RE = /catching up|syncing details|safe to retry
function deferredRecoveryVerdict(): RefConnectorSummary["rendered_verdict"] {
return verdict({
channel: "calm",
- pill: { label: "Degraded", tone: "amber" },
forward_statement: "The next run is expected to fill the remaining data.",
+ pill: { label: "Degraded", tone: "amber" },
required_actions: [
{
affects: [],
@@ -732,13 +732,13 @@ function inactiveRecoveryHealth(): RefConnectorSummary["connection_health"] {
test("dashboard cross-surface: every source-work section count equals its rendered row count", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "chatgpt",
connection_id: "cin_chatgpt",
+ connector_id: "chatgpt",
display_name: "ChatGPT - personal",
rendered_verdict: verdict({
channel: "attention",
- pill: { label: "Can't collect", tone: "red" },
forward_statement: "Reconnect this account and collection resumes.",
+ pill: { label: "Can't collect", tone: "red" },
required_actions: [
{
affects: [],
@@ -753,21 +753,21 @@ test("dashboard cross-surface: every source-work section count equals its render
}),
}),
connector({
- connector_id: "amazon",
- connection_id: "cin_amazon",
- display_name: "Amazon - Personal",
// Durable, inactive recovery backlog → passive progress ("PDPP is working").
connection_health: inactiveRecoveryHealth(),
+ connection_id: "cin_amazon",
+ connector_id: "amazon",
+ display_name: "Amazon - Personal",
rendered_verdict: deferredRecoveryVerdict(),
}),
connector({
- connector_id: "reddit",
connection_id: "cin_reddit",
+ connector_id: "reddit",
display_name: "Reddit - Personal",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Degraded", tone: "amber" },
forward_statement: "Run a refresh to bring this up to date.",
+ pill: { label: "Degraded", tone: "amber" },
required_actions: [
{
affects: [],
@@ -782,13 +782,13 @@ test("dashboard cross-surface: every source-work section count equals its render
}),
}),
connector({
- connector_id: "chase",
connection_id: "cin_chase",
+ connector_id: "chase",
display_name: "Chase - Personal",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Can't collect", tone: "red" },
forward_statement: "Connector code needs a fix before this can collect again.",
+ pill: { label: "Can't collect", tone: "red" },
required_actions: [
{
affects: [],
@@ -831,10 +831,10 @@ test("dashboard cross-surface: every source-work section count equals its render
test("dashboard cross-surface: an inactive queued recovery row is passive progress, never a Checking or degraded row", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "amazon",
+ connection_health: inactiveRecoveryHealth(),
connection_id: "cin_amazon",
+ connector_id: "amazon",
display_name: "Amazon - Personal",
- connection_health: inactiveRecoveryHealth(),
rendered_verdict: deferredRecoveryVerdict(),
}),
];
@@ -850,7 +850,7 @@ test("dashboard cross-surface: an inactive queued recovery row is passive progre
const allRows = data.sourceWorkSections.flatMap((section) => section.rows);
assert.equal(allRows.length, 1);
- const row = allRows[0];
+ const [row] = allRows;
assert.ok(row);
assert.doesNotMatch(row.what, DASHBOARD_CHECKING_RE);
assert.match(`${row.what} ${row.why ?? ""}`, DASHBOARD_PASSIVE_RECOVERY_RE);
@@ -859,13 +859,13 @@ test("dashboard cross-surface: an inactive queued recovery row is passive progre
test("reviewable degraded source appears once rather than as review plus source issue", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "amazon",
connection_id: "cin_amazon",
+ connector_id: "amazon",
display_name: "Amazon - Personal",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Degraded", tone: "amber" },
forward_statement: "Retry now to give the recoverable gap another run.",
+ pill: { label: "Degraded", tone: "amber" },
required_actions: [
{
affects: [],
@@ -894,13 +894,13 @@ test("reviewable degraded source appears once rather than as review plus source
test("source actionability follows primary-action parity with push policy", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "mixed",
connection_id: "cin_mixed",
+ connector_id: "mixed",
display_name: "Mixed-action source",
rendered_verdict: verdict({
channel: "attention",
- pill: { label: "Can't collect", tone: "red" },
forward_statement: "Connector code needs a fix before this can collect again.",
+ pill: { label: "Can't collect", tone: "red" },
required_actions: [
{
affects: [],
@@ -935,13 +935,13 @@ test("source actionability follows primary-action parity with push policy", () =
test("maintainer-only actions are not advisory owner actions", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "maintainer-only",
connection_id: "cin_maintainer",
+ connector_id: "maintainer-only",
display_name: "Maintainer-only source",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Degraded", tone: "amber" },
forward_statement: "This source needs a connector code fix before it can make progress.",
+ pill: { label: "Degraded", tone: "amber" },
required_actions: [
{
affects: [],
@@ -965,13 +965,13 @@ test("maintainer-only actions are not advisory owner actions", () => {
test("source issues omit healthy advisory refresh hints", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "reddit",
connection_id: "cin_reddit",
+ connector_id: "reddit",
display_name: "Reddit - dondochaka",
rendered_verdict: verdict({
channel: "advisory",
- pill: { label: "Healthy", tone: "green" },
forward_statement: "Run a refresh to bring this up to date.",
+ pill: { label: "Healthy", tone: "green" },
required_actions: [
{
affects: [],
@@ -998,13 +998,13 @@ test("source issues omit healthy advisory refresh hints", () => {
test("source issues surface attention verdicts that have no owner action, even with a green pill", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "maintainer-only",
connection_id: "cin_maintainer",
+ connector_id: "maintainer-only",
display_name: "Maintainer-only source",
rendered_verdict: verdict({
channel: "attention",
- pill: { label: "Healthy", tone: "green" },
forward_statement: "This source needs a maintainer action before it can make progress.",
+ pill: { label: "Healthy", tone: "green" },
required_actions: [
{
affects: [],
@@ -1033,9 +1033,9 @@ test("source issues surface attention verdicts that have no owner action, even w
test("source issues fall back to legacy degraded health when rendered verdict is absent", () => {
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "usaa",
- connection_id: "cin_usaa",
connection_health: legacyHealth("degraded"),
+ connection_id: "cin_usaa",
+ connector_id: "usaa",
display_name: "USAA - Personal",
rendered_verdict: null,
}),
@@ -1064,13 +1064,13 @@ test("attention routeId targets the EXACT connection instance, not the connector
// the CTA lands on the connection that actually needs the owner.
const connectors: RefConnectorSummary[] = [
connector({
- connector_id: "claude-code",
connection_id: "cin_simon",
+ connector_id: "claude-code",
rendered_verdict: verdict({ channel: "calm" }),
}), // healthy, first
connector({
- connector_id: "claude-code",
connection_id: "cin_laptop",
+ connector_id: "claude-code",
connector_instance_id: "ci_laptop",
rendered_verdict: verdict({}),
}), // the attention one
@@ -1091,8 +1091,8 @@ test("hero ALARMs on a stale projection even with no failures", () => {
stale.summary = {
...stale.summary,
projection: {
- state: "stale",
last_error: "bulk write on unknown connection",
+ state: "stale",
},
} as StandingInputs["summary"];
const hero = computeHero(stale);
@@ -1113,8 +1113,8 @@ test("hero uses owner-safe copy for failed projection details", () => {
failed.summary = {
...failed.summary,
projection: {
- state: "failed",
last_error: "SQL failed: bulk write on unknown connection",
+ state: "failed",
},
} as StandingInputs["summary"];
const hero = computeHero(failed);
@@ -1146,7 +1146,7 @@ test("hero ALARMs when dashboard inputs fail instead of claiming all-clear from
test("hero is CALM with reassurance when all is well", () => {
const clients: OwnerIssuedClient[] = [
- { client_id: "c1", client_name: "Claude Desktop", active_token_count: 1, created_at: NOW.toISOString() },
+ { active_token_count: 1, client_id: "c1", client_name: "Claude Desktop", created_at: NOW.toISOString() },
];
const hero = computeHero(baseInputs({ bearerClients: clients }));
assert.equal(hero.tone, "calm");
@@ -1156,8 +1156,8 @@ test("hero is CALM with reassurance when all is well", () => {
test("bearer section and hero count only active owner tokens", () => {
const clients: OwnerIssuedClient[] = [
- { client_id: "inactive", client_name: "Old smoke client", active_token_count: 0, created_at: NOW.toISOString() },
- { client_id: "active", client_name: "Claude Desktop", active_token_count: 2, created_at: NOW.toISOString() },
+ { active_token_count: 0, client_id: "inactive", client_name: "Old smoke client", created_at: NOW.toISOString() },
+ { active_token_count: 2, client_id: "active", client_name: "Claude Desktop", created_at: NOW.toISOString() },
];
const data = buildStandingData(baseInputs({ bearerClients: clients }));
@@ -1169,7 +1169,7 @@ test("bearer section and hero count only active owner tokens", () => {
test("hero says no owner token can act when all issued clients are inactive", () => {
const clients: OwnerIssuedClient[] = [
- { client_id: "inactive", client_name: "Old smoke client", active_token_count: 0, created_at: NOW.toISOString() },
+ { active_token_count: 0, client_id: "inactive", client_name: "Old smoke client", created_at: NOW.toISOString() },
];
const data = buildStandingData(baseInputs({ bearerClients: clients }));
@@ -1181,7 +1181,7 @@ test("hero says no owner token can act when all issued clients are inactive", ()
test("bearer row carries the raw created_at for the shared IcTimestamp, not a prebaked date string", () => {
const clients: OwnerIssuedClient[] = [
- { client_id: "c1", client_name: "Claude Desktop", active_token_count: 1, created_at: "2026-06-01T00:00:00Z" },
+ { active_token_count: 1, client_id: "c1", client_name: "Claude Desktop", created_at: "2026-06-01T00:00:00Z" },
];
const data = buildStandingData(baseInputs({ bearerClients: clients }));
@@ -1197,10 +1197,10 @@ test("bearer row carries the raw created_at for the shared IcTimestamp, not a pr
test('single-token bearer labels created_at "issued"; multi-token bearer degrades to "first issued"', () => {
const single: OwnerIssuedClient[] = [
- { client_id: "one", client_name: "Solo", active_token_count: 1, created_at: NOW.toISOString() },
+ { active_token_count: 1, client_id: "one", client_name: "Solo", created_at: NOW.toISOString() },
];
const multi: OwnerIssuedClient[] = [
- { client_id: "many", client_name: "Legacy", active_token_count: 3, created_at: NOW.toISOString() },
+ { active_token_count: 3, client_id: "many", client_name: "Legacy", created_at: NOW.toISOString() },
];
const singleData = buildStandingData(baseInputs({ bearerClients: single }));
@@ -1216,9 +1216,9 @@ test('single-token bearer labels created_at "issued"; multi-token bearer degrade
test("bearer block previews the most-recent few and reports the hidden overflow count", () => {
const clients: OwnerIssuedClient[] = Array.from({ length: 7 }, (_, i) => ({
+ active_token_count: 1,
client_id: `c${i}`,
client_name: `Client ${i}`,
- active_token_count: 1,
created_at: NOW.toISOString(),
}));
const data = buildStandingData(baseInputs({ bearerClients: clients }));
@@ -1231,7 +1231,7 @@ test("bearer block previews the most-recent few and reports the hidden overflow
test("bearer overflow is zero when active bearers fit within the preview cap", () => {
const clients: OwnerIssuedClient[] = [
- { client_id: "c1", client_name: "Claude Desktop", active_token_count: 1, created_at: NOW.toISOString() },
+ { active_token_count: 1, client_id: "c1", client_name: "Claude Desktop", created_at: NOW.toISOString() },
];
const data = buildStandingData(baseInputs({ bearerClients: clients }));
@@ -1244,43 +1244,43 @@ test("bearer overflow is zero when active bearers fit within the preview cap", (
test("grant packages are surfaced from loaded grants without a count endpoint", () => {
const grants: GrantSummary[] = [
{
- object: "grant_summary",
- grant_id: "g1",
client_id: "App A",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T00:00:00Z",
event_count: 5,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
grant_package_id: "pkg_alpha",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T00:00:00Z",
+ object: "grant_summary",
+ status: "active",
},
{
- object: "grant_summary",
- grant_id: "g2",
client_id: "App A",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T00:00:00Z",
event_count: 3,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g2",
grant_package_id: "pkg_alpha",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T00:00:00Z",
+ object: "grant_summary",
+ status: "active",
},
{
- object: "grant_summary",
- grant_id: "g3",
client_id: "App B",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T00:00:00Z",
event_count: 1,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g3",
grant_package_id: "pkg_beta",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T00:00:00Z",
+ object: "grant_summary",
+ status: "active",
},
];
@@ -1300,20 +1300,20 @@ test("the authoritative grant-package count drives the overview badge when prese
// The overview must trust the endpoint (exact), not the loaded-grants floor,
// so packages not represented in the preview still surface.
const grant: GrantSummary = {
- object: "grant_summary",
- grant_id: "g1",
client_id: "App A",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T00:00:00Z",
event_count: 5,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
grant_package_id: "pkg_alpha",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T00:00:00Z",
+ object: "grant_summary",
+ status: "active",
};
- const data = buildStandingData(baseInputs({ grants: [grant], grantPackageCount: 4 }));
+ const data = buildStandingData(baseInputs({ grantPackageCount: 4, grants: [grant] }));
assert.equal(data.grantPackages?.count, 4);
assert.equal(data.grantPackages?.exact, true);
assert.equal(data.grantPackages?.href, HREFS.grantPackages);
@@ -1321,55 +1321,55 @@ test("the authoritative grant-package count drives the overview badge when prese
test("an authoritative zero grant-package count collapses the badge even if a stale grant carries a package id", () => {
const grant: GrantSummary = {
- object: "grant_summary",
- grant_id: "g1",
client_id: "App A",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T00:00:00Z",
event_count: 5,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
grant_package_id: "pkg_alpha",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T00:00:00Z",
+ object: "grant_summary",
+ status: "active",
};
- const data = buildStandingData(baseInputs({ grants: [grant], grantPackageCount: 0 }));
+ const data = buildStandingData(baseInputs({ grantPackageCount: 0, grants: [grant] }));
assert.equal(data.grantPackages, null);
});
test("a null grant-package count falls back to the loaded-grants floor", () => {
const grant: GrantSummary = {
- object: "grant_summary",
- grant_id: "g1",
client_id: "App A",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T00:00:00Z",
event_count: 5,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
grant_package_id: "pkg_alpha",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T00:00:00Z",
+ object: "grant_summary",
+ status: "active",
};
- const data = buildStandingData(baseInputs({ grants: [grant], grantPackageCount: null }));
+ const data = buildStandingData(baseInputs({ grantPackageCount: null, grants: [grant] }));
assert.equal(data.grantPackages?.count, 1);
assert.equal(data.grantPackages?.exact, false);
});
test("grant packages are absent when no loaded grant carries a package id", () => {
const grant: GrantSummary = {
- object: "grant_summary",
- grant_id: "g1",
client_id: "App A",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T00:00:00Z",
event_count: 5,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T00:00:00Z",
+ object: "grant_summary",
+ status: "active",
};
const data = buildStandingData(baseInputs({ grants: [grant] }));
@@ -1378,17 +1378,17 @@ test("grant packages are absent when no loaded grant carries a package id", () =
test("a fully-revoked package does not advertise from the overview", () => {
const grant: GrantSummary = {
- object: "grant_summary",
- grant_id: "g1",
client_id: "App A",
connector_id: "pdpp",
- status: "revoked",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T00:00:00Z",
event_count: 5,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
grant_package_id: "pkg_dead",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T00:00:00Z",
+ object: "grant_summary",
+ status: "revoked",
};
const data = buildStandingData(baseInputs({ grants: [grant] }));
@@ -1399,35 +1399,35 @@ test("a fully-revoked package does not advertise from the overview", () => {
test("buildStandingData wires bearers, relationships, lately, attention", () => {
const clients: OwnerIssuedClient[] = [
- { client_id: "c1", client_name: "Claude Desktop", active_token_count: 2, created_at: "2026-06-01T00:00:00Z" },
+ { active_token_count: 2, client_id: "c1", client_name: "Claude Desktop", created_at: "2026-06-01T00:00:00Z" },
];
const grant: GrantSummary = {
- object: "grant_summary",
- grant_id: "g1",
client_id: "Atlas Mortgage",
connector_id: "plaid",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T00:00:00Z",
event_count: 5,
- kinds: ["pay_statements"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
+ kinds: ["pay_statements"],
+ last_at: "2026-06-12T00:00:00Z",
+ object: "grant_summary",
+ status: "active",
};
const readTrace: TraceSummary = {
- object: "trace_summary",
- trace_id: "t1",
- status: "succeeded",
actor_id: "Claude Desktop",
actor_type: "client",
client_id: "Claude Desktop",
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: "2026-06-13T00:00:00Z",
- last_at: "2026-06-13T00:00:00Z",
event_count: 412,
- kinds: ["transactions"],
failure: null,
+ first_at: "2026-06-13T00:00:00Z",
+ grant_id: null,
+ kinds: ["transactions"],
+ last_at: "2026-06-13T00:00:00Z",
+ object: "trace_summary",
+ request_id: null,
+ run_id: null,
+ status: "succeeded",
+ trace_id: "t1",
};
const data = buildStandingData(baseInputs({ bearerClients: clients, grants: [grant], traces: [readTrace] }));
assert.equal(data.bearers.length, 1);
@@ -1444,25 +1444,25 @@ test("buildStandingData wires bearers, relationships, lately, attention", () =>
test("lately uses trace client metadata instead of raw client ids", () => {
const trace: TraceSummary = {
- object: "trace_summary",
- trace_id: "trc_named",
- status: "succeeded",
actor_id: "client",
actor_type: "client",
- client_id: "cli_named",
client: {
client_id: "cli_named",
client_name: "Claude",
registration_mode: "dynamic",
},
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: "2026-06-13T00:00:00Z",
- last_at: "2026-06-13T00:00:00Z",
+ client_id: "cli_named",
event_count: 3,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-13T00:00:00Z",
+ grant_id: null,
+ kinds: ["query.received"],
+ last_at: "2026-06-13T00:00:00Z",
+ object: "trace_summary",
+ request_id: null,
+ run_id: null,
+ status: "succeeded",
+ trace_id: "trc_named",
};
const data = buildStandingData(baseInputs({ traces: [trace] }));
@@ -1474,23 +1474,23 @@ test("lately uses trace client metadata instead of raw client ids", () => {
test("lately humanizes live denial reason codes instead of rendering raw diagnostics", () => {
const trace: TraceSummary = {
- object: "trace_summary",
- trace_id: "trc_orphaned",
- status: "denied",
actor_id: "slack",
actor_type: "client",
client_id: "slack",
- grant_id: null,
- run_id: "run_orphaned",
- request_id: null,
- first_at: "2026-06-13T00:00:00Z",
- last_at: "2026-06-13T00:00:00Z",
event_count: 1,
- kinds: ["query.rejected"],
failure: {
event_type: "run.started",
reason: "orphaned_started_run",
},
+ first_at: "2026-06-13T00:00:00Z",
+ grant_id: null,
+ kinds: ["query.rejected"],
+ last_at: "2026-06-13T00:00:00Z",
+ object: "trace_summary",
+ request_id: null,
+ run_id: "run_orphaned",
+ status: "denied",
+ trace_id: "trc_orphaned",
};
const data = buildStandingData(baseInputs({ traces: [trace] }));
@@ -1502,23 +1502,23 @@ test("lately humanizes live denial reason codes instead of rendering raw diagnos
test("lately does not fall through to unknown snake-case denial reasons", () => {
const trace: TraceSummary = {
- object: "trace_summary",
- trace_id: "trc_unknown_denial",
- status: "denied",
actor_id: "client",
actor_type: "client",
client_id: "client",
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: "2026-06-13T00:00:00Z",
- last_at: "2026-06-13T00:00:00Z",
event_count: 1,
- kinds: ["query.rejected"],
failure: {
event_type: "query.rejected",
reason: "new_internal_reason_code",
},
+ first_at: "2026-06-13T00:00:00Z",
+ grant_id: null,
+ kinds: ["query.rejected"],
+ last_at: "2026-06-13T00:00:00Z",
+ object: "trace_summary",
+ request_id: null,
+ run_id: null,
+ status: "denied",
+ trace_id: "trc_unknown_denial",
};
const data = buildStandingData(baseInputs({ traces: [trace] }));
@@ -1531,42 +1531,42 @@ test("lately does not fall through to unknown snake-case denial reasons", () =>
test("lately does not overclaim off-surface expired or credential scope failures", () => {
const traces: TraceSummary[] = [
{
- object: "trace_summary",
- trace_id: "trc_state_expired",
- status: "denied",
actor_id: "state_client",
actor_type: "client",
client_id: "state_client",
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: "2026-06-13T00:00:00Z",
- last_at: "2026-06-13T00:00:00Z",
event_count: 1,
- kinds: ["query.rejected"],
failure: {
event_type: "query.rejected",
reason: "state_expired",
},
- },
- {
+ first_at: "2026-06-13T00:00:00Z",
+ grant_id: null,
+ kinds: ["query.rejected"],
+ last_at: "2026-06-13T00:00:00Z",
object: "trace_summary",
- trace_id: "trc_credential_scope",
+ request_id: null,
+ run_id: null,
status: "denied",
+ trace_id: "trc_state_expired",
+ },
+ {
actor_id: "credential_client",
actor_type: "client",
client_id: "credential_client",
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: "2026-06-13T00:00:01Z",
- last_at: "2026-06-13T00:00:01Z",
event_count: 1,
- kinds: ["query.rejected"],
failure: {
event_type: "query.rejected",
reason: "github_credential_insufficient_scope",
},
+ first_at: "2026-06-13T00:00:01Z",
+ grant_id: null,
+ kinds: ["query.rejected"],
+ last_at: "2026-06-13T00:00:01Z",
+ object: "trace_summary",
+ request_id: null,
+ run_id: null,
+ status: "denied",
+ trace_id: "trc_credential_scope",
},
];
@@ -1580,20 +1580,20 @@ test("lately does not overclaim off-surface expired or credential scope failures
test("lately does not bold raw technical client ids when metadata is missing", () => {
const trace: TraceSummary = {
- object: "trace_summary",
- trace_id: "trc_raw",
- status: "succeeded",
actor_id: "cli_raw",
actor_type: "client",
client_id: "cli_raw",
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: "2026-06-13T00:00:00Z",
- last_at: "2026-06-13T00:00:00Z",
event_count: 3,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-13T00:00:00Z",
+ grant_id: null,
+ kinds: ["query.received"],
+ last_at: "2026-06-13T00:00:00Z",
+ object: "trace_summary",
+ request_id: null,
+ run_id: null,
+ status: "succeeded",
+ trace_id: "trc_raw",
};
const data = buildStandingData(baseInputs({ traces: [trace] }));
@@ -1606,20 +1606,20 @@ test("lately does not bold raw technical client ids when metadata is missing", (
test("lately does not render bare opaque client ids as names", () => {
const opaqueClientId = "d9f1c1bb7a5c4a6f9e8d7c6b5a4f3210";
const trace: TraceSummary = {
- object: "trace_summary",
- trace_id: "trc_opaque",
- status: "succeeded",
actor_id: opaqueClientId,
actor_type: "unknown",
client_id: opaqueClientId,
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: "2026-06-13T00:00:00Z",
- last_at: "2026-06-13T00:00:00Z",
event_count: 3,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-13T00:00:00Z",
+ grant_id: null,
+ kinds: ["query.received"],
+ last_at: "2026-06-13T00:00:00Z",
+ object: "trace_summary",
+ request_id: null,
+ run_id: null,
+ status: "succeeded",
+ trace_id: "trc_opaque",
};
const data = buildStandingData(baseInputs({ traces: [trace] }));
@@ -1633,37 +1633,37 @@ test("lately summarizes identical recent reads instead of repeating the same row
const repeated = Array.from(
{ length: 5 },
(_, i): TraceSummary => ({
- object: "trace_summary",
- trace_id: `trc_longview_${i}`,
- status: "succeeded",
actor_id: "client",
actor_type: "client",
- client_id: "cli_longview",
client: {
client_id: "cli_longview",
client_name: "Longview CLI",
registration_mode: "pre_registered_public",
},
- grant_id: null,
- run_id: null,
- request_id: null,
- first_at: "2026-06-13T00:00:00Z",
- last_at: "2026-06-13T00:00:00Z",
+ client_id: "cli_longview",
event_count: 3,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-13T00:00:00Z",
+ grant_id: null,
+ kinds: ["query.received"],
+ last_at: "2026-06-13T00:00:00Z",
+ object: "trace_summary",
+ request_id: null,
+ run_id: null,
+ status: "succeeded",
+ trace_id: `trc_longview_${i}`,
})
);
- const baseRepeated = repeated[0];
+ const [baseRepeated] = repeated;
assert.ok(baseRepeated);
const different: TraceSummary = {
...baseRepeated,
- trace_id: "trc_controller",
actor_id: "controller",
actor_type: "runtime",
- client_id: null,
client: undefined,
+ client_id: null,
event_count: 1,
+ trace_id: "trc_controller",
};
const data = buildStandingData(baseInputs({ traces: [...repeated, different] }));
@@ -1678,28 +1678,28 @@ test("lately summarizes identical recent reads instead of repeating the same row
test("relationships summarize grants by client instead of repeating one row per grant", () => {
const grants: GrantSummary[] = [
{
- object: "grant_summary",
- grant_id: "g1",
client_id: "CLI agent",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-10T00:00:00Z",
event_count: 5,
- kinds: ["token.issued", "query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
+ kinds: ["token.issued", "query.received"],
+ last_at: "2026-06-10T00:00:00Z",
+ object: "grant_summary",
+ status: "active",
},
{
- object: "grant_summary",
- grant_id: "g2",
client_id: "CLI agent",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-02T00:00:00Z",
- last_at: "2026-06-12T12:00:00Z",
event_count: 7,
- kinds: ["disclosure.served", "query.rejected"],
failure: null,
+ first_at: "2026-06-02T00:00:00Z",
+ grant_id: "g2",
+ kinds: ["disclosure.served", "query.rejected"],
+ last_at: "2026-06-12T12:00:00Z",
+ object: "grant_summary",
+ status: "active",
},
];
@@ -1719,16 +1719,16 @@ test("relationships summarize grants by client instead of repeating one row per
test("relationships use known client names without replacing the verified client id", () => {
const grants: GrantSummary[] = [
{
- object: "grant_summary",
- grant_id: "g1",
client_id: "cli_known",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T12:00:00Z",
event_count: 7,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T12:00:00Z",
+ object: "grant_summary",
+ status: "active",
},
];
const clients: OwnerIssuedClient[] = [
@@ -1751,21 +1751,21 @@ test("relationships use known client names without replacing the verified client
test("relationships prefer grant client metadata over owner-token labels", () => {
const grants: GrantSummary[] = [
{
- object: "grant_summary",
- grant_id: "g1",
- client_id: "cli_known",
client: {
client_id: "cli_known",
client_name: "Claude Code",
registration_mode: "dynamic",
},
+ client_id: "cli_known",
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T12:00:00Z",
event_count: 7,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T12:00:00Z",
+ object: "grant_summary",
+ status: "active",
},
];
const clients: OwnerIssuedClient[] = [
@@ -1788,16 +1788,16 @@ test("relationships do not render raw URL client ids as owner-facing names", ()
const urlClientId = "https://chatgpt.com/oauth/Dyp26IIu2iQg/client.json?token_endpoint_auth_method=none";
const grants: GrantSummary[] = [
{
- object: "grant_summary",
- grant_id: "g1",
client_id: urlClientId,
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T12:00:00Z",
event_count: 7,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T12:00:00Z",
+ object: "grant_summary",
+ status: "active",
},
];
@@ -1813,16 +1813,16 @@ test("relationships do not render bare UUID or opaque client ids as owner-facing
for (const clientId of ["0b643449-9516-45e0-b375-7feb9ecb7a58", "d9f1c1bb7a5c4a6f9e8d7c6b5a4f3210"]) {
const grants: GrantSummary[] = [
{
- object: "grant_summary",
- grant_id: "g1",
client_id: clientId,
connector_id: "pdpp",
- status: "active",
- first_at: "2026-06-01T00:00:00Z",
- last_at: "2026-06-12T12:00:00Z",
event_count: 7,
- kinds: ["query.received"],
failure: null,
+ first_at: "2026-06-01T00:00:00Z",
+ grant_id: "g1",
+ kinds: ["query.received"],
+ last_at: "2026-06-12T12:00:00Z",
+ object: "grant_summary",
+ status: "active",
},
];
@@ -1837,16 +1837,16 @@ test("relationships do not render bare UUID or opaque client ids as owner-facing
test("revoked grants are excluded from relationships", () => {
const revoked: GrantSummary = {
- object: "grant_summary",
- grant_id: "g2",
client_id: "Old App",
connector_id: null,
- status: "revoked",
- first_at: "2026-05-01T00:00:00Z",
- last_at: "2026-05-02T00:00:00Z",
event_count: 0,
- kinds: [],
failure: null,
+ first_at: "2026-05-01T00:00:00Z",
+ grant_id: "g2",
+ kinds: [],
+ last_at: "2026-05-02T00:00:00Z",
+ object: "grant_summary",
+ status: "revoked",
};
const data = buildStandingData(baseInputs({ grants: [revoked] }));
assert.equal(data.relationships.length, 0);
diff --git a/apps/console/src/app/(console)/components/views/standing-view-model.ts b/apps/console/src/app/(console)/components/views/standing-view-model.ts
index f8deaa706..20e5b387f 100644
--- a/apps/console/src/app/(console)/components/views/standing-view-model.ts
+++ b/apps/console/src/app/(console)/components/views/standing-view-model.ts
@@ -41,31 +41,31 @@ import {
// back to its own prettified name. We never invent a meaning we can't justify.
const SCOPE_HUMAN: Record = {
- pay_statements: "your pay",
- paystubs: "your pay",
- income: "your pay",
- employment: "your employment history",
- listening_history: "what you listen to",
- watch_history: "what you watch",
- transactions: "your spending",
- current_activity: "your spending",
- statements: "your statements",
- tax_docs: "your tax documents",
- tax_documents: "your tax documents",
- browsing: "your browsing",
browser_history: "your browsing",
- messages: "your messages",
+ browsing: "your browsing",
+ "consent.approved": "grant decisions",
conversations: "your conversations",
+ current_activity: "your spending",
+ "disclosure.served": "data disclosures",
emails: "your email",
- orders: "your orders",
- purchases: "your purchases",
+ employment: "your employment history",
health: "your health records",
+ income: "your pay",
+ listening_history: "what you listen to",
location: "where you've been",
- "consent.approved": "grant decisions",
- "disclosure.served": "data disclosures",
+ messages: "your messages",
+ orders: "your orders",
+ pay_statements: "your pay",
+ paystubs: "your pay",
+ purchases: "your purchases",
"query.received": "read requests",
"query.rejected": "rejected reads",
+ statements: "your statements",
+ tax_docs: "your tax documents",
+ tax_documents: "your tax documents",
"token.issued": "token activity",
+ transactions: "your spending",
+ watch_history: "what you watch",
};
const READ_SUFFIX_RE = /\.read$/;
@@ -100,15 +100,15 @@ export function joinHuman(parts: readonly string[]): string {
}
const STREAM_RECORD_NOUN: Record = {
- pay_statements: "pay records",
+ current_activity: "transactions",
+ emails: "emails",
employment: "employment records",
listening_history: "listening records",
- tax_docs: "tax records",
- transactions: "transactions",
- current_activity: "transactions",
messages: "messages",
- emails: "emails",
orders: "orders",
+ pay_statements: "pay records",
+ tax_docs: "tax records",
+ transactions: "transactions",
};
/** "transactions" / "pay records" — the plural noun for a stream of records. */
@@ -528,13 +528,13 @@ function toBearers(clients: OwnerIssuedClient[], hrefs: StandingHrefs): BearerVi
const tokenWord = count === 1 ? "token" : "tokens";
return {
clientId: c.client_id,
- who: clientLabel(c.client_name, c.client_id),
how: `owner token · ${count} active ${tokenWord}`,
+ issuedAt: c.created_at,
// A client with more than one active token registered before the newest
// token was issued, so `created_at` is a "first issued", not "issued".
issuedLabel: count > 1 ? "first issued" : "issued",
- issuedAt: c.created_at,
revokeHref: hrefs.deploymentTokens,
+ who: clientLabel(c.client_name, c.client_id),
};
});
}
@@ -741,18 +741,18 @@ function toLately(traces: TraceSummary[], now: Date): LatelyView[] {
let row: LatelyView;
if (isDeny) {
row = {
+ deny: true,
id: tr.trace_id,
+ text: { rest: `tried to read — turned away, ${denyReason(tr.failure?.reason ?? null)}.`, who },
when: relDay(tr.last_at, now),
- deny: true,
- text: { who, rest: `tried to read — turned away, ${denyReason(tr.failure?.reason ?? null)}.` },
};
} else {
const noun = tr.event_count === 1 ? "record" : "records";
row = {
+ deny: false,
id: tr.trace_id,
+ text: { rest: `read ${fmtInt(tr.event_count)} ${noun}.`, who },
when: relDay(tr.last_at, now),
- deny: false,
- text: { who, rest: `read ${fmtInt(tr.event_count)} ${noun}.` },
};
}
const key = `${row.deny ? "deny" : "read"}|${row.when}|${row.text.who}|${row.text.rest}`;
@@ -829,19 +829,19 @@ export function advisoryOwnerActionsFromConnectors(
function toAttention(attention: AttentionConnection[], hrefs: StandingHrefs): AttentionRowView[] {
return attention.map((a) => ({
+ href: hrefs.connection(a.routeId),
id: `connection:${a.routeId}`,
what: `${a.label} needs you`,
why: a.what,
- href: hrefs.connection(a.routeId),
}));
}
function toSourceIssues(sourceIssues: SourceIssueConnection[], hrefs: StandingHrefs): AttentionRowView[] {
return sourceIssues.map((issue) => ({
+ href: hrefs.connection(issue.routeId),
id: `source-issue:${issue.routeId}`,
what: `${issue.label} ${issue.status}`,
why: issue.what,
- href: hrefs.connection(issue.routeId),
}));
}
@@ -850,10 +850,10 @@ function toAdvisoryOwnerActions(
hrefs: StandingHrefs
): AttentionRowView[] {
return advisoryOwnerActions.map((action) => ({
+ href: hrefs.connection(action.routeId),
id: `advisory-owner-action:${action.routeId}`,
what: `${action.label} has an action to review`,
why: action.what,
- href: hrefs.connection(action.routeId),
}));
}
@@ -864,13 +864,13 @@ function toOverviewIssues(loadIssues: readonly string[], hrefs: StandingHrefs):
const count = loadIssues.length;
return [
{
+ href: hrefs.deployment,
id: "overview:partial-data",
what: "Overview could not check everything",
why:
count === 1
? "One dashboard check did not load. Refresh this page; if it keeps happening, check deployment."
: `${count} dashboard checks did not load. Refresh this page; if it keeps happening, check deployment.`,
- href: hrefs.deployment,
},
];
}
@@ -958,10 +958,10 @@ function sourceWorkRow(item: SourceWorkItem, hrefs: StandingHrefs): AttentionRow
what = `${item.label} ${item.statusLabel}`;
}
return {
+ href: hrefs.connection(item.routeId),
id: item.id,
what,
why: item.group === "working" || item.group === "notMeasured" ? item.statusLabel : item.what,
- href: hrefs.connection(item.routeId),
};
}
@@ -977,52 +977,52 @@ function toSourceWorkSections(
const sections: SourceWorkSectionView[] = [];
if (groups.needsOwner.length > 0) {
sections.push({
+ countLabel: pluralSource(groups.needsOwner.length),
id: "needsOwner",
- title: SOURCE_WORK_GROUP_COPY.needsOwner.label,
note: SOURCE_WORK_GROUP_COPY.needsOwner.note,
- countLabel: pluralSource(groups.needsOwner.length),
- tone: "owner",
rows: groups.needsOwner.map((item) => sourceWorkRow(item, hrefs)),
+ title: SOURCE_WORK_GROUP_COPY.needsOwner.label,
+ tone: "owner",
});
}
if (groups.review.length > 0) {
sections.push({
+ countLabel: pluralSource(groups.review.length),
id: "review",
- title: SOURCE_WORK_GROUP_COPY.review.label,
note: SOURCE_WORK_GROUP_COPY.review.note,
- countLabel: pluralSource(groups.review.length),
- tone: "review",
rows: groups.review.map((item) => sourceWorkRow(item, hrefs)),
+ title: SOURCE_WORK_GROUP_COPY.review.label,
+ tone: "review",
});
}
if (groups.systemIssues.length > 0 || overviewIssues.length > 0) {
sections.push({
+ countLabel: pluralSource(groups.systemIssues.length + overviewIssues.length),
id: "systemIssue",
- title: SOURCE_WORK_GROUP_COPY.systemIssue.label,
note: SOURCE_WORK_GROUP_COPY.systemIssue.note,
- countLabel: pluralSource(groups.systemIssues.length + overviewIssues.length),
- tone: "system",
rows: [...groups.systemIssues.map((item) => sourceWorkRow(item, hrefs)), ...overviewIssues],
+ title: SOURCE_WORK_GROUP_COPY.systemIssue.label,
+ tone: "system",
});
}
if (groups.working.length > 0) {
sections.push({
+ countLabel: pluralSource(groups.working.length),
id: "working",
- title: SOURCE_WORK_GROUP_COPY.working.label,
note: SOURCE_WORK_GROUP_COPY.working.note,
- countLabel: pluralSource(groups.working.length),
- tone: "muted",
rows: groups.working.map((item) => sourceWorkRow(item, hrefs)),
+ title: SOURCE_WORK_GROUP_COPY.working.label,
+ tone: "muted",
});
}
if (groups.notMeasured.length > 0) {
sections.push({
+ countLabel: pluralSource(groups.notMeasured.length),
id: "notMeasured",
- title: SOURCE_WORK_GROUP_COPY.notMeasured.label,
note: SOURCE_WORK_GROUP_COPY.notMeasured.note,
- countLabel: pluralSource(groups.notMeasured.length),
- tone: "muted",
rows: groups.notMeasured.map((item) => sourceWorkRow(item, hrefs)),
+ title: SOURCE_WORK_GROUP_COPY.notMeasured.label,
+ tone: "muted",
});
}
return sections;
@@ -1032,17 +1032,17 @@ function toSourceWorkSections(
/** DECIDE — a request is waiting on the owner. */
function buildDecideHero(pending: PendingApproval[], hrefs: StandingHrefs): StandingHero {
- const first = pending[0];
+ const [first] = pending;
const more = pending.length - 1;
const who = first ? clientLabel(first.client_id ?? null, first.approval_id) : "An app";
const reads = first ? approvalReads(first) : "parts of your data";
const moreSub = `Nothing leaves until you say so — review each request one at a time. ${more} more after this one.`;
return {
- tone: "decide",
+ cta: { href: hrefs.grants, human: true, label: "Review the request" },
kicker: pending.length === 1 ? "A request is waiting on you" : `${pending.length} requests are waiting`,
- line: { text: `${who} wants to read `, emphasis: reads, tail: "." },
+ line: { emphasis: reads, tail: ".", text: `${who} wants to read ` },
sub: more > 0 ? moreSub : "Nothing leaves until you say so — approve it one piece at a time.",
- cta: { label: "Review the request", href: hrefs.grants, human: true },
+ tone: "decide",
};
}
@@ -1055,27 +1055,27 @@ function buildFailureHero(attention: AttentionConnection[], hrefs: StandingHrefs
const [only] = attention;
if (count === 1 && only) {
return {
- tone: "alarm",
- kicker: "One thing needs you",
- line: { text: `${only.label} `, emphasis: "needs you", tail: "." },
- sub: only.what,
// A device-local recovery is not performed by clicking — the CTA only
// navigates to where the commands are. Use a navigation label ("See what
// to do") so the owner doesn't click expecting the dashboard to run it.
// A dashboard-actionable verdict (reauth, refresh) keeps its action verb.
cta: {
- label: only.deviceLocal ? "See what to do" : only.actionLabel,
href: hrefs.connection(only.routeId),
human: true,
+ label: only.deviceLocal ? "See what to do" : only.actionLabel,
},
+ kicker: "One thing needs you",
+ line: { emphasis: "needs you", tail: ".", text: `${only.label} ` },
+ sub: only.what,
+ tone: "alarm",
};
}
return {
- tone: "alarm",
+ cta: { href: hrefs.runs, label: "See what needs you" },
kicker: `${count} things need you`,
- line: { text: `${count} connections `, emphasis: "need a look", tail: "." },
+ line: { emphasis: "need a look", tail: ".", text: `${count} connections ` },
sub: "Nothing you already have is lost — open each one to see what it needs.",
- cta: { label: "See what needs you", href: hrefs.runs },
+ tone: "alarm",
};
}
@@ -1084,32 +1084,32 @@ function buildStaleHero(summary: DatasetSummary | null, hrefs: StandingHrefs): S
const projectionState = summary?.projection?.state;
const isFailed = projectionState === "failed";
return {
- tone: "alarm",
+ cta: { href: hrefs.deployment, label: "View status" },
kicker: isFailed ? "Totals update delayed" : "Totals updating",
line: {
- text: "Records ",
emphasis: "are still available",
tail: ".",
+ text: "Records ",
},
sub: isFailed
? "Dashboard totals are using the last completed update."
: "Dashboard totals may use the last completed update for a few minutes.",
- cta: { label: "View status", href: hrefs.deployment },
+ tone: "alarm",
};
}
function buildPartialDataHero(loadIssues: readonly string[], hrefs: StandingHrefs): StandingHero {
const count = loadIssues.length;
return {
- tone: "alarm",
+ cta: { href: hrefs.deployment, label: "Check deployment" },
kicker: "Overview is incomplete",
line: {
- text: count === 1 ? "One dashboard check " : `${count} dashboard checks `,
emphasis: "did not load",
tail: ".",
+ text: count === 1 ? "One dashboard check " : `${count} dashboard checks `,
},
sub: "Refresh this page; if it keeps happening, check deployment. This page will not claim all-clear from partial data.",
- cta: { label: "Check deployment", href: hrefs.deployment },
+ tone: "alarm",
};
}
@@ -1118,21 +1118,22 @@ function buildAdvisoryHero(actions: AdvisoryOwnerActionConnection[], hrefs: Stan
if (actions.length === 1 && only) {
// Lead with the CONCRETE action the owner can run ("Refresh now" / "Retry
// now"), not the "ready for review" taxonomy phrasing.
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
const action = only.actionLabel ?? "Run the available action";
return {
- tone: "decide",
+ cta: { href: hrefs.connection(only.routeId), human: true, label: action },
kicker: "One optional action is available",
- line: { text: `${only.label}: `, emphasis: action, tail: "." },
+ line: { emphasis: action, tail: ".", text: `${only.label}: ` },
sub: only.what,
- cta: { label: action, href: hrefs.connection(only.routeId), human: true },
+ tone: "decide",
};
}
return {
- tone: "decide",
+ cta: { href: hrefs.sources, label: "See available actions" },
kicker: `${actions.length} optional actions are available`,
- line: { text: "Refreshes and retries ", emphasis: "are available", tail: "." },
+ line: { emphasis: "are available", tail: ".", text: "Refreshes and retries " },
sub: "Nothing is broken — run these refreshes and retries when you like. Records remain available.",
- cta: { label: "See available actions", href: hrefs.sources },
+ tone: "decide",
};
}
@@ -1143,6 +1144,7 @@ function buildCalmHero(input: StandingInputs): StandingHero {
const activeTokenCount = activeOwnerTokenCount(activeClients);
const liveGrants = input.grants.filter(isLiveGrant);
const records = summary ? fmtInt(summary.record_count) : "0";
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
const sources = summary?.connector_count ?? 0;
const sourceWord = sources === 1 ? "source" : "sources";
const grantWord = liveGrants.length === 1 ? "app reads" : "apps read";
@@ -1151,10 +1153,10 @@ function buildCalmHero(input: StandingInputs): StandingHero {
const withBearers = `${activeClients.length} ${clientWord} ${fmtInt(activeTokenCount)} active owner ${tokenWord} with full access. ${liveGrants.length} ${grantWord} only the slices you granted. Revoke any of them instantly.`;
const noBearers = `No owner token can act as you yet. ${liveGrants.length} ${grantWord} only the slices you granted. Revoke any of them instantly.`;
return {
- tone: "calm",
kicker: "Where you stand",
- line: { text: `${records} records from ${sources} ${sourceWord} — `, emphasis: "all yours to read", tail: "." },
+ line: { emphasis: "all yours to read", tail: ".", text: `${records} records from ${sources} ${sourceWord} — ` },
sub: activeTokenCount > 0 ? withBearers : noBearers,
+ tone: "calm",
};
}
@@ -1178,9 +1180,9 @@ export function computeHero(input: StandingInputs): StandingHero {
sourceWork.needsOwner.map((item) => ({
actionLabel: item.actionLabel ?? "Review source",
connectorKey: "",
- routeId: item.routeId,
deviceLocal: item.deviceLocal,
label: item.label,
+ routeId: item.routeId,
what: item.what,
})),
input.hrefs
@@ -1215,15 +1217,15 @@ export function buildStandingData(input: StandingInputs): StandingData {
const allBearers = toBearers(input.bearerClients, input.hrefs);
const bearers = allBearers.slice(0, BEARER_PREVIEW_LIMIT);
return {
- hero: computeHero(input),
+ advisoryOwnerActions: toAdvisoryOwnerActions(input.advisoryOwnerActions, input.hrefs),
+ attention: toAttention(input.attentionConnections, input.hrefs),
bearers,
bearersOverflow: allBearers.length - bearers.length,
grantPackages: toGrantPackages(input.grants, input.hrefs, input.grantPackageCount),
- relationships: toRelationships(input.grants, input.hrefs, input.now, clientNamesById(input.bearerClients)),
+ hero: computeHero(input),
lately: toLately(input.traces, input.now),
- advisoryOwnerActions: toAdvisoryOwnerActions(input.advisoryOwnerActions, input.hrefs),
- attention: toAttention(input.attentionConnections, input.hrefs),
overviewIssues,
+ relationships: toRelationships(input.grants, input.hrefs, input.now, clientNamesById(input.bearerClients)),
sourceIssues: toSourceIssues(input.sourceIssues, input.hrefs),
sourceWorkSections: toSourceWorkSections(sourceWork, overviewIssues, input.hrefs),
};
diff --git a/apps/console/src/app/(console)/components/warnings-banner.tsx b/apps/console/src/app/(console)/components/warnings-banner.tsx
index 713b9790a..8322bda2c 100644
--- a/apps/console/src/app/(console)/components/warnings-banner.tsx
+++ b/apps/console/src/app/(console)/components/warnings-banner.tsx
@@ -18,6 +18,7 @@ function warningKey(warning: CanonicalReadWarning): string {
* `deprecated_alias_used` plus a `count_downgraded`).
*/
export function WarningsBanner({ warnings }: { warnings: CanonicalReadWarning[] }) {
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
if (!warnings || warnings.length === 0) {
return null;
}
diff --git a/apps/console/src/app/(console)/components/web-push-settings.tsx b/apps/console/src/app/(console)/components/web-push-settings.tsx
index e70a77577..3da10d2c3 100644
--- a/apps/console/src/app/(console)/components/web-push-settings.tsx
+++ b/apps/console/src/app/(console)/components/web-push-settings.tsx
@@ -40,11 +40,11 @@ type DeviceAction =
function deviceReducer(state: DeviceState, action: DeviceAction): DeviceState {
switch (action.type) {
case "supportDetected":
- return { ...state, unavailable: action.unavailable, permission: action.permission, status: action.status };
+ return { ...state, permission: action.permission, status: action.status, unavailable: action.unavailable };
case "swState":
return action.status === undefined
? { ...state, swState: action.swState }
- : { ...state, swState: action.swState, status: action.status };
+ : { ...state, status: action.status, swState: action.swState };
case "subscribed":
return { ...state, endpoint: action.endpoint, status: action.status };
case "disabled":
@@ -177,91 +177,91 @@ function setupStepToneClass(state: DiagnosticState) {
function secureContextRow(): DiagnosticRow {
if (typeof window === "undefined") {
- return { label: "Secure context (HTTPS/localhost)", state: "unknown", detail: "Server-rendered" };
+ return { detail: "Server-rendered", label: "Secure context (HTTPS/localhost)", state: "unknown" };
}
if (window.isSecureContext) {
- return { label: "Secure context (HTTPS/localhost)", state: "ok", detail: window.location.origin };
+ return { detail: window.location.origin, label: "Secure context (HTTPS/localhost)", state: "ok" };
}
return {
+ detail: "Page is not served over a secure origin.",
label: "Secure context (HTTPS/localhost)",
state: "fail",
- detail: "Page is not served over a secure origin.",
};
}
function featureRow(label: string, present: boolean, presentDetail: string, missingDetail: string): DiagnosticRow {
- return present ? { label, state: "ok", detail: presentDetail } : { label, state: "fail", detail: missingDetail };
+ return present ? { detail: presentDetail, label, state: "ok" } : { detail: missingDetail, label, state: "fail" };
}
function vapidRow(config: WebPushConfig): DiagnosticRow {
if (config.enabled && config.public_key) {
return {
+ detail: "/_ref/web-push/config reports enabled",
label: "Server VAPID keys configured",
state: "ok",
- detail: "/_ref/web-push/config reports enabled",
};
}
return {
+ detail: config.unavailable_reason || "Server VAPID keys are not configured.",
label: "Server VAPID keys configured",
state: "fail",
- detail: config.unavailable_reason || "Server VAPID keys are not configured.",
};
}
function swRow(swState: "registered" | "absent" | "unknown" | "unsupported"): DiagnosticRow {
const label = "Service worker registered";
if (swState === "registered") {
- return { label, state: "ok", detail: "The PDPP service worker controls /." };
+ return { detail: "The PDPP service worker controls /.", label, state: "ok" };
}
if (swState === "absent") {
- return { label, state: "warn", detail: "Not registered yet - use Enable this device." };
+ return { detail: "Not registered yet - use Enable this device.", label, state: "warn" };
}
if (swState === "unsupported") {
- return { label, state: "fail", detail: "Browser lacks serviceWorker." };
+ return { detail: "Browser lacks serviceWorker.", label, state: "fail" };
}
- return { label, state: "unknown", detail: "Could not inspect registration." };
+ return { detail: "Could not inspect registration.", label, state: "unknown" };
}
function permissionRow(permission: NotificationPermission | "unknown"): DiagnosticRow {
const label = "Notification permission granted";
if (permission === "granted") {
- return { label, state: "ok", detail: 'Notification.permission === "granted"' };
+ return { detail: 'Notification.permission === "granted"', label, state: "ok" };
}
if (permission === "denied") {
return {
+ detail: 'Notification.permission === "denied" - change browser/OS notification settings to opt in.',
label,
state: "fail",
- detail: 'Notification.permission === "denied" - change browser/OS notification settings to opt in.',
};
}
if (permission === "default") {
return {
+ detail: "Permission has not been requested on this device - use Enable this device.",
label,
state: "warn",
- detail: "Permission has not been requested on this device - use Enable this device.",
};
}
- return { label, state: "unknown", detail: "Notification API not available." };
+ return { detail: "Notification API not available.", label, state: "unknown" };
}
function browserSubscriptionRow(endpoint: string | null, matchesThisBrowser: boolean): DiagnosticRow {
const label = "Browser push subscription active";
if (!endpoint) {
return {
- label,
- state: "warn",
detail:
"No active subscription on this device - use Enable this device to create one (installing the PWA alone does not subscribe).",
+ label,
+ state: "warn",
};
}
if (matchesThisBrowser) {
- return { label, state: "ok", detail: "Browser endpoint is registered for this owner on the server." };
+ return { detail: "Browser endpoint is registered for this owner on the server.", label, state: "ok" };
}
return {
- label,
- state: "warn",
detail:
"Browser has a subscription but the server does not list it for this owner - use Enable this device to re-register.",
+ label,
+ state: "warn",
};
}
@@ -269,15 +269,15 @@ function deliveryHealthRow(lastSubscription: WebPushSubscriptionSummary | undefi
const label = "Last delivery health";
if (lastSubscription?.last_failure_reason) {
return {
+ detail: `Most recent failure: ${lastSubscription.last_failure_reason} (${lastSubscription.last_failure_at ?? "unknown time"}). Use Enable this device on the affected device to re-subscribe.`,
label,
state: "warn",
- detail: `Most recent failure: ${lastSubscription.last_failure_reason} (${lastSubscription.last_failure_at ?? "unknown time"}). Use Enable this device on the affected device to re-subscribe.`,
};
}
if (lastSubscription?.last_success_at) {
- return { label, state: "ok", detail: `Last success: ${lastSubscription.last_success_at}.` };
+ return { detail: `Last success: ${lastSubscription.last_success_at}.`, label, state: "ok" };
}
- return { label, state: "unknown", detail: "No delivery attempt recorded yet." };
+ return { detail: "No delivery attempt recorded yet.", label, state: "unknown" };
}
function deviceStatus({
@@ -295,43 +295,43 @@ function deviceStatus({
}): DeviceStatus {
if (unavailable) {
return {
- title: "This browser cannot receive PDPP notifications.",
detail: unavailable,
+ title: "This browser cannot receive PDPP notifications.",
};
}
if (permission === "unknown" && swState === "unknown") {
return {
- title: "Checking this device…",
detail: "Inspecting browser permission and subscription state.",
+ title: "Checking this device…",
};
}
if (permission === "denied") {
return {
- title: "Notifications are blocked for this browser.",
detail: "Change browser or OS notification settings, then return here and enable this device.",
+ title: "Notifications are blocked for this browser.",
};
}
if (matchesThisBrowser) {
return {
- title: "This device is subscribed.",
detail: "Pending connector interactions can send browser notifications to this browser or installed app.",
+ title: "This device is subscribed.",
};
}
if (endpoint) {
return {
- title: "This browser has a local subscription, but the server does not recognize it.",
detail: "Enable this device again to repair the server-side subscription.",
+ title: "This browser has a local subscription, but the server does not recognize it.",
};
}
if (permission === "granted") {
return {
- title: "Notifications are allowed, but this device is not subscribed.",
detail: "Enable this device once so PDPP can send alerts here.",
+ title: "Notifications are allowed, but this device is not subscribed.",
};
}
return {
- title: "This device is not subscribed yet.",
detail: "Installing the PWA only adds the app icon. You still need to enable notifications from this device.",
+ title: "This device is not subscribed yet.",
};
}
@@ -352,26 +352,26 @@ function buildSetupSteps({
return [
{
+ detail: "This page configures notifications only for the browser or installed app you are using right now.",
label: "Open the right device",
state: "ok",
- detail: "This page configures notifications only for the browser or installed app you are using right now.",
},
{
+ detail: setupPermissionDetail(permission),
label: "Allow notifications",
state: setupPermissionState(permission, unavailable),
- detail: setupPermissionDetail(permission),
},
{
+ detail: setupSubscriptionDetail({ endpoint, matchesThisBrowser }),
label: "Subscribe this device",
state: setupSubscriptionState({ matchesThisBrowser, unavailable }),
- detail: setupSubscriptionDetail({ endpoint, matchesThisBrowser }),
},
{
- label: "Send a test",
- state: setupTestState({ matchesThisBrowser, testNotificationAccepted }),
detail: testNotificationAccepted
? "The push provider accepted the test. Only the device can confirm whether it displayed."
: "Use Send test notification after this device is subscribed.",
+ label: "Send a test",
+ state: setupTestState({ matchesThisBrowser, testNotificationAccepted }),
},
];
}
@@ -493,12 +493,12 @@ function buildDiagnostics({
permissionRow(permission),
browserSubscriptionRow(endpoint, matchesThisBrowser),
{
- label: "Server-tracked subscriptions for this owner",
- state: subscriptions.length > 0 ? "ok" : "warn",
detail:
subscriptions.length > 0
? `${subscriptions.length} saved across all of this owner's devices.`
: "Server has no saved subscriptions yet for this owner.",
+ label: "Server-tracked subscriptions for this owner",
+ state: subscriptions.length > 0 ? "ok" : "warn",
},
deliveryHealthRow(lastSubscription),
];
@@ -564,27 +564,33 @@ export function WebPushSettings({
async function refreshSubscriptionState() {
if (!hasNavigatorFeature("serviceWorker")) {
- dispatch({ type: "swState", swState: "unsupported" });
+ dispatch({ swState: "unsupported", type: "swState" });
return;
}
try {
const registration = await navigator.serviceWorker.getRegistration("/");
- await registration?.update().catch(() => undefined);
- dispatch({ type: "swState", swState: registration ? "registered" : "absent" });
+ if (registration) {
+ try {
+ await registration.update();
+ } catch {
+ // A refresh failure is non-fatal; subscription state remains usable.
+ }
+ }
+ dispatch({ swState: registration ? "registered" : "absent", type: "swState" });
const existing = await registration?.pushManager.getSubscription();
- dispatch({ type: "endpoint", endpoint: existing?.endpoint ?? null });
+ dispatch({ endpoint: existing?.endpoint ?? null, type: "endpoint" });
} catch {
- dispatch({ type: "swState", swState: "unknown" });
+ dispatch({ swState: "unknown", type: "swState" });
}
}
useEffect(() => {
const reason = detectSupport(config);
dispatch({
- type: "supportDetected",
- unavailable: reason,
permission: "Notification" in window ? Notification.permission : "unknown",
status: reason ? "Unavailable in this browser" : `Permission: ${Notification.permission}`,
+ type: "supportDetected",
+ unavailable: reason,
});
if (reason) {
return;
@@ -596,26 +602,32 @@ export function WebPushSettings({
if (cancelled) {
return;
}
- dispatch({ type: "swState", swState: registration ? "registered" : "absent" });
- await registration?.update().catch(() => undefined);
+ dispatch({ swState: registration ? "registered" : "absent", type: "swState" });
+ if (registration) {
+ try {
+ await registration.update();
+ } catch {
+ // A refresh failure is non-fatal; subscription state remains usable.
+ }
+ }
const existing = await registration?.pushManager.getSubscription();
if (cancelled) {
return;
}
if (existing) {
dispatch({
- type: "subscribed",
endpoint: existing.endpoint,
status: "Web Push is enabled for this browser.",
+ type: "subscribed",
});
}
})
.catch(() => {
if (!cancelled) {
dispatch({
- type: "swState",
- swState: "unknown",
status: "Could not inspect this browser's Web Push subscription.",
+ swState: "unknown",
+ type: "swState",
});
}
});
@@ -632,45 +644,45 @@ export function WebPushSettings({
setTestStatus(null);
try {
const registration = await navigator.serviceWorker.register("/pdpp-dashboard-sw.js");
- dispatch({ type: "swState", swState: "registered" });
+ dispatch({ swState: "registered", type: "swState" });
const result = await Notification.requestPermission();
- dispatch({ type: "permission", permission: result });
+ dispatch({ permission: result, type: "permission" });
if (result !== "granted") {
dispatch({
- type: "status",
status:
result === "denied"
? "Permission denied. Enable notifications in browser settings."
: "Permission was not granted.",
+ type: "status",
});
return;
}
const subscription =
(await registration.pushManager.getSubscription()) ??
(await registration.pushManager.subscribe({
- userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(config.public_key),
+ userVisibleOnly: true,
}));
const response = await fetch("/_ref/web-push/subscriptions", {
- method: "POST",
- credentials: "same-origin",
- headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({
- subscription: subscription.toJSON(),
- platform: navigator.platform || null,
device_label: "PDPP browser",
+ platform: navigator.platform || null,
+ subscription: subscription.toJSON(),
}),
+ credentials: "same-origin",
+ headers: { Accept: "application/json", "Content-Type": "application/json" },
+ method: "POST",
});
if (!response.ok) {
throw await webPushResponseError(response, "Subscription failed");
}
dispatch({
- type: "subscribed",
endpoint: subscription.endpoint,
status: "Web Push is enabled for this browser.",
+ type: "subscribed",
});
} catch (err) {
- dispatch({ type: "status", status: err instanceof Error ? err.message : "Failed to enable Web Push." });
+ dispatch({ status: err instanceof Error ? err.message : "Failed to enable Web Push.", type: "status" });
} finally {
setBusy(false);
}
@@ -681,9 +693,9 @@ export function WebPushSettings({
setTestStatus("Sending test notification…");
try {
const response = await fetch("/_ref/web-push/test", {
- method: "POST",
credentials: "same-origin",
headers: { Accept: "application/json" },
+ method: "POST",
});
if (!response.ok) {
throw await webPushResponseError(response, "Test notification failed");
@@ -721,18 +733,18 @@ export function WebPushSettings({
}
if (targetEndpoint) {
const response = await fetch("/_ref/web-push/subscriptions", {
- method: "DELETE",
- credentials: "same-origin",
- headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({ endpoint: targetEndpoint }),
+ credentials: "same-origin",
+ headers: { Accept: "application/json", "Content-Type": "application/json" },
+ method: "DELETE",
});
if (!response.ok) {
throw await webPushResponseError(response, "Unsubscribe failed");
}
}
- dispatch({ type: "disabled", status: "Web Push is disabled for this browser." });
+ dispatch({ status: "Web Push is disabled for this browser.", type: "disabled" });
} catch (err) {
- dispatch({ type: "status", status: err instanceof Error ? err.message : "Failed to disable Web Push." });
+ dispatch({ status: err instanceof Error ? err.message : "Failed to disable Web Push.", type: "status" });
} finally {
setBusy(false);
}
@@ -744,19 +756,19 @@ export function WebPushSettings({
const caveat =
"Mobile browsers may require opening the installed PDPP app before notifications can arrive. Each phone, tablet, and browser profile must be enabled separately.";
- const lastSubscription = subscriptions[0];
+ const [lastSubscription] = subscriptions;
const matchesThisBrowser = endpoint ? subscriptions.some((s) => s.endpoint === endpoint && !s.revoked_at) : false;
- const currentDeviceStatus = deviceStatus({ unavailable, permission, endpoint, matchesThisBrowser, swState });
- const setupSteps = buildSetupSteps({ unavailable, permission, endpoint, matchesThisBrowser, testStatus });
+ const currentDeviceStatus = deviceStatus({ endpoint, matchesThisBrowser, permission, swState, unavailable });
+ const setupSteps = buildSetupSteps({ endpoint, matchesThisBrowser, permission, testStatus, unavailable });
const diagnostics = buildDiagnostics({
config,
- swState,
- permission,
endpoint,
+ lastSubscription,
matchesThisBrowser,
+ permission,
subscriptions,
- lastSubscription,
+ swState,
});
// Whether this browser is set up and healthy, so the demoted summary line can
@@ -791,8 +803,9 @@ export function WebPushSettings({
{enabled || unavailable ? null : (
@@ -803,6 +816,7 @@ export function WebPushSettings({
aria-controls="web-push-setup"
aria-expanded={showSetup}
className="rounded-md border border-border px-3 py-1.5 text-sm hover:bg-muted/40"
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onClick={() => setShowSetup((open) => !open)}
type="button"
>
@@ -819,9 +833,13 @@ export function WebPushSettings({
diagnostics={diagnostics}
endpoint={endpoint}
lastSubscription={lastSubscription}
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onDisable={disable}
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onEnable={enable}
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onTest={sendTest}
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onToggleDetails={async () => {
const next = !showDetails;
setShowDetails(next);
@@ -888,7 +906,7 @@ function WebPushSetupDetails({
{caveat}
{
for (let attempt = 0; attempt < attempts; attempt += 1) {
if (attempt > 0) {
+ // biome-ignore lint/performance/noAwaitInLoops: sequential by design
await delay(400);
}
try {
@@ -153,13 +154,14 @@ export function BrowserSessionLaunchPanel({
{state.error ? (
-
+ {/** biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional */}
+
Try again
-
+
Open Syncs
-
+
Back to Sources
diff --git a/apps/console/src/app/(console)/connect/browser-session/[connectorId]/launch/page.tsx b/apps/console/src/app/(console)/connect/browser-session/[connectorId]/launch/page.tsx
index dd3f7f0aa..f93d947dc 100644
--- a/apps/console/src/app/(console)/connect/browser-session/[connectorId]/launch/page.tsx
+++ b/apps/console/src/app/(console)/connect/browser-session/[connectorId]/launch/page.tsx
@@ -48,7 +48,7 @@ export default async function BrowserSessionLaunchPage({
+
Back to sources
}
diff --git a/apps/console/src/app/(console)/connect/browser-session/[connectorId]/launch/recovery-classification.ts b/apps/console/src/app/(console)/connect/browser-session/[connectorId]/launch/recovery-classification.ts
index 55afb6651..0c6cc098c 100644
--- a/apps/console/src/app/(console)/connect/browser-session/[connectorId]/launch/recovery-classification.ts
+++ b/apps/console/src/app/(console)/connect/browser-session/[connectorId]/launch/recovery-classification.ts
@@ -3,7 +3,12 @@
import type { RunSummary } from "../../../../lib/ref-client.ts";
-const RECOVERABLE_BROWSER_RUN_STATUSES = new Set(["started", "in_progress", "starting_surface", "waiting_for_browser_surface"]);
+const RECOVERABLE_BROWSER_RUN_STATUSES = new Set([
+ "started",
+ "in_progress",
+ "starting_surface",
+ "waiting_for_browser_surface",
+]);
export function isRecoverableBrowserSessionRun(run: Pick): boolean {
return RECOVERABLE_BROWSER_RUN_STATUSES.has(run.status);
diff --git a/apps/console/src/app/(console)/connect/browser-session/[connectorId]/page.tsx b/apps/console/src/app/(console)/connect/browser-session/[connectorId]/page.tsx
index bf8f43737..07829fa38 100644
--- a/apps/console/src/app/(console)/connect/browser-session/[connectorId]/page.tsx
+++ b/apps/console/src/app/(console)/connect/browser-session/[connectorId]/page.tsx
@@ -65,10 +65,10 @@ function UnavailableSetupCard({ displayName }: { displayName: string }) {
existing source to reconnect it, or return to Add source to see what this dashboard can add now.
-
+
Open sources
-
+
Add source
@@ -119,7 +119,7 @@ export default async function BrowserSessionConnectPage({
Connect account
@@ -133,7 +133,7 @@ export default async function BrowserSessionConnectPage({
Need to reconnect an existing source instead? Go back to Sources and open that source from the list.
-
+
Choose an existing source
@@ -147,7 +147,7 @@ export default async function BrowserSessionConnectPage({
+
Back to sources
}
@@ -199,7 +199,7 @@ export default async function BrowserSessionConnectPage({
) : null}
Reconnect {displayName}
diff --git a/apps/console/src/app/(console)/connect/browser-session/[connectorId]/start/route.ts b/apps/console/src/app/(console)/connect/browser-session/[connectorId]/start/route.ts
index e2724c51c..d05f0592c 100644
--- a/apps/console/src/app/(console)/connect/browser-session/[connectorId]/start/route.ts
+++ b/apps/console/src/app/(console)/connect/browser-session/[connectorId]/start/route.ts
@@ -82,8 +82,11 @@ function readOptionalDisplayNameField(formData: FormData): string | null {
return trimmed;
}
-export async function POST(request: Request, { params }: { params: Promise }): Promise {
- const { connectorId: rawConnectorId } = await params;
+export async function POST(
+ request: Request,
+ { params: routeParams }: { params: Promise }
+): Promise {
+ const { connectorId: rawConnectorId } = await routeParams;
const connectorId = decodeURIComponent(rawConnectorId);
await requireDashboardAccess(pagePath(connectorId));
@@ -113,11 +116,11 @@ export async function POST(request: Request, { params }: { params: Promise 0 ? status.replaceAll("_", " ") : null;
}
function formatBytes(bytes: number): string {
const units = ["B", "KB", "MB", "GB"];
let value = bytes;
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
let unit = units[0] ?? "B";
for (const nextUnit of units) {
unit = nextUnit;
@@ -226,12 +227,13 @@ function ProgressCard({ progress }: { progress: NonNullable(
connectionId?: string | null;
contentType?: string;
displayName?: string | null;
- onProgress(percent: number | null): void;
+ onProgress: (percent: number | null) => void;
}
): Promise {
const url = new URL(path, window.location.origin);
@@ -386,10 +389,11 @@ async function pollArtifactStatus(
currentFile: number;
fileName: string;
totalFiles: number;
- update(progress: NonNullable): void;
+ update: (progress: NonNullable) => void;
}
): Promise {
for (let attempt = 0; attempt < 180; attempt += 1) {
+ // biome-ignore lint/performance/noAwaitInLoops: sequential by design
const res = await fetch(`/_ref/manual-upload/artifacts/${encodeURIComponent(artifactId)}`, {
credentials: "same-origin",
headers: { Accept: "application/json" },
@@ -456,7 +460,7 @@ interface PreparedSubmission {
}
function submitIntent(event: FormEvent): PreparedSubmission["intent"] {
- const submitter = (event.nativeEvent as SubmitEvent).submitter;
+ const { submitter } = event.nativeEvent as SubmitEvent;
return submitter instanceof HTMLButtonElement && submitter.value === "preview" ? "preview" : "import";
}
@@ -552,8 +556,8 @@ async function stageManualUploadFile(
`/_ref/connectors/${encodeURIComponent(setup.connector_id)}/manual-upload-staged-artifact`,
file,
{
- contentType: "application/vnd.pdpp.manual-upload",
connectionId: args.connectionId,
+ contentType: "application/vnd.pdpp.manual-upload",
displayName: args.connectionId ? null : args.displayName,
onProgress: (percent) =>
args.setState(uploadProgress(file, { currentFile, percent, phase: "uploading", totalFiles: args.totalFiles })),
@@ -573,11 +577,12 @@ async function importManualUploads(
target: UploadTarget,
setState: SetUploadState
): Promise {
- let connectionId = target.connectionId;
+ let { connectionId } = target;
let lastConnectionId: string | null = target.connectionId;
let shouldRun = false;
for (let index = 0; index < files.length; index += 1) {
const file = files[index] as File;
+ // biome-ignore lint/performance/noAwaitInLoops: sequential by design
const artifact = await stageManualUploadFile(setup, file, {
connectionId,
displayName: target.displayName,
@@ -645,7 +650,7 @@ export function ManualUploadForm({
}
const submission = prepareSubmission(event, setup);
if ("error" in submission) {
- setState({ ok: false, message: submission.error });
+ setState({ message: submission.error, ok: false });
return;
}
@@ -657,13 +662,14 @@ export function ManualUploadForm({
}
window.location.href = await importManualUploads(setup, submission.files, submission.target, setState);
} catch (err) {
- setState({ ok: false, message: err instanceof Error ? err.message : "Manual upload setup failed." });
+ setState({ message: err instanceof Error ? err.message : "Manual upload setup failed.", ok: false });
} finally {
setPending(false);
}
}
return (
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
{selected ? "Selected" : "Use"}
@@ -192,27 +192,27 @@ function SelectedIdentityCommands({
const cimd = buildCimdCommands(mcpUrl, selected.client_id);
const entries: SetupEntry[] = [
{
- title: "Claude Code",
body: "Default discovery; use this unless the client asks for an explicit client_id.",
label: "Claude Code default command",
+ title: "Claude Code",
value: targets.claudeCodeCommand,
},
{
- title: "Claude Code + CIMD",
body: "Pins this local client to the selected stable metadata URL.",
label: "Claude Code CIMD command",
+ title: "Claude Code + CIMD",
value: cimd.claudeCodeCimdCommand,
},
{
- title: "Codex",
body: "Default discovery for the hosted MCP endpoint.",
label: "Codex default command",
+ title: "Codex",
value: targets.codexCommand,
},
{
- title: "Codex + CIMD",
body: "Pins Codex to the selected stable metadata URL.",
label: "Codex CIMD command",
+ title: "Codex + CIMD",
value: cimd.codexCimdCommand,
},
];
@@ -277,35 +277,35 @@ export default async function ConnectPage({ searchParams }: { searchParams: Prom
const notice = noticeText(params.notice);
const primaryEntries: SetupEntry[] = [
{
- title: "MCP URL",
body: "Use this for ChatGPT, Claude.ai, and remote MCP clients. Browser clients use PKCE; sandboxed clients can use the advertised device-code flow.",
label: "MCP server URL",
+ title: "MCP URL",
value: targets.mcpUrl,
},
{
- title: "Claude Code",
body: "Adds the remote Streamable HTTP MCP server.",
label: "Claude Code command",
+ title: "Claude Code",
value: targets.claudeCodeCommand,
},
{
- title: "Codex",
body: "Adds the same remote MCP endpoint without a bearer-token env var.",
label: "Codex command",
+ title: "Codex",
value: targets.codexCommand,
},
];
const secondaryEntries: SetupEntry[] = [
{
- title: "PDPP CLI",
body: "For a shell agent that will use scoped REST reads instead of hosted MCP.",
label: "PDPP CLI connect command",
+ title: "PDPP CLI",
value: targets.pdppCliCommand,
},
{
- title: "Agent skill",
body: "For agents that discover instructions before choosing MCP or CLI.",
label: "agent-readable entrypoint URL",
+ title: "Agent skill",
value: targets.agentEntrypoint,
},
];
@@ -314,7 +314,7 @@ export default async function ConnectPage({ searchParams }: { searchParams: Prom
+
Deployment readiness
}
diff --git a/apps/console/src/app/(console)/connect/static-secret-payload.test.ts b/apps/console/src/app/(console)/connect/static-secret-payload.test.ts
index 6150b656b..f8fddd0ed 100644
--- a/apps/console/src/app/(console)/connect/static-secret-payload.test.ts
+++ b/apps/console/src/app/(console)/connect/static-secret-payload.test.ts
@@ -249,5 +249,5 @@ test("required bundled fields fail before capture instead of storing incomplete
form
);
- assert.deepEqual(payload, { ok: false, error: "Password is required." });
+ assert.deepEqual(payload, { error: "Password is required.", ok: false });
});
diff --git a/apps/console/src/app/(console)/connect/static-secret/[connectorId]/actions.ts b/apps/console/src/app/(console)/connect/static-secret/[connectorId]/actions.ts
index 86c131a1b..12bc434f5 100644
--- a/apps/console/src/app/(console)/connect/static-secret/[connectorId]/actions.ts
+++ b/apps/console/src/app/(console)/connect/static-secret/[connectorId]/actions.ts
@@ -74,6 +74,7 @@ function autoResumeRunId(capture: StaticSecretCaptureResult): string | null {
function shouldStartRunAfterCapture(capture: StaticSecretCaptureResult): boolean {
const autoResume = capture.auto_resume;
+ // biome-ignore lint/suspicious/noEqualsToNull: The API may omit auto_resume as well as return null.
return autoResume == null || autoResume.status === "no_satisfied_action";
}
@@ -133,6 +134,7 @@ export async function replaceStaticSecretCredentialAction(formData: FormData) {
});
const runId = await runIdAfterCapture(connectionId, captured);
revalidatePath("/sources");
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
target = statusHref(connectionId, runId, captured.identity?.account_identity ?? null);
} catch (err) {
if (err instanceof StaticSecretValidationError) {
@@ -200,6 +202,7 @@ export async function createStaticSecretConnectionAction(formData: FormData) {
// Land on the durable setup-status surface, not a transient form notice. The
// status page reads the connection's projected setup_state and, for a
// synchronous-probe connector, surfaces the echoed account identity.
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
target = statusHref(draft.connection_id, runId, captured.identity?.account_identity ?? null);
} catch (err) {
if (err instanceof StaticSecretValidationError) {
diff --git a/apps/console/src/app/(console)/connect/static-secret/[connectorId]/page.tsx b/apps/console/src/app/(console)/connect/static-secret/[connectorId]/page.tsx
index 30b9a6547..e92f7fdd9 100644
--- a/apps/console/src/app/(console)/connect/static-secret/[connectorId]/page.tsx
+++ b/apps/console/src/app/(console)/connect/static-secret/[connectorId]/page.tsx
@@ -55,8 +55,8 @@ export default async function StaticSecretConnectPage({
});
const resolvedSearchParams = await searchParams;
const pageParams: PageSearchParams = {
- error: firstValue(resolvedSearchParams.error),
connectionId: firstValue(resolvedSearchParams.connection_id),
+ error: firstValue(resolvedSearchParams.error),
};
// Repair/update mode: a connection_id in the query means the owner is
// replacing the credential on an existing connection, not creating a new one.
@@ -86,7 +86,7 @@ export default async function StaticSecretConnectPage({
+
{backLabel}
}
diff --git a/apps/console/src/app/(console)/connect/static-secret/[connectorId]/static-secret-payload.ts b/apps/console/src/app/(console)/connect/static-secret/[connectorId]/static-secret-payload.ts
index e17a9b34a..29dc56126 100644
--- a/apps/console/src/app/(console)/connect/static-secret/[connectorId]/static-secret-payload.ts
+++ b/apps/console/src/app/(console)/connect/static-secret/[connectorId]/static-secret-payload.ts
@@ -52,7 +52,7 @@ export function buildStaticSecretPayload(
? bundledSecretPayload(setup, formData)
: singleSecretPayload(setup, formData);
if ("error" in result) {
- return { ok: false, error: result.error };
+ return { error: result.error, ok: false };
}
return { ok: true, secret: result.secret };
}
diff --git a/apps/console/src/app/(console)/connect/status/[connectionId]/page.tsx b/apps/console/src/app/(console)/connect/status/[connectionId]/page.tsx
index 1bb9330a7..23a7b9ea4 100644
--- a/apps/console/src/app/(console)/connect/status/[connectionId]/page.tsx
+++ b/apps/console/src/app/(console)/connect/status/[connectionId]/page.tsx
@@ -60,32 +60,32 @@ function describeActiveConnectionState(status: ConnectionSetupStatus): StatusDes
if (status.setup_kind === "static_secret" && runStartedAfterCredentialRotation(status)) {
if (status.running) {
return {
- tone: "pending",
- headline: "Credential saved",
detail:
"A sync is running now to verify the updated credential. Existing records remain available while it runs.",
+ headline: "Credential saved",
+ tone: "pending",
};
}
if (statusRunIsFailure(status)) {
return {
- tone: "failed",
- headline: "Credential saved, sync failed",
detail:
"The updated credential was saved, but the verification sync failed. Re-enter it or open the run timeline for the exact failure.",
+ headline: "Credential saved, sync failed",
+ tone: "failed",
};
}
if (statusRunIsSuccess(status)) {
return {
- tone: "active",
- headline: "Connection active",
detail: "The updated credential was verified by a completed sync. Records are available.",
+ headline: "Connection active",
+ tone: "active",
};
}
}
return {
- tone: "active",
- headline: "Connection active",
detail: "Records are available for this account.",
+ headline: "Connection active",
+ tone: "active",
};
}
@@ -93,45 +93,46 @@ function describeImportState(status: ConnectionSetupStatus): StatusDescription {
switch (status.setup_state) {
case "active":
return {
- tone: "active",
- headline: "Import complete",
detail: status.import_receipt
? "Your import was validated and committed. Review the durable coverage receipt below."
: "Your import was committed. This connector did not provide a validation preview for the setup receipt.",
+ headline: "Import complete",
+ tone: "active",
};
case "first_sync_running":
return {
- tone: "pending",
- headline: "Import running",
detail: "The import file is captured and the import is in progress. This page updates as it finishes.",
+ headline: "Import running",
+ tone: "pending",
};
case "first_sync_pending":
return {
- tone: "pending",
- headline: "Import starting",
detail: "The import file is captured and the import is queued. This page updates as it runs.",
+ headline: "Import starting",
+ tone: "pending",
};
case "awaiting_credential":
return {
- tone: "pending",
- headline: "File needed",
detail: "This source is set up but no import file is captured yet.",
+ headline: "File needed",
+ tone: "pending",
};
case "first_sync_failed":
return {
- tone: "failed",
- headline: "Import failed",
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
detail: status.last_error?.remediation ?? "Start the import again.",
+ headline: "Import failed",
+ tone: "failed",
};
case "paused":
- return { tone: "pending", headline: "Connection paused", detail: "This connection is paused." };
+ return { detail: "This connection is paused.", headline: "Connection paused", tone: "pending" };
case "revoked":
- return { tone: "failed", headline: "Connection revoked", detail: "This connection has been revoked." };
+ return { detail: "This connection has been revoked.", headline: "Connection revoked", tone: "failed" };
default:
return {
- tone: "pending",
- headline: "Setting up",
detail: "This connection is being set up. This page updates as the setup progresses.",
+ headline: "Setting up",
+ tone: "pending",
};
}
}
@@ -142,38 +143,39 @@ function describeConnectionState(status: ConnectionSetupStatus): StatusDescripti
return describeActiveConnectionState(status);
case "first_sync_running":
return {
- tone: "pending",
- headline: "First sync running",
detail:
"The provider credential is captured and the first sync is in progress. This page updates as it finishes.",
+ headline: "First sync running",
+ tone: "pending",
};
case "first_sync_pending":
return {
- tone: "pending",
- headline: "First sync starting",
detail: "The provider credential is captured and the first sync is queued. This page updates as it runs.",
+ headline: "First sync starting",
+ tone: "pending",
};
case "awaiting_credential":
return {
- tone: "pending",
- headline: "Setup material needed",
detail: "This connection is set up but no provider credential is captured yet.",
+ headline: "Setup material needed",
+ tone: "pending",
};
case "first_sync_failed":
return {
- tone: "failed",
- headline: "First sync failed",
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
detail: status.last_error?.remediation ?? "Start the first sync again.",
+ headline: "First sync failed",
+ tone: "failed",
};
case "paused":
- return { tone: "pending", headline: "Connection paused", detail: "This connection is paused." };
+ return { detail: "This connection is paused.", headline: "Connection paused", tone: "pending" };
case "revoked":
- return { tone: "failed", headline: "Connection revoked", detail: "This connection has been revoked." };
+ return { detail: "This connection has been revoked.", headline: "Connection revoked", tone: "failed" };
default:
return {
- tone: "pending",
- headline: "Setting up",
detail: "This connection is being set up. This page updates as the setup progresses.",
+ headline: "Setting up",
+ tone: "pending",
};
}
}
@@ -274,7 +276,7 @@ interface ReceiptRow {
function receiptRows(receipt: ImportReceipt): readonly ReceiptRow[] {
const baseRows: ReceiptRow[] = [
- { label: "Batch", value: receipt.batch_id, monospace: true },
+ { label: "Batch", monospace: true, value: receipt.batch_id },
{ label: "File", value: receipt.uploaded_file_name },
{ label: "Receipt status", value: receipt.status },
{ label: "Detected format", value: receipt.detected_format },
@@ -403,41 +405,41 @@ function importPhaseProgress(status: ConnectionSetupStatus): readonly ImportPhas
const facts = importPhaseFacts(status);
return [
{
- label: "Received",
detail: facts.fileReceived ? "PDPP captured the file for this import." : "Choose a file to start.",
+ label: "Received",
state: facts.fileReceived ? "done" : "waiting",
},
{
- label: "Parsed",
detail: facts.parsed
? "The connector parser produced safe validation facts."
: "PDPP has not parsed this file yet.",
+ label: "Parsed",
state: parsedPhaseState(facts),
},
{
- label: "Deduplicated",
detail: facts.deduped
? "Duplicate and skipped counts are available."
: "Duplicate checks run before records commit.",
+ label: "Deduplicated",
state: dedupedPhaseState(facts),
},
{
- label: "Committed",
detail: facts.committed
? "Accepted records or duplicate-only receipt facts are committed."
: "Records are not committed yet.",
+ label: "Committed",
state: committedPhaseState(facts),
},
{
- label: "Indexed",
detail: facts.active ? "Committed records are available on owner surfaces." : "Indexing follows commit.",
+ label: "Indexed",
state: indexedPhaseState(facts),
},
{
- label: "Health projected",
detail: facts.active
? "Connection health and acquisition coverage include this batch."
: "Coverage updates after commit.",
+ label: "Health projected",
state: healthProjectedPhaseState(facts),
},
];
@@ -526,7 +528,7 @@ export default async function ConnectionSetupStatusPage({
+
Back to Sources
}
@@ -582,26 +584,26 @@ export default async function ConnectionSetupStatusPage({
{described.tone === "active" ? (
<>
-
+
Open in Explore
-
+
Source details
{status.setup_kind === "manual_upload" ? (
-
+
Import another file
) : null}
>
) : null}
{described.tone === "failed" || status.setup_state === "awaiting_credential" ? (
-
+
{retryLabel(status)}
) : null}
{described.tone === "pending" && status.setup_state !== "awaiting_credential" ? (
-
+
Refresh status
) : null}
diff --git a/apps/console/src/app/(console)/deployment/page.tsx b/apps/console/src/app/(console)/deployment/page.tsx
index 21e408889..bd50935f1 100644
--- a/apps/console/src/app/(console)/deployment/page.tsx
+++ b/apps/console/src/app/(console)/deployment/page.tsx
@@ -68,7 +68,7 @@ export default async function DeploymentPage() {
+
Tokens
}
diff --git a/apps/console/src/app/(console)/deployment/tokens/actions.ts b/apps/console/src/app/(console)/deployment/tokens/actions.ts
index 20c74fd90..962d76685 100644
--- a/apps/console/src/app/(console)/deployment/tokens/actions.ts
+++ b/apps/console/src/app/(console)/deployment/tokens/actions.ts
@@ -187,8 +187,8 @@ export async function revokeOwnerTokenAction(formData: FormData) {
const res = await fetch(
url,
await withOwnerSessionCookie({
- method: "DELETE",
cache: "no-store",
+ method: "DELETE",
})
);
if (res.status !== 204 && res.status !== 404) {
diff --git a/apps/console/src/app/(console)/deployment/tokens/page.tsx b/apps/console/src/app/(console)/deployment/tokens/page.tsx
index 4c094420b..75dcca01b 100644
--- a/apps/console/src/app/(console)/deployment/tokens/page.tsx
+++ b/apps/console/src/app/(console)/deployment/tokens/page.tsx
@@ -81,7 +81,7 @@ function OwnerAgentOnboardingCard({ entrypoint }: { entrypoint: string }) {
pasted into chat or copied out of the dashboard.
-
+
Review deployment metadata
@@ -191,9 +191,9 @@ function Transcript({ flow }: { flow: FlowState }) {
const approve = JSON.stringify({ user_code: flow.userCode }, null, 2);
const exchange = JSON.stringify(
{
- grant_type: "urn:ietf:params:oauth:grant-type:device_code",
- device_code: flow.deviceCode,
client_id: flow.clientId,
+ device_code: flow.deviceCode,
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
},
null,
2
@@ -491,6 +491,7 @@ export default async function DeploymentTokensPage({ searchParams }: { searchPar
const tokenDetailsByClient = new Map();
try {
const resp = await listOwnerIssuedClients();
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
tokens = resp.data ?? [];
// Only clients with more than one active token get a per-token drilldown;
// a single-token client is fully described by its row.
@@ -499,6 +500,7 @@ export default async function DeploymentTokensPage({ searchParams }: { searchPar
multiTokenClients.map(async (client) => {
try {
const detail = await listOwnerClientTokens(client.client_id);
+ // biome-ignore lint/suspicious/noUnnecessaryConditions: runtime value, TS type is optimistic
tokenDetailsByClient.set(client.client_id, detail.data ?? []);
} catch {
// A per-client drilldown failure must not break the whole page; the
@@ -522,11 +524,11 @@ export default async function DeploymentTokensPage({ searchParams }: { searchPar
+
Deployment overview
}
- breadcrumbs={[{ label: "Deployment", href: "/deployment" }, { label: "Tokens" }]}
+ breadcrumbs={[{ href: "/deployment", label: "Deployment" }, { label: "Tokens" }]}
description="Set up trusted local owner automation without pasting bearer material. Manual owner bearers stay available below for debugging."
title="Owner-agent access"
/>
@@ -545,6 +547,7 @@ export default async function DeploymentTokensPage({ searchParams }: { searchPar
{
assert.equal(formatLastError(null), "none");
assert.equal(
- formatLastError({ message: "browser session expired", code: "session_expired" }),
+ formatLastError({ code: "session_expired", message: "browser session expired" }),
"browser session expired"
);
assert.equal(formatLastError({ code: "rate_limited" }), "rate_limited");
diff --git a/apps/console/src/app/(console)/device-exporters/render.ts b/apps/console/src/app/(console)/device-exporters/render.ts
index 56c307fa0..3eb5bb19e 100644
--- a/apps/console/src/app/(console)/device-exporters/render.ts
+++ b/apps/console/src/app/(console)/device-exporters/render.ts
@@ -57,8 +57,8 @@ export function formatLastError(error: Record | null | undefine
if (!error) {
return "none";
}
- const message = error.message;
- const code = error.code;
+ const { message } = error;
+ const { code } = error;
if (typeof message === "string" && message.trim()) {
return message;
}
diff --git a/apps/console/src/app/(console)/error.tsx b/apps/console/src/app/(console)/error.tsx
index 43612f23c..1f7751932 100644
--- a/apps/console/src/app/(console)/error.tsx
+++ b/apps/console/src/app/(console)/error.tsx
@@ -29,10 +29,11 @@ export default function DashboardError({ error, reset }: { error: Error & { dige
sign back in if the problem persists.
-
reset()} type="button">
+ {/** biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional */}
+ reset()} type="button">
Try again
-
+
Sign in again
diff --git a/apps/console/src/app/(console)/event-subscriptions/[subscriptionId]/page.tsx b/apps/console/src/app/(console)/event-subscriptions/[subscriptionId]/page.tsx
index 2b58667bd..490f0a737 100644
--- a/apps/console/src/app/(console)/event-subscriptions/[subscriptionId]/page.tsx
+++ b/apps/console/src/app/(console)/event-subscriptions/[subscriptionId]/page.tsx
@@ -217,7 +217,7 @@ function RecentAttempts({ attempts }: { attempts: ClientEventSubscriptionAttempt
{attempt.event_type}
- {attempt.latency_ms == null ? "—" : `${attempt.latency_ms}ms`}
+ {attempt.latency_ms === null ? "—" : `${attempt.latency_ms}ms`}
diff --git a/apps/console/src/app/(console)/event-subscriptions/disable-action.ts b/apps/console/src/app/(console)/event-subscriptions/disable-action.ts
index 152d18b23..c20c6ada6 100644
--- a/apps/console/src/app/(console)/event-subscriptions/disable-action.ts
+++ b/apps/console/src/app/(console)/event-subscriptions/disable-action.ts
@@ -43,7 +43,7 @@ function validateReason(raw: string): { ok: true; value: string | null } | { ok:
// (an `email-loop_suspected_…` reason that becomes `email-l…` is worse
// than no reason at all).
if (Buffer.byteLength(raw, "utf8") > MAX_REASON_BYTES) {
- return { ok: false, message: reasonOverflowMessage() };
+ return { message: reasonOverflowMessage(), ok: false };
}
return { ok: true, value: raw };
}
diff --git a/apps/console/src/app/(console)/event-subscriptions/page.tsx b/apps/console/src/app/(console)/event-subscriptions/page.tsx
index 019504b37..f9a034413 100644
--- a/apps/console/src/app/(console)/event-subscriptions/page.tsx
+++ b/apps/console/src/app/(console)/event-subscriptions/page.tsx
@@ -582,7 +582,7 @@ function RecentAttempts({ attempts }: { attempts: ClientEventSubscriptionAttempt
{attempt.event_type}
- {attempt.latency_ms == null ? "—" : `${attempt.latency_ms}ms`}
+ {attempt.latency_ms === null ? "—" : `${attempt.latency_ms}ms`}
diff --git a/apps/console/src/app/(console)/explore/actions.ts b/apps/console/src/app/(console)/explore/actions.ts
index 1d1be8487..d5cc6d872 100644
--- a/apps/console/src/app/(console)/explore/actions.ts
+++ b/apps/console/src/app/(console)/explore/actions.ts
@@ -49,17 +49,17 @@ export async function loadExploreBuckets(req: ExploreBucketRequest): Promise
-
reset()} type="button">
+ {/** biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional */}
+ reset()} type="button">
Reload
-
+
Back to PDPP
diff --git a/apps/console/src/app/(console)/explore/explore-acceptance.test.ts b/apps/console/src/app/(console)/explore/explore-acceptance.test.ts
index f04d9492b..137f5fba7 100644
--- a/apps/console/src/app/(console)/explore/explore-acceptance.test.ts
+++ b/apps/console/src/app/(console)/explore/explore-acceptance.test.ts
@@ -107,13 +107,13 @@ function makeHit(over: {
connection_id?: string;
}): SearchResultHit {
return {
- connector_id: over.connector_id,
connection_id: over.connection_id,
- stream: over.stream ?? "records",
- record_key: over.record_key ?? "rec-1",
+ connector_id: over.connector_id,
emitted_at: "2026-01-01T00:00:00Z",
matched_fields: [],
object: "search_result",
+ record_key: over.record_key ?? "rec-1",
+ stream: over.stream ?? "records",
};
}
@@ -139,11 +139,11 @@ function makeLexicalPage(
function makeRecordsPage(ids: string[], opts?: { has_more?: boolean; next_cursor?: string }): RecordsPage {
return {
data: ids.map((id) => ({
+ data: {},
+ emitted_at: "2026-01-01T00:00:00Z",
id,
object: "record" as const,
stream: "transactions",
- emitted_at: "2026-01-01T00:00:00Z",
- data: {},
})),
has_more: opts?.has_more ?? false,
...(opts?.next_cursor ? { next_cursor: opts.next_cursor } : {}),
@@ -157,19 +157,19 @@ function makeTimelinePage(
): ExploreTimelinePage {
return {
data: Array.from({ length: count }, (_, i) => ({
- object: "timeline_record" as const,
connector_id: "ynab",
connector_instance_id: `cin_ynab_stub_${i}`,
- stream: "transactions",
- record_key: `rec-${i}`,
- emitted_at: `2026-01-0${i + 1}T00:00:00Z`,
data: {},
+ emitted_at: `2026-01-0${i + 1}T00:00:00Z`,
+ object: "timeline_record" as const,
+ record_key: `rec-${i}`,
+ stream: "transactions",
})),
has_more: opts.has_more,
+ new_since_snapshot: 0,
next_cursor: opts.next_cursor ?? null,
object: "list",
snapshot_at: opts.snapshot_at ?? "2026-06-19T00:00:00Z",
- new_since_snapshot: 0,
};
}
@@ -177,40 +177,40 @@ const notStubbed = () => Promise.reject(new Error("not stubbed"));
function makeDataSource(overrides: Partial): DashboardDataSource {
return {
- kind: "sandbox" as const,
aggregateRecordsByTime: notStubbed,
- listExploreRecordBuckets: notStubbed,
- isHybridRetrievalAdvertised: () => Promise.resolve(false),
- isSemanticRetrievalAdvertised: () => Promise.resolve(false),
- listConnectorSummaries: notStubbed,
- listConnectorManifests: notStubbed,
- searchRecordsLexical: notStubbed,
- searchRecordsHybrid: notStubbed,
- searchRecordsSemantic: notStubbed,
- queryRecords: notStubbed,
- getRecord: notStubbed,
getConnectorOverview: notStubbed,
- getStreamMetadata: notStubbed,
- getTraceTimeline: notStubbed,
- getGrantTimeline: notStubbed,
- getRunTimeline: notStubbed,
getDatasetSummary: notStubbed,
getDeploymentDiagnostics: notStubbed,
- listGrants: notStubbed,
- listPendingApprovals: notStubbed,
- listRuns: notStubbed,
- listStreams: notStubbed,
- listTraces: notStubbed,
- refSearch: notStubbed,
+ getGrantTimeline: notStubbed,
+ getRecord: notStubbed,
+ getRunTimeline: notStubbed,
+ getStreamMetadata: notStubbed,
+ getTraceTimeline: notStubbed,
+ isHybridRetrievalAdvertised: () => Promise.resolve(false),
+ isSemanticRetrievalAdvertised: () => Promise.resolve(false),
+ kind: "sandbox" as const,
+ listConnectorManifests: notStubbed,
+ listConnectorSummaries: notStubbed,
+ listExploreRecordBuckets: notStubbed,
listExploreTimeline: () =>
Promise.resolve({
- object: "list" as const,
data: [],
has_more: false,
+ new_since_snapshot: 0,
next_cursor: null,
+ object: "list" as const,
snapshot_at: new Date(0).toISOString(),
- new_since_snapshot: 0,
}),
+ listGrants: notStubbed,
+ listPendingApprovals: notStubbed,
+ listRuns: notStubbed,
+ listStreams: notStubbed,
+ listTraces: notStubbed,
+ queryRecords: notStubbed,
+ refSearch: notStubbed,
+ searchRecordsHybrid: notStubbed,
+ searchRecordsLexical: notStubbed,
+ searchRecordsSemantic: notStubbed,
...overrides,
};
}
@@ -333,7 +333,6 @@ test("P1 assembler: streamSeeAllLinks is non-empty when the time-range fan-out h
// produce the ramps.
const summary = makeSummary({ connection_id: "ynab-1", connector_id: "ynab", streams: ["transactions"] });
const ds = makeDataSource({
- listConnectorSummaries: async () => summaryListResponse([summary]),
// The time-range fan-out requires a consent_time_field on the stream so
// timeRangeStreamTargets includes it. The base makeManifest helper does not
// set this field; provide an explicit manifest here with it declared.
@@ -341,22 +340,23 @@ test("P1 assembler: streamSeeAllLinks is non-empty when the time-range fan-out h
[
{
connector_id: "ynab",
- streams: [{ name: "transactions", consent_time_field: "date" }],
+ streams: [{ consent_time_field: "date", name: "transactions" }],
},
] satisfies ConnectorManifest[],
- // Time-range fan-out: queryRecords returns has_more=true so the see-all ramp fires.
- queryRecords: async () =>
- makeRecordsPage(["rec-1", "rec-2", "rec-3", "rec-4", "rec-5", "rec-6"], { has_more: true }),
+ listConnectorSummaries: async () => summaryListResponse([summary]),
// The recent lens would call this; it is irrelevant here (time-range lens),
// but provide a valid empty page rather than throwing.
listExploreTimeline: async () => ({
- object: "list" as const,
data: [],
has_more: false,
+ new_since_snapshot: 0,
next_cursor: null,
+ object: "list" as const,
snapshot_at: new Date(0).toISOString(),
- new_since_snapshot: 0,
}),
+ // Time-range fan-out: queryRecords returns has_more=true so the see-all ramp fires.
+ queryRecords: async () =>
+ makeRecordsPage(["rec-1", "rec-2", "rec-3", "rec-4", "rec-5", "rec-6"], { has_more: true }),
});
const result = await assembleExplorerData(
@@ -369,7 +369,7 @@ test("P1 assembler: streamSeeAllLinks is non-empty when the time-range fan-out h
result.streamSeeAllLinks.length > 0,
"streamSeeAllLinks must be non-empty when a time-range fan-out stream has has_more=true"
);
- const link = result.streamSeeAllLinks[0];
+ const [link] = result.streamSeeAllLinks;
assert.equal(link?.connectionId, "ynab-1", "see-all link must carry the correct connectionId");
assert.equal(link?.stream, "transactions", "see-all link must carry the correct stream");
});
@@ -387,8 +387,8 @@ test("P3 invariant: day-group (rr-x-day) and burst-collapse (rr-x-burst) class n
test("P3 Load-more cursor: assembler returns non-null nextCursor when real endpoint has_more=true", async () => {
const summary = makeSummary({ connection_id: "ynab-1", connector_id: "ynab", streams: ["transactions"] });
const ds = makeDataSource({
- listConnectorSummaries: async () => summaryListResponse([summary]),
listConnectorManifests: async () => [makeManifest("ynab", ["transactions"])],
+ listConnectorSummaries: async () => summaryListResponse([summary]),
// Real endpoint: returns has_more=true with a real composite cursor
listExploreTimeline: async () => makeTimelinePage(32, { has_more: true, next_cursor: "composite-cursor-p2" }),
});
@@ -404,8 +404,8 @@ test("P3 Load-more cursor: assembler returns non-null nextCursor when real endpo
test("P3 Load-more cursor: assembler returns null nextCursor when real endpoint has_more=false (end of feed)", async () => {
const summary = makeSummary({ connection_id: "ynab-1", connector_id: "ynab", streams: ["transactions"] });
const ds = makeDataSource({
- listConnectorSummaries: async () => summaryListResponse([summary]),
listConnectorManifests: async () => [makeManifest("ynab", ["transactions"])],
+ listConnectorSummaries: async () => summaryListResponse([summary]),
listExploreTimeline: async () => makeTimelinePage(5, { has_more: false, snapshot_at: "2026-06-19T00:00:00Z" }),
});
@@ -430,39 +430,39 @@ test("P3 Load-more trail: second page ACCUMULATES (page 1 stays, page 2 appended
// Snapshot newer than every record so the page-1 filter keeps the whole snapshot.
const PAGE1_SNAPSHOT = "2026-12-31T00:00:00Z";
const mkRecord = (page: string, i: number, dayOffset: number) => ({
- object: "timeline_record" as const,
connector_id: "ynab",
connector_instance_id: "ynab-1",
- stream: "transactions",
- record_key: `${page}-${i}`,
- emitted_at: new Date(baseMs - dayOffset * dayMs).toISOString(),
data: {},
+ emitted_at: new Date(baseMs - dayOffset * dayMs).toISOString(),
+ object: "timeline_record" as const,
+ record_key: `${page}-${i}`,
+ stream: "transactions",
});
const page1Records = Array.from({ length: 32 }, (_, i) => mkRecord("p1", i, i));
const page2Records = Array.from({ length: 3 }, (_, i) => mkRecord("p2", i, 100 + i));
const page1: ExploreTimelinePage = {
- object: "list",
data: page1Records,
has_more: true,
+ new_since_snapshot: 0,
next_cursor: "composite-cursor-p2",
+ object: "list",
snapshot_at: PAGE1_SNAPSHOT,
- new_since_snapshot: 0,
};
const page2: ExploreTimelinePage = {
- object: "list",
data: page2Records,
has_more: false,
+ new_since_snapshot: 0,
next_cursor: null,
+ object: "list",
snapshot_at: PAGE1_SNAPSHOT,
- new_since_snapshot: 0,
};
// Capture each fetch as `${rewind ? "rewind:" : "cursor:"}${cursor}` so we can
// assert the fetch plan distinguishes a REWIND of the trail head (page 1) from a
// plain fetch of the same cursor (page 2).
const capturedFetches: string[] = [];
const ds = makeDataSource({
- listConnectorSummaries: async () => summaryListResponse([summary]),
listConnectorManifests: async () => [makeManifest("ynab", ["transactions"])],
+ listConnectorSummaries: async () => summaryListResponse([summary]),
listExploreTimeline: (opts) => {
const cursor = opts?.cursor ?? null;
const rewind = Boolean(opts?.rewindToFirstPage);
@@ -485,7 +485,7 @@ test("P3 Load-more trail: second page ACCUMULATES (page 1 stays, page 2 appended
// Page 2: append the page-1 cursor to the trail (Load more), forwarding the anchor.
const accumulated = await assembleExplorerData(
- { cursors: "composite-cursor-p2", anchor: firstSnapshot ?? undefined },
+ { anchor: firstSnapshot ?? undefined, cursors: "composite-cursor-p2" },
ds,
"https://rs.test"
);
@@ -503,7 +503,7 @@ test("P3 Load-more trail: second page ACCUMULATES (page 1 stays, page 2 appended
);
// Non-increasing emitted_at across the concatenation; no duplicates.
const times = accumulated.feed.map((e) => Date.parse(e.emittedAt));
- for (let i = 1; i < times.length; i++) {
+ for (let i = 1; i < times.length; i += 1) {
assert.ok((times[i] ?? 0) <= (times[i - 1] ?? 0), "feed must stay non-increasing emitted_at");
}
const ids = accumulated.feed.map((e) => `${e.connectionId} ${e.stream} ${e.recordId}`);
@@ -549,28 +549,28 @@ test("P2 Option D invariant: escape links to search_sort=recent in the URL build
test("P2 sort toggle: lexical Most-relevant and Most-recent return same hit count (same pool)", async () => {
const summary = makeSummary({ connection_id: "ynab-1", connector_id: "ynab", streams: ["transactions"] });
- const hit1 = makeHit({ connector_id: "ynab", stream: "transactions", record_key: "r1", connection_id: "ynab-1" });
- const hit2 = makeHit({ connector_id: "ynab", stream: "transactions", record_key: "r2", connection_id: "ynab-1" });
+ const hit1 = makeHit({ connection_id: "ynab-1", connector_id: "ynab", record_key: "r1", stream: "transactions" });
+ const hit2 = makeHit({ connection_id: "ynab-1", connector_id: "ynab", record_key: "r2", stream: "transactions" });
// Both orderings use the same assembler data source with the same hits.
// Most-relevant: lexical call returns the hits ranked by relevance.
// Most-recent (single-stream): switches to queryRecords for the same stream.
// The feed count must be the same (same pool, different ordering).
const dsRelevance = makeDataSource({
- listConnectorSummaries: async () => summaryListResponse([summary]),
- listConnectorManifests: async () => [makeManifest("ynab", ["transactions"])],
isHybridRetrievalAdvertised: async () => false,
+ listConnectorManifests: async () => [makeManifest("ynab", ["transactions"])],
+ listConnectorSummaries: async () => summaryListResponse([summary]),
searchRecordsLexical: async () => makeLexicalPage([hit1, hit2], { has_more: false }),
});
const dsRecent = makeDataSource({
- listConnectorSummaries: async () => summaryListResponse([summary]),
- listConnectorManifests: async () => [makeManifest("ynab", ["transactions"])],
isHybridRetrievalAdvertised: async () => false,
- // Most-recent detection path: lexical to find stream door
- searchRecordsLexical: async () => makeLexicalPage([hit1, hit2], { has_more: false }),
+ listConnectorManifests: async () => [makeManifest("ynab", ["transactions"])],
+ listConnectorSummaries: async () => summaryListResponse([summary]),
// Then queryRecords for the same 2 records in time order
queryRecords: async () => makeRecordsPage(["r1", "r2"], { has_more: false }),
+ // Most-recent detection path: lexical to find stream door
+ searchRecordsLexical: async () => makeLexicalPage([hit1, hit2], { has_more: false }),
});
const relevanceResult = await assembleExplorerData({ q: "rent" }, dsRelevance, "https://rs.test");
@@ -586,14 +586,14 @@ test("P2 sort toggle: lexical Most-relevant and Most-recent return same hit coun
test("P2 lexical Load-more forwards cursor (assembler advances, does not re-fetch from top)", async () => {
const summary = makeSummary({ connection_id: "ynab-1", connector_id: "ynab", streams: ["transactions"] });
- const hit1 = makeHit({ connector_id: "ynab", stream: "transactions", record_key: "p1", connection_id: "ynab-1" });
- const hit2 = makeHit({ connector_id: "ynab", stream: "transactions", record_key: "p2", connection_id: "ynab-1" });
+ const hit1 = makeHit({ connection_id: "ynab-1", connector_id: "ynab", record_key: "p1", stream: "transactions" });
+ const hit2 = makeHit({ connection_id: "ynab-1", connector_id: "ynab", record_key: "p2", stream: "transactions" });
const capturedCursors: (string | undefined)[] = [];
const ds = makeDataSource({
- listConnectorSummaries: async () => summaryListResponse([summary]),
- listConnectorManifests: async () => [makeManifest("ynab", ["transactions"])],
isHybridRetrievalAdvertised: () => Promise.resolve(false),
+ listConnectorManifests: async () => [makeManifest("ynab", ["transactions"])],
+ listConnectorSummaries: async () => summaryListResponse([summary]),
searchRecordsLexical: (_q, opts) => {
capturedCursors.push(opts?.cursor);
// Recall proven complete: keyword_pageable, so the cursor pages exhaustively.
@@ -608,7 +608,7 @@ test("P2 lexical Load-more forwards cursor (assembler advances, does not re-fetc
const page1 = await assembleExplorerData({ q: "coffee" }, ds, "https://rs.test");
assert.equal(page1.searchNextCursor, "lex-p2");
- const page2 = await assembleExplorerData({ q: "coffee", cursor: "lex-p2" }, ds, "https://rs.test");
+ const page2 = await assembleExplorerData({ cursor: "lex-p2", q: "coffee" }, ds, "https://rs.test");
assert.equal(page2.searchNextCursor, null, "page 2 must be exhausted");
assert.equal(capturedCursors[0], undefined, "page 1: no cursor");
diff --git a/apps/console/src/app/(console)/explore/explore-canvas.tsx b/apps/console/src/app/(console)/explore/explore-canvas.tsx
index 337c8cbcc..34a792e08 100644
--- a/apps/console/src/app/(console)/explore/explore-canvas.tsx
+++ b/apps/console/src/app/(console)/explore/explore-canvas.tsx
@@ -248,18 +248,18 @@ function dateNormalizedHref(explorePath: string, state: DateNormalizeState): str
const dateNav = dateNavFromLift(dateLift.after, dateLift.before);
return withOrderSuffix(
buildHref(explorePath, {
- query: dateLift.rest,
connectionIds: state.selectedConnectionIds,
excludeConnectionIds: state.excludeConnectionIds,
- streams: state.selectedStreams,
excludeStreams: state.excludeStreams,
+ // Preserve a peeked record from a shared `?q=after:X&peek=Y` link.
+ peek: state.peek,
+ query: dateLift.rest,
+ searchSort: state.searchSort === "recent" ? "recent" : undefined,
// Only the endpoint the URL actually typed overrides the canonical window; the
// other side is carried forward from the existing window (never stacks/clears).
since: dateNav.since ?? state.since,
+ streams: state.selectedStreams,
until: dateNav.until ?? state.until,
- searchSort: state.searchSort === "recent" ? "recent" : undefined,
- // Preserve a peeked record from a shared `?q=after:X&peek=Y` link.
- peek: state.peek,
}),
state.order
);
@@ -299,9 +299,9 @@ function composeFacetSelection(
const nextStreams = unionIds(cur.streams, lift.includeStreams);
return {
connectionIds: nextInclude,
- streams: nextStreams,
excludeConnectionIds: unionIds(cur.excludeConnectionIds, liftedExclude).filter((id) => !nextInclude.includes(id)),
excludeStreams: unionIds(cur.excludeStreams, lift.excludeStreams).filter((s) => !nextStreams.includes(s)),
+ streams: nextStreams,
};
}
@@ -541,19 +541,19 @@ function buildFilterChips(args: {
for (const id of args.selectedConnectionIds) {
const name = args.connections.find((c) => c.connectionId === id)?.displayName ?? id;
out.push({
+ canNegate: true,
+ clear: () => args.toggleConnection(id),
id: `con:${id}`,
label: name,
- property: "source",
- operator: "is",
- value: name,
- negated: false,
- canNegate: true,
negate: () => {
// Toggle include → exclude: remove from include, add to exclude
args.toggleConnection(id);
args.toggleExcludeConnection(id);
},
- clear: () => args.toggleConnection(id),
+ negated: false,
+ operator: "is",
+ property: "source",
+ value: name,
});
}
// EXCLUDE chips render the facet/operator exclusion as a visible chip in the SAME
@@ -562,51 +562,51 @@ function buildFilterChips(args: {
for (const id of args.excludeConnectionIds) {
const name = args.connections.find((c) => c.connectionId === id)?.displayName ?? id;
out.push({
+ canNegate: true,
+ clear: () => args.toggleExcludeConnection(id),
id: `xcon:${id}`,
label: `not ${name}`,
- property: "source",
- operator: "is not",
- value: name,
- negated: true,
- canNegate: true,
negate: () => {
// Toggle exclude → include: remove from exclude, add to include
args.toggleExcludeConnection(id);
args.toggleConnection(id);
},
- clear: () => args.toggleExcludeConnection(id),
+ negated: true,
+ operator: "is not",
+ property: "source",
+ value: name,
});
}
for (const s of args.selectedStreams) {
out.push({
+ canNegate: true,
+ clear: () => args.toggleStream(s),
id: `stream:${s}`,
label: `stream: ${s}`,
- property: "stream",
- operator: "is",
- value: s,
- negated: false,
- canNegate: true,
negate: () => {
args.toggleStream(s);
args.toggleExcludeStream(s);
},
- clear: () => args.toggleStream(s),
+ negated: false,
+ operator: "is",
+ property: "stream",
+ value: s,
});
}
for (const s of args.excludeStreams) {
out.push({
+ canNegate: true,
+ clear: () => args.toggleExcludeStream(s),
id: `xstream:${s}`,
label: `not stream: ${s}`,
- property: "stream",
- operator: "is not",
- value: s,
- negated: true,
- canNegate: true,
negate: () => {
args.toggleExcludeStream(s);
args.toggleStream(s);
},
- clear: () => args.toggleExcludeStream(s),
+ negated: true,
+ operator: "is not",
+ property: "stream",
+ value: s,
});
}
// NB: the active DATE window is NOT pushed here. It is rendered ONCE, by the
@@ -620,24 +620,24 @@ function buildFilterChips(args: {
// raw shapes: "stream:messages", "-con:abc", "has:link", "before:2026-01-01", or a
// bare word (free-text search). A leading "-" is the exclude operator. A bare word
// (no colon) is a free-text search term → property "search".
- const raw = tk.raw;
+ const { raw } = tk;
const negated = raw.startsWith("-");
const body = negated ? raw.slice(1) : raw;
const colon = body.indexOf(":");
const property = colon > 0 ? body.slice(0, colon) : "search";
const value = colon > 0 ? body.slice(colon + 1) : body;
out.push({
+ canNegate: false,
+ clear: () => args.navigate({ query: removeToken(args.query, tk.raw) }),
id: `tok:${i}`,
label: tk.label,
- property,
- operator: negated ? "is not" : "is",
- value,
- negated,
- canNegate: false,
negate: () => {
// token chips do not support negation toggling (use -operator: in the query)
},
- clear: () => args.navigate({ query: removeToken(args.query, tk.raw) }),
+ negated,
+ operator: negated ? "is not" : "is",
+ property,
+ value,
});
});
return out;
@@ -809,7 +809,7 @@ function QueryInput(props: QueryInputProps) {
return;
}
// At this point kind is "has-image" | "has-link" | "date" — all handled by suggestionToken.
- const kind = s.kind;
+ const { kind } = s;
if (kind === "has-image" || kind === "has-link" || kind === "date") {
props.onDraftChange(appendOperatorToken(props.draft, suggestionToken(kind)));
}
@@ -873,7 +873,9 @@ function QueryInput(props: QueryInputProps) {
aria-expanded={menuOpen && suggestions.length > 0}
aria-label="Search or filter"
className="rr-x-search"
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onBlur={() => setMenuOpen(false)}
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onChange={(e: ChangeEvent) => {
props.onDraftChange(e.target.value);
setMenuOpen(true);
@@ -881,6 +883,7 @@ function QueryInput(props: QueryInputProps) {
// until the owner explicitly arrows into the menu (Enter-hijack fix, F3).
setCursor(NO_HIGHLIGHT);
}}
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onFocus={() => setMenuOpen(true)}
onKeyDown={onKeyDown}
placeholder="Search or filter…"
@@ -891,6 +894,7 @@ function QueryInput(props: QueryInputProps) {
setMenuOpen((v) => !v)}
type="button"
>
@@ -900,6 +904,7 @@ function QueryInput(props: QueryInputProps) {
{/* Inline "Jump to record" affordance — command-palette style, NOT a 2nd box. */}
{jumpId ? (
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
e.preventDefault()} type="button">
↵ Jump to record {jumpId}
@@ -923,6 +928,7 @@ function QueryInput(props: QueryInputProps) {
aria-selected={i === cursor}
className={["rr-x-typeahead__btn", i === cursor ? "is-active" : ""].filter(Boolean).join(" ")}
id={`rr-x-typeahead-opt-${i}`}
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onMouseDown={(e) => {
e.preventDefault();
pickSuggestion(s);
@@ -1229,6 +1235,7 @@ function DateChip({
aria-expanded={open}
aria-haspopup="dialog"
className="rr-x-datechip__trigger"
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onClick={() => setOpen((v) => !v)}
type="button"
>
@@ -1256,6 +1263,7 @@ function DateChip({
aria-checked={selected}
className={["rr-x-datechip__preset", selected ? "is-on" : ""].filter(Boolean).join(" ")}
key={preset.key}
+ // biome-ignore lint/performance/noJsxPropsBind: non-memoized, inline binding intentional
onClick={() => {
onPreset(preset.key);
setOpen(false);
@@ -1275,6 +1283,7 @@ function DateChip({
instantly above. */}