Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
40 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

API: notifications over REST and MCP, with notifications scopes1import { useEffect } from "react";
2import { useNavigation, useRevalidator } from "react-router";
3
4/** How often a page with something moving asks again. */
5export const REFRESH_MS = 4000;
6
7/**
Merge branch 'worktree-agent-a9934473c8cf2bca6'8 * Revalidates the page `everyMs` after it last loaded while `on` and the
9 * tab is visible. Whatever refreshed it last (this, a live change, a form,
10 * a navigation) starts the count again, so a page that also follows live
11 * changes is not refreshed twice in a row. Out of view it waits, and asks
12 * once when the tab comes back if the time has passed meanwhile.
13 *
API: notifications over REST and MCP, with notifications scopes14 * Never while a navigation is pending: a revalidation then restarts the
15 * navigation, aborting its loaders, so a click to a page slower than the
16 * interval would never arrive. Never on top of a revalidation still going.
17 */
18export function useRefreshWhile(on: boolean, everyMs = REFRESH_MS) {
19 const revalidator = useRevalidator();
Merge branch 'worktree-agent-a9934473c8cf2bca6'20 const idle = useNavigation().state === "idle" && revalidator.state === "idle";
API: notifications over REST and MCP, with notifications scopes21 useEffect(() => {
Merge branch 'worktree-agent-a9934473c8cf2bca6'22 if (!on || !idle) return;
23 let due = false;
24 const ask = () => {
25 if (document.visibilityState === "visible") revalidator.revalidate();
26 else due = true;
27 };
28 const timer = setTimeout(ask, everyMs);
29 const back = () => {
30 if (due && document.visibilityState === "visible") ask();
31 };
32 document.addEventListener("visibilitychange", back);
33 return () => {
34 clearTimeout(timer);
35 document.removeEventListener("visibilitychange", back);
36 };
37 // `revalidator` is a new object whenever its state changes, which `idle` already follows.
38 // eslint-disable-next-line react-hooks/exhaustive-deps
39 }, [on, idle, everyMs]);
API: notifications over REST and MCP, with notifications scopes40}

This file's history is long; its oldest lines are credited to the oldest commit read.